From 31240736f6e79882d7534f1e42eb4ce7be823f02 Mon Sep 17 00:00:00 2001 From: Samuel Stokes Date: Tue, 17 Dec 2024 15:43:26 -0500 Subject: [PATCH 1/7] validation: decouple GasToken tests --- validation/gas-token_test.go | 90 --------------------- validation/gas_token.go | 104 +++++++++++++++++++++++++ validation/gas_token_test.go | 97 +++++++++++++++++++++++ validation/testutils/mock_ethclient.go | 29 +++++++ validation/utils.go | 5 ++ 5 files changed, 235 insertions(+), 90 deletions(-) delete mode 100644 validation/gas-token_test.go create mode 100644 validation/gas_token.go create mode 100644 validation/gas_token_test.go create mode 100644 validation/testutils/mock_ethclient.go diff --git a/validation/gas-token_test.go b/validation/gas-token_test.go deleted file mode 100644 index f82522549..000000000 --- a/validation/gas-token_test.go +++ /dev/null @@ -1,90 +0,0 @@ -package validation - -import ( - "context" - "errors" - "testing" - - . "github.com/ethereum-optimism/superchain-registry/superchain" - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/stretchr/testify/require" -) - -func testGasToken(t *testing.T, chain *ChainConfig) { - client, err := ethclient.Dial(chain.PublicRPC) - require.NoError(t, err, "Failed to connect to the Ethereum client at RPC url %s", chain.PublicRPC) - defer client.Close() - - // WETH predeploy name() check - want := "0000000000000000000000000000000000000000000000000000000000000020" + // offset - "000000000000000000000000000000000000000000000000000000000000000d" + // length - "5772617070656420457468657200000000000000000000000000000000000000" // "Wrapped Ether" padded to 32 bytes - gotName, err := getHexString("name()", MustHexToAddress("0x4200000000000000000000000000000000000006"), client) - require.NoError(t, err) - require.Equal(t, want, gotName) - - // L1Block .isCustomGasToken() check - got, err := getBool("isCustomGasToken()", MustHexToAddress("0x4200000000000000000000000000000000000015"), client) - - if err != nil { - // Pre: Custom Gas Token feature. Reverting is acceptable. - require.Contains(t, err.Error(), "execution reverted") - } else { - // Post: Custom Gas Token fearure. Must be set to false. - require.False(t, got) - } - - // SystemConfig .isCustomGasToken() check (L1) - client, err = ethclient.Dial(Superchains[chain.Superchain].Config.L1.PublicRPC) - require.NoError(t, err, "Failed to connect to the Ethereum client at RPC url %s", chain.PublicRPC) - defer client.Close() - - got, err = getBool("isCustomGasToken()", Addresses[chain.ChainID].SystemConfigProxy, client) - if err != nil { - // Pre: Custom Gas Token feature. Reverting is acceptable. - require.Contains(t, err.Error(), "execution reverted") - } else { - // Post: Custom Gas Token fearure. Must be set to false. - require.False(t, got) - } -} - -func getBytes(method string, contractAddress Address, client *ethclient.Client) ([]byte, error) { - addr := (common.Address(contractAddress)) - callMsg := ethereum.CallMsg{ - To: &addr, - Data: crypto.Keccak256([]byte(method))[:4], - } - - // Make the call - callContract := func(msg ethereum.CallMsg) ([]byte, error) { - return client.CallContract(context.Background(), msg, nil) - } - - return Retry(callContract)(callMsg) -} - -func getHexString(method string, contractAddress Address, client *ethclient.Client) (string, error) { - result, err := getBytes(method, contractAddress, client) - - return common.Bytes2Hex(result), err -} - -func getBool(method string, contractAddress Address, client *ethclient.Client) (bool, error) { - result, err := getBytes(method, contractAddress, client) - if err != nil { - return false, err - } - - switch common.HexToHash(string(result)) { - case common.Hash{1}: - return true, nil - case common.Hash{}: - return false, nil - default: - return false, errors.New("unexpected non-bool return value") - } -} diff --git a/validation/gas_token.go b/validation/gas_token.go new file mode 100644 index 000000000..ce8fd2905 --- /dev/null +++ b/validation/gas_token.go @@ -0,0 +1,104 @@ +package validation + +import ( + "context" + "errors" + "fmt" + "strings" + "testing" + + "github.com/ethereum-optimism/superchain-registry/superchain" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/stretchr/testify/require" +) + +func testGasToken(t *testing.T, chain *superchain.ChainConfig) { + l1Client, err := ethclient.Dial(superchain.Superchains[chain.Superchain].Config.L1.PublicRPC) + require.NoError(t, err, "Failed to connect to the Ethereum client at RPC url %s", chain.PublicRPC) + defer l1Client.Close() + + err = CheckGasToken(chain, l1Client) + require.NoError(t, err) +} + +func CheckGasToken(chain *superchain.ChainConfig, l1Client *ethclient.Client) error { + l2Client, err := ethclient.Dial(chain.PublicRPC) + if err != nil { + return err + } + defer l2Client.Close() + + weth9PredeployAddress := superchain.MustHexToAddress("0x4200000000000000000000000000000000000006") + want := "0000000000000000000000000000000000000000000000000000000000000020" + // offset + "000000000000000000000000000000000000000000000000000000000000000d" + // length + "5772617070656420457468657200000000000000000000000000000000000000" // "Wrapped Ether" padded to 32 bytes + gotName, err := getHexString("WETH9.name()", weth9PredeployAddress, l2Client) + if err != nil { + return err + } + if want != gotName { + return fmt.Errorf("predeploy WETH9.name(): want=%s, got=%s", want, gotName) + } + + l1BlockPredeployAddress := superchain.MustHexToAddress("0x4200000000000000000000000000000000000015") + got, err := getBool("isCustomGasToken()", l1BlockPredeployAddress, l2Client) + if err != nil && !strings.Contains(err.Error(), "execution reverted") { + // Pre: reverting is acceptable + return err + } else { + // Post: must be set to false + if got != false { + return fmt.Errorf("L1Block.isCustomGasToken() must return false") + } + } + + got, err = getBool("isCustomGasToken()", superchain.Addresses[chain.ChainID].SystemConfigProxy, l2Client) + if err != nil && !strings.Contains(err.Error(), "execution reverted") { + // Pre: reverting is acceptable + return err + } else { + // Post: must be set to false + if got != false { + return fmt.Errorf("SystemConfigProxy.isCustomGasToken() must return false") + } + } + return nil +} + +func getBytes(method string, contractAddress superchain.Address, client EthClient) ([]byte, error) { + addr := (common.Address(contractAddress)) + callMsg := ethereum.CallMsg{ + To: &addr, + Data: crypto.Keccak256([]byte(method))[:4], + } + + callContract := func(msg ethereum.CallMsg) ([]byte, error) { + return client.CallContract(context.Background(), msg, nil) + } + + return Retry(callContract)(callMsg) +} + +func getHexString(method string, contractAddress superchain.Address, client EthClient) (string, error) { + result, err := getBytes(method, contractAddress, client) + return common.Bytes2Hex(result), err +} + +func getBool(method string, contractAddress superchain.Address, client EthClient) (bool, error) { + result, err := getBytes(method, contractAddress, client) + if err != nil { + return false, err + } + + switch common.HexToHash(string(result)) { + case common.Hash{1}: + return true, nil + case common.Hash{}: + return false, nil + default: + return false, errors.New("unexpected non-bool return value") + } +} diff --git a/validation/gas_token_test.go b/validation/gas_token_test.go new file mode 100644 index 000000000..66b29b1d9 --- /dev/null +++ b/validation/gas_token_test.go @@ -0,0 +1,97 @@ +package validation + +import ( + "errors" + "testing" + + "github.com/ethereum-optimism/superchain-registry/superchain" + "github.com/ethereum-optimism/superchain-registry/validation/testutils" + "github.com/stretchr/testify/require" +) + +func TestGetBytes_Success(t *testing.T) { + t.Parallel() + mockClient := &testutils.MockEthClient{ + Responses: map[string][]byte{ + string(testutils.MethodID("myMethod()")): {0xde, 0xad, 0xbe, 0xef}, + }, + } + contractAddress := superchain.MustHexToAddress("0x1234567890abcdef1234567890abcdef12345678") + result, err := getBytes("myMethod()", contractAddress, mockClient) + require.NoError(t, err) + require.Equal(t, []byte{0xde, 0xad, 0xbe, 0xef}, result) +} + +func TestGetBytes_Error(t *testing.T) { + t.Parallel() + mockClient := &testutils.MockEthClient{ + Err: errors.New("some call error"), + } + contractAddress := superchain.MustHexToAddress("0x1234567890abcdef1234567890abcdef12345678") + _, err := getBytes("failingMethod()", contractAddress, mockClient) + require.Error(t, err) + require.Contains(t, err.Error(), "some call error") +} + +func TestGetHexString_Success(t *testing.T) { + t.Parallel() + mockClient := &testutils.MockEthClient{ + Responses: map[string][]byte{ + string(testutils.MethodID("hexMethod()")): {0x00, 0x11, 0x22, 0x33}, + }, + } + contractAddress := superchain.MustHexToAddress("0xabcdef7890abcdef1234567890abcdef12345678") + hexVal, err := getHexString("hexMethod()", contractAddress, mockClient) + require.NoError(t, err) + require.Equal(t, "00112233", hexVal) +} + +func TestGetHexString_Error(t *testing.T) { + t.Parallel() + mockClient := &testutils.MockEthClient{ + Err: errors.New("getHexString error"), + } + contractAddress := superchain.MustHexToAddress("0x1234567890abcdef1234567890abcdef12345678") + _, err := getHexString("hexMethod()", contractAddress, mockClient) + require.Error(t, err) + require.Contains(t, err.Error(), "getHexString error") +} + +func TestGetBool_True(t *testing.T) { + t.Parallel() + mockClient := &testutils.MockEthClient{ + Responses: map[string][]byte{ + string(testutils.MethodID("boolMethod()")): []byte("0x0100000000000000000000000000000000000000000000000000000000000000"), + }, + } + contractAddress := superchain.MustHexToAddress("0x1111117890abcdef1234567890abcdef12345678") + val, err := getBool("boolMethod()", contractAddress, mockClient) + require.NoError(t, err) + require.True(t, val) +} + +func TestGetBool_False(t *testing.T) { + t.Parallel() + mockClient := &testutils.MockEthClient{ + Responses: map[string][]byte{ + string(testutils.MethodID("boolMethod()")): []byte(""), + }, + } + contractAddress := superchain.MustHexToAddress("0x2222227890abcdef1234567890abcdef12345678") + val, err := getBool("boolMethod()", contractAddress, mockClient) + require.NoError(t, err) + require.False(t, val) +} + +func TestGetBool_ErrorUnexpectedValue(t *testing.T) { + t.Parallel() + mockClient := &testutils.MockEthClient{ + Responses: map[string][]byte{ + string(testutils.MethodID("boolMethod()")): []byte("0xabcdef"), + }, + } + contractAddress := superchain.MustHexToAddress("0x2222227890abcdef1234567890abcdef12345678") + _, err := getBool("boolMethod()", contractAddress, mockClient) + require.Error(t, err) + require.Contains(t, err.Error(), "unexpected non-bool return value") +} diff --git a/validation/testutils/mock_ethclient.go b/validation/testutils/mock_ethclient.go new file mode 100644 index 000000000..20d269172 --- /dev/null +++ b/validation/testutils/mock_ethclient.go @@ -0,0 +1,29 @@ +package testutils + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/crypto" +) + +// MockEthClient is a mock that implements EthCaller for testing. +type MockEthClient struct { + // Setup response maps keyed by method 4-byte signature + address, or + // just by method signature if that's simpler for your tests. + Responses map[string][]byte + Err error +} + +func (m *MockEthClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { + if m.Err != nil { + return nil, m.Err + } + return m.Responses[string(msg.Data)], nil +} + +// Helper to get the 4-byte method ID (like what getBytes does internally) +func MethodID(method string) []byte { + return crypto.Keccak256([]byte(method))[:4] +} diff --git a/validation/utils.go b/validation/utils.go index 6a9d0feee..87e0bb36d 100644 --- a/validation/utils.go +++ b/validation/utils.go @@ -11,9 +11,14 @@ import ( "github.com/ethereum-optimism/optimism/op-service/retry" "github.com/ethereum-optimism/superchain-registry/superchain" + "github.com/ethereum/go-ethereum" "github.com/stretchr/testify/assert" ) +type EthClient interface { + CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) +} + // isBigIntWithinBounds returns true if actual is within bounds, where the bounds are [lower bound, upper bound] and are inclusive. var isBigIntWithinBounds = func(actual *big.Int, bounds [2]*big.Int) bool { if (bounds[1].Cmp(bounds[0])) < 0 { From b2549f3f94796db9ee3b313c17ad00b2fa20dfa2 Mon Sep 17 00:00:00 2001 From: Samuel Stokes Date: Tue, 17 Dec 2024 15:49:37 -0500 Subject: [PATCH 2/7] just lint-all --- validation/gas_token.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/validation/gas_token.go b/validation/gas_token.go index ce8fd2905..1eb8aee51 100644 --- a/validation/gas_token.go +++ b/validation/gas_token.go @@ -44,24 +44,24 @@ func CheckGasToken(chain *superchain.ChainConfig, l1Client *ethclient.Client) er } l1BlockPredeployAddress := superchain.MustHexToAddress("0x4200000000000000000000000000000000000015") - got, err := getBool("isCustomGasToken()", l1BlockPredeployAddress, l2Client) + isCustomGasToken, err := getBool("isCustomGasToken()", l1BlockPredeployAddress, l2Client) if err != nil && !strings.Contains(err.Error(), "execution reverted") { // Pre: reverting is acceptable return err } else { // Post: must be set to false - if got != false { + if isCustomGasToken { return fmt.Errorf("L1Block.isCustomGasToken() must return false") } } - got, err = getBool("isCustomGasToken()", superchain.Addresses[chain.ChainID].SystemConfigProxy, l2Client) + isCustomGasToken, err = getBool("isCustomGasToken()", superchain.Addresses[chain.ChainID].SystemConfigProxy, l2Client) if err != nil && !strings.Contains(err.Error(), "execution reverted") { // Pre: reverting is acceptable return err } else { // Post: must be set to false - if got != false { + if isCustomGasToken { return fmt.Errorf("SystemConfigProxy.isCustomGasToken() must return false") } } From 721c2760bc6bbf582cbee964b8ded4c201ad0a88 Mon Sep 17 00:00:00 2001 From: Samuel Stokes Date: Fri, 20 Dec 2024 12:01:14 -0500 Subject: [PATCH 3/7] fix WETH9.name() call --- validation/gas_token.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/validation/gas_token.go b/validation/gas_token.go index 1eb8aee51..1e950233a 100644 --- a/validation/gas_token.go +++ b/validation/gas_token.go @@ -24,7 +24,7 @@ func testGasToken(t *testing.T, chain *superchain.ChainConfig) { require.NoError(t, err) } -func CheckGasToken(chain *superchain.ChainConfig, l1Client *ethclient.Client) error { +func CheckGasToken(chain *superchain.ChainConfig, l1Client EthClient) error { l2Client, err := ethclient.Dial(chain.PublicRPC) if err != nil { return err @@ -35,7 +35,7 @@ func CheckGasToken(chain *superchain.ChainConfig, l1Client *ethclient.Client) er want := "0000000000000000000000000000000000000000000000000000000000000020" + // offset "000000000000000000000000000000000000000000000000000000000000000d" + // length "5772617070656420457468657200000000000000000000000000000000000000" // "Wrapped Ether" padded to 32 bytes - gotName, err := getHexString("WETH9.name()", weth9PredeployAddress, l2Client) + gotName, err := getHexString("name()", weth9PredeployAddress, l2Client) if err != nil { return err } From a5cb887436406788a4296e13a926da5cc528e4f6 Mon Sep 17 00:00:00 2001 From: Samuel Stokes Date: Fri, 20 Dec 2024 14:39:34 -0500 Subject: [PATCH 4/7] update MockEthClient to use mock.Mock framework --- validation/gas_token_test.go | 94 +++++++++++++++++--------- validation/testutils/mock_ethclient.go | 19 ++---- 2 files changed, 66 insertions(+), 47 deletions(-) diff --git a/validation/gas_token_test.go b/validation/gas_token_test.go index 66b29b1d9..602a445f7 100644 --- a/validation/gas_token_test.go +++ b/validation/gas_token_test.go @@ -2,96 +2,126 @@ package validation import ( "errors" + "math/big" "testing" "github.com/ethereum-optimism/superchain-registry/superchain" "github.com/ethereum-optimism/superchain-registry/validation/testutils" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) func TestGetBytes_Success(t *testing.T) { t.Parallel() - mockClient := &testutils.MockEthClient{ - Responses: map[string][]byte{ - string(testutils.MethodID("myMethod()")): {0xde, 0xad, 0xbe, 0xef}, - }, - } + + mockClient := &testutils.MockEthClient{} + expected := []byte{0xde, 0xad, 0xbe, 0xef} + mockClient.On("CallContract", mock.Anything, mock.Anything, (*big.Int)(nil)). + Return(expected, nil). + Once() + contractAddress := superchain.MustHexToAddress("0x1234567890abcdef1234567890abcdef12345678") result, err := getBytes("myMethod()", contractAddress, mockClient) require.NoError(t, err) - require.Equal(t, []byte{0xde, 0xad, 0xbe, 0xef}, result) + require.Equal(t, expected, result) + + mockClient.AssertExpectations(t) } func TestGetBytes_Error(t *testing.T) { t.Parallel() - mockClient := &testutils.MockEthClient{ - Err: errors.New("some call error"), - } + + mockClient := &testutils.MockEthClient{} + mockClient.On("CallContract", mock.Anything, mock.Anything, (*big.Int)(nil)). + Return(nil, errors.New("some call error")). + Once() + contractAddress := superchain.MustHexToAddress("0x1234567890abcdef1234567890abcdef12345678") _, err := getBytes("failingMethod()", contractAddress, mockClient) require.Error(t, err) require.Contains(t, err.Error(), "some call error") + + mockClient.AssertExpectations(t) } func TestGetHexString_Success(t *testing.T) { t.Parallel() - mockClient := &testutils.MockEthClient{ - Responses: map[string][]byte{ - string(testutils.MethodID("hexMethod()")): {0x00, 0x11, 0x22, 0x33}, - }, - } + + mockClient := &testutils.MockEthClient{} + expected := []byte{0x00, 0x11, 0x22, 0x33} + mockClient.On("CallContract", mock.Anything, mock.Anything, (*big.Int)(nil)). + Return(expected, nil). + Once() + contractAddress := superchain.MustHexToAddress("0xabcdef7890abcdef1234567890abcdef12345678") hexVal, err := getHexString("hexMethod()", contractAddress, mockClient) require.NoError(t, err) require.Equal(t, "00112233", hexVal) + + mockClient.AssertExpectations(t) } func TestGetHexString_Error(t *testing.T) { t.Parallel() - mockClient := &testutils.MockEthClient{ - Err: errors.New("getHexString error"), - } + + mockClient := &testutils.MockEthClient{} + mockClient.On("CallContract", mock.Anything, mock.Anything, (*big.Int)(nil)). + Return(nil, errors.New("getHexString error")). + Once() + contractAddress := superchain.MustHexToAddress("0x1234567890abcdef1234567890abcdef12345678") _, err := getHexString("hexMethod()", contractAddress, mockClient) require.Error(t, err) require.Contains(t, err.Error(), "getHexString error") + + mockClient.AssertExpectations(t) } func TestGetBool_True(t *testing.T) { t.Parallel() - mockClient := &testutils.MockEthClient{ - Responses: map[string][]byte{ - string(testutils.MethodID("boolMethod()")): []byte("0x0100000000000000000000000000000000000000000000000000000000000000"), - }, - } + + // Returning bytes that correspond to `true` value + mockClient := &testutils.MockEthClient{} + mockClient.On("CallContract", mock.Anything, mock.Anything, (*big.Int)(nil)). + Return([]byte("0x0100000000000000000000000000000000000000000000000000000000000000"), nil). + Once() + contractAddress := superchain.MustHexToAddress("0x1111117890abcdef1234567890abcdef12345678") val, err := getBool("boolMethod()", contractAddress, mockClient) require.NoError(t, err) require.True(t, val) + + mockClient.AssertExpectations(t) } func TestGetBool_False(t *testing.T) { t.Parallel() - mockClient := &testutils.MockEthClient{ - Responses: map[string][]byte{ - string(testutils.MethodID("boolMethod()")): []byte(""), - }, - } + + mockClient := &testutils.MockEthClient{} + mockClient.On("CallContract", mock.Anything, mock.Anything, (*big.Int)(nil)). + Return([]byte(""), nil). + Once() + contractAddress := superchain.MustHexToAddress("0x2222227890abcdef1234567890abcdef12345678") val, err := getBool("boolMethod()", contractAddress, mockClient) require.NoError(t, err) require.False(t, val) + + mockClient.AssertExpectations(t) } func TestGetBool_ErrorUnexpectedValue(t *testing.T) { t.Parallel() - mockClient := &testutils.MockEthClient{ - Responses: map[string][]byte{ - string(testutils.MethodID("boolMethod()")): []byte("0xabcdef"), - }, - } + + mockClient := &testutils.MockEthClient{} + mockClient.On("CallContract", mock.Anything, mock.Anything, (*big.Int)(nil)). + Return([]byte("0xabcdef"), nil). + Once() + contractAddress := superchain.MustHexToAddress("0x2222227890abcdef1234567890abcdef12345678") _, err := getBool("boolMethod()", contractAddress, mockClient) require.Error(t, err) require.Contains(t, err.Error(), "unexpected non-bool return value") + + mockClient.AssertExpectations(t) } diff --git a/validation/testutils/mock_ethclient.go b/validation/testutils/mock_ethclient.go index 20d269172..8516bee4d 100644 --- a/validation/testutils/mock_ethclient.go +++ b/validation/testutils/mock_ethclient.go @@ -5,25 +5,14 @@ import ( "math/big" "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/mock" ) -// MockEthClient is a mock that implements EthCaller for testing. type MockEthClient struct { - // Setup response maps keyed by method 4-byte signature + address, or - // just by method signature if that's simpler for your tests. - Responses map[string][]byte - Err error + mock.Mock } func (m *MockEthClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { - if m.Err != nil { - return nil, m.Err - } - return m.Responses[string(msg.Data)], nil -} - -// Helper to get the 4-byte method ID (like what getBytes does internally) -func MethodID(method string) []byte { - return crypto.Keccak256([]byte(method))[:4] + args := m.Called(ctx, msg, blockNumber) + return args.Get(0).([]byte), args.Error(1) } From 9b47dbdbfca84cbe63908fa5e4156c5a798f2fc0 Mon Sep 17 00:00:00 2001 From: Samuel Stokes Date: Fri, 20 Dec 2024 14:40:27 -0500 Subject: [PATCH 5/7] refactor EthClient args --- validation/gas_token.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/validation/gas_token.go b/validation/gas_token.go index 1e950233a..6bf52c632 100644 --- a/validation/gas_token.go +++ b/validation/gas_token.go @@ -17,20 +17,18 @@ import ( func testGasToken(t *testing.T, chain *superchain.ChainConfig) { l1Client, err := ethclient.Dial(superchain.Superchains[chain.Superchain].Config.L1.PublicRPC) - require.NoError(t, err, "Failed to connect to the Ethereum client at RPC url %s", chain.PublicRPC) + require.NoError(t, err, "Failed to connect to L1 EthClient at RPC url %s", superchain.Superchains[chain.Superchain].Config.L1.PublicRPC) defer l1Client.Close() - err = CheckGasToken(chain, l1Client) - require.NoError(t, err) -} - -func CheckGasToken(chain *superchain.ChainConfig, l1Client EthClient) error { l2Client, err := ethclient.Dial(chain.PublicRPC) - if err != nil { - return err - } + require.NoError(t, err, "Failed to connect to L2 EthClient at RPC url %s", chain.PublicRPC) defer l2Client.Close() + err = CheckGasToken(chain, l1Client, l2Client) + require.NoError(t, err) +} + +func CheckGasToken(chain *superchain.ChainConfig, l1Client EthClient, l2Client EthClient) error { weth9PredeployAddress := superchain.MustHexToAddress("0x4200000000000000000000000000000000000006") want := "0000000000000000000000000000000000000000000000000000000000000020" + // offset "000000000000000000000000000000000000000000000000000000000000000d" + // length @@ -55,7 +53,7 @@ func CheckGasToken(chain *superchain.ChainConfig, l1Client EthClient) error { } } - isCustomGasToken, err = getBool("isCustomGasToken()", superchain.Addresses[chain.ChainID].SystemConfigProxy, l2Client) + isCustomGasToken, err = getBool("isCustomGasToken()", superchain.Addresses[chain.ChainID].SystemConfigProxy, l1Client) if err != nil && !strings.Contains(err.Error(), "execution reverted") { // Pre: reverting is acceptable return err From 224fb016a9ec97c1e3a86993b3cd5592d90c8f7d Mon Sep 17 00:00:00 2001 From: Samuel Stokes Date: Fri, 20 Dec 2024 15:01:06 -0500 Subject: [PATCH 6/7] go mod tidy --- validation/go.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/validation/go.mod b/validation/go.mod index a667a9705..c6e10ea2b 100644 --- a/validation/go.mod +++ b/validation/go.mod @@ -76,6 +76,7 @@ require ( github.com/rs/cors v1.11.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/supranational/blst v0.3.13 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect From d29c33ac67e02e623a8d60d8c1b8272c75f521bc Mon Sep 17 00:00:00 2001 From: Samuel Stokes Date: Fri, 20 Dec 2024 15:01:43 -0500 Subject: [PATCH 7/7] refactor tests to remove unused code --- validation/gas_token_test.go | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/validation/gas_token_test.go b/validation/gas_token_test.go index 602a445f7..74a895950 100644 --- a/validation/gas_token_test.go +++ b/validation/gas_token_test.go @@ -20,8 +20,7 @@ func TestGetBytes_Success(t *testing.T) { Return(expected, nil). Once() - contractAddress := superchain.MustHexToAddress("0x1234567890abcdef1234567890abcdef12345678") - result, err := getBytes("myMethod()", contractAddress, mockClient) + result, err := getBytes("myMethod()", superchain.Address{}, mockClient) require.NoError(t, err) require.Equal(t, expected, result) @@ -33,11 +32,10 @@ func TestGetBytes_Error(t *testing.T) { mockClient := &testutils.MockEthClient{} mockClient.On("CallContract", mock.Anything, mock.Anything, (*big.Int)(nil)). - Return(nil, errors.New("some call error")). - Once() + Return([]byte{}, errors.New("some call error")). + Times(DefaultMaxRetries) - contractAddress := superchain.MustHexToAddress("0x1234567890abcdef1234567890abcdef12345678") - _, err := getBytes("failingMethod()", contractAddress, mockClient) + _, err := getBytes("failingMethod()", superchain.Address{}, mockClient) require.Error(t, err) require.Contains(t, err.Error(), "some call error") @@ -53,8 +51,7 @@ func TestGetHexString_Success(t *testing.T) { Return(expected, nil). Once() - contractAddress := superchain.MustHexToAddress("0xabcdef7890abcdef1234567890abcdef12345678") - hexVal, err := getHexString("hexMethod()", contractAddress, mockClient) + hexVal, err := getHexString("hexMethod()", superchain.Address{}, mockClient) require.NoError(t, err) require.Equal(t, "00112233", hexVal) @@ -66,11 +63,10 @@ func TestGetHexString_Error(t *testing.T) { mockClient := &testutils.MockEthClient{} mockClient.On("CallContract", mock.Anything, mock.Anything, (*big.Int)(nil)). - Return(nil, errors.New("getHexString error")). - Once() + Return([]byte{}, errors.New("getHexString error")). + Times(DefaultMaxRetries) - contractAddress := superchain.MustHexToAddress("0x1234567890abcdef1234567890abcdef12345678") - _, err := getHexString("hexMethod()", contractAddress, mockClient) + _, err := getHexString("hexMethod()", superchain.Address{}, mockClient) require.Error(t, err) require.Contains(t, err.Error(), "getHexString error") @@ -86,8 +82,7 @@ func TestGetBool_True(t *testing.T) { Return([]byte("0x0100000000000000000000000000000000000000000000000000000000000000"), nil). Once() - contractAddress := superchain.MustHexToAddress("0x1111117890abcdef1234567890abcdef12345678") - val, err := getBool("boolMethod()", contractAddress, mockClient) + val, err := getBool("boolMethod()", superchain.Address{}, mockClient) require.NoError(t, err) require.True(t, val) @@ -102,8 +97,7 @@ func TestGetBool_False(t *testing.T) { Return([]byte(""), nil). Once() - contractAddress := superchain.MustHexToAddress("0x2222227890abcdef1234567890abcdef12345678") - val, err := getBool("boolMethod()", contractAddress, mockClient) + val, err := getBool("boolMethod()", superchain.Address{}, mockClient) require.NoError(t, err) require.False(t, val) @@ -118,8 +112,7 @@ func TestGetBool_ErrorUnexpectedValue(t *testing.T) { Return([]byte("0xabcdef"), nil). Once() - contractAddress := superchain.MustHexToAddress("0x2222227890abcdef1234567890abcdef12345678") - _, err := getBool("boolMethod()", contractAddress, mockClient) + _, err := getBool("boolMethod()", superchain.Address{}, mockClient) require.Error(t, err) require.Contains(t, err.Error(), "unexpected non-bool return value")