From 21e324f731f00d8f21064f6f1a1a4f69d2fc5944 Mon Sep 17 00:00:00 2001 From: alecps Date: Mon, 5 Aug 2024 15:53:32 -0400 Subject: [PATCH] add e2e test, saving progress --- cmd/geth/main.go | 22 ++++++++ consensus/istanbul/backend/backend.go | 10 ++-- consensus/istanbul/backend/engine.go | 2 +- core/blockchain.go | 6 ++ core/genesis.go | 6 +- e2e_test/e2e_bench_test.go | 4 +- e2e_test/e2e_test.go | 80 ++++++++++++++++++++------- e2e_test/e2e_transfer_test.go | 4 +- eth/backend.go | 4 ++ eth/ethconfig/config.go | 2 +- les/client.go | 2 +- params/config.go | 4 +- test/node.go | 3 +- 13 files changed, 112 insertions(+), 37 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 4d551e74b9..ac555a567d 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -390,6 +390,28 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { } }() + // if ctx.GlobalIsSet(utils.L2ForkFlag.Name) { + // go func() { + // sub := stack.EventMux().Subscribe(ethCore.ChainHeadEvent{}) + // defer sub.Unsubscribe() + // for { + // event := <-sub.Chan() + // if event == nil { + // continue + // } + // var latest *types.Header + // if done, ok := event.Data.(ethCore.ChainHeadEvent); ok { + // latest = done.Block.Header() + // } + + // if ctx.GlobalUint64(utils.L2ForkFlag.Name) >= latest.Number.Uint64() { + // log.Info("L2 Migration Block Reached", "latest", latest.Number.Uint64(), "latesthash", latest.Hash()) + // stack.Close() + // } + // } + // }() + // } + // Spawn a standalone goroutine for status synchronization monitoring, // close the node when synchronization is complete if user required. if ctx.GlobalBool(utils.ExitWhenSyncedFlag.Name) { diff --git a/consensus/istanbul/backend/backend.go b/consensus/istanbul/backend/backend.go index bb03e34a3e..ea6dee75a3 100644 --- a/consensus/istanbul/backend/backend.go +++ b/consensus/istanbul/backend/backend.go @@ -554,9 +554,11 @@ func (sb *Backend) Commit(proposal istanbul.Proposal, aggregatedSeal types.Istan } } sb.onNewConsensusBlock(block, result.Receipts, result.Logs, result.State) + if sb.chain.Config().IsL2(block.Number()) { sb.logger.Info("L2 hard fork reached, stopping the backend") - sb.StopValidating() + sb.Close() + //sb.core.Stop() } return nil } @@ -576,9 +578,9 @@ func (sb *Backend) Verify(proposal istanbul.Proposal) (*istanbulCore.StateProces } // Don't verify blocks after the L2 hard fork - if sb.chain.Config().IsL2(block.Number()) { - return nil, 0, core.ErrPostL2BlockNumber - } + // if sb.chain.Config().IsL2(block.Number()) { + // return nil, 0, core.ErrPostL2BlockNumber + // } // check bad block if sb.hasBadProposal(block.Hash()) { diff --git a/consensus/istanbul/backend/engine.go b/consensus/istanbul/backend/engine.go index 41f5f100e6..6fb4999563 100644 --- a/consensus/istanbul/backend/engine.go +++ b/consensus/istanbul/backend/engine.go @@ -1058,7 +1058,7 @@ func (sb *Backend) SetStartValidatingBlock(blockNumber *big.Int) error { } // SetStopValidatingBlock sets the block that the validator will stop just before (exclusive range) -func (sb *Backend) SetStopValidatingBlock(blockNumber *big.Int) error { // TODO(Alec) code pointer +func (sb *Backend) SetStopValidatingBlock(blockNumber *big.Int) error { if sb.replicaState == nil { return errNotAValidator } diff --git a/core/blockchain.go b/core/blockchain.go index 48b0e8b0e3..8215eca5c6 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -811,6 +811,12 @@ func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { // // Note, this function assumes that the `mu` mutex is held! func (bc *BlockChain) writeHeadBlock(block *types.Block) { + if bc.Config().IsL2(block.Number()) { + log.Info("L2 hard fork reached, stopping the blockchain") + bc.StopInsert() + // bc.Stop() + bc.Engine().Close() + } // If the block is on a side chain or an unknown one, force other heads onto it too updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash() diff --git a/core/genesis.go b/core/genesis.go index bacb1bdf37..3e0baa4e89 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -207,9 +207,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override if overrideHFork != nil { newcfg.HForkBlock = overrideHFork } - if l2Fork != nil { - newcfg.L2Block = l2Fork - } + // if l2Fork != nil { + // newcfg.L2Block = l2Fork + // } if err := newcfg.CheckConfigForkOrder(); err != nil { return newcfg, common.Hash{}, err } diff --git a/e2e_test/e2e_bench_test.go b/e2e_test/e2e_bench_test.go index 69b3bd4ba3..438d2f6e89 100644 --- a/e2e_test/e2e_bench_test.go +++ b/e2e_test/e2e_bench_test.go @@ -19,7 +19,7 @@ func BenchmarkNet100EmptyBlocks(b *testing.B) { for i := 0; i < b.N; i++ { ac := test.AccountConfig(n, 0) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(b, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(b, err) @@ -45,7 +45,7 @@ func BenchmarkNet1000Txs(b *testing.B) { ac := test.AccountConfig(n, n) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(b, err) accounts := test.Accounts(ac.DeveloperAccounts(), gc.ChainConfig()) network, shutdown, err := test.NewNetwork(ac, gc, ec) diff --git a/e2e_test/e2e_test.go b/e2e_test/e2e_test.go index fc73486ec6..6fe45379e8 100644 --- a/e2e_test/e2e_test.go +++ b/e2e_test/e2e_test.go @@ -45,7 +45,7 @@ func init() { func TestSendCelo(t *testing.T) { ac := test.AccountConfig(3, 2) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) @@ -71,7 +71,7 @@ func TestSendCelo(t *testing.T) { func TestTraceSendCeloViaGoldToken(t *testing.T) { ac := test.AccountConfig(3, 2) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) @@ -108,7 +108,7 @@ func TestTraceSendCeloViaGoldToken(t *testing.T) { func TestCallTraceTransactionNativeTransfer(t *testing.T) { ac := test.AccountConfig(1, 2) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) @@ -146,7 +146,7 @@ func TestCallTraceTransactionNativeTransfer(t *testing.T) { func TestPrestateTransactionNativeTransfer(t *testing.T) { ac := test.AccountConfig(1, 2) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) @@ -184,7 +184,7 @@ func TestSingleNodeNetworkManyTxs(t *testing.T) { txsPerIteration := 5 ac := test.AccountConfig(1, 1) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) gc.Istanbul.Epoch = uint64(iterations) * 50 // avoid the epoch for this test network, shutdown, err := test.NewNetwork(ac, gc, ec) @@ -210,7 +210,7 @@ func TestSingleNodeNetworkManyTxs(t *testing.T) { func TestEpochBlockMarshaling(t *testing.T) { accounts := test.AccountConfig(1, 0) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(accounts, gingerbreadBlock) + gc, ec, err := test.BuildConfig(accounts, gingerbreadBlock, nil) require.NoError(t, err) // Configure the shortest possible epoch, uptimeLookbackWindow minimum is 3 @@ -240,7 +240,7 @@ func TestEpochBlockMarshaling(t *testing.T) { func TestStartStopValidators(t *testing.T) { ac := test.AccountConfig(4, 2) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, _, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) @@ -369,6 +369,46 @@ func TestStartStopValidators(t *testing.T) { } +// TODO(Alec) +func TestStopNetworkAtL2Block(t *testing.T) { + ac := test.AccountConfig(3, 2) + gingerbreadBlock := common.Big0 + l2Block := big.NewInt(2) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, l2Block) + require.NoError(t, err) + network, _, err := test.NewNetwork(ac, gc, ec) + require.NoError(t, err) + + // We define our own shutdown function because we don't want to print + // errors about already stopped nodes. Since this test can fail while we + // have stopped nodes. + defer func() { + for _, err := range network.Shutdown() { + if !errors.Is(err, test.ErrTrackerAlreadyStopped) && !errors.Is(err, node.ErrNodeStopped) { + fmt.Println(err.Error()) + } + } + }() + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*200) + defer cancel() + + err = network.AwaitBlock(ctx, l2Block.Uint64()) + require.NoError(t, err) + + // err = network.AwaitBlock(ctx, l2Block.Uint64()) + // require.NoError(t, err) + + shortCtx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + + err = network.AwaitBlock(shortCtx, l2Block.Uint64()+1) + // Expect DeadlineExceeded error + if !errors.Is(err, context.DeadlineExceeded) { + t.Fatalf("expecting %q, instead got: %v ", context.DeadlineExceeded.Error(), err) + } +} + // This test was created to reproduce the concurrent map access error in // https://github.com/celo-org/celo-blockchain/issues/1799 // @@ -377,7 +417,7 @@ func TestStartStopValidators(t *testing.T) { func TestBlockTracingConcurrentMapAccess(t *testing.T) { ac := test.AccountConfig(1, 2) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) @@ -428,7 +468,7 @@ func TestBlockTracingConcurrentMapAccess(t *testing.T) { func TestBlockTracingSequentialAccess(t *testing.T) { ac := test.AccountConfig(1, 2) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) @@ -463,7 +503,7 @@ type rpcCustomTransaction struct { func TestRPCDynamicTxGasPriceWithBigFeeCap(t *testing.T) { ac := test.AccountConfig(3, 2) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) @@ -504,7 +544,7 @@ func TestRPCDynamicTxGasPriceWithBigFeeCap(t *testing.T) { func TestRPCDynamicTxGasPriceWithState(t *testing.T) { ac := test.AccountConfig(3, 2) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) ec.TxLookupLimit = 0 ec.NoPruning = true @@ -582,7 +622,7 @@ func testRPCDynamicTxGasPriceWithoutState(t *testing.T, afterGingerbread, altern } cusdAddress := common.HexToAddress("0xd008") ac := test.AccountConfig(3, 2) - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) ec.TrieDirtyCache = 5 require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) @@ -656,7 +696,7 @@ func pruneStateOfBlock(ctx context.Context, node *test.Node, blockNumber *big.In func runMochaTest(t *testing.T, add_args func(*env.AccountsConfig, *genesis.Config, test.Network) []string) { ac := test.AccountConfig(1, 1) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) @@ -702,7 +742,7 @@ func TestEthersJSCompatibility(t *testing.T) { func TestEthersJSCompatibilityDisableAfterGingerbread(t *testing.T) { ac := test.AccountConfig(1, 1) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) // Check fields present (compatibility set by default) @@ -750,7 +790,7 @@ func TestEthersJSCompatibilityDisableAfterGingerbread(t *testing.T) { func TestEthersJSCompatibilityDisableBeforeGingerbread(t *testing.T) { ac := test.AccountConfig(1, 1) var gingerbreadBlock *big.Int = nil - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) // Check fields present (compatibility set by default) @@ -807,7 +847,7 @@ func TestEthCompatibilityFieldsOnGenesisBlock(t *testing.T) { var gingerbreadBlock *big.Int = nil // Fist we test without eth compatibility to ensure that the setting has an effect. - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) ec.RPCEthCompatibility = false require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) @@ -826,7 +866,7 @@ func TestEthCompatibilityFieldsOnGenesisBlock(t *testing.T) { // Now we with eth compatility enabled and see that gasLimit and baseFee // are returned on the block. - gc, ec, err = test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err = test.BuildConfig(ac, gingerbreadBlock, nil) ec.RPCEthCompatibility = true require.NoError(t, err) network, shutdown, err = test.NewNetwork(ac, gc, ec) @@ -848,7 +888,7 @@ func TestSettingGingerbreadOnGenesisBlock(t *testing.T) { // Fist we test without gingerbread to ensure that setting the gingerbread // actually has an effect. var gingerbreadBlock *big.Int = nil - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) ec.RPCEthCompatibility = false require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) @@ -867,7 +907,7 @@ func TestSettingGingerbreadOnGenesisBlock(t *testing.T) { // Now we check that setting the gingerbread block at genesis causes gasLimit and baseFee to be set on the block. gingerbreadBlock = big.NewInt(0) - gc, ec, err = test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err = test.BuildConfig(ac, gingerbreadBlock, nil) ec.RPCEthCompatibility = false require.NoError(t, err) network, shutdown, err = test.NewNetwork(ac, gc, ec) @@ -886,7 +926,7 @@ func TestSettingGingerbreadOnGenesisBlock(t *testing.T) { func TestGetFinalizedBlock(t *testing.T) { ac := test.AccountConfig(2, 2) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) diff --git a/e2e_test/e2e_transfer_test.go b/e2e_test/e2e_transfer_test.go index 4ebbbf929f..cdc2f0cdba 100644 --- a/e2e_test/e2e_transfer_test.go +++ b/e2e_test/e2e_transfer_test.go @@ -37,7 +37,7 @@ const ( func TestTransferCELO(t *testing.T) { ac := test.AccountConfig(1, 3) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) @@ -259,7 +259,7 @@ func prepareTransaction(txArgs ethapi.TransactionArgs, senderKey *ecdsa.PrivateK func TestTransferERC20(t *testing.T) { ac := test.AccountConfig(1, 3) gingerbreadBlock := common.Big0 - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock, nil) require.NoError(t, err) network, shutdown, err := test.NewNetwork(ac, gc, ec) require.NoError(t, err) diff --git a/eth/backend.go b/eth/backend.go index d9acf8fdf8..eba1accd7b 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -138,6 +138,10 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { log.Info("Initialised chain configuration", "config", chainConfig) chainConfig.FullHeaderChainAvailable = config.SyncMode.SyncFullHeaderChain() + if config.L2Fork != nil { + chainConfig.L2Block = config.L2Fork + } + if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb, stack.ResolvePath(config.TrieCleanCacheJournal)); err != nil { log.Error("Failed to recover state", "error", err) } diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 788829e28f..d64f94df62 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -165,7 +165,7 @@ type Config struct { // HFork block override (TODO: remove after the fork) OverrideHFork *big.Int `toml:",omitempty"` - // l2 fork block override + // l2 fork block L2Fork *big.Int `toml:",omitempty"` // The minimum required peers in order for syncing to be initiated, if left diff --git a/les/client.go b/les/client.go index 30ed058af4..fd8c9e7b1c 100644 --- a/les/client.go +++ b/les/client.go @@ -104,7 +104,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*LightEthereum, error) { return nil, err } chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, - config.OverrideHFork) + config.OverrideHFork, config.L2Fork) if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat { return nil, genesisErr } diff --git a/params/config.go b/params/config.go index ff80b4d402..0a72127bf4 100644 --- a/params/config.go +++ b/params/config.go @@ -516,7 +516,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "gingerbreadBlock", block: c.GingerbreadBlock}, {name: "gingerbreadP2Block", block: c.GingerbreadP2Block}, {name: "hforkBlock", block: c.HForkBlock}, - {name: "l2Block", block: c.L2Block}, + // {name: "l2Block", block: c.L2Block}, } { if lastFork.name != "" { // Next one must be higher number @@ -721,7 +721,7 @@ func (c *ChainConfig) DisableGingerbread() *ChainConfig { c.GingerbreadP2Block = nil // Since gingerbread is disabled disable following forks as well c.HForkBlock = nil - c.L2Block = nil + // c.L2Block = nil return c } diff --git a/test/node.go b/test/node.go index 74e3f9b879..44de0f6f97 100644 --- a/test/node.go +++ b/test/node.go @@ -344,7 +344,7 @@ func AccountConfig(numValidators, numExternal int) *env.AccountsConfig { // NOTE: Do not edit the Istanbul field of the returned genesis config it will // be overwritten with the corresponding config from the Istanbul field of the // returned eth config. -func BuildConfig(accounts *env.AccountsConfig, gingerbreadBlock *big.Int) (*genesis.Config, *ethconfig.Config, error) { +func BuildConfig(accounts *env.AccountsConfig, gingerbreadBlock, l2MigrationBlock *big.Int) (*genesis.Config, *ethconfig.Config, error) { gc, err := genesis.CreateCommonGenesisConfig( big.NewInt(1), accounts.AdminAccount().Address, @@ -361,6 +361,7 @@ func BuildConfig(accounts *env.AccountsConfig, gingerbreadBlock *big.Int) (*gene // original. ec := ð.Config{} err = copyObject(BaseEthConfig, ec) + ec.L2Fork = l2MigrationBlock return gc, ec, err }