From 30ae50058830350dbf79698ead5d59a8d7697079 Mon Sep 17 00:00:00 2001 From: Rachit Sonthalia Date: Fri, 6 Sep 2024 15:16:00 +0530 Subject: [PATCH] wip --- aggregator/config.go | 2 +- aggregator/prover/prover.go | 14 ++-- cmd/main.go | 6 +- cmd/run.go | 28 ++++++- etherman/aggregator.go | 8 +- test/helpers/aggoracle_e2e.go | 134 +++++++++++++++++++++---------- test/helpers/ethtxmanmock_e2e.go | 35 +++++--- 7 files changed, 157 insertions(+), 70 deletions(-) diff --git a/aggregator/config.go b/aggregator/config.go index b6060193..e17a24d1 100644 --- a/aggregator/config.go +++ b/aggregator/config.go @@ -89,7 +89,7 @@ type Config struct { ChainID uint64 // ForkID is the L2 ForkID provided by the Network Config - ForkId uint64 `mapstructure:"ForkId"` + ForkId uint64 `mapstructure:"ForkId"` //nolint:stylecheck // SenderAddress defines which private key the eth tx manager needs to use // to sign the L1 txs diff --git a/aggregator/prover/prover.go b/aggregator/prover/prover.go index 8844f5a3..285eadb2 100644 --- a/aggregator/prover/prover.go +++ b/aggregator/prover/prover.go @@ -23,13 +23,13 @@ const ( ) var ( - ErrBadProverResponse = errors.New("Prover returned wrong type for response") //nolint:revive - ErrProverInternalError = errors.New("Prover returned INTERNAL_ERROR response") //nolint:revive - ErrProverCompletedError = errors.New("Prover returned COMPLETED_ERROR response") //nolint:revive - ErrBadRequest = errors.New("Prover returned ERROR for a bad request") //nolint:revive - ErrUnspecified = errors.New("Prover returned an UNSPECIFIED response") //nolint:revive - ErrUnknown = errors.New("Prover returned an unknown response") //nolint:revive - ErrProofCanceled = errors.New("Proof has been canceled") //nolint:revive + ErrBadProverResponse = errors.New("prover returned wrong type for response") //nolint:revive + ErrProverInternalError = errors.New("prover returned INTERNAL_ERROR response") //nolint:revive + ErrProverCompletedError = errors.New("prover returned COMPLETED_ERROR response") //nolint:revive + ErrBadRequest = errors.New("prover returned ERROR for a bad request") //nolint:revive + ErrUnspecified = errors.New("prover returned an UNSPECIFIED response") //nolint:revive + ErrUnknown = errors.New("prover returned an unknown response") //nolint:revive + ErrProofCanceled = errors.New("proof has been canceled") //nolint:revive ) // Prover abstraction of the grpc prover client. diff --git a/cmd/main.go b/cmd/main.go index 4686902f..050fad2b 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -13,7 +13,7 @@ const appName = "cdk" const ( // SEQUENCE_SENDER name to identify the sequence-sender component - SEQUENCE_SENDER = "sequence-sender" + SEQUENCE_SENDER = "sequence-sender" //nolint:stylecheck // AGGREGATOR name to identify the aggregator component AGGREGATOR = "aggregator" // AGGORACLE name to identify the aggoracle component @@ -23,8 +23,8 @@ const ( ) const ( - // NETWORK_CONFIGFILE name to identify the netowk_custom (genesis) config-file - NETWORK_CONFIGFILE = "custom_network" + // NetworkConfigFile name to identify the network_custom (genesis) config-file + NetworkConfigFile = "custom_network" ) var ( diff --git a/cmd/run.go b/cmd/run.go index 79d5c0ab..757a8272 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -519,7 +519,19 @@ func runReorgDetectorL1IfNeeded( return nil } rd := newReorgDetector(cfg, l1Client) - go rd.Start(ctx) + + errChan := make(chan error, 1) + go func() { + if err := rd.Start(ctx); err != nil { + errChan <- err + } + close(errChan) + }() + go func() { + if err := <-errChan; err != nil { + log.Errorf("Failed to start ReorgDetector: %v", err) + } + }() return rd } @@ -534,7 +546,19 @@ func runReorgDetectorL2IfNeeded( return nil } rd := newReorgDetector(cfg, l2Client) - go rd.Start(ctx) + + errChan := make(chan error, 1) + go func() { + if err := rd.Start(ctx); err != nil { + errChan <- err + } + close(errChan) + }() + go func() { + if err := <-errChan; err != nil { + log.Errorf("Failed to start ReorgDetector: %v", err) + } + }() return rd } diff --git a/etherman/aggregator.go b/etherman/aggregator.go index c7eef1e4..4197c7a2 100644 --- a/etherman/aggregator.go +++ b/etherman/aggregator.go @@ -67,9 +67,9 @@ func (etherMan *Client) BuildTrustedVerifyBatchesTxData( } // GetBatchAccInputHash gets the batch accumulated input hash from the ethereum -func (etherman *Client) GetBatchAccInputHash(ctx context.Context, batchNumber uint64) (common.Hash, error) { - rollupData, err := etherman.Contracts.Banana.RollupManager.GetRollupSequencedBatches( - &bind.CallOpts{Pending: false}, etherman.RollupID, batchNumber, +func (etherMan *Client) GetBatchAccInputHash(ctx context.Context, batchNumber uint64) (common.Hash, error) { + rollupData, err := etherMan.Contracts.Banana.RollupManager.GetRollupSequencedBatches( + &bind.CallOpts{Pending: false}, etherMan.RollupID, batchNumber, ) if err != nil { return common.Hash{}, err @@ -79,7 +79,7 @@ func (etherman *Client) GetBatchAccInputHash(ctx context.Context, batchNumber ui } // GetRollupId returns the rollup id -func (etherMan *Client) GetRollupId() uint32 { +func (etherMan *Client) GetRollupId() uint32 { //nolint:stylecheck return etherMan.RollupID } diff --git a/test/helpers/aggoracle_e2e.go b/test/helpers/aggoracle_e2e.go index 744f2ab9..311ba189 100644 --- a/test/helpers/aggoracle_e2e.go +++ b/test/helpers/aggoracle_e2e.go @@ -26,7 +26,10 @@ import ( ) const ( - NetworkIDL2 = uint32(1) + NetworkIDL2 = uint32(1) + chainID = 1337 + initialBalance = "10000000000000000000000000" + blockGasLimit = uint64(999999999999999999) ) type AggoracleWithEVMChainEnv struct { @@ -56,7 +59,7 @@ func SetupAggoracleWithEVMChain(t *testing.T) *AggoracleWithEVMChainEnv { ctx := context.Background() l1Client, syncer, gerL1Contract, gerL1Addr, bridgeL1Contract, bridgeL1Addr, authL1, rd := CommonSetup(t) sender, l2Client, gerL2Contract, gerL2Addr, bridgeL2Contract, bridgeL2Addr, authL2, ethTxManMockL2 := EVMSetup(t) - oracle, err := aggoracle.New(sender, l1Client.Client(), syncer, etherman.LatestBlock, time.Millisecond*20) + oracle, err := aggoracle.New(sender, l1Client.Client(), syncer, etherman.LatestBlock, time.Millisecond*20) //nolint:gomnd require.NoError(t, err) go oracle.Start(ctx) @@ -99,7 +102,7 @@ func CommonSetup(t *testing.T) ( // Simulated L1 privateKeyL1, err := crypto.GenerateKey() require.NoError(t, err) - authL1, err := bind.NewKeyedTransactorWithChainID(privateKeyL1, big.NewInt(1337)) + authL1, err := bind.NewKeyedTransactorWithChainID(privateKeyL1, big.NewInt(chainID)) require.NoError(t, err) l1Client, gerL1Addr, gerL1Contract, bridgeL1Addr, bridgeL1Contract, err := newSimulatedL1(authL1) require.NoError(t, err) @@ -109,7 +112,7 @@ func CommonSetup(t *testing.T) ( require.NoError(t, err) // Syncer dbPathSyncer := t.TempDir() - syncer, err := l1infotreesync.New(ctx, dbPathSyncer, gerL1Addr, common.Address{}, 10, etherman.LatestBlock, reorg, l1Client.Client(), time.Millisecond, 0, 100*time.Millisecond, 3) + syncer, err := l1infotreesync.New(ctx, dbPathSyncer, gerL1Addr, common.Address{}, 10, etherman.LatestBlock, reorg, l1Client.Client(), time.Millisecond, 0, 100*time.Millisecond, 3) //nolint:gomnd require.NoError(t, err) go syncer.Start(ctx) @@ -130,12 +133,12 @@ func EVMSetup(t *testing.T) ( privateKeyL2, err := crypto.GenerateKey() require.NoError(t, err) - authL2, err := bind.NewKeyedTransactorWithChainID(privateKeyL2, big.NewInt(1337)) + authL2, err := bind.NewKeyedTransactorWithChainID(privateKeyL2, big.NewInt(chainID)) require.NoError(t, err) l2Client, gerL2Addr, gerL2Sc, bridgeL2Addr, bridgeL2Sc, err := newSimulatedEVMAggSovereignChain(authL2) require.NoError(t, err) ethTxManMock := NewEthTxManMock(t, l2Client, authL2) - sender, err := chaingersender.NewEVMChainGERSender(gerL2Addr, authL2.From, l2Client.Client(), ethTxManMock, 0, time.Millisecond*50) + sender, err := chaingersender.NewEVMChainGERSender(gerL2Addr, authL2.From, l2Client.Client(), ethTxManMock, 0, time.Millisecond*50) //nolint:gomnd require.NoError(t, err) return sender, l2Client, gerL2Sc, gerL2Addr, bridgeL2Sc, bridgeL2Addr, authL2, ethTxManMock @@ -150,12 +153,18 @@ func newSimulatedL1(auth *bind.TransactOpts) ( err error, ) { ctx := context.Background() + privateKeyL1, err := crypto.GenerateKey() if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to generate private key: %w", err) + } + + authDeployer, err := bind.NewKeyedTransactorWithChainID(privateKeyL1, big.NewInt(chainID)) + if err != nil { + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to create transactor: %w", err) } - authDeployer, err := bind.NewKeyedTransactorWithChainID(privateKeyL1, big.NewInt(1337)) - balance, _ := new(big.Int).SetString("10000000000000000000000000", 10) //nolint:gomnd + + balance, _ := new(big.Int).SetString(initialBalance, 10) //nolint:gomnd address := auth.From genesisAlloc := map[common.Address]types.Account{ address: { @@ -165,28 +174,29 @@ func newSimulatedL1(auth *bind.TransactOpts) ( Balance: balance, }, } - blockGasLimit := uint64(999999999999999999) //nolint:gomnd + client = simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit)) bridgeImplementationAddr, _, _, err := polygonzkevmbridgev2.DeployPolygonzkevmbridgev2(authDeployer, client.Client()) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to deploy bridge implementation: %w", err) } client.Commit() nonce, err := client.Client().PendingNonceAt(ctx, authDeployer.From) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to get pending nonce: %w", err) } precalculatedAddr := crypto.CreateAddress(authDeployer.From, nonce+1) bridgeABI, err := polygonzkevmbridgev2.Polygonzkevmbridgev2MetaData.GetAbi() if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to get bridge ABI: %w", err) } if bridgeABI == nil { err = errors.New("GetABI returned nil") - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to get bridge ABI: %w", err) } + dataCallProxy, err := bridgeABI.Pack("initialize", uint32(0), // networkIDMainnet common.Address{}, // gasTokenAddressMainnet" @@ -196,8 +206,9 @@ func newSimulatedL1(auth *bind.TransactOpts) ( []byte{}, // gasTokenMetadata ) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to pack data for proxy initialization: %w", err) } + bridgeAddr, _, _, err = transparentupgradableproxy.DeployTransparentupgradableproxy( authDeployer, client.Client(), @@ -206,28 +217,40 @@ func newSimulatedL1(auth *bind.TransactOpts) ( dataCallProxy, ) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to deploy transparent upgradable proxy: %w", err) } client.Commit() + bridgeContract, err = polygonzkevmbridgev2.NewPolygonzkevmbridgev2(bridgeAddr, client.Client()) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to create bridge contract instance: %w", err) } + checkGERAddr, err := bridgeContract.GlobalExitRootManager(&bind.CallOpts{Pending: false}) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to get Global Exit Root Manager: %w", err) } if precalculatedAddr != checkGERAddr { - err = fmt.Errorf("error deploying bridge, unexpected GER addr. Expected %s. Actual %s", precalculatedAddr.Hex(), checkGERAddr.Hex()) + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf( + "error deploying bridge, unexpected GER addr. Expected %s. Actual %s", + precalculatedAddr.Hex(), checkGERAddr.Hex(), + ) } gerAddr, _, gerContract, err = gerContractL1.DeployGlobalexitrootnopush0(authDeployer, client.Client(), auth.From, bridgeAddr) - + if err != nil { + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to deploy GER contract: %w", err) + } client.Commit() + if precalculatedAddr != gerAddr { - err = fmt.Errorf("error calculating addr. Expected %s. Actual %s", precalculatedAddr.Hex(), gerAddr.Hex()) + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf( + "error calculating GER address. Expected %s. Actual %s", + precalculatedAddr.Hex(), gerAddr.Hex(), + ) } - return + + return client, gerAddr, gerContract, bridgeAddr, bridgeContract, nil } func newSimulatedEVMAggSovereignChain(auth *bind.TransactOpts) ( @@ -239,14 +262,21 @@ func newSimulatedEVMAggSovereignChain(auth *bind.TransactOpts) ( err error, ) { ctx := context.Background() + privateKeyL1, err := crypto.GenerateKey() if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to generate private key: %w", err) } - authDeployer, err := bind.NewKeyedTransactorWithChainID(privateKeyL1, big.NewInt(1337)) - balance, _ := new(big.Int).SetString("10000000000000000000000000", 10) //nolint:gomnd + + authDeployer, err := bind.NewKeyedTransactorWithChainID(privateKeyL1, big.NewInt(chainID)) + if err != nil { + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to create transactor: %w", err) + } + + balance, _ := new(big.Int).SetString(initialBalance, 10) //nolint:gomnd address := auth.From precalculatedBridgeAddr := crypto.CreateAddress(authDeployer.From, 1) + genesisAlloc := map[common.Address]types.Account{ address: { Balance: balance, @@ -258,28 +288,31 @@ func newSimulatedEVMAggSovereignChain(auth *bind.TransactOpts) ( Balance: balance, }, } - blockGasLimit := uint64(999999999999999999) //nolint:gomnd + + const blockGasLimit = uint64(999999999999999999) client = simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit)) bridgeImplementationAddr, _, _, err := polygonzkevmbridgev2.DeployPolygonzkevmbridgev2(authDeployer, client.Client()) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to deploy bridge implementation: %w", err) } client.Commit() nonce, err := client.Client().PendingNonceAt(ctx, authDeployer.From) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to get pending nonce: %w", err) } precalculatedAddr := crypto.CreateAddress(authDeployer.From, nonce+1) + bridgeABI, err := polygonzkevmbridgev2.Polygonzkevmbridgev2MetaData.GetAbi() if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to get bridge ABI: %w", err) } if bridgeABI == nil { err = errors.New("GetABI returned nil") - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to get bridge ABI: %w", err) } + dataCallProxy, err := bridgeABI.Pack("initialize", NetworkIDL2, common.Address{}, // gasTokenAddressMainnet" @@ -289,8 +322,9 @@ func newSimulatedEVMAggSovereignChain(auth *bind.TransactOpts) ( []byte{}, // gasTokenMetadata ) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to pack data for proxy initialization: %w", err) } + bridgeAddr, _, _, err = transparentupgradableproxy.DeployTransparentupgradableproxy( authDeployer, client.Client(), @@ -299,40 +333,52 @@ func newSimulatedEVMAggSovereignChain(auth *bind.TransactOpts) ( dataCallProxy, ) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to deploy transparent upgradable proxy: %w", err) } if bridgeAddr != precalculatedBridgeAddr { - err = fmt.Errorf("error calculating bridge addr. Expected: %s. Actual: %s", precalculatedBridgeAddr, bridgeAddr) - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf( + "error calculating bridge addr. Expected: %s. Actual: %s", + precalculatedBridgeAddr, bridgeAddr, + ) } client.Commit() + bridgeContract, err = polygonzkevmbridgev2.NewPolygonzkevmbridgev2(bridgeAddr, client.Client()) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to create bridge contract instance: %w", err) } + checkGERAddr, err := bridgeContract.GlobalExitRootManager(&bind.CallOpts{}) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to get Global Exit Root Manager: %w", err) } if precalculatedAddr != checkGERAddr { - err = errors.New("error deploying bridge") + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf( + "error deploying bridge, unexpected Global Exit Root Manager address", + ) } gerAddr, _, gerContract, err = gerContractEVMChain.DeployPessimisticglobalexitrootnopush0(authDeployer, client.Client(), auth.From) if err != nil { - return + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to deploy GER contract: %w", err) } client.Commit() - _GLOBAL_EXIT_ROOT_SETTER_ROLE := common.HexToHash("0x7b95520991dfda409891be0afa2635b63540f92ee996fda0bf695a166e5c5176") - _, err = gerContract.GrantRole(authDeployer, _GLOBAL_EXIT_ROOT_SETTER_ROLE, auth.From) + globalExitRootSetterRole := common.HexToHash("0x7b95520991dfda409891be0afa2635b63540f92ee996fda0bf695a166e5c5176") + _, err = gerContract.GrantRole(authDeployer, globalExitRootSetterRole, auth.From) + if err != nil { + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to grant role to GER contract: %w", err) + } client.Commit() - hasRole, _ := gerContract.HasRole(&bind.CallOpts{Pending: false}, _GLOBAL_EXIT_ROOT_SETTER_ROLE, auth.From) + + hasRole, _ := gerContract.HasRole(&bind.CallOpts{Pending: false}, globalExitRootSetterRole, auth.From) if !hasRole { - err = errors.New("failed to set role") + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("failed to set role for GER contract") } + if precalculatedAddr != gerAddr { - err = errors.New("error calculating addr") + return nil, common.Address{}, nil, common.Address{}, nil, fmt.Errorf("error calculating GER address") } - return + + return client, gerAddr, gerContract, bridgeAddr, bridgeContract, nil } diff --git a/test/helpers/ethtxmanmock_e2e.go b/test/helpers/ethtxmanmock_e2e.go index 92170a47..c7d7455d 100644 --- a/test/helpers/ethtxmanmock_e2e.go +++ b/test/helpers/ethtxmanmock_e2e.go @@ -22,6 +22,12 @@ func NewEthTxManMock( ) *EthTxManagerMock { t.Helper() + const ( + ArgToIndex = 1 + ArgDataIndex = 4 + ZeroValue = 0 + ) + ethTxMock := NewEthTxManagerMock(t) ethTxMock.On("Add", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Run(func(args mock.Arguments) { @@ -33,17 +39,17 @@ func NewEthTxManMock( } gas, err := client.Client().EstimateGas(ctx, ethereum.CallMsg{ From: auth.From, - To: args.Get(1).(*common.Address), - Value: big.NewInt(0), - Data: args.Get(4).([]byte), + To: args.Get(ArgToIndex).(*common.Address), + Value: big.NewInt(ZeroValue), + Data: args.Get(ArgDataIndex).([]byte), }) if err != nil { log.Error(err) res, err := client.Client().CallContract(ctx, ethereum.CallMsg{ From: auth.From, - To: args.Get(1).(*common.Address), - Value: big.NewInt(0), - Data: args.Get(4).([]byte), + To: args.Get(ArgToIndex).(*common.Address), + Value: big.NewInt(ZeroValue), + Data: args.Get(ArgDataIndex).([]byte), }, nil) log.Debugf("contract call: %s", res) if err != nil { @@ -55,11 +61,22 @@ func NewEthTxManMock( if err != nil { log.Error(err) } + + to, ok := args.Get(ArgToIndex).(*common.Address) + if !ok { + log.Error("expected *common.Address for ArgToIndex") + return + } + data, ok := args.Get(ArgDataIndex).([]byte) + if !ok { + log.Error("expected []byte for ArgDataIndex") + return + } tx := types.NewTx(&types.LegacyTx{ - To: args.Get(1).(*common.Address), + To: to, Nonce: nonce, - Value: big.NewInt(0), - Data: args.Get(4).([]byte), + Value: big.NewInt(ZeroValue), + Data: data, Gas: gas, GasPrice: price, })