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 <arijitad.in@gmail.com>
This commit is contained in:
parent
afc63ac960
commit
70f7face75
@ -482,7 +482,7 @@ func (b *Backend) GetTransaction(ctx context.Context, txHash common.Hash) (*type
|
|||||||
|
|
||||||
// GetReceipts retrieves receipts for provided block hash
|
// GetReceipts retrieves receipts for provided block hash
|
||||||
func (b *Backend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if err := rlp.DecodeBytes(rctBytes, rct); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
rct.TxHash = txs[i]
|
||||||
rcts[i] = rct
|
rcts[i] = rct
|
||||||
}
|
}
|
||||||
return rcts, nil
|
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
|
// GetLogs returns all the logs for the given block hash
|
||||||
func (b *Backend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -510,6 +511,10 @@ func (b *Backend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, log := range rct.Logs {
|
||||||
|
log.TxHash = txs[i]
|
||||||
|
}
|
||||||
|
|
||||||
logs[i] = rct.Logs
|
logs[i] = rct.Logs
|
||||||
}
|
}
|
||||||
return logs, nil
|
return logs, nil
|
||||||
|
@ -83,7 +83,7 @@ const (
|
|||||||
INNER JOIN eth.transaction_cids ON (receipt_cids.tx_id = transaction_cids.id)
|
INNER JOIN eth.transaction_cids ON (receipt_cids.tx_id = transaction_cids.id)
|
||||||
INNER JOIN public.blocks ON (receipt_cids.mh_key = blocks.key)
|
INNER JOIN public.blocks ON (receipt_cids.mh_key = blocks.key)
|
||||||
WHERE tx_hash = ANY($1::VARCHAR(66)[])`
|
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
|
FROM eth.receipt_cids
|
||||||
INNER JOIN eth.transaction_cids ON (receipt_cids.tx_id = transaction_cids.id)
|
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)
|
INNER JOIN eth.header_cids ON (transaction_cids.header_id = header_cids.id)
|
||||||
@ -161,9 +161,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ipldResult struct {
|
type ipldResult struct {
|
||||||
CID string `db:"cid"`
|
CID string `db:"cid"`
|
||||||
Data []byte `db:"data"`
|
Data []byte `db:"data"`
|
||||||
|
TxHash string `db:"tx_hash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type IPLDRetriever struct {
|
type IPLDRetriever struct {
|
||||||
db *postgres.DB
|
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
|
// 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)
|
rctResults := make([]ipldResult, 0)
|
||||||
if err := r.db.Select(&rctResults, RetrieveReceiptsByBlockHashPgStr, hash.Hex()); err != nil {
|
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))
|
cids := make([]string, len(rctResults))
|
||||||
rcts := make([][]byte, len(rctResults))
|
rcts := make([][]byte, len(rctResults))
|
||||||
|
txs := make([]common.Hash, len(rctResults))
|
||||||
|
|
||||||
for i, res := range rctResults {
|
for i, res := range rctResults {
|
||||||
cids[i] = res.CID
|
cids[i] = res.CID
|
||||||
rcts[i] = res.Data
|
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
|
// RetrieveReceiptsByBlockNumber returns the cids and rlp bytes for the receipts corresponding to the provided block hash
|
||||||
|
@ -21,8 +21,13 @@ type GetStorageAt struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LogResponse struct {
|
type LogResponse struct {
|
||||||
Topics []common.Hash `json:"topics"`
|
Topics []common.Hash `json:"topics"`
|
||||||
Data hexutil.Bytes `json:"data"`
|
Data hexutil.Bytes `json:"data"`
|
||||||
|
Transaction TransactionResp `json:"transaction"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TransactionResp struct {
|
||||||
|
Hash common.Hash `json:"hash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetLogs struct {
|
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") {
|
getLogs(blockHash: "%s", contract: "%s") {
|
||||||
data
|
data
|
||||||
topics
|
topics
|
||||||
|
transaction {
|
||||||
|
hash
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, hash.String(), address.String())
|
`, hash.String(), address.String())
|
||||||
|
@ -1005,15 +1005,16 @@ func (r *Resolver) GetStorageAt(ctx context.Context, args struct {
|
|||||||
|
|
||||||
func (r *Resolver) GetLogs(ctx context.Context, args struct {
|
func (r *Resolver) GetLogs(ctx context.Context, args struct {
|
||||||
BlockHash common.Hash
|
BlockHash common.Hash
|
||||||
Contract common.Address
|
Contract *common.Address
|
||||||
}) (*[]*Log, error) {
|
}) (*[]*Log, error) {
|
||||||
ret := make([]*Log, 0, 10)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var logIndexInBlock uint = 0
|
||||||
receipts := make(types.Receipts, len(receiptsBytes))
|
receipts := make(types.Receipts, len(receiptsBytes))
|
||||||
for index, receiptBytes := range receiptsBytes {
|
for index, receiptBytes := range receiptsBytes {
|
||||||
receiptCID := receiptCIDs[index]
|
receiptCID := receiptCIDs[index]
|
||||||
@ -1024,12 +1025,18 @@ func (r *Resolver) GetLogs(ctx context.Context, args struct {
|
|||||||
|
|
||||||
receipts[index] = receipt
|
receipts[index] = receipt
|
||||||
for _, log := range receipt.Logs {
|
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{
|
ret = append(ret, &Log{
|
||||||
backend: r.backend,
|
backend: r.backend,
|
||||||
log: log,
|
log: log,
|
||||||
cid: receiptCID,
|
cid: receiptCID,
|
||||||
ipldBlock: receiptBytes,
|
ipldBlock: receiptBytes,
|
||||||
|
transaction: &Transaction{
|
||||||
|
hash: txs[index],
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,8 +161,9 @@ var _ = Describe("GraphQL", func() {
|
|||||||
|
|
||||||
expectedLogs := []graphql.LogResponse{
|
expectedLogs := []graphql.LogResponse{
|
||||||
{
|
{
|
||||||
Topics: test_helpers.MockLog1.Topics,
|
Topics: test_helpers.MockLog1.Topics,
|
||||||
Data: hexutil.Bytes(test_helpers.MockLog1.Data),
|
Data: hexutil.Bytes(test_helpers.MockLog1.Data),
|
||||||
|
Transaction: graphql.TransactionResp{Hash: test_helpers.MockTransactions[0].Hash()},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Expect(logs).To(Equal(expectedLogs))
|
Expect(logs).To(Equal(expectedLogs))
|
||||||
|
@ -295,6 +295,6 @@ const schema string = `
|
|||||||
getStorageAt(blockHash: Bytes32!, contract: Address!, slot: Bytes32!): StorageResult
|
getStorageAt(blockHash: Bytes32!, contract: Address!, slot: Bytes32!): StorageResult
|
||||||
|
|
||||||
# Get contract logs by block hash and contract address.
|
# Get contract logs by block hash and contract address.
|
||||||
getLogs(blockHash: Bytes32!, contract: Address!): [Log!]
|
getLogs(blockHash: Bytes32!, contract: Address): [Log!]
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
Loading…
Reference in New Issue
Block a user