Add test for graphql.

This commit is contained in:
Arijit Das 2021-09-01 12:32:28 +05:30
parent 71837c4b24
commit 967c148eff
12 changed files with 241 additions and 175 deletions

View File

@ -24,6 +24,7 @@ import (
"fmt" "fmt"
"io" "io"
"math/big" "math/big"
"strconv"
"time" "time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -120,12 +121,7 @@ func (pea *PublicEthAPI) GetHeaderByHash(ctx context.Context, hash common.Hash)
// rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field // rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field
func (pea *PublicEthAPI) rpcMarshalHeader(header *types.Header) (map[string]interface{}, error) { func (pea *PublicEthAPI) rpcMarshalHeader(header *types.Header) (map[string]interface{}, error) {
var extractMiner bool fields := RPCMarshalHeader(header, pea.B.Config.ChainConfig.Clique != nil)
if pea.B.Config.ChainConfig.Clique != nil {
extractMiner = true
}
fields := RPCMarshalHeader(header, extractMiner)
td, err := pea.B.GetTd(header.Hash()) td, err := pea.B.GetTd(header.Hash())
if err != nil { if err != nil {
return nil, err return nil, err
@ -628,7 +624,7 @@ func (pea *PublicEthAPI) localGetLogs(crit filters.FilterCriteria) ([]*types.Log
return nil, err return nil, err
} }
return pea.B.Fetcher.FetchLogs(filteredLogs) return decomposeLogs(filteredLogs)
} }
// Otherwise, create block range from criteria // Otherwise, create block range from criteria
@ -651,12 +647,12 @@ func (pea *PublicEthAPI) localGetLogs(crit filters.FilterCriteria) ([]*types.Log
end := endingBlock.Int64() end := endingBlock.Int64()
var logs []*types.Log var logs []*types.Log
for i := start; i <= end; i++ { for i := start; i <= end; i++ {
filteredLog, err := pea.B.Retriever.RetrieveFilteredLog(tx, filter, i, nil) filteredLogs, err := pea.B.Retriever.RetrieveFilteredLog(tx, filter, i, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
logCIDs, err := pea.B.Fetcher.FetchLogs(filteredLog) logCIDs, err := decomposeLogs(filteredLogs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1084,12 +1080,7 @@ func (pea *PublicEthAPI) writeStateDiffFor(blockHash common.Hash) {
// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field // rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field
func (pea *PublicEthAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { func (pea *PublicEthAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
var extractMiner bool fields, err := RPCMarshalBlock(b, inclTx, fullTx, pea.B.Config.ChainConfig.Clique != nil)
if pea.B.Config.ChainConfig.Clique != nil {
extractMiner = true
}
fields, err := RPCMarshalBlock(b, inclTx, fullTx, extractMiner)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1105,12 +1096,7 @@ func (pea *PublicEthAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx boo
// rpcMarshalBlockWithUncleHashes uses the generalized output filler, then adds the total difficulty field // rpcMarshalBlockWithUncleHashes uses the generalized output filler, then adds the total difficulty field
func (pea *PublicEthAPI) rpcMarshalBlockWithUncleHashes(b *types.Block, uncleHashes []common.Hash, inclTx bool, fullTx bool) (map[string]interface{}, error) { func (pea *PublicEthAPI) rpcMarshalBlockWithUncleHashes(b *types.Block, uncleHashes []common.Hash, inclTx bool, fullTx bool) (map[string]interface{}, error) {
var extractMiner bool fields, err := RPCMarshalBlockWithUncleHashes(b, uncleHashes, inclTx, fullTx, pea.B.Config.ChainConfig.Clique != nil)
if pea.B.Config.ChainConfig.Clique != nil {
extractMiner = true
}
fields, err := RPCMarshalBlockWithUncleHashes(b, uncleHashes, inclTx, fullTx, extractMiner)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1130,3 +1116,42 @@ func toHexSlice(b [][]byte) []string {
} }
return r return r
} }
// decomposeLogs return logs from LogResult.
func decomposeLogs(logCIDs []LogResult) ([]*types.Log, error) {
logs := make([]*types.Log, len(logCIDs))
for i, l := range logCIDs {
topics := make([]common.Hash, 0)
if l.Topic0 != "" {
topics = append(topics, common.HexToHash(l.Topic0))
}
if l.Topic1 != "" {
topics = append(topics, common.HexToHash(l.Topic1))
}
if l.Topic2 != "" {
topics = append(topics, common.HexToHash(l.Topic2))
}
if l.Topic3 != "" {
topics = append(topics, common.HexToHash(l.Topic3))
}
// TODO: should we convert string to uint ?
blockNum, err := strconv.ParseUint(l.BlockNumber, 10, 64)
if err != nil {
return nil, err
}
logs[i] = &types.Log{
Address: common.HexToAddress(l.Address),
Topics: topics,
Data: l.Data,
BlockNumber: blockNum,
TxHash: common.HexToHash(l.TxHash),
TxIndex: uint(l.TxnIndex),
BlockHash: common.HexToHash(l.BlockHash),
Index: uint(l.Index),
}
}
return logs, nil
}

View File

@ -34,7 +34,6 @@ import (
"github.com/ethereum/go-ethereum/statediff/indexer" "github.com/ethereum/go-ethereum/statediff/indexer"
"github.com/ethereum/go-ethereum/statediff/indexer/node" "github.com/ethereum/go-ethereum/statediff/indexer/node"
"github.com/ethereum/go-ethereum/statediff/indexer/postgres" "github.com/ethereum/go-ethereum/statediff/indexer/postgres"
"github.com/ethereum/go-ethereum/statediff/indexer/shared"
sdtypes "github.com/ethereum/go-ethereum/statediff/types" sdtypes "github.com/ethereum/go-ethereum/statediff/types"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
@ -48,7 +47,7 @@ var (
randomHash = crypto.Keccak256Hash(randomAddr.Bytes()) randomHash = crypto.Keccak256Hash(randomAddr.Bytes())
number = rpc.BlockNumber(test_helpers.BlockNumber.Int64()) number = rpc.BlockNumber(test_helpers.BlockNumber.Int64())
londonBlockNum = rpc.BlockNumber(test_helpers.LondonBlockNum.Int64()) londonBlockNum = rpc.BlockNumber(test_helpers.LondonBlockNum.Int64())
wrongNumber = rpc.BlockNumber(number + 1) wrongNumber = number + 1
blockHash = test_helpers.MockBlock.Header().Hash() blockHash = test_helpers.MockBlock.Header().Hash()
baseFee = test_helpers.MockLondonBlock.BaseFee() baseFee = test_helpers.MockLondonBlock.BaseFee()
ctx = context.Background() ctx = context.Background()
@ -482,14 +481,14 @@ var _ = Describe("API", func() {
Describe("eth_getBlockTransactionCountByNumber", func() { Describe("eth_getBlockTransactionCountByNumber", func() {
It("Retrieves the number of transactions in the canonical block with the provided number", func() { It("Retrieves the number of transactions in the canonical block with the provided number", func() {
count := api.GetBlockTransactionCountByNumber(ctx, number) count := api.GetBlockTransactionCountByNumber(ctx, number)
Expect(uint64(*count)).To(Equal(uint64(3))) Expect(uint64(*count)).To(Equal(uint64(4)))
}) })
}) })
Describe("eth_getBlockTransactionCountByHash", func() { Describe("eth_getBlockTransactionCountByHash", func() {
It("Retrieves the number of transactions in the block with the provided hash ", func() { It("Retrieves the number of transactions in the block with the provided hash ", func() {
count := api.GetBlockTransactionCountByHash(ctx, blockHash) count := api.GetBlockTransactionCountByHash(ctx, blockHash)
Expect(uint64(*count)).To(Equal(uint64(3))) Expect(uint64(*count)).To(Equal(uint64(4)))
}) })
}) })
@ -875,8 +874,8 @@ var _ = Describe("API", func() {
} }
logs, err = api.GetLogs(ctx, crit) logs, err = api.GetLogs(ctx, crit)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(len(logs)).To(Equal(5)) Expect(len(logs)).To(Equal(6))
Expect(logs).To(Equal([]*types.Log{test_helpers.MockLog1, test_helpers.MockLog2, test_helpers.MockLog3, test_helpers.MockLog4, test_helpers.MockLog5})) Expect(logs).To(Equal([]*types.Log{test_helpers.MockLog1, test_helpers.MockLog2, test_helpers.MockLog3, test_helpers.MockLog4, test_helpers.MockLog5, test_helpers.MockLog6}))
}) })
It("Uses the provided blockhash if one is provided", func() { It("Uses the provided blockhash if one is provided", func() {
@ -1011,8 +1010,8 @@ var _ = Describe("API", func() {
} }
logs, err = api.GetLogs(ctx, crit) logs, err = api.GetLogs(ctx, crit)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(len(logs)).To(Equal(5)) Expect(len(logs)).To(Equal(6))
Expect(logs).To(Equal([]*types.Log{test_helpers.MockLog1, test_helpers.MockLog2, test_helpers.MockLog3, test_helpers.MockLog4, test_helpers.MockLog5})) Expect(logs).To(Equal([]*types.Log{test_helpers.MockLog1, test_helpers.MockLog2, test_helpers.MockLog3, test_helpers.MockLog4, test_helpers.MockLog5, test_helpers.MockLog6}))
}) })
It("Filters on contract address if any are provided", func() { It("Filters on contract address if any are provided", func() {
@ -1134,20 +1133,3 @@ var _ = Describe("API", func() {
}) })
}) })
}) })
func publishCode(db *postgres.DB, codeHash common.Hash, code []byte) error {
tx, err := db.Beginx()
if err != nil {
return err
}
mhKey, err := shared.MultihashKeyFromKeccak256(codeHash)
if err != nil {
tx.Rollback()
return err
}
if err := shared.PublishDirect(tx, mhKey, code); err != nil {
tx.Rollback()
return err
}
return tx.Commit()
}

View File

@ -310,7 +310,7 @@ func (ecr *CIDRetriever) RetrieveRctCIDsByHeaderID(tx *sqlx.Tx, rctFilter Receip
// RetrieveFilteredGQLLogs retrieves and returns all the log cIDs provided blockHash that conform to the provided // RetrieveFilteredGQLLogs retrieves and returns all the log cIDs provided blockHash that conform to the provided
// filter parameters. // 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) ([]LogResult, error) {
log.Debug("retrieving log cids for receipt ids") log.Debug("retrieving log cids for receipt ids")
args := make([]interface{}, 0, 4) args := make([]interface{}, 0, 4)
id := 1 id := 1
@ -321,7 +321,7 @@ func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptF
WHERE eth.log_cids.receipt_id = receipt_cids.id WHERE eth.log_cids.receipt_id = receipt_cids.id
AND receipt_cids.tx_id = transaction_cids.id AND receipt_cids.tx_id = transaction_cids.id
AND transaction_cids.header_id = header_cids.id AND transaction_cids.header_id = header_cids.id
AND receipt_cids.mh_key = blocks.key AND header_cids.block_hash = $1` AND log_cids.leaf_mh_key = blocks.key AND header_cids.block_hash = $1`
args = append(args, blockHash.String()) args = append(args, blockHash.String())
id++ id++
@ -329,7 +329,7 @@ func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptF
pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter) pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter)
pgStr += ` ORDER BY log_cids.index` pgStr += ` ORDER BY log_cids.index`
logCIDs := make([]logResult, 0) logCIDs := make([]LogResult, 0)
err := tx.Select(&logCIDs, pgStr, args...) err := tx.Select(&logCIDs, pgStr, args...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -340,7 +340,7 @@ func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptF
// RetrieveFilteredLog retrieves and returns all the log cIDs provided blockHeight or blockHash that conform to the provided // RetrieveFilteredLog retrieves and returns all the log cIDs provided blockHeight or blockHash that conform to the provided
// filter parameters. // filter parameters.
func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash) ([]logResult, error) { func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash) ([]LogResult, error) {
log.Debug("retrieving log cids for receipt ids") log.Debug("retrieving log cids for receipt ids")
args := make([]interface{}, 0, 4) args := make([]interface{}, 0, 4)
pgStr := `SELECT eth.log_cids.id,eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.receipt_id, pgStr := `SELECT eth.log_cids.id,eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.receipt_id,
@ -366,7 +366,7 @@ func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilte
pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter) pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter)
pgStr += ` ORDER BY log_cids.index` pgStr += ` ORDER BY log_cids.index`
logCIDs := make([]logResult, 0) logCIDs := make([]LogResult, 0)
err := tx.Select(&logCIDs, pgStr, args...) err := tx.Select(&logCIDs, pgStr, args...)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -249,11 +249,11 @@ var _ = Describe("Retriever", func() {
expectedHeaderCID.ID = cids[0].Header.ID expectedHeaderCID.ID = cids[0].Header.ID
expectedHeaderCID.NodeID = cids[0].Header.NodeID expectedHeaderCID.NodeID = cids[0].Header.NodeID
Expect(cids[0].Header).To(Equal(expectedHeaderCID)) Expect(cids[0].Header).To(Equal(expectedHeaderCID))
Expect(len(cids[0].Transactions)).To(Equal(3)) Expect(len(cids[0].Transactions)).To(Equal(4))
Expect(eth.TxModelsContainsCID(cids[0].Transactions, test_helpers.MockCIDWrapper.Transactions[0].CID)).To(BeTrue()) Expect(eth.TxModelsContainsCID(cids[0].Transactions, test_helpers.MockCIDWrapper.Transactions[0].CID)).To(BeTrue())
Expect(eth.TxModelsContainsCID(cids[0].Transactions, test_helpers.MockCIDWrapper.Transactions[1].CID)).To(BeTrue()) Expect(eth.TxModelsContainsCID(cids[0].Transactions, test_helpers.MockCIDWrapper.Transactions[1].CID)).To(BeTrue())
Expect(eth.TxModelsContainsCID(cids[0].Transactions, test_helpers.MockCIDWrapper.Transactions[2].CID)).To(BeTrue()) Expect(eth.TxModelsContainsCID(cids[0].Transactions, test_helpers.MockCIDWrapper.Transactions[2].CID)).To(BeTrue())
Expect(len(cids[0].Receipts)).To(Equal(3)) Expect(len(cids[0].Receipts)).To(Equal(4))
Expect(eth.ReceiptModelsContainsCID(cids[0].Receipts, test_helpers.MockCIDWrapper.Receipts[0].CID)).To(BeTrue()) Expect(eth.ReceiptModelsContainsCID(cids[0].Receipts, test_helpers.MockCIDWrapper.Receipts[0].CID)).To(BeTrue())
Expect(eth.ReceiptModelsContainsCID(cids[0].Receipts, test_helpers.MockCIDWrapper.Receipts[1].CID)).To(BeTrue()) Expect(eth.ReceiptModelsContainsCID(cids[0].Receipts, test_helpers.MockCIDWrapper.Receipts[1].CID)).To(BeTrue())
Expect(eth.ReceiptModelsContainsCID(cids[0].Receipts, test_helpers.MockCIDWrapper.Receipts[2].CID)).To(BeTrue()) Expect(eth.ReceiptModelsContainsCID(cids[0].Receipts, test_helpers.MockCIDWrapper.Receipts[2].CID)).To(BeTrue())
@ -345,13 +345,13 @@ var _ = Describe("Retriever", func() {
Expect(len(cids5)).To(Equal(1)) Expect(len(cids5)).To(Equal(1))
Expect(cids5[0].BlockNumber).To(Equal(test_helpers.MockCIDWrapper.BlockNumber)) Expect(cids5[0].BlockNumber).To(Equal(test_helpers.MockCIDWrapper.BlockNumber))
Expect(cids5[0].Header).To(Equal(models.HeaderModel{})) Expect(cids5[0].Header).To(Equal(models.HeaderModel{}))
Expect(len(cids5[0].Transactions)).To(Equal(3)) Expect(len(cids5[0].Transactions)).To(Equal(4))
Expect(eth.TxModelsContainsCID(cids5[0].Transactions, test_helpers.Trx1CID.String())).To(BeTrue()) Expect(eth.TxModelsContainsCID(cids5[0].Transactions, test_helpers.Trx1CID.String())).To(BeTrue())
Expect(eth.TxModelsContainsCID(cids5[0].Transactions, test_helpers.Trx2CID.String())).To(BeTrue()) Expect(eth.TxModelsContainsCID(cids5[0].Transactions, test_helpers.Trx2CID.String())).To(BeTrue())
Expect(eth.TxModelsContainsCID(cids5[0].Transactions, test_helpers.Trx3CID.String())).To(BeTrue()) Expect(eth.TxModelsContainsCID(cids5[0].Transactions, test_helpers.Trx3CID.String())).To(BeTrue())
Expect(len(cids5[0].StateNodes)).To(Equal(0)) Expect(len(cids5[0].StateNodes)).To(Equal(0))
Expect(len(cids5[0].StorageNodes)).To(Equal(0)) Expect(len(cids5[0].StorageNodes)).To(Equal(0))
Expect(len(cids5[0].Receipts)).To(Equal(3)) Expect(len(cids5[0].Receipts)).To(Equal(4))
Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct1CID.String())).To(BeTrue()) Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct1CID.String())).To(BeTrue())
Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct2CID.String())).To(BeTrue()) Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct2CID.String())).To(BeTrue())
Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct3CID.String())).To(BeTrue()) Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct3CID.String())).To(BeTrue())

View File

@ -48,11 +48,11 @@ var _ = Describe("Filterer", func() {
Expect(iplds.Header).To(Equal(test_helpers.MockIPLDs.Header)) Expect(iplds.Header).To(Equal(test_helpers.MockIPLDs.Header))
var expectedEmptyUncles []ipfs.BlockModel var expectedEmptyUncles []ipfs.BlockModel
Expect(iplds.Uncles).To(Equal(expectedEmptyUncles)) Expect(iplds.Uncles).To(Equal(expectedEmptyUncles))
Expect(len(iplds.Transactions)).To(Equal(3)) Expect(len(iplds.Transactions)).To(Equal(4))
Expect(shared.IPLDsContainBytes(iplds.Transactions, test_helpers.Tx1)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds.Transactions, test_helpers.Tx1)).To(BeTrue())
Expect(shared.IPLDsContainBytes(iplds.Transactions, test_helpers.Tx2)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds.Transactions, test_helpers.Tx2)).To(BeTrue())
Expect(shared.IPLDsContainBytes(iplds.Transactions, test_helpers.Tx3)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds.Transactions, test_helpers.Tx3)).To(BeTrue())
Expect(len(iplds.Receipts)).To(Equal(3)) Expect(len(iplds.Receipts)).To(Equal(4))
Expect(shared.IPLDsContainBytes(iplds.Receipts, test_helpers.Rct1)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds.Receipts, test_helpers.Rct1)).To(BeTrue())
Expect(shared.IPLDsContainBytes(iplds.Receipts, test_helpers.Rct2)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds.Receipts, test_helpers.Rct2)).To(BeTrue())
Expect(shared.IPLDsContainBytes(iplds.Receipts, test_helpers.Rct3)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds.Receipts, test_helpers.Rct3)).To(BeTrue())
@ -142,13 +142,13 @@ var _ = Describe("Filterer", func() {
Expect(iplds5.BlockNumber.Int64()).To(Equal(test_helpers.MockIPLDs.BlockNumber.Int64())) Expect(iplds5.BlockNumber.Int64()).To(Equal(test_helpers.MockIPLDs.BlockNumber.Int64()))
Expect(iplds5.Header).To(Equal(ipfs.BlockModel{})) Expect(iplds5.Header).To(Equal(ipfs.BlockModel{}))
Expect(len(iplds5.Uncles)).To(Equal(0)) Expect(len(iplds5.Uncles)).To(Equal(0))
Expect(len(iplds5.Transactions)).To(Equal(3)) Expect(len(iplds5.Transactions)).To(Equal(4))
Expect(shared.IPLDsContainBytes(iplds5.Transactions, test_helpers.Tx1)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds5.Transactions, test_helpers.Tx1)).To(BeTrue())
Expect(shared.IPLDsContainBytes(iplds5.Transactions, test_helpers.Tx2)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds5.Transactions, test_helpers.Tx2)).To(BeTrue())
Expect(shared.IPLDsContainBytes(iplds5.Transactions, test_helpers.Tx3)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds5.Transactions, test_helpers.Tx3)).To(BeTrue())
Expect(len(iplds5.StorageNodes)).To(Equal(0)) Expect(len(iplds5.StorageNodes)).To(Equal(0))
Expect(len(iplds5.StateNodes)).To(Equal(0)) Expect(len(iplds5.StateNodes)).To(Equal(0))
Expect(len(iplds5.Receipts)).To(Equal(3)) Expect(len(iplds5.Receipts)).To(Equal(4))
Expect(shared.IPLDsContainBytes(iplds5.Receipts, test_helpers.Rct1)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds5.Receipts, test_helpers.Rct1)).To(BeTrue())
Expect(shared.IPLDsContainBytes(iplds5.Receipts, test_helpers.Rct2)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds5.Receipts, test_helpers.Rct2)).To(BeTrue())
Expect(shared.IPLDsContainBytes(iplds5.Receipts, test_helpers.Rct3)).To(BeTrue()) Expect(shared.IPLDsContainBytes(iplds5.Receipts, test_helpers.Rct3)).To(BeTrue())

View File

@ -20,10 +20,8 @@ import (
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"strconv"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/statediff/indexer/ipfs" "github.com/ethereum/go-ethereum/statediff/indexer/ipfs"
"github.com/ethereum/go-ethereum/statediff/indexer/models" "github.com/ethereum/go-ethereum/statediff/indexer/models"
"github.com/ethereum/go-ethereum/statediff/indexer/postgres" "github.com/ethereum/go-ethereum/statediff/indexer/postgres"
@ -167,93 +165,6 @@ func (f *IPLDFetcher) FetchRcts(tx *sqlx.Tx, cids []models.ReceiptModel) ([]ipfs
return rctIPLDs, nil return rctIPLDs, nil
} }
// FetchLogs fetches logs.
func (f *IPLDFetcher) FetchLogs(logCIDs []logResult) ([]*types.Log, error) {
log.Debug("fetching logs")
logs := make([]*types.Log, len(logCIDs))
for i, l := range logCIDs {
topics := make([]common.Hash, 0)
if l.Topic0 != "" {
topics = append(topics, common.HexToHash(l.Topic0))
}
if l.Topic1 != "" {
topics = append(topics, common.HexToHash(l.Topic1))
}
if l.Topic2 != "" {
topics = append(topics, common.HexToHash(l.Topic2))
}
if l.Topic3 != "" {
topics = append(topics, common.HexToHash(l.Topic3))
}
// TODO: should we convert string to uint ?
blockNum, err := strconv.ParseUint(l.BlockNumber, 10, 64)
if err != nil {
return nil, err
}
logs[i] = &types.Log{
Address: common.HexToAddress(l.Address),
Topics: topics,
Data: l.Data,
BlockNumber: blockNum,
TxHash: common.HexToHash(l.TxHash),
TxIndex: uint(l.TxnIndex),
BlockHash: common.HexToHash(l.BlockHash),
Index: uint(l.Index),
}
}
return logs, nil
}
type logsCID struct {
Log *types.Log
CID string
RctCID string
RctData []byte
RctStatus uint64
}
// FetchGQLLogs fetches logs for graphql.
func (f *IPLDFetcher) FetchGQLLogs(logCIDs []logResult) ([]logsCID, error) {
log.Debug("fetching logs")
logs := make([]logsCID, len(logCIDs))
for i, l := range logCIDs {
topics := make([]common.Hash, 0)
if l.Topic0 != "" {
topics = append(topics, common.HexToHash(l.Topic0))
}
if l.Topic1 != "" {
topics = append(topics, common.HexToHash(l.Topic1))
}
if l.Topic2 != "" {
topics = append(topics, common.HexToHash(l.Topic2))
}
if l.Topic3 != "" {
topics = append(topics, common.HexToHash(l.Topic3))
}
logs[i] = logsCID{
Log: &types.Log{
Address: common.HexToAddress(l.Address),
Topics: topics,
Data: l.Data,
Index: uint(l.Index),
TxHash: common.HexToHash(l.TxHash),
},
CID: l.LeafCID,
RctCID: l.RctCID,
RctData: l.RctData,
RctStatus: l.RctStatus,
}
}
return logs, nil
}
// FetchState fetches state nodes // FetchState fetches state nodes
func (f *IPLDFetcher) FetchState(tx *sqlx.Tx, cids []models.StateNodeModel) ([]StateNode, error) { func (f *IPLDFetcher) FetchState(tx *sqlx.Tx, cids []models.StateNodeModel) ([]StateNode, error) {
log.Debug("fetching state iplds") log.Debug("fetching state iplds")

View File

@ -96,6 +96,7 @@ var (
Address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592") Address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592")
AnotherAddress = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476593") AnotherAddress = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476593")
AnotherAddress1 = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476594") AnotherAddress1 = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476594")
AnotherAddress2 = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476596")
ContractAddress = crypto.CreateAddress(SenderAddr, MockTransactions[2].Nonce()) ContractAddress = crypto.CreateAddress(SenderAddr, MockTransactions[2].Nonce())
ContractHash = crypto.Keccak256Hash(ContractAddress.Bytes()).String() ContractHash = crypto.Keccak256Hash(ContractAddress.Bytes()).String()
MockContractByteCode = []byte{0, 1, 2, 3, 4, 5} MockContractByteCode = []byte{0, 1, 2, 3, 4, 5}
@ -108,6 +109,7 @@ var (
mockTopic42 = common.HexToHash("0x0a") mockTopic42 = common.HexToHash("0x0a")
mockTopic43 = common.HexToHash("0x0b") mockTopic43 = common.HexToHash("0x0b")
mockTopic51 = common.HexToHash("0x0c") mockTopic51 = common.HexToHash("0x0c")
mockTopic61 = common.HexToHash("0x0d")
MockLog1 = &types.Log{ MockLog1 = &types.Log{
Address: Address, Address: Address,
Topics: []common.Hash{mockTopic11, mockTopic12}, Topics: []common.Hash{mockTopic11, mockTopic12},
@ -129,8 +131,8 @@ var (
Topics: []common.Hash{mockTopic31}, Topics: []common.Hash{mockTopic31},
Data: []byte{}, Data: []byte{},
BlockNumber: BlockNumber.Uint64(), BlockNumber: BlockNumber.Uint64(),
TxIndex: 1, TxIndex: 2,
Index: 1, Index: 2,
} }
MockLog4 = &types.Log{ MockLog4 = &types.Log{
@ -138,25 +140,35 @@ var (
Topics: []common.Hash{mockTopic41, mockTopic42, mockTopic43}, Topics: []common.Hash{mockTopic41, mockTopic42, mockTopic43},
Data: []byte{}, Data: []byte{},
BlockNumber: BlockNumber.Uint64(), BlockNumber: BlockNumber.Uint64(),
TxIndex: 1, TxIndex: 2,
Index: 1, Index: 3,
} }
MockLog5 = &types.Log{ MockLog5 = &types.Log{
Address: AnotherAddress1, Address: AnotherAddress1,
Topics: []common.Hash{mockTopic51}, Topics: []common.Hash{mockTopic51},
Data: []byte{}, Data: []byte{},
BlockNumber: BlockNumber.Uint64(), BlockNumber: BlockNumber.Uint64(),
TxIndex: 1, TxIndex: 2,
Index: 1, Index: 4,
}
MockLog6 = &types.Log{
Address: AnotherAddress2,
Topics: []common.Hash{mockTopic61},
Data: []byte{},
BlockNumber: BlockNumber.Uint64(),
TxIndex: 3,
Index: 5,
} }
Tx1 = GetTxnRlp(0, MockTransactions) Tx1 = GetTxnRlp(0, MockTransactions)
Tx2 = GetTxnRlp(1, MockTransactions) Tx2 = GetTxnRlp(1, MockTransactions)
Tx3 = GetTxnRlp(2, MockTransactions) Tx3 = GetTxnRlp(2, MockTransactions)
Tx4 = GetTxnRlp(3, MockTransactions)
Rct1 = GetRctRlp(0, MockReceipts) Rct1 = GetRctRlp(0, MockReceipts)
Rct2 = GetRctRlp(1, MockReceipts) Rct2 = GetRctRlp(1, MockReceipts)
Rct3 = GetRctRlp(2, MockReceipts) Rct3 = GetRctRlp(2, MockReceipts)
Rct4 = GetRctRlp(3, MockReceipts)
HeaderCID, _ = ipld.RawdataToCid(ipld.MEthHeader, MockHeaderRlp, multihash.KECCAK_256) HeaderCID, _ = ipld.RawdataToCid(ipld.MEthHeader, MockHeaderRlp, multihash.KECCAK_256)
HeaderMhKey = shared.MultihashKeyFromCID(HeaderCID) HeaderMhKey = shared.MultihashKeyFromCID(HeaderCID)
@ -166,12 +178,16 @@ var (
Trx2MhKey = shared.MultihashKeyFromCID(Trx2CID) Trx2MhKey = shared.MultihashKeyFromCID(Trx2CID)
Trx3CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx3, multihash.KECCAK_256) Trx3CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx3, multihash.KECCAK_256)
Trx3MhKey = shared.MultihashKeyFromCID(Trx3CID) Trx3MhKey = shared.MultihashKeyFromCID(Trx3CID)
Trx4CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx4, multihash.KECCAK_256)
Trx4MhKey = shared.MultihashKeyFromCID(Trx4CID)
Rct1CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct1, multihash.KECCAK_256) Rct1CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct1, multihash.KECCAK_256)
Rct1MhKey = shared.MultihashKeyFromCID(Rct1CID) Rct1MhKey = shared.MultihashKeyFromCID(Rct1CID)
Rct2CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct2, multihash.KECCAK_256) Rct2CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct2, multihash.KECCAK_256)
Rct2MhKey = shared.MultihashKeyFromCID(Rct2CID) Rct2MhKey = shared.MultihashKeyFromCID(Rct2CID)
Rct3CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct3, multihash.KECCAK_256) Rct3CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct3, multihash.KECCAK_256)
Rct3MhKey = shared.MultihashKeyFromCID(Rct3CID) Rct3MhKey = shared.MultihashKeyFromCID(Rct3CID)
Rct4CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct4, multihash.KECCAK_256)
Rct4MhKey = shared.MultihashKeyFromCID(Rct4CID)
State1CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, ContractLeafNode, multihash.KECCAK_256) State1CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, ContractLeafNode, multihash.KECCAK_256)
State1MhKey = shared.MultihashKeyFromCID(State1CID) State1MhKey = shared.MultihashKeyFromCID(State1CID)
State2CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, AccountLeafNode, multihash.KECCAK_256) State2CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, AccountLeafNode, multihash.KECCAK_256)
@ -206,6 +222,15 @@ var (
TxHash: MockTransactions[2].Hash().String(), TxHash: MockTransactions[2].Hash().String(),
Data: MockContractByteCode, Data: MockContractByteCode,
}, },
{
CID: "",
MhKey: "",
Src: SenderAddr.Hex(),
Dst: "",
Index: 3,
TxHash: MockTransactions[3].Hash().String(),
Data: []byte{},
},
} }
MockTrxMetaPostPublsh = []models.TxModel{ MockTrxMetaPostPublsh = []models.TxModel{
{ {
@ -235,6 +260,15 @@ var (
TxHash: MockTransactions[2].Hash().String(), TxHash: MockTransactions[2].Hash().String(),
Data: MockContractByteCode, Data: MockContractByteCode,
}, },
{
CID: Trx4CID.String(),
MhKey: Trx4MhKey,
Src: SenderAddr.Hex(),
Dst: "",
Index: 2,
TxHash: MockTransactions[2].Hash().String(),
Data: MockContractByteCode,
},
} }
MockRctMeta = []models.ReceiptModel{ MockRctMeta = []models.ReceiptModel{
{ {
@ -255,6 +289,12 @@ var (
Contract: ContractAddress.String(), Contract: ContractAddress.String(),
ContractHash: ContractHash, ContractHash: ContractHash,
}, },
{
CID: "",
MhKey: "",
Contract: "",
ContractHash: "",
},
} }
MockRctMetaPostPublish = []models.ReceiptModel{ MockRctMetaPostPublish = []models.ReceiptModel{
{ {
@ -275,6 +315,12 @@ var (
Contract: ContractAddress.String(), Contract: ContractAddress.String(),
ContractHash: ContractHash, ContractHash: ContractHash,
}, },
{
CID: Rct4CID.String(),
MhKey: Rct4MhKey,
Contract: "",
ContractHash: "",
},
} }
// statediff data // statediff data
@ -431,9 +477,11 @@ var (
Trx1IPLD, _ = blocks.NewBlockWithCid(Tx1, Trx1CID) Trx1IPLD, _ = blocks.NewBlockWithCid(Tx1, Trx1CID)
Trx2IPLD, _ = blocks.NewBlockWithCid(Tx2, Trx2CID) Trx2IPLD, _ = blocks.NewBlockWithCid(Tx2, Trx2CID)
Trx3IPLD, _ = blocks.NewBlockWithCid(Tx3, Trx3CID) Trx3IPLD, _ = blocks.NewBlockWithCid(Tx3, Trx3CID)
Trx4IPLD, _ = blocks.NewBlockWithCid(Tx4, Trx4CID)
Rct1IPLD, _ = blocks.NewBlockWithCid(Rct1, Rct1CID) Rct1IPLD, _ = blocks.NewBlockWithCid(Rct1, Rct1CID)
Rct2IPLD, _ = blocks.NewBlockWithCid(Rct2, Rct2CID) Rct2IPLD, _ = blocks.NewBlockWithCid(Rct2, Rct2CID)
Rct3IPLD, _ = blocks.NewBlockWithCid(Rct3, Rct3CID) Rct3IPLD, _ = blocks.NewBlockWithCid(Rct3, Rct3CID)
Rct4IPLD, _ = blocks.NewBlockWithCid(Rct4, Rct4CID)
State1IPLD, _ = blocks.NewBlockWithCid(ContractLeafNode, State1CID) State1IPLD, _ = blocks.NewBlockWithCid(ContractLeafNode, State1CID)
State2IPLD, _ = blocks.NewBlockWithCid(AccountLeafNode, State2CID) State2IPLD, _ = blocks.NewBlockWithCid(AccountLeafNode, State2CID)
StorageIPLD, _ = blocks.NewBlockWithCid(StorageLeafNode, StorageCID) StorageIPLD, _ = blocks.NewBlockWithCid(StorageLeafNode, StorageCID)
@ -457,6 +505,10 @@ var (
Data: Trx3IPLD.RawData(), Data: Trx3IPLD.RawData(),
CID: Trx3IPLD.Cid().String(), CID: Trx3IPLD.Cid().String(),
}, },
{
Data: Trx4IPLD.RawData(),
CID: Trx4IPLD.Cid().String(),
},
}, },
Receipts: []ipfs.BlockModel{ Receipts: []ipfs.BlockModel{
{ {
@ -471,6 +523,10 @@ var (
Data: Rct3IPLD.RawData(), Data: Rct3IPLD.RawData(),
CID: Rct3IPLD.Cid().String(), CID: Rct3IPLD.Cid().String(),
}, },
{
Data: Rct4IPLD.RawData(),
CID: Rct4IPLD.Cid().String(),
},
}, },
StateNodes: []eth.StateNode{ StateNodes: []eth.StateNode{
{ {
@ -584,6 +640,7 @@ func createLegacyTransactionsAndReceipts() (types.Transactions, types.Receipts,
trx1 := types.NewTransaction(0, Address, big.NewInt(1000), 50, big.NewInt(100), []byte{}) trx1 := types.NewTransaction(0, Address, big.NewInt(1000), 50, big.NewInt(100), []byte{})
trx2 := types.NewTransaction(1, AnotherAddress, big.NewInt(2000), 100, big.NewInt(200), []byte{}) trx2 := types.NewTransaction(1, AnotherAddress, big.NewInt(2000), 100, big.NewInt(200), []byte{})
trx3 := types.NewContractCreation(2, big.NewInt(1500), 75, big.NewInt(150), MockContractByteCode) trx3 := types.NewContractCreation(2, big.NewInt(1500), 75, big.NewInt(150), MockContractByteCode)
trx4 := types.NewTransaction(3, AnotherAddress1, big.NewInt(2000), 100, big.NewInt(200), []byte{})
transactionSigner := types.MakeSigner(params.MainnetChainConfig, new(big.Int).Set(BlockNumber)) transactionSigner := types.MakeSigner(params.MainnetChainConfig, new(big.Int).Set(BlockNumber))
mockCurve := elliptic.P256() mockCurve := elliptic.P256()
mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader) mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader)
@ -602,6 +659,10 @@ func createLegacyTransactionsAndReceipts() (types.Transactions, types.Receipts,
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
signedTrx4, err := types.SignTx(trx4, transactionSigner, mockPrvKey)
if err != nil {
log.Fatal(err)
}
SenderAddr, err := types.Sender(transactionSigner, signedTrx1) // same for both trx SenderAddr, err := types.Sender(transactionSigner, signedTrx1) // same for both trx
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -629,7 +690,13 @@ func createLegacyTransactionsAndReceipts() (types.Transactions, types.Receipts,
mockReceipt3.TxHash = signedTrx3.Hash() mockReceipt3.TxHash = signedTrx3.Hash()
mockReceipt3.GasUsed = mockReceipt3.CumulativeGasUsed - mockReceipt2.CumulativeGasUsed mockReceipt3.GasUsed = mockReceipt3.CumulativeGasUsed - mockReceipt2.CumulativeGasUsed
return types.Transactions{signedTrx1, signedTrx2, signedTrx3}, types.Receipts{mockReceipt1, mockReceipt2, mockReceipt3}, SenderAddr // Receipt with failed status.
mockReceipt4 := types.NewReceipt(nil, true, 250)
mockReceipt4.Logs = []*types.Log{MockLog6}
mockReceipt4.TxHash = signedTrx4.Hash()
mockReceipt4.GasUsed = mockReceipt4.CumulativeGasUsed - mockReceipt3.CumulativeGasUsed
return types.Transactions{signedTrx1, signedTrx2, signedTrx3, signedTrx4}, types.Receipts{mockReceipt1, mockReceipt2, mockReceipt3, mockReceipt4}, SenderAddr
} }
func GetTxnRlp(num int, txs types.Transactions) []byte { func GetTxnRlp(num int, txs types.Transactions) []byte {

View File

@ -167,8 +167,8 @@ type ConvertedPayload struct {
StorageNodes map[string][]sdtypes.StorageNode StorageNodes map[string][]sdtypes.StorageNode
} }
// logResult represent a log. // LogResult represent a log.
type logResult struct { type LogResult struct {
ID int64 `db:"id"` ID int64 `db:"id"`
LeafCID string `db:"leaf_cid"` LeafCID string `db:"leaf_cid"`
LeafMhKey string `db:"leaf_mh_key"` LeafMhKey string `db:"leaf_mh_key"`
@ -180,7 +180,7 @@ type logResult struct {
Topic1 string `db:"topic1"` Topic1 string `db:"topic1"`
Topic2 string `db:"topic2"` Topic2 string `db:"topic2"`
Topic3 string `db:"topic3"` Topic3 string `db:"topic3"`
RctData []byte `db:"data"` LogLeafData []byte `db:"data"`
RctCID string `db:"cid"` RctCID string `db:"cid"`
RctStatus uint64 `db:"post_status"` RctStatus uint64 `db:"post_status"`
BlockNumber string `db:"block_number"` BlockNumber string `db:"block_number"`

View File

@ -24,6 +24,7 @@ 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"` Transaction TransactionResp `json:"transaction"`
ReceiptCID string `json:"receiptCID"`
Status int32 `json:"status"` Status int32 `json:"status"`
} }
@ -54,6 +55,7 @@ func (c *Client) GetLogs(ctx context.Context, hash common.Hash, address common.A
hash hash
} }
status status
receiptCID
} }
} }
`, hash.String(), address.String()) `, hash.String(), address.String())

View File

@ -94,15 +94,17 @@ type Log struct {
log *types.Log log *types.Log
cid string cid string
receiptCID string receiptCID string
ipldBlock []byte ipldBlock []byte // log leaf node IPLD block data
status uint64 status uint64
} }
func (l *Log) Transaction(ctx context.Context) *Transaction { // Transaction returns transaction that generated this log entry.
func (l *Log) Transaction(_ context.Context) *Transaction {
return l.transaction return l.transaction
} }
func (l *Log) Account(ctx context.Context, args BlockNumberArgs) *Account { // Account returns the contract account which generated this log.
func (l *Log) Account(_ context.Context, args BlockNumberArgs) *Account {
return &Account{ return &Account{
backend: l.backend, backend: l.backend,
address: l.log.Address, address: l.log.Address,
@ -110,30 +112,41 @@ func (l *Log) Account(ctx context.Context, args BlockNumberArgs) *Account {
} }
} }
func (l *Log) Index(ctx context.Context) int32 { // Index returns the index of this log in the block
func (l *Log) Index(_ context.Context) int32 {
return int32(l.log.Index) return int32(l.log.Index)
} }
func (l *Log) Topics(ctx context.Context) []common.Hash { // Topics returns the list of 0-4 indexed topics for the log.
func (l *Log) Topics(_ context.Context) []common.Hash {
return l.log.Topics return l.log.Topics
} }
func (l *Log) Data(ctx context.Context) hexutil.Bytes { // Data returns data of this log.
return hexutil.Bytes(l.log.Data) func (l *Log) Data(_ context.Context) hexutil.Bytes {
return l.log.Data
} }
func (l *Log) Cid(ctx context.Context) string { // Cid returns cid of the leaf node of this log.
func (l *Log) Cid(_ context.Context) string {
return l.cid return l.cid
} }
func (l *Log) IpldBlock(ctx context.Context) hexutil.Bytes { // IpldBlock returns IPLD block of the leaf node of this log.
return hexutil.Bytes(l.ipldBlock) func (l *Log) IpldBlock(_ context.Context) hexutil.Bytes {
return l.ipldBlock
} }
func (l *Log) Status(ctx context.Context) int32 { // Status returns the status of the receipt IPLD block this Log exists in.
func (l *Log) Status(_ context.Context) int32 {
return int32(l.status) return int32(l.status)
} }
// ReceiptCID returns the receipt CID of the receipt IPLD block this Log exists in.
func (l *Log) ReceiptCID(_ context.Context) string {
return l.receiptCID
}
// Transaction represents an Ethereum transaction. // Transaction represents an Ethereum transaction.
// backend and hash are mandatory; all others will be fetched when required. // backend and hash are mandatory; all others will be fetched when required.
type Transaction struct { type Transaction struct {
@ -1033,7 +1046,7 @@ func (r *Resolver) GetLogs(ctx context.Context, args struct {
return nil, err return nil, err
} }
rctLog, err := r.backend.Fetcher.FetchGQLLogs(filteredLogs) rctLog := decomposeGQLLogs(filteredLogs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1044,7 +1057,7 @@ func (r *Resolver) GetLogs(ctx context.Context, args struct {
log: l.Log, log: l.Log,
cid: l.CID, cid: l.CID,
receiptCID: l.RctCID, receiptCID: l.RctCID,
ipldBlock: l.RctData, ipldBlock: l.LogLeafData,
transaction: &Transaction{ transaction: &Transaction{
hash: l.Log.TxHash, hash: l.Log.TxHash,
}, },
@ -1054,3 +1067,47 @@ func (r *Resolver) GetLogs(ctx context.Context, args struct {
return &ret, nil return &ret, nil
} }
type logsCID struct {
Log *types.Log
CID string
RctCID string
LogLeafData []byte
RctStatus uint64
}
// decomposeGQLLogs return logs for graphql.
func decomposeGQLLogs(logCIDs []eth.LogResult) []logsCID {
logs := make([]logsCID, len(logCIDs))
for i, l := range logCIDs {
topics := make([]common.Hash, 0)
if l.Topic0 != "" {
topics = append(topics, common.HexToHash(l.Topic0))
}
if l.Topic1 != "" {
topics = append(topics, common.HexToHash(l.Topic1))
}
if l.Topic2 != "" {
topics = append(topics, common.HexToHash(l.Topic2))
}
if l.Topic3 != "" {
topics = append(topics, common.HexToHash(l.Topic3))
}
logs[i] = logsCID{
Log: &types.Log{
Address: common.HexToAddress(l.Address),
Topics: topics,
Data: l.Data,
Index: uint(l.Index),
TxHash: common.HexToHash(l.TxHash),
},
CID: l.LeafCID,
RctCID: l.RctCID,
LogLeafData: l.LogLeafData,
RctStatus: l.RctStatus,
}
}
return logs
}

View File

@ -191,9 +191,28 @@ var _ = Describe("GraphQL", func() {
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()}, Transaction: graphql.TransactionResp{Hash: test_helpers.MockTransactions[0].Hash()},
ReceiptCID: test_helpers.Rct1CID.String(),
Status: int32(test_helpers.MockReceipts[0].Status), Status: int32(test_helpers.MockReceipts[0].Status),
}, },
} }
Expect(logs).To(Equal(expectedLogs))
})
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)
Expect(err).ToNot(HaveOccurred())
expectedLogs := []graphql.LogResponse{
{
Topics: test_helpers.MockLog6.Topics,
Data: hexutil.Bytes(test_helpers.MockLog6.Data),
Transaction: graphql.TransactionResp{Hash: test_helpers.MockTransactions[3].Hash()},
ReceiptCID: test_helpers.Rct4CID.String(),
Status: int32(test_helpers.MockReceipts[3].Status),
},
}
Expect(logs).To(Equal(expectedLogs)) Expect(logs).To(Equal(expectedLogs))
}) })

View File

@ -67,14 +67,17 @@ const schema string = `
# Transaction is the transaction that generated this log entry. # Transaction is the transaction that generated this log entry.
transaction: Transaction transaction: Transaction
# CID for the Receipt IPLD block this Log exists in. # CID for the Receipt IPLD block of leaf node.
cid: String! cid: String!
# IPLD block data for the Receipt this Log exists in. # ReceiptCID for the Receipt IPLD block this Log exists in.
receiptCID: String!
# IPLD block data for the Log Leaf node.
ipldBlock: Bytes! ipldBlock: Bytes!
# Status of the Receipt IPLD block this Log exists in. # Status of the Receipt IPLD block this Log exists in.
status: Int! status: Int!
} }
# Transaction is an Ethereum transaction. # Transaction is an Ethereum transaction.