mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 21:38:05 -05:00
Compare commits
5 Commits
fulu-e2e
...
future-pro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
029b31c21e | ||
|
|
ef7ec31b89 | ||
|
|
308f6adff9 | ||
|
|
d6f6bc18b8 | ||
|
|
11ebb45b61 |
@@ -51,15 +51,15 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *notifyForkcho
|
||||
if !isExecutionBlk {
|
||||
return nil, nil
|
||||
}
|
||||
headPayload, err := headBlk.Body().ExecutionPayload()
|
||||
blockHashFromPayload, err := blocks.BlockHashFromExecutionPayload(headBlk)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get execution payload for head block")
|
||||
log.WithError(err).Error("Could not get block hash for block from payload")
|
||||
return nil, nil
|
||||
}
|
||||
finalizedHash := s.ForkChoicer().FinalizedPayloadBlockHash()
|
||||
justifiedHash := s.ForkChoicer().JustifiedPayloadBlockHash()
|
||||
fcs := &enginev1.ForkchoiceState{
|
||||
HeadBlockHash: headPayload.BlockHash,
|
||||
HeadBlockHash: blockHashFromPayload[:],
|
||||
SafeBlockHash: justifiedHash[:],
|
||||
FinalizedBlockHash: finalizedHash[:],
|
||||
}
|
||||
@@ -78,7 +78,7 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *notifyForkcho
|
||||
forkchoiceUpdatedOptimisticNodeCount.Inc()
|
||||
log.WithFields(logrus.Fields{
|
||||
"headSlot": headBlk.Slot(),
|
||||
"headPayloadBlockHash": fmt.Sprintf("%#x", bytesutil.Trunc(headPayload.BlockHash)),
|
||||
"headPayloadBlockHash": fmt.Sprintf("%#x", bytesutil.Trunc(blockHashFromPayload[:])),
|
||||
"finalizedPayloadBlockHash": fmt.Sprintf("%#x", bytesutil.Trunc(finalizedHash[:])),
|
||||
}).Info("Called fork choice updated with optimistic block")
|
||||
err := s.optimisticCandidateBlock(ctx, headBlk)
|
||||
@@ -153,21 +153,14 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *notifyForkcho
|
||||
return payloadID, nil
|
||||
}
|
||||
|
||||
// getPayloadHash returns the payload hash given the block root.
|
||||
// payloadBlockHashByBeaconBlockRoot returns the payload hash given the block root.
|
||||
// if the block is before bellatrix fork epoch, it returns the zero hash.
|
||||
func (s *Service) getPayloadHash(ctx context.Context, root []byte) ([32]byte, error) {
|
||||
func (s *Service) payloadBlockHashByBeaconBlockRoot(ctx context.Context, root []byte) ([32]byte, error) {
|
||||
blk, err := s.getBlock(ctx, s.ensureRootNotZeros(bytesutil.ToBytes32(root)))
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
if blocks.IsPreBellatrixVersion(blk.Block().Version()) {
|
||||
return params.BeaconConfig().ZeroHash, nil
|
||||
}
|
||||
payload, err := blk.Block().Body().ExecutionPayload()
|
||||
if err != nil {
|
||||
return [32]byte{}, errors.Wrap(err, "could not get execution payload")
|
||||
}
|
||||
return bytesutil.ToBytes32(payload.BlockHash), nil
|
||||
return blocks.BlockHashFromExecutionPayload(blk.Block())
|
||||
}
|
||||
|
||||
// notifyForkchoiceUpdate signals execution engine on a new payload.
|
||||
@@ -258,6 +251,7 @@ func (s *Service) optimisticCandidateBlock(ctx context.Context, blk interfaces.B
|
||||
}
|
||||
parentIsExecutionBlock, err := blocks.IsExecutionBlock(parent.Block().Body())
|
||||
if err != nil {
|
||||
log.Errorf("NOT AN EXECUTION BLOCK: %v", err)
|
||||
return err
|
||||
}
|
||||
if parentIsExecutionBlock {
|
||||
|
||||
@@ -1141,7 +1141,7 @@ func TestService_getPayloadHash(t *testing.T) {
|
||||
service, err := NewService(ctx, opts...)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = service.getPayloadHash(ctx, []byte{})
|
||||
_, err = service.payloadBlockHashByBeaconBlockRoot(ctx, []byte{})
|
||||
require.ErrorIs(t, errBlockNotFoundInCacheOrDB, err)
|
||||
|
||||
b := util.NewBeaconBlock()
|
||||
@@ -1151,7 +1151,7 @@ func TestService_getPayloadHash(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.saveInitSyncBlock(ctx, r, wsb))
|
||||
|
||||
h, err := service.getPayloadHash(ctx, r[:])
|
||||
h, err := service.payloadBlockHashByBeaconBlockRoot(ctx, r[:])
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, params.BeaconConfig().ZeroHash, h)
|
||||
|
||||
@@ -1164,7 +1164,7 @@ func TestService_getPayloadHash(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.saveInitSyncBlock(ctx, r, wsb))
|
||||
|
||||
h, err = service.getPayloadHash(ctx, r[:])
|
||||
h, err = service.payloadBlockHashByBeaconBlockRoot(ctx, r[:])
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, [32]byte{'a'}, h)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
@@ -52,6 +53,14 @@ func logStateTransitionData(b interfaces.BeaconBlock) error {
|
||||
log = log.WithField("payloadHash", fmt.Sprintf("%#x", bytesutil.Trunc(p.BlockHash)))
|
||||
log = log.WithField("txCount", len(p.Transactions))
|
||||
}
|
||||
if b.Version() == version.BellatrixBlind {
|
||||
p, err := b.Body().ExecutionPayloadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log = log.WithField("payloadHash", fmt.Sprintf("%#x", bytesutil.Trunc(p.BlockHash)))
|
||||
log = log.WithField("txsRoot", fmt.Sprintf("%#x", bytesutil.Trunc(p.TransactionsRoot)))
|
||||
}
|
||||
log.Info("Finished applying state transition")
|
||||
return nil
|
||||
}
|
||||
@@ -98,19 +107,47 @@ func logPayload(block interfaces.BeaconBlock) error {
|
||||
if !isExecutionBlk {
|
||||
return nil
|
||||
}
|
||||
var gasLimit, gasUsed float64
|
||||
var blockNum uint64
|
||||
var blockHash, parentHash []byte
|
||||
payload, err := block.Body().ExecutionPayload()
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, wrapper.ErrUnsupportedField):
|
||||
payloadHeader, err := block.Body().ExecutionPayloadHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if payloadHeader == nil {
|
||||
log.Warn("Nil execution payload header in block")
|
||||
return nil
|
||||
}
|
||||
gasLimit = float64(payloadHeader.GasLimit)
|
||||
gasUsed = float64(payloadHeader.GasUsed)
|
||||
blockNum = payloadHeader.BlockNumber
|
||||
blockHash = payloadHeader.BlockHash
|
||||
parentHash = payloadHeader.ParentHash
|
||||
case err != nil:
|
||||
return err
|
||||
default:
|
||||
if payload == nil {
|
||||
log.Warn("Nil execution payload in block")
|
||||
return nil
|
||||
}
|
||||
gasLimit = float64(payload.GasLimit)
|
||||
gasUsed = float64(payload.GasUsed)
|
||||
blockNum = payload.BlockNumber
|
||||
blockHash = payload.BlockHash
|
||||
parentHash = payload.ParentHash
|
||||
}
|
||||
if payload.GasLimit == 0 {
|
||||
if gasLimit == 0 {
|
||||
return errors.New("gas limit should not be 0")
|
||||
}
|
||||
gasUtilized := float64(payload.GasUsed) / float64(payload.GasLimit)
|
||||
gasUtilized := gasUsed / gasLimit
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"blockHash": fmt.Sprintf("%#x", bytesutil.Trunc(payload.BlockHash)),
|
||||
"parentHash": fmt.Sprintf("%#x", bytesutil.Trunc(payload.ParentHash)),
|
||||
"blockNumber": payload.BlockNumber,
|
||||
"blockHash": fmt.Sprintf("%#x", bytesutil.Trunc(blockHash)),
|
||||
"parentHash": fmt.Sprintf("%#x", bytesutil.Trunc(parentHash)),
|
||||
"blockNumber": blockNum,
|
||||
"gasUtilized": fmt.Sprintf("%.2f", gasUtilized),
|
||||
}).Debug("Synced new payload")
|
||||
return nil
|
||||
|
||||
@@ -10,12 +10,12 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||
"github.com/prysmaticlabs/prysm/time/slots"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@@ -41,17 +41,14 @@ func (s *Service) validateMergeBlock(ctx context.Context, b interfaces.SignedBea
|
||||
if err := wrapper.BeaconBlockIsNil(b); err != nil {
|
||||
return err
|
||||
}
|
||||
payload, err := b.Block().Body().ExecutionPayload()
|
||||
parentHashForPayload, err := blocks.ParentBlockHashFromExecutionPayload(b.Block())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if payload == nil {
|
||||
return errors.New("nil execution payload")
|
||||
}
|
||||
if err := validateTerminalBlockHash(b.Block().Slot(), payload); err != nil {
|
||||
if err := validateTerminalBlockHash(b.Block().Slot(), parentHashForPayload[:]); err != nil {
|
||||
return errors.Wrap(err, "could not validate terminal block hash")
|
||||
}
|
||||
mergeBlockParentHash, mergeBlockTD, err := s.getBlkParentHashAndTD(ctx, payload.ParentHash)
|
||||
mergeBlockParentHash, mergeBlockTD, err := s.getBlkParentHashAndTD(ctx, parentHashForPayload[:])
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get merge block parent hash and total difficulty")
|
||||
}
|
||||
@@ -71,7 +68,7 @@ func (s *Service) validateMergeBlock(ctx context.Context, b interfaces.SignedBea
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"slot": b.Block().Slot(),
|
||||
"mergeBlockHash": common.BytesToHash(payload.ParentHash).String(),
|
||||
"mergeBlockHash": common.BytesToHash(parentHashForPayload[:]).String(),
|
||||
"mergeBlockParentHash": common.BytesToHash(mergeBlockParentHash).String(),
|
||||
"terminalTotalDifficulty": params.BeaconConfig().TerminalTotalDifficulty,
|
||||
"mergeBlockTotalDifficulty": mergeBlockTD,
|
||||
@@ -110,14 +107,14 @@ func (s *Service) getBlkParentHashAndTD(ctx context.Context, blkHash []byte) ([]
|
||||
// assert compute_epoch_at_slot(block.slot) >= TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH
|
||||
// assert block.body.execution_payload.parent_hash == TERMINAL_BLOCK_HASH
|
||||
// return
|
||||
func validateTerminalBlockHash(blkSlot types.Slot, payload *enginev1.ExecutionPayload) error {
|
||||
func validateTerminalBlockHash(blkSlot types.Slot, payloadParentHash []byte) error {
|
||||
if bytesutil.ToBytes32(params.BeaconConfig().TerminalBlockHash.Bytes()) == [32]byte{} {
|
||||
return nil
|
||||
}
|
||||
if params.BeaconConfig().TerminalBlockHashActivationEpoch > slots.ToEpoch(blkSlot) {
|
||||
return errors.New("terminal block hash activation epoch not reached")
|
||||
}
|
||||
if !bytes.Equal(payload.ParentHash, params.BeaconConfig().TerminalBlockHash.Bytes()) {
|
||||
if !bytes.Equal(payloadParentHash, params.BeaconConfig().TerminalBlockHash.Bytes()) {
|
||||
return errors.New("parent hash does not match terminal block hash")
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -211,16 +211,16 @@ func Test_getBlkParentHashAndTD(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_validateTerminalBlockHash(t *testing.T) {
|
||||
require.NoError(t, validateTerminalBlockHash(1, &enginev1.ExecutionPayload{}))
|
||||
require.NoError(t, validateTerminalBlockHash(1, make([]byte, 32)))
|
||||
|
||||
cfg := params.BeaconConfig()
|
||||
cfg.TerminalBlockHash = [32]byte{0x01}
|
||||
params.OverrideBeaconConfig(cfg)
|
||||
require.ErrorContains(t, "terminal block hash activation epoch not reached", validateTerminalBlockHash(1, &enginev1.ExecutionPayload{}))
|
||||
require.ErrorContains(t, "terminal block hash activation epoch not reached", validateTerminalBlockHash(1, make([]byte, 32)))
|
||||
|
||||
cfg.TerminalBlockHashActivationEpoch = 0
|
||||
params.OverrideBeaconConfig(cfg)
|
||||
require.ErrorContains(t, "parent hash does not match terminal block hash", validateTerminalBlockHash(1, &enginev1.ExecutionPayload{}))
|
||||
require.ErrorContains(t, "parent hash does not match terminal block hash", validateTerminalBlockHash(1, make([]byte, 32)))
|
||||
|
||||
require.NoError(t, validateTerminalBlockHash(1, &enginev1.ExecutionPayload{ParentHash: cfg.TerminalBlockHash.Bytes()}))
|
||||
require.NoError(t, validateTerminalBlockHash(1, cfg.TerminalBlockHash.Bytes()))
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNilPayload = errors.New("nil execution payload")
|
||||
ErrInvalidPayloadBlockHash = errors.New("invalid payload block hash")
|
||||
ErrInvalidPayloadTimeStamp = errors.New("invalid payload timestamp")
|
||||
ErrInvalidPayloadPrevRandao = errors.New("invalid payload previous randao")
|
||||
@@ -67,7 +68,11 @@ func IsExecutionBlock(body interfaces.BeaconBlockBody) (bool, error) {
|
||||
payload, err := body.ExecutionPayload()
|
||||
switch {
|
||||
case errors.Is(err, wrapper.ErrUnsupportedField):
|
||||
return false, nil
|
||||
payloadHeader, err := body.ExecutionPayloadHeader()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return !bellatrix.IsEmptyHeader(payloadHeader), nil
|
||||
case err != nil:
|
||||
return false, err
|
||||
default:
|
||||
@@ -272,15 +277,60 @@ func ProcessPayloadHeader(st state.BeaconState, header *enginev1.ExecutionPayloa
|
||||
return st, nil
|
||||
}
|
||||
|
||||
// GetBlockPayloadHash returns the hash of the execution payload of the block
|
||||
func GetBlockPayloadHash(blk interfaces.BeaconBlock) ([32]byte, error) {
|
||||
payloadHash := [32]byte{}
|
||||
// BlockHashFromExecutionPayload reads the block hash field from an execution payload or
|
||||
// execution payload header contained within a specified beacon block's body.
|
||||
func BlockHashFromExecutionPayload(blk interfaces.BeaconBlock) ([32]byte, error) {
|
||||
var blockHashFromPayload [32]byte
|
||||
if IsPreBellatrixVersion(blk.Version()) {
|
||||
return payloadHash, nil
|
||||
return blockHashFromPayload, nil
|
||||
}
|
||||
payload, err := blk.Body().ExecutionPayload()
|
||||
if err != nil {
|
||||
return payloadHash, err
|
||||
switch {
|
||||
case errors.Is(err, wrapper.ErrUnsupportedField):
|
||||
payloadHeader, err := blk.Body().ExecutionPayloadHeader()
|
||||
if err != nil {
|
||||
return blockHashFromPayload, err
|
||||
}
|
||||
if payloadHeader == nil {
|
||||
return blockHashFromPayload, ErrNilPayload
|
||||
}
|
||||
blockHashFromPayload = bytesutil.ToBytes32(payloadHeader.BlockHash)
|
||||
case err != nil:
|
||||
return blockHashFromPayload, err
|
||||
default:
|
||||
if payload == nil {
|
||||
return blockHashFromPayload, ErrNilPayload
|
||||
}
|
||||
blockHashFromPayload = bytesutil.ToBytes32(payload.BlockHash)
|
||||
}
|
||||
return bytesutil.ToBytes32(payload.BlockHash), nil
|
||||
return blockHashFromPayload, nil
|
||||
}
|
||||
|
||||
// ParentBlockHashFromExecutionPayload reads the parent hash field from an execution
|
||||
// payload or execution payload header contained within a specified beacon block's body.
|
||||
func ParentBlockHashFromExecutionPayload(blk interfaces.BeaconBlock) ([32]byte, error) {
|
||||
var parentHashFromPayload [32]byte
|
||||
if IsPreBellatrixVersion(blk.Version()) {
|
||||
return parentHashFromPayload, nil
|
||||
}
|
||||
payload, err := blk.Body().ExecutionPayload()
|
||||
switch {
|
||||
case errors.Is(err, wrapper.ErrUnsupportedField):
|
||||
payloadHeader, err := blk.Body().ExecutionPayloadHeader()
|
||||
if err != nil {
|
||||
return parentHashFromPayload, err
|
||||
}
|
||||
if payloadHeader == nil {
|
||||
return parentHashFromPayload, ErrNilPayload
|
||||
}
|
||||
parentHashFromPayload = bytesutil.ToBytes32(payloadHeader.ParentHash)
|
||||
case err != nil:
|
||||
return parentHashFromPayload, err
|
||||
default:
|
||||
if payload == nil {
|
||||
return parentHashFromPayload, ErrNilPayload
|
||||
}
|
||||
parentHashFromPayload = bytesutil.ToBytes32(payload.ParentHash)
|
||||
}
|
||||
return parentHashFromPayload, nil
|
||||
}
|
||||
|
||||
@@ -549,7 +549,7 @@ func (f *ForkChoice) InsertOptimisticChain(ctx context.Context, chain []*forkcho
|
||||
b := chain[i].Block
|
||||
r := bytesutil.ToBytes32(chain[i-1].Block.ParentRoot())
|
||||
parentRoot := bytesutil.ToBytes32(b.ParentRoot())
|
||||
payloadHash, err := blocks.GetBlockPayloadHash(b)
|
||||
payloadHash, err := blocks.BlockHashFromExecutionPayload(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -994,7 +994,7 @@ func (f *ForkChoice) InsertOptimisticChain(ctx context.Context, chain []*forkcho
|
||||
b := chain[i].Block
|
||||
r := bytesutil.ToBytes32(chain[i-1].Block.ParentRoot())
|
||||
parentRoot := bytesutil.ToBytes32(b.ParentRoot())
|
||||
payloadHash, err := blocks.GetBlockPayloadHash(b)
|
||||
payloadHash, err := blocks.BlockHashFromExecutionPayload(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user