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  }