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