Add indexer tests for header and transactions in a non canonical block
This commit is contained in:
parent
11286ebe77
commit
f8c715fedd
@ -24,15 +24,15 @@ var (
|
||||
ind interfaces.StateDiffIndexer
|
||||
ipfsPgGet = `SELECT data FROM public.blocks
|
||||
WHERE key = $1 AND block_number = $2`
|
||||
tx1, tx2, tx3, tx4, tx5, rct1, rct2, rct3, rct4, rct5 []byte
|
||||
mockBlock *types.Block
|
||||
headerCID, trx1CID, trx2CID, trx3CID, trx4CID, trx5CID cid.Cid
|
||||
rct1CID, rct2CID, rct3CID, rct4CID, rct5CID cid.Cid
|
||||
rctLeaf1, rctLeaf2, rctLeaf3, rctLeaf4, rctLeaf5 []byte
|
||||
state1CID, state2CID, storageCID cid.Cid
|
||||
contract1Address, contract2Address, contract3Address, contract4Address string
|
||||
contract1CreatedAt, contract2CreatedAt, contract3CreatedAt, contract4CreatedAt uint64
|
||||
lastFilledAt, watchedAt1, watchedAt2, watchedAt3 uint64
|
||||
tx1, tx2, tx3, tx4, tx5, rct1, rct2, rct3, rct4, rct5 []byte
|
||||
mockBlock, mockNonCanonicalBlock *types.Block
|
||||
headerCID, mockNonCanonicalHeaderCID, trx1CID, trx2CID, trx3CID, trx4CID, trx5CID cid.Cid
|
||||
rct1CID, rct2CID, rct3CID, rct4CID, rct5CID cid.Cid
|
||||
rctLeaf1, rctLeaf2, rctLeaf3, rctLeaf4, rctLeaf5 []byte
|
||||
state1CID, state2CID, storageCID cid.Cid
|
||||
contract1Address, contract2Address, contract3Address, contract4Address string
|
||||
contract1CreatedAt, contract2CreatedAt, contract3CreatedAt, contract4CreatedAt uint64
|
||||
lastFilledAt, watchedAt1, watchedAt2, watchedAt3 uint64
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -44,6 +44,8 @@ func init() {
|
||||
mockBlock = mocks.MockBlock
|
||||
txs, rcts := mocks.MockBlock.Transactions(), mocks.MockReceipts
|
||||
|
||||
mockNonCanonicalBlock = mocks.MockNonCanonicalBlock
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
txs.EncodeIndex(0, buf)
|
||||
tx1 = make([]byte, buf.Len())
|
||||
@ -96,6 +98,7 @@ func init() {
|
||||
buf.Reset()
|
||||
|
||||
headerCID, _ = ipld.RawdataToCid(ipld.MEthHeader, mocks.MockHeaderRlp, multihash.KECCAK_256)
|
||||
mockNonCanonicalHeaderCID, _ = ipld.RawdataToCid(ipld.MEthHeader, mocks.MockNonCanonicalHeaderRlp, multihash.KECCAK_256)
|
||||
trx1CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx1, multihash.KECCAK_256)
|
||||
trx2CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx2, multihash.KECCAK_256)
|
||||
trx3CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx3, multihash.KECCAK_256)
|
||||
|
@ -19,6 +19,7 @@ package sql_test
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
@ -71,6 +72,44 @@ func setupPGX(t *testing.T) {
|
||||
require.Equal(t, mocks.BlockNumber.String(), tx.(*sql.BatchTx).BlockNumber)
|
||||
}
|
||||
|
||||
func setupPGXNonCanonical(t *testing.T) {
|
||||
setupPGXIndexer(t)
|
||||
var tx1 interfaces.Batch
|
||||
|
||||
tx1, err = ind.PushBlock(
|
||||
mockBlock,
|
||||
mocks.MockReceipts,
|
||||
mocks.MockBlock.Difficulty())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, node := range mocks.StateDiffs {
|
||||
err = ind.PushStateNode(tx1, node, mockBlock.Hash().String())
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
require.Equal(t, mocks.BlockNumber.String(), tx1.(*sql.BatchTx).BlockNumber)
|
||||
if err := tx1.Submit(err); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var tx2 interfaces.Batch
|
||||
tx2, err = ind.PushBlock(
|
||||
mocks.MockNonCanonicalBlock,
|
||||
mocks.MockNonCanonicalBlockReceipts,
|
||||
mocks.MockNonCanonicalBlock.Difficulty())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
require.Equal(t, mocks.BlockNumber.String(), tx2.(*sql.BatchTx).BlockNumber)
|
||||
if err := tx2.Submit(err); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// TODO index state & storage nodes for second block
|
||||
}
|
||||
|
||||
func TestPGXIndexer(t *testing.T) {
|
||||
t.Run("Publish and index header IPLDs in a single tx", func(t *testing.T) {
|
||||
setupPGX(t)
|
||||
@ -258,7 +297,7 @@ func TestPGXIndexer(t *testing.T) {
|
||||
AND header_cids.block_number = $1
|
||||
ORDER BY transaction_cids.index`
|
||||
logsPgStr := `SELECT log_cids.index, log_cids.address, log_cids.topic0, log_cids.topic1, data FROM eth.log_cids
|
||||
INNER JOIN eth.receipt_cids ON (log_cids.rct_id = receipt_cids.tx_id)
|
||||
INNER JOIN eth.receipt_cids ON (log_cids.rct_id = receipt_cids.tx_id)
|
||||
INNER JOIN public.blocks ON (log_cids.leaf_mh_key = blocks.key)
|
||||
WHERE receipt_cids.leaf_cid = $1 ORDER BY eth.log_cids.index ASC`
|
||||
err = db.Select(context.Background(), &rcts, rctsPgStr, mocks.BlockNumber.Uint64())
|
||||
@ -605,6 +644,215 @@ func TestPGXIndexer(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func XTestPGXIndexerNonCanonical(t *testing.T) {
|
||||
t.Run("Publish and index header", func(t *testing.T) {
|
||||
setupPGXNonCanonical(t)
|
||||
defer tearDown(t)
|
||||
defer checkTxClosure(t, 1, 0, 1)
|
||||
|
||||
// check indexed headers
|
||||
pgStr := `SELECT block_hash, cid, cast(td AS TEXT), cast(reward AS TEXT),
|
||||
tx_root, receipt_root, uncle_root, coinbase
|
||||
FROM eth.header_cids
|
||||
WHERE block_number = $1`
|
||||
headerRes := make([]models.HeaderModel, 0)
|
||||
err = db.Select(context.Background(), &headerRes, pgStr, mocks.BlockNumber.Uint64())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expectedRes := []models.HeaderModel{
|
||||
{
|
||||
BlockHash: mockBlock.Hash().String(),
|
||||
CID: headerCID.String(),
|
||||
TotalDifficulty: mockBlock.Difficulty().String(),
|
||||
TxRoot: mockBlock.TxHash().String(),
|
||||
RctRoot: mockBlock.ReceiptHash().String(),
|
||||
UncleRoot: mockBlock.UncleHash().String(),
|
||||
Coinbase: mocks.MockHeader.Coinbase.String(),
|
||||
},
|
||||
{
|
||||
BlockHash: mockNonCanonicalBlock.Hash().String(),
|
||||
CID: mockNonCanonicalHeaderCID.String(),
|
||||
TotalDifficulty: mockNonCanonicalBlock.Difficulty().String(),
|
||||
TxRoot: mockNonCanonicalBlock.TxHash().String(),
|
||||
RctRoot: mockNonCanonicalBlock.ReceiptHash().String(),
|
||||
UncleRoot: mockNonCanonicalBlock.UncleHash().String(),
|
||||
Coinbase: mocks.MockNonCanonicalHeader.Coinbase.String(),
|
||||
},
|
||||
}
|
||||
expectedRes[0].Reward = shared.CalcEthBlockReward(mockBlock.Header(), mockBlock.Uncles(), mockBlock.Transactions(), mocks.MockReceipts).String()
|
||||
expectedRes[1].Reward = shared.CalcEthBlockReward(mockNonCanonicalBlock.Header(), mockNonCanonicalBlock.Uncles(), mockNonCanonicalBlock.Transactions(), mocks.MockNonCanonicalBlockReceipts).String()
|
||||
|
||||
require.Equal(t, len(expectedRes), len(headerRes))
|
||||
require.ElementsMatch(t,
|
||||
[]string{mockBlock.Hash().String(), mocks.MockNonCanonicalBlock.Hash().String()},
|
||||
[]string{headerRes[0].BlockHash, headerRes[1].BlockHash},
|
||||
)
|
||||
|
||||
if headerRes[0].BlockHash == mockBlock.Hash().String() {
|
||||
require.Equal(t, expectedRes[0], headerRes[0])
|
||||
require.Equal(t, expectedRes[1], headerRes[1])
|
||||
} else {
|
||||
require.Equal(t, expectedRes[1], headerRes[0])
|
||||
require.Equal(t, expectedRes[0], headerRes[1])
|
||||
}
|
||||
|
||||
// check indexed IPLD blocks
|
||||
var data []byte
|
||||
var prefixedKey string
|
||||
|
||||
prefixedKey = shared.MultihashKeyFromCID(headerCID)
|
||||
err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Equal(t, mocks.MockHeaderRlp, data)
|
||||
|
||||
prefixedKey = shared.MultihashKeyFromCID(mockNonCanonicalHeaderCID)
|
||||
err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Equal(t, mocks.MockNonCanonicalHeaderRlp, data)
|
||||
})
|
||||
|
||||
t.Run("Publish and index transactions", func(t *testing.T) {
|
||||
setupPGXNonCanonical(t)
|
||||
defer tearDown(t)
|
||||
defer checkTxClosure(t, 1, 0, 1)
|
||||
|
||||
// check indexed transactions
|
||||
pgStr := `SELECT header_id, tx_hash, cid, dst, src, index,
|
||||
tx_data, tx_type, CAST(value as TEXT)
|
||||
FROM eth.transaction_cids
|
||||
WHERE block_number = $1`
|
||||
txRes := make([]models.TxModel, 0)
|
||||
err = db.Select(context.Background(), &txRes, pgStr, mocks.BlockNumber.Uint64())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mockBlockTxs := mocks.MockBlock.Transactions()
|
||||
expectedBlockTxs := []models.TxModel{
|
||||
{
|
||||
HeaderID: mockBlock.Hash().String(),
|
||||
TxHash: mockBlockTxs[0].Hash().String(),
|
||||
CID: trx1CID.String(),
|
||||
Dst: shared.HandleZeroAddrPointer(mockBlockTxs[0].To()),
|
||||
Src: mocks.SenderAddr.String(),
|
||||
Index: 0,
|
||||
Data: mockBlockTxs[0].Data(),
|
||||
Type: mockBlockTxs[0].Type(),
|
||||
Value: mockBlockTxs[0].Value().String(),
|
||||
},
|
||||
{
|
||||
HeaderID: mockBlock.Hash().String(),
|
||||
TxHash: mockBlockTxs[1].Hash().String(),
|
||||
CID: trx2CID.String(),
|
||||
Dst: shared.HandleZeroAddrPointer(mockBlockTxs[1].To()),
|
||||
Src: mocks.SenderAddr.String(),
|
||||
Index: 1,
|
||||
Data: mockBlockTxs[1].Data(),
|
||||
Type: mockBlockTxs[1].Type(),
|
||||
Value: mockBlockTxs[1].Value().String(),
|
||||
},
|
||||
{
|
||||
HeaderID: mockBlock.Hash().String(),
|
||||
TxHash: mockBlockTxs[2].Hash().String(),
|
||||
CID: trx3CID.String(),
|
||||
Dst: shared.HandleZeroAddrPointer(mockBlockTxs[2].To()),
|
||||
Src: mocks.SenderAddr.String(),
|
||||
Index: 2,
|
||||
Data: mockBlockTxs[2].Data(),
|
||||
Type: mockBlockTxs[2].Type(),
|
||||
Value: mockBlockTxs[2].Value().String(),
|
||||
},
|
||||
{
|
||||
HeaderID: mockBlock.Hash().String(),
|
||||
TxHash: mockBlockTxs[3].Hash().String(),
|
||||
CID: trx4CID.String(),
|
||||
Dst: shared.HandleZeroAddrPointer(mockBlockTxs[3].To()),
|
||||
Src: mocks.SenderAddr.String(),
|
||||
Index: 3,
|
||||
Data: mockBlockTxs[3].Data(),
|
||||
Type: mockBlockTxs[3].Type(),
|
||||
Value: mockBlockTxs[3].Value().String(),
|
||||
},
|
||||
{
|
||||
HeaderID: mockBlock.Hash().String(),
|
||||
TxHash: mockBlockTxs[4].Hash().String(),
|
||||
CID: trx5CID.String(),
|
||||
Dst: shared.HandleZeroAddrPointer(mockBlockTxs[4].To()),
|
||||
Src: mocks.SenderAddr.String(),
|
||||
Index: 4,
|
||||
Data: mockBlockTxs[4].Data(),
|
||||
Type: mockBlockTxs[4].Type(),
|
||||
Value: mockBlockTxs[4].Value().String(),
|
||||
},
|
||||
}
|
||||
|
||||
mockNonCanonicalBlockTxs := mocks.MockNonCanonicalBlock.Transactions()
|
||||
expectedNonCanonicalBlockTxs := []models.TxModel{
|
||||
{
|
||||
HeaderID: mockNonCanonicalBlock.Hash().String(),
|
||||
TxHash: mockNonCanonicalBlockTxs[0].Hash().String(),
|
||||
CID: trx2CID.String(),
|
||||
Dst: mockNonCanonicalBlockTxs[0].To().String(),
|
||||
Src: mocks.SenderAddr.String(),
|
||||
Index: 0,
|
||||
Data: mockNonCanonicalBlockTxs[0].Data(),
|
||||
Type: mockNonCanonicalBlockTxs[0].Type(),
|
||||
Value: mockNonCanonicalBlockTxs[0].Value().String(),
|
||||
},
|
||||
{
|
||||
HeaderID: mockNonCanonicalBlock.Hash().String(),
|
||||
TxHash: mockNonCanonicalBlockTxs[1].Hash().String(),
|
||||
CID: trx5CID.String(),
|
||||
Dst: mockNonCanonicalBlockTxs[1].To().String(),
|
||||
Src: mocks.SenderAddr.String(),
|
||||
Index: 1,
|
||||
Data: mockNonCanonicalBlockTxs[1].Data(),
|
||||
Type: mockNonCanonicalBlockTxs[1].Type(),
|
||||
Value: mockNonCanonicalBlockTxs[1].Value().String(),
|
||||
},
|
||||
}
|
||||
|
||||
require.Equal(t, len(expectedBlockTxs)+len(expectedNonCanonicalBlockTxs), len(txRes))
|
||||
sort.Slice(txRes, func(i, j int) bool {
|
||||
if txRes[i].HeaderID == txRes[j].HeaderID {
|
||||
return txRes[i].Index < txRes[j].Index
|
||||
} else if txRes[i].HeaderID == mockBlock.Hash().String() {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
for i, expectedTx := range expectedBlockTxs {
|
||||
require.Equal(t, expectedTx, txRes[i])
|
||||
}
|
||||
for i, expectedTx := range expectedNonCanonicalBlockTxs {
|
||||
require.Equal(t, expectedTx, txRes[len(expectedBlockTxs)+i])
|
||||
}
|
||||
|
||||
// check indexed IPLD blocks
|
||||
var data []byte
|
||||
var prefixedKey string
|
||||
|
||||
txCIDs := []cid.Cid{trx1CID, trx2CID, trx3CID, trx4CID, trx5CID}
|
||||
txRLPs := [][]byte{tx1, tx2, tx3, tx4, tx5}
|
||||
for i, txCID := range txCIDs {
|
||||
prefixedKey = shared.MultihashKeyFromCID(txCID)
|
||||
err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Equal(t, txRLPs[i], data)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestPGXWatchAddressMethods(t *testing.T) {
|
||||
setupPGXIndexer(t)
|
||||
defer tearDown(t)
|
||||
|
@ -51,23 +51,30 @@ var (
|
||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||
Coinbase: common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476777"),
|
||||
}
|
||||
MockTransactions, MockReceipts, SenderAddr = createTransactionsAndReceipts(TestConfig, BlockNumber)
|
||||
MockBlock = types.NewBlock(&MockHeader, MockTransactions, nil, MockReceipts, new(trie.Trie))
|
||||
MockHeaderRlp, _ = rlp.EncodeToBytes(MockBlock.Header())
|
||||
Address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592")
|
||||
AnotherAddress = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476593")
|
||||
ContractAddress = crypto.CreateAddress(SenderAddr, MockTransactions[2].Nonce())
|
||||
ContractAddress2 = crypto.CreateAddress(SenderAddr, MockTransactions[3].Nonce())
|
||||
MockContractByteCode = []byte{0, 1, 2, 3, 4, 5}
|
||||
mockTopic11 = common.HexToHash("0x04")
|
||||
mockTopic12 = common.HexToHash("0x06")
|
||||
mockTopic21 = common.HexToHash("0x05")
|
||||
mockTopic22 = common.HexToHash("0x07")
|
||||
ExpectedPostStatus uint64 = 1
|
||||
ExpectedPostState1 = common.Bytes2Hex(common.HexToHash("0x1").Bytes())
|
||||
ExpectedPostState2 = common.Bytes2Hex(common.HexToHash("0x2").Bytes())
|
||||
ExpectedPostState3 = common.Bytes2Hex(common.HexToHash("0x3").Bytes())
|
||||
MockLog1 = &types.Log{
|
||||
MockTransactions, MockReceipts, SenderAddr = createTransactionsAndReceipts(TestConfig, BlockNumber)
|
||||
MockBlock = types.NewBlock(&MockHeader, MockTransactions, nil, MockReceipts, new(trie.Trie))
|
||||
MockHeaderRlp, _ = rlp.EncodeToBytes(MockBlock.Header())
|
||||
|
||||
MockNonCanonicalHeader = MockHeader
|
||||
MockNonCanonicalBlockTransactions = types.Transactions{MockTransactions[1], MockTransactions[4]}
|
||||
MockNonCanonicalBlockReceipts = createNonCanonicalBlockReceipts(TestConfig, BlockNumber, MockNonCanonicalBlockTransactions)
|
||||
MockNonCanonicalBlock = types.NewBlock(&MockNonCanonicalHeader, MockNonCanonicalBlockTransactions, nil, MockNonCanonicalBlockReceipts, new(trie.Trie))
|
||||
MockNonCanonicalHeaderRlp, _ = rlp.EncodeToBytes(MockNonCanonicalBlock.Header())
|
||||
|
||||
Address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592")
|
||||
AnotherAddress = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476593")
|
||||
ContractAddress = crypto.CreateAddress(SenderAddr, MockTransactions[2].Nonce())
|
||||
ContractAddress2 = crypto.CreateAddress(SenderAddr, MockTransactions[3].Nonce())
|
||||
MockContractByteCode = []byte{0, 1, 2, 3, 4, 5}
|
||||
mockTopic11 = common.HexToHash("0x04")
|
||||
mockTopic12 = common.HexToHash("0x06")
|
||||
mockTopic21 = common.HexToHash("0x05")
|
||||
mockTopic22 = common.HexToHash("0x07")
|
||||
ExpectedPostStatus uint64 = 1
|
||||
ExpectedPostState1 = common.Bytes2Hex(common.HexToHash("0x1").Bytes())
|
||||
ExpectedPostState2 = common.Bytes2Hex(common.HexToHash("0x2").Bytes())
|
||||
ExpectedPostState3 = common.Bytes2Hex(common.HexToHash("0x3").Bytes())
|
||||
MockLog1 = &types.Log{
|
||||
Address: Address,
|
||||
Topics: []common.Hash{mockTopic11, mockTopic12},
|
||||
Data: []byte{},
|
||||
@ -440,3 +447,37 @@ func createTransactionsAndReceipts(config *params.ChainConfig, blockNumber *big.
|
||||
|
||||
return types.Transactions{signedTrx1, signedTrx2, signedTrx3, signedTrx4, signedTrx5}, types.Receipts{mockReceipt1, mockReceipt2, mockReceipt3, mockReceipt4, mockReceipt5}, senderAddr
|
||||
}
|
||||
|
||||
func createNonCanonicalBlockReceipts(config *params.ChainConfig, blockNumber *big.Int, transactions types.Transactions) types.Receipts {
|
||||
transactionSigner := types.MakeSigner(config, blockNumber)
|
||||
mockCurve := elliptic.P256()
|
||||
mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader)
|
||||
if err != nil {
|
||||
log.Crit(err.Error())
|
||||
}
|
||||
|
||||
signedTrx0, err := types.SignTx(transactions[0], transactionSigner, mockPrvKey)
|
||||
if err != nil {
|
||||
log.Crit(err.Error())
|
||||
}
|
||||
|
||||
signedTrx1, err := types.SignTx(transactions[1], transactionSigner, mockPrvKey)
|
||||
if err != nil {
|
||||
log.Crit(err.Error())
|
||||
}
|
||||
|
||||
mockReceipt0 := types.NewReceipt(common.HexToHash("0x1").Bytes(), false, 100)
|
||||
mockReceipt0.Logs = []*types.Log{MockLog2, ShortLog1}
|
||||
mockReceipt0.TxHash = signedTrx0.Hash()
|
||||
|
||||
mockReceipt1 := &types.Receipt{
|
||||
Type: types.DynamicFeeTxType,
|
||||
PostState: common.HexToHash("0x3").Bytes(),
|
||||
Status: types.ReceiptStatusSuccessful,
|
||||
CumulativeGasUsed: 175,
|
||||
Logs: []*types.Log{},
|
||||
TxHash: signedTrx1.Hash(),
|
||||
}
|
||||
|
||||
return types.Receipts{mockReceipt0, mockReceipt1}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user