Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playback via ledger entries #721

Merged
merged 58 commits into from
Feb 3, 2020
Merged

Playback via ledger entries #721

merged 58 commits into from
Feb 3, 2020

Conversation

olgavrou
Copy link
Contributor

Resolves #694 and #693

Status messages are used to detect if a replica is so far behind that it can not catch up by message re transmission. In that case the Replica will send an Append_entries (new type) message. This will be intercepted by Pbft and will send entries from the ledger.

Pbft keeps the ledger index every time something is written to the ledger via replicate. This is needed since version, seqno, and ledger index's do not match in any way. Also it keeps track of the ledger index when a seqno is marked as stable. This is needed because when a replica joins very late, we want to send ledger entries up until our last seqno that was marked as stable. From there we can send messages that are stored in the replica (who is helping the late joiner catch up) state.

When a ledger entry is received it will be deserialised and then passed to the Replica for execution. Entries should come in the sequence of: request(s) and then pre-prepare. Playbacks will also take the transaction that was populated when Store::deserialise was called, and it will be used to execute the request or write the pre-prepare to the ledger.

As replicas might be playing-back and receiving out of order pre-prepares/prepares/commits, we need to reject those pre-prepares/prepares/commits if they are old.

Opening as a draft since I need to look at things a bit more closely and possibly cleanup-refactor some bits here and there

Before opening as a normal PR I need to add the batching method for the append entries size (same as raft)

@olgavrou olgavrou requested a review from a team as a code owner January 24, 2020 15:43
src/enclave/enclavetypes.h Outdated Show resolved Hide resolved
src/kv/kv.h Show resolved Hide resolved
@ghost
Copy link

ghost commented Jan 24, 2020

playback_via_ae@4481 aka 20200203.3 vs master ewma over 30 builds from 4059 to 4477
images

@codecov-io
Copy link

codecov-io commented Jan 24, 2020

Codecov Report

Merging #721 into master will decrease coverage by 6.38%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #721      +/-   ##
==========================================
- Coverage   79.17%   72.79%   -6.38%     
==========================================
  Files         153      153              
  Lines       11638    11638              
==========================================
- Hits         9214     8471     -743     
- Misses       2424     3167     +743
Flag Coverage Δ
#e2e_BFT 51.32% <0%> (-5.85%) ⬇️
#e2e_CFT 59.9% <100%> (-13.1%) ⬇️
#unit_BFT 54.11% <ø> (-0.19%) ⬇️
#unit_CFT 68.98% <100%> (+0.41%) ⬆️
Impacted Files Coverage Δ
src/consensus/raft/raft.h 74.04% <100%> (-8.29%) ⬇️
src/enclave/rpcclient.h 100% <0%> (ø) ⬆️
src/node/notifier.h 20% <0%> (-80%) ⬇️
src/tls/entropy.h 23.53% <0%> (-70.59%) ⬇️
src/enclave/framedtlsendpoint.h 66% <0%> (ø) ⬆️
src/enclave/rpcendpoint.h 65.33% <0%> (ø) ⬆️
src/crypto/symmkey.h 50% <0%> (-47.06%) ⬇️
src/node/ledgersecrets.h 21.92% <0%> (-42.47%) ⬇️
src/host/notifyconnections.h 30.88% <0%> (-38.24%) ⬇️
src/node/nodestate.h 46.4% <0%> (-37.03%) ⬇️
... and 37 more

src/consensus/pbft/pbft.h Outdated Show resolved Hide resolved
src/kv/kv.h Outdated Show resolved Hide resolved
src/consensus/pbft/pbfttypes.h Outdated Show resolved Hide resolved
@@ -337,8 +337,17 @@ namespace ccf
std::shared_ptr<enclave::RpcContext> ctx,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: it seems that the comment above is now out-of-date?

src/kv/kv.h Outdated Show resolved Hide resolved
src/consensus/pbft/pbft.h Outdated Show resolved Hide resolved
}
case kv::DeserialiseSuccess::PASS_SIGNATURE:
{
throw std::logic_error(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if the kv should return a similar status when it has deserialised a Pre_Prepare transaction (in my mental model, PBFT's Pre-prepares are roughly Raft's signatures). Then you can remove playback_transaction() from Replica.cpp and call playback_request() and playback_pre_prepare() directly from here, which I think is neater?

Copy link
Contributor Author

@olgavrou olgavrou Jan 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would entail having the kv look for ccf.signature table and ccf.pbft.preprepares table and return PASS_SIGNATURE status. I am weary of semantically mixing up pre-prepares with signatures. A pre-prepare is not necessarily signed and therefore it will not necessarily globally commit. The code will work, but the semantics will be off.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can return PASS_PRE_PREPARE from deserialise to keep the two enum different.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure if we can agree on that I can add the PASS_PRE_PREPARE to DeserialiseSuccess and there will be no need for the playback_transaction as you said

tests/late_joiners.py Outdated Show resolved Hide resolved
tests/late_joiners.py Outdated Show resolved Hide resolved
Copy link
Contributor

@jumaffre jumaffre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy with this once the KV reserved stuff is fixed. As discussed, could you also create a ticket or write a TODO in the code so that we can think of making the late_joiners.py test part of the existing end-to-end suite as we have all the building blocks for that already?

@olgavrou olgavrou merged commit 15d42ac into master Feb 3, 2020
@olgavrou olgavrou deleted the playback_via_ae branch February 3, 2020 16:12
eddyashton pushed a commit to eddyashton/CCF that referenced this pull request Mar 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Store::deserialise() should be able to deserialise without committing
6 participants