github.com/MetalBlockchain/subnet-evm@v0.4.9/plugin/evm/message/syncable.go (about)

     1  // (c) 2021-2022, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package message
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"github.com/MetalBlockchain/metalgo/ids"
    11  	"github.com/ethereum/go-ethereum/common"
    12  	"github.com/ethereum/go-ethereum/crypto"
    13  
    14  	"github.com/MetalBlockchain/metalgo/snow/engine/snowman/block"
    15  )
    16  
    17  var _ block.StateSummary = &SyncSummary{}
    18  
    19  // SyncSummary provides the information necessary to sync a node starting
    20  // at the given block.
    21  type SyncSummary struct {
    22  	BlockNumber uint64      `serialize:"true"`
    23  	BlockHash   common.Hash `serialize:"true"`
    24  	BlockRoot   common.Hash `serialize:"true"`
    25  
    26  	summaryID  ids.ID
    27  	bytes      []byte
    28  	acceptImpl func(SyncSummary) (block.StateSyncMode, error)
    29  }
    30  
    31  func NewSyncSummaryFromBytes(summaryBytes []byte, acceptImpl func(SyncSummary) (block.StateSyncMode, error)) (SyncSummary, error) {
    32  	summary := SyncSummary{}
    33  	if codecVersion, err := Codec.Unmarshal(summaryBytes, &summary); err != nil {
    34  		return SyncSummary{}, err
    35  	} else if codecVersion != Version {
    36  		return SyncSummary{}, fmt.Errorf("failed to parse syncable summary due to unexpected codec version (%d != %d)", codecVersion, Version)
    37  	}
    38  
    39  	summary.bytes = summaryBytes
    40  	summaryID, err := ids.ToID(crypto.Keccak256(summaryBytes))
    41  	if err != nil {
    42  		return SyncSummary{}, err
    43  	}
    44  	summary.summaryID = summaryID
    45  	summary.acceptImpl = acceptImpl
    46  	return summary, nil
    47  }
    48  
    49  func NewSyncSummary(blockHash common.Hash, blockNumber uint64, blockRoot common.Hash) (SyncSummary, error) {
    50  	summary := SyncSummary{
    51  		BlockNumber: blockNumber,
    52  		BlockHash:   blockHash,
    53  		BlockRoot:   blockRoot,
    54  	}
    55  	bytes, err := Codec.Marshal(Version, &summary)
    56  	if err != nil {
    57  		return SyncSummary{}, err
    58  	}
    59  
    60  	summary.bytes = bytes
    61  	summaryID, err := ids.ToID(crypto.Keccak256(bytes))
    62  	if err != nil {
    63  		return SyncSummary{}, err
    64  	}
    65  	summary.summaryID = summaryID
    66  
    67  	return summary, nil
    68  }
    69  
    70  func (s SyncSummary) Bytes() []byte {
    71  	return s.bytes
    72  }
    73  
    74  func (s SyncSummary) Height() uint64 {
    75  	return s.BlockNumber
    76  }
    77  
    78  func (s SyncSummary) ID() ids.ID {
    79  	return s.summaryID
    80  }
    81  
    82  func (s SyncSummary) String() string {
    83  	return fmt.Sprintf("SyncSummary(BlockHash=%s, BlockNumber=%d, BlockRoot=%s)", s.BlockHash, s.BlockNumber, s.BlockRoot)
    84  }
    85  
    86  func (s SyncSummary) Accept(context.Context) (block.StateSyncMode, error) {
    87  	if s.acceptImpl == nil {
    88  		return block.StateSyncSkipped, fmt.Errorf("accept implementation not specified for summary: %s", s)
    89  	}
    90  	return s.acceptImpl(s)
    91  }