Skip to content

Commit aa85cd8

Browse files
authored
Snapshot Term/whole TxID in KV so as to report status correctly in multi-threaded configuration (#1288)
1 parent fc1e833 commit aa85cd8

File tree

21 files changed

+272
-119
lines changed

21 files changed

+272
-119
lines changed

src/consensus/pbft/libbyz/replica.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,8 @@ bool Replica::compare_execution_results(
463463

464464
void Replica::playback_request(kv::Tx& tx)
465465
{
466-
auto view = tx.get_view(pbft_requests_map);
467-
auto req_v = view->get(0);
466+
auto tx_view = tx.get_view(pbft_requests_map);
467+
auto req_v = tx_view->get(0);
468468
CCF_ASSERT(
469469
req_v.has_value(),
470470
"Deserialised request but it was not found in the requests map");
@@ -499,7 +499,7 @@ void Replica::playback_request(kv::Tx& tx)
499499
vec_exec_cmds[0] = std::move(execute_tentative_request(
500500
*req, playback_max_local_commit_value, true, &tx, -1));
501501

502-
exec_command(vec_exec_cmds, playback_byz_info, 1, 0, false);
502+
exec_command(vec_exec_cmds, playback_byz_info, 1, 0, false, view());
503503
did_exec_gov_req = did_exec_gov_req || playback_byz_info.did_exec_gov_req;
504504

505505
auto owned_req = req.release();
@@ -2443,7 +2443,12 @@ bool Replica::execute_tentative(Pre_prepare* pp, ByzInfo& info, uint64_t nonce)
24432443
pp, info.max_local_commit_value, vec_exec_cmds, num_requests))
24442444
{
24452445
exec_command(
2446-
vec_exec_cmds, info, num_requests, nonce, !pp->should_reorder());
2446+
vec_exec_cmds,
2447+
info,
2448+
num_requests,
2449+
nonce,
2450+
!pp->should_reorder(),
2451+
pp->view());
24472452
return true;
24482453
}
24492454
return false;
@@ -2488,7 +2493,12 @@ bool Replica::execute_tentative(
24882493
}
24892494

24902495
exec_command(
2491-
vec_exec_cmds, info, num_requests, nonce, !pp->should_reorder());
2496+
vec_exec_cmds,
2497+
info,
2498+
num_requests,
2499+
nonce,
2500+
!pp->should_reorder(),
2501+
pp->view());
24922502
if (!node_info.general_info.support_threading)
24932503
{
24942504
cb(pp, this, std::move(ctx));

src/consensus/pbft/libbyz/test/replica_unit_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ class ExecutionMock
4343
ByzInfo& info,
4444
uint32_t num_requests,
4545
uint64_t nonce,
46-
bool executed_single_threaded) {
46+
bool executed_single_threaded,
47+
View view) {
4748
for (uint32_t i = 0; i < num_requests; ++i)
4849
{
4950
std::unique_ptr<ExecCommandMsg>& msg = msgs[i];

src/consensus/pbft/libbyz/types.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ using ExecCommand = std::function<int(
141141
ByzInfo& info,
142142
uint32_t num_requests,
143143
uint64_t nonce,
144-
bool executed_single_threaded)>;
144+
bool executed_single_threaded,
145+
View view)>;
145146

146147
using VerifyAndParseCommand = std::function<std::unique_ptr<pbft::RequestCtx>(
147-
Byz_req* inb, uint8_t* req_start, size_t req_size)>;
148+
Byz_req* inb, uint8_t* req_start, size_t req_size)>;

src/consensus/pbft/pbft.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ namespace pbft
623623
return client_proxy->get_statistics();
624624
}
625625

626-
bool replicate(const kv::BatchVector& entries) override
626+
bool replicate(const kv::BatchVector& entries, View view) override
627627
{
628628
for (auto& [index, data, globally_committable] : entries)
629629
{

src/consensus/pbft/pbft_config.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,13 @@ namespace pbft
259259
ByzInfo& info,
260260
uint32_t num_requests,
261261
uint64_t nonce,
262-
bool executed_single_threaded) {
262+
bool executed_single_threaded,
263+
View view) {
263264
info.pending_cmd_callbacks = num_requests;
264265
info.version_before_execution_start = store->current_version();
266+
// PBFT views start at 0, where Raft (and therefore CCF, historically)
267+
// starts at 2
268+
store->set_view(view + 2);
265269
for (uint32_t i = 0; i < num_requests; ++i)
266270
{
267271
std::unique_ptr<ExecCommandMsg>& msg = msgs[i];

src/consensus/pbft/pbft_types.h

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ namespace pbft
6161
virtual void commit_new_view(
6262
const pbft::NewView& new_view, pbft::NewViewsMap& pbft_new_views_map) = 0;
6363
virtual std::shared_ptr<kv::AbstractTxEncryptor> get_encryptor() = 0;
64+
virtual void set_view(Term t) = 0;
65+
66+
virtual kv::TxID next_txid() = 0;
6467
};
6568

6669
template <typename T, typename S>
@@ -93,16 +96,16 @@ namespace pbft
9396
auto p = x.lock();
9497
if (p)
9598
{
96-
auto version = p->next_version();
99+
auto txid = p->next_txid();
97100
LOG_TRACE_FMT("Storing pre prepare at seqno {}", pp.seqno);
98101
auto success = p->commit(
99-
version,
100-
[version,
102+
txid,
103+
[txid,
101104
&pbft_pre_prepares_map,
102105
&signatures,
103106
pp,
104107
root = std::vector<uint8_t>(root.p, root.p + root.n)]() {
105-
kv::Tx tx(version);
108+
kv::Tx tx(txid.version);
106109
auto pp_view = tx.get_view(pbft_pre_prepares_map);
107110
pp_view->put(0, pp);
108111
auto sig_view = tx.get_view(signatures);
@@ -113,7 +116,7 @@ namespace pbft
113116
false);
114117
if (success == kv::CommitSuccess::OK)
115118
{
116-
return version;
119+
return txid.version;
117120
}
118121
}
119122
return kv::NoVersion;
@@ -147,25 +150,21 @@ namespace pbft
147150
auto p = x.lock();
148151
if (p)
149152
{
150-
auto version = p->next_version();
153+
auto txid = p->next_txid();
151154
LOG_TRACE_FMT(
152155
"Storing new view message at view {} for node {}",
153156
new_view.view,
154157
new_view.node_id);
155158

156159
auto success = p->commit(
157-
version,
158-
[version, &pbft_new_views_map, new_view]() {
159-
kv::Tx tx(version);
160+
txid,
161+
[txid, &pbft_new_views_map, new_view]() {
162+
kv::Tx tx(txid.version);
160163
auto vc_view = tx.get_view(pbft_new_views_map);
161164
vc_view->put(0, new_view);
162165
return tx.commit_reserved();
163166
},
164167
false);
165-
if (success == kv::CommitSuccess::OK)
166-
{
167-
return;
168-
}
169168
}
170169
}
171170

@@ -175,7 +174,6 @@ namespace pbft
175174
if (p)
176175
{
177176
p->compact(v);
178-
return;
179177
}
180178
}
181179

@@ -198,6 +196,25 @@ namespace pbft
198196
return kv::NoVersion;
199197
}
200198

199+
kv::TxID next_txid()
200+
{
201+
auto p = x.lock();
202+
if (p)
203+
{
204+
return p->next_txid();
205+
}
206+
return {0, kv::NoVersion};
207+
}
208+
209+
void set_view(Term view)
210+
{
211+
auto p = x.lock();
212+
if (p)
213+
{
214+
p->set_term(view);
215+
}
216+
}
217+
201218
std::shared_ptr<kv::AbstractTxEncryptor> get_encryptor()
202219
{
203220
auto p = x.lock();

src/consensus/raft/raft.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,8 @@ namespace raft
326326
}
327327

328328
template <typename T>
329-
bool replicate(const std::vector<std::tuple<Index, T, bool>>& entries)
329+
bool replicate(
330+
const std::vector<std::tuple<Index, T, bool>>& entries, Term term)
330331
{
331332
std::lock_guard<SpinLock> guard(lock);
332333

@@ -338,6 +339,16 @@ namespace raft
338339
return false;
339340
}
340341

342+
if (term != current_term)
343+
{
344+
LOG_FAIL_FMT(
345+
"Failed to replicate {} items at term {}, current term is {}",
346+
entries.size(),
347+
term,
348+
current_term);
349+
return false;
350+
}
351+
341352
LOG_DEBUG_FMT("Replicating {} entries", entries.size());
342353

343354
for (auto& [index, data, globally_committable] : entries)
@@ -1031,6 +1042,11 @@ namespace raft
10311042
{
10321043
rollback(commit_idx);
10331044
}
1045+
else
1046+
{
1047+
// but we still want the KV to know which term we're in
1048+
store->set_term(current_term);
1049+
}
10341050

10351051
committable_indices.clear();
10361052
state = Leader;
@@ -1197,7 +1213,8 @@ namespace raft
11971213

11981214
void rollback(Index idx)
11991215
{
1200-
store->rollback(idx);
1216+
store->rollback(idx, current_term);
1217+
LOG_DEBUG_FMT("Setting term in store to: {}", current_term);
12011218
ledger->truncate(idx);
12021219
last_idx = idx;
12031220
LOG_DEBUG_FMT("Rolled back at {}", idx);

src/consensus/raft/raft_consensus.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ namespace raft
4949
raft->force_become_leader(seqno, view, terms, commit_seqno);
5050
}
5151

52-
bool replicate(const kv::BatchVector& entries) override
52+
bool replicate(const kv::BatchVector& entries, View view) override
5353
{
54-
return raft->replicate(entries);
54+
return raft->replicate(entries, view);
5555
}
5656

5757
std::pair<View, SeqNo> get_committed_txid() override

src/consensus/raft/raft_types.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ namespace raft
2828
bool public_only = false,
2929
Term* term = nullptr) = 0;
3030
virtual void compact(Index v) = 0;
31-
virtual void rollback(Index v) = 0;
31+
virtual void rollback(Index v, std::optional<Term> t = std::nullopt) = 0;
32+
virtual void set_term(Term t) = 0;
3233
};
3334

3435
template <typename T, typename S>
@@ -60,13 +61,18 @@ namespace raft
6061
}
6162
}
6263

63-
void rollback(Index v)
64+
void rollback(Index v, std::optional<Term> t = std::nullopt)
6465
{
6566
auto p = x.lock();
6667
if (p)
67-
{
68-
p->rollback(v);
69-
}
68+
p->rollback(v, t);
69+
}
70+
71+
void set_term(Term t)
72+
{
73+
auto p = x.lock();
74+
if (p)
75+
p->set_term(t);
7076
}
7177
};
7278

src/consensus/raft/test/driver.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ class RaftDriver
223223
{
224224
std::cout << " KV" << node_id << "->>Node" << node_id
225225
<< ": replicate idx: " << idx << std::endl;
226-
_nodes.at(node_id).raft->replicate(kv::BatchVector{{idx, data, true}});
226+
_nodes.at(node_id).raft->replicate(kv::BatchVector{{idx, data, true}}, 1);
227227
}
228228

229229
void disconnect(raft::NodeId left, raft::NodeId right)

0 commit comments

Comments
 (0)