2022-02-07 01:26:20 +00:00
package blockchain
import (
"context"
2023-07-10 19:02:44 +00:00
"crypto/sha256"
2022-03-01 16:43:06 +00:00
"fmt"
2022-02-07 01:26:20 +00:00
2023-08-08 22:49:06 +00:00
"github.com/ethereum/go-ethereum/common"
2022-02-10 22:18:42 +00:00
"github.com/pkg/errors"
2024-02-15 05:46:47 +00:00
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/execution"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
"github.com/prysmaticlabs/prysm/v5/config/features"
"github.com/prysmaticlabs/prysm/v5/config/params"
consensusblocks "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
payloadattribute "github.com/prysmaticlabs/prysm/v5/consensus-types/payload-attribute"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/time/slots"
2022-03-01 16:43:06 +00:00
"github.com/sirupsen/logrus"
2022-03-23 22:17:09 +00:00
"go.opencensus.io/trace"
2022-02-07 01:26:20 +00:00
)
2023-08-03 20:35:30 +00:00
const blobCommitmentVersionKZG uint8 = 0x01
2022-07-28 16:46:50 +00:00
var defaultLatestValidHash = bytesutil . PadTo ( [ ] byte { 0xff } , 32 )
2022-03-01 16:43:06 +00:00
// notifyForkchoiceUpdate signals execution engine the fork choice updates. Execution engine should:
// 1. Re-organizes the execution payload chain and corresponding state to make head_block_hash the head.
// 2. Applies finality to the execution state: it irreversibly persists the chain of all execution payloads and corresponding state, up to and including finalized_block_hash.
2024-01-02 22:45:55 +00:00
func ( s * Service ) notifyForkchoiceUpdate ( ctx context . Context , arg * fcuConfig ) ( * enginev1 . PayloadIDBytes , error ) {
2022-03-23 22:17:09 +00:00
ctx , span := trace . StartSpan ( ctx , "blockChain.notifyForkchoiceUpdate" )
defer span . End ( )
2024-01-02 22:45:55 +00:00
if arg . headBlock . IsNil ( ) {
log . Error ( "Head block is nil" )
return nil , nil
}
headBlk := arg . headBlock . Block ( )
2022-03-01 16:43:06 +00:00
if headBlk == nil || headBlk . IsNil ( ) || headBlk . Body ( ) . IsNil ( ) {
2022-07-09 20:51:03 +00:00
log . Error ( "Head block is nil" )
return nil , nil
2022-03-01 16:43:06 +00:00
}
// Must not call fork choice updated until the transition conditions are met on the Pow network.
2022-03-28 15:25:49 +00:00
isExecutionBlk , err := blocks . IsExecutionBlock ( headBlk . Body ( ) )
2022-03-01 16:43:06 +00:00
if err != nil {
2022-07-09 20:51:03 +00:00
log . WithError ( err ) . Error ( "Could not determine if head block is execution block" )
return nil , nil
2022-03-01 16:43:06 +00:00
}
if ! isExecutionBlk {
return nil , nil
}
2022-07-13 01:49:38 +00:00
headPayload , err := headBlk . Body ( ) . Execution ( )
2022-03-01 16:43:06 +00:00
if err != nil {
2022-07-09 20:51:03 +00:00
log . WithError ( err ) . Error ( "Could not get execution payload for head block" )
return nil , nil
2022-03-01 16:43:06 +00:00
}
2023-03-22 01:12:54 +00:00
finalizedHash := s . cfg . ForkChoiceStore . FinalizedPayloadBlockHash ( )
2023-04-20 15:59:12 +00:00
justifiedHash := s . cfg . ForkChoiceStore . UnrealizedJustifiedPayloadBlockHash ( )
2022-03-01 16:43:06 +00:00
fcs := & enginev1 . ForkchoiceState {
2022-07-13 01:49:38 +00:00
HeadBlockHash : headPayload . BlockHash ( ) ,
2022-05-10 21:20:28 +00:00
SafeBlockHash : justifiedHash [ : ] ,
FinalizedBlockHash : finalizedHash [ : ] ,
2022-03-01 16:43:06 +00:00
}
2024-01-02 17:37:18 +00:00
if arg . attributes == nil {
arg . attributes = payloadattribute . EmptyWithVersion ( headBlk . Version ( ) )
}
payloadID , lastValidHash , err := s . cfg . ExecutionEngineCaller . ForkchoiceUpdated ( ctx , fcs , arg . attributes )
2022-03-01 16:43:06 +00:00
if err != nil {
switch err {
2022-08-01 14:43:47 +00:00
case execution . ErrAcceptedSyncingPayloadStatus :
2022-04-12 09:51:13 +00:00
forkchoiceUpdatedOptimisticNodeCount . Inc ( )
2022-03-01 16:43:06 +00:00
log . WithFields ( logrus . Fields {
2022-04-09 23:09:04 +00:00
"headSlot" : headBlk . Slot ( ) ,
2022-07-13 01:49:38 +00:00
"headPayloadBlockHash" : fmt . Sprintf ( "%#x" , bytesutil . Trunc ( headPayload . BlockHash ( ) ) ) ,
2022-05-10 21:20:28 +00:00
"finalizedPayloadBlockHash" : fmt . Sprintf ( "%#x" , bytesutil . Trunc ( finalizedHash [ : ] ) ) ,
2022-03-01 16:43:06 +00:00
} ) . Info ( "Called fork choice updated with optimistic block" )
2022-07-09 20:51:03 +00:00
return payloadID , nil
2022-08-01 14:43:47 +00:00
case execution . ErrInvalidPayloadStatus :
2022-08-31 22:05:50 +00:00
forkchoiceUpdatedInvalidNodeCount . Inc ( )
2022-05-05 00:36:09 +00:00
headRoot := arg . headRoot
2022-07-28 16:46:50 +00:00
if len ( lastValidHash ) == 0 {
lastValidHash = defaultLatestValidHash
}
2023-03-22 01:12:54 +00:00
invalidRoots , err := s . cfg . ForkChoiceStore . SetOptimisticToInvalid ( ctx , headRoot , headBlk . ParentRoot ( ) , bytesutil . ToBytes32 ( lastValidHash ) )
2022-05-03 03:48:58 +00:00
if err != nil {
2022-07-09 20:51:03 +00:00
log . WithError ( err ) . Error ( "Could not set head root to invalid" )
return nil , nil
2022-05-03 03:48:58 +00:00
}
if err := s . removeInvalidBlockAndState ( ctx , invalidRoots ) ; err != nil {
2022-07-09 20:51:03 +00:00
log . WithError ( err ) . Error ( "Could not remove invalid block and state" )
return nil , nil
2022-05-03 03:48:58 +00:00
}
2022-05-10 20:02:00 +00:00
2023-02-15 14:19:46 +00:00
r , err := s . cfg . ForkChoiceStore . Head ( ctx )
2022-05-10 20:02:00 +00:00
if err != nil {
2022-08-02 14:55:05 +00:00
log . WithFields ( logrus . Fields {
2022-09-06 14:04:32 +00:00
"slot" : headBlk . Slot ( ) ,
"blockRoot" : fmt . Sprintf ( "%#x" , bytesutil . Trunc ( headRoot [ : ] ) ) ,
"invalidChildrenCount" : len ( invalidRoots ) ,
2022-08-02 14:55:05 +00:00
} ) . Warn ( "Pruned invalid blocks, could not update head root" )
return nil , invalidBlock { error : ErrInvalidPayload , root : arg . headRoot , invalidAncestorRoots : invalidRoots }
2022-05-10 20:02:00 +00:00
}
b , err := s . getBlock ( ctx , r )
if err != nil {
2022-07-09 20:51:03 +00:00
log . WithError ( err ) . Error ( "Could not get head block" )
return nil , nil
2022-05-10 20:02:00 +00:00
}
st , err := s . cfg . StateGen . StateByRoot ( ctx , r )
if err != nil {
2022-07-09 20:51:03 +00:00
log . WithError ( err ) . Error ( "Could not get head state" )
return nil , nil
2022-05-10 20:02:00 +00:00
}
2024-01-02 22:45:55 +00:00
pid , err := s . notifyForkchoiceUpdate ( ctx , & fcuConfig {
2024-01-02 17:37:18 +00:00
headState : st ,
headRoot : r ,
2024-01-02 22:45:55 +00:00
headBlock : b ,
2024-01-02 17:37:18 +00:00
attributes : arg . attributes ,
2022-05-10 20:02:00 +00:00
} )
if err != nil {
2022-07-09 20:51:03 +00:00
return nil , err // Returning err because it's recursive here.
2022-05-10 20:02:00 +00:00
}
2022-07-02 16:38:08 +00:00
if err := s . saveHead ( ctx , r , b , st ) ; err != nil {
log . WithError ( err ) . Error ( "could not save head after pruning invalid blocks" )
}
2022-05-03 03:48:58 +00:00
log . WithFields ( logrus . Fields {
2022-09-06 14:04:32 +00:00
"slot" : headBlk . Slot ( ) ,
"blockRoot" : fmt . Sprintf ( "%#x" , bytesutil . Trunc ( headRoot [ : ] ) ) ,
"invalidChildrenCount" : len ( invalidRoots ) ,
"newHeadRoot" : fmt . Sprintf ( "%#x" , bytesutil . Trunc ( r [ : ] ) ) ,
2022-05-03 03:48:58 +00:00
} ) . Warn ( "Pruned invalid blocks" )
2022-07-25 13:45:03 +00:00
return pid , invalidBlock { error : ErrInvalidPayload , root : arg . headRoot , invalidAncestorRoots : invalidRoots }
2022-05-10 20:02:00 +00:00
2022-03-01 16:43:06 +00:00
default :
2022-07-09 20:51:03 +00:00
log . WithError ( err ) . Error ( ErrUndefinedExecutionEngineError )
return nil , nil
2022-03-01 16:43:06 +00:00
}
}
2022-04-12 09:51:13 +00:00
forkchoiceUpdatedValidNodeCount . Inc ( )
2022-05-05 00:36:09 +00:00
if err := s . cfg . ForkChoiceStore . SetOptimisticToValid ( ctx , arg . headRoot ) ; err != nil {
2022-07-09 20:51:03 +00:00
log . WithError ( err ) . Error ( "Could not set head root to valid" )
return nil , nil
2022-03-14 17:25:40 +00:00
}
2023-12-22 18:47:51 +00:00
// If the forkchoice update call has an attribute, update the payload ID cache.
2024-01-02 17:37:18 +00:00
hasAttr := arg . attributes != nil && ! arg . attributes . IsEmpty ( )
nextSlot := s . CurrentSlot ( ) + 1
2022-12-08 21:39:45 +00:00
if hasAttr && payloadID != nil {
2022-04-06 23:36:52 +00:00
var pId [ 8 ] byte
copy ( pId [ : ] , payloadID [ : ] )
2023-10-30 12:30:20 +00:00
log . WithFields ( logrus . Fields {
"blockRoot" : fmt . Sprintf ( "%#x" , bytesutil . Trunc ( arg . headRoot [ : ] ) ) ,
2023-10-30 19:56:20 +00:00
"headSlot" : headBlk . Slot ( ) ,
2023-10-30 12:30:20 +00:00
"payloadID" : fmt . Sprintf ( "%#x" , bytesutil . Trunc ( payloadID [ : ] ) ) ,
} ) . Info ( "Forkchoice updated with payload attributes for proposal" )
2023-12-22 18:47:51 +00:00
s . cfg . PayloadIDCache . Set ( nextSlot , arg . headRoot , pId )
2023-06-16 17:01:57 +00:00
} else if hasAttr && payloadID == nil && ! features . Get ( ) . PrepareAllPayloads {
2022-07-13 12:49:40 +00:00
log . WithFields ( logrus . Fields {
"blockHash" : fmt . Sprintf ( "%#x" , headPayload . BlockHash ( ) ) ,
"slot" : headBlk . Slot ( ) ,
} ) . Error ( "Received nil payload ID on VALID engine response" )
2022-04-06 23:36:52 +00:00
}
2022-03-01 16:43:06 +00:00
return payloadID , nil
}
2022-05-05 00:36:09 +00:00
// getPayloadHash returns the payload hash given the block root.
// if the block is before bellatrix fork epoch, it returns the zero hash.
2022-05-10 21:20:28 +00:00
func ( s * Service ) getPayloadHash ( ctx context . Context , root [ ] byte ) ( [ 32 ] byte , error ) {
blk , err := s . getBlock ( ctx , s . ensureRootNotZeros ( bytesutil . ToBytes32 ( root ) ) )
2022-05-05 00:36:09 +00:00
if err != nil {
2022-05-10 21:20:28 +00:00
return [ 32 ] byte { } , err
2022-05-05 00:36:09 +00:00
}
2022-05-10 21:20:28 +00:00
if blocks . IsPreBellatrixVersion ( blk . Block ( ) . Version ( ) ) {
return params . BeaconConfig ( ) . ZeroHash , nil
2022-05-05 00:36:09 +00:00
}
2022-07-13 01:49:38 +00:00
payload , err := blk . Block ( ) . Body ( ) . Execution ( )
2022-05-05 00:36:09 +00:00
if err != nil {
2022-05-10 21:20:28 +00:00
return [ 32 ] byte { } , errors . Wrap ( err , "could not get execution payload" )
2022-05-05 00:36:09 +00:00
}
2022-07-13 01:49:38 +00:00
return bytesutil . ToBytes32 ( payload . BlockHash ( ) ) , nil
2022-05-05 00:36:09 +00:00
}
2022-10-28 16:17:56 +00:00
// notifyNewPayload signals execution engine on a new payload.
2022-03-31 12:17:49 +00:00
// It returns true if the EL has returned VALID for the block
2023-07-05 13:12:21 +00:00
func ( s * Service ) notifyNewPayload ( ctx context . Context , preStateVersion int ,
preStateHeader interfaces . ExecutionData , blk interfaces . ReadOnlySignedBeaconBlock ) ( bool , error ) {
2022-03-23 22:17:09 +00:00
ctx , span := trace . StartSpan ( ctx , "blockChain.notifyNewPayload" )
defer span . End ( )
2022-03-22 03:35:02 +00:00
// Execution payload is only supported in Bellatrix and beyond. Pre
// merge blocks are never optimistic
2023-07-05 13:12:21 +00:00
if blk == nil {
return false , errors . New ( "signed beacon block can't be nil" )
}
if preStateVersion < version . Bellatrix {
2022-03-31 12:17:49 +00:00
return true , nil
2022-03-01 16:43:06 +00:00
}
2022-08-02 15:30:46 +00:00
if err := consensusblocks . BeaconBlockIsNil ( blk ) ; err != nil {
2022-03-31 12:17:49 +00:00
return false , err
2022-03-01 16:43:06 +00:00
}
body := blk . Block ( ) . Body ( )
2023-07-05 13:12:21 +00:00
enabled , err := blocks . IsExecutionEnabledUsingHeader ( preStateHeader , body )
2022-03-01 16:43:06 +00:00
if err != nil {
2022-07-09 20:51:03 +00:00
return false , errors . Wrap ( invalidBlock { error : err } , "could not determine if execution is enabled" )
2022-03-01 16:43:06 +00:00
}
if ! enabled {
2022-03-31 12:17:49 +00:00
return true , nil
2022-03-01 16:43:06 +00:00
}
2022-07-13 01:49:38 +00:00
payload , err := body . Execution ( )
2022-03-01 16:43:06 +00:00
if err != nil {
2022-07-09 20:51:03 +00:00
return false , errors . Wrap ( invalidBlock { error : err } , "could not get execution payload" )
2022-03-01 16:43:06 +00:00
}
2023-05-26 18:09:16 +00:00
var lastValidHash [ ] byte
if blk . Version ( ) >= version . Deneb {
2023-08-08 22:49:06 +00:00
var versionedHashes [ ] common . Hash
2023-08-03 20:35:30 +00:00
versionedHashes , err = kzgCommitmentsToVersionedHashes ( blk . Block ( ) . Body ( ) )
2023-05-26 18:09:16 +00:00
if err != nil {
2023-08-03 20:35:30 +00:00
return false , errors . Wrap ( err , "could not get versioned hashes to feed the engine" )
2023-07-10 19:02:44 +00:00
}
2023-08-08 22:49:06 +00:00
pr := common . Hash ( blk . Block ( ) . ParentRoot ( ) )
lastValidHash , err = s . cfg . ExecutionEngineCaller . NewPayload ( ctx , payload , versionedHashes , & pr )
2023-05-26 18:09:16 +00:00
} else {
2023-08-08 22:49:06 +00:00
lastValidHash , err = s . cfg . ExecutionEngineCaller . NewPayload ( ctx , payload , [ ] common . Hash { } , & common . Hash { } /*empty version hashes and root before Deneb*/ )
2023-05-26 18:09:16 +00:00
}
2022-04-23 08:11:15 +00:00
switch err {
case nil :
newPayloadValidNodeCount . Inc ( )
2022-03-31 12:17:49 +00:00
return true , nil
2022-08-01 14:43:47 +00:00
case execution . ErrAcceptedSyncingPayloadStatus :
2022-04-23 08:11:15 +00:00
newPayloadOptimisticNodeCount . Inc ( )
log . WithFields ( logrus . Fields {
"slot" : blk . Block ( ) . Slot ( ) ,
2022-07-13 01:49:38 +00:00
"payloadBlockHash" : fmt . Sprintf ( "%#x" , bytesutil . Trunc ( payload . BlockHash ( ) ) ) ,
2022-04-23 08:11:15 +00:00
} ) . Info ( "Called new payload with optimistic block" )
2022-09-16 16:05:30 +00:00
return false , nil
2022-08-01 14:43:47 +00:00
case execution . ErrInvalidPayloadStatus :
2023-06-28 13:38:24 +00:00
lvh := bytesutil . ToBytes32 ( lastValidHash )
2022-07-25 13:45:03 +00:00
return false , invalidBlock {
2023-06-28 13:38:24 +00:00
error : ErrInvalidPayload ,
lastValidHash : lvh ,
2022-07-25 13:45:03 +00:00
}
2022-04-23 08:11:15 +00:00
default :
2022-04-25 18:41:35 +00:00
return false , errors . WithMessage ( ErrUndefinedExecutionEngineError , err . Error ( ) )
2022-03-01 16:43:06 +00:00
}
}
2023-06-28 13:38:24 +00:00
// reportInvalidBlock deals with the event that an invalid block was detected by the execution layer
2023-07-05 13:12:21 +00:00
func ( s * Service ) pruneInvalidBlock ( ctx context . Context , root , parentRoot , lvh [ 32 ] byte ) error {
2023-06-28 13:38:24 +00:00
newPayloadInvalidNodeCount . Inc ( )
2023-07-05 13:12:21 +00:00
invalidRoots , err := s . SetOptimisticToInvalid ( ctx , root , parentRoot , lvh )
2023-06-28 13:38:24 +00:00
if err != nil {
return err
}
if err := s . removeInvalidBlockAndState ( ctx , invalidRoots ) ; err != nil {
return err
}
log . WithFields ( logrus . Fields {
"blockRoot" : fmt . Sprintf ( "%#x" , root ) ,
"invalidChildrenCount" : len ( invalidRoots ) ,
} ) . Warn ( "Pruned invalid blocks" )
return invalidBlock {
invalidAncestorRoots : invalidRoots ,
error : ErrInvalidPayload ,
lastValidHash : lvh ,
}
}
2022-04-06 23:36:52 +00:00
// getPayloadAttributes returns the payload attributes for the given state and slot.
// The attribute is required to initiate a payload build process in the context of an `engine_forkchoiceUpdated` call.
2024-01-02 22:45:55 +00:00
func ( s * Service ) getPayloadAttribute ( ctx context . Context , st state . BeaconState , slot primitives . Slot , headRoot [ ] byte ) payloadattribute . Attributer {
2022-12-08 21:39:45 +00:00
emptyAttri := payloadattribute . EmptyWithVersion ( st . Version ( ) )
2023-12-22 18:47:51 +00:00
2023-12-28 15:19:09 +00:00
// If it is an epoch boundary then process slots to get the right
// shuffling before checking if the proposer is tracked. Otherwise
// perform this check before. This is cheap as the NSC has already been updated.
var val cache . TrackedValidator
var ok bool
e := slots . ToEpoch ( slot )
stateEpoch := slots . ToEpoch ( st . Slot ( ) )
if e == stateEpoch {
val , ok = s . trackedProposer ( st , slot )
if ! ok {
2024-01-02 22:45:55 +00:00
return emptyAttri
2023-12-28 15:19:09 +00:00
}
2022-04-06 23:36:52 +00:00
}
st = st . Copy ( )
2023-04-25 23:13:24 +00:00
if slot > st . Slot ( ) {
var err error
st , err = transition . ProcessSlotsUsingNextSlotCache ( ctx , st , headRoot , slot )
if err != nil {
log . WithError ( err ) . Error ( "Could not process slots to get payload attribute" )
2024-01-02 22:45:55 +00:00
return emptyAttri
2023-04-25 23:13:24 +00:00
}
2022-04-06 23:36:52 +00:00
}
2023-12-28 15:19:09 +00:00
if e > stateEpoch {
2024-01-02 22:45:55 +00:00
emptyAttri := payloadattribute . EmptyWithVersion ( st . Version ( ) )
2023-12-28 15:19:09 +00:00
val , ok = s . trackedProposer ( st , slot )
if ! ok {
2024-01-02 22:45:55 +00:00
return emptyAttri
2023-12-28 15:19:09 +00:00
}
}
// Get previous randao.
2022-04-06 23:36:52 +00:00
prevRando , err := helpers . RandaoMix ( st , time . CurrentEpoch ( st ) )
if err != nil {
2022-12-08 21:39:45 +00:00
log . WithError ( err ) . Error ( "Could not get randao mix to get payload attribute" )
2024-01-02 22:45:55 +00:00
return emptyAttri
2022-04-06 23:36:52 +00:00
}
// Get timestamp.
t , err := slots . ToTime ( uint64 ( s . genesisTime . Unix ( ) ) , slot )
if err != nil {
2022-12-08 21:39:45 +00:00
log . WithError ( err ) . Error ( "Could not get timestamp to get payload attribute" )
2024-01-02 22:45:55 +00:00
return emptyAttri
2022-04-06 23:36:52 +00:00
}
2022-12-08 21:39:45 +00:00
var attr payloadattribute . Attributer
switch st . Version ( ) {
2023-08-08 22:49:06 +00:00
case version . Deneb :
withdrawals , err := st . ExpectedWithdrawals ( )
if err != nil {
log . WithError ( err ) . Error ( "Could not get expected withdrawals to get payload attribute" )
2024-01-02 22:45:55 +00:00
return emptyAttri
2023-08-08 22:49:06 +00:00
}
attr , err = payloadattribute . New ( & enginev1 . PayloadAttributesV3 {
Timestamp : uint64 ( t . Unix ( ) ) ,
PrevRandao : prevRando ,
2023-12-22 18:47:51 +00:00
SuggestedFeeRecipient : val . FeeRecipient [ : ] ,
2023-08-08 22:49:06 +00:00
Withdrawals : withdrawals ,
ParentBeaconBlockRoot : headRoot ,
} )
if err != nil {
log . WithError ( err ) . Error ( "Could not get payload attribute" )
2024-01-02 22:45:55 +00:00
return emptyAttri
2023-08-08 22:49:06 +00:00
}
case version . Capella :
2022-12-08 21:39:45 +00:00
withdrawals , err := st . ExpectedWithdrawals ( )
if err != nil {
log . WithError ( err ) . Error ( "Could not get expected withdrawals to get payload attribute" )
2024-01-02 22:45:55 +00:00
return emptyAttri
2022-12-08 21:39:45 +00:00
}
attr , err = payloadattribute . New ( & enginev1 . PayloadAttributesV2 {
Timestamp : uint64 ( t . Unix ( ) ) ,
PrevRandao : prevRando ,
2023-12-22 18:47:51 +00:00
SuggestedFeeRecipient : val . FeeRecipient [ : ] ,
2022-12-08 21:39:45 +00:00
Withdrawals : withdrawals ,
} )
if err != nil {
log . WithError ( err ) . Error ( "Could not get payload attribute" )
2024-01-02 22:45:55 +00:00
return emptyAttri
2022-12-08 21:39:45 +00:00
}
case version . Bellatrix :
attr , err = payloadattribute . New ( & enginev1 . PayloadAttributes {
Timestamp : uint64 ( t . Unix ( ) ) ,
PrevRandao : prevRando ,
2023-12-22 18:47:51 +00:00
SuggestedFeeRecipient : val . FeeRecipient [ : ] ,
2022-12-08 21:39:45 +00:00
} )
if err != nil {
log . WithError ( err ) . Error ( "Could not get payload attribute" )
2024-01-02 22:45:55 +00:00
return emptyAttri
2022-12-08 21:39:45 +00:00
}
default :
log . WithField ( "version" , st . Version ( ) ) . Error ( "Could not get payload attribute due to unknown state version" )
2024-01-02 22:45:55 +00:00
return emptyAttri
2022-04-06 23:36:52 +00:00
}
2022-12-08 21:39:45 +00:00
2024-01-02 22:45:55 +00:00
return attr
2022-04-06 23:36:52 +00:00
}
2023-08-14 19:18:29 +00:00
// removeInvalidBlockAndState removes the invalid block, blob and its corresponding state from the cache and DB.
2022-04-06 21:24:00 +00:00
func ( s * Service ) removeInvalidBlockAndState ( ctx context . Context , blkRoots [ ] [ 32 ] byte ) error {
for _ , root := range blkRoots {
if err := s . cfg . StateGen . DeleteStateFromCaches ( ctx , root ) ; err != nil {
return err
}
// Delete block also deletes the state as well.
if err := s . cfg . BeaconDB . DeleteBlock ( ctx , root ) ; err != nil {
// TODO(10487): If a caller requests to delete a root that's justified and finalized. We should gracefully shutdown.
// This is an irreparable condition, it would me a justified or finalized block has become invalid.
return err
}
2024-01-12 08:09:45 +00:00
if err := s . blobStorage . Remove ( root ) ; err != nil {
// Blobs may not exist for some blocks, leading to deletion failures. Log such errors at debug level.
log . WithError ( err ) . Debug ( "Could not remove blob from blob storage" )
}
2022-04-06 21:24:00 +00:00
}
return nil
}
2023-07-10 19:02:44 +00:00
2023-08-08 22:49:06 +00:00
func kzgCommitmentsToVersionedHashes ( body interfaces . ReadOnlyBeaconBlockBody ) ( [ ] common . Hash , error ) {
2023-08-03 20:35:30 +00:00
commitments , err := body . BlobKzgCommitments ( )
if err != nil {
return nil , errors . Wrap ( invalidBlock { error : err } , "could not get blob kzg commitments" )
}
2023-07-10 19:02:44 +00:00
2023-08-08 22:49:06 +00:00
versionedHashes := make ( [ ] common . Hash , len ( commitments ) )
2023-08-03 20:35:30 +00:00
for i , commitment := range commitments {
2023-09-22 21:54:10 +00:00
versionedHashes [ i ] = ConvertKzgCommitmentToVersionedHash ( commitment )
2023-08-03 20:35:30 +00:00
}
return versionedHashes , nil
2023-07-10 19:02:44 +00:00
}
2023-09-22 21:54:10 +00:00
func ConvertKzgCommitmentToVersionedHash ( commitment [ ] byte ) common . Hash {
versionedHash := sha256 . Sum256 ( commitment )
versionedHash [ 0 ] = blobCommitmentVersionKZG
return versionedHash
}