diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 00000000..93a62f50 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,3 @@ +.PHONY: run-tests +run-tests: ## Runs all tests within the workspace + go test -v -race ./... \ No newline at end of file diff --git a/test/ethtransfer_test.go b/test/ethtransfer_test.go new file mode 100644 index 00000000..e7326c20 --- /dev/null +++ b/test/ethtransfer_test.go @@ -0,0 +1,54 @@ +package test + +import ( + "math/big" + "testing" + "time" + + "github.com/0xPolygon/cdk/test/operations" + "github.com/stretchr/testify/require" + "github.com/umbracle/ethgo" + "github.com/umbracle/ethgo/jsonrpc" + "github.com/umbracle/ethgo/wallet" +) + +func TestEthTransfer(t *testing.T) { + cmd := exec.Command("kurtosis", "port", "print", "cdk-v1", "zkevm-node-rpc-001", "http-rpc") + output, err := cmd.CombinedOutput() + if err != nil { + log.Fatalf("Failed to execute command: %s", err) + } + operations.L2RPCURL = strings.TrimSpace(string(output)) + + const amountOfTxsToSend = 10 + client, err := jsonrpc.NewClient(operations.L2RPCURL) + require.NoError(t, err) + key, err := operations.GetL2Wallet() + require.NoError(t, err) + signer := wallet.NewEIP155Signer(operations.L2ChainID) + initialNonce, err := client.Eth().GetNonce(key.Address(), ethgo.Latest) + require.NoError(t, err) + gasPrice, err := client.Eth().GasPrice() + require.NoError(t, err) + + txHashes := []ethgo.Hash{} + for i := 0; i < amountOfTxsToSend; i++ { + tx := ðgo.Transaction{ + ChainID: big.NewInt(operations.L2ChainID), + Nonce: initialNonce + uint64(i), + GasPrice: gasPrice, + Gas: 21000, + To: ðgo.ZeroAddress, + } + signedTxn, err := signer.SignTx(tx, key) + require.NoError(t, err) + rawTx, err := signedTxn.MarshalRLPTo(nil) + require.NoError(t, err) + hash, err := client.Eth().SendRawTransaction(rawTx) + require.NoError(t, err) + txHashes = append(txHashes, hash) + } + for _, h := range txHashes { + require.NoError(t, operations.WaitTxToBeMined(h, operations.Verified, client, time.Minute*2)) + } +} \ No newline at end of file diff --git a/test/operations/operations.go b/test/operations/operations.go new file mode 100644 index 00000000..f4fc7ca9 --- /dev/null +++ b/test/operations/operations.go @@ -0,0 +1,24 @@ +package operations + +import( + "encoding/hex" + "github.com/umbracle/ethgo/wallet" +) + +const ( + L1RPCURL = "http://el-1-geth-lighthouse:8545" + L2ChainID = 10101 + + // Prefunded account present on kurtosis-cdk + PrivateKeyWithFundsOnL2 = "12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625" +) + +var L2RPCURL = "http://localhost:8123" + +func GetL2Wallet() (*wallet.Key, error) { + prvKeyBytes, err := hex.DecodeString(PrivateKeyWithFundsOnL2) + if err != nil { + return nil, err + } + return wallet.NewWalletFromPrivKey(prvKeyBytes) +} \ No newline at end of file diff --git a/test/operations/transactions.go b/test/operations/transactions.go new file mode 100644 index 00000000..a680dd70 --- /dev/null +++ b/test/operations/transactions.go @@ -0,0 +1,67 @@ +package operations + +import ( + "errors" + "fmt" + "time" + + "github.com/umbracle/ethgo" + "github.com/umbracle/ethgo/jsonrpc" +) + +type ConfirmationLevel string + +const ( + Trusted ConfirmationLevel = "trusted" + Virtual ConfirmationLevel = "virtual" + Verified ConfirmationLevel = "verified" +) + +func WaitTxToBeMined(hash ethgo.Hash, level ConfirmationLevel, client *jsonrpc.Client, timeout time.Duration) error { + startingTime := time.Now() + fmt.Printf("waiting for tx %s to be included in the %s state\n", hash.String(), level) + var ( + encodedL2BlockNumber string + isVirtualized bool + isVerified bool + ) + for time.Since(startingTime) < timeout { + if encodedL2BlockNumber == "" { + receipt, err := client.Eth().GetTransactionReceipt(hash) + if err != nil || receipt == nil { + time.Sleep(time.Second) + continue + } + fmt.Printf("tx %s included in the trusted state at the L2 block %d\n", hash.String(), receipt.BlockNumber) + if level == Trusted { + return nil + } + encodedL2BlockNumber = fmt.Sprintf("0x%x", receipt.BlockNumber) + } + + if !isVirtualized { + if err := client.Call("zkevm_isBlockVirtualized", &isVirtualized, encodedL2BlockNumber); err != nil { + time.Sleep(time.Second) + continue + } + if isVirtualized { + fmt.Printf("tx %s included in the virtual state\n", hash.String()) + if level == Virtual { + return nil + } + } else { + time.Sleep(time.Second) + continue + } + } + if err := client.Call("zkevm_isBlockConsolidated", &isVerified, encodedL2BlockNumber); err != nil { + time.Sleep(time.Second) + continue + } + if isVerified { + fmt.Printf("tx %s included in the verified state\n", hash.String()) + return nil + } + } + return errors.New("timed out") +} \ No newline at end of file