From 575b7b3c0e000091f39029c40225ad609b453b3b Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Thu, 7 Dec 2023 12:29:05 +0100 Subject: [PATCH 01/12] test setup --- .gitignore | 3 +- cmd/main.go | 17 +++- etherman/ethclient_mock.go | 132 ++++++++++++++++++++++++++++++ etherman/etherman.go | 20 +---- etherman/etherman_test.go | 159 +++++++++++++++++++++++++++++++++++++ 5 files changed, 312 insertions(+), 19 deletions(-) create mode 100644 etherman/ethclient_mock.go create mode 100644 etherman/etherman_test.go diff --git a/.gitignore b/.gitignore index 6c3a496..f7390e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ dist -docker/data \ No newline at end of file +docker/data +.idea diff --git a/cmd/main.go b/cmd/main.go index 48c241f..7f54983 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/urfave/cli/v2" "math/big" "net/http" "os" @@ -19,7 +21,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/crypto" "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/urfave/cli/v2" "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/sdk/metric" @@ -93,7 +94,19 @@ func start(cliCtx *cli.Context) error { if err != nil { log.Fatal(err) } - ethMan, err := etherman.New(cliCtx.Context, c.L1.NodeURL, *auth) + + // Connect to ethereum node + ethClient, err := ethclient.DialContext(cliCtx.Context, c.L1.NodeURL) + if err != nil { + log.Fatal("error connecting to %s: %+v", url, err) + } + + // Make sure the connection is okay + if _, err = ethClient.ChainID(cliCtx.Context); err != nil { + log.Fatal("error getting chain ID from l1 with address: %+v", err) + } + + ethMan, err := etherman.New(ethClient, *auth) if err != nil { log.Fatal(err) } diff --git a/etherman/ethclient_mock.go b/etherman/ethclient_mock.go new file mode 100644 index 0000000..07c7b7f --- /dev/null +++ b/etherman/ethclient_mock.go @@ -0,0 +1,132 @@ +package etherman + +import ( + "context" + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/mock" + "math/big" +) + +type ethereumClientMock struct { + mock.Mock +} + +func (e *ethereumClientMock) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { + //TODO implement me + panic("implement me") +} + +func (e *ethereumClientMock) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { + args := e.Called(ctx, call, blockNumber) + + return args.Get(0).([]byte), args.Error(1) +} + +func (e *ethereumClientMock) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + args := e.Called(ctx, txHash) + + return args.Get(0).(*types.Receipt), args.Error(1) +} + +func (e *ethereumClientMock) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) { + args := e.Called(ctx, account, blockNumber) + + return args.Get(0).(uint64), args.Error(1) +} + +func (e *ethereumClientMock) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) { + args := e.Called(ctx, txHash) + + return args.Get(0).(*types.Transaction), args.Bool(1), args.Error(2) +} + +func (e *ethereumClientMock) SendTransaction(ctx context.Context, tx *types.Transaction) error { + args := e.Called(ctx, tx) + + return args.Error(0) +} + +func (e *ethereumClientMock) SuggestGasPrice(ctx context.Context) (*big.Int, error) { + args := e.Called(ctx) + + return args.Get(0).(*big.Int), args.Error(1) +} + +func (e *ethereumClientMock) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) { + args := e.Called(ctx, call) + + return args.Get(0).(uint64), args.Error(1) +} + +func (e *ethereumClientMock) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { + args := e.Called(ctx, number) + + return args.Get(0).(*types.Block), args.Error(1) +} diff --git a/etherman/etherman.go b/etherman/etherman.go index 560a879..839b4b3 100644 --- a/etherman/etherman.go +++ b/etherman/etherman.go @@ -15,7 +15,6 @@ import ( "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" "github.com/jackc/pgx/v4" ) @@ -24,20 +23,7 @@ type Etherman struct { auth bind.TransactOpts } -func New(ctx context.Context, url string, auth bind.TransactOpts) (Etherman, error) { - // Connect to ethereum node - ethClient, err := ethclient.DialContext(ctx, url) - if err != nil { - log.Errorf("error connecting to %s: %+v", url, err) - return Etherman{}, err - } - - // Make sure the connection is okay - if _, err = ethClient.ChainID(ctx); err != nil { - log.Errorf("error getting chain ID from l1 with %s address: %+v", url, err) - return Etherman{}, err - } - +func New(ethClient EthereumClient, auth bind.TransactOpts) (Etherman, error) { return Etherman{ ethClient: ethClient, auth: auth, @@ -49,7 +35,8 @@ func (e *Etherman) GetSequencerAddr(l1Contract common.Address) (common.Address, if err != nil { return common.Address{}, err } - return contract.TrustedSequencer(&bind.CallOpts{Pending: false}) + + return contract.TrustedSequencer(&bind.CallOpts{Pending: false}), nil } func (e *Etherman) BuildTrustedVerifyBatchesTxData(lastVerifiedBatch, newVerifiedBatch uint64, proof tx.ZKP) (data []byte, err error) { @@ -69,6 +56,7 @@ func (e *Etherman) BuildTrustedVerifyBatchesTxData(lastVerifiedBatch, newVerifie log.Errorf("error geting ABI: %v, Proof: %s", err) return nil, err } + return abi.Pack( "verifyBatchesTrustedAggregator", pendStateNum, diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go new file mode 100644 index 0000000..f41ba34 --- /dev/null +++ b/etherman/etherman_test.go @@ -0,0 +1,159 @@ +package etherman + +import ( + "context" + "github.com/0xPolygon/beethoven/tx" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "math/big" + "testing" +) + +func signer(from common.Address, tx *types.Transaction) (*types.Transaction, error) { + return tx, nil +} + +type EthermanTestSuite struct { + suite.Suite + ethman *Etherman +} + +func (suite *EthermanTestSuite) SetupTest() { + ethman, _ := New( + new(ethereumClientMock), + bind.TransactOpts{ + From: common.HexToAddress("0x742d35Cc6634C0532925a3b844Bc454e4438f44e"), + Nonce: big.NewInt(0), + Signer: signer, + Value: big.NewInt(0), + GasPrice: big.NewInt(0), + GasTipCap: big.NewInt(0), + GasLimit: 0, + Context: context.TODO(), + NoSend: false, + }, + ) + + suite.ethman = ðman +} + +/*func (suite *EthermanTestSuite) TestGetSequencerAddr(t *testing.T) { + t.Parallel() + + t.Run("Returns expected error", func(t *testing.T) { + t.Parallel() + + _, err := suite.ethman.GetSequencerAddr() + + assert.NotNil(t, err) + }) + + t.Run("Returns expected sequencer address", func(t *testing.T) { + t.Parallel() + + address, err := suite.ethman.GetSequencerAddr() + + assert.Equal(t, err, nil) + assert.Equal(t, address, common.HexToAddress("0x71c7656ec7ab88b098defb751b7401b5f6d8976f")) + }) +}*/ + +func (suite *EthermanTestSuite) TestBuildTrustedVerifyBatches(t *testing.T) { + t.Parallel() + assert := assert.New(t) + + t.Run("Return expected ABI encoded bytes array", func(t *testing.T) { + data, err := suite.ethman.BuildTrustedVerifyBatches( + 0, + 1, + tx.ZKP{ + NewStateRoot: common.HexToHash("0x001"), + NewLocalExitRoot: common.HexToHash("0x002"), + Proof: common.Hex2Bytes("0x003"), + }, + ) + + assert.Equal(data, "") + assert.Nil(err) + }) +} + +/** + +func TestBuildTrustedVerifyBatchesTxDataAndReturnProofConvertionError() { + +} + +func TestBuildTrustedVerifyBatchesTxDataAndReturnABIError() { + +} + +func TestBuildTrustedVerifyBatchesTxDataAndReturnExpectedPackedRLPValue() { + +} + + +func TestCallContractAndReturnExpectedValue() { + +} + +func TestCallContractAndReturnExpectedError() { + +} + + +func TestCheckTxWasMinedAndReceiptCouldntGetFound() { + +} + +func TestCheckTxWasMinedAndReturnsTheExpectedGenericError() { + +} + +func TestCheckTXWasMinedAndReturnsTheExpectedReceipt() { + +} + + +func TestCurrentNonceAndReturnExpectedValue() { + +} + +func TestCurrentNonceAndReturnExpectedError() { + +} + + +func TestGetTxAndReturnExpectedValue() { + +} + +func TestGetTxAndReturnExpextedError() { + +} + + +func TestGetTxReceiptAndReturnExpectedValue() { + +} + +func TestGetTxReceiptAndReturnExpectedError() { + +} + + +func TestWaitTxToBeMinedAndReturnExpectedDeadlineExceededError() { + +} + +func TestWaitTxToBeMinedAndReturnTheExpectedGenericError() { + +} + +func TestWaitTXToBeMinedAndReturnExpectedValue() { + +} +*/ From fef323130593af0a147814292e46b39551983dd4 Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Wed, 13 Dec 2023 10:12:41 +0100 Subject: [PATCH 02/12] etherman test created with the exception of a few cases --- etherman/etherman.go | 8 +- etherman/etherman_test.go | 795 ++++++++++++++++++++++++-- {etherman => mocks}/ethclient_mock.go | 55 +- 3 files changed, 779 insertions(+), 79 deletions(-) rename {etherman => mocks}/ethclient_mock.go (61%) diff --git a/etherman/etherman.go b/etherman/etherman.go index 839b4b3..13cf738 100644 --- a/etherman/etherman.go +++ b/etherman/etherman.go @@ -15,7 +15,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/jackc/pgx/v4" ) type Etherman struct { @@ -36,7 +35,7 @@ func (e *Etherman) GetSequencerAddr(l1Contract common.Address) (common.Address, return common.Address{}, err } - return contract.TrustedSequencer(&bind.CallOpts{Pending: false}), nil + return contract.TrustedSequencer(&bind.CallOpts{Pending: false}) } func (e *Etherman) BuildTrustedVerifyBatchesTxData(lastVerifiedBatch, newVerifiedBatch uint64, proof tx.ZKP) (data []byte, err error) { @@ -148,7 +147,7 @@ func (e *Etherman) EstimateGas(ctx context.Context, from common.Address, to *com } // SignTx tries to sign a transaction accordingly to the provided sender -func (e *Etherman) SignTx(ctx context.Context, sender common.Address, tx *types.Transaction) (*types.Transaction, error) { +func (e *Etherman) SignTx(tx *types.Transaction) (*types.Transaction, error) { return e.auth.Signer(e.auth.From, tx) } @@ -165,6 +164,7 @@ func (e *Etherman) GetRevertMessage(ctx context.Context, tx *types.Transaction) if receipt.Status == types.ReceiptStatusFailed { revertMessage, err := operations.RevertReason(ctx, e.ethClient, tx, receipt.BlockNumber) + if err != nil { return "", err } @@ -173,7 +173,7 @@ func (e *Etherman) GetRevertMessage(ctx context.Context, tx *types.Transaction) return "", nil } -func (e *Etherman) GetLastBlock(ctx context.Context, dbTx pgx.Tx) (*state.Block, error) { +func (e *Etherman) GetLastBlock(ctx context.Context) (*state.Block, error) { block, err := e.ethClient.BlockByNumber(ctx, nil) if err != nil { return nil, err diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go index f41ba34..33a70cd 100644 --- a/etherman/etherman_test.go +++ b/etherman/etherman_test.go @@ -2,12 +2,16 @@ package etherman import ( "context" + "errors" + "github.com/0xPolygon/beethoven/mocks" "github.com/0xPolygon/beethoven/tx" + cdkTypes "github.com/0xPolygon/cdk-validium-node/jsonrpc/types" + "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/stretchr/testify/assert" - "github.com/stretchr/testify/suite" + "github.com/stretchr/testify/mock" "math/big" "testing" ) @@ -16,14 +20,9 @@ func signer(from common.Address, tx *types.Transaction) (*types.Transaction, err return tx, nil } -type EthermanTestSuite struct { - suite.Suite - ethman *Etherman -} - -func (suite *EthermanTestSuite) SetupTest() { +func getEtherman(ethClientMock EthereumClient) Etherman { ethman, _ := New( - new(ethereumClientMock), + ethClientMock, bind.TransactOpts{ From: common.HexToAddress("0x742d35Cc6634C0532925a3b844Bc454e4438f44e"), Nonce: big.NewInt(0), @@ -37,123 +36,823 @@ func (suite *EthermanTestSuite) SetupTest() { }, ) - suite.ethman = ðman + return ethman } -/*func (suite *EthermanTestSuite) TestGetSequencerAddr(t *testing.T) { +func TestGetSequencerAddr(t *testing.T) { t.Parallel() + assert := assert.New(t) - t.Run("Returns expected error", func(t *testing.T) { + t.Run("Returns expected error (improperly formatted output)", func(t *testing.T) { t.Parallel() - _, err := suite.ethman.GetSequencerAddr() + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "CallContract", + mock.Anything, + ethereum.CallMsg{ + From: common.HexToAddress("0x0000000000000000000000000000000000000000"), + To: &common.Address{}, + Gas: 0, + GasPrice: nil, + GasFeeCap: nil, + GasTipCap: nil, + Value: nil, + Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, + }, + (*big.Int)(nil), + ).Return( // Invalid return value below to provocate error + common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000000000"), + nil, + ).Once() + + _, err := ethman.GetSequencerAddr(common.HexToAddress("0x0000000000000000000000000000000000000000")) - assert.NotNil(t, err) + assert.ErrorContains(err, "abi: improperly formatted output:") + ethClient.AssertExpectations(t) }) t.Run("Returns expected sequencer address", func(t *testing.T) { t.Parallel() - address, err := suite.ethman.GetSequencerAddr() + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "CallContract", + mock.Anything, + ethereum.CallMsg{ + From: common.HexToAddress("0x0000000000000000000000000000000000000000"), + To: &common.Address{}, + Gas: 0, + GasPrice: nil, + GasFeeCap: nil, + GasTipCap: nil, + Value: nil, + Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, + }, + (*big.Int)(nil), + ).Return( // Invalid return value below to provocate error + common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000000"), + nil, + ).Once() + + returnValue, _ := ethman.GetSequencerAddr(common.HexToAddress("0x0000000000000000000000000000000000000000")) - assert.Equal(t, err, nil) - assert.Equal(t, address, common.HexToAddress("0x71c7656ec7ab88b098defb751b7401b5f6d8976f")) + assert.Equal(returnValue, common.Address{}) + ethClient.AssertExpectations(t) }) -}*/ +} -func (suite *EthermanTestSuite) TestBuildTrustedVerifyBatches(t *testing.T) { +func TestBuildTrustedVerifyBatches(t *testing.T) { t.Parallel() assert := assert.New(t) + ethman := getEtherman(new(mocks.EthereumClientMock)) - t.Run("Return expected ABI encoded bytes array", func(t *testing.T) { - data, err := suite.ethman.BuildTrustedVerifyBatches( + // Because we cant mock the ABI dependency is this the only test case that we somehow + // can have here in a unit test. Further test coverage can get achieved with e2e or integration tests. + t.Run("Returns expected error on proof conversion", func(t *testing.T) { + data, err := ethman.BuildTrustedVerifyBatchesTxData( 0, 1, tx.ZKP{ NewStateRoot: common.HexToHash("0x001"), NewLocalExitRoot: common.HexToHash("0x002"), - Proof: common.Hex2Bytes("0x003"), + Proof: cdkTypes.ArgBytes("0x30030030030003003300300030033003000300330030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030003003003000300300300030030030"), }, ) - assert.Equal(data, "") - assert.Nil(err) + assert.ErrorContains(err, "invalid proof length. Expected length: 1538, Actual length 1534") + assert.Nil(data) }) } -/** +func TestCallContract(t *testing.T) { + t.Parallel() + assert := assert.New(t) -func TestBuildTrustedVerifyBatchesTxDataAndReturnProofConvertionError() { + t.Run("Returns expected value", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "CallContract", + context.TODO(), + ethereum.CallMsg{ + From: common.HexToAddress("0x0000000000000000000000000000000000000000"), + To: &common.Address{}, + Gas: 0, + GasPrice: nil, + GasFeeCap: nil, + GasTipCap: nil, + Value: nil, + Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, // TrustedSequencer sig + }, + (*big.Int)(nil), + ).Return( // Invalid return value below to provocate error + common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"), + nil, + ).Once() + + result, err := ethman.CallContract( + context.TODO(), + ethereum.CallMsg{ + From: common.HexToAddress("0x0000000000000000000000000000000000000000"), + To: &common.Address{}, + Gas: 0, + GasPrice: nil, + GasFeeCap: nil, + GasTipCap: nil, + Value: nil, + Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, + }, + (*big.Int)(nil), + ) -} + assert.Equal(result, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")) + assert.Equal(err, nil) + ethClient.AssertExpectations(t) + }) -func TestBuildTrustedVerifyBatchesTxDataAndReturnABIError() { + t.Run("Returns expected error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "CallContract", + context.TODO(), + ethereum.CallMsg{ + From: common.HexToAddress("0x0000000000000000000000000000000000000000"), + To: &common.Address{}, + Gas: 0, + GasPrice: nil, + GasFeeCap: nil, + GasTipCap: nil, + Value: nil, + Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, // TrustedSequencer sig + }, + (*big.Int)(nil), + ).Return( // Invalid return value below to provocate error + []uint8{}, + errors.New("NOOOPE!"), + ).Once() + + result, err := ethman.CallContract( + context.TODO(), + ethereum.CallMsg{ + From: common.HexToAddress("0x0000000000000000000000000000000000000000"), + To: &common.Address{}, + Gas: 0, + GasPrice: nil, + GasFeeCap: nil, + GasTipCap: nil, + Value: nil, + Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, + }, + (*big.Int)(nil), + ) + assert.Equal(result, []uint8{}) + assert.ErrorContains(err, "NOOOPE!") + ethClient.AssertExpectations(t) + }) } -func TestBuildTrustedVerifyBatchesTxDataAndReturnExpectedPackedRLPValue() { +func TestCheckTxWasMined(t *testing.T) { + t.Parallel() + assert := assert.New(t) -} + t.Run("Returns expected error on 'ethereum.NotFound'", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "TransactionReceipt", + context.TODO(), + common.Hash{}, + ).Return( + &types.Receipt{}, + errors.New("not found"), + ).Once() + + status, receipt, err := ethman.CheckTxWasMined(context.TODO(), common.Hash{}) + + assert.False(status) + assert.Nil(receipt) + assert.ErrorContains(err, "not found") + ethClient.AssertExpectations(t) + }) + t.Run("Returns expected error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "TransactionReceipt", + context.TODO(), + common.Hash{}, + ).Return( + &types.Receipt{}, + errors.New("Nooope!"), + ).Once() + + status, receipt, err := ethman.CheckTxWasMined(context.TODO(), common.Hash{}) + + assert.False(status) + assert.Nil(receipt) + assert.ErrorContains(err, "Nooope!") + ethClient.AssertExpectations(t) + }) -func TestCallContractAndReturnExpectedValue() { + t.Run("Returns the expected values", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) -} + ethClient.On( + "TransactionReceipt", + context.TODO(), + common.Hash{}, + ).Return( + &types.Receipt{}, + nil, + ).Once() -func TestCallContractAndReturnExpectedError() { + status, receipt, err := ethman.CheckTxWasMined(context.TODO(), common.Hash{}) + assert.True(status) + assert.Equal(receipt, &types.Receipt{}) + assert.Nil(err) + ethClient.AssertExpectations(t) + }) } +func TestCurrentNonce(t *testing.T) { + t.Parallel() + assert := assert.New(t) -func TestCheckTxWasMinedAndReceiptCouldntGetFound() { + t.Run("Returns the expected nonce value", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) -} + ethClient.On( + "NonceAt", + context.TODO(), + common.Address{}, + (*big.Int)(nil), + ).Return( + uint64(1), + nil, + ).Once() + + result, err := ethman.CurrentNonce(context.TODO(), common.Address{}) -func TestCheckTxWasMinedAndReturnsTheExpectedGenericError() { + assert.Equal(result, uint64(1)) + assert.Nil(err) + ethClient.AssertExpectations(t) + }) + t.Run("Returns the expected error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "NonceAt", + context.TODO(), + common.Address{}, + (*big.Int)(nil), + ).Return( + uint64(0), + errors.New("NA NA NA!"), + ).Once() + + result, err := ethman.CurrentNonce(context.TODO(), common.Address{}) + + assert.Equal(result, uint64(0)) + assert.ErrorContains(err, "NA NA NA!") + ethClient.AssertExpectations(t) + }) } -func TestCheckTXWasMinedAndReturnsTheExpectedReceipt() { +func TestGetTx(t *testing.T) { + t.Parallel() + assert := assert.New(t) -} + t.Run("Returns the expected transaction", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "TransactionByHash", + context.TODO(), + common.Hash{}, + ).Return( + &types.Transaction{}, + true, + nil, + ).Once() + transaction, status, err := ethman.GetTx(context.TODO(), common.Hash{}) -func TestCurrentNonceAndReturnExpectedValue() { + assert.Equal(transaction, &types.Transaction{}) + assert.True(status) + assert.Nil(err) + ethClient.AssertExpectations(t) + }) + t.Run("Returns the expected error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "TransactionByHash", + context.TODO(), + common.Hash{}, + ).Return( + &types.Transaction{}, + false, + errors.New("NOPE NOPE!"), + ).Once() + + transaction, status, err := ethman.GetTx(context.TODO(), common.Hash{}) + + assert.Equal(transaction, &types.Transaction{}) + assert.False(status) + assert.ErrorContains(err, "NOPE NOPE!") + ethClient.AssertExpectations(t) + }) } -func TestCurrentNonceAndReturnExpectedError() { +func TestGetTxReceipt(t *testing.T) { + t.Parallel() + assert := assert.New(t) -} + t.Run("Returns expected receipt", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + ethClient.On( + "TransactionReceipt", + context.TODO(), + common.Hash{}, + ).Return( + &types.Receipt{}, + nil, + ).Once() -func TestGetTxAndReturnExpectedValue() { + receipt, err := ethman.GetTxReceipt(context.TODO(), common.Hash{}) + assert.Equal(receipt, &types.Receipt{}) + assert.Nil(err) + ethClient.AssertExpectations(t) + }) + + t.Run("Returns expected error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "TransactionReceipt", + context.TODO(), + common.Hash{}, + ).Return( + &types.Receipt{}, + errors.New("NANANA!"), + ).Once() + + receipt, err := ethman.GetTxReceipt(context.TODO(), common.Hash{}) + + assert.Equal(receipt, &types.Receipt{}) + assert.ErrorContains(err, "NANANA!") + ethClient.AssertExpectations(t) + }) } -func TestGetTxAndReturnExpextedError() { +/*func TestWaitTxToBeMined(t *testing.T) { + t.Parallel() + assert := assert.New(t) + + t.Run("Returns expected 'DeadlineExceeded' error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + transaction := types.NewTransaction( + uint64(1), + common.Address{}, + big.NewInt(1), + uint64(1), + big.NewInt(1), + []byte{}, + ) + + ethClient.On( + "TransactionReceipt", + mock.Anything, + transaction.Hash(), + ).Return( + &types.Receipt{}, + context.DeadlineExceeded, + ).Once() + + status, err := ethman.WaitTxToBeMined( + context.TODO(), + transaction, + time.Duration(100), + ) + + assert.False(status) + assert.Nil(err) + ethClient.AssertExpectations(t) + }) + t.Run("Returns expected error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + transaction := types.NewTransaction( + uint64(1), + common.Address{}, + big.NewInt(1), + uint64(1), + big.NewInt(1), + []byte{}, + ) + + ethClient.On( + "TransactionReceipt", + mock.Anything, + transaction.Hash(), + ).Return( + &types.Receipt{}, + errors.New("NANANA!"), + ).Once() + + status, err := ethman.WaitTxToBeMined( + context.TODO(), + transaction, + time.Duration(100000000), + ) + + assert.False(status) + assert.ErrorContains(err, "NANANA!") + ethClient.AssertExpectations(t) + }) + + t.Run("Returns expected value", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + transaction := types.NewTransaction( + uint64(1), + common.Address{}, + big.NewInt(1), + uint64(1), + big.NewInt(1), + []byte{}, + ) + + ethClient.On( + "TransactionReceipt", + mock.Anything, + transaction.Hash(), + ).Return( + &types.Receipt{}, + nil, + ).Once() + + status, err := ethman.WaitTxToBeMined( + context.TODO(), + transaction, + time.Duration(100), + ) + + assert.True(status) + assert.Nil(err) + ethClient.AssertExpectations(t) + }) +}*/ + +func TestSendTx(t *testing.T) { + t.Parallel() + assert := assert.New(t) + transaction := types.NewTransaction( + uint64(1), + common.Address{}, + big.NewInt(1), + uint64(1), + big.NewInt(1), + []byte{}, + ) + + t.Run("Returns expected value", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "SendTransaction", + context.TODO(), + transaction, + ).Return( + nil, + ).Once() + + err := ethman.SendTx(context.TODO(), transaction) + + assert.Nil(err) + ethClient.AssertExpectations(t) + }) + + t.Run("Returns expected error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "SendTransaction", + context.TODO(), + transaction, + ).Return( + errors.New("NANANA!"), + ).Once() + + err := ethman.SendTx(context.TODO(), transaction) + + assert.ErrorContains(err, "NANANA!") + ethClient.AssertExpectations(t) + }) } +func TestSuggestedGasPrice(t *testing.T) { + t.Parallel() + assert := assert.New(t) + + t.Run("Returns expected value", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "SuggestGasPrice", + context.TODO(), + ).Return( + big.NewInt(1), + nil, + ).Once() + + result, err := ethman.SuggestedGasPrice(context.TODO()) -func TestGetTxReceiptAndReturnExpectedValue() { + assert.Equal(result, big.NewInt(1)) + assert.Nil(err) + ethClient.AssertExpectations(t) + }) + t.Run("Returns expected error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "SuggestGasPrice", + context.TODO(), + ).Return( + (*big.Int)(nil), + errors.New("NOPE!"), + ).Once() + + result, err := ethman.SuggestedGasPrice(context.TODO()) + + assert.Equal(result, (*big.Int)(nil)) + assert.ErrorContains(err, "NOPE!") + ethClient.AssertExpectations(t) + }) } -func TestGetTxReceiptAndReturnExpectedError() { +func TestEstimateGas(t *testing.T) { + t.Parallel() + assert := assert.New(t) + t.Run("Returns the expected value", func(t *testing.T) { + ethclient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethclient) + + ethclient.On( + "EstimateGas", + context.TODO(), + ethereum.CallMsg{ + From: common.Address{}, + To: &common.Address{}, + Value: big.NewInt(10), + Data: []byte{}, + }, + ).Return( + uint64(1), + nil, + ).Once() + + result, err := ethman.EstimateGas( + context.TODO(), + common.Address{}, + &common.Address{}, + big.NewInt(10), + []byte{}, + ) + + assert.Equal(result, uint64(1)) + assert.Nil(err) + ethclient.AssertExpectations(t) + }) + + t.Run("Returns the expected error", func(t *testing.T) { + ethclient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethclient) + + ethclient.On( + "EstimateGas", + context.TODO(), + ethereum.CallMsg{ + From: common.Address{}, + To: &common.Address{}, + Value: big.NewInt(10), + Data: []byte{}, + }, + ).Return( + uint64(0), + errors.New("NOOOPE!"), + ).Once() + + result, err := ethman.EstimateGas( + context.TODO(), + common.Address{}, + &common.Address{}, + big.NewInt(10), + []byte{}, + ) + + assert.Equal(result, uint64(0)) + assert.ErrorContains(err, "NOOOPE!") + ethclient.AssertExpectations(t) + }) } +func TestSignTx(t *testing.T) { + t.Parallel() + assert := assert.New(t) + txData := types.NewTransaction( + uint64(1), + common.Address{}, + big.NewInt(1), + uint64(1), + big.NewInt(1), + []byte{}, + ) -func TestWaitTxToBeMinedAndReturnExpectedDeadlineExceededError() { + t.Run("Returns the expected value", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + transaction, err := ethman.SignTx(txData) + + assert.Equal(transaction, txData) + assert.Nil(err) + }) } -func TestWaitTxToBeMinedAndReturnTheExpectedGenericError() { +func TestGetRevertMessage(t *testing.T) { + t.Parallel() + assert := assert.New(t) + txData := types.NewTransaction( + uint64(1), + common.Address{}, + big.NewInt(1), + uint64(1), + big.NewInt(1), + []byte{0xcf, 0xa8, 0xed, 0x47}, + ) + + t.Run("Returns an empty string and the expected error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + ethClient.On( + "TransactionReceipt", + context.TODO(), + txData.Hash(), + ).Return( + &types.Receipt{}, + errors.New("NANANA!"), + ).Once() + + result, err := ethman.GetRevertMessage(context.TODO(), txData) + + assert.Equal(result, "") + assert.ErrorContains(err, "NANANA!") + }) + + t.Run("Returns an empty string and the error set to nil", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "TransactionReceipt", + context.TODO(), + txData.Hash(), + ).Return( + &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + }, + nil, + ).Once() + + result, err := ethman.GetRevertMessage(context.TODO(), txData) + + assert.Equal(result, "") + assert.Nil(err) + }) + + /*t.Run("Returns the expected revert reason string", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "TransactionReceipt", + context.TODO(), + txData.Hash(), + ).Return( + &types.Receipt{ + Status: types.ReceiptStatusFailed, + BlockNumber: big.NewInt(1), + }, + nil, + ).Once() + + ethClient.On( + "CallContract", + context.TODO(), + ethereum.CallMsg{ + From: common.HexToAddress("0x742d35Cc6634C0532925a3b844Bc454e4438f44e"), + To: &common.Address{}, + Gas: 0, + GasPrice: nil, + GasFeeCap: nil, + GasTipCap: nil, + Value: nil, + Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, // TrustedSequencer sig + }, + big.NewInt(1), + ).Return( // Invalid return value below to provocate error + common.Hex2Bytes("08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000548454c4c4f000000000000000000000000000000000000000000000000000000"), + nil, + ).Once() + + result, err := ethman.GetRevertMessage(context.TODO(), txData) + + assert.Equal(result, "HELLO") + assert.Nil(err) + })*/ } -func TestWaitTXToBeMinedAndReturnExpectedValue() { +func TestGetLastBlock(t *testing.T) { + t.Parallel() + assert := assert.New(t) + + t.Run("Returns the expected values", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "BlockByNumber", + context.TODO(), + (*big.Int)(nil), + ).Return( + types.NewBlock( + &types.Header{}, + []*types.Transaction{}, + []*types.Header{}, + []*types.Receipt{}, + types.TrieHasher(nil), + ), + nil, + ) + + result, err := ethman.GetLastBlock(context.TODO()) + + assert.Equal(result.BlockNumber, uint64(0)) + assert.Equal(result.BlockHash, common.HexToHash("0xb159a077fc2af79b9a9c748c9c0e50ff95b74c32946ed52418fcc093d0953f26")) + assert.Equal(result.ParentHash, common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000")) + assert.Nil(err) + }) + t.Run("Returns the expected error", func(t *testing.T) { + ethClient := new(mocks.EthereumClientMock) + ethman := getEtherman(ethClient) + + ethClient.On( + "BlockByNumber", + context.TODO(), + (*big.Int)(nil), + ).Return( + &types.Block{}, + errors.New("NOOPE!"), + ) + + result, err := ethman.GetLastBlock(context.TODO()) + + assert.ErrorContains(err, "NOOPE!") + assert.Nil(result) + }) } -*/ diff --git a/etherman/ethclient_mock.go b/mocks/ethclient_mock.go similarity index 61% rename from etherman/ethclient_mock.go rename to mocks/ethclient_mock.go index 07c7b7f..5e8f33e 100644 --- a/etherman/ethclient_mock.go +++ b/mocks/ethclient_mock.go @@ -1,131 +1,132 @@ -package etherman +package mocks import ( "context" - ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/mock" "math/big" ) -type ethereumClientMock struct { +type EthereumClientMock struct { mock.Mock } -func (e *ethereumClientMock) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { +func (e *EthereumClientMock) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { +func (e *EthereumClientMock) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { +func (e *EthereumClientMock) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) { +func (e *EthereumClientMock) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) { +func (e *EthereumClientMock) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { +func (e *EthereumClientMock) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) { +func (e *EthereumClientMock) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) { +func (e *EthereumClientMock) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { - //TODO implement me - panic("implement me") +func (e *EthereumClientMock) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { + args := e.Called(ctx, account, blockNumber) + + return args.Get(0).([]byte), args.Error(1) } -func (e *ethereumClientMock) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { +func (e *EthereumClientMock) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { +func (e *EthereumClientMock) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { +func (e *EthereumClientMock) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { +func (e *EthereumClientMock) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { +func (e *EthereumClientMock) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { //TODO implement me panic("implement me") } -func (e *ethereumClientMock) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { +func (e *EthereumClientMock) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { args := e.Called(ctx, call, blockNumber) return args.Get(0).([]byte), args.Error(1) } -func (e *ethereumClientMock) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { +func (e *EthereumClientMock) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { args := e.Called(ctx, txHash) return args.Get(0).(*types.Receipt), args.Error(1) } -func (e *ethereumClientMock) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) { +func (e *EthereumClientMock) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) { args := e.Called(ctx, account, blockNumber) return args.Get(0).(uint64), args.Error(1) } -func (e *ethereumClientMock) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) { +func (e *EthereumClientMock) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) { args := e.Called(ctx, txHash) return args.Get(0).(*types.Transaction), args.Bool(1), args.Error(2) } -func (e *ethereumClientMock) SendTransaction(ctx context.Context, tx *types.Transaction) error { +func (e *EthereumClientMock) SendTransaction(ctx context.Context, tx *types.Transaction) error { args := e.Called(ctx, tx) return args.Error(0) } -func (e *ethereumClientMock) SuggestGasPrice(ctx context.Context) (*big.Int, error) { +func (e *EthereumClientMock) SuggestGasPrice(ctx context.Context) (*big.Int, error) { args := e.Called(ctx) return args.Get(0).(*big.Int), args.Error(1) } -func (e *ethereumClientMock) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) { +func (e *EthereumClientMock) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) { args := e.Called(ctx, call) return args.Get(0).(uint64), args.Error(1) } -func (e *ethereumClientMock) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { +func (e *EthereumClientMock) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { args := e.Called(ctx, number) return args.Get(0).(*types.Block), args.Error(1) From 688b7619b5057b57d0acf695d11ead65c5288918 Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Wed, 13 Dec 2023 10:28:23 +0100 Subject: [PATCH 03/12] ethclient_mock completed --- mocks/ethclient_mock.go | 65 ++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/mocks/ethclient_mock.go b/mocks/ethclient_mock.go index 5e8f33e..285108e 100644 --- a/mocks/ethclient_mock.go +++ b/mocks/ethclient_mock.go @@ -14,43 +14,51 @@ type EthereumClientMock struct { } func (e *EthereumClientMock) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, hash) + + return args.Get(0).(*types.Block), args.Error(1) } func (e *EthereumClientMock) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, hash) + + return args.Get(0).(*types.Header), args.Error(1) } func (e *EthereumClientMock) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, number) + + return args.Get(0).(*types.Header), args.Error(1) } func (e *EthereumClientMock) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, blockHash) + + return args.Get(0).(uint), args.Error(1) } func (e *EthereumClientMock) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, blockHash) + + return args.Get(0).(*types.Transaction), args.Error(1) } func (e *EthereumClientMock) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, ch) + + return args.Get(0).(ethereum.Subscription), args.Error(1) } func (e *EthereumClientMock) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, account, blockNumber) + + return args.Get(0).(*big.Int), args.Error(1) } func (e *EthereumClientMock) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, account, key, blockNumber) + + return args.Get(0).([]byte), args.Error(1) } func (e *EthereumClientMock) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { @@ -60,28 +68,33 @@ func (e *EthereumClientMock) CodeAt(ctx context.Context, account common.Address, } func (e *EthereumClientMock) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, q) + + return args.Get(0).([]types.Log), args.Error(1) } func (e *EthereumClientMock) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, q, ch) + + return args.Get(0).(ethereum.Subscription), args.Error(1) } func (e *EthereumClientMock) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, account) + + return args.Get(0).([]byte), args.Error(1) } func (e *EthereumClientMock) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx, account) + + return args.Get(0).(uint64), args.Error(1) } func (e *EthereumClientMock) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { - //TODO implement me - panic("implement me") + args := e.Called(ctx) + + return args.Get(0).(*big.Int), args.Error(1) } func (e *EthereumClientMock) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { From 7ad41e5d3929f6a0c8847da9529a5eebd03080e7 Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Wed, 13 Dec 2023 10:30:09 +0100 Subject: [PATCH 04/12] typo fixed --- cmd/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/main.go b/cmd/main.go index b39d0c1..9542adb 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -98,7 +98,7 @@ func start(cliCtx *cli.Context) error { // Connect to ethereum node ethClient, err := ethclient.DialContext(cliCtx.Context, c.L1.NodeURL) if err != nil { - log.Fatal("error connecting to %s: %+v", url, err) + log.Fatal("error connecting to %s: %+v", c.L1.NodeURL, err) } // Make sure the connection is okay From 112724841ef9148a7c97298a1a2094f7949da9fa Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Wed, 13 Dec 2023 10:36:06 +0100 Subject: [PATCH 05/12] SignTx not used arguments added back cause otherwise we arent compatible with the defined etherman interface --- etherman/etherman.go | 2 +- etherman/etherman_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/etherman/etherman.go b/etherman/etherman.go index 13cf738..572c8e1 100644 --- a/etherman/etherman.go +++ b/etherman/etherman.go @@ -147,7 +147,7 @@ func (e *Etherman) EstimateGas(ctx context.Context, from common.Address, to *com } // SignTx tries to sign a transaction accordingly to the provided sender -func (e *Etherman) SignTx(tx *types.Transaction) (*types.Transaction, error) { +func (e *Etherman) SignTx(ctx context.Context, sender common.Address, tx *types.Transaction) (*types.Transaction, error) { return e.auth.Signer(e.auth.From, tx) } diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go index 33a70cd..6d6e4f2 100644 --- a/etherman/etherman_test.go +++ b/etherman/etherman_test.go @@ -705,7 +705,7 @@ func TestSignTx(t *testing.T) { ethClient := new(mocks.EthereumClientMock) ethman := getEtherman(ethClient) - transaction, err := ethman.SignTx(txData) + transaction, err := ethman.SignTx(context.TODO(), common.Address{}, txData) assert.Equal(transaction, txData) assert.Nil(err) From 4d098a5766c31bae6fa63c94aa14f638d2feee9c Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Wed, 13 Dec 2023 11:12:39 +0100 Subject: [PATCH 06/12] TxMock moved to mocks folder (will move the others with a different PR) --- etherman/etherman.go | 3 +- etherman/etherman_test.go | 4 +-- mocks/tx_mock.go | 72 +++++++++++++++++++++++++++++++++++++++ rpc/rpc_test.go | 72 +++------------------------------------ 4 files changed, 80 insertions(+), 71 deletions(-) create mode 100644 mocks/tx_mock.go diff --git a/etherman/etherman.go b/etherman/etherman.go index 572c8e1..32720f6 100644 --- a/etherman/etherman.go +++ b/etherman/etherman.go @@ -3,6 +3,7 @@ package etherman import ( "context" "errors" + "github.com/jackc/pgx/v4" "math/big" "time" @@ -173,7 +174,7 @@ func (e *Etherman) GetRevertMessage(ctx context.Context, tx *types.Transaction) return "", nil } -func (e *Etherman) GetLastBlock(ctx context.Context) (*state.Block, error) { +func (e *Etherman) GetLastBlock(ctx context.Context, dbTx pgx.Tx) (*state.Block, error) { block, err := e.ethClient.BlockByNumber(ctx, nil) if err != nil { return nil, err diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go index 6d6e4f2..d849d87 100644 --- a/etherman/etherman_test.go +++ b/etherman/etherman_test.go @@ -829,7 +829,7 @@ func TestGetLastBlock(t *testing.T) { nil, ) - result, err := ethman.GetLastBlock(context.TODO()) + result, err := ethman.GetLastBlock(context.TODO(), new(mocks.TxMock)) assert.Equal(result.BlockNumber, uint64(0)) assert.Equal(result.BlockHash, common.HexToHash("0xb159a077fc2af79b9a9c748c9c0e50ff95b74c32946ed52418fcc093d0953f26")) @@ -850,7 +850,7 @@ func TestGetLastBlock(t *testing.T) { errors.New("NOOPE!"), ) - result, err := ethman.GetLastBlock(context.TODO()) + result, err := ethman.GetLastBlock(context.TODO(), new(mocks.TxMock)) assert.ErrorContains(err, "NOOPE!") assert.Nil(result) diff --git a/mocks/tx_mock.go b/mocks/tx_mock.go new file mode 100644 index 0000000..0edeb53 --- /dev/null +++ b/mocks/tx_mock.go @@ -0,0 +1,72 @@ +package mocks + +import ( + "context" + "github.com/jackc/pgconn" + "github.com/jackc/pgx/v4" + "github.com/stretchr/testify/mock" +) + +var _ pgx.Tx = (*TxMock)(nil) + +type TxMock struct { + mock.Mock +} + +func (tx *TxMock) Begin(ctx context.Context) (pgx.Tx, error) { + return nil, nil +} + +func (tx *TxMock) BeginFunc(ctx context.Context, f func(pgx.Tx) error) (err error) { + return nil +} + +func (tx *TxMock) Commit(ctx context.Context) error { + args := tx.Called(ctx) + + return args.Error(0) +} + +func (tx *TxMock) Rollback(ctx context.Context) error { + args := tx.Called(ctx) + + return args.Error(0) +} + +func (tx *TxMock) CopyFrom(ctx context.Context, tableName pgx.Identifier, + columnNames []string, rowSrc pgx.CopyFromSource) (int64, error) { + return 0, nil +} + +func (tx *TxMock) SendBatch(ctx context.Context, b *pgx.Batch) pgx.BatchResults { + return nil +} + +func (tx *TxMock) LargeObjects() pgx.LargeObjects { + return pgx.LargeObjects{} +} + +func (tx *TxMock) Prepare(ctx context.Context, name, sql string) (*pgconn.StatementDescription, error) { + return nil, nil +} + +func (tx *TxMock) Exec(ctx context.Context, sql string, arguments ...interface{}) (commandTag pgconn.CommandTag, err error) { + return nil, nil +} + +func (tx *TxMock) Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error) { + return nil, nil +} + +func (tx *TxMock) QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row { + return nil +} + +func (tx *TxMock) QueryFunc(ctx context.Context, sql string, + args []interface{}, scans []interface{}, f func(pgx.QueryFuncRow) error) (pgconn.CommandTag, error) { + return nil, nil +} + +func (tx *TxMock) Conn() *pgx.Conn { + return nil +} diff --git a/rpc/rpc_test.go b/rpc/rpc_test.go index 64a4d6a..6ffdfd1 100644 --- a/rpc/rpc_test.go +++ b/rpc/rpc_test.go @@ -3,6 +3,7 @@ package rpc import ( "context" "errors" + "github.com/0xPolygon/beethoven/mocks" "math/big" "testing" @@ -13,7 +14,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/jackc/pgconn" "github.com/jackc/pgx/v4" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -94,70 +94,6 @@ func (e *ethTxManagerMock) ProcessPendingMonitoredTxs(ctx context.Context, owner e.Called(ctx, owner, failedResultHandler, dbTx) } -var _ pgx.Tx = (*txMock)(nil) - -type txMock struct { - mock.Mock -} - -func (tx *txMock) Begin(ctx context.Context) (pgx.Tx, error) { - return nil, nil -} - -func (tx *txMock) BeginFunc(ctx context.Context, f func(pgx.Tx) error) (err error) { - return nil -} - -func (tx *txMock) Commit(ctx context.Context) error { - args := tx.Called(ctx) - - return args.Error(0) -} - -func (tx *txMock) Rollback(ctx context.Context) error { - args := tx.Called(ctx) - - return args.Error(0) -} - -func (tx *txMock) CopyFrom(ctx context.Context, tableName pgx.Identifier, - columnNames []string, rowSrc pgx.CopyFromSource) (int64, error) { - return 0, nil -} - -func (tx *txMock) SendBatch(ctx context.Context, b *pgx.Batch) pgx.BatchResults { - return nil -} - -func (tx *txMock) LargeObjects() pgx.LargeObjects { - return pgx.LargeObjects{} -} - -func (tx *txMock) Prepare(ctx context.Context, name, sql string) (*pgconn.StatementDescription, error) { - return nil, nil -} - -func (tx *txMock) Exec(ctx context.Context, sql string, arguments ...interface{}) (commandTag pgconn.CommandTag, err error) { - return nil, nil -} - -func (tx *txMock) Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error) { - return nil, nil -} - -func (tx *txMock) QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row { - return nil -} - -func (tx *txMock) QueryFunc(ctx context.Context, sql string, - args []interface{}, scans []interface{}, f func(pgx.QueryFuncRow) error) (pgconn.CommandTag, error) { - return nil, nil -} - -func (tx *txMock) Conn() *pgx.Conn { - return nil -} - var _ ZkEVMClientInterface = (*zkEVMClientMock)(nil) type zkEVMClientMock struct { @@ -217,7 +153,7 @@ func TestInteropEndpointsGetTxStatus(t *testing.T) { txHash := common.HexToHash("0xsomeTxHash") - txMock := new(txMock) + txMock := new(mocks.TxMock) txMock.On("Rollback", mock.Anything).Return(nil).Once() dbMock := new(dbMock) @@ -260,7 +196,7 @@ func TestInteropEndpointsGetTxStatus(t *testing.T) { }, } - txMock := new(txMock) + txMock := new(mocks.TxMock) txMock.On("Rollback", mock.Anything).Return(nil).Once() dbMock := new(dbMock) @@ -326,7 +262,7 @@ func TestInteropEndpointsSendTx(t *testing.T) { zkEVMClientCreatorMock := new(zkEVMClientCreatorMock) zkEVMClientMock := new(zkEVMClientMock) dbMock := new(dbMock) - txMock := new(txMock) + txMock := new(mocks.TxMock) ethTxManagerMock := new(ethTxManagerMock) executeTestFn := func() { From 6b1052acca7b67a13b5a6daf4dff1bbf3e61e015 Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Wed, 13 Dec 2023 13:32:13 +0100 Subject: [PATCH 07/12] TestGetRevertMessage extended by one test case --- etherman/etherman_test.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go index d849d87..6d6c8a2 100644 --- a/etherman/etherman_test.go +++ b/etherman/etherman_test.go @@ -10,6 +10,7 @@ import ( "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/stretchr/testify/assert" "github.com/stretchr/testify/mock" "math/big" @@ -764,14 +765,18 @@ func TestGetRevertMessage(t *testing.T) { assert.Nil(err) }) - /*t.Run("Returns the expected revert reason string", func(t *testing.T) { + t.Run("Returns the expected revert reason string", func(t *testing.T) { ethClient := new(mocks.EthereumClientMock) ethman := getEtherman(ethClient) + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + signedTx, err := types.SignTx(txData, types.NewEIP155Signer(big.NewInt(1)), key) + ethClient.On( "TransactionReceipt", context.TODO(), - txData.Hash(), + signedTx.Hash(), ).Return( &types.Receipt{ Status: types.ReceiptStatusFailed, @@ -784,13 +789,13 @@ func TestGetRevertMessage(t *testing.T) { "CallContract", context.TODO(), ethereum.CallMsg{ - From: common.HexToAddress("0x742d35Cc6634C0532925a3b844Bc454e4438f44e"), + From: addr, To: &common.Address{}, - Gas: 0, + Gas: 1, GasPrice: nil, GasFeeCap: nil, GasTipCap: nil, - Value: nil, + Value: big.NewInt(1), Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, // TrustedSequencer sig }, big.NewInt(1), @@ -799,11 +804,11 @@ func TestGetRevertMessage(t *testing.T) { nil, ).Once() - result, err := ethman.GetRevertMessage(context.TODO(), txData) + result, err := ethman.GetRevertMessage(context.TODO(), signedTx) assert.Equal(result, "HELLO") assert.Nil(err) - })*/ + }) } func TestGetLastBlock(t *testing.T) { From 8a7c3275a8b29a50617714899b513552f3a0c949 Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Wed, 13 Dec 2023 15:11:41 +0100 Subject: [PATCH 08/12] ineffectual assignment of 'err' removed --- etherman/etherman_test.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go index 6d6c8a2..ed00336 100644 --- a/etherman/etherman_test.go +++ b/etherman/etherman_test.go @@ -510,10 +510,13 @@ func TestGetTxReceipt(t *testing.T) { []byte{}, ) + key, _ := crypto.GenerateKey() + signedTx, err := types.SignTx(transaction, types.NewEIP155Signer(big.NewInt(1)), key) + ethClient.On( "TransactionReceipt", mock.Anything, - transaction.Hash(), + signedTx.Hash(), ).Return( &types.Receipt{}, nil, @@ -521,7 +524,7 @@ func TestGetTxReceipt(t *testing.T) { status, err := ethman.WaitTxToBeMined( context.TODO(), - transaction, + signedTx, time.Duration(100), ) @@ -529,7 +532,7 @@ func TestGetTxReceipt(t *testing.T) { assert.Nil(err) ethClient.AssertExpectations(t) }) -}*/ +} */ func TestSendTx(t *testing.T) { t.Parallel() @@ -771,7 +774,7 @@ func TestGetRevertMessage(t *testing.T) { key, _ := crypto.GenerateKey() addr := crypto.PubkeyToAddress(key.PublicKey) - signedTx, err := types.SignTx(txData, types.NewEIP155Signer(big.NewInt(1)), key) + signedTx, _ := types.SignTx(txData, types.NewEIP155Signer(big.NewInt(1)), key) ethClient.On( "TransactionReceipt", From a0676ae4637080f05edcf15c03a199f85d096937 Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Wed, 13 Dec 2023 16:19:58 +0100 Subject: [PATCH 09/12] 'mocks' added to exclusion rule of sonarqube --- sonar-project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index 1e052fa..b540976 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -12,7 +12,7 @@ sonar.exclusions=**/*_test.go,**/vendor/** sonar.tests=. sonar.test.inclusions=**/*_test.go -sonar.test.exclusions=**/vendor/** +sonar.test.exclusions=**/vendor/**, mocks/** sonar.issue.enforceSemantic=true # ===================================================== From 96a36fdabd36e95681b8fcb427606e798adba813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Thu, 14 Dec 2023 06:58:06 +0100 Subject: [PATCH 10/12] Exclude mocks folder from coverage analysis --- sonar-project.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonar-project.properties b/sonar-project.properties index b540976..f966263 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -8,11 +8,11 @@ sonar.projectName=Beethoven sonar.organization=0xpolygon sonar.sources=. -sonar.exclusions=**/*_test.go,**/vendor/** +sonar.exclusions=**/*_test.go,**/vendor/**,mocks/** sonar.tests=. sonar.test.inclusions=**/*_test.go -sonar.test.exclusions=**/vendor/**, mocks/** +sonar.test.exclusions=**/vendor/**,mocks/** sonar.issue.enforceSemantic=true # ===================================================== From 2653b18b6193d7448216d916afdba919948643b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Thu, 14 Dec 2023 10:24:07 +0100 Subject: [PATCH 11/12] Exclude cmd/main.go --- sonar-project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index 1517b92..785e314 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -7,7 +7,7 @@ sonar.projectName=Beethoven sonar.organization=0xpolygon sonar.sources=. -sonar.exclusions=**/*_test.go,**/vendor/**,mocks/** +sonar.exclusions=**/*_test.go,**/vendor/**,mocks/**,cmd/main.go sonar.tests=. sonar.test.inclusions=**/*_test.go From ff7e67fc566480c2bf8bff501e687dfbc8823853 Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Thu, 14 Dec 2023 16:46:08 +0100 Subject: [PATCH 12/12] part of the requested changes applied to the PR --- cmd/main.go | 6 +- etherman/etherman_test.go | 166 +++++++------------------------------- 2 files changed, 32 insertions(+), 140 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 9542adb..0b6fb25 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,15 +4,12 @@ import ( "context" "errors" "fmt" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/urfave/cli/v2" "math/big" "net/http" "os" "os/signal" "time" - beethoven "github.com/0xPolygon/beethoven" "github.com/0xPolygon/cdk-data-availability/dummyinterfaces" dbConf "github.com/0xPolygon/cdk-validium-node/db" "github.com/0xPolygon/cdk-validium-node/ethtxmanager" @@ -20,10 +17,13 @@ import ( "github.com/0xPolygon/cdk-validium-node/log" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/urfave/cli/v2" "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/sdk/metric" + beethoven "github.com/0xPolygon/beethoven" "github.com/0xPolygon/beethoven/config" "github.com/0xPolygon/beethoven/db" "github.com/0xPolygon/beethoven/etherman" diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go index ed00336..4480dc0 100644 --- a/etherman/etherman_test.go +++ b/etherman/etherman_test.go @@ -85,24 +85,20 @@ func TestGetSequencerAddr(t *testing.T) { "CallContract", mock.Anything, ethereum.CallMsg{ - From: common.HexToAddress("0x0000000000000000000000000000000000000000"), - To: &common.Address{}, - Gas: 0, - GasPrice: nil, - GasFeeCap: nil, - GasTipCap: nil, - Value: nil, - Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, + From: common.HexToAddress("0x0000000000000000000000000000000000000000"), + To: &common.Address{}, + Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, }, (*big.Int)(nil), - ).Return( // Invalid return value below to provocate error + ).Return( common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000000"), nil, ).Once() - returnValue, _ := ethman.GetSequencerAddr(common.HexToAddress("0x0000000000000000000000000000000000000000")) + returnValue, err := ethman.GetSequencerAddr(common.HexToAddress("0x0000000000000000000000000000000000000000")) - assert.Equal(returnValue, common.Address{}) + assert.Equal(common.Address{}, returnValue) + assert.NoError(err) ethClient.AssertExpectations(t) }) } @@ -172,8 +168,8 @@ func TestCallContract(t *testing.T) { (*big.Int)(nil), ) - assert.Equal(result, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")) - assert.Equal(err, nil) + assert.Equal(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"), result) + assert.Equal(nil, err) ethClient.AssertExpectations(t) }) @@ -215,7 +211,7 @@ func TestCallContract(t *testing.T) { (*big.Int)(nil), ) - assert.Equal(result, []uint8{}) + assert.Equal([]uint8{}, result) assert.ErrorContains(err, "NOOOPE!") ethClient.AssertExpectations(t) }) @@ -283,7 +279,7 @@ func TestCheckTxWasMined(t *testing.T) { status, receipt, err := ethman.CheckTxWasMined(context.TODO(), common.Hash{}) assert.True(status) - assert.Equal(receipt, &types.Receipt{}) + assert.Equal(&types.Receipt{}, receipt) assert.Nil(err) ethClient.AssertExpectations(t) }) @@ -309,7 +305,7 @@ func TestCurrentNonce(t *testing.T) { result, err := ethman.CurrentNonce(context.TODO(), common.Address{}) - assert.Equal(result, uint64(1)) + assert.Equal(uint64(1), result) assert.Nil(err) ethClient.AssertExpectations(t) }) @@ -330,7 +326,7 @@ func TestCurrentNonce(t *testing.T) { result, err := ethman.CurrentNonce(context.TODO(), common.Address{}) - assert.Equal(result, uint64(0)) + assert.Equal(uint64(0), result) assert.ErrorContains(err, "NA NA NA!") ethClient.AssertExpectations(t) }) @@ -356,7 +352,7 @@ func TestGetTx(t *testing.T) { transaction, status, err := ethman.GetTx(context.TODO(), common.Hash{}) - assert.Equal(transaction, &types.Transaction{}) + assert.Equal(&types.Transaction{}, transaction) assert.True(status) assert.Nil(err) ethClient.AssertExpectations(t) @@ -378,7 +374,7 @@ func TestGetTx(t *testing.T) { transaction, status, err := ethman.GetTx(context.TODO(), common.Hash{}) - assert.Equal(transaction, &types.Transaction{}) + assert.Equal(&types.Transaction{}, transaction) assert.False(status) assert.ErrorContains(err, "NOPE NOPE!") ethClient.AssertExpectations(t) @@ -404,7 +400,7 @@ func TestGetTxReceipt(t *testing.T) { receipt, err := ethman.GetTxReceipt(context.TODO(), common.Hash{}) - assert.Equal(receipt, &types.Receipt{}) + assert.Equal(&types.Receipt{}, receipt) assert.Nil(err) ethClient.AssertExpectations(t) }) @@ -424,116 +420,12 @@ func TestGetTxReceipt(t *testing.T) { receipt, err := ethman.GetTxReceipt(context.TODO(), common.Hash{}) - assert.Equal(receipt, &types.Receipt{}) + assert.Equal(&types.Receipt{}, receipt) assert.ErrorContains(err, "NANANA!") ethClient.AssertExpectations(t) }) } -/*func TestWaitTxToBeMined(t *testing.T) { - t.Parallel() - assert := assert.New(t) - - t.Run("Returns expected 'DeadlineExceeded' error", func(t *testing.T) { - ethClient := new(mocks.EthereumClientMock) - ethman := getEtherman(ethClient) - transaction := types.NewTransaction( - uint64(1), - common.Address{}, - big.NewInt(1), - uint64(1), - big.NewInt(1), - []byte{}, - ) - - ethClient.On( - "TransactionReceipt", - mock.Anything, - transaction.Hash(), - ).Return( - &types.Receipt{}, - context.DeadlineExceeded, - ).Once() - - status, err := ethman.WaitTxToBeMined( - context.TODO(), - transaction, - time.Duration(100), - ) - - assert.False(status) - assert.Nil(err) - ethClient.AssertExpectations(t) - }) - - t.Run("Returns expected error", func(t *testing.T) { - ethClient := new(mocks.EthereumClientMock) - ethman := getEtherman(ethClient) - transaction := types.NewTransaction( - uint64(1), - common.Address{}, - big.NewInt(1), - uint64(1), - big.NewInt(1), - []byte{}, - ) - - ethClient.On( - "TransactionReceipt", - mock.Anything, - transaction.Hash(), - ).Return( - &types.Receipt{}, - errors.New("NANANA!"), - ).Once() - - status, err := ethman.WaitTxToBeMined( - context.TODO(), - transaction, - time.Duration(100000000), - ) - - assert.False(status) - assert.ErrorContains(err, "NANANA!") - ethClient.AssertExpectations(t) - }) - - t.Run("Returns expected value", func(t *testing.T) { - ethClient := new(mocks.EthereumClientMock) - ethman := getEtherman(ethClient) - transaction := types.NewTransaction( - uint64(1), - common.Address{}, - big.NewInt(1), - uint64(1), - big.NewInt(1), - []byte{}, - ) - - key, _ := crypto.GenerateKey() - signedTx, err := types.SignTx(transaction, types.NewEIP155Signer(big.NewInt(1)), key) - - ethClient.On( - "TransactionReceipt", - mock.Anything, - signedTx.Hash(), - ).Return( - &types.Receipt{}, - nil, - ).Once() - - status, err := ethman.WaitTxToBeMined( - context.TODO(), - signedTx, - time.Duration(100), - ) - - assert.True(status) - assert.Nil(err) - ethClient.AssertExpectations(t) - }) -} */ - func TestSendTx(t *testing.T) { t.Parallel() assert := assert.New(t) @@ -601,7 +493,7 @@ func TestSuggestedGasPrice(t *testing.T) { result, err := ethman.SuggestedGasPrice(context.TODO()) - assert.Equal(result, big.NewInt(1)) + assert.Equal(big.NewInt(1), result) assert.Nil(err) ethClient.AssertExpectations(t) }) @@ -620,7 +512,7 @@ func TestSuggestedGasPrice(t *testing.T) { result, err := ethman.SuggestedGasPrice(context.TODO()) - assert.Equal(result, (*big.Int)(nil)) + assert.Equal((*big.Int)(nil), result) assert.ErrorContains(err, "NOPE!") ethClient.AssertExpectations(t) }) @@ -656,7 +548,7 @@ func TestEstimateGas(t *testing.T) { []byte{}, ) - assert.Equal(result, uint64(1)) + assert.Equal(uint64(1), result) assert.Nil(err) ethclient.AssertExpectations(t) }) @@ -687,7 +579,7 @@ func TestEstimateGas(t *testing.T) { []byte{}, ) - assert.Equal(result, uint64(0)) + assert.Equal(uint64(0), result) assert.ErrorContains(err, "NOOOPE!") ethclient.AssertExpectations(t) }) @@ -711,7 +603,7 @@ func TestSignTx(t *testing.T) { transaction, err := ethman.SignTx(context.TODO(), common.Address{}, txData) - assert.Equal(transaction, txData) + assert.Equal(txData, transaction) assert.Nil(err) }) } @@ -743,7 +635,7 @@ func TestGetRevertMessage(t *testing.T) { result, err := ethman.GetRevertMessage(context.TODO(), txData) - assert.Equal(result, "") + assert.Equal("", result) assert.ErrorContains(err, "NANANA!") }) @@ -764,7 +656,7 @@ func TestGetRevertMessage(t *testing.T) { result, err := ethman.GetRevertMessage(context.TODO(), txData) - assert.Equal(result, "") + assert.Equal("", result) assert.Nil(err) }) @@ -802,14 +694,14 @@ func TestGetRevertMessage(t *testing.T) { Data: []uint8{0xcf, 0xa8, 0xed, 0x47}, // TrustedSequencer sig }, big.NewInt(1), - ).Return( // Invalid return value below to provocate error + ).Return( common.Hex2Bytes("08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000548454c4c4f000000000000000000000000000000000000000000000000000000"), nil, ).Once() result, err := ethman.GetRevertMessage(context.TODO(), signedTx) - assert.Equal(result, "HELLO") + assert.Equal("HELLO", result) assert.Nil(err) }) } @@ -839,9 +731,9 @@ func TestGetLastBlock(t *testing.T) { result, err := ethman.GetLastBlock(context.TODO(), new(mocks.TxMock)) - assert.Equal(result.BlockNumber, uint64(0)) - assert.Equal(result.BlockHash, common.HexToHash("0xb159a077fc2af79b9a9c748c9c0e50ff95b74c32946ed52418fcc093d0953f26")) - assert.Equal(result.ParentHash, common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000")) + assert.Equal(uint64(0), result.BlockNumber) + assert.Equal(common.HexToHash("0xb159a077fc2af79b9a9c748c9c0e50ff95b74c32946ed52418fcc093d0953f26"), result.BlockHash) + assert.Equal(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), result.ParentHash) assert.Nil(err) })