From 70f7face75272201bf1651d94b8f2f2786f3499e Mon Sep 17 00:00:00 2001 From: Ashwin Phatak Date: Mon, 26 Jul 2021 15:43:38 +0530 Subject: [PATCH] getLogs API changes to return txHash, make contract arg optional. (#81) * getLogs API changes to return txHash, make contract arg optional. * Populate log index. * Add test for txn hash in GetLogs request. * Convert tx string to common.Hash after fetching. Co-authored-by: Arijit Das --- pkg/eth/backend.go | 9 +++++++-- pkg/eth/ipld_retriever.go | 18 ++++++++++++------ pkg/graphql/client.go | 12 ++++++++++-- pkg/graphql/graphql.go | 13 ++++++++++--- pkg/graphql/graphql_test.go | 5 +++-- pkg/graphql/schema.go | 2 +- 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/pkg/eth/backend.go b/pkg/eth/backend.go index c1bd1de7..59246fee 100644 --- a/pkg/eth/backend.go +++ b/pkg/eth/backend.go @@ -482,7 +482,7 @@ func (b *Backend) GetTransaction(ctx context.Context, txHash common.Hash) (*type // GetReceipts retrieves receipts for provided block hash func (b *Backend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { - _, receiptBytes, err := b.IPLDRetriever.RetrieveReceiptsByBlockHash(hash) + _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceiptsByBlockHash(hash) if err != nil { return nil, err } @@ -492,6 +492,7 @@ func (b *Backend) GetReceipts(ctx context.Context, hash common.Hash) (types.Rece if err := rlp.DecodeBytes(rctBytes, rct); err != nil { return nil, err } + rct.TxHash = txs[i] rcts[i] = rct } return rcts, nil @@ -499,7 +500,7 @@ func (b *Backend) GetReceipts(ctx context.Context, hash common.Hash) (types.Rece // GetLogs returns all the logs for the given block hash func (b *Backend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { - _, receiptBytes, err := b.IPLDRetriever.RetrieveReceiptsByBlockHash(hash) + _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceiptsByBlockHash(hash) if err != nil { return nil, err } @@ -510,6 +511,10 @@ func (b *Backend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log return nil, err } + for _, log := range rct.Logs { + log.TxHash = txs[i] + } + logs[i] = rct.Logs } return logs, nil diff --git a/pkg/eth/ipld_retriever.go b/pkg/eth/ipld_retriever.go index 3e54e28d..7442756d 100644 --- a/pkg/eth/ipld_retriever.go +++ b/pkg/eth/ipld_retriever.go @@ -83,7 +83,7 @@ const ( INNER JOIN eth.transaction_cids ON (receipt_cids.tx_id = transaction_cids.id) INNER JOIN public.blocks ON (receipt_cids.mh_key = blocks.key) WHERE tx_hash = ANY($1::VARCHAR(66)[])` - RetrieveReceiptsByBlockHashPgStr = `SELECT receipt_cids.cid, data + RetrieveReceiptsByBlockHashPgStr = `SELECT receipt_cids.cid, data, eth.transaction_cids.tx_hash FROM eth.receipt_cids INNER JOIN eth.transaction_cids ON (receipt_cids.tx_id = transaction_cids.id) INNER JOIN eth.header_cids ON (transaction_cids.header_id = header_cids.id) @@ -161,9 +161,11 @@ const ( ) type ipldResult struct { - CID string `db:"cid"` - Data []byte `db:"data"` + CID string `db:"cid"` + Data []byte `db:"data"` + TxHash string `db:"tx_hash"` } + type IPLDRetriever struct { db *postgres.DB } @@ -345,18 +347,22 @@ func (r *IPLDRetriever) RetrieveReceiptsByTxHashes(hashes []common.Hash) ([]stri } // RetrieveReceiptsByBlockHash returns the cids and rlp bytes for the receipts corresponding to the provided block hash -func (r *IPLDRetriever) RetrieveReceiptsByBlockHash(hash common.Hash) ([]string, [][]byte, error) { +func (r *IPLDRetriever) RetrieveReceiptsByBlockHash(hash common.Hash) ([]string, [][]byte, []common.Hash, error) { rctResults := make([]ipldResult, 0) if err := r.db.Select(&rctResults, RetrieveReceiptsByBlockHashPgStr, hash.Hex()); err != nil { - return nil, nil, err + 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.CID rcts[i] = res.Data + txs[i] = common.HexToHash(res.TxHash) } - return cids, rcts, nil + + return cids, rcts, txs, nil } // RetrieveReceiptsByBlockNumber returns the cids and rlp bytes for the receipts corresponding to the provided block hash diff --git a/pkg/graphql/client.go b/pkg/graphql/client.go index 0bb4705d..83fd820a 100644 --- a/pkg/graphql/client.go +++ b/pkg/graphql/client.go @@ -21,8 +21,13 @@ type GetStorageAt struct { } type LogResponse struct { - Topics []common.Hash `json:"topics"` - Data hexutil.Bytes `json:"data"` + Topics []common.Hash `json:"topics"` + Data hexutil.Bytes `json:"data"` + Transaction TransactionResp `json:"transaction"` +} + +type TransactionResp struct { + Hash common.Hash `json:"hash"` } type GetLogs struct { @@ -44,6 +49,9 @@ func (c *Client) GetLogs(ctx context.Context, hash common.Hash, address common.A getLogs(blockHash: "%s", contract: "%s") { data topics + transaction { + hash + } } } `, hash.String(), address.String()) diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 2ae86666..181ac37a 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -1005,15 +1005,16 @@ func (r *Resolver) GetStorageAt(ctx context.Context, args struct { func (r *Resolver) GetLogs(ctx context.Context, args struct { BlockHash common.Hash - Contract common.Address + Contract *common.Address }) (*[]*Log, error) { ret := make([]*Log, 0, 10) - receiptCIDs, receiptsBytes, err := r.backend.IPLDRetriever.RetrieveReceiptsByBlockHash(args.BlockHash) + receiptCIDs, receiptsBytes, txs, err := r.backend.IPLDRetriever.RetrieveReceiptsByBlockHash(args.BlockHash) if err != nil { return nil, err } + var logIndexInBlock uint = 0 receipts := make(types.Receipts, len(receiptsBytes)) for index, receiptBytes := range receiptsBytes { receiptCID := receiptCIDs[index] @@ -1024,12 +1025,18 @@ func (r *Resolver) GetLogs(ctx context.Context, args struct { receipts[index] = receipt for _, log := range receipt.Logs { - if log.Address == args.Contract { + log.Index = logIndexInBlock + logIndexInBlock++ + + if args.Contract == nil || *args.Contract == log.Address { ret = append(ret, &Log{ backend: r.backend, log: log, cid: receiptCID, ipldBlock: receiptBytes, + transaction: &Transaction{ + hash: txs[index], + }, }) } } diff --git a/pkg/graphql/graphql_test.go b/pkg/graphql/graphql_test.go index f91ce2a3..c1665154 100644 --- a/pkg/graphql/graphql_test.go +++ b/pkg/graphql/graphql_test.go @@ -161,8 +161,9 @@ var _ = Describe("GraphQL", func() { expectedLogs := []graphql.LogResponse{ { - Topics: test_helpers.MockLog1.Topics, - Data: hexutil.Bytes(test_helpers.MockLog1.Data), + Topics: test_helpers.MockLog1.Topics, + Data: hexutil.Bytes(test_helpers.MockLog1.Data), + Transaction: graphql.TransactionResp{Hash: test_helpers.MockTransactions[0].Hash()}, }, } Expect(logs).To(Equal(expectedLogs)) diff --git a/pkg/graphql/schema.go b/pkg/graphql/schema.go index 2d49abe5..4da17186 100644 --- a/pkg/graphql/schema.go +++ b/pkg/graphql/schema.go @@ -295,6 +295,6 @@ const schema string = ` getStorageAt(blockHash: Bytes32!, contract: Address!, slot: Bytes32!): StorageResult # Get contract logs by block hash and contract address. - getLogs(blockHash: Bytes32!, contract: Address!): [Log!] + getLogs(blockHash: Bytes32!, contract: Address): [Log!] } `