github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/state/cluster/badger/state_root.go (about)

     1  package badger
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/onflow/flow-go/model/cluster"
     7  	"github.com/onflow/flow-go/model/flow"
     8  )
     9  
    10  // StateRoot is the root information required to bootstrap the cluster state.
    11  type StateRoot struct {
    12  	block *cluster.Block          // root block for the cluster chain
    13  	qc    *flow.QuorumCertificate // root QC for the cluster chain
    14  	epoch uint64                  // operating epoch for the cluster chain
    15  }
    16  
    17  func NewStateRoot(genesis *cluster.Block, qc *flow.QuorumCertificate, epoch uint64) (*StateRoot, error) {
    18  	err := validateClusterGenesis(genesis)
    19  	if err != nil {
    20  		return nil, fmt.Errorf("inconsistent state root: %w", err)
    21  	}
    22  	return &StateRoot{
    23  		block: genesis,
    24  		qc:    qc,
    25  		epoch: epoch,
    26  	}, nil
    27  }
    28  
    29  func validateClusterGenesis(genesis *cluster.Block) error {
    30  	// check height of genesis block
    31  	if genesis.Header.Height != 0 {
    32  		return fmt.Errorf("height of genesis cluster block should be 0 (got %d)", genesis.Header.Height)
    33  	}
    34  	// check header parent ID
    35  	if genesis.Header.ParentID != flow.ZeroID {
    36  		return fmt.Errorf("genesis parent ID must be zero hash (got %x)", genesis.Header.ParentID)
    37  	}
    38  
    39  	// check payload integrity
    40  	if genesis.Header.PayloadHash != genesis.Payload.Hash() {
    41  		return fmt.Errorf("computed payload hash does not match header")
    42  	}
    43  
    44  	// check payload
    45  	collSize := len(genesis.Payload.Collection.Transactions)
    46  	if collSize != 0 {
    47  		return fmt.Errorf("genesis collection should contain no transactions (got %d)", collSize)
    48  	}
    49  
    50  	return nil
    51  }
    52  
    53  func (s StateRoot) ClusterID() flow.ChainID {
    54  	return s.block.Header.ChainID
    55  }
    56  
    57  func (s StateRoot) Block() *cluster.Block {
    58  	return s.block
    59  }
    60  
    61  func (s StateRoot) QC() *flow.QuorumCertificate {
    62  	return s.qc
    63  }
    64  
    65  func (s StateRoot) EpochCounter() uint64 {
    66  	return s.epoch
    67  }