diff --git a/bridgesync/bridgesync.go b/bridgesync/bridgesync.go index fdbac628..11ca7ed6 100644 --- a/bridgesync/bridgesync.go +++ b/bridgesync/bridgesync.go @@ -37,6 +37,7 @@ func NewL1( rd sync.ReorgDetector, ethClient EthClienter, initialBlock uint64, + waitForNewBlocksPeriod time.Duration, ) (*BridgeSync, error) { return new( ctx, @@ -49,6 +50,7 @@ func NewL1( initialBlock, dbPrefixL1, reorgDetectorIDL1, + waitForNewBlocksPeriod, ) } @@ -62,6 +64,7 @@ func NewL2( rd sync.ReorgDetector, ethClient EthClienter, initialBlock uint64, + waitForNewBlocksPeriod time.Duration, ) (*BridgeSync, error) { return new( ctx, @@ -74,6 +77,7 @@ func NewL2( initialBlock, dbPrefixL1, reorgDetectorIDL1, + waitForNewBlocksPeriod, ) } @@ -87,6 +91,7 @@ func new( ethClient EthClienter, initialBlock uint64, dbPrefix, reorgDetectorID string, + waitForNewBlocksPeriod time.Duration, ) (*BridgeSync, error) { processor, err := newProcessor(ctx, dbPath, dbPrefix) if err != nil { diff --git a/bridgesync/downloader.go b/bridgesync/downloader.go index d2ef4e7c..fdd60d1f 100644 --- a/bridgesync/downloader.go +++ b/bridgesync/downloader.go @@ -3,7 +3,6 @@ package bridgesync import ( "fmt" "math/big" - "time" "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmbridge" "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmbridgev2" @@ -15,10 +14,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" ) -const ( - waitForNewBlocksPeriod = time.Millisecond * 100 -) - var ( bridgeEventSignature = crypto.Keccak256Hash([]byte("BridgeEvent(uint8,uint32,address,uint32,address,uint256,bytes,uint32)")) claimEventSignature = crypto.Keccak256Hash([]byte("ClaimEvent(uint256,uint32,address,address,uint256)")) diff --git a/bridgesync/e2e_test.go b/bridgesync/e2e_test.go index ccb7cba0..02b5b2a7 100644 --- a/bridgesync/e2e_test.go +++ b/bridgesync/e2e_test.go @@ -54,7 +54,7 @@ func TestBridgeEventE2E(t *testing.T) { rd, err := reorgdetector.New(ctx, client.Client(), dbPathReorg) go rd.Start(ctx) - syncer, err := bridgesync.NewL1(ctx, dbPathSyncer, bridgeAddr, 10, etherman.LatestBlock, rd, client.Client(), 0) + syncer, err := bridgesync.NewL1(ctx, dbPathSyncer, bridgeAddr, 10, etherman.LatestBlock, rd, client.Client(), 0, time.Millisecond*10) require.NoError(t, err) go syncer.Start(ctx) diff --git a/bridgesync/processor.go b/bridgesync/processor.go index 77938a69..1fdf05f4 100644 --- a/bridgesync/processor.go +++ b/bridgesync/processor.go @@ -296,3 +296,21 @@ func (p *processor) updateLastProcessedBlock(tx kv.RwTx, blockNum uint64) error blockNumBytes := dbCommon.Uint64ToBytes(blockNum) return tx.Put(p.lastBlockTable, lastBlokcKey, blockNumBytes) } + +func GenerateGlobalIndex(mainnetFlag bool, rollupIndex uint, localExitRootIndex uint32) *big.Int { + var ( + globalIndexBytes []byte + buf [4]byte + ) + if mainnetFlag { + globalIndexBytes = append(globalIndexBytes, big.NewInt(1).Bytes()...) + ri := big.NewInt(0).FillBytes(buf[:]) + globalIndexBytes = append(globalIndexBytes, ri...) + } else { + ri := big.NewInt(0).SetUint64(uint64(rollupIndex)).FillBytes(buf[:]) + globalIndexBytes = append(globalIndexBytes, ri...) + } + leri := big.NewInt(0).SetUint64(uint64(localExitRootIndex)).FillBytes(buf[:]) + globalIndexBytes = append(globalIndexBytes, leri...) + return big.NewInt(0).SetBytes(globalIndexBytes) +} diff --git a/claimsponsor/claimsponsor.go b/claimsponsor/claimsponsor.go index 204e868b..4b70f8e7 100644 --- a/claimsponsor/claimsponsor.go +++ b/claimsponsor/claimsponsor.go @@ -60,7 +60,7 @@ func (c *Claim) Key() []byte { type ClaimSender interface { checkClaim(ctx context.Context, claim *Claim) error sendClaim(ctx context.Context, claim *Claim) (string, error) - claimStatus(id string) (ClaimStatus, error) + claimStatus(ctx context.Context, id string) (ClaimStatus, error) } type ClaimSponsor struct { @@ -68,9 +68,17 @@ type ClaimSponsor struct { sender ClaimSender rh *sync.RetryHandler waitTxToBeMinedPeriod time.Duration + waitOnEmptyQueue time.Duration } -func newClaimSponsor(dbPath string) (*ClaimSponsor, error) { +func newClaimSponsor( + dbPath string, + sender ClaimSender, + retryAfterErrorPeriod time.Duration, + maxRetryAttemptsAfterError int, + waitTxToBeMinedPeriod time.Duration, + waitOnEmptyQueue time.Duration, +) (*ClaimSponsor, error) { tableCfgFunc := func(defaultBuckets kv.TableCfg) kv.TableCfg { cfg := kv.TableCfg{ claimTable: {}, @@ -85,8 +93,16 @@ func newClaimSponsor(dbPath string) (*ClaimSponsor, error) { if err != nil { return nil, err } + rh := &sync.RetryHandler{ + MaxRetryAttemptsAfterError: maxRetryAttemptsAfterError, + RetryAfterErrorPeriod: retryAfterErrorPeriod, + } return &ClaimSponsor{ - db: db, + db: db, + sender: sender, + rh: rh, + waitTxToBeMinedPeriod: waitTxToBeMinedPeriod, + waitOnEmptyQueue: waitOnEmptyQueue, }, nil } @@ -98,7 +114,7 @@ func (c *ClaimSponsor) Start(ctx context.Context) { for { if err != nil { attempts++ - c.rh.Handle("claimsponsor start", attempts) + c.rh.Handle("claimsponsor main loop", attempts) } tx, err2 := c.db.BeginRw(ctx) if err2 != nil { @@ -110,6 +126,12 @@ func (c *ClaimSponsor) Start(ctx context.Context) { if err2 != nil { err = err2 tx.Rollback() + if err == ErrNotFound { + log.Debugf("queue is empty") + err = nil + time.Sleep(c.waitOnEmptyQueue) + continue + } log.Errorf("error calling getFirstQueueIndex: %v", err) continue } @@ -182,6 +204,7 @@ func (c *ClaimSponsor) Start(ctx context.Context) { } attempts = 0 + log.Error("wtf: ", err) } } @@ -192,7 +215,7 @@ func (c *ClaimSponsor) waitTxToBeSuccessOrFail(ctx context.Context, txID string) case <-ctx.Done(): return "", errors.New("context cancelled") case <-t.C: - status, err := c.sender.claimStatus(txID) + status, err := c.sender.claimStatus(ctx, txID) if err != nil { return "", err } @@ -216,8 +239,10 @@ func (c *ClaimSponsor) AddClaimToQueue(ctx context.Context, claim *Claim) error _, err = getClaim(tx, claim.GlobalIndex) if err != ErrNotFound { if err != nil { + tx.Rollback() return err } else { + tx.Rollback() return errors.New("claim already added") } } @@ -228,12 +253,16 @@ func (c *ClaimSponsor) AddClaimToQueue(ctx context.Context, claim *Claim) error return err } + var queuePosition uint64 lastQueuePosition, _, err := getLastQueueIndex(tx) - if err != nil { + if err == ErrNotFound { + queuePosition = 0 + } else if err != nil { tx.Rollback() return err + } else { + queuePosition = lastQueuePosition + 1 } - queuePosition := lastQueuePosition + 1 err = tx.Put(queueTable, dbCommon.Uint64ToBytes(queuePosition), claim.Key()) if err != nil { tx.Rollback() diff --git a/claimsponsor/e2e_test.go b/claimsponsor/e2e_test.go index 0eda6e82..b2683be9 100644 --- a/claimsponsor/e2e_test.go +++ b/claimsponsor/e2e_test.go @@ -2,6 +2,7 @@ package claimsponsor_test import ( "context" + "errors" "fmt" "math/big" "testing" @@ -21,14 +22,22 @@ func TestE2EL1toEVML2(t *testing.T) { ctx := context.Background() env := helpers.SetupAggoracleWithEVMChain(t) dbPathBridgeSyncL1 := t.TempDir() - bridgeSyncL1, err := bridgesync.NewL1(ctx, dbPathBridgeSyncL1, env.BridgeL1Addr, 10, etherman.LatestBlock, env.ReorgDetector, env.L1Client.Client(), 0) + bridgeSyncL1, err := bridgesync.NewL1(ctx, dbPathBridgeSyncL1, env.BridgeL1Addr, 10, etherman.LatestBlock, env.ReorgDetector, env.L1Client.Client(), 0, time.Millisecond*10) require.NoError(t, err) go bridgeSyncL1.Start(ctx) // start claim sponsor dbPathClaimSponsor := t.TempDir() - ethTxMock := helpers.NewEthTxManagerMock(t) - claimer, err := claimsponsor.NewEVMClaimSponsor(dbPathClaimSponsor, env.L2Client.Client(), env.BridgeL2Addr, env.AuthL2.From, 100_000, 0, ethTxMock) + claimer, err := claimsponsor.NewEVMClaimSponsor( + dbPathClaimSponsor, + env.L2Client.Client(), + env.BridgeL2Addr, + env.AuthL2.From, + 200_000, + 0, + env.EthTxManMockL2, + 0, 0, time.Millisecond*10, time.Millisecond*10, + ) require.NoError(t, err) go claimer.Start(ctx) @@ -36,8 +45,8 @@ func TestE2EL1toEVML2(t *testing.T) { for i := 0; i < 10; i++ { // Send bridges to L2, wait for GER to be injected on L2 amount := big.NewInt(int64(i) + 1) + env.AuthL1.Value = amount _, err := env.BridgeL1Contract.BridgeAsset(env.AuthL1, env.NetworkIDL2, env.AuthL2.From, amount, common.Address{}, true, nil) - require.NoError(t, err) env.L1Client.Commit() time.Sleep(time.Millisecond * 50) expectedGER, err := env.GERL1Contract.GetLastGlobalExitRoot(&bind.CallOpts{Pending: false}) @@ -54,11 +63,12 @@ func TestE2EL1toEVML2(t *testing.T) { rollupProof, err := env.L1InfoTreeSync.GetRollupExitTreeMerkleProof(ctx, 0, common.Hash{}) // Request to sponsor claim - claimer.AddClaimToQueue(ctx, &claimsponsor.Claim{ + globalIndex := bridgesync.GenerateGlobalIndex(true, 0, uint32(i)) + err = claimer.AddClaimToQueue(ctx, &claimsponsor.Claim{ LeafType: 0, ProofLocalExitRoot: localProof, ProofRollupExitRoot: rollupProof, - GlobalIndex: nil, // TODO + GlobalIndex: globalIndex, MainnetExitRoot: info.MainnetExitRoot, RollupExitRoot: info.RollupExitRoot, OriginNetwork: 0, @@ -68,8 +78,22 @@ func TestE2EL1toEVML2(t *testing.T) { Amount: amount, Metadata: nil, }) + require.NoError(t, err) - // TODO: Wait until success + // Wait until success + succeed := false + for i := 0; i < 10; i++ { + claim, err := claimer.GetClaim(ctx, globalIndex) + require.NoError(t, err) + if claim.Status == claimsponsor.FailedClaimStatus { + require.NoError(t, errors.New("claim failed")) + } else if claim.Status == claimsponsor.SuccessClaimStatus { + succeed = true + break + } + time.Sleep(50 * time.Millisecond) + } + require.True(t, succeed) // Check on contract that is claimed isClaimed, err := env.BridgeL2Contract.IsClaimed(&bind.CallOpts{Pending: false}, uint32(i), 0) diff --git a/claimsponsor/evmclaimsponsor.go b/claimsponsor/evmclaimsponsor.go index 111a5ebd..fe01d2b5 100644 --- a/claimsponsor/evmclaimsponsor.go +++ b/claimsponsor/evmclaimsponsor.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math/big" + "time" "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmbridgev2" "github.com/0xPolygonHermez/zkevm-ethtx-manager/ethtxmanager" @@ -53,6 +54,10 @@ func NewEVMClaimSponsor( sender common.Address, maxGas, gasOffset uint64, ethTxManager EthTxManager, + retryAfterErrorPeriod time.Duration, + maxRetryAttemptsAfterError int, + waitTxToBeMinedPeriod time.Duration, + waitOnEmptyQueue time.Duration, ) (*EVMClaimSponsor, error) { contract, err := polygonzkevmbridgev2.NewPolygonzkevmbridgev2(bridge, l2Client) if err != nil { @@ -62,12 +67,7 @@ func NewEVMClaimSponsor( if err != nil { return nil, err } - sponsor, err := newClaimSponsor(dbPath) - if err != nil { - return nil, err - } - return &EVMClaimSponsor{ - ClaimSponsor: sponsor, + evmSponsor := &EVMClaimSponsor{ l2Client: l2Client, bridgeABI: abi, bridgeAddr: bridge, @@ -76,7 +76,20 @@ func NewEVMClaimSponsor( gasOffest: gasOffset, maxGas: maxGas, ethTxManager: ethTxManager, - }, nil + } + baseSponsor, err := newClaimSponsor( + dbPath, + evmSponsor, + retryAfterErrorPeriod, + maxRetryAttemptsAfterError, + waitTxToBeMinedPeriod, + waitOnEmptyQueue, + ) + if err != nil { + return nil, err + } + evmSponsor.ClaimSponsor = baseSponsor + return evmSponsor, nil } func (c *EVMClaimSponsor) checkClaim(ctx context.Context, claim *Claim) error { @@ -98,7 +111,7 @@ func (c *EVMClaimSponsor) checkClaim(ctx context.Context, claim *Claim) error { return nil } -func (c *EVMClaimSponsor) sendTx(ctx context.Context, claim *Claim) (string, error) { +func (c *EVMClaimSponsor) sendClaim(ctx context.Context, claim *Claim) (string, error) { data, err := c.buildClaimTxData(claim) if err != nil { return "", err diff --git a/l1bridge2infoindexsync/e2e_test.go b/l1bridge2infoindexsync/e2e_test.go index 71f5a008..561a7b0c 100644 --- a/l1bridge2infoindexsync/e2e_test.go +++ b/l1bridge2infoindexsync/e2e_test.go @@ -135,7 +135,7 @@ func TestE2E(t *testing.T) { rd, err := reorgdetector.New(ctx, client.Client(), dbPathReorg) go rd.Start(ctx) - bridgeSync, err := bridgesync.NewL1(ctx, dbPathBridgeSync, bridgeAddr, 10, etherman.LatestBlock, rd, client.Client(), 0) + bridgeSync, err := bridgesync.NewL1(ctx, dbPathBridgeSync, bridgeAddr, 10, etherman.LatestBlock, rd, client.Client(), 0, time.Millisecond*10) require.NoError(t, err) go bridgeSync.Start(ctx) diff --git a/test/helpers/aggoracle_e2e.go b/test/helpers/aggoracle_e2e.go index 86db8a45..c2908b8d 100644 --- a/test/helpers/aggoracle_e2e.go +++ b/test/helpers/aggoracle_e2e.go @@ -3,28 +3,25 @@ package helpers import ( "context" "errors" + "fmt" "math/big" "testing" "time" - "github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmbridgev2" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/elderberry-paris/polygonzkevmbridgev2" gerContractL1 "github.com/0xPolygon/cdk-contracts-tooling/contracts/manual/globalexitrootnopush0" gerContractEVMChain "github.com/0xPolygon/cdk-contracts-tooling/contracts/manual/pessimisticglobalexitrootnopush0" "github.com/0xPolygon/cdk/aggoracle" "github.com/0xPolygon/cdk/aggoracle/chaingersender" "github.com/0xPolygon/cdk/etherman" "github.com/0xPolygon/cdk/l1infotreesync" - "github.com/0xPolygon/cdk/log" "github.com/0xPolygon/cdk/reorgdetector" "github.com/0xPolygon/cdk/test/contracts/transparentupgradableproxy" - "github.com/0xPolygonHermez/zkevm-ethtx-manager/ethtxmanager" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient/simulated" - "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -50,13 +47,14 @@ type AggoracleWithEVMChainEnv struct { BridgeL2Contract *polygonzkevmbridgev2.Polygonzkevmbridgev2 BridgeL2Addr common.Address NetworkIDL2 uint32 + EthTxManMockL2 *EthTxManagerMock } 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 := EVMSetup(t) - oracle, err := aggoracle.New(sender, l1Client.Client(), syncer, etherman.LatestBlock, time.Millisecond) + sender, l2Client, gerL2Contract, gerL2Addr, bridgeL2Contract, bridgeL2Addr, authL2, ethTxManMockL2 := EVMSetup(t) + oracle, err := aggoracle.New(sender, l1Client.Client(), syncer, etherman.LatestBlock, time.Millisecond*20) require.NoError(t, err) go oracle.Start(ctx) @@ -77,6 +75,8 @@ func SetupAggoracleWithEVMChain(t *testing.T) *AggoracleWithEVMChainEnv { BridgeL1Addr: bridgeL1Addr, BridgeL2Contract: bridgeL2Contract, BridgeL2Addr: bridgeL2Addr, + NetworkIDL2: NetworkIDL2, + EthTxManMockL2: ethTxManMockL2, } } @@ -120,6 +120,7 @@ func EVMSetup(t *testing.T) ( *polygonzkevmbridgev2.Polygonzkevmbridgev2, common.Address, *bind.TransactOpts, + *EthTxManagerMock, ) { privateKeyL2, err := crypto.GenerateKey() require.NoError(t, err) @@ -127,69 +128,11 @@ func EVMSetup(t *testing.T) ( require.NoError(t, err) l2Client, gerL2Addr, gerL2Sc, bridgeL2Addr, bridgeL2Sc, err := newSimulatedEVMAggSovereignChain(authL2) require.NoError(t, err) - ethTxManMock := NewEthTxManagerMock(t) - // id, err := c.ethTxMan.Add(ctx, &c.gerAddr, nil, big.NewInt(0), tx.Data(), c.gasOffset, nil) - ethTxManMock.On("Add", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). - Run(func(args mock.Arguments) { - ctx := context.Background() - nonce, err := l2Client.Client().PendingNonceAt(ctx, authL2.From) - if err != nil { - log.Error(err) - return - } - gas, err := l2Client.Client().EstimateGas(ctx, ethereum.CallMsg{ - From: authL2.From, - To: args.Get(1).(*common.Address), - Value: big.NewInt(0), - Data: args.Get(4).([]byte), - }) - if err != nil { - log.Error(err) - res, err := l2Client.Client().CallContract(ctx, ethereum.CallMsg{ - From: authL2.From, - To: args.Get(1).(*common.Address), - Value: big.NewInt(0), - Data: args.Get(4).([]byte), - }, nil) - log.Debugf("contract call: %s", res) - if err != nil { - log.Error(err) - } - return - } - price, err := l2Client.Client().SuggestGasPrice(ctx) - if err != nil { - log.Error(err) - } - tx := types.NewTx(&types.LegacyTx{ - To: args.Get(1).(*common.Address), - Nonce: nonce, - Value: big.NewInt(0), - Data: args.Get(4).([]byte), - Gas: gas, - GasPrice: price, - }) - tx.Gas() - signedTx, err := authL2.Signer(authL2.From, tx) - if err != nil { - log.Error(err) - return - } - err = l2Client.Client().SendTransaction(ctx, signedTx) - if err != nil { - log.Error(err) - return - } - l2Client.Commit() - }). - Return(common.Hash{}, nil) - // res, err := c.ethTxMan.Result(ctx, id) - ethTxManMock.On("Result", mock.Anything, mock.Anything). - Return(ethtxmanager.MonitoredTxResult{Status: ethtxmanager.MonitoredTxStatusMined}, nil) + ethTxManMock := NewEthTxManMock(t, l2Client, authL2) sender, err := chaingersender.NewEVMChainGERSender(gerL2Addr, authL2.From, l2Client.Client(), ethTxManMock, 0, time.Millisecond*50) require.NoError(t, err) - return sender, l2Client, gerL2Sc, gerL2Addr, bridgeL2Sc, bridgeL2Addr, authL2 + return sender, l2Client, gerL2Sc, gerL2Addr, bridgeL2Sc, bridgeL2Addr, authL2, ethTxManMock } func newSimulatedL1(auth *bind.TransactOpts) ( @@ -212,6 +155,9 @@ func newSimulatedL1(auth *bind.TransactOpts) ( address: { Balance: balance, }, + authDeployer.From: { + Balance: balance, + }, } blockGasLimit := uint64(999999999999999999) //nolint:gomnd client = simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit)) @@ -261,19 +207,19 @@ func newSimulatedL1(auth *bind.TransactOpts) ( if err != nil { return } - checkGERAddr, err := bridgeContract.GlobalExitRootManager(&bind.CallOpts{}) + checkGERAddr, err := bridgeContract.GlobalExitRootManager(&bind.CallOpts{Pending: false}) if err != nil { return } if precalculatedAddr != checkGERAddr { - err = errors.New("error deploying bridge") + err = fmt.Errorf("error deploying bridge, unexpected GER addr. Expected %s. Actual %s", precalculatedAddr.Hex(), checkGERAddr.Hex()) } - gerAddr, _, gerContract, err = gerContractL1.DeployGlobalexitrootnopush0(auth, client.Client(), auth.From, auth.From) + gerAddr, _, gerContract, err = gerContractL1.DeployGlobalexitrootnopush0(authDeployer, client.Client(), auth.From, bridgeAddr) client.Commit() if precalculatedAddr != gerAddr { - err = errors.New("error calculating addr") + err = fmt.Errorf("error calculating addr. Expected %s. Actual %s", precalculatedAddr.Hex(), gerAddr.Hex()) } return } @@ -294,10 +240,17 @@ func newSimulatedEVMAggSovereignChain(auth *bind.TransactOpts) ( authDeployer, err := bind.NewKeyedTransactorWithChainID(privateKeyL1, big.NewInt(1337)) balance, _ := new(big.Int).SetString("10000000000000000000000000", 10) //nolint:gomnd address := auth.From + precalculatedBridgeAddr := crypto.CreateAddress(authDeployer.From, 1) genesisAlloc := map[common.Address]types.Account{ address: { Balance: balance, }, + authDeployer.From: { + Balance: balance, + }, + precalculatedBridgeAddr: { + Balance: balance, + }, } blockGasLimit := uint64(999999999999999999) //nolint:gomnd client = simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit)) @@ -342,6 +295,10 @@ func newSimulatedEVMAggSovereignChain(auth *bind.TransactOpts) ( if err != nil { return } + if bridgeAddr != precalculatedBridgeAddr { + err = fmt.Errorf("error calculating bridge addr. Expected: %s. Actual: %s", precalculatedBridgeAddr, bridgeAddr) + return + } client.Commit() bridgeContract, err = polygonzkevmbridgev2.NewPolygonzkevmbridgev2(bridgeAddr, client.Client()) if err != nil { @@ -355,14 +312,14 @@ func newSimulatedEVMAggSovereignChain(auth *bind.TransactOpts) ( err = errors.New("error deploying bridge") } - gerAddr, _, gerContract, err = gerContractEVMChain.DeployPessimisticglobalexitrootnopush0(auth, client.Client(), auth.From) + gerAddr, _, gerContract, err = gerContractEVMChain.DeployPessimisticglobalexitrootnopush0(authDeployer, client.Client(), auth.From) if err != nil { return } client.Commit() _GLOBAL_EXIT_ROOT_SETTER_ROLE := common.HexToHash("0x7b95520991dfda409891be0afa2635b63540f92ee996fda0bf695a166e5c5176") - _, err = gerContract.GrantRole(auth, _GLOBAL_EXIT_ROOT_SETTER_ROLE, auth.From) + _, err = gerContract.GrantRole(authDeployer, _GLOBAL_EXIT_ROOT_SETTER_ROLE, auth.From) client.Commit() hasRole, _ := gerContract.HasRole(&bind.CallOpts{Pending: false}, _GLOBAL_EXIT_ROOT_SETTER_ROLE, auth.From) if !hasRole { diff --git a/test/helpers/ethtxmanmock_e2e.go b/test/helpers/ethtxmanmock_e2e.go new file mode 100644 index 00000000..b63ecc49 --- /dev/null +++ b/test/helpers/ethtxmanmock_e2e.go @@ -0,0 +1,83 @@ +package helpers + +import ( + "context" + "math/big" + "testing" + + "github.com/0xPolygon/cdk/log" + "github.com/0xPolygonHermez/zkevm-ethtx-manager/ethtxmanager" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient/simulated" + "github.com/stretchr/testify/mock" +) + +func NewEthTxManMock( + t *testing.T, + client *simulated.Backend, + auth *bind.TransactOpts, +) *EthTxManagerMock { + 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) { + ctx := context.Background() + nonce, err := client.Client().PendingNonceAt(ctx, auth.From) + if err != nil { + log.Error(err) + return + } + 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), + }) + 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), + }, nil) + log.Debugf("contract call: %s", res) + if err != nil { + log.Errorf("%+v", err) + } + return + } + price, err := client.Client().SuggestGasPrice(ctx) + if err != nil { + log.Error(err) + } + tx := types.NewTx(&types.LegacyTx{ + To: args.Get(1).(*common.Address), + Nonce: nonce, + Value: big.NewInt(0), + Data: args.Get(4).([]byte), + Gas: gas, + GasPrice: price, + }) + tx.Gas() + signedTx, err := auth.Signer(auth.From, tx) + if err != nil { + log.Error(err) + return + } + err = client.Client().SendTransaction(ctx, signedTx) + if err != nil { + log.Error(err) + return + } + client.Commit() + }). + Return(common.Hash{}, nil) + // res, err := c.ethTxMan.Result(ctx, id) + ethTxMock.On("Result", mock.Anything, mock.Anything). + Return(ethtxmanager.MonitoredTxResult{Status: ethtxmanager.MonitoredTxStatusMined}, nil) + + return ethTxMock +}