linera-protocol
linera-protocol copied to clipboard
Refactor BlockProposal
The field content: BlockAndRound in BlockProposal was meant to be the part that the signature applies to.
Now that we are adding oracles, we have to make the block proposer sign not only the block and round, but also the oracle records in the validated block, if it is included. Otherwise, if there were already multiple rounds where the same proposed block got validated with different oracle values, someone who isn't the current round leader could take my proposal signature and swap out the validated block for a different one (same block, different oracle values) and make my round fail.
The block itself is currently duplicated, since it occurs both in content and in validated.
We could rename BlockAndRound to ProposalContent and add a field outcome: Option<BlockExecutionOutcome> (or even just oracle_records: Option<Vec<OracleRecord>>). We could then make validated a lite certificate. A proposal would only be valid if validated.is_some() == outcome.is_some(), and if the lite certificate's hash matches the CertificateValue::ValidatedBlock resulting from combining the block with the outcome.
Alternatively, we could make the block in BlockAndRound an enum:
enum BlockOrCertificate {
NewBlock(Block),
ValidatedBlock(Certificate), // Must be `ValidatedBlock`.
}