From 2a73e1c2e1578d5e71c3bdd4e1e720e9f1dcd448 Mon Sep 17 00:00:00 2001 From: Ian Davis Date: Tue, 24 Jan 2023 13:12:31 +0000 Subject: [PATCH] Add test for eth_getStorageAt --- itests/eth_conformance_test.go | 167 ++++++++++++++++++-------------- itests/eth_filter_test.go | 10 +- itests/eth_transactions_test.go | 3 - 3 files changed, 99 insertions(+), 81 deletions(-) diff --git a/itests/eth_conformance_test.go b/itests/eth_conformance_test.go index 9e5541786..ce920092f 100644 --- a/itests/eth_conformance_test.go +++ b/itests/eth_conformance_test.go @@ -24,6 +24,7 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/ethtypes" + "github.com/filecoin-project/lotus/chain/wallet/key" "github.com/filecoin-project/lotus/itests/kit" ) @@ -95,15 +96,11 @@ func TestEthOpenRPCConformance(t *testing.T) { contractBin, err := hex.DecodeString(string(contractHex)) require.NoError(t, err) - senderAddr, err := client.EVM().WalletDefaultAddress(ctx) - require.NoError(t, err) - // senderEthAddr := getContractEthAddress(ctx, t, client, senderAddr) + senderKey, senderEthAddr, senderFilAddr := client.EVM().NewAccount() + _, receiverEthAddr, _ := client.EVM().NewAccount() + kit.SendFunds(ctx, t, client, senderFilAddr, types.FromFil(1000)) - result := client.EVM().DeployContract(ctx, senderAddr, contractBin) - - // set up some standard values for tests - - contractAddr, err := address.NewIDAddress(result.ActorID) + deployerAddr, err := client.EVM().WalletDefaultAddress(ctx) require.NoError(t, err) pendingTransactionFilterID, err := client.EthNewPendingTransactionFilter(ctx) @@ -120,73 +117,15 @@ func TestEthOpenRPCConformance(t *testing.T) { uninstallableFilterID, err := client.EthNewFilter(ctx, filterAllLogs) require.NoError(t, err) - // send a message that exercises event logs - messages := invokeAndWaitUntilAllOnChain(t, client, []Invocation{ - { - Sender: senderAddr, - Target: contractAddr, - Selector: EventMatrixContract.Fn["logEventThreeIndexedWithData"], - Data: packUint64Values(44, 27, 19, 12), - }, - }) + rawSignedEthTx := createRawSignedEthTx(ctx, t, client, senderEthAddr, receiverEthAddr, senderKey, contractBin) - require.NotEmpty(t, messages) - - var messageWithEvents ethtypes.EthHash - var blockHashWithMessage ethtypes.EthHash - var blockNumberWithMessage ethtypes.EthUint64 - - for k, mts := range messages { - messageWithEvents = k - ts := mts.ts - blockNumberWithMessage = ethtypes.EthUint64(ts.Height()) - - tsCid, err := ts.Key().Cid() - require.NoError(t, err) - - blockHashWithMessage, err = ethtypes.EthHashFromCid(tsCid) - require.NoError(t, err) - break - } - - // install contract - contract2Hex, err := os.ReadFile("./contracts/SimpleCoin.hex") + result := client.EVM().DeployContract(ctx, deployerAddr, contractBin) + contractAddr, err := address.NewIDAddress(result.ActorID) require.NoError(t, err) - contract, err := hex.DecodeString(string(contract2Hex)) - require.NoError(t, err) + contractEthAddr := ethtypes.EthAddress(result.EthAddress) - // create a new Ethereum account - key, ethAddr, deployer := client.EVM().NewAccount() - _, ethAddr2, _ := client.EVM().NewAccount() - - kit.SendFunds(ctx, t, client, deployer, types.FromFil(1000)) - - gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ - From: ðAddr, - Data: contract, - }) - require.NoError(t, err) - - maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) - require.NoError(t, err) - - tx := ethtypes.EthTxArgs{ - ChainID: build.Eip155ChainId, - Value: big.NewInt(100), - Nonce: 0, - To: ðAddr2, - MaxFeePerGas: types.NanoFil, - MaxPriorityFeePerGas: big.Int(maxPriorityFeePerGas), - GasLimit: int(gaslimit), - V: big.Zero(), - R: big.Zero(), - S: big.Zero(), - } - - client.EVM().SignTransaction(&tx, key.PrivateKey) - signed, err := tx.ToRlpSignedMsg() - require.NoError(t, err) + messageWithEvents, blockHashWithMessage, blockNumberWithMessage := waitForMessageWithEvents(ctx, t, client, deployerAddr, contractAddr) // create a json-rpc client that returns raw json responses var ethapi ethAPIRaw @@ -339,7 +278,7 @@ func TestEthOpenRPCConformance(t *testing.T) { { method: "eth_sendRawTransaction", call: func(a *ethAPIRaw) (json.RawMessage, error) { - return ethapi.EthSendRawTransaction(context.Background(), signed) + return ethapi.EthSendRawTransaction(context.Background(), rawSignedEthTx) }, }, @@ -402,7 +341,7 @@ func TestEthOpenRPCConformance(t *testing.T) { method: "eth_estimateGas", call: func(a *ethAPIRaw) (json.RawMessage, error) { return ethapi.EthEstimateGas(context.Background(), ethtypes.EthCall{ - From: ðAddr, + From: &senderEthAddr, Data: contractBin, }) }, @@ -414,6 +353,29 @@ func TestEthOpenRPCConformance(t *testing.T) { return ethapi.EthFeeHistory(context.Background(), ethtypes.EthUint64(2), "", nil) }, }, + { + method: "eth_getTransactionCount", + variant: "blocknumber", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetTransactionCount(context.Background(), senderEthAddr, "0x0") + }, + }, + + { + method: "eth_getCode", + variant: "blocknumber", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetCode(context.Background(), contractEthAddr, "0x0") + }, + }, + + { + method: "eth_getStorageAt", + variant: "blocknumber", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetStorageAt(context.Background(), contractEthAddr, ethtypes.EthBytes{0}, "0x0") + }, + }, } for _, tc := range testCases { @@ -464,3 +426,62 @@ func TestEthOpenRPCConformance(t *testing.T) { }) } } + +func createRawSignedEthTx(ctx context.Context, t *testing.T, client *kit.TestFullNode, senderEthAddr ethtypes.EthAddress, receiverEthAddr ethtypes.EthAddress, senderKey *key.Key, contractBin []byte) []byte { + gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + From: &senderEthAddr, + Data: contractBin, + }) + require.NoError(t, err) + + maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) + require.NoError(t, err) + + tx := ethtypes.EthTxArgs{ + ChainID: build.Eip155ChainId, + Value: big.NewInt(100), + Nonce: 0, + To: &receiverEthAddr, + MaxFeePerGas: types.NanoFil, + MaxPriorityFeePerGas: big.Int(maxPriorityFeePerGas), + GasLimit: int(gaslimit), + V: big.Zero(), + R: big.Zero(), + S: big.Zero(), + } + + client.EVM().SignTransaction(&tx, senderKey.PrivateKey) + signed, err := tx.ToRlpSignedMsg() + require.NoError(t, err) + return signed +} + +func waitForMessageWithEvents(ctx context.Context, t *testing.T, client *kit.TestFullNode, sender address.Address, target address.Address) (ethtypes.EthHash, ethtypes.EthHash, ethtypes.EthUint64) { + // send a message that exercises event logs + messages := invokeAndWaitUntilAllOnChain(t, client, []Invocation{ + { + Sender: sender, + Target: target, + Selector: EventMatrixContract.Fn["logEventThreeIndexedWithData"], + Data: packUint64Values(44, 27, 19, 12), + }, + }) + + require.NotEmpty(t, messages) + + for msgHash, mts := range messages { + ts := mts.ts + blockNumber := ethtypes.EthUint64(ts.Height()) + + tsCid, err := ts.Key().Cid() + require.NoError(t, err) + + blockHash, err := ethtypes.EthHashFromCid(tsCid) + require.NoError(t, err) + return msgHash, blockHash, blockNumber + } + + // should not get here + t.FailNow() + return ethtypes.EthHash{}, ethtypes.EthHash{}, 0 +} diff --git a/itests/eth_filter_test.go b/itests/eth_filter_test.go index aba61f934..bc12bbb30 100644 --- a/itests/eth_filter_test.go +++ b/itests/eth_filter_test.go @@ -1091,7 +1091,7 @@ func TestEthGetLogsWithBlockRanges(t *testing.T) { // Select events for partitioning for _, m := range messages { if bytes.Equal(m.invocation.Selector, EventMatrixContract.Fn["logEventTwoIndexedWithData"]) { - addr := getContractEthAddress(ctx, t, client, m.invocation.Target) + addr := getEthAddress(ctx, t, client, m.invocation.Target) args := unpackUint64Values(m.invocation.Data) require.Equal(3, len(args), "logEventTwoIndexedWithData should have 3 arguments") @@ -1295,7 +1295,7 @@ type msgInTipset struct { reverted bool } -func getContractEthAddress(ctx context.Context, t *testing.T, client *kit.TestFullNode, addr address.Address) ethtypes.EthAddress { +func getEthAddress(ctx context.Context, t *testing.T, client *kit.TestFullNode, addr address.Address) ethtypes.EthAddress { head, err := client.ChainHead(ctx) require.NoError(t, err) @@ -1446,7 +1446,7 @@ func invokeLogFourData(t *testing.T, client *kit.TestFullNode, iterations int) ( messages := invokeAndWaitUntilAllOnChain(t, client, invocations) - ethAddr := getContractEthAddress(ctx, t, client, idAddr) + ethAddr := getEthAddress(ctx, t, client, idAddr) return ethAddr, messages } @@ -1641,8 +1641,8 @@ func invokeEventMatrix(ctx context.Context, t *testing.T, client *kit.TestFullNo } messages := invokeAndWaitUntilAllOnChain(t, client, invocations) - ethAddr1 := getContractEthAddress(ctx, t, client, contract1) - ethAddr2 := getContractEthAddress(ctx, t, client, contract2) + ethAddr1 := getEthAddress(ctx, t, client, contract1) + ethAddr2 := getEthAddress(ctx, t, client, contract2) return ethAddr1, ethAddr2, messages } diff --git a/itests/eth_transactions_test.go b/itests/eth_transactions_test.go index 0c8f1baa5..ab46378f0 100644 --- a/itests/eth_transactions_test.go +++ b/itests/eth_transactions_test.go @@ -100,11 +100,9 @@ func TestLegacyTransaction(t *testing.T) { require.NoError(t, err) _, err = client.EVM().EthSendRawTransaction(ctx, txBytes) require.ErrorContains(t, err, "legacy transaction is not supported") - } func TestContractDeploymentValidSignature(t *testing.T) { - blockTime := 100 * time.Millisecond client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC()) @@ -253,7 +251,6 @@ func TestContractInvocation(t *testing.T) { // Success. require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status) - } func deployContractTx(ctx context.Context, client *kit.TestFullNode, ethAddr ethtypes.EthAddress, contract []byte) (*ethtypes.EthTxArgs, error) {