-
Notifications
You must be signed in to change notification settings - Fork 479
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
agreement: split ValidatedBlock and AssembledBlock interfaces #5967
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #5967 +/- ##
==========================================
+ Coverage 55.71% 55.77% +0.06%
==========================================
Files 490 490
Lines 68125 68138 +13
==========================================
+ Hits 37954 38006 +52
+ Misses 27599 27565 -34
+ Partials 2572 2567 -5 ☔ 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.
Suggested a nit correction, but overall this makes sense and is very logical
Since AssembledBlock is a subset of ValidatedBlock, ledgercore.ValidatedBlock is both. And there are many places that use |
I think there may be tests that use GenerateBlock and want the deltas, which is why I left GenerateBlock as is but changed only the return type of AssembleBlock.. I can modify GenerateBlock too if it turns out there are no tests that use the deltas |
Would it be too crazy to give the Deltas() as different name in the two interfaces? I can see good reasons to look at the deltas, but that shouldn't force us to conflate the interfaces. |
Looking at it now I'm not sure it's essential to modify the return type of |
I don't follow.
If And with my planned changes, I'd want to go even further: AssembledBlock becomes SeededBlock then it becomes a ValidatedBlock only after be Eval()d again, so that the incentive payout appears in the deltas. I think the PR can and should be merged as is, because it makes things better, but I would still like to understand your reasoning, so I can think about how we might want to evolve later. (I'm now seeing that we could potentially have an optimization in which the SeededBlock is not re-evaluated, we just tack on the incentive payout to create a ValidatedBlock. But I think we are currently performing the re-evaluation anyway, so it's not like we need such an optimization.) |
My point is that agreement controls the only way for validated blocks to get added to the ledger when calling agreement.EnsureValidatedBlock — which this PR addresses (just the types handled by agreement and agreement's AssembleBlock generated block now contains no deltas). Any other shortcut to take GenerateBlock's output and add it to a ledger is in simulation & test code.. it sounds like those tests may break, or not be testing realistic enough cases after your changes in #5757 now, though? |
Closing, merged into #5757 via jannotti#19 |
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 don't follow yet.
// reflect the value of the new seed. | ||
FinalizeBlock(seed committee.Seed, proposer basics.Address) ProposableBlock | ||
|
||
Round() basics.Round |
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.
Why do we need Round() now?
AssembledBlocks can't give out their 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.
The idea is not to allow access to the AssembledBlock, it is an opaque type that should not be used for serializing or access until Finalize is called
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.
Making this more opaque also helped me catch some agreement tests & test helpers that were using the AssembleBlock() value without calling WithSeed before — those tests were ignoring and not validating the seed anyway, but it was good to find where they were.
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.
It does seem good that an assembledBlock will no longer implement ValidatedBlock.
@@ -413,7 +417,7 @@ type testAccountData struct { | |||
} | |||
|
|||
func makeProposalsTesting(accs testAccountData, round basics.Round, period period, factory BlockFactory, ledger Ledger) (ps []proposal, vs []vote) { | |||
ve, err := factory.AssembleBlock(round) | |||
ve, err := factory.AssembleBlock(round, accs.addresses) |
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.
So the idea is that the underlying type is not going to be a Block, it's going to be something that holds onto extra information about those addresses (balances, presumably) so that a later call to FinalizeBlock can erase the payout if it won't leave the account above min balance?
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.
Yes and whatever else you need to do (like updating the seed, assigning proposer etc) to finish/finalize the block
Closing, replaced by #5973 and what has already been merged into #5757 via jannotti#19 |
Summary
Agreement has three main interfaces dealing with blocks: the
BlockFactory
(used to produce block proposals to send out, implemented by the transaction pool), theBlockValidator
(used to verify incoming block proposals, implemented by the ledger), and theLedgerWriter
(used to write blocks to the ledger after consensus has been reached).These interfaces all share a common block type,
ValidatedBlock
, which is used when building proposals, validating proposals, and later writing blocks (if they have already been validated). To support building proposals,ValidatedBlock
provides aWithSeed()
method used to modify an assembled proposal's headers just before sending it out. To avoid re-evaluating winning proposals twice,ValidatedBlock
also holds on to block evaluation outputs between calls toBlockValidator.Validate()
andLedgerWriter.EnsureValidatedBlock()
.This PR splits the
AssembledBlock
interface from theValidatedBlock
interface to split the block-building calls (AssembleBlock()
,WithSeed()
) from the block-validating-and-writing calls (Validate()
,EnsureValidatedBlock()
) more strictly.Test Plan
Relatively small interface change, updated tests that implement BlockFactory so existing tests will pass.