Compare commits

...

5 Commits

Author SHA1 Message Date
Raul Jordan
029b31c21e rem deadcode 2022-07-11 14:05:59 -04:00
Raul Jordan
ef7ec31b89 build 2022-07-11 13:58:29 -04:00
Raul Jordan
308f6adff9 gaz 2022-07-11 13:31:36 -04:00
Raul Jordan
d6f6bc18b8 refactor payload funcs 2022-07-11 13:22:32 -04:00
Raul Jordan
11ebb45b61 work with both blinded and full blocks to get payload block hash 2022-07-11 12:20:43 -04:00
8 changed files with 125 additions and 47 deletions

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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

View File

@@ -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()))
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}