forked from cerc-io/ipld-eth-server
Optimize getLogs
GQL API (#198)
* Avoid joins with header and transaction tables while getting logs * Update getLogs GQL API to accept multiple addresses * Update version * Update unit tests
This commit is contained in:
parent
b29b5269ee
commit
33602aa0e0
1
.github/workflows/run_unit_test.sh
vendored
1
.github/workflows/run_unit_test.sh
vendored
@ -6,6 +6,7 @@ set -e
|
|||||||
start_dir=$(pwd)
|
start_dir=$(pwd)
|
||||||
temp_dir=$(mktemp -d)
|
temp_dir=$(mktemp -d)
|
||||||
cd $temp_dir
|
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"
|
git clone -b $(cat /tmp/git_head_ref) "https://github.com/$(cat /tmp/git_repository).git"
|
||||||
cd ipld-eth-server
|
cd ipld-eth-server
|
||||||
|
|
||||||
|
@ -364,22 +364,17 @@ func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptF
|
|||||||
log.Debug("retrieving log cids for receipt ids with block hash", blockHash.String())
|
log.Debug("retrieving log cids for receipt ids with block hash", blockHash.String())
|
||||||
args := make([]interface{}, 0, 4)
|
args := make([]interface{}, 0, 4)
|
||||||
id := 1
|
id := 1
|
||||||
pgStr := `SELECT CAST(eth.log_cids.block_number as Text), eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.rct_id,
|
pgStr := `SELECT CAST(eth.log_cids.block_number as Text), eth.log_cids.header_id as block_hash,
|
||||||
eth.log_cids.address, eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3,
|
eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.rct_id, eth.log_cids.address,
|
||||||
eth.log_cids.log_data, eth.transaction_cids.tx_hash, eth.transaction_cids.index as txn_index, data,
|
eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3, eth.log_cids.log_data,
|
||||||
eth.receipt_cids.leaf_cid as cid, eth.receipt_cids.post_status, header_cids.block_hash
|
data, eth.receipt_cids.leaf_cid as cid, eth.receipt_cids.post_status, eth.receipt_cids.tx_id AS tx_hash
|
||||||
FROM eth.log_cids, eth.receipt_cids, eth.transaction_cids, eth.header_cids, public.blocks
|
FROM eth.log_cids, eth.receipt_cids, public.blocks
|
||||||
WHERE eth.log_cids.rct_id = receipt_cids.tx_id
|
WHERE eth.log_cids.rct_id = receipt_cids.tx_id
|
||||||
AND eth.log_cids.header_id = eth.receipt_cids.header_id
|
AND eth.log_cids.header_id = receipt_cids.header_id
|
||||||
AND eth.log_cids.block_number = eth.receipt_cids.block_number
|
AND eth.log_cids.block_number = receipt_cids.block_number
|
||||||
AND 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
|
|
||||||
AND transaction_cids.header_id = header_cids.block_hash
|
|
||||||
AND transaction_cids.block_number = header_cids.block_number
|
|
||||||
AND log_cids.leaf_mh_key = blocks.key
|
AND log_cids.leaf_mh_key = blocks.key
|
||||||
AND log_cids.block_number = blocks.block_number
|
AND log_cids.block_number = blocks.block_number
|
||||||
AND header_cids.block_hash = $1`
|
AND receipt_cids.header_id = $1`
|
||||||
|
|
||||||
args = append(args, blockHash.String())
|
args = append(args, blockHash.String())
|
||||||
id++
|
id++
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
@ -91,10 +92,16 @@ func NewClient(endpoint string) *Client {
|
|||||||
return &Client{client: client}
|
return &Client{client: client}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) GetLogs(ctx context.Context, hash common.Hash, address *common.Address) ([]LogResponse, error) {
|
func (c *Client) GetLogs(ctx context.Context, hash common.Hash, addresses []common.Address) ([]LogResponse, error) {
|
||||||
params := fmt.Sprintf(`blockHash: "%s"`, hash.String())
|
params := fmt.Sprintf(`blockHash: "%s"`, hash.String())
|
||||||
if address != nil {
|
|
||||||
params += fmt.Sprintf(`, contract: "%s"`, address.String())
|
if addresses != nil {
|
||||||
|
addressStrings := make([]string, len(addresses))
|
||||||
|
for i, address := range addresses {
|
||||||
|
addressStrings[i] = fmt.Sprintf(`"%s"`, address.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
params += fmt.Sprintf(`, addresses: [%s]`, strings.Join(addressStrings, ","))
|
||||||
}
|
}
|
||||||
|
|
||||||
getLogsQuery := fmt.Sprintf(`query{
|
getLogsQuery := fmt.Sprintf(`query{
|
||||||
|
@ -1037,12 +1037,15 @@ 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
|
Addresses *[]common.Address
|
||||||
}) (*[]*Log, error) {
|
}) (*[]*Log, error) {
|
||||||
|
|
||||||
var filter eth.ReceiptFilter
|
var filter eth.ReceiptFilter
|
||||||
if args.Contract != nil {
|
|
||||||
filter.LogAddresses = []string{args.Contract.String()}
|
if args.Addresses != nil {
|
||||||
|
filter.LogAddresses = make([]string, len(*args.Addresses))
|
||||||
|
for i, address := range *args.Addresses {
|
||||||
|
filter.LogAddresses[i] = address.String()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin tx
|
// Begin tx
|
||||||
|
@ -174,7 +174,7 @@ var _ = Describe("GraphQL", func() {
|
|||||||
|
|
||||||
Describe("eth_getLogs", func() {
|
Describe("eth_getLogs", func() {
|
||||||
It("Retrieves logs that matches the provided blockHash and contract address", func() {
|
It("Retrieves logs that matches the provided blockHash and contract address", func() {
|
||||||
logs, err := client.GetLogs(ctx, blockHash, &contractAddress)
|
logs, err := client.GetLogs(ctx, blockHash, []common.Address{contractAddress})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
expectedLogs := []graphql.LogResponse{
|
expectedLogs := []graphql.LogResponse{
|
||||||
@ -191,7 +191,7 @@ var _ = Describe("GraphQL", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("Retrieves logs for the failed receipt status that matches the provided blockHash and another contract address", func() {
|
It("Retrieves logs for the failed receipt status that matches the provided blockHash and another contract address", func() {
|
||||||
logs, err := client.GetLogs(ctx, blockHash, &test_helpers.AnotherAddress2)
|
logs, err := client.GetLogs(ctx, blockHash, []common.Address{test_helpers.AnotherAddress2})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
expectedLogs := []graphql.LogResponse{
|
expectedLogs := []graphql.LogResponse{
|
||||||
@ -207,6 +207,30 @@ var _ = Describe("GraphQL", func() {
|
|||||||
Expect(logs).To(Equal(expectedLogs))
|
Expect(logs).To(Equal(expectedLogs))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("Retrieves logs that matches the provided blockHash and multiple contract addresses", func() {
|
||||||
|
logs, err := client.GetLogs(ctx, blockHash, []common.Address{contractAddress, test_helpers.AnotherAddress2})
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
expectedLogs := []graphql.LogResponse{
|
||||||
|
{
|
||||||
|
Topics: test_helpers.MockLog1.Topics,
|
||||||
|
Data: hexutil.Bytes(test_helpers.MockLog1.Data),
|
||||||
|
Transaction: graphql.TransactionResponse{Hash: test_helpers.MockTransactions[0].Hash()},
|
||||||
|
ReceiptCID: test_helpers.Rct1CID.String(),
|
||||||
|
Status: int32(test_helpers.MockReceipts[0].Status),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Topics: test_helpers.MockLog6.Topics,
|
||||||
|
Data: hexutil.Bytes(test_helpers.MockLog6.Data),
|
||||||
|
Transaction: graphql.TransactionResponse{Hash: test_helpers.MockTransactions[3].Hash()},
|
||||||
|
ReceiptCID: test_helpers.Rct4CID.String(),
|
||||||
|
Status: int32(test_helpers.MockReceipts[3].Status),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Expect(logs).To(Equal(expectedLogs))
|
||||||
|
})
|
||||||
|
|
||||||
It("Retrieves all the logs for the receipt that matches the provided blockHash and nil contract address", func() {
|
It("Retrieves all the logs for the receipt that matches the provided blockHash and nil contract address", func() {
|
||||||
logs, err := client.GetLogs(ctx, blockHash, nil)
|
logs, err := client.GetLogs(ctx, blockHash, nil)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@ -214,7 +238,7 @@ var _ = Describe("GraphQL", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("Retrieves logs with random hash", func() {
|
It("Retrieves logs with random hash", func() {
|
||||||
logs, err := client.GetLogs(ctx, randomHash, &contractAddress)
|
logs, err := client.GetLogs(ctx, randomHash, []common.Address{contractAddress})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(len(logs)).To(Equal(0))
|
Expect(len(logs)).To(Equal(0))
|
||||||
})
|
})
|
||||||
|
@ -343,7 +343,7 @@ 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!, addresses: [Address!]): [Log!]
|
||||||
|
|
||||||
# PostGraphile alternative to get headers with transactions using block number or block hash.
|
# PostGraphile alternative to get headers with transactions using block number or block hash.
|
||||||
allEthHeaderCids(condition: EthHeaderCidCondition): EthHeaderCidsConnection
|
allEthHeaderCids(condition: EthHeaderCidCondition): EthHeaderCidsConnection
|
||||||
|
@ -20,8 +20,8 @@ import "fmt"
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
Major = 4 // Major version component of the current release
|
Major = 4 // Major version component of the current release
|
||||||
Minor = 1 // Minor version component of the current release
|
Minor = 2 // Minor version component of the current release
|
||||||
Patch = 9 // Patch version component of the current release
|
Patch = 0 // Patch version component of the current release
|
||||||
Meta = "alpha" // Version metadata to append to the version string
|
Meta = "alpha" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user