From b56215db3f7187709d7543c721c8bb0fb72756ab Mon Sep 17 00:00:00 2001 From: i-norden Date: Wed, 29 Dec 2021 15:01:09 -0600 Subject: [PATCH] integration tests for when we have direct proxy forwarding of eth_calls turned on --- test/direct_proxy_integration_test.go | 445 ++++++++++++++++++++++++++ test/integration_test.go | 7 + 2 files changed, 452 insertions(+) create mode 100644 test/direct_proxy_integration_test.go diff --git a/test/direct_proxy_integration_test.go b/test/direct_proxy_integration_test.go new file mode 100644 index 00000000..fb653c9b --- /dev/null +++ b/test/direct_proxy_integration_test.go @@ -0,0 +1,445 @@ +package integration_test + +import ( + "context" + "math/big" + "os" + "strconv" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/vulcanize/ipld-eth-server/pkg/eth" + integration "github.com/vulcanize/ipld-eth-server/test" +) + +var _ = Describe("Integration test", func() { + directProxyEthCalls, err := strconv.ParseBool(os.Getenv("ETH_FORWARD_ETH_CALLS")) + Expect(err).To(BeNil()) + if !directProxyEthCalls { + Skip("skipping direct-proxy-forwarding integration tests") + } + gethHttpPath := "http://127.0.0.1:8545" + gethClient, err := ethclient.Dial(gethHttpPath) + Expect(err).ToNot(HaveOccurred()) + + ipldEthHttpPath := "http://127.0.0.1:8081" + ipldClient, err := ethclient.Dial(ipldEthHttpPath) + Expect(err).ToNot(HaveOccurred()) + + ctx := context.Background() + + var contract *integration.ContractDeployed + var erc20TotalSupply *big.Int + var tx *integration.Tx + var bigIntResult bool + var contractErr error + var txErr error + sleepInterval := 2 * time.Second + + Describe("get Block", func() { + BeforeEach(func() { + contract, contractErr = integration.DeployContract() + time.Sleep(sleepInterval) + }) + + It("get not existing block by number", func() { + Expect(contractErr).ToNot(HaveOccurred()) + + blockNum := contract.BlockNumber + 100 + + gethBlock, err := gethClient.BlockByNumber(ctx, big.NewInt(int64(blockNum))) + Expect(err).To(MatchError(ethereum.NotFound)) + Expect(gethBlock).To(BeZero()) + + ipldBlock, err := ipldClient.BlockByNumber(ctx, big.NewInt(int64(blockNum))) + Expect(err).To(MatchError(ethereum.NotFound)) + Expect(ipldBlock).To(BeZero()) + }) + + It("get not existing block by hash", func() { + gethBlock, err := gethClient.BlockByHash(ctx, common.HexToHash(nonExistingBlockHash)) + Expect(err).To(MatchError(ethereum.NotFound)) + Expect(gethBlock).To(BeZero()) + + ipldBlock, err := ipldClient.BlockByHash(ctx, common.HexToHash(nonExistingBlockHash)) + Expect(err).To(MatchError(ethereum.NotFound)) + Expect(ipldBlock).To(BeZero()) + }) + + It("get block by number", func() { + Expect(contractErr).ToNot(HaveOccurred()) + + blockNum := contract.BlockNumber + + _, err := gethClient.BlockByNumber(ctx, big.NewInt(int64(blockNum))) + Expect(err).ToNot(HaveOccurred()) + + _, err = ipldClient.BlockByNumber(ctx, big.NewInt(int64(blockNum))) + Expect(err).To(HaveOccurred()) + }) + + It("get block by hash", func() { + _, err := gethClient.BlockByHash(ctx, common.HexToHash(contract.BlockHash)) + Expect(err).ToNot(HaveOccurred()) + + _, err = ipldClient.BlockByHash(ctx, common.HexToHash(contract.BlockHash)) + Expect(err).To(HaveOccurred()) + }) + }) + + Describe("Transaction", func() { + BeforeEach(func() { + contract, contractErr = integration.DeployContract() + time.Sleep(sleepInterval) + }) + + It("Get tx by hash", func() { + Expect(contractErr).ToNot(HaveOccurred()) + + _, _, err := gethClient.TransactionByHash(ctx, common.HexToHash(contract.TransactionHash)) + Expect(err).ToNot(HaveOccurred()) + + _, _, err = ipldClient.TransactionByHash(ctx, common.HexToHash(contract.TransactionHash)) + Expect(err).To(HaveOccurred()) + }) + + It("Get tx by block hash and index", func() { + _, err := gethClient.TransactionInBlock(ctx, common.HexToHash(contract.BlockHash), 0) + Expect(err).ToNot(HaveOccurred()) + + _, err = ipldClient.TransactionInBlock(ctx, common.HexToHash(contract.BlockHash), 0) + Expect(err).To(HaveOccurred()) + }) + }) + + Describe("Receipt", func() { + BeforeEach(func() { + contract, contractErr = integration.DeployContract() + time.Sleep(sleepInterval) + }) + + It("Get tx receipt", func() { + Expect(contractErr).ToNot(HaveOccurred()) + + _, err := gethClient.TransactionReceipt(ctx, common.HexToHash(contract.TransactionHash)) + Expect(err).ToNot(HaveOccurred()) + + _, err = ipldClient.TransactionReceipt(ctx, common.HexToHash(contract.TransactionHash)) + Expect(err).To(HaveOccurred()) + }) + }) + + Describe("FilterLogs", func() { + BeforeEach(func() { + contract, contractErr = integration.DeployContract() + time.Sleep(sleepInterval) + }) + + It("with blockhash", func() { + Expect(contractErr).ToNot(HaveOccurred()) + + blockHash := common.HexToHash(contract.BlockHash) + filterQuery := ethereum.FilterQuery{ + //Addresses: addresses, + BlockHash: &blockHash, + Topics: [][]common.Hash{}, + } + + _, err := gethClient.FilterLogs(ctx, filterQuery) + Expect(err).ToNot(HaveOccurred()) + + _, err = ipldClient.FilterLogs(ctx, filterQuery) + Expect(err).To(HaveOccurred()) + }) + }) + + Describe("CodeAt", func() { + BeforeEach(func() { + contract, contractErr = integration.DeployContract() + time.Sleep(sleepInterval) + }) + + It("gets code at non-existing address without block number", func() { + Expect(contractErr).ToNot(HaveOccurred()) + + gethCode, err := gethClient.CodeAt(ctx, common.HexToAddress(nonExistingAddress), nil) + Expect(err).ToNot(HaveOccurred()) + + ipldCode, err := ipldClient.CodeAt(ctx, common.HexToAddress(nonExistingAddress), nil) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethCode).To(BeEmpty()) + Expect(gethCode).To(Equal(ipldCode)) + }) + It("gets code of deployed contract without block number", func() { + gethCode, err := gethClient.CodeAt(ctx, common.HexToAddress(contract.Address), nil) + Expect(err).ToNot(HaveOccurred()) + + ipldCode, err := ipldClient.CodeAt(ctx, common.HexToAddress(contract.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(gethCode).To(Equal(ipldCode)) + }) + It("gets code of deployed contract with block number", func() { + gethCode, err := gethClient.CodeAt(ctx, common.HexToAddress(contract.Address), big.NewInt(int64(contract.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + + ipldCode, err := ipldClient.CodeAt(ctx, common.HexToAddress(contract.Address), big.NewInt(int64(contract.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + Expect(gethCode).To(Equal(ipldCode)) + }) + It("gets code of contract that doesn't exist at this height", func() { + gethCode, err := gethClient.CodeAt(ctx, common.HexToAddress(contract.Address), big.NewInt(int64(contract.BlockNumber-1))) + Expect(err).ToNot(HaveOccurred()) + + ipldCode, err := ipldClient.CodeAt(ctx, common.HexToAddress(contract.Address), big.NewInt(int64(contract.BlockNumber-1))) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethCode).To(BeEmpty()) + Expect(gethCode).To(Equal(ipldCode)) + }) + }) + + Describe("Get balance", func() { + address := "0x1111111111111111111111111111111111111112" + BeforeEach(func() { + tx, txErr = integration.SendEth(address, "0.01") + time.Sleep(sleepInterval) + }) + + It("gets balance for an account with eth without block number", func() { + Expect(txErr).ToNot(HaveOccurred()) + + gethBalance, err := gethClient.BalanceAt(ctx, common.HexToAddress(address), nil) + Expect(err).ToNot(HaveOccurred()) + + ipldBalance, err := ipldClient.BalanceAt(ctx, common.HexToAddress(address), nil) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethBalance).To(Equal(ipldBalance)) + }) + It("gets balance for an account with eth with block number", func() { + Expect(txErr).ToNot(HaveOccurred()) + + gethBalance, err := gethClient.BalanceAt(ctx, common.HexToAddress(address), big.NewInt(int64(tx.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + + ipldBalance, err := ipldClient.BalanceAt(ctx, common.HexToAddress(address), big.NewInt(int64(tx.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethBalance).To(Equal(ipldBalance)) + }) + It("gets historical balance for an account with eth with block number", func() { + Expect(txErr).ToNot(HaveOccurred()) + + gethBalance, err := gethClient.BalanceAt(ctx, common.HexToAddress(address), big.NewInt(int64(tx.BlockNumber-1))) + Expect(err).ToNot(HaveOccurred()) + + ipldBalance, err := ipldClient.BalanceAt(ctx, common.HexToAddress(address), big.NewInt(int64(tx.BlockNumber-1))) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethBalance).To(Equal(ipldBalance)) + }) + It("gets balance for a non-existing account without block number", func() { + Expect(txErr).ToNot(HaveOccurred()) + + gethBalance, err := gethClient.BalanceAt(ctx, common.HexToAddress(nonExistingAddress), nil) + Expect(err).ToNot(HaveOccurred()) + + ipldBalance, err := ipldClient.BalanceAt(ctx, common.HexToAddress(nonExistingAddress), nil) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethBalance).To(Equal(ipldBalance)) + }) + It("gets balance for an non-existing block number", func() { + Expect(txErr).ToNot(HaveOccurred()) + + gethBalance, err := gethClient.BalanceAt(ctx, common.HexToAddress(address), big.NewInt(int64(tx.BlockNumber+3))) + Expect(err).To(MatchError("header not found")) + + ipldBalance, err := ipldClient.BalanceAt(ctx, common.HexToAddress(nonExistingAddress), big.NewInt(int64(tx.BlockNumber+3))) + Expect(err).To(MatchError("header not found")) + + Expect(gethBalance).To(Equal(ipldBalance)) + }) + }) + + Describe("Get Storage", func() { + BeforeEach(func() { + contract, contractErr = integration.DeployContract() + erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10) + + time.Sleep(sleepInterval) + }) + + It("gets ERC20 total supply (without block number)", func() { + Expect(contractErr).ToNot(HaveOccurred()) + Expect(bigIntResult).To(Equal(true)) + + totalSupplyIndex := "0x2" + + gethStorage, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), nil) + Expect(err).ToNot(HaveOccurred()) + + gethTotalSupply := new(big.Int).SetBytes(gethStorage) + Expect(gethTotalSupply).To(Equal(erc20TotalSupply)) + + ipldStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), nil) + Expect(err).ToNot(HaveOccurred()) + + ipldTotalSupply := new(big.Int).SetBytes(ipldStorage) + Expect(ipldTotalSupply).To(Equal(erc20TotalSupply)) + + Expect(gethStorage).To(Equal(ipldStorage)) + }) + + It("gets ERC20 total supply (with block number)", func() { + totalSupplyIndex := "0x2" + + gethStorage, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(int64(contract.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + + gethTotalSupply := new(big.Int).SetBytes(gethStorage) + Expect(gethTotalSupply).To(Equal(erc20TotalSupply)) + + ipldStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(int64(contract.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + Expect(gethStorage).To(Equal(ipldStorage)) + }) + It("gets storage for non-existing account", func() { + totalSupplyIndex := "0x2" + + gethStorage, err := gethClient.StorageAt(ctx, common.HexToAddress(nonExistingAddress), common.HexToHash(totalSupplyIndex), big.NewInt(int64(contract.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + + ipldStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(nonExistingAddress), common.HexToHash(totalSupplyIndex), big.NewInt(int64(contract.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + Expect(gethStorage).To(Equal(ipldStorage)) + }) + It("gets storage for non-existing contract slot", func() { + gethStorage, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), randomHash, big.NewInt(int64(contract.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + + ipldStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract.Address), randomHash, big.NewInt(int64(contract.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + Expect(gethStorage).To(Equal(ipldStorage)) + }) + It("gets storage for non-existing contract", func() { + totalSupplyIndex := "0x2" + gethStorage, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(0)) + Expect(err).ToNot(HaveOccurred()) + + ipldStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(0)) + Expect(err).ToNot(HaveOccurred()) + Expect(gethStorage).To(Equal(ipldStorage)) + }) + It("gets storage for non-existing block number", func() { + blockNum := contract.BlockNumber + 100 + totalSupplyIndex := "0x2" + + gethStorage, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(int64(blockNum))) + Expect(err).To(MatchError("header not found")) + + ipldStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(int64(blockNum))) + Expect(err).To(MatchError("header not found")) + Expect(gethStorage).To(Equal(ipldStorage)) + }) + + It("get storage after self destruct", func() { + totalSupplyIndex := "0x2" + + tx, err := integration.DestroyContract(contract.Address) + Expect(err).ToNot(HaveOccurred()) + + time.Sleep(sleepInterval) + + gethStorage1, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(tx.BlockNumber-1)) + Expect(err).ToNot(HaveOccurred()) + gethStorage2, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(tx.BlockNumber)) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethStorage1).NotTo(Equal(gethStorage2)) + Expect(gethStorage2).To(Equal(eth.EmptyNodeValue)) + + ipldStorage1, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(tx.BlockNumber-1)) + Expect(err).ToNot(HaveOccurred()) + ipldStorage2, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(tx.BlockNumber)) + Expect(err).ToNot(HaveOccurred()) + + Expect(ipldStorage1).To(Equal(gethStorage1)) + Expect(ipldStorage2).To(Equal(gethStorage2)) + + // Query the current block + ipldStorage3, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), nil) + Expect(err).ToNot(HaveOccurred()) + + Expect(ipldStorage2).To(Equal(ipldStorage3)) + }) + }) + + Describe("eth call", func() { + BeforeEach(func() { + contract, contractErr = integration.DeployContract() + erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10) + + time.Sleep(sleepInterval) + }) + + It("calls totalSupply() without block number", func() { + Expect(contractErr).ToNot(HaveOccurred()) + Expect(bigIntResult).To(Equal(true)) + + contractAddress := common.HexToAddress(contract.Address) + + msg := ethereum.CallMsg{ + To: &contractAddress, + Data: common.Hex2Bytes("18160ddd"), // totalSupply() + } + gethResult, err := gethClient.CallContract(ctx, msg, nil) + Expect(err).ToNot(HaveOccurred()) + + gethTotalSupply := new(big.Int).SetBytes(gethResult) + Expect(gethTotalSupply).To(Equal(erc20TotalSupply)) + + ipldResult, err := ipldClient.CallContract(ctx, msg, nil) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethResult).To(Equal(ipldResult)) + }) + + It("calls totalSupply() with block number", func() { + contractAddress := common.HexToAddress(contract.Address) + + msg := ethereum.CallMsg{ + To: &contractAddress, + Data: common.Hex2Bytes("18160ddd"), // totalSupply() + } + gethResult, err := gethClient.CallContract(ctx, msg, big.NewInt(int64(contract.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + + gethTotalSupply := new(big.Int).SetBytes(gethResult) + Expect(gethTotalSupply).To(Equal(erc20TotalSupply)) + + ipldResult, err := ipldClient.CallContract(ctx, msg, big.NewInt(int64(contract.BlockNumber))) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethResult).To(Equal(ipldResult)) + }) + }) + + Describe("Chain ID", func() { + It("Check chain id", func() { + gethChainId, err := gethClient.ChainID(ctx) + Expect(err).ToNot(HaveOccurred()) + + ipldChainId, err := ipldClient.ChainID(ctx) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethChainId).To(Equal(ipldChainId)) + }) + }) +}) diff --git a/test/integration_test.go b/test/integration_test.go index d250fcce..5a6f1ab6 100644 --- a/test/integration_test.go +++ b/test/integration_test.go @@ -3,6 +3,8 @@ package integration_test import ( "context" "math/big" + "os" + "strconv" "time" "github.com/ethereum/go-ethereum" @@ -27,6 +29,11 @@ var ( ) var _ = Describe("Integration test", func() { + directProxyEthCalls, err := strconv.ParseBool(os.Getenv("ETH_FORWARD_ETH_CALLS")) + Expect(err).To(BeNil()) + if directProxyEthCalls { + Skip("skipping no-direct-proxy-forwarding integration tests") + } gethHttpPath := "http://127.0.0.1:8545" gethClient, err := ethclient.Dial(gethHttpPath) Expect(err).ToNot(HaveOccurred())