V1.10.8 statediff #121

Merged
telackey merged 6 commits from v1.10.8-statediff into statediff 2021-09-21 14:36:19 +00:00
13 changed files with 206 additions and 104 deletions

View File

@ -24,7 +24,7 @@ const (
VersionMajor = 1 // Major version component of the current release
VersionMinor = 10 // Minor version component of the current release
VersionPatch = 8 // Patch version component of the current release
VersionMeta = "statediff-0.0.26" // Version metadata to append to the version string
VersionMeta = "statediff-0.0.27" // Version metadata to append to the version string
)
// Version holds the textual version string.

View File

@ -2,8 +2,8 @@
CREATE TABLE eth.receipt_cids (
id SERIAL PRIMARY KEY,
tx_id INTEGER NOT NULL REFERENCES eth.transaction_cids (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
cid TEXT NOT NULL,
mh_key TEXT NOT NULL REFERENCES public.blocks (key) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
leaf_cid TEXT NOT NULL,
leaf_mh_key TEXT NOT NULL REFERENCES public.blocks (key) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
contract VARCHAR(66),
contract_hash VARCHAR(66),
post_state VARCHAR(66),

View File

@ -28,9 +28,9 @@ CREATE INDEX tx_src_index ON eth.transaction_cids USING btree (src);
-- receipt indexes
CREATE INDEX rct_tx_id_index ON eth.receipt_cids USING btree (tx_id);
CREATE INDEX rct_cid_index ON eth.receipt_cids USING btree (cid);
CREATE INDEX rct_leaf_cid_index ON eth.receipt_cids USING btree (leaf_cid);
CREATE INDEX rct_mh_index ON eth.receipt_cids USING btree (mh_key);
CREATE INDEX rct_leaf_mh_index ON eth.receipt_cids USING btree (leaf_mh_key);
CREATE INDEX rct_contract_index ON eth.receipt_cids USING btree (contract);
@ -91,8 +91,8 @@ DROP INDEX eth.state_header_id_index;
-- receipt indexes
DROP INDEX eth.rct_contract_hash_index;
DROP INDEX eth.rct_contract_index;
DROP INDEX eth.rct_mh_index;
DROP INDEX eth.rct_cid_index;
DROP INDEX eth.rct_leaf_mh_index;
DROP INDEX eth.rct_leaf_cid_index;
DROP INDEX eth.rct_tx_id_index;
-- transaction indexes

View File

@ -363,8 +363,8 @@ ALTER SEQUENCE eth.log_cids_id_seq OWNED BY eth.log_cids.id;
CREATE TABLE eth.receipt_cids (
id integer NOT NULL,
tx_id integer NOT NULL,
cid text NOT NULL,
mh_key text NOT NULL,
leaf_cid text NOT NULL,
leaf_mh_key text NOT NULL,
contract character varying(66),
contract_hash character varying(66),
post_state character varying(66),
@ -1012,10 +1012,10 @@ CREATE INDEX log_topic3_index ON eth.log_cids USING btree (topic3);
--
-- Name: rct_cid_index; Type: INDEX; Schema: eth; Owner: -
-- Name: rct_leaf_cid_index; Type: INDEX; Schema: eth; Owner: -
--
CREATE INDEX rct_cid_index ON eth.receipt_cids USING btree (cid);
CREATE INDEX rct_leaf_cid_index ON eth.receipt_cids USING btree (leaf_cid);
--
@ -1033,10 +1033,10 @@ CREATE INDEX rct_contract_index ON eth.receipt_cids USING btree (contract);
--
-- Name: rct_mh_index; Type: INDEX; Schema: eth; Owner: -
-- Name: rct_leaf_mh_index; Type: INDEX; Schema: eth; Owner: -
--
CREATE INDEX rct_mh_index ON eth.receipt_cids USING btree (mh_key);
CREATE INDEX rct_leaf_mh_index ON eth.receipt_cids USING btree (leaf_mh_key);
--
@ -1287,7 +1287,7 @@ ALTER TABLE ONLY eth.log_cids
--
ALTER TABLE ONLY eth.receipt_cids
ADD CONSTRAINT receipt_cids_mh_key_fkey FOREIGN KEY (mh_key) REFERENCES public.blocks(key) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
ADD CONSTRAINT receipt_cids_leaf_mh_key_fkey FOREIGN KEY (leaf_mh_key) REFERENCES public.blocks(key) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
--

View File

@ -110,13 +110,13 @@ func (sdi *StateDiffIndexer) PushBlock(block *types.Block, receipts types.Receip
}
// Generate the block iplds
headerNode, uncleNodes, txNodes, txTrieNodes, rctNodes, rctTrieNodes, logTrieNodes, logLeafNodeCIDs, err := ipld.FromBlockAndReceipts(block, receipts)
headerNode, uncleNodes, txNodes, txTrieNodes, rctNodes, rctTrieNodes, logTrieNodes, logLeafNodeCIDs, rctLeafNodeCIDs, err := ipld.FromBlockAndReceipts(block, receipts)
if err != nil {
return nil, fmt.Errorf("error creating IPLD nodes from block and receipts: %v", err)
}
if len(txNodes) != len(txTrieNodes) && len(rctNodes) != len(rctTrieNodes) && len(txNodes) != len(rctNodes) {
return nil, fmt.Errorf("expected number of transactions (%d), transaction trie nodes (%d), receipts (%d), and receipt trie nodes (%d)to be equal", len(txNodes), len(txTrieNodes), len(rctNodes), len(rctTrieNodes))
if len(txNodes) != len(rctNodes) || len(rctNodes) != len(rctLeafNodeCIDs) {
return nil, fmt.Errorf("expected number of transactions (%d), receipts (%d), and receipt trie leaf nodes (%d)to be equal", len(txNodes), len(rctNodes), len(rctLeafNodeCIDs))
}
// Calculate reward
@ -202,6 +202,7 @@ func (sdi *StateDiffIndexer) PushBlock(block *types.Block, receipts types.Receip
txTrieNodes: txTrieNodes,
logTrieNodes: logTrieNodes,
logLeafNodeCIDs: logLeafNodeCIDs,
rctLeafNodeCIDs: rctLeafNodeCIDs,
})
if err != nil {
return nil, err
@ -288,6 +289,7 @@ type processArgs struct {
txTrieNodes []*ipld.EthTxTrie
logTrieNodes [][]*ipld.EthLogTrie
logLeafNodeCIDs [][]cid.Cid
rctLeafNodeCIDs []cid.Cid
}
// processReceiptsAndTxs publishes and indexes receipt and transaction IPLDs in Postgres
@ -309,13 +311,10 @@ func (sdi *StateDiffIndexer) processReceiptsAndTxs(tx *sqlx.Tx, args processArgs
}
// publish the txs and receipts
txNode, rctNode := args.txNodes[i], args.rctNodes[i]
txNode := args.txNodes[i]
if err := shared.PublishIPLD(tx, txNode); err != nil {
return fmt.Errorf("error publishing tx IPLD: %v", err)
}
if err := shared.PublishIPLD(tx, rctNode); err != nil {
return fmt.Errorf("error publishing rct IPLD: %v", err)
}
// Indexing
// extract topic and contract data from the receipt for indexing
@ -390,13 +389,18 @@ func (sdi *StateDiffIndexer) processReceiptsAndTxs(tx *sqlx.Tx, args processArgs
return err
}
}
// index the receipt
if !args.rctLeafNodeCIDs[i].Defined() {
return fmt.Errorf("invalid receipt leaf node cid")
}
rctModel := &models.ReceiptModel{
Contract: contract,
ContractHash: contractHash,
CID: rctNode.Cid().String(),
MhKey: shared.MultihashKeyFromCID(rctNode.Cid()),
LogRoot: rctNode.LogRoot.String(),
LeafCID: args.rctLeafNodeCIDs[i].String(),
LeafMhKey: shared.MultihashKeyFromCID(args.rctLeafNodeCIDs[i]),
LogRoot: args.rctNodes[i].LogRoot.String(),
}
if len(receipt.PostState) == 0 {
rctModel.PostStatus = receipt.Status

View File

@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/statediff/indexer"
"github.com/ethereum/go-ethereum/statediff/indexer/ipfs"
"github.com/ethereum/go-ethereum/statediff/indexer/ipfs/ipld"
"github.com/ethereum/go-ethereum/statediff/indexer/mocks"
"github.com/ethereum/go-ethereum/statediff/indexer/models"
@ -310,9 +311,21 @@ func TestPublishAndIndexer(t *testing.T) {
}
})
t.Run("Publish and index log IPLDs for single receipt", func(t *testing.T) {
t.Run("Publish and index log IPLDs for multiple receipt of a specific block", func(t *testing.T) {
setup(t)
defer tearDown(t)
rcts := make([]string, 0)
pgStr := `SELECT receipt_cids.leaf_cid FROM eth.receipt_cids, eth.transaction_cids, eth.header_cids
WHERE receipt_cids.tx_id = transaction_cids.id
AND transaction_cids.header_id = header_cids.id
AND header_cids.block_number = $1
ORDER BY transaction_cids.index`
err = db.Select(&rcts, pgStr, mocks.BlockNumber.Uint64())
if err != nil {
t.Fatal(err)
}
type logIPLD struct {
Index int `db:"index"`
Address string `db:"address"`
@ -320,52 +333,72 @@ func TestPublishAndIndexer(t *testing.T) {
Topic0 string `db:"topic0"`
Topic1 string `db:"topic1"`
}
results := make([]logIPLD, 0)
pgStr := `SELECT log_cids.index, log_cids.address, log_cids.Topic0, log_cids.Topic1, data FROM eth.log_cids
for i := range rcts {
results := make([]logIPLD, 0)
pgStr = `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.receipt_id = receipt_cids.id)
INNER JOIN public.blocks ON (log_cids.leaf_mh_key = blocks.key)
WHERE receipt_cids.cid = $1 ORDER BY eth.log_cids.index ASC`
err = db.Select(&results, pgStr, rct4CID.String())
require.NoError(t, err)
// expecting MockLog1 and MockLog2 for mockReceipt4
expectedLogs := mocks.MockReceipts[3].Logs
shared.ExpectEqual(t, len(results), len(expectedLogs))
var nodeElements []interface{}
for idx, r := range results {
// Decode the log leaf node.
err = rlp.DecodeBytes(r.Data, &nodeElements)
WHERE receipt_cids.leaf_cid = $1 ORDER BY eth.log_cids.index ASC`
err = db.Select(&results, pgStr, rcts[i])
require.NoError(t, err)
logRaw, err := rlp.EncodeToBytes(expectedLogs[idx])
require.NoError(t, err)
// expecting MockLog1 and MockLog2 for mockReceipt4
expectedLogs := mocks.MockReceipts[i].Logs
shared.ExpectEqual(t, len(results), len(expectedLogs))
// 2nd element of the leaf node contains the encoded log data.
shared.ExpectEqual(t, logRaw, nodeElements[1].([]byte))
var nodeElements []interface{}
for idx, r := range results {
// Decode the log leaf node.
err = rlp.DecodeBytes(r.Data, &nodeElements)
require.NoError(t, err)
logRaw, err := rlp.EncodeToBytes(expectedLogs[idx])
require.NoError(t, err)
// 2nd element of the leaf node contains the encoded log data.
shared.ExpectEqual(t, logRaw, nodeElements[1].([]byte))
}
}
})
t.Run("Publish and index receipt IPLDs in a single tx", func(t *testing.T) {
setup(t)
defer tearDown(t)
// check receipts were properly indexed
rcts := make([]string, 0)
pgStr := `SELECT receipt_cids.cid FROM eth.receipt_cids, eth.transaction_cids, eth.header_cids
pgStr := `SELECT receipt_cids.leaf_cid FROM eth.receipt_cids, eth.transaction_cids, eth.header_cids
WHERE receipt_cids.tx_id = transaction_cids.id
AND transaction_cids.header_id = header_cids.id
AND header_cids.block_number = $1`
AND header_cids.block_number = $1 order by transaction_cids.id`
err = db.Select(&rcts, pgStr, mocks.BlockNumber.Uint64())
if err != nil {
t.Fatal(err)
}
shared.ExpectEqual(t, len(rcts), 5)
expectTrue(t, shared.ListContainsString(rcts, rct1CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct2CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct3CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct4CID.String()))
expectTrue(t, shared.ListContainsString(rcts, rct5CID.String()))
for idx, rctLeafCID := range rcts {
result := make([]ipfs.BlockModel, 0)
pgStr = `SELECT data
FROM eth.receipt_cids
INNER JOIN public.blocks ON (receipt_cids.leaf_mh_key = public.blocks.key)
WHERE receipt_cids.leaf_cid = $1`
err = db.Select(&result, pgStr, rctLeafCID)
if err != nil {
t.Fatal(err)
}
// Decode the log leaf node.
var nodeElements []interface{}
err = rlp.DecodeBytes(result[0].Data, &nodeElements)
require.NoError(t, err)
expectedRct, err := mocks.MockReceipts[idx].MarshalBinary()
require.NoError(t, err)
shared.ExpectEqual(t, expectedRct, nodeElements[1].([]byte))
}
// and published
for _, c := range rcts {
dc, err := cid.Decode(c)
@ -379,11 +412,12 @@ func TestPublishAndIndexer(t *testing.T) {
if err != nil {
t.Fatal(err)
}
switch c {
case rct1CID.String():
shared.ExpectEqual(t, data, rct1)
var postStatus uint64
pgStr = `SELECT post_status FROM eth.receipt_cids WHERE cid = $1`
pgStr = `SELECT post_status FROM eth.receipt_cids WHERE leaf_cid = $1`
err = db.Get(&postStatus, pgStr, c)
if err != nil {
t.Fatal(err)
@ -392,7 +426,7 @@ func TestPublishAndIndexer(t *testing.T) {
case rct2CID.String():
shared.ExpectEqual(t, data, rct2)
var postState string
pgStr = `SELECT post_state FROM eth.receipt_cids WHERE cid = $1`
pgStr = `SELECT post_state FROM eth.receipt_cids WHERE leaf_cid = $1`
err = db.Get(&postState, pgStr, c)
if err != nil {
t.Fatal(err)
@ -401,7 +435,7 @@ func TestPublishAndIndexer(t *testing.T) {
case rct3CID.String():
shared.ExpectEqual(t, data, rct3)
var postState string
pgStr = `SELECT post_state FROM eth.receipt_cids WHERE cid = $1`
pgStr = `SELECT post_state FROM eth.receipt_cids WHERE leaf_cid = $1`
err = db.Get(&postState, pgStr, c)
if err != nil {
t.Fatal(err)
@ -410,7 +444,7 @@ func TestPublishAndIndexer(t *testing.T) {
case rct4CID.String():
shared.ExpectEqual(t, data, rct4)
var postState string
pgStr = `SELECT post_state FROM eth.receipt_cids WHERE cid = $1`
pgStr = `SELECT post_state FROM eth.receipt_cids WHERE leaf_cid = $1`
err = db.Get(&postState, pgStr, c)
if err != nil {
t.Fatal(err)
@ -419,7 +453,7 @@ func TestPublishAndIndexer(t *testing.T) {
case rct5CID.String():
shared.ExpectEqual(t, data, rct5)
var postState string
pgStr = `SELECT post_state FROM eth.receipt_cids WHERE cid = $1`
pgStr = `SELECT post_state FROM eth.receipt_cids WHERE leaf_cid = $1`
err = db.Get(&postState, pgStr, c)
if err != nil {
t.Fatal(err)

View File

@ -123,11 +123,11 @@ func FromBlockJSON(r io.Reader) (*EthHeader, []*EthTx, []*EthTxTrie, error) {
// FromBlockAndReceipts takes a block and processes it
// to return it a set of IPLD nodes for further processing.
func FromBlockAndReceipts(block *types.Block, receipts []*types.Receipt) (*EthHeader, []*EthHeader, []*EthTx, []*EthTxTrie, []*EthReceipt, []*EthRctTrie, [][]*EthLogTrie, [][]cid.Cid, error) {
func FromBlockAndReceipts(block *types.Block, receipts []*types.Receipt) (*EthHeader, []*EthHeader, []*EthTx, []*EthTxTrie, []*EthReceipt, []*EthRctTrie, [][]*EthLogTrie, [][]cid.Cid, []cid.Cid, error) {
// Process the header
headerNode, err := NewEthHeader(block.Header())
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, err
return nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
// Process the uncles
@ -135,7 +135,7 @@ func FromBlockAndReceipts(block *types.Block, receipts []*types.Receipt) (*EthHe
for i, uncle := range block.Uncles() {
uncleNode, err := NewEthHeader(uncle)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, err
return nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
uncleNodes[i] = uncleNode
}
@ -144,14 +144,14 @@ func FromBlockAndReceipts(block *types.Block, receipts []*types.Receipt) (*EthHe
txNodes, txTrieNodes, err := processTransactions(block.Transactions(),
block.Header().TxHash[:])
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, err
return nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
// Process the receipts and logs
rctNodes, tctTrieNodes, logTrieNodes, logLeafNodeCIDs, err := processReceiptsAndLogs(receipts,
rctNodes, tctTrieNodes, logTrieNodes, logLeafNodeCIDs, rctLeafNodeCIDs, err := processReceiptsAndLogs(receipts,
block.Header().ReceiptHash[:])
return headerNode, uncleNodes, txNodes, txTrieNodes, rctNodes, tctTrieNodes, logTrieNodes, logLeafNodeCIDs, err
return headerNode, uncleNodes, txNodes, txTrieNodes, rctNodes, tctTrieNodes, logTrieNodes, logLeafNodeCIDs, rctLeafNodeCIDs, err
}
// processTransactions will take the found transactions in a parsed block body
@ -166,7 +166,7 @@ func processTransactions(txs []*types.Transaction, expectedTxRoot []byte) ([]*Et
return nil, nil, err
}
ethTxNodes = append(ethTxNodes, ethTx)
if err := transactionTrie.add(idx, ethTx.RawData()); err != nil {
if err := transactionTrie.Add(idx, ethTx.RawData()); err != nil {
return nil, nil, err
}
}
@ -179,20 +179,20 @@ func processTransactions(txs []*types.Transaction, expectedTxRoot []byte) ([]*Et
}
// processReceiptsAndLogs will take in receipts
// to return IPLD node slices for eth-rct, eth-rct-trie, eth-log, eth-log-trie
func processReceiptsAndLogs(rcts []*types.Receipt, expectedRctRoot []byte) ([]*EthReceipt, []*EthRctTrie, [][]*EthLogTrie, [][]cid.Cid, error) {
// to return IPLD node slices for eth-rct, eth-rct-trie, eth-log, eth-log-trie, eth-log-trie-CID, eth-rct-trie-CID
func processReceiptsAndLogs(rcts []*types.Receipt, expectedRctRoot []byte) ([]*EthReceipt, []*EthRctTrie, [][]*EthLogTrie, [][]cid.Cid, []cid.Cid, error) {
// Pre allocating memory.
ethRctNodes := make([]*EthReceipt, 0, len(rcts))
ethLogleafNodeCids := make([][]cid.Cid, 0, len(rcts))
ethLogTrieNodes := make([][]*EthLogTrie, 0, len(rcts))
receiptTrie := newRctTrie()
receiptTrie := NewRctTrie()
for idx, rct := range rcts {
// Process logs for each receipt.
logTrieNodes, leafNodeCids, logTrieHash, err := processLogs(rct.Logs)
if err != nil {
return nil, nil, nil, nil, err
return nil, nil, nil, nil, nil, err
}
rct.LogRoot = logTrieHash
ethLogTrieNodes = append(ethLogTrieNodes, logTrieNodes)
@ -200,20 +200,42 @@ func processReceiptsAndLogs(rcts []*types.Receipt, expectedRctRoot []byte) ([]*E
ethRct, err := NewReceipt(rct)
if err != nil {
return nil, nil, nil, nil, err
return nil, nil, nil, nil, nil, err
}
ethRctNodes = append(ethRctNodes, ethRct)
if err = receiptTrie.add(idx, ethRct.RawData()); err != nil {
return nil, nil, nil, nil, err
if err = receiptTrie.Add(idx, ethRct.RawData()); err != nil {
return nil, nil, nil, nil, nil, err
}
}
if !bytes.Equal(receiptTrie.rootHash(), expectedRctRoot) {
return nil, nil, nil, nil, fmt.Errorf("wrong receipt hash computed")
return nil, nil, nil, nil, nil, fmt.Errorf("wrong receipt hash computed")
}
rctTrieNodes, err := receiptTrie.getNodes()
return ethRctNodes, rctTrieNodes, ethLogTrieNodes, ethLogleafNodeCids, err
rctTrieNodes, err := receiptTrie.GetNodes()
if err != nil {
return nil, nil, nil, nil, nil, err
}
rctLeafNodes, keys, err := receiptTrie.GetLeafNodes()
if err != nil {
return nil, nil, nil, nil, nil, err
}
ethRctleafNodeCids := make([]cid.Cid, len(rctLeafNodes))
for i, rln := range rctLeafNodes {
var idx uint
r := bytes.NewReader(keys[i].TrieKey)
err = rlp.Decode(r, &idx)
if err != nil {
return nil, nil, nil, nil, nil, err
}
ethRctleafNodeCids[idx] = rln.Cid()
}
return ethRctNodes, rctTrieNodes, ethLogTrieNodes, ethLogleafNodeCids, ethRctleafNodeCids, err
}
func processLogs(logs []*types.Log) ([]*EthLogTrie, []cid.Cid, common.Hash, error) {
@ -223,7 +245,7 @@ func processLogs(logs []*types.Log) ([]*EthLogTrie, []cid.Cid, common.Hash, erro
if err != nil {
return nil, nil, common.Hash{}, err
}
if err = logTr.add(idx, ethLog.RawData()); err != nil {
if err = logTr.Add(idx, ethLog.RawData()); err != nil {
return nil, nil, common.Hash{}, err
}
}
@ -242,7 +264,7 @@ func processLogs(logs []*types.Log) ([]*EthLogTrie, []cid.Cid, common.Hash, erro
for i, ln := range leafNodes {
var idx uint
r := bytes.NewReader(keys[i].trieKey)
r := bytes.NewReader(keys[i].TrieKey)
err = rlp.Decode(r, &idx)
if err != nil {
return nil, nil, common.Hash{}, err

View File

@ -91,7 +91,7 @@ func loadBlockData(t *testing.T) []testCase {
func TestFromBlockAndReceipts(t *testing.T) {
testCases := loadBlockData(t)
for _, tc := range testCases {
_, _, _, _, _, _, _, _, err := FromBlockAndReceipts(tc.block, tc.receipts)
_, _, _, _, _, _, _, _, _, err := FromBlockAndReceipts(tc.block, tc.receipts)
if err != nil {
t.Fatalf("error generating IPLDs from block and receipts, err %v, kind %s, block hash %s", err, tc.kind, tc.block.Hash())
}

View File

@ -113,17 +113,17 @@ type rctTrie struct {
*localTrie
}
// newRctTrie initializes and returns a rctTrie.
func newRctTrie() *rctTrie {
// NewRctTrie initializes and returns a rctTrie.
func NewRctTrie() *rctTrie {
return &rctTrie{
localTrie: newLocalTrie(),
}
}
// getNodes invokes the localTrie, which computes the root hash of the
// GetNodes invokes the localTrie, which computes the root hash of the
// transaction trie and returns its database keys, to return a slice
// of EthRctTrie nodes.
func (rt *rctTrie) getNodes() ([]*EthRctTrie, error) {
func (rt *rctTrie) GetNodes() ([]*EthRctTrie, error) {
keys, err := rt.getKeys()
if err != nil {
return nil, err
@ -131,20 +131,51 @@ func (rt *rctTrie) getNodes() ([]*EthRctTrie, error) {
var out []*EthRctTrie
for _, k := range keys {
rawdata, err := rt.db.Get(k)
n, err := rt.getNodeFromDB(k)
if err != nil {
return nil, err
}
c, err := RawdataToCid(MEthTxReceiptTrie, rawdata, multihash.KECCAK_256)
if err != nil {
return nil, err
}
tn := &TrieNode{
cid: c,
rawdata: rawdata,
}
out = append(out, &EthRctTrie{TrieNode: tn})
out = append(out, n)
}
return out, nil
}
// GetLeafNodes invokes the localTrie, which returns a slice
// of EthRctTrie leaf nodes.
func (rt *rctTrie) GetLeafNodes() ([]*EthRctTrie, []*nodeKey, error) {
keys, err := rt.getLeafKeys()
if err != nil {
return nil, nil, err
}
out := make([]*EthRctTrie, 0, len(keys))
for _, k := range keys {
n, err := rt.getNodeFromDB(k.dbKey)
if err != nil {
return nil, nil, err
}
out = append(out, n)
}
return out, keys, nil
}
func (rt *rctTrie) getNodeFromDB(key []byte) (*EthRctTrie, error) {
rawdata, err := rt.db.Get(key)
if err != nil {
return nil, err
}
cid, err := RawdataToCid(MEthTxReceiptTrie, rawdata, multihash.KECCAK_256)
if err != nil {
return nil, err
}
tn := &TrieNode{
cid: cid,
rawdata: rawdata,
}
return &EthRctTrie{TrieNode: tn}, nil
}

View File

@ -112,9 +112,9 @@ func newLocalTrie() *localTrie {
return lt
}
// add receives the index of an object and its rawdata value
// Add receives the index of an object and its rawdata value
// and includes it into the localTrie
func (lt *localTrie) add(idx int, rawdata []byte) error {
func (lt *localTrie) Add(idx int, rawdata []byte) error {
key, err := rlp.EncodeToBytes(uint(idx))
if err != nil {
panic(err)
@ -128,19 +128,27 @@ func (lt *localTrie) rootHash() []byte {
return lt.trie.Hash().Bytes()
}
// getKeys returns the stored keys of the memory database
// of the localTrie for further processing.
func (lt *localTrie) getKeys() ([][]byte, error) {
func (lt *localTrie) commit() error {
// commit trie nodes to trieDB
var err error
_, err = lt.trie.Commit(nil)
if err != nil {
return nil, err
return err
}
// commit trieDB to the underlying ethdb.Database
if err := lt.trieDB.Commit(lt.trie.Hash(), false, nil); err != nil {
return err
}
return nil
}
// getKeys returns the stored keys of the memory database
// of the localTrie for further processing.
func (lt *localTrie) getKeys() ([][]byte, error) {
if err := lt.commit(); err != nil {
return nil, err
}
// collect all of the node keys
it := lt.trie.NodeIterator([]byte{})
keyBytes := make([][]byte, 0)
@ -155,14 +163,17 @@ func (lt *localTrie) getKeys() ([][]byte, error) {
type nodeKey struct {
dbKey []byte
trieKey []byte
TrieKey []byte
}
// getLeafKeys returns the stored leaf keys from the memory database
// of the localTrie for further processing.
func (lt *localTrie) getLeafKeys() ([]*nodeKey, error) {
it := lt.trie.NodeIterator([]byte{})
if err := lt.commit(); err != nil {
return nil, err
}
it := lt.trie.NodeIterator([]byte{})
leafKeys := make([]*nodeKey, 0)
for it.Next(true) {
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
@ -183,7 +194,7 @@ func (lt *localTrie) getLeafKeys() ([]*nodeKey, error) {
encodedPath := trie.HexToCompact(valueNodePath)
leafKey := encodedPath[1:]
leafKeys = append(leafKeys, &nodeKey{dbKey: it.Hash().Bytes(), trieKey: leafKey})
leafKeys = append(leafKeys, &nodeKey{dbKey: it.Hash().Bytes(), TrieKey: leafKey})
}
return leafKeys, nil
}

Binary file not shown.

View File

@ -77,8 +77,8 @@ type AccessListElementModel struct {
type ReceiptModel struct {
ID int64 `db:"id"`
TxID int64 `db:"tx_id"`
CID string `db:"cid"`
MhKey string `db:"mh_key"`
LeafCID string `db:"leaf_cid"`
LeafMhKey string `db:"leaf_mh_key"`
PostStatus uint64 `db:"post_status"`
PostState string `db:"post_state"`
Contract string `db:"contract"`

View File

@ -93,10 +93,10 @@ func (in *PostgresCIDWriter) upsertAccessListElement(tx *sqlx.Tx, accessListElem
func (in *PostgresCIDWriter) upsertReceiptCID(tx *sqlx.Tx, rct *models.ReceiptModel, txID int64) (int64, error) {
var receiptID int64
err := tx.QueryRowx(`INSERT INTO eth.receipt_cids (tx_id, cid, contract, contract_hash, mh_key, post_state, post_status, log_root) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
ON CONFLICT (tx_id) DO UPDATE SET (cid, contract, contract_hash, mh_key, post_state, post_status, log_root) = ($2, $3, $4, $5, $6, $7, $8)
err := tx.QueryRowx(`INSERT INTO eth.receipt_cids (tx_id, leaf_cid, contract, contract_hash, leaf_mh_key, post_state, post_status, log_root) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
ON CONFLICT (tx_id) DO UPDATE SET (leaf_cid, contract, contract_hash, leaf_mh_key, post_state, post_status, log_root) = ($2, $3, $4, $5, $6, $7, $8)
RETURNING id`,
txID, rct.CID, rct.Contract, rct.ContractHash, rct.MhKey, rct.PostState, rct.PostStatus, rct.LogRoot).Scan(&receiptID)
txID, rct.LeafCID, rct.Contract, rct.ContractHash, rct.LeafMhKey, rct.PostState, rct.PostStatus, rct.LogRoot).Scan(&receiptID)
if err != nil {
return 0, fmt.Errorf("error upserting receipt_cids entry: %w", err)
}