diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 056c1c1abc..7ed77e828a 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "math/big" + "strings" "sync" "time" @@ -681,6 +682,9 @@ func (api *ConsensusAPI) delayPayloadImport(block *types.Block) (engine.PayloadS // that the parent state is missing and the syncer rejected extending the // current cycle with the new payload. log.Warn("Ignoring payload with missing parent", "number", block.NumberU64(), "hash", block.Hash(), "parent", block.ParentHash(), "reason", err) + if strings.Contains(err.Error(), "forced head needed for startup") { + return engine.PayloadStatusV1{Status: engine.SYNCING}, err + } } else { // In non-full sync mode (i.e. snap sync) all payloads are rejected until // snap sync terminates as snap sync relies on direct database injections diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go index cbf744cd6d..acba42f565 100644 --- a/eth/catalyst/api_test.go +++ b/eth/catalyst/api_test.go @@ -24,12 +24,15 @@ import ( "math/big" "math/rand" "reflect" + "strings" "sync" "testing" "time" "github.com/stretchr/testify/require" + "github.com/mattn/go-colorable" + "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -50,7 +53,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/trie" - "github.com/mattn/go-colorable" ) var ( @@ -717,7 +719,7 @@ func TestEmptyBlocks(t *testing.T) { payload := getNewPayload(t, api, commonAncestor, nil) status, err := api.NewPayloadV1(*payload) - if err != nil { + if err != nil && !strings.Contains(err.Error(), "forced head needed for startup") { t.Fatal(err) } if status.Status != engine.VALID { @@ -733,7 +735,7 @@ func TestEmptyBlocks(t *testing.T) { payload = setBlockhash(payload) // Now latestValidHash should be the common ancestor status, err = api.NewPayloadV1(*payload) - if err != nil { + if err != nil && !strings.Contains(err.Error(), "forced head needed for startup") { t.Fatal(err) } if status.Status != engine.INVALID { @@ -751,7 +753,7 @@ func TestEmptyBlocks(t *testing.T) { payload = setBlockhash(payload) // Now latestValidHash should be the common ancestor status, err = api.NewPayloadV1(*payload) - if err != nil { + if err != nil && !strings.Contains(err.Error(), "forced head needed for startup") { t.Fatal(err) } if status.Status != engine.SYNCING { @@ -863,7 +865,7 @@ func TestTrickRemoteBlockCache(t *testing.T) { // feed the payloads to node B for _, payload := range invalidChain { status, err := apiB.NewPayloadV1(*payload) - if err != nil { + if err != nil && !strings.Contains(err.Error(), "forced head needed for startup") { panic(err) } if status.Status == engine.VALID {