unit tests for GetTransactionCount, GetTransactionReceipt, GetBalance, and GetCode

This commit is contained in:
Ian Norden 2020-10-29 22:08:26 -05:00
parent cffceb53db
commit b664aee621
6 changed files with 186 additions and 183 deletions

View File

@ -20,18 +20,19 @@ import (
"context"
"strconv"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
eth2 "github.com/vulcanize/ipld-eth-indexer/pkg/eth"
"github.com/vulcanize/ipld-eth-indexer/pkg/postgres"
shared2 "github.com/vulcanize/ipld-eth-indexer/pkg/shared"
"github.com/vulcanize/ipld-eth-server/pkg/eth"
"github.com/vulcanize/ipld-eth-server/pkg/eth/test_helpers"
@ -39,6 +40,8 @@ import (
)
var (
randomAddr = common.HexToAddress("0x1C3ab14BBaD3D99F4203bd7a11aCB94882050E6f")
randomHash = crypto.Keccak256Hash(randomAddr.Bytes())
number = rpc.BlockNumber(test_helpers.BlockNumber.Int64())
blockHash = test_helpers.MockBlock.Header().Hash()
ctx = context.Background()
@ -128,6 +131,48 @@ var (
expectRawTx, _ = rlp.EncodeToBytes(test_helpers.MockTransactions[0])
expectRawTx2, _ = rlp.EncodeToBytes(test_helpers.MockTransactions[1])
expectRawTx3, _ = rlp.EncodeToBytes(test_helpers.MockTransactions[2])
expectedReceipt = map[string]interface{}{
"blockHash": blockHash,
"blockNumber": hexutil.Uint64(uint64(number.Int64())),
"transactionHash": expectedTransaction.Hash,
"transactionIndex": hexutil.Uint64(0),
"from": expectedTransaction.From,
"to": expectedTransaction.To,
"gasUsed": hexutil.Uint64(test_helpers.MockReceipts[0].GasUsed),
"cumulativeGasUsed": hexutil.Uint64(test_helpers.MockReceipts[0].CumulativeGasUsed),
"contractAddress": nil,
"logs": test_helpers.MockReceipts[0].Logs,
"logsBloom": test_helpers.MockReceipts[0].Bloom,
"root": hexutil.Bytes(test_helpers.MockReceipts[0].PostState),
}
expectedReceipt2 = map[string]interface{}{
"blockHash": blockHash,
"blockNumber": hexutil.Uint64(uint64(number.Int64())),
"transactionHash": expectedTransaction2.Hash,
"transactionIndex": hexutil.Uint64(1),
"from": expectedTransaction2.From,
"to": expectedTransaction2.To,
"gasUsed": hexutil.Uint64(test_helpers.MockReceipts[1].GasUsed),
"cumulativeGasUsed": hexutil.Uint64(test_helpers.MockReceipts[1].CumulativeGasUsed),
"contractAddress": nil,
"logs": test_helpers.MockReceipts[1].Logs,
"logsBloom": test_helpers.MockReceipts[1].Bloom,
"root": hexutil.Bytes(test_helpers.MockReceipts[1].PostState),
}
expectedReceipt3 = map[string]interface{}{
"blockHash": blockHash,
"blockNumber": hexutil.Uint64(uint64(number.Int64())),
"transactionHash": expectedTransaction3.Hash,
"transactionIndex": hexutil.Uint64(2),
"from": expectedTransaction3.From,
"to": expectedTransaction3.To,
"gasUsed": hexutil.Uint64(test_helpers.MockReceipts[2].GasUsed),
"cumulativeGasUsed": hexutil.Uint64(test_helpers.MockReceipts[2].CumulativeGasUsed),
"contractAddress": nil,
"logs": test_helpers.MockReceipts[2].Logs,
"logsBloom": test_helpers.MockReceipts[2].Bloom,
"root": hexutil.Bytes(test_helpers.MockReceipts[2].PostState),
}
)
var _ = Describe("API", func() {
@ -137,7 +182,8 @@ var _ = Describe("API", func() {
backend *eth.Backend
api *eth.PublicEthAPI
)
BeforeEach(func() {
// Test db setup, rather than using BeforeEach we only need to setup once since the tests do not mutate the database
It("", func() {
var err error
db, err = shared.SetupDB()
Expect(err).ToNot(HaveOccurred())
@ -147,6 +193,8 @@ var _ = Describe("API", func() {
api = eth.NewPublicEthAPI(backend, nil)
err = indexAndPublisher.Publish(test_helpers.MockConvertedPayload)
Expect(err).ToNot(HaveOccurred())
err = publishCode(db, test_helpers.ContractCodeHash, test_helpers.ContractCode)
Expect(err).ToNot(HaveOccurred())
uncles := test_helpers.MockBlock.Uncles()
uncleHashes := make([]common.Hash, len(uncles))
for i, uncle := range uncles {
@ -154,21 +202,13 @@ var _ = Describe("API", func() {
}
expectedBlock["uncles"] = uncleHashes
})
AfterEach(func() {
eth.TearDownDB(db)
})
// Single test db tear down at end of all tests
defer It("", func() { eth.TearDownDB(db) })
/*
Headers and blocks
*/
Describe("GetHeaderByHash", func() {
It("Retrieves a header by hash", func() {
header := api.GetHeaderByHash(ctx, blockHash)
Expect(header).To(Equal(expectedHeader))
})
})
Describe("GetHeaderByNumber", func() {
It("Retrieves a header by number", func() {
header, err := api.GetHeaderByNumber(ctx, number)
@ -298,8 +338,23 @@ var _ = Describe("API", func() {
*/
Describe("GetTransactionCount", func() {
It("Retrieves the number of transactions the given address has sent for the given block number or block hash", func() {
It("Retrieves the number of transactions the given address has sent for the given block number", func() {
count, err := api.GetTransactionCount(ctx, test_helpers.ContractAddress, rpc.BlockNumberOrHashWithNumber(number))
Expect(err).ToNot(HaveOccurred())
Expect(*count).To(Equal(hexutil.Uint64(1)))
count, err = api.GetTransactionCount(ctx, test_helpers.AccountAddresss, rpc.BlockNumberOrHashWithNumber(number))
Expect(err).ToNot(HaveOccurred())
Expect(*count).To(Equal(hexutil.Uint64(0)))
})
It("Retrieves the number of transactions the given address has sent for the given block hash", func() {
count, err := api.GetTransactionCount(ctx, test_helpers.ContractAddress, rpc.BlockNumberOrHashWithHash(blockHash, true))
Expect(err).ToNot(HaveOccurred())
Expect(*count).To(Equal(hexutil.Uint64(1)))
count, err = api.GetTransactionCount(ctx, test_helpers.AccountAddresss, rpc.BlockNumberOrHashWithHash(blockHash, true))
Expect(err).ToNot(HaveOccurred())
Expect(*count).To(Equal(hexutil.Uint64(0)))
})
})
@ -398,6 +453,10 @@ var _ = Describe("API", func() {
Expect(err).ToNot(HaveOccurred())
Expect(tx).To(Equal(expectedTransaction3))
})
It("Throws an error if it cannot find a tx for the provided tx hash", func() {
_, err := api.GetTransactionByHash(ctx, randomHash)
Expect(err).To(HaveOccurred())
})
})
Describe("GetRawTransactionByHash", func() {
@ -417,6 +476,10 @@ var _ = Describe("API", func() {
Expect(err).ToNot(HaveOccurred())
Expect(tx).To(Equal(hexutil.Bytes(expectRawTx3)))
})
It("Throws an error if it cannot find a tx for the provided tx hash", func() {
_, err := api.GetRawTransactionByHash(ctx, randomHash)
Expect(err).To(HaveOccurred())
})
})
/*
@ -427,7 +490,24 @@ var _ = Describe("API", func() {
Describe("GetTransactionReceipt", func() {
It("Retrieves a receipt by tx hash", func() {
hash := test_helpers.MockTransactions[0].Hash()
rct, err := api.GetTransactionReceipt(ctx, hash)
Expect(err).ToNot(HaveOccurred())
Expect(rct).To(Equal(expectedReceipt))
hash = test_helpers.MockTransactions[1].Hash()
rct, err = api.GetTransactionReceipt(ctx, hash)
Expect(err).ToNot(HaveOccurred())
Expect(rct).To(Equal(expectedReceipt2))
hash = test_helpers.MockTransactions[2].Hash()
rct, err = api.GetTransactionReceipt(ctx, hash)
Expect(err).ToNot(HaveOccurred())
Expect(rct).To(Equal(expectedReceipt3))
})
It("Throws an error if it cannot find a receipt for the provided tx hash", func() {
_, err := api.GetTransactionReceipt(ctx, randomHash)
Expect(err).To(HaveOccurred())
})
})
@ -809,21 +889,56 @@ var _ = Describe("API", func() {
*/
Describe("GetBalance", func() {
It("Retrieves the eth balance for the provided account address at the block with the provided hash or number", func() {
It("Retrieves the eth balance for the provided account address at the block with the provided number", func() {
bal, err := api.GetBalance(ctx, test_helpers.AccountAddresss, rpc.BlockNumberOrHashWithNumber(number))
Expect(err).ToNot(HaveOccurred())
Expect(bal).To(Equal((*hexutil.Big)(test_helpers.AccountBalance)))
bal, err = api.GetBalance(ctx, test_helpers.ContractAddress, rpc.BlockNumberOrHashWithNumber(number))
Expect(err).ToNot(HaveOccurred())
Expect(bal).To(Equal((*hexutil.Big)(common.Big0)))
})
It("Retrieves the eth balance for the provided account address at the block with the provided hash", func() {
bal, err := api.GetBalance(ctx, test_helpers.AccountAddresss, rpc.BlockNumberOrHashWithHash(blockHash, true))
Expect(err).ToNot(HaveOccurred())
Expect(bal).To(Equal((*hexutil.Big)(test_helpers.AccountBalance)))
bal, err = api.GetBalance(ctx, test_helpers.ContractAddress, rpc.BlockNumberOrHashWithHash(blockHash, true))
Expect(err).ToNot(HaveOccurred())
Expect(bal).To(Equal((*hexutil.Big)(common.Big0)))
})
It("Throws an error for an account it cannot find the balance for", func() {
_, err := api.GetBalance(ctx, randomAddr, rpc.BlockNumberOrHashWithHash(blockHash, true))
Expect(err).To(HaveOccurred())
})
})
Describe("GetStorageAt", func() {
It("Retrieves the storage value at the provided contract address and storage leaf key at the block with the provided hash or number", func() {
/*
val, err := api.GetStorageAt(ctx, test_helpers.ContractAddress, common.Bytes2Hex(test_helpers.StorageLeafKey), rpc.BlockNumberOrHashWithNumber(number))
Expect(err).ToNot(HaveOccurred())
Expect(val).To(Equal((hexutil.Bytes)(test_helpers.StorageValue)))
*/
})
})
Describe("GetCode", func() {
It("Retrieves the code for the provided contract address at the block with the provied hash or number", func() {
It("Retrieves the code for the provided contract address at the block with the provided number", func() {
code, err := api.GetCode(ctx, test_helpers.ContractAddress, rpc.BlockNumberOrHashWithNumber(number))
Expect(err).ToNot(HaveOccurred())
Expect(code).To(Equal((hexutil.Bytes)(test_helpers.ContractCode)))
})
It("Retrieves the code for the provided contract address at the block with the provided hash", func() {
code, err := api.GetCode(ctx, test_helpers.ContractAddress, rpc.BlockNumberOrHashWithHash(blockHash, true))
Expect(err).ToNot(HaveOccurred())
Expect(code).To(Equal((hexutil.Bytes)(test_helpers.ContractCode)))
})
It("Throws an error for an account it cannot find the code for", func() {
_, err := api.GetCode(ctx, randomAddr, rpc.BlockNumberOrHashWithHash(blockHash, true))
Expect(err).To(HaveOccurred())
})
})
Describe("GetProof", func() {
@ -831,5 +946,21 @@ var _ = Describe("API", func() {
})
})
})
func publishCode(db *postgres.DB, codeHash common.Hash, code []byte) error {
tx, err := db.Beginx()
if err != nil {
return err
}
mhKey, err := shared2.MultihashKeyFromKeccak256(codeHash)
if err != nil {
tx.Rollback()
return err
}
if err := shared2.PublishDirect(tx, mhKey, code); err != nil {
tx.Rollback()
return err
}
return tx.Commit()
}

View File

@ -67,7 +67,12 @@ const (
WHERE state_accounts.state_id = state_cids.id
AND state_cids.header_id = header_cids.id
AND state_leaf_key = $1
AND block_hash = $2`
AND block_number <= (SELECT block_number
FROM eth.header_cids
WHERE block_hash = $2)
AND header_cids.id = (SELECT canonical_header(block_number))
ORDER BY block_number DESC
LIMIT 1`
RetrieveCodeByMhKey = `SELECT data FROM public.blocks WHERE key = $1`
)

View File

@ -89,7 +89,7 @@ var _ = Describe("eth_call", func() {
api = eth.NewPublicEthAPI(backend, nil)
// make the test blockchain (and state)
blocks, receipts, chain = test_helpers.MakeChain(4, test_helpers.Genesis, test_helpers.TestChainGen)
blocks, receipts, chain = test_helpers.MakeChain(5, test_helpers.Genesis, test_helpers.TestChainGen)
pams = statediff.Params{
IntermediateStateNodes: true,
IntermediateStorageNodes: true,
@ -146,7 +146,17 @@ var _ = Describe("eth_call", func() {
To: &test_helpers.ContractAddr,
Data: &bdata,
}
res, err := api.Call(context.Background(), callArgs, rpc.BlockNumberOrHashWithNumber(2), nil)
// Before contract deployment
res, err := api.Call(context.Background(), callArgs, rpc.BlockNumberOrHashWithNumber(0), nil)
Expect(err).ToNot(HaveOccurred())
Expect(res).To(BeNil())
res, err = api.Call(context.Background(), callArgs, rpc.BlockNumberOrHashWithNumber(1), nil)
Expect(err).ToNot(HaveOccurred())
Expect(res).To(BeNil())
// After deployment
res, err = api.Call(context.Background(), callArgs, rpc.BlockNumberOrHashWithNumber(2), nil)
Expect(err).ToNot(HaveOccurred())
expectedRes := hexutil.Bytes(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"))
Expect(res).To(Equal(expectedRes))
@ -160,6 +170,11 @@ var _ = Describe("eth_call", func() {
Expect(err).ToNot(HaveOccurred())
expectedRes = hexutil.Bytes(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000009"))
Expect(res).To(Equal(expectedRes))
res, err = api.Call(context.Background(), callArgs, rpc.BlockNumberOrHashWithNumber(5), nil)
Expect(err).ToNot(HaveOccurred())
expectedRes = hexutil.Bytes(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000"))
Expect(res).To(Equal(expectedRes))
})
})
})

View File

@ -87,12 +87,19 @@ const (
WHERE state_cids.header_id = header_cids.id
AND state_cids.mh_key = blocks.key
AND state_leaf_key = $1
AND block_hash = $2`
AND block_number <= (SELECT block_number
FROM eth.header_cids
WHERE block_hash = $2)
AND header_cids.id = (SELECT canonical_header(block_number))
ORDER BY block_number DESC
LIMIT 1`
RetrieveAccountByLeafKeyAndBlockNumberPgStr = `SELECT state_cids.cid, data FROM eth.state_cids, eth.header_cids, public.blocks
WHERE state_cids.header_id = header_cids.id
AND state_cids.mh_key = blocks.key
AND state_leaf_key = $1
AND block_number = $2`
AND block_number <= $2
ORDER BY block_number DESC
LIMIT 1`
)
type ipldResult struct {

View File

@ -1,156 +0,0 @@
// VulcanizeDB
// Copyright © 2019 Vulcanize
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package eth_test
/*
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
eth2 "github.com/vulcanize/ipld-eth-indexer/pkg/eth"
"github.com/vulcanize/ipld-eth-indexer/pkg/postgres"
"github.com/vulcanize/ipld-eth-server/pkg/eth"
"github.com/vulcanize/ipld-eth-server/pkg/eth/mocks"
"github.com/vulcanize/ipld-eth-server/pkg/shared"
)
var _ = Describe("IPLD Retriever", func() {
var (
db *postgres.DB
repo *eth2.IPLDPublisher
//retriever *eth.IPLDRetriever
)
BeforeEach(func() {
var err error
db, err = shared.SetupDB()
Expect(err).ToNot(HaveOccurred())
repo = eth2.NewIPLDPublisher(db)
//retriever = eth.NewIPLDRetriever(db)
err = repo.Publish(mocks.MockConvertedPayload)
Expect(err).ToNot(HaveOccurred())
err = repo.Publish(mocks.MockConvertedPayload2)
Expect(err).ToNot(HaveOccurred())
})
AfterEach(func() {
eth.TearDownDB(db)
})
Describe("RetrieveHeadersByHashes", func() {
It("Retrieves all of the headers that correspond to the provided hashes", func() {
})
})
Describe("RetrieveHeadersByBlockNumber", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveHeaderByHash", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveUnclesByHashes", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveUnclesByBlockHash", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveUnclesByBlockNumber", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveUncleByHash", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveTransactionsByHashes", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveTransactionsByBlockHash", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveTransactionsByBlockNumber", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveTransactionByTxHash", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveReceiptsByTxHashes", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveReceiptsByBlockHash", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveReceiptsByBlockNumber", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveReceiptByHash", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveAccountByAddressAndBlockHash", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
Describe("RetrieveAccountByAddressAndBlockNumber", func() {
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
})
})
})
*/

View File

@ -259,7 +259,7 @@ var (
// statediff data
storageLocation = common.HexToHash("0")
StorageLeafKey = crypto.Keccak256Hash(storageLocation[:]).Bytes()
StorageValue = common.Hex2Bytes("01")
StorageValue = crypto.Keccak256([]byte{1, 2, 3, 4, 5})
StoragePartialPath = common.Hex2Bytes("20290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")
StorageLeafNode, _ = rlp.EncodeToBytes([]interface{}{
StoragePartialPath,
@ -268,7 +268,7 @@ var (
nonce1 = uint64(1)
ContractRoot = "0x821e2556a290c86405f8160a2d662042a431ba456b9db265c79bb837c04be5f0"
ContractCodeHash = common.HexToHash("0x753f98a8d4328b15636e46f66f2cb4bc860100aa17967cc145fcd17d1d4710ea")
ContractCodeHash = crypto.Keccak256Hash(MockContractByteCode)
contractPath = common.Bytes2Hex([]byte{'\x06'})
ContractLeafKey = testhelpers.AddressToLeafKey(ContractAddress)
ContractAccount, _ = rlp.EncodeToBytes(state.Account{
@ -284,13 +284,14 @@ var (
})
nonce0 = uint64(0)
AccountBalance = big.NewInt(1000)
AccountRoot = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
AccountCodeHash = common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
AccountAddresss = common.HexToAddress("0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e")
AccountLeafKey = testhelpers.Account2LeafKey
Account, _ = rlp.EncodeToBytes(state.Account{
Nonce: nonce0,
Balance: big.NewInt(1000),
Balance: AccountBalance,
CodeHash: AccountCodeHash.Bytes(),
Root: common.HexToHash(AccountRoot),
})