github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/model/flow/seal.go (about) 1 package flow 2 3 import "encoding/json" 4 5 // A Seal is produced when an Execution Result (referenced by `ResultID`) for 6 // particular block (referenced by `BlockID`) is committed into the chain. 7 // A Seal for a block B can be included in the payload B's descendants. Only 8 // in the respective fork where the seal for B is included, the referenced 9 // result is considered committed. Different forks might contain different 10 // seals for the same result (or in edge cases, even for different results). 11 // 12 // NOTES 13 // (1) As Seals are (currently) included in the payload, they are not strictly 14 // entities. (Entities can be sent between nodes as self-contained messages 15 // whose integrity is protected by a signature). By itself, a seal does 16 // _not_ contain enough information to determine its validity (verifier 17 // assignment cannot be computed) and its integrity is not protected by a 18 // signature of a node that is authorized to generate it. A seal should only 19 // be processed in the context of the block, which contains it. 20 // 21 // (2) Even though seals are not strictly entities, they still implement the 22 // Entity interface. This allows us to store and retrieve seals individually. 23 // CAUTION: As seals are part of the block payload, their _exact_ content must 24 // be preserved by the storage system. This includes the exact list of approval 25 // signatures (incl. order). While it is possible to construct different valid 26 // seals for the same result (using different subsets of assigned verifiers), 27 // they cannot be treated as equivalent for the following reason: 28 // 29 // - Swapping a seal in a block with a different once changes the binary 30 // representation of the block payload containing the seal. 31 // - Changing the binary block representation would invalidate the block 32 // proposer's signature. 33 // 34 // Therefore, to retrieve valid blocks from storage, it is required that 35 // the Seal.ID includes all fields with independent degrees of freedom 36 // (such as AggregatedApprovalSigs). 37 type Seal struct { 38 BlockID Identifier 39 ResultID Identifier 40 FinalState StateCommitment 41 AggregatedApprovalSigs []AggregatedSignature // one AggregatedSignature per chunk 42 } 43 44 func (s Seal) Body() interface{} { 45 return struct { 46 BlockID Identifier 47 ResultID Identifier 48 FinalState StateCommitment 49 AggregatedApprovalSigs []AggregatedSignature 50 }{ 51 BlockID: s.BlockID, 52 ResultID: s.ResultID, 53 FinalState: s.FinalState, 54 AggregatedApprovalSigs: s.AggregatedApprovalSigs, 55 } 56 } 57 58 func (s Seal) ID() Identifier { 59 return MakeID(s.Body()) 60 } 61 62 func (s Seal) Checksum() Identifier { 63 return MakeID(s) 64 } 65 66 func (s Seal) MarshalJSON() ([]byte, error) { 67 type Alias Seal 68 return json.Marshal(struct { 69 Alias 70 ID string 71 }{ 72 Alias: Alias(s), 73 ID: s.ID().String(), 74 }) 75 }