From c10486bba079731b6ee238e2cffc207cac8c8d30 Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Wed, 2 Nov 2022 13:15:09 +0530 Subject: [PATCH 1/8] Add optional block number filter to getLogs API --- pkg/eth/cid_retriever.go | 8 +++++++- pkg/graphql/graphql.go | 7 ++++--- pkg/graphql/schema.go | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index d2f12ecf..96d50a62 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -360,7 +360,7 @@ func receiptFilterConditions(id *int, pgStr string, args []interface{}, rctFilte // RetrieveFilteredGQLLogs retrieves and returns all the log CIDs provided blockHash that conform to the provided // filter parameters. -func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockHash *common.Hash) ([]LogResult, error) { +func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockHash *common.Hash, blockNumber *big.Int) ([]LogResult, error) { log.Debug("retrieving log cids for receipt ids with block hash", blockHash.String()) args := make([]interface{}, 0, 4) id := 1 @@ -379,6 +379,12 @@ func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptF args = append(args, blockHash.String()) id++ + if blockNumber != nil { + pgStr += ` AND receipt_cids.block_number = $2` + id++ + args = append(args, blockNumber.Int64()) + } + pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter) pgStr += ` ORDER BY log_cids.index` diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 97282037..2b203813 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -1036,8 +1036,9 @@ func (r *Resolver) GetStorageAt(ctx context.Context, args struct { } func (r *Resolver) GetLogs(ctx context.Context, args struct { - BlockHash common.Hash - Addresses *[]common.Address + BlockHash common.Hash + BlockNumber *BigInt + Addresses *[]common.Address }) (*[]*Log, error) { var filter eth.ReceiptFilter @@ -1054,7 +1055,7 @@ func (r *Resolver) GetLogs(ctx context.Context, args struct { return nil, err } - filteredLogs, err := r.backend.Retriever.RetrieveFilteredGQLLogs(tx, filter, &args.BlockHash) + filteredLogs, err := r.backend.Retriever.RetrieveFilteredGQLLogs(tx, filter, &args.BlockHash, args.BlockNumber.ToInt()) if err != nil { return nil, err } diff --git a/pkg/graphql/schema.go b/pkg/graphql/schema.go index d07d311b..9e09a359 100644 --- a/pkg/graphql/schema.go +++ b/pkg/graphql/schema.go @@ -343,7 +343,7 @@ const schema string = ` getStorageAt(blockHash: Bytes32!, contract: Address!, slot: Bytes32!): StorageResult # Get contract logs by block hash and contract address. - getLogs(blockHash: Bytes32!, addresses: [Address!]): [Log!] + getLogs(blockHash: Bytes32!, blockNumber: BigInt, addresses: [Address!]): [Log!] # PostGraphile alternative to get headers with transactions using block number or block hash. allEthHeaderCids(condition: EthHeaderCidCondition): EthHeaderCidsConnection -- 2.45.2 From 706dfcab8fd1c028372dbba0a6204b3762e4aa9d Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Wed, 2 Nov 2022 17:56:10 +0530 Subject: [PATCH 2/8] Use block number while fetching block with transactions --- pkg/eth/cid_retriever.go | 9 +++++++-- pkg/graphql/graphql.go | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index 96d50a62..c9d65087 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -713,16 +713,21 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) } // RetrieveHeaderAndTxCIDsByBlockHash retrieves header CID and their associated tx CIDs by block hash -func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash) (HeaderCIDRecord, error) { +func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash, blockNumber *big.Int) (HeaderCIDRecord, error) { log.Debug("retrieving header cid and tx cids for block hash ", blockHash.String()) var headerCIDs []HeaderCIDRecord + conditions := map[string]interface{}{"block_hash": blockHash.String()} + if blockNumber != nil { + conditions["header_cids.block_number"] = blockNumber.Int64() + } + // https://github.com/go-gorm/gorm/issues/4083#issuecomment-778883283 // Will use join for TransactionCIDs once preload for 1:N is supported. err := ecr.gormDB.Preload("TransactionCIDs", func(tx *gorm.DB) *gorm.DB { return tx.Select("cid", "tx_hash", "index", "src", "dst", "header_id", "block_number") - }).Joins("IPLD").Find(&headerCIDs, "block_hash = ?", blockHash.String()).Error + }).Joins("IPLD").Find(&headerCIDs, conditions).Error if err != nil { log.Error("header cid retrieval error") diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 2b203813..8b4e1972 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -1272,7 +1272,7 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { var headerCIDs []eth.HeaderCIDRecord var err error if args.Condition.BlockHash != nil { - headerCID, err := r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(common.HexToHash(*args.Condition.BlockHash)) + headerCID, err := r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(common.HexToHash(*args.Condition.BlockHash), args.Condition.BlockNumber.ToInt()) if err != nil { if !strings.Contains(err.Error(), "not found") { return nil, err -- 2.45.2 From e6ac0625d730c69c39c574a7460577aec755e080 Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Wed, 2 Nov 2022 18:49:21 +0530 Subject: [PATCH 3/8] Fix for failing tests --- pkg/graphql/graphql_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/graphql/graphql_test.go b/pkg/graphql/graphql_test.go index 258d6afe..f52c9be0 100644 --- a/pkg/graphql/graphql_test.go +++ b/pkg/graphql/graphql_test.go @@ -296,7 +296,7 @@ var _ = Describe("GraphQL", func() { allEthHeaderCIDsResp, err := client.AllEthHeaderCIDs(ctx, graphql.EthHeaderCIDCondition{BlockHash: &blockHash}) Expect(err).ToNot(HaveOccurred()) - headerCID, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(blocks[1].Hash()) + headerCID, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(blocks[1].Hash(), nil) Expect(err).ToNot(HaveOccurred()) Expect(len(allEthHeaderCIDsResp.Nodes)).To(Equal(1)) -- 2.45.2 From e01fd374a7545f0962160b81a152bc29772734bd Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Wed, 2 Nov 2022 20:33:16 +0530 Subject: [PATCH 4/8] Use block number when fetching block objects --- pkg/eth/backend.go | 38 +++++++++++++++++--------------------- pkg/eth/ipld_retriever.go | 27 +++++++++++++++------------ 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/pkg/eth/backend.go b/pkg/eth/backend.go index 7e55877c..cfa9d091 100644 --- a/pkg/eth/backend.go +++ b/pkg/eth/backend.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "math/big" + "strconv" "time" validator "github.com/cerc-io/eth-ipfs-state-validator/v4/pkg" @@ -364,8 +365,10 @@ func (b *Backend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Blo return nil, err } + blockNumber := header.Number.Uint64() + // Fetch uncles - uncles, err := b.GetUnclesByBlockHash(tx, hash) + uncles, err := b.GetUnclesByBlockHashAndNumber(tx, hash, blockNumber) if err != nil && err != sql.ErrNoRows { log.Error("error fetching uncles: ", err) return nil, err @@ -389,14 +392,14 @@ func (b *Backend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Blo } // Fetch transactions - transactions, err := b.GetTransactionsByBlockHash(tx, hash) + transactions, err := b.GetTransactionsByBlockHashAndNumber(tx, hash, blockNumber) if err != nil && err != sql.ErrNoRows { log.Error("error fetching transactions: ", err) return nil, err } // Fetch receipts - receipts, err := b.GetReceiptsByBlockHash(tx, hash) + receipts, err := b.GetReceiptsByBlockHashAndNumber(tx, hash, blockNumber) if err != nil && err != sql.ErrNoRows { log.Error("error fetching receipts: ", err) return nil, err @@ -418,8 +421,8 @@ func (b *Backend) GetHeaderByBlockHash(tx *sqlx.Tx, hash common.Hash) (*types.He } // GetUnclesByBlockHash retrieves uncles for a provided block hash -func (b *Backend) GetUnclesByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]*types.Header, error) { - _, uncleBytes, err := b.IPLDRetriever.RetrieveUnclesByBlockHash(tx, hash) +func (b *Backend) GetUnclesByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, number uint64) ([]*types.Header, error) { + _, uncleBytes, err := b.IPLDRetriever.RetrieveUncles(tx, hash, number) if err != nil { return nil, err } @@ -439,8 +442,8 @@ func (b *Backend) GetUnclesByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]*types. } // GetTransactionsByBlockHash retrieves transactions for a provided block hash -func (b *Backend) GetTransactionsByBlockHash(tx *sqlx.Tx, hash common.Hash) (types.Transactions, error) { - _, transactionBytes, err := b.IPLDRetriever.RetrieveTransactionsByBlockHash(tx, hash) +func (b *Backend) GetTransactionsByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, number uint64) (types.Transactions, error) { + _, transactionBytes, err := b.IPLDRetriever.RetrieveTransactions(tx, hash, number) if err != nil { return nil, err } @@ -459,8 +462,8 @@ func (b *Backend) GetTransactionsByBlockHash(tx *sqlx.Tx, hash common.Hash) (typ } // GetReceiptsByBlockHash retrieves receipts for a provided block hash -func (b *Backend) GetReceiptsByBlockHash(tx *sqlx.Tx, hash common.Hash) (types.Receipts, error) { - _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceiptsByBlockHash(tx, hash) +func (b *Backend) GetReceiptsByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, number uint64) (types.Receipts, error) { + _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceipts(tx, hash, number) if err != nil { return nil, err } @@ -523,20 +526,13 @@ func (b *Backend) GetReceipts(ctx context.Context, hash common.Hash) (types.Rece } }() - _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceiptsByBlockHash(tx, hash) + headerCID, err := b.Retriever.RetrieveHeaderCIDByHash(tx, hash) if err != nil { return nil, err } - rcts := make(types.Receipts, len(receiptBytes)) - for i, rctBytes := range receiptBytes { - rct := new(types.Receipt) - if err := rct.UnmarshalBinary(rctBytes); err != nil { - return nil, err - } - rct.TxHash = txs[i] - rcts[i] = rct - } - return rcts, nil + blockNumber, _ := strconv.ParseUint(string(headerCID.BlockNumber), 10, 64) + + return b.GetReceiptsByBlockHashAndNumber(tx, hash, blockNumber) } // GetLogs returns all the logs for the given block hash @@ -557,7 +553,7 @@ func (b *Backend) GetLogs(ctx context.Context, hash common.Hash, number uint64) } }() - _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceiptsByBlockHash(tx, hash) + _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceipts(tx, hash, number) if err != nil { return nil, err } diff --git a/pkg/eth/ipld_retriever.go b/pkg/eth/ipld_retriever.go index 217ab563..8473e584 100644 --- a/pkg/eth/ipld_retriever.go +++ b/pkg/eth/ipld_retriever.go @@ -64,7 +64,7 @@ const ( AND uncle_cids.block_number = blocks.block_number ) WHERE block_hash = ANY($1::VARCHAR(66)[])` - RetrieveUnclesByBlockHashPgStr = `SELECT uncle_cids.cid, data + RetrieveUnclesPgStr = `SELECT uncle_cids.cid, data FROM eth.uncle_cids INNER JOIN eth.header_cids ON ( uncle_cids.header_id = header_cids.block_hash @@ -75,6 +75,7 @@ const ( AND uncle_cids.block_number = blocks.block_number ) WHERE header_cids.block_hash = $1 + AND header_cids.block_number = $2 ORDER BY uncle_cids.parent_hash` RetrieveUnclesByBlockNumberPgStr = `SELECT uncle_cids.cid, data FROM eth.uncle_cids @@ -101,7 +102,7 @@ const ( AND transaction_cids.block_number = blocks.block_number ) WHERE tx_hash = ANY($1::VARCHAR(66)[])` - RetrieveTransactionsByBlockHashPgStr = `SELECT transaction_cids.cid, data + RetrieveTransactionsPgStr = `SELECT transaction_cids.cid, data FROM eth.transaction_cids INNER JOIN eth.header_cids ON ( transaction_cids.header_id = header_cids.block_hash @@ -112,6 +113,7 @@ const ( AND transaction_cids.block_number = blocks.block_number ) WHERE block_hash = $1 + AND header_cids.block_number = $2 ORDER BY eth.transaction_cids.index ASC` RetrieveTransactionsByBlockNumberPgStr = `SELECT transaction_cids.cid, data FROM eth.transaction_cids @@ -146,7 +148,7 @@ const ( ) WHERE tx_hash = ANY($1::VARCHAR(66)[]) AND transaction_cids.header_id = (SELECT canonical_header_hash(transaction_cids.block_number))` - RetrieveReceiptsByBlockHashPgStr = `SELECT receipt_cids.leaf_cid, data, eth.transaction_cids.tx_hash + RetrieveReceiptsPgStr = `SELECT receipt_cids.leaf_cid, data, eth.transaction_cids.tx_hash FROM eth.receipt_cids INNER JOIN eth.transaction_cids ON ( receipt_cids.tx_id = transaction_cids.tx_hash @@ -162,6 +164,7 @@ const ( AND receipt_cids.block_number = blocks.block_number ) WHERE block_hash = $1 + AND header_cids.block_number = $2 ORDER BY eth.transaction_cids.index ASC` RetrieveReceiptsByBlockNumberPgStr = `SELECT receipt_cids.leaf_cid, data FROM eth.receipt_cids @@ -338,10 +341,10 @@ func (r *IPLDRetriever) RetrieveUnclesByHashes(hashes []common.Hash) ([]string, return cids, uncles, nil } -// RetrieveUnclesByBlockHash returns the cids and rlp bytes for the uncles corresponding to the provided block hash (of non-omner root block) -func (r *IPLDRetriever) RetrieveUnclesByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, error) { +// RetrieveUncles returns the cids and rlp bytes for the uncles corresponding to the provided block hash, number (of non-omner root block) +func (r *IPLDRetriever) RetrieveUncles(tx *sqlx.Tx, hash common.Hash, number uint64) ([]string, [][]byte, error) { uncleResults := make([]ipldResult, 0) - if err := tx.Select(&uncleResults, RetrieveUnclesByBlockHashPgStr, hash.Hex()); err != nil { + if err := tx.Select(&uncleResults, RetrieveUnclesPgStr, hash.Hex(), number); err != nil { return nil, nil, err } cids := make([]string, len(uncleResults)) @@ -393,10 +396,10 @@ func (r *IPLDRetriever) RetrieveTransactionsByHashes(hashes []common.Hash) ([]st return cids, txs, nil } -// RetrieveTransactionsByBlockHash returns the cids and rlp bytes for the transactions corresponding to the provided block hash -func (r *IPLDRetriever) RetrieveTransactionsByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, error) { +// RetrieveTransactions returns the cids and rlp bytes for the transactions corresponding to the provided block hash, number +func (r *IPLDRetriever) RetrieveTransactions(tx *sqlx.Tx, hash common.Hash, number uint64) ([]string, [][]byte, error) { txResults := make([]ipldResult, 0) - if err := tx.Select(&txResults, RetrieveTransactionsByBlockHashPgStr, hash.Hex()); err != nil { + if err := tx.Select(&txResults, RetrieveTransactionsPgStr, hash.Hex(), number); err != nil { return nil, nil, err } cids := make([]string, len(txResults)) @@ -469,11 +472,11 @@ func (r *IPLDRetriever) RetrieveReceiptsByTxHashes(hashes []common.Hash) ([]stri return cids, rcts, nil } -// RetrieveReceiptsByBlockHash returns the cids and rlp bytes for the receipts corresponding to the provided block hash. +// RetrieveReceipts returns the cids and rlp bytes for the receipts corresponding to the provided block hash, number. // cid returned corresponds to the leaf node data which contains the receipt. -func (r *IPLDRetriever) RetrieveReceiptsByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, []common.Hash, error) { +func (r *IPLDRetriever) RetrieveReceipts(tx *sqlx.Tx, hash common.Hash, number uint64) ([]string, [][]byte, []common.Hash, error) { rctResults := make([]rctIpldResult, 0) - if err := tx.Select(&rctResults, RetrieveReceiptsByBlockHashPgStr, hash.Hex()); err != nil { + if err := tx.Select(&rctResults, RetrieveReceiptsPgStr, hash.Hex(), number); err != nil { return nil, nil, nil, err } cids := make([]string, len(rctResults)) -- 2.45.2 From 4d1873eb65574779bdc1b172b727ec08af170c11 Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Thu, 3 Nov 2022 11:41:29 +0530 Subject: [PATCH 5/8] Use block number when fetching a tx by hash --- pkg/eth/cid_retriever.go | 15 ++++++++++----- pkg/graphql/graphql.go | 5 +++-- pkg/graphql/graphql_test.go | 2 +- pkg/graphql/schema.go | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index c9d65087..1ef56aae 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -712,7 +712,7 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) return headerCIDs, nil } -// RetrieveHeaderAndTxCIDsByBlockHash retrieves header CID and their associated tx CIDs by block hash +// RetrieveHeaderAndTxCIDsByBlockHash retrieves header CID and their associated tx CIDs by block hash (and optionally block number) func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash, blockNumber *big.Int) (HeaderCIDRecord, error) { log.Debug("retrieving header cid and tx cids for block hash ", blockHash.String()) @@ -743,15 +743,20 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Has return headerCIDs[0], nil } -// RetrieveTxCIDByHash returns the tx for the given tx hash -func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string) (TransactionCIDRecord, error) { +// RetrieveTxCIDByHash returns the tx for the given tx hash (and optionally block number) +func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string, blockNumber *big.Int) (TransactionCIDRecord, error) { log.Debug("retrieving tx cid for tx hash ", txHash) var txCIDs []TransactionCIDRecord - err := ecr.gormDB.Joins("IPLD").Find(&txCIDs, "tx_hash = ? AND transaction_cids.header_id = (SELECT canonical_header_hash(transaction_cids.block_number))", txHash).Error + var err error + if blockNumber != nil { + err = ecr.gormDB.Joins("IPLD").Find(&txCIDs, "tx_hash = ? AND transaction_cids.header_id = (SELECT canonical_header_hash(transaction_cids.block_number)) AND transaction_cids.block_number = ?", txHash, blockNumber.Int64()).Error + } else { + err = ecr.gormDB.Joins("IPLD").Find(&txCIDs, "tx_hash = ? AND transaction_cids.header_id = (SELECT canonical_header_hash(transaction_cids.block_number))", txHash).Error + } if err != nil { - log.Error("header cid retrieval error") + log.Error("tx retrieval error") return TransactionCIDRecord{}, err } diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 8b4e1972..2a930f76 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -1353,9 +1353,10 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { } func (r *Resolver) EthTransactionCidByTxHash(ctx context.Context, args struct { - TxHash string + TxHash string + BlockNumber *BigInt }) (*EthTransactionCID, error) { - txCID, err := r.backend.Retriever.RetrieveTxCIDByHash(args.TxHash) + txCID, err := r.backend.Retriever.RetrieveTxCIDByHash(args.TxHash, args.BlockNumber.ToInt()) if err != nil { return nil, err diff --git a/pkg/graphql/graphql_test.go b/pkg/graphql/graphql_test.go index f52c9be0..7dfc3185 100644 --- a/pkg/graphql/graphql_test.go +++ b/pkg/graphql/graphql_test.go @@ -311,7 +311,7 @@ var _ = Describe("GraphQL", func() { ethTransactionCIDResp, err := client.EthTransactionCIDByTxHash(ctx, txHash) Expect(err).ToNot(HaveOccurred()) - txCID, err := backend.Retriever.RetrieveTxCIDByHash(txHash) + txCID, err := backend.Retriever.RetrieveTxCIDByHash(txHash, nil) Expect(err).ToNot(HaveOccurred()) compareEthTxCID(*ethTransactionCIDResp, txCID) diff --git a/pkg/graphql/schema.go b/pkg/graphql/schema.go index 9e09a359..14c5eb0e 100644 --- a/pkg/graphql/schema.go +++ b/pkg/graphql/schema.go @@ -349,6 +349,6 @@ const schema string = ` allEthHeaderCids(condition: EthHeaderCidCondition): EthHeaderCidsConnection # PostGraphile alternative to get transactions using transaction hash. - ethTransactionCidByTxHash(txHash: String!): EthTransactionCid + ethTransactionCidByTxHash(txHash: String!, blockNumber: BigInt): EthTransactionCid } ` -- 2.45.2 From 7f3be6bb4aa2ee48b23d8b3d08c1979252cbe4fe Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Thu, 3 Nov 2022 15:45:48 +0530 Subject: [PATCH 6/8] Add back methods to get block objects by block hash --- pkg/eth/backend.go | 59 ++++++++++++++++++++++++ pkg/eth/ipld_retriever.go | 95 +++++++++++++++++++++++++++++++++++++++ pkg/graphql/graphql.go | 2 + 3 files changed, 156 insertions(+) diff --git a/pkg/eth/backend.go b/pkg/eth/backend.go index cfa9d091..24d86e54 100644 --- a/pkg/eth/backend.go +++ b/pkg/eth/backend.go @@ -421,6 +421,27 @@ func (b *Backend) GetHeaderByBlockHash(tx *sqlx.Tx, hash common.Hash) (*types.He } // GetUnclesByBlockHash retrieves uncles for a provided block hash +func (b *Backend) GetUnclesByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]*types.Header, error) { + _, uncleBytes, err := b.IPLDRetriever.RetrieveUnclesByBlockHash(tx, hash) + if err != nil { + return nil, err + } + + uncles := make([]*types.Header, len(uncleBytes)) + for i, bytes := range uncleBytes { + var uncle types.Header + err = rlp.DecodeBytes(bytes, &uncle) + if err != nil { + return nil, err + } + + uncles[i] = &uncle + } + + return uncles, nil +} + +// GetUnclesByBlockHashAndNumber retrieves uncles for a provided block hash and number func (b *Backend) GetUnclesByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, number uint64) ([]*types.Header, error) { _, uncleBytes, err := b.IPLDRetriever.RetrieveUncles(tx, hash, number) if err != nil { @@ -442,6 +463,26 @@ func (b *Backend) GetUnclesByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, n } // GetTransactionsByBlockHash retrieves transactions for a provided block hash +func (b *Backend) GetTransactionsByBlockHash(tx *sqlx.Tx, hash common.Hash) (types.Transactions, error) { + _, transactionBytes, err := b.IPLDRetriever.RetrieveTransactionsByBlockHash(tx, hash) + if err != nil { + return nil, err + } + + txs := make(types.Transactions, len(transactionBytes)) + for i, txBytes := range transactionBytes { + var tx types.Transaction + if err := tx.UnmarshalBinary(txBytes); err != nil { + return nil, err + } + + txs[i] = &tx + } + + return txs, nil +} + +// GetTransactionsByBlockHashAndNumber retrieves transactions for a provided block hash and number func (b *Backend) GetTransactionsByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, number uint64) (types.Transactions, error) { _, transactionBytes, err := b.IPLDRetriever.RetrieveTransactions(tx, hash, number) if err != nil { @@ -462,6 +503,24 @@ func (b *Backend) GetTransactionsByBlockHashAndNumber(tx *sqlx.Tx, hash common.H } // GetReceiptsByBlockHash retrieves receipts for a provided block hash +func (b *Backend) GetReceiptsByBlockHash(tx *sqlx.Tx, hash common.Hash) (types.Receipts, error) { + _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceiptsByBlockHash(tx, hash) + if err != nil { + return nil, err + } + rcts := make(types.Receipts, len(receiptBytes)) + for i, rctBytes := range receiptBytes { + rct := new(types.Receipt) + if err := rct.UnmarshalBinary(rctBytes); err != nil { + return nil, err + } + rct.TxHash = txs[i] + rcts[i] = rct + } + return rcts, nil +} + +// GetReceiptsByBlockHashAndNumber retrieves receipts for a provided block hash and number func (b *Backend) GetReceiptsByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, number uint64) (types.Receipts, error) { _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceipts(tx, hash, number) if err != nil { diff --git a/pkg/eth/ipld_retriever.go b/pkg/eth/ipld_retriever.go index 8473e584..dc18fa68 100644 --- a/pkg/eth/ipld_retriever.go +++ b/pkg/eth/ipld_retriever.go @@ -77,6 +77,18 @@ const ( WHERE header_cids.block_hash = $1 AND header_cids.block_number = $2 ORDER BY uncle_cids.parent_hash` + RetrieveUnclesByBlockHashPgStr = `SELECT uncle_cids.cid, data + FROM eth.uncle_cids + INNER JOIN eth.header_cids ON ( + uncle_cids.header_id = header_cids.block_hash + AND uncle_cids.block_number = header_cids.block_number + ) + INNER JOIN public.blocks ON ( + uncle_cids.mh_key = blocks.key + AND uncle_cids.block_number = blocks.block_number + ) + WHERE header_cids.block_hash = $1 + ORDER BY uncle_cids.parent_hash` RetrieveUnclesByBlockNumberPgStr = `SELECT uncle_cids.cid, data FROM eth.uncle_cids INNER JOIN eth.header_cids ON ( @@ -115,6 +127,18 @@ const ( WHERE block_hash = $1 AND header_cids.block_number = $2 ORDER BY eth.transaction_cids.index ASC` + RetrieveTransactionsByBlockHashPgStr = `SELECT transaction_cids.cid, data + FROM eth.transaction_cids + INNER JOIN eth.header_cids ON ( + transaction_cids.header_id = header_cids.block_hash + AND transaction_cids.block_number = header_cids.block_number + ) + INNER JOIN public.blocks ON ( + transaction_cids.mh_key = blocks.key + AND transaction_cids.block_number = blocks.block_number + ) + WHERE block_hash = $1 + ORDER BY eth.transaction_cids.index ASC` RetrieveTransactionsByBlockNumberPgStr = `SELECT transaction_cids.cid, data FROM eth.transaction_cids INNER JOIN eth.header_cids ON ( @@ -166,6 +190,23 @@ const ( WHERE block_hash = $1 AND header_cids.block_number = $2 ORDER BY eth.transaction_cids.index ASC` + RetrieveReceiptsByBlockHashPgStr = `SELECT receipt_cids.leaf_cid, data, eth.transaction_cids.tx_hash + FROM eth.receipt_cids + INNER JOIN eth.transaction_cids ON ( + receipt_cids.tx_id = transaction_cids.tx_hash + AND receipt_cids.header_id = transaction_cids.header_id + AND receipt_cids.block_number = transaction_cids.block_number + ) + INNER JOIN eth.header_cids ON ( + transaction_cids.header_id = header_cids.block_hash + AND transaction_cids.block_number = header_cids.block_number + ) + INNER JOIN public.blocks ON ( + receipt_cids.leaf_mh_key = blocks.key + AND receipt_cids.block_number = blocks.block_number + ) + WHERE block_hash = $1 + ORDER BY eth.transaction_cids.index ASC` RetrieveReceiptsByBlockNumberPgStr = `SELECT receipt_cids.leaf_cid, data FROM eth.receipt_cids INNER JOIN eth.transaction_cids ON ( @@ -356,6 +397,21 @@ func (r *IPLDRetriever) RetrieveUncles(tx *sqlx.Tx, hash common.Hash, number uin return cids, uncles, nil } +// RetrieveUnclesByBlockHash returns the cids and rlp bytes for the uncles corresponding to the provided block hash (of non-omner root block) +func (r *IPLDRetriever) RetrieveUnclesByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, error) { + uncleResults := make([]ipldResult, 0) + if err := tx.Select(&uncleResults, RetrieveUnclesByBlockHashPgStr, hash.Hex()); err != nil { + return nil, nil, err + } + cids := make([]string, len(uncleResults)) + uncles := make([][]byte, len(uncleResults)) + for i, res := range uncleResults { + cids[i] = res.CID + uncles[i] = res.Data + } + return cids, uncles, nil +} + // RetrieveUnclesByBlockNumber returns the cids and rlp bytes for the uncles corresponding to the provided block number (of non-omner root block) func (r *IPLDRetriever) RetrieveUnclesByBlockNumber(number uint64) ([]string, [][]byte, error) { uncleResults := make([]ipldResult, 0) @@ -411,6 +467,21 @@ func (r *IPLDRetriever) RetrieveTransactions(tx *sqlx.Tx, hash common.Hash, numb return cids, txs, nil } +// RetrieveTransactionsByBlockHash returns the cids and rlp bytes for the transactions corresponding to the provided block hash +func (r *IPLDRetriever) RetrieveTransactionsByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, error) { + txResults := make([]ipldResult, 0) + if err := tx.Select(&txResults, RetrieveTransactionsByBlockHashPgStr, hash.Hex()); err != nil { + return nil, nil, err + } + cids := make([]string, len(txResults)) + txs := make([][]byte, len(txResults)) + for i, res := range txResults { + cids[i] = res.CID + txs[i] = res.Data + } + return cids, txs, nil +} + // RetrieveTransactionsByBlockNumber returns the cids and rlp bytes for the transactions corresponding to the provided block number func (r *IPLDRetriever) RetrieveTransactionsByBlockNumber(number uint64) ([]string, [][]byte, error) { txResults := make([]ipldResult, 0) @@ -496,6 +567,30 @@ func (r *IPLDRetriever) RetrieveReceipts(tx *sqlx.Tx, hash common.Hash, number u return cids, rcts, txs, nil } +// RetrieveReceiptsByBlockHash returns the cids and rlp bytes for the receipts corresponding to the provided block hash. +// cid returned corresponds to the leaf node data which contains the receipt. +func (r *IPLDRetriever) RetrieveReceiptsByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, []common.Hash, error) { + rctResults := make([]rctIpldResult, 0) + if err := tx.Select(&rctResults, RetrieveReceiptsByBlockHashPgStr, hash.Hex()); err != nil { + return nil, nil, nil, err + } + cids := make([]string, len(rctResults)) + rcts := make([][]byte, len(rctResults)) + txs := make([]common.Hash, len(rctResults)) + + for i, res := range rctResults { + cids[i] = res.LeafCID + nodeVal, err := DecodeLeafNode(res.Data) + if err != nil { + return nil, nil, nil, err + } + rcts[i] = nodeVal + txs[i] = common.HexToHash(res.TxHash) + } + + return cids, rcts, txs, nil +} + // RetrieveReceiptsByBlockNumber returns the cids and rlp bytes for the receipts corresponding to the provided block hash. // cid returned corresponds to the leaf node data which contains the receipt. func (r *IPLDRetriever) RetrieveReceiptsByBlockNumber(number uint64) ([]string, [][]byte, error) { diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 2a930f76..afcbd0f3 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -1356,6 +1356,8 @@ func (r *Resolver) EthTransactionCidByTxHash(ctx context.Context, args struct { TxHash string BlockNumber *BigInt }) (*EthTransactionCID, error) { + // Need not check args.BlockNumber for nil as .ToInt() uses a pointer receiver and returns nil if BlockNumber is nil + // https://stackoverflow.com/questions/42238624/calling-a-method-on-a-nil-struct-pointer-doesnt-panic-why-not txCID, err := r.backend.Retriever.RetrieveTxCIDByHash(args.TxHash, args.BlockNumber.ToInt()) if err != nil { -- 2.45.2 From ad26f5abb0249231809d27809faa370c670fe373 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 3 Nov 2022 11:11:26 -0400 Subject: [PATCH 7/8] Update run_unit_test.sh Removing echo command, as it seems to be only change in CICD. --- .github/workflows/run_unit_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_unit_test.sh b/.github/workflows/run_unit_test.sh index 63fbb99f..0169f9cc 100755 --- a/.github/workflows/run_unit_test.sh +++ b/.github/workflows/run_unit_test.sh @@ -6,7 +6,7 @@ set -e start_dir=$(pwd) temp_dir=$(mktemp -d) cd $temp_dir -echo "git clone -b $(cat /tmp/git_head_ref) https://github.com/$(cat /tmp/git_repository).git" + git clone -b $(cat /tmp/git_head_ref) "https://github.com/$(cat /tmp/git_repository).git" cd ipld-eth-server -- 2.45.2 From 5f6f277e41babcafb03fefead010d607cacd96f0 Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Fri, 4 Nov 2022 09:34:37 +0530 Subject: [PATCH 8/8] Increase wait time for db setup in unit test job --- .github/workflows/run_unit_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_unit_test.sh b/.github/workflows/run_unit_test.sh index 0169f9cc..c1c5e182 100755 --- a/.github/workflows/run_unit_test.sh +++ b/.github/workflows/run_unit_test.sh @@ -17,7 +17,7 @@ rm -f /tmp/git_head_ref /tmp/git_repository echo 'docker-compose up -d migrations ipld-eth-db' docker-compose up -d migrations ipld-eth-db trap "docker-compose down -v --remove-orphans; cd $start_dir ; rm -r $temp_dir" SIGINT SIGTERM ERR -sleep 30 +sleep 60 # Remove old logs so there's no confusion, then run test rm -f /tmp/test.log /tmp/return_test.txt -- 2.45.2