Skip to content

Commit 8c0698d

Browse files
vladjdkalmk-dev
andauthored
test: eip712 e2e tests (#700)
* awd * cleaninggggggg uppppppppppppp yayayaya * moar cleanup * summed up * tidy * change evm chain id * use constants * set default evm node chain id * fix gas prices * mod fix * Update tests/systemtests/clients/cosmosclient.go Co-authored-by: Abdul Malek <[email protected]> * Update tests/systemtests/eip712/test_suite.go Co-authored-by: Abdul Malek <[email protected]> * remove memo --------- Co-authored-by: Abdul Malek <[email protected]>
1 parent 89bb381 commit 8c0698d

File tree

12 files changed

+670
-103
lines changed

12 files changed

+670
-103
lines changed

tests/systemtests/accountabstraction/types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package accountabstraction
22

33
import (
44
"fmt"
5+
"github.com/cosmos/evm/tests/systemtests/clients"
56
"math/big"
67

78
"github.com/ethereum/go-ethereum/accounts/abi"
@@ -44,7 +45,7 @@ func NewUserOperation(sender common.Address, nonce uint64, calldata []byte) *Use
4445
}
4546

4647
func SignUserOperation(userOp *UserOperation, entryPointAddr common.Address, privKey cryptotypes.PrivKey) (*UserOperation, error) {
47-
chainID := uint64(4221)
48+
chainID := clients.EVMChainID
4849

4950
addressType, _ := abi.NewType("address", "", nil)
5051
uint256Type, _ := abi.NewType("uint256", "", nil)

tests/systemtests/clients/config.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package clients
22

33
import (
4-
"fmt"
54
"math/big"
65
)
76

@@ -22,7 +21,7 @@ import (
2221

2322
const (
2423
ChainID = "local-4221"
25-
EVMChainID = "262144"
24+
EVMChainID = 4221
2625

2726
Acc0PrivKey = "88cbead91aee890d27bf06e003ade3d4e952427e88f88d31d61d3ef5e5d54305"
2827
Acc1PrivKey = "741de4f8988ea941d3ff0287911ca4074e62b7d45c991a51186455366f10b544"
@@ -50,11 +49,6 @@ type Config struct {
5049

5150
// NewConfig creates a new Config instance.
5251
func NewConfig() (*Config, error) {
53-
// evm chainID
54-
evmChainID, ok := new(big.Int).SetString(EVMChainID, 10)
55-
if !ok {
56-
return nil, fmt.Errorf("error whilte setting chain id")
57-
}
5852

5953
// private keys of test accounts
6054
privKeys := []string{Acc0PrivKey, Acc1PrivKey, Acc2PrivKey, Acc3PrivKey}
@@ -67,7 +61,7 @@ func NewConfig() (*Config, error) {
6761

6862
return &Config{
6963
ChainID: ChainID,
70-
EVMChainID: evmChainID,
64+
EVMChainID: big.NewInt(EVMChainID),
7165
PrivKeys: privKeys,
7266
JsonRPCUrls: jsonRPCUrls,
7367
NodeRPCUrls: nodeRPCUrls,

tests/systemtests/clients/cosmosclient.go

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,14 @@ import (
2020
"github.com/cosmos/cosmos-sdk/client"
2121
"github.com/cosmos/cosmos-sdk/client/flags"
2222
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
23-
"github.com/cosmos/cosmos-sdk/codec"
24-
"github.com/cosmos/cosmos-sdk/codec/types"
2523
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
26-
"github.com/cosmos/cosmos-sdk/std"
2724
sdk "github.com/cosmos/cosmos-sdk/types"
2825
"github.com/cosmos/cosmos-sdk/types/tx/signing"
2926
xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
30-
"github.com/cosmos/cosmos-sdk/x/auth/tx"
3127
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
3228
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
29+
30+
evmencoding "github.com/cosmos/evm/encoding"
3331
)
3432

3533
// CosmosClient is a client for interacting with Cosmos SDK-based nodes.
@@ -183,20 +181,43 @@ func (c *CosmosClient) UnconfirmedTxs(nodeID string) (*coretypes.ResultUnconfirm
183181
return c.RpcClients[nodeID].UnconfirmedTxs(context.Background(), nil)
184182
}
185183

184+
// GetBalance retrieves the balance of a given address for a specific denomination.
185+
func (c *CosmosClient) GetBalance(nodeID string, address sdk.AccAddress, denom string) (*big.Int, error) {
186+
c.ClientCtx = c.ClientCtx.WithClient(c.RpcClients[nodeID])
187+
188+
queryClient := banktypes.NewQueryClient(c.ClientCtx)
189+
190+
res, err := queryClient.Balance(context.Background(), &banktypes.QueryBalanceRequest{
191+
Address: address.String(),
192+
Denom: denom,
193+
})
194+
if err != nil {
195+
return nil, fmt.Errorf("failed to query balance: %w", err)
196+
}
197+
198+
return res.Balance.Amount.BigInt(), nil
199+
}
200+
186201
// newClientContext creates a new client context for the Cosmos SDK.
187202
func newClientContext(config *Config) (*client.Context, error) {
188-
// Create codec and tx config
189-
interfaceRegistry := types.NewInterfaceRegistry()
190-
std.RegisterInterfaces(interfaceRegistry)
191-
marshaler := codec.NewProtoCodec(interfaceRegistry)
192-
txConfig := tx.NewTxConfig(marshaler, tx.DefaultSignModes)
203+
// Use the encoding config setup which properly initializes EIP-712
204+
encodingConfig := evmencoding.MakeConfig(config.EVMChainID.Uint64())
205+
206+
// Register auth module types for account queries
207+
authtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
208+
209+
// Register bank module types for EIP-712 signing
210+
// Note: The MakeConfig only registers base SDK and EVM types,
211+
// but we need bank types for MsgSend transactions
212+
banktypes.RegisterLegacyAminoCodec(encodingConfig.Amino)
213+
banktypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
193214

194215
// Create client context
195216
clientCtx := client.Context{
196217
BroadcastMode: flags.BroadcastSync,
197-
TxConfig: txConfig,
198-
Codec: marshaler,
199-
InterfaceRegistry: interfaceRegistry,
218+
TxConfig: encodingConfig.TxConfig,
219+
Codec: encodingConfig.Codec,
220+
InterfaceRegistry: encodingConfig.InterfaceRegistry,
200221
ChainID: config.ChainID,
201222
AccountRetriever: authtypes.AccountRetriever{},
202223
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//go:build system_test
2+
3+
package eip712
4+
5+
import (
6+
"context"
7+
"fmt"
8+
"math/big"
9+
10+
sdkmath "cosmossdk.io/math"
11+
12+
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
13+
sdk "github.com/cosmos/cosmos-sdk/types"
14+
"github.com/cosmos/cosmos-sdk/types/tx/signing"
15+
xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
16+
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
17+
18+
"github.com/cosmos/evm/ethereum/eip712"
19+
"github.com/cosmos/evm/tests/systemtests/clients"
20+
)
21+
22+
// BankSendWithEIP712 sends a bank send transaction using EIP-712 signing.
23+
func BankSendWithEIP712(
24+
cosmosClient *clients.CosmosClient,
25+
nodeID, accID string,
26+
from, to sdk.AccAddress,
27+
amount sdkmath.Int,
28+
nonce uint64,
29+
gasPrice *big.Int,
30+
) (*sdk.TxResponse, error) {
31+
cosmosClient.ClientCtx = cosmosClient.ClientCtx.WithClient(cosmosClient.RpcClients[nodeID])
32+
33+
privKey := cosmosClient.Accs[accID].PrivKey
34+
35+
// Query account number from chain
36+
account, err := cosmosClient.ClientCtx.AccountRetriever.GetAccount(cosmosClient.ClientCtx, from)
37+
if err != nil {
38+
return nil, fmt.Errorf("failed to get account: %v", err)
39+
}
40+
accountNumber := account.GetAccountNumber()
41+
42+
msg := banktypes.NewMsgSend(from, to, sdk.NewCoins(sdk.NewCoin("atest", amount)))
43+
44+
txBytes, err := signMsgsWithEIP712(cosmosClient, privKey, accountNumber, nonce, gasPrice, msg)
45+
if err != nil {
46+
return nil, fmt.Errorf("failed to sign tx msg with EIP-712: %v", err)
47+
}
48+
49+
resp, err := cosmosClient.ClientCtx.BroadcastTx(txBytes)
50+
if err != nil {
51+
return nil, fmt.Errorf("failed to broadcast tx: %v", err)
52+
}
53+
54+
return resp, nil
55+
}
56+
57+
// signMsgsWithEIP712 signs the provided messages using EIP-712 and returns the signed transaction bytes.
58+
func signMsgsWithEIP712(
59+
cosmosClient *clients.CosmosClient,
60+
privKey cryptotypes.PrivKey,
61+
accountNumber, sequence uint64,
62+
gasPrice *big.Int,
63+
msg sdk.Msg,
64+
) ([]byte, error) {
65+
senderAddr := sdk.AccAddress(privKey.PubKey().Address().Bytes())
66+
signMode := signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON
67+
68+
txBuilder := cosmosClient.ClientCtx.TxConfig.NewTxBuilder()
69+
70+
txBuilder.SetGasLimit(150_000)
71+
txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin("atest", sdkmath.NewIntFromBigInt(gasPrice).MulRaw(150_001))))
72+
73+
err := txBuilder.SetMsgs(msg)
74+
if err != nil {
75+
return nil, fmt.Errorf("failed to set messages: %v", err)
76+
}
77+
78+
signerData := xauthsigning.SignerData{
79+
Address: senderAddr.String(),
80+
ChainID: cosmosClient.ChainID,
81+
AccountNumber: accountNumber,
82+
Sequence: sequence,
83+
PubKey: privKey.PubKey(),
84+
}
85+
86+
// Set empty signature first
87+
sigsV2 := signing.SignatureV2{
88+
PubKey: privKey.PubKey(),
89+
Data: &signing.SingleSignatureData{
90+
SignMode: signMode,
91+
Signature: nil,
92+
},
93+
Sequence: sequence,
94+
}
95+
96+
err = txBuilder.SetSignatures(sigsV2)
97+
if err != nil {
98+
return nil, fmt.Errorf("failed to set empty signatures: %v", err)
99+
}
100+
101+
// Get sign bytes
102+
signBytes, err := xauthsigning.GetSignBytesAdapter(
103+
context.Background(),
104+
cosmosClient.ClientCtx.TxConfig.SignModeHandler(),
105+
signMode,
106+
signerData,
107+
txBuilder.GetTx(),
108+
)
109+
if err != nil {
110+
return nil, fmt.Errorf("failed to get sign bytes: %v", err)
111+
}
112+
113+
// Get EIP-712 bytes for the message
114+
eip712Bytes, err := eip712.GetEIP712BytesForMsg(signBytes)
115+
if err != nil {
116+
return nil, fmt.Errorf("failed to get EIP-712 bytes: %v", err)
117+
}
118+
119+
// Sign the EIP-712 hash
120+
signature, err := privKey.Sign(eip712Bytes)
121+
if err != nil {
122+
return nil, fmt.Errorf("failed to sign EIP-712 bytes: %v", err)
123+
}
124+
125+
// Set the signature
126+
sigsV2 = signing.SignatureV2{
127+
PubKey: privKey.PubKey(),
128+
Data: &signing.SingleSignatureData{
129+
SignMode: signMode,
130+
Signature: signature,
131+
},
132+
Sequence: sequence,
133+
}
134+
135+
err = txBuilder.SetSignatures(sigsV2)
136+
if err != nil {
137+
return nil, fmt.Errorf("failed to set signatures: %v", err)
138+
}
139+
140+
txBytes, err := cosmosClient.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
141+
if err != nil {
142+
return nil, fmt.Errorf("failed to encode tx: %v", err)
143+
}
144+
145+
return txBytes, nil
146+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package eip712
2+
3+
import (
4+
"math/big"
5+
"testing"
6+
7+
sdk "github.com/cosmos/cosmos-sdk/types"
8+
)
9+
10+
type TestSuite interface {
11+
// Test Lifecycle
12+
BeforeEachCase(t *testing.T)
13+
AfterEachCase(t *testing.T)
14+
15+
// Tx - EIP-712 signing
16+
SendBankSendWithEIP712(t *testing.T, nodeID string, accID string, to sdk.AccAddress, amount *big.Int, nonce uint64, gasPrice *big.Int) (string, error)
17+
18+
// Query
19+
GetBalance(t *testing.T, nodeID string, address sdk.AccAddress, denom string) (*big.Int, error)
20+
WaitForCommit(nodeID string, txHash string, timeout ...int) error
21+
22+
// Config
23+
Node(idx int) string
24+
Acc(idx int) string
25+
26+
// Test Utils
27+
AwaitNBlocks(t *testing.T, n int64)
28+
}

0 commit comments

Comments
 (0)