@@ -287,3 +287,91 @@ func TestNewPayloadShouldReturnValidWhenSideChainGoingBackIsLtMaxReorgDepth(t *t
287287 require .Equal (t , enginetypes .ValidStatus , ps .Status )
288288 })
289289}
290+
291+ func TestFcuAllowsReorgBackOnCanonicalChainWhenAfterFinalisedHash (t * testing.T ) {
292+ // as per spec update: https://github.com/ethereum/execution-apis/pull/786
293+ eat := engineapitester .DefaultEngineApiTester (t )
294+ eat .Run (t , func (ctx context.Context , t * testing.T , eat engineapitester.EngineApiTester ) {
295+ // deploy changer at b2
296+ transactOpts , err := bind .NewKeyedTransactorWithChainID (eat .CoinbaseKey , eat .ChainId ())
297+ require .NoError (t , err )
298+ transactOpts .GasLimit = params .MaxTxnGasLimit
299+ _ , txn , changer , err := contracts .DeployChanger (transactOpts , eat .ContractBackend )
300+ require .NoError (t , err )
301+ b2Canon , err := eat .MockCl .BuildCanonicalBlock (ctx )
302+ require .NoError (t , err )
303+ err = eat .TxnInclusionVerifier .VerifyTxnsInclusion (ctx , b2Canon .ExecutionPayload , txn .Hash ())
304+ require .NoError (t , err )
305+ // change changer at b3
306+ txn , err = changer .Change (transactOpts )
307+ require .NoError (t , err )
308+ b3Canon , err := eat .MockCl .BuildCanonicalBlock (ctx )
309+ require .NoError (t , err )
310+ err = eat .TxnInclusionVerifier .VerifyTxnsInclusion (ctx , b3Canon .ExecutionPayload , txn .Hash ())
311+ require .NoError (t , err )
312+ blockNum , err := eat .RpcApiClient .BlockNumber ()
313+ require .NoError (t , err )
314+ require .Equal (t , uint64 (3 ), blockNum )
315+ // unwind back to b2
316+ err = eat .MockCl .UpdateForkChoice (ctx , b2Canon )
317+ require .NoError (t , err )
318+ // verify canonical head went back
319+ blockNum , err = eat .RpcApiClient .BlockNumber ()
320+ require .NoError (t , err )
321+ require .Equal (t , uint64 (2 ), blockNum )
322+ })
323+ }
324+
325+ func TestFcuReturnsReorgTooDeepCode38006 (t * testing.T ) {
326+ // as per spec update: https://github.com/ethereum/execution-apis/pull/786
327+ genesis , coinbaseKey := engineapitester .DefaultEngineApiTesterGenesis (t )
328+ eat := engineapitester .InitialiseEngineApiTester (t , engineapitester.EngineApiTesterInitArgs {
329+ Logger : testlog .Logger (t , log .LvlDebug ),
330+ DataDir : t .TempDir (),
331+ Genesis : genesis ,
332+ CoinbaseKey : coinbaseKey ,
333+ EthConfigTweaker : func (config * ethconfig.Config ) {
334+ config .MaxReorgDepth = 2
335+ },
336+ })
337+ eat .Run (t , func (ctx context.Context , t * testing.T , eat engineapitester.EngineApiTester ) {
338+ // deploy changer at b2
339+ transactOpts , err := bind .NewKeyedTransactorWithChainID (eat .CoinbaseKey , eat .ChainId ())
340+ require .NoError (t , err )
341+ transactOpts .GasLimit = params .MaxTxnGasLimit
342+ _ , txn , changer , err := contracts .DeployChanger (transactOpts , eat .ContractBackend )
343+ require .NoError (t , err )
344+ b2Canon , err := eat .MockCl .BuildCanonicalBlock (ctx )
345+ require .NoError (t , err )
346+ err = eat .TxnInclusionVerifier .VerifyTxnsInclusion (ctx , b2Canon .ExecutionPayload , txn .Hash ())
347+ require .NoError (t , err )
348+ // change changer at b3
349+ txn , err = changer .Change (transactOpts )
350+ require .NoError (t , err )
351+ b3Canon , err := eat .MockCl .BuildCanonicalBlock (ctx )
352+ require .NoError (t , err )
353+ err = eat .TxnInclusionVerifier .VerifyTxnsInclusion (ctx , b3Canon .ExecutionPayload , txn .Hash ())
354+ require .NoError (t , err )
355+ // change changer at b4
356+ txn , err = changer .Change (transactOpts )
357+ require .NoError (t , err )
358+ b4Canon , err := eat .MockCl .BuildCanonicalBlock (ctx )
359+ require .NoError (t , err )
360+ err = eat .TxnInclusionVerifier .VerifyTxnsInclusion (ctx , b4Canon .ExecutionPayload , txn .Hash ())
361+ require .NoError (t , err )
362+ // change changer at b5
363+ txn , err = changer .Change (transactOpts )
364+ require .NoError (t , err )
365+ b5Canon , err := eat .MockCl .BuildCanonicalBlock (ctx )
366+ require .NoError (t , err )
367+ err = eat .TxnInclusionVerifier .VerifyTxnsInclusion (ctx , b5Canon .ExecutionPayload , txn .Hash ())
368+ require .NoError (t , err )
369+ // unwind back to b2 should return "Too deep reorg" error with code 38006
370+ err = eat .MockCl .UpdateForkChoice (ctx , b2Canon )
371+ require .Error (t , err )
372+ var rpcErr rpc.Error
373+ require .ErrorAs (t , err , & rpcErr )
374+ require .Equal (t , - 38006 , rpcErr .ErrorCode ())
375+ require .Equal (t , "Too deep reorg" , rpcErr .Error ())
376+ })
377+ }
0 commit comments