-
Notifications
You must be signed in to change notification settings - Fork 176
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
[BFT] ReceiptValidator
ensures k
receipts committing to the execution result
#5050
[BFT] ReceiptValidator
ensures k
receipts committing to the execution result
#5050
Conversation
… for execution result to be considered valid
… k receipts in candidate block
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #5050 +/- ##
==========================================
- Coverage 56.31% 56.30% -0.01%
==========================================
Files 976 976
Lines 91752 91761 +9
==========================================
- Hits 51673 51670 -3
- Misses 36253 36265 +12
Partials 3826 3826
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, however I think we can simplify by removing the parameter k
.
My interpretation of the issue is that k
was meant to abstractly describe the set of valid payload inputs the implementation needs to accept, not to actually be a parameter we add to the implementation. I don't think there is a need for k
to be configurable.
s.Require().True(engine.IsInvalidInputError(err)) | ||
} | ||
|
||
// TestValidateReceiptResultHasNotEnoughReceipts tests a case when a malicious leader incorporates an execution result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove this test case. If k
is constant, then this is equivalent to the previous test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, alright, I thought that it's useful for some BFT cases in future development. I will remove it.
@@ -881,22 +829,9 @@ func (s *ReceiptValidationSuite) TestValidateReceiptResultHasEnoughReceipts() { | |||
} | |||
s.PersistedResults[result0.ID()] = result0 | |||
|
|||
candidateReceipts := []*flow.ExecutionReceiptMeta{receiptB.Meta()} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is still worthwhile to test both valid cases:
- Proposer includes result and 1 receipt in block
- Proposer includes result and multiple receipts in block
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added it back 856c8cc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎸
Co-authored-by: Jordan Schalm <jordan@dapperlabs.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great code and detailed test 🎵
// first validate all results that were included into payload | ||
// if one of results is invalid we fail the whole check because it could be violating | ||
// parent-children relationship | ||
// if one of results is invalid we fail the whole check because it could be violating parent-children relationship | ||
// each execution |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this function ValidatePayload
, we are checking the protocol compliance of all the results in the payload. Anything that violates protocol rules makes the entire block invalid. I think arguing at that level is totally fine. I don't think we need to go into the details of parent-children relationship (tbh, I didn't follow that argument about parent-children relationship ... it might have well been me adding or suggesting this comment).
// first validate all results that were included into payload | |
// if one of results is invalid we fail the whole check because it could be violating | |
// parent-children relationship | |
// if one of results is invalid we fail the whole check because it could be violating parent-children relationship | |
// each execution | |
// Validate all results that are incorporated into the payload. If one is malformed, the entire block is invalid. |
// TestValidateReceiptResultHasEnoughReceipts tests a case where a leader incorporates an execution result | ||
// into their proposal, which has multiple receipts and ReceiptValidator accepts it as valid payload. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would help to extend this description a bit.
// TestValidateReceiptResultHasEnoughReceipts tests a case where a leader incorporates an execution result | |
// into their proposal, which has multiple receipts and ReceiptValidator accepts it as valid payload. | |
// TestValidateReceiptResultHasEnoughReceipts tests the happy path of a block proposal, where a leader | |
// includes multiple Execution Receipts that commit to the same result. In this case, the Flow protocol | |
// prescribes that | |
// - the Execution Result is only incorporated once | |
// - from each Receipt the `ExecutionReceiptMeta` is to be included | |
// | |
// The validator is expected to accept such Payload as valid. |
https://github.com/dapperlabs/flow-go/issues/6863
Context
As summarized in the issue currently
ReceiptValidator
is not ensuring that an execution result was actually executed, by not checking the availability of receipt we allow a malicious leader to incorporate made-up execution results. This PR fixes is by introducing a parameterk
which controls how many different execution receipts have to be committing to the execution result