mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-28 07:36:44 +00:00
* fix: handle checkpoint ordering * create checkpoint verifier, add unit tests * fix: remove mutex * address comment for default checkpoint verifier Co-authored-by: Evgeny Danienko <6655321@bk.ru>
60 lines
1.9 KiB
Go
60 lines
1.9 KiB
Go
package eth
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
"github.com/ethereum/go-ethereum/consensus/bor/heimdall/checkpoint"
|
|
"github.com/ethereum/go-ethereum/log"
|
|
"github.com/ethereum/go-ethereum/rpc"
|
|
)
|
|
|
|
type checkpointVerifier struct {
|
|
verify func(ctx context.Context, handler *ethHandler, checkpoint *checkpoint.Checkpoint) (string, error)
|
|
}
|
|
|
|
func newCheckpointVerifier(verifyFn func(ctx context.Context, handler *ethHandler, checkpoint *checkpoint.Checkpoint) (string, error)) *checkpointVerifier {
|
|
if verifyFn != nil {
|
|
return &checkpointVerifier{verifyFn}
|
|
}
|
|
|
|
verifyFn = func(ctx context.Context, handler *ethHandler, checkpoint *checkpoint.Checkpoint) (string, error) {
|
|
var (
|
|
startBlock = checkpoint.StartBlock.Uint64()
|
|
endBlock = checkpoint.EndBlock.Uint64()
|
|
)
|
|
|
|
// check if we have the checkpoint blocks
|
|
head := handler.ethAPI.BlockNumber()
|
|
if head < hexutil.Uint64(endBlock) {
|
|
log.Debug("Head block behind checkpoint block", "head", head, "checkpoint end block", endBlock)
|
|
return "", errMissingCheckpoint
|
|
}
|
|
|
|
// verify the root hash of checkpoint
|
|
roothash, err := handler.ethAPI.GetRootHash(ctx, startBlock, endBlock)
|
|
if err != nil {
|
|
log.Debug("Failed to get root hash of checkpoint while whitelisting", "err", err)
|
|
return "", errRootHash
|
|
}
|
|
|
|
if roothash != checkpoint.RootHash.String()[2:] {
|
|
log.Warn("Checkpoint root hash mismatch while whitelisting", "expected", checkpoint.RootHash.String()[2:], "got", roothash)
|
|
return "", errCheckpointRootHashMismatch
|
|
}
|
|
|
|
// fetch the end checkpoint block hash
|
|
block, err := handler.ethAPI.GetBlockByNumber(ctx, rpc.BlockNumber(endBlock), false)
|
|
if err != nil {
|
|
log.Debug("Failed to get end block hash of checkpoint while whitelisting", "err", err)
|
|
return "", errEndBlock
|
|
}
|
|
|
|
hash := fmt.Sprintf("%v", block["hash"])
|
|
|
|
return hash, nil
|
|
}
|
|
|
|
return &checkpointVerifier{verifyFn}
|
|
}
|