From f144d932cdecc4a11c86ad4aed3c8b850fe26a07 Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Wed, 25 May 2022 18:43:53 +0530 Subject: [PATCH 01/13] Implement graphql query to get header with transactions --- pkg/eth/cid_retriever.go | 85 ++++++++++++++++++++++- pkg/graphql/graphql.go | 142 ++++++++++++++++++++++++++++++++++++++- pkg/graphql/schema.go | 72 ++++++++++++++------ 3 files changed, 277 insertions(+), 22 deletions(-) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index bcebcde7..0872d76d 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -576,7 +576,7 @@ func (ecr *CIDRetriever) RetrieveBlockByNumber(blockNumber int64) (models.Header // RetrieveHeaderCIDByHash returns the header for the given block hash func (ecr *CIDRetriever) RetrieveHeaderCIDByHash(tx *sqlx.Tx, blockHash common.Hash) (models.HeaderModel, error) { log.Debug("retrieving header cids for block hash ", blockHash.String()) - pgStr := `SELECT block_hash,cid,mh_key FROM eth.header_cids + pgStr := `SELECT block_hash, CAST(block_number as Text), parent_hash, cid, mh_key, timestamp FROM eth.header_cids WHERE block_hash = $1` var headerCID models.HeaderModel return headerCID, tx.Get(&headerCID, pgStr, blockHash.String()) @@ -604,3 +604,86 @@ func (ecr *CIDRetriever) RetrieveReceiptCIDsByTxIDs(tx *sqlx.Tx, txHashes []stri var rctCIDs []models.ReceiptModel return rctCIDs, tx.Select(&rctCIDs, pgStr, pq.Array(txHashes)) } + +func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]models.HeaderModel, [][]models.TxModel, error) { + log.Debug("retrieving header cids and tx cids for block number ", blockNumber) + + // Begin new db tx + tx, err := ecr.db.Beginx() + if err != nil { + return nil, nil, err + } + defer func() { + if p := recover(); p != nil { + shared.Rollback(tx) + panic(p) + } else if err != nil { + shared.Rollback(tx) + } else { + err = tx.Commit() + } + }() + + var headerCIDs []models.HeaderModel + headerCIDs, err = ecr.RetrieveHeaderCIDs(tx, blockNumber) + if err != nil { + log.Error("header cid retrieval error") + return nil, nil, err + } + if len(headerCIDs) < 1 { + return nil, nil, fmt.Errorf("header cid retrieval error, no header CIDs found at block %d", blockNumber) + } + + var allTxCIDs [][]models.TxModel + for _, headerCID := range headerCIDs { + var txCIDs []models.TxModel + txCIDs, err = ecr.RetrieveTxCIDsByHeaderID(tx, headerCID.BlockHash) + if err != nil { + log.Error("tx cid retrieval error") + return nil, nil, err + } + allTxCIDs = append(allTxCIDs, txCIDs) + } + + return headerCIDs, allTxCIDs, nil +} + +func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash) (models.HeaderModel, []models.TxModel, error) { + log.Debug("retrieving header cid and tx cids for block hash ", blockHash.String()) + + // Begin new db tx + tx, err := ecr.db.Beginx() + if err != nil { + return models.HeaderModel{}, nil, err + } + defer func() { + if p := recover(); p != nil { + shared.Rollback(tx) + panic(p) + } else if err != nil { + shared.Rollback(tx) + } else { + err = tx.Commit() + } + }() + + var headerCID models.HeaderModel + headerCID, err = ecr.RetrieveHeaderCIDByHash(tx, blockHash) + if err != nil { + log.Error("header cid retrieval error") + return models.HeaderModel{}, nil, err + } + if err != nil { + return models.HeaderModel{}, nil, err + } + fmt.Println("RetrieveHeaderAndTxCIDsByBlockHash", headerCID.ParentHash, headerCID.Timestamp) + + var txCIDs []models.TxModel + txCIDs, err = ecr.RetrieveTxCIDsByHeaderID(tx, headerCID.BlockHash) + if err != nil { + log.Error("tx cid retrieval error") + return models.HeaderModel{}, nil, err + } + + return headerCID, txCIDs, nil +} diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 465bf286..588261e6 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -22,6 +22,8 @@ import ( "context" "database/sql" "errors" + "fmt" + "math/big" "time" "github.com/ethereum/go-ethereum/common" @@ -32,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/statediff/indexer/models" "github.com/vulcanize/ipld-eth-server/v3/pkg/eth" ) @@ -1017,7 +1020,7 @@ func (r *Resolver) GetStorageAt(ctx context.Context, args struct { return nil, err } - if bytes.Compare(rlpValue, eth.EmptyNodeValue) == 0 { + if bytes.Equal(rlpValue, eth.EmptyNodeValue) { return &StorageResult{value: eth.EmptyNodeValue, cid: cid, ipldBlock: ipldBlock}, nil } @@ -1122,3 +1125,140 @@ func decomposeGQLLogs(logCIDs []eth.LogResult) []logsCID { return logs } + +type EthTransactionCid struct { + cid string + txHash string + index int32 + src string + dst string +} + +func (t EthTransactionCid) Cid(ctx context.Context) string { + return t.cid +} + +func (t EthTransactionCid) TxHash(ctx context.Context) string { + return t.txHash +} + +func (t EthTransactionCid) Index(ctx context.Context) int32 { + return t.index +} + +func (t EthTransactionCid) Src(ctx context.Context) string { + return t.src +} + +func (t EthTransactionCid) Dst(ctx context.Context) string { + return t.dst +} + +type EthTransactionCidsConnection struct { + nodes []*EthTransactionCid +} + +func (transactionCIDResult EthTransactionCidsConnection) Nodes(ctx context.Context) []*EthTransactionCid { + return transactionCIDResult.nodes +} + +type EthHeaderCid struct { + cid string + blockNumber hexutil.Uint64 + blockHash string + parentHash string + timestamp hexutil.Uint64 + transactions []*EthTransactionCid +} + +func (h EthHeaderCid) Cid(ctx context.Context) string { + return h.cid +} + +func (h EthHeaderCid) BlockNumber(ctx context.Context) hexutil.Uint64 { + return h.blockNumber +} + +func (h EthHeaderCid) BlockHash(ctx context.Context) string { + return h.blockHash +} + +func (h EthHeaderCid) ParentHash(ctx context.Context) string { + return h.parentHash +} + +func (h EthHeaderCid) Timestamp(ctx context.Context) hexutil.Uint64 { + return h.timestamp +} + +func (h EthHeaderCid) EthTransactionCidsByHeaderId(ctx context.Context) EthTransactionCidsConnection { + return EthTransactionCidsConnection{nodes: h.transactions} +} + +type EthHeaderCidsConnection struct { + nodes []*EthHeaderCid +} + +func (headerCIDResult EthHeaderCidsConnection) Nodes(ctx context.Context) []*EthHeaderCid { + return headerCIDResult.nodes +} + +type EthHeaderCidCondition struct { + BlockNumber *hexutil.Big + BlockHash *string +} + +func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { + Condition *EthHeaderCidCondition +}) (*EthHeaderCidsConnection, error) { + var headerCIDs []models.HeaderModel + var allTxCIDs [][]models.TxModel + var err error + if args.Condition.BlockHash != nil { + headerCID, txCIDs, err := r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(common.HexToHash(*args.Condition.BlockHash)) + if err != nil { + return nil, err + } + + headerCIDs = append(headerCIDs, headerCID) + allTxCIDs = append(allTxCIDs, txCIDs) + } else if args.Condition.BlockNumber != nil { + headerCIDs, allTxCIDs, err = r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockNumber(args.Condition.BlockNumber.ToInt().Int64()) + if err != nil { + return nil, err + } + } else { + return nil, fmt.Errorf("provide block number or block hash") + } + + var resultNodes []*EthHeaderCid + for idx, headerCID := range headerCIDs { + blockNumber := new(big.Int) + blockNumber.SetString(headerCID.BlockNumber, 10) + + ethHeaderCidNode := EthHeaderCid{ + cid: headerCID.CID, + blockNumber: hexutil.Uint64(blockNumber.Uint64()), + blockHash: headerCID.BlockHash, + parentHash: headerCID.ParentHash, + timestamp: hexutil.Uint64(headerCID.Timestamp), + } + + txCIDs := allTxCIDs[idx] + for _, txCID := range txCIDs { + ethHeaderCidNode.transactions = append(ethHeaderCidNode.transactions, &EthTransactionCid{ + cid: txCID.CID, + txHash: txCID.TxHash, + index: int32(txCID.Index), + src: txCID.Src, + dst: txCID.Dst, + }) + } + + resultNodes = append(resultNodes, ðHeaderCidNode) + } + + return &EthHeaderCidsConnection{ + nodes: resultNodes, + }, nil +} diff --git a/pkg/graphql/schema.go b/pkg/graphql/schema.go index b70765ac..f85d489a 100644 --- a/pkg/graphql/schema.go +++ b/pkg/graphql/schema.go @@ -138,16 +138,16 @@ const schema string = ` # empty, results will not be filtered by address. addresses: [Address!] # Topics list restricts matches to particular event topics. Each event has a list - # of topics. Topics matches a prefix of that list. An empty element array matches any - # topic. Non-empty elements represent an alternative that matches any of the - # contained topics. - # - # Examples: - # - [] or nil matches any topic list - # - [[A]] matches topic A in first position - # - [[], [B]] matches any topic in first position, B in second position - # - [[A], [B]] matches topic A in first position, B in second position - # - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position + # of topics. Topics matches a prefix of that list. An empty element array matches any + # topic. Non-empty elements represent an alternative that matches any of the + # contained topics. + # + # Examples: + # - [] or nil matches any topic list + # - [[A]] matches topic A in first position + # - [[], [B]] matches any topic in first position, B in second position + # - [[A], [B]] matches topic A in first position, B in second position + # - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position topics: [[Bytes32!]!] } @@ -258,16 +258,16 @@ const schema string = ` # empty, results will not be filtered by address. addresses: [Address!] # Topics list restricts matches to particular event topics. Each event has a list - # of topics. Topics matches a prefix of that list. An empty element array matches any - # topic. Non-empty elements represent an alternative that matches any of the - # contained topics. - # - # Examples: - # - [] or nil matches any topic list - # - [[A]] matches topic A in first position - # - [[], [B]] matches any topic in first position, B in second position - # - [[A], [B]] matches topic A in first position, B in second position - # - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position + # of topics. Topics matches a prefix of that list. An empty element array matches any + # topic. Non-empty elements represent an alternative that matches any of the + # contained topics. + # + # Examples: + # - [] or nil matches any topic list + # - [[A]] matches topic A in first position + # - [[], [B]] matches any topic in first position, B in second position + # - [[A], [B]] matches topic A in first position, B in second position + # - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position topics: [[Bytes32!]!] } @@ -282,6 +282,36 @@ const schema string = ` ipldBlock: Bytes! } + input EthHeaderCidCondition { + blockNumber: BigInt + blockHash: String + } + + type EthTransactionCid { + cid: String! + txHash: String! + index: Int! + src: String! + dst: String! + } + + type EthTransactionCidsConnection { + nodes: [EthTransactionCid]! + } + + type EthHeaderCid { + cid: String! + blockNumber: Long! + blockHash: String! + parentHash: String! + timestamp: Long! + ethTransactionCidsByHeaderId: EthTransactionCidsConnection! + } + + type EthHeaderCidsConnection { + nodes: [EthHeaderCid]! + } + type Query { # Block fetches an Ethereum block by number or by hash. If neither is # supplied, the most recent known block is returned. @@ -302,5 +332,7 @@ const schema string = ` # Get contract logs by block hash and contract address. getLogs(blockHash: Bytes32!, contract: Address): [Log!] + + allEthHeaderCids(condition: EthHeaderCidCondition): EthHeaderCidsConnection } ` -- 2.45.2 From fe7329c2844a5a685c6a66bf350e8dca04fdbf4b Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Thu, 26 May 2022 19:57:23 +0530 Subject: [PATCH 02/13] Add custom implementation for graphql scalar BigInt --- pkg/graphql/graphql.go | 22 +++++----- pkg/graphql/schema.go | 8 ++-- pkg/graphql/types.go | 94 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 pkg/graphql/types.go diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 588261e6..44738003 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -23,7 +23,6 @@ import ( "database/sql" "errors" "fmt" - "math/big" "time" "github.com/ethereum/go-ethereum/common" @@ -1164,10 +1163,10 @@ func (transactionCIDResult EthTransactionCidsConnection) Nodes(ctx context.Conte type EthHeaderCid struct { cid string - blockNumber hexutil.Uint64 + blockNumber BigInt blockHash string parentHash string - timestamp hexutil.Uint64 + timestamp BigInt transactions []*EthTransactionCid } @@ -1175,7 +1174,7 @@ func (h EthHeaderCid) Cid(ctx context.Context) string { return h.cid } -func (h EthHeaderCid) BlockNumber(ctx context.Context) hexutil.Uint64 { +func (h EthHeaderCid) BlockNumber(ctx context.Context) BigInt { return h.blockNumber } @@ -1187,7 +1186,7 @@ func (h EthHeaderCid) ParentHash(ctx context.Context) string { return h.parentHash } -func (h EthHeaderCid) Timestamp(ctx context.Context) hexutil.Uint64 { +func (h EthHeaderCid) Timestamp(ctx context.Context) BigInt { return h.timestamp } @@ -1204,7 +1203,7 @@ func (headerCIDResult EthHeaderCidsConnection) Nodes(ctx context.Context) []*Eth } type EthHeaderCidCondition struct { - BlockNumber *hexutil.Big + BlockNumber *BigInt BlockHash *string } @@ -1233,15 +1232,18 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { var resultNodes []*EthHeaderCid for idx, headerCID := range headerCIDs { - blockNumber := new(big.Int) - blockNumber.SetString(headerCID.BlockNumber, 10) + var blockNumber BigInt + blockNumber.UnmarshalText([]byte(headerCID.BlockNumber)) + + var timestamp BigInt + timestamp.SetUint64(headerCID.Timestamp) ethHeaderCidNode := EthHeaderCid{ cid: headerCID.CID, - blockNumber: hexutil.Uint64(blockNumber.Uint64()), + blockNumber: blockNumber, blockHash: headerCID.BlockHash, parentHash: headerCID.ParentHash, - timestamp: hexutil.Uint64(headerCID.Timestamp), + timestamp: timestamp, } txCIDs := allTxCIDs[idx] diff --git a/pkg/graphql/schema.go b/pkg/graphql/schema.go index f85d489a..b8f5ef6d 100644 --- a/pkg/graphql/schema.go +++ b/pkg/graphql/schema.go @@ -25,8 +25,7 @@ const schema string = ` # An empty byte string is represented as '0x'. Byte strings must have an even number of hexadecimal nybbles. scalar Bytes # BigInt is a large integer. Input is accepted as either a JSON number or as a string. - # Strings may be either decimal or 0x-prefixed hexadecimal. Output values are all - # 0x-prefixed hexadecimal. + # Input and output strings may be either decimal or 0x-prefixed hexadecimal depending upon the resolver implementation. scalar BigInt # Long is a 64 bit unsigned integer. scalar Long @@ -301,10 +300,10 @@ const schema string = ` type EthHeaderCid { cid: String! - blockNumber: Long! + blockNumber: BigInt! blockHash: String! parentHash: String! - timestamp: Long! + timestamp: BigInt! ethTransactionCidsByHeaderId: EthTransactionCidsConnection! } @@ -333,6 +332,7 @@ const schema string = ` # Get contract logs by block hash and contract address. getLogs(blockHash: Bytes32!, contract: Address): [Log!] + # PostGraphile alternative to get headers with transactions using block number or block hash. allEthHeaderCids(condition: EthHeaderCidCondition): EthHeaderCidsConnection } ` diff --git a/pkg/graphql/types.go b/pkg/graphql/types.go new file mode 100644 index 00000000..2756070d --- /dev/null +++ b/pkg/graphql/types.go @@ -0,0 +1,94 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package graphql + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common/hexutil" +) + +type BigInt big.Int + +// ToInt converts b to a big.Int. +func (b *BigInt) ToInt() *big.Int { + return (*big.Int)(b) +} + +// String returns value of b as a decimal string. +func (b *BigInt) String() string { + return b.ToInt().String() +} + +// SetUint64 sets b to x and returns x. +func (b *BigInt) SetUint64(x uint64) *BigInt { + var val big.Int + val.SetUint64(x) + *b = (BigInt)(val) + return b +} + +// MarshalText implements encoding.TextMarshaler +func (b BigInt) MarshalText() ([]byte, error) { + return []byte(b.String()), nil +} + +// UnmarshalText implements encoding.TextUnmarshaler +func (b *BigInt) UnmarshalText(input []byte) error { + raw, err := checkNumberText(input) + if err != nil { + return err + } + if len(raw) > 64 { + return hexutil.ErrBig256Range + } + + var val big.Int + val.SetString(string(input[:]), 10) + *b = (BigInt)(val) + return nil +} + +// ImplementsGraphQLType returns true if BigInt implements the provided GraphQL type. +func (b BigInt) ImplementsGraphQLType(name string) bool { return name == "BigInt" } + +// UnmarshalGraphQL unmarshals the provided GraphQL query data. +func (b *BigInt) UnmarshalGraphQL(input interface{}) error { + var err error + switch input := input.(type) { + case string: + return b.UnmarshalText([]byte(input)) + case int32: + var num big.Int + num.SetInt64(int64(input)) + *b = BigInt(num) + default: + err = fmt.Errorf("unexpected type %T for BigInt", input) + } + return err +} + +func checkNumberText(input []byte) (raw []byte, err error) { + if len(input) == 0 { + return nil, nil // empty strings are allowed + } + if len(input) > 1 && input[0] == '0' { + return nil, hexutil.ErrLeadingZero + } + return input, nil +} -- 2.45.2 From da1c8b233206f060cd8c256d02be6875a9342ce9 Mon Sep 17 00:00:00 2001 From: nabarun Date: Fri, 27 May 2022 19:16:10 +0530 Subject: [PATCH 03/13] Implement single query for transactions and blockByMhKey --- go.mod | 1 + pkg/eth/cid_retriever.go | 42 +++++++++++++++++++---- pkg/eth/ipld_fetcher.go | 36 +++++++++++++++++++- pkg/graphql/graphql.go | 73 ++++++++++++++++++++++++++++++++++++++++ pkg/graphql/schema.go | 17 ++++++++++ pkg/shared/functions.go | 14 ++++++++ 6 files changed, 175 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 43e74ba9..cfc23a2b 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.11.0 github.com/vulcanize/eth-ipfs-state-validator/v3 v3.0.2 + github.com/thoas/go-funk v0.9.2 github.com/vulcanize/gap-filler v0.3.1 github.com/vulcanize/ipfs-ethdb/v3 v3.0.3 ) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index 0872d76d..dc77608c 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -26,6 +26,7 @@ import ( "github.com/jmoiron/sqlx" "github.com/lib/pq" log "github.com/sirupsen/logrus" + "github.com/thoas/go-funk" "github.com/vulcanize/ipld-eth-server/v3/pkg/shared" ) @@ -592,6 +593,17 @@ func (ecr *CIDRetriever) RetrieveTxCIDsByHeaderID(tx *sqlx.Tx, headerID string) return txCIDs, tx.Select(&txCIDs, pgStr, headerID) } +func (ecr *CIDRetriever) RetrieveTxCIDsByBlockNumber(tx *sqlx.Tx, blockNumber int64) ([]models.TxModel, error) { + log.Debug("retrieving tx cids for block number ", blockNumber) + pgStr := `SELECT CAST(block_number as Text), header_id, index, tx_hash, cid, mh_key, + dst, src, tx_data, tx_type, value + FROM eth.transaction_cids + WHERE block_number = $1 + ORDER BY index` + var txCIDs []models.TxModel + return txCIDs, tx.Select(&txCIDs, pgStr, blockNumber) +} + // RetrieveReceiptCIDsByTxIDs retrieves receipt CIDs by their associated tx IDs func (ecr *CIDRetriever) RetrieveReceiptCIDsByTxIDs(tx *sqlx.Tx, txHashes []string) ([]models.ReceiptModel, error) { log.Debugf("retrieving receipt cids for tx hashes %v", txHashes) @@ -635,13 +647,30 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) } var allTxCIDs [][]models.TxModel + txCIDs, err := ecr.RetrieveTxCIDsByBlockNumber(tx, blockNumber) + if err != nil { + log.Error("tx cid retrieval error") + return nil, nil, err + } + + txCIDsByHeaderID := funk.Reduce( + txCIDs, + func(acc map[string][]models.TxModel, txCID models.TxModel) map[string][]models.TxModel { + if _, ok := acc[txCID.HeaderID]; !ok { + acc[txCID.HeaderID] = []models.TxModel{} + } + + txCIDs = append(acc[txCID.HeaderID], txCID) + acc[txCID.HeaderID] = txCIDs + return acc + }, + make(map[string][]models.TxModel), + ) + + txCIDsByHeaderIDMap := txCIDsByHeaderID.(map[string][]models.TxModel) + for _, headerCID := range headerCIDs { - var txCIDs []models.TxModel - txCIDs, err = ecr.RetrieveTxCIDsByHeaderID(tx, headerCID.BlockHash) - if err != nil { - log.Error("tx cid retrieval error") - return nil, nil, err - } + txCIDs := txCIDsByHeaderIDMap[headerCID.BlockHash] allTxCIDs = append(allTxCIDs, txCIDs) } @@ -676,7 +705,6 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Has if err != nil { return models.HeaderModel{}, nil, err } - fmt.Println("RetrieveHeaderAndTxCIDsByBlockHash", headerCID.ParentHash, headerCID.Timestamp) var txCIDs []models.TxModel txCIDs, err = ecr.RetrieveTxCIDsByHeaderID(tx, headerCID.BlockHash) diff --git a/pkg/eth/ipld_fetcher.go b/pkg/eth/ipld_fetcher.go index 8396d368..6b191eb8 100644 --- a/pkg/eth/ipld_fetcher.go +++ b/pkg/eth/ipld_fetcher.go @@ -20,11 +20,13 @@ import ( "errors" "fmt" "math/big" + "strconv" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/statediff/indexer/models" "github.com/jmoiron/sqlx" log "github.com/sirupsen/logrus" + "github.com/thoas/go-funk" "github.com/vulcanize/ipld-eth-server/v3/pkg/shared" ) @@ -99,7 +101,7 @@ func (f *IPLDFetcher) Fetch(cids CIDWrapper) (*IPLDs, error) { return iplds, err } -// FetchHeaders fetches headers +// FetchHeader fetches header func (f *IPLDFetcher) FetchHeader(tx *sqlx.Tx, c models.HeaderModel) (models.IPLDModel, error) { log.Debug("fetching header ipld") headerBytes, err := shared.FetchIPLDByMhKey(tx, c.MhKey) @@ -112,6 +114,38 @@ func (f *IPLDFetcher) FetchHeader(tx *sqlx.Tx, c models.HeaderModel) (models.IPL }, nil } +// FetchHeaders fetches headers +func (f *IPLDFetcher) FetchHeaders(tx *sqlx.Tx, cids []models.HeaderModel) ([]models.IPLDModel, error) { + log.Debug("fetching header iplds") + headerIPLDs := make([]models.IPLDModel, len(cids)) + + blockNumbers := make([]uint64, len(cids)) + mhKeys := make([]string, len(cids)) + for i, c := range cids { + var err error + mhKeys[i] = c.MhKey + blockNumbers[i], err = strconv.ParseUint(c.BlockNumber, 10, 64) + if err != nil { + return nil, err + } + } + + fetchedIPLDs, err := shared.FetchIPLDsByMhKeysAndBlockNumbers(tx, mhKeys, blockNumbers) + if err != nil { + return nil, err + } + + for i, c := range cids { + headerIPLD := funk.Find(fetchedIPLDs, func(ipld models.IPLDModel) bool { + return ipld.Key == c.MhKey + }).(models.IPLDModel) + + headerIPLDs[i] = headerIPLD + } + + return headerIPLDs, nil +} + // FetchUncles fetches uncles func (f *IPLDFetcher) FetchUncles(tx *sqlx.Tx, cids []models.UncleModel) ([]models.IPLDModel, error) { log.Debug("fetching uncle iplds") diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 44738003..2de90c46 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -1161,13 +1161,33 @@ func (transactionCIDResult EthTransactionCidsConnection) Nodes(ctx context.Conte return transactionCIDResult.nodes } +type IPFSBlock struct { + key string + data string +} + +func (b IPFSBlock) Key(ctx context.Context) string { + return b.key +} + +func (b IPFSBlock) Data(ctx context.Context) string { + return b.data +} + type EthHeaderCid struct { cid string blockNumber BigInt blockHash string parentHash string timestamp BigInt + stateRoot string + td BigInt + txRoot string + receiptRoot string + uncleRoot string + bloom string transactions []*EthTransactionCid + ipfsBlock IPFSBlock } func (h EthHeaderCid) Cid(ctx context.Context) string { @@ -1190,10 +1210,38 @@ func (h EthHeaderCid) Timestamp(ctx context.Context) BigInt { return h.timestamp } +func (h EthHeaderCid) StateRoot(ctx context.Context) string { + return h.stateRoot +} + +func (h EthHeaderCid) Td(ctx context.Context) BigInt { + return h.td +} + +func (h EthHeaderCid) TxRoot(ctx context.Context) string { + return h.txRoot +} + +func (h EthHeaderCid) ReceiptRoot(ctx context.Context) string { + return h.receiptRoot +} + +func (h EthHeaderCid) UncleRoot(ctx context.Context) string { + return h.uncleRoot +} + +func (h EthHeaderCid) Bloom(ctx context.Context) string { + return h.bloom +} + func (h EthHeaderCid) EthTransactionCidsByHeaderId(ctx context.Context) EthTransactionCidsConnection { return EthTransactionCidsConnection{nodes: h.transactions} } +func (h EthHeaderCid) BlockByMhKey(ctx context.Context) IPFSBlock { + return h.ipfsBlock +} + type EthHeaderCidsConnection struct { nodes []*EthHeaderCid } @@ -1230,6 +1278,17 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { return nil, fmt.Errorf("provide block number or block hash") } + // Begin tx + tx, err := r.backend.DB.Beginx() + if err != nil { + return nil, err + } + + headerIPLDs, err := r.backend.Fetcher.FetchHeaders(tx, headerCIDs) + if err != nil { + return nil, err + } + var resultNodes []*EthHeaderCid for idx, headerCID := range headerCIDs { var blockNumber BigInt @@ -1238,12 +1297,21 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { var timestamp BigInt timestamp.SetUint64(headerCID.Timestamp) + var td BigInt + td.UnmarshalText([]byte(headerCID.TotalDifficulty)) + ethHeaderCidNode := EthHeaderCid{ cid: headerCID.CID, blockNumber: blockNumber, blockHash: headerCID.BlockHash, parentHash: headerCID.ParentHash, timestamp: timestamp, + stateRoot: headerCID.StateRoot, + td: td, + txRoot: headerCID.TxRoot, + receiptRoot: headerCID.RctRoot, + uncleRoot: headerCID.UncleRoot, + bloom: hexutil.Bytes(headerCID.Bloom).String(), } txCIDs := allTxCIDs[idx] @@ -1257,6 +1325,11 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { }) } + ethHeaderCidNode.ipfsBlock = IPFSBlock{ + key: headerIPLDs[idx].Key, + data: hexutil.Bytes(headerIPLDs[idx].Data).String(), + } + resultNodes = append(resultNodes, ðHeaderCidNode) } diff --git a/pkg/graphql/schema.go b/pkg/graphql/schema.go index b8f5ef6d..2a25043e 100644 --- a/pkg/graphql/schema.go +++ b/pkg/graphql/schema.go @@ -29,6 +29,8 @@ const schema string = ` scalar BigInt # Long is a 64 bit unsigned integer. scalar Long + # BigFloat is a floating point number. + scalar BigFloat schema { query: Query @@ -298,13 +300,28 @@ const schema string = ` nodes: [EthTransactionCid]! } + type IPFSBlock { + key: String! + data: String! + } + type EthHeaderCid { cid: String! blockNumber: BigInt! blockHash: String! parentHash: String! timestamp: BigInt! + stateRoot: String! + + # TODO: Use BigFloat + td: BigInt! + + txRoot: String! + receiptRoot: String! + uncleRoot: String! + bloom: String! ethTransactionCidsByHeaderId: EthTransactionCidsConnection! + blockByMhKey: IPFSBlock! } type EthHeaderCidsConnection { diff --git a/pkg/shared/functions.go b/pkg/shared/functions.go index b1ac4550..c17d1b01 100644 --- a/pkg/shared/functions.go +++ b/pkg/shared/functions.go @@ -19,6 +19,7 @@ package shared import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/statediff/indexer/ipld" + "github.com/ethereum/go-ethereum/statediff/indexer/models" "github.com/ipfs/go-cid" blockstore "github.com/ipfs/go-ipfs-blockstore" dshelp "github.com/ipfs/go-ipfs-ds-help" @@ -77,6 +78,19 @@ func FetchIPLDByMhKey(tx *sqlx.Tx, mhKey string) ([]byte, error) { return block, tx.Get(&block, pgStr, mhKey) } +// FetchIPLDByMhKeysAndBlockNumbers is used to retrieve iplds from Postgres blockstore with the provided tx, mhkey strings and blockNumbers +func FetchIPLDsByMhKeysAndBlockNumbers(tx *sqlx.Tx, mhKeys []string, blockNumbers []uint64) ([]models.IPLDModel, error) { + var blocks []models.IPLDModel + pgStr := `SELECT key, data, block_number FROM public.blocks WHERE key IN (?) AND block_number IN (?)` + query, args, err := sqlx.In(pgStr, mhKeys, blockNumbers) + if err != nil { + return blocks, err + } + query = tx.Rebind(query) + + return blocks, tx.Select(&blocks, query, args...) +} + // MultihashKeyFromCID converts a cid into a blockstore-prefixed multihash db key string func MultihashKeyFromCID(c cid.Cid) string { dbKey := dshelp.MultihashToDsKey(c.Hash()) -- 2.45.2 From 9550d6046792a750a8728220f5baabcbe44ca3bb Mon Sep 17 00:00:00 2001 From: nabarun Date: Mon, 30 May 2022 12:01:27 +0530 Subject: [PATCH 04/13] Add query ethTransactionCidByTxHash --- pkg/eth/cid_retriever.go | 32 +++++++++++++++++++++++++++ pkg/graphql/graphql.go | 48 +++++++++++++++++++++++++++++++++++----- pkg/graphql/schema.go | 4 ++++ 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index dc77608c..81190809 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -593,6 +593,7 @@ func (ecr *CIDRetriever) RetrieveTxCIDsByHeaderID(tx *sqlx.Tx, headerID string) return txCIDs, tx.Select(&txCIDs, pgStr, headerID) } +// RetrieveTxCIDsByBlockNumber retrieves all tx CIDs for the given blockNumber func (ecr *CIDRetriever) RetrieveTxCIDsByBlockNumber(tx *sqlx.Tx, blockNumber int64) ([]models.TxModel, error) { log.Debug("retrieving tx cids for block number ", blockNumber) pgStr := `SELECT CAST(block_number as Text), header_id, index, tx_hash, cid, mh_key, @@ -617,6 +618,7 @@ func (ecr *CIDRetriever) RetrieveReceiptCIDsByTxIDs(tx *sqlx.Tx, txHashes []stri return rctCIDs, tx.Select(&rctCIDs, pgStr, pq.Array(txHashes)) } +// RetrieveHeaderAndTxCIDsByBlockNumber retrieves header CIDs and their associated tx CIDs by block number func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]models.HeaderModel, [][]models.TxModel, error) { log.Debug("retrieving header cids and tx cids for block number ", blockNumber) @@ -677,6 +679,7 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) return headerCIDs, allTxCIDs, nil } +// RetrieveHeaderAndTxCIDsByBlockHash retrieves header CID and their associated tx CIDs by block hash func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash) (models.HeaderModel, []models.TxModel, error) { log.Debug("retrieving header cid and tx cids for block hash ", blockHash.String()) @@ -715,3 +718,32 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Has return headerCID, txCIDs, nil } + +// RetrieveTxCIDByHash returns the tx for the given tx hash +func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string) (models.TxModel, error) { + log.Debug("retrieving tx cid for tx hash ", txHash) + + // Begin new db tx + tx, err := ecr.db.Beginx() + if err != nil { + return models.TxModel{}, err + } + defer func() { + if p := recover(); p != nil { + shared.Rollback(tx) + panic(p) + } else if err != nil { + shared.Rollback(tx) + } else { + err = tx.Commit() + } + }() + + pgStr := `SELECT CAST(block_number as Text), header_id, index, tx_hash, cid, mh_key, + dst, src, tx_data, tx_type, value + FROM eth.transaction_cids + WHERE tx_hash = $1 + ORDER BY index` + var txCID models.TxModel + return txCID, tx.Get(&txCID, pgStr, txHash) +} diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 2de90c46..c5553993 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -1126,11 +1126,12 @@ func decomposeGQLLogs(logCIDs []eth.LogResult) []logsCID { } type EthTransactionCid struct { - cid string - txHash string - index int32 - src string - dst string + cid string + txHash string + index int32 + src string + dst string + ipfsBlock IPFSBlock } func (t EthTransactionCid) Cid(ctx context.Context) string { @@ -1153,6 +1154,10 @@ func (t EthTransactionCid) Dst(ctx context.Context) string { return t.dst } +func (t EthTransactionCid) BlockByMhKey(ctx context.Context) IPFSBlock { + return t.ipfsBlock +} + type EthTransactionCidsConnection struct { nodes []*EthTransactionCid } @@ -1337,3 +1342,36 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { nodes: resultNodes, }, nil } + +func (r *Resolver) EthTransactionCidByTxHash(ctx context.Context, args struct { + TxHash string +}) (*EthTransactionCid, error) { + txCID, err := r.backend.Retriever.RetrieveTxCIDByHash(args.TxHash) + + if err != nil { + return nil, err + } + + // Begin tx + tx, err := r.backend.DB.Beginx() + if err != nil { + return nil, err + } + + txIPLDs, err := r.backend.Fetcher.FetchTrxs(tx, []models.TxModel{txCID}) + if err != nil { + return nil, err + } + + return &EthTransactionCid{ + cid: txCID.CID, + txHash: txCID.TxHash, + index: int32(txCID.Index), + src: txCID.Src, + dst: txCID.Dst, + ipfsBlock: IPFSBlock{ + key: txIPLDs[0].Key, + data: hexutil.Bytes(txIPLDs[0].Data).String(), + }, + }, nil +} diff --git a/pkg/graphql/schema.go b/pkg/graphql/schema.go index 2a25043e..48a2309c 100644 --- a/pkg/graphql/schema.go +++ b/pkg/graphql/schema.go @@ -294,6 +294,7 @@ const schema string = ` index: Int! src: String! dst: String! + blockByMhKey: IPFSBlock! } type EthTransactionCidsConnection { @@ -351,5 +352,8 @@ const schema string = ` # PostGraphile alternative to get headers with transactions using block number or block hash. allEthHeaderCids(condition: EthHeaderCidCondition): EthHeaderCidsConnection + + # PostGraphile alternative to get transactions using transaction hash. + ethTransactionCidByTxHash(txHash: String!): EthTransactionCid } ` -- 2.45.2 From 217cfc63ec95f3a5207ac820c5237493a9fe70ff Mon Sep 17 00:00:00 2001 From: nabarun Date: Mon, 30 May 2022 17:24:14 +0530 Subject: [PATCH 05/13] Return empty headerCIDs and commit db tx --- pkg/eth/cid_retriever.go | 3 --- pkg/eth/ipld_fetcher.go | 4 ++++ pkg/graphql/graphql.go | 21 +++++++++++++++++++++ pkg/graphql/schema.go | 5 ----- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index 81190809..206ca791 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -644,9 +644,6 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) log.Error("header cid retrieval error") return nil, nil, err } - if len(headerCIDs) < 1 { - return nil, nil, fmt.Errorf("header cid retrieval error, no header CIDs found at block %d", blockNumber) - } var allTxCIDs [][]models.TxModel txCIDs, err := ecr.RetrieveTxCIDsByBlockNumber(tx, blockNumber) diff --git a/pkg/eth/ipld_fetcher.go b/pkg/eth/ipld_fetcher.go index 6b191eb8..965028c1 100644 --- a/pkg/eth/ipld_fetcher.go +++ b/pkg/eth/ipld_fetcher.go @@ -119,6 +119,10 @@ func (f *IPLDFetcher) FetchHeaders(tx *sqlx.Tx, cids []models.HeaderModel) ([]mo log.Debug("fetching header iplds") headerIPLDs := make([]models.IPLDModel, len(cids)) + if len(cids) < 1 { + return headerIPLDs, nil + } + blockNumbers := make([]uint64, len(cids)) mhKeys := make([]string, len(cids)) for i, c := range cids { diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index c5553993..19480ab5 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/statediff/indexer/models" "github.com/vulcanize/ipld-eth-server/v3/pkg/eth" + "github.com/vulcanize/ipld-eth-server/v3/pkg/shared" ) var ( @@ -1288,6 +1289,16 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { if err != nil { return nil, err } + defer func() { + if p := recover(); p != nil { + shared.Rollback(tx) + panic(p) + } else if err != nil { + shared.Rollback(tx) + } else { + err = tx.Commit() + } + }() headerIPLDs, err := r.backend.Fetcher.FetchHeaders(tx, headerCIDs) if err != nil { @@ -1357,6 +1368,16 @@ func (r *Resolver) EthTransactionCidByTxHash(ctx context.Context, args struct { if err != nil { return nil, err } + defer func() { + if p := recover(); p != nil { + shared.Rollback(tx) + panic(p) + } else if err != nil { + shared.Rollback(tx) + } else { + err = tx.Commit() + } + }() txIPLDs, err := r.backend.Fetcher.FetchTrxs(tx, []models.TxModel{txCID}) if err != nil { diff --git a/pkg/graphql/schema.go b/pkg/graphql/schema.go index 48a2309c..eb0d89fc 100644 --- a/pkg/graphql/schema.go +++ b/pkg/graphql/schema.go @@ -29,8 +29,6 @@ const schema string = ` scalar BigInt # Long is a 64 bit unsigned integer. scalar Long - # BigFloat is a floating point number. - scalar BigFloat schema { query: Query @@ -313,10 +311,7 @@ const schema string = ` parentHash: String! timestamp: BigInt! stateRoot: String! - - # TODO: Use BigFloat td: BigInt! - txRoot: String! receiptRoot: String! uncleRoot: String! -- 2.45.2 From 7f15befdeeb5b0f946308d26b39b25aefebededb Mon Sep 17 00:00:00 2001 From: prathamesh0 Date: Mon, 30 May 2022 18:09:50 +0530 Subject: [PATCH 06/13] Add custom implementation for Bytes to be returned as string --- pkg/graphql/graphql.go | 6 +++--- pkg/graphql/types.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 19480ab5..1c8cc31b 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -1327,7 +1327,7 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { txRoot: headerCID.TxRoot, receiptRoot: headerCID.RctRoot, uncleRoot: headerCID.UncleRoot, - bloom: hexutil.Bytes(headerCID.Bloom).String(), + bloom: Bytes(headerCID.Bloom).String(), } txCIDs := allTxCIDs[idx] @@ -1343,7 +1343,7 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { ethHeaderCidNode.ipfsBlock = IPFSBlock{ key: headerIPLDs[idx].Key, - data: hexutil.Bytes(headerIPLDs[idx].Data).String(), + data: Bytes(headerIPLDs[idx].Data).String(), } resultNodes = append(resultNodes, ðHeaderCidNode) @@ -1392,7 +1392,7 @@ func (r *Resolver) EthTransactionCidByTxHash(ctx context.Context, args struct { dst: txCID.Dst, ipfsBlock: IPFSBlock{ key: txIPLDs[0].Key, - data: hexutil.Bytes(txIPLDs[0].Data).String(), + data: Bytes(txIPLDs[0].Data).String(), }, }, nil } diff --git a/pkg/graphql/types.go b/pkg/graphql/types.go index 2756070d..7213cecc 100644 --- a/pkg/graphql/types.go +++ b/pkg/graphql/types.go @@ -17,12 +17,40 @@ package graphql import ( + "encoding/hex" "fmt" "math/big" "github.com/ethereum/go-ethereum/common/hexutil" ) +// Bytes marshals as a JSON string with \x prefix. +// The empty slice marshals as "\x". +type Bytes []byte + +// MarshalText implements encoding.TextMarshaler +func (b Bytes) MarshalText() ([]byte, error) { + result := make([]byte, len(b)*2+2) + copy(result, `\x`) + hex.Encode(result[2:], b) + return result, nil +} + +// String returns the hex encoding of b. +func (b Bytes) String() string { + return b.encode() +} + +// Encode encodes b as a hex string with "\x" prefix. +// This is to make the output to be the same as given by postgraphile. +// graphql-go prepends another "\" to the output resulting in prefix "\\x". +func (b Bytes) encode() string { + result := make([]byte, len(b)*2+2) + copy(result, `\x`) + hex.Encode(result[2:], b) + return string(result) +} + type BigInt big.Int // ToInt converts b to a big.Int. -- 2.45.2 From 80413211c2a9d0d5ff34c44dcca6d5a817c9b488 Mon Sep 17 00:00:00 2001 From: nabarun Date: Mon, 30 May 2022 19:41:03 +0530 Subject: [PATCH 07/13] Remove block_number from queries for v3 schema --- pkg/eth/cid_retriever.go | 36 +++++++++++++++++++++++++++--------- pkg/eth/ipld_fetcher.go | 5 +---- pkg/shared/functions.go | 6 +++--- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index 206ca791..789ad459 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -577,7 +577,8 @@ func (ecr *CIDRetriever) RetrieveBlockByNumber(blockNumber int64) (models.Header // RetrieveHeaderCIDByHash returns the header for the given block hash func (ecr *CIDRetriever) RetrieveHeaderCIDByHash(tx *sqlx.Tx, blockHash common.Hash) (models.HeaderModel, error) { log.Debug("retrieving header cids for block hash ", blockHash.String()) - pgStr := `SELECT block_hash, CAST(block_number as Text), parent_hash, cid, mh_key, timestamp FROM eth.header_cids + pgStr := `SELECT block_hash, CAST(block_number as Text), parent_hash, cid, mh_key, CAST(td as Text), + state_root,uncle_root,tx_root,receipt_root,bloom,timestamp FROM eth.header_cids WHERE block_hash = $1` var headerCID models.HeaderModel return headerCID, tx.Get(&headerCID, pgStr, blockHash.String()) @@ -593,16 +594,27 @@ func (ecr *CIDRetriever) RetrieveTxCIDsByHeaderID(tx *sqlx.Tx, headerID string) return txCIDs, tx.Select(&txCIDs, pgStr, headerID) } -// RetrieveTxCIDsByBlockNumber retrieves all tx CIDs for the given blockNumber -func (ecr *CIDRetriever) RetrieveTxCIDsByBlockNumber(tx *sqlx.Tx, blockNumber int64) ([]models.TxModel, error) { - log.Debug("retrieving tx cids for block number ", blockNumber) - pgStr := `SELECT CAST(block_number as Text), header_id, index, tx_hash, cid, mh_key, +// RetrieveTxCIDsByHeaderIDs retrieves all tx CIDs for the given headerIDs +func (ecr *CIDRetriever) RetrieveTxCIDsByHeaderIDs(tx *sqlx.Tx, headerIDs []string) ([]models.TxModel, error) { + log.Debug("retrieving tx cids for headerIDs ", headerIDs) + pgStr := `SELECT header_id, index, tx_hash, cid, mh_key, dst, src, tx_data, tx_type, value FROM eth.transaction_cids - WHERE block_number = $1 + WHERE header_id in (?) ORDER BY index` + var txCIDs []models.TxModel - return txCIDs, tx.Select(&txCIDs, pgStr, blockNumber) + if len(headerIDs) < 1 { + return txCIDs, nil + } + + query, args, err := sqlx.In(pgStr, headerIDs) + if err != nil { + return txCIDs, err + } + query = tx.Rebind(query) + + return txCIDs, tx.Select(&txCIDs, query, args...) } // RetrieveReceiptCIDsByTxIDs retrieves receipt CIDs by their associated tx IDs @@ -646,7 +658,13 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) } var allTxCIDs [][]models.TxModel - txCIDs, err := ecr.RetrieveTxCIDsByBlockNumber(tx, blockNumber) + txHeaderIDs := funk.Map( + headerCIDs, + func(headerCID models.HeaderModel) string { + return headerCID.BlockHash + }, + ) + txCIDs, err := ecr.RetrieveTxCIDsByHeaderIDs(tx, txHeaderIDs.([]string)) if err != nil { log.Error("tx cid retrieval error") return nil, nil, err @@ -736,7 +754,7 @@ func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string) (models.TxModel, err } }() - pgStr := `SELECT CAST(block_number as Text), header_id, index, tx_hash, cid, mh_key, + pgStr := `SELECT header_id, index, tx_hash, cid, mh_key, dst, src, tx_data, tx_type, value FROM eth.transaction_cids WHERE tx_hash = $1 diff --git a/pkg/eth/ipld_fetcher.go b/pkg/eth/ipld_fetcher.go index 965028c1..fa0d4c57 100644 --- a/pkg/eth/ipld_fetcher.go +++ b/pkg/eth/ipld_fetcher.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "math/big" - "strconv" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/statediff/indexer/models" @@ -123,18 +122,16 @@ func (f *IPLDFetcher) FetchHeaders(tx *sqlx.Tx, cids []models.HeaderModel) ([]mo return headerIPLDs, nil } - blockNumbers := make([]uint64, len(cids)) mhKeys := make([]string, len(cids)) for i, c := range cids { var err error mhKeys[i] = c.MhKey - blockNumbers[i], err = strconv.ParseUint(c.BlockNumber, 10, 64) if err != nil { return nil, err } } - fetchedIPLDs, err := shared.FetchIPLDsByMhKeysAndBlockNumbers(tx, mhKeys, blockNumbers) + fetchedIPLDs, err := shared.FetchIPLDsByMhKeys(tx, mhKeys) if err != nil { return nil, err } diff --git a/pkg/shared/functions.go b/pkg/shared/functions.go index c17d1b01..eede20bc 100644 --- a/pkg/shared/functions.go +++ b/pkg/shared/functions.go @@ -79,10 +79,10 @@ func FetchIPLDByMhKey(tx *sqlx.Tx, mhKey string) ([]byte, error) { } // FetchIPLDByMhKeysAndBlockNumbers is used to retrieve iplds from Postgres blockstore with the provided tx, mhkey strings and blockNumbers -func FetchIPLDsByMhKeysAndBlockNumbers(tx *sqlx.Tx, mhKeys []string, blockNumbers []uint64) ([]models.IPLDModel, error) { +func FetchIPLDsByMhKeys(tx *sqlx.Tx, mhKeys []string) ([]models.IPLDModel, error) { var blocks []models.IPLDModel - pgStr := `SELECT key, data, block_number FROM public.blocks WHERE key IN (?) AND block_number IN (?)` - query, args, err := sqlx.In(pgStr, mhKeys, blockNumbers) + pgStr := `SELECT key, data FROM public.blocks WHERE key IN (?)` + query, args, err := sqlx.In(pgStr, mhKeys) if err != nil { return blocks, err } -- 2.45.2 From 0c44882cb274d5c8dec08f9472b530627e1b2c73 Mon Sep 17 00:00:00 2001 From: nabarun Date: Wed, 1 Jun 2022 14:45:48 +0530 Subject: [PATCH 08/13] Added test for allEthHeaderCids query --- pkg/graphql/client.go | 106 ++++++++++++++++++++++++++++++++++++ pkg/graphql/graphql_test.go | 99 +++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) diff --git a/pkg/graphql/client.go b/pkg/graphql/client.go index 1040b1bc..255c0951 100644 --- a/pkg/graphql/client.go +++ b/pkg/graphql/client.go @@ -36,6 +36,48 @@ type GetLogs struct { Responses []LogResponse `json:"getLogs"` } +type IPFSBlockResp struct { + Key string `json:"key"` + Data string `json:"data"` +} + +type EthTransactionCidResp struct { + Cid string `json:"cid"` + TxHash string `json:"txHash"` + Index int32 `json:"index"` + Src string `json:"src"` + Dst string `json:"dst"` + BlockByMhKey IPFSBlockResp `json:"blockByMhKey"` +} + +type EthTransactionCidsByHeaderIdResp struct { + Nodes []EthTransactionCidResp `json:"nodes"` +} + +type EthHeaderCidResp struct { + Cid string `json:"cid"` + BlockNumber BigInt `json:"blockNumber"` + BlockHash string `json:"blockHash"` + ParentHash string `json:"parentHash"` + Timestamp BigInt `json:"timestamp"` + StateRoot string `json:"stateRoot"` + Td BigInt `json:"td"` + TxRoot string `json:"txRoot"` + ReceiptRoot string `json:"receiptRoot"` + UncleRoot string `json:"uncleRoot"` + Bloom string `json:"bloom"` + EthTransactionCidsByHeaderId EthTransactionCidsByHeaderIdResp `json:"ethTransactionCidsByHeaderId"` + BlockByMhKey IPFSBlockResp `json:"blockByMhKey"` +} + +type AllEthHeaderCidsResp struct { + Nodes []EthHeaderCidResp `json:"nodes"` +} + +type AllEthHeaderCids struct { + Response AllEthHeaderCidsResp `json:"allEthHeaderCids"` +} + type Client struct { client *gqlclient.Client } @@ -117,3 +159,67 @@ func (c *Client) GetStorageAt(ctx context.Context, hash common.Hash, address com } return &storageAt.Response, nil } + +func (c *Client) AllEthHeaderCids(ctx context.Context, condition EthHeaderCidCondition) (*AllEthHeaderCidsResp, error) { + var params string + if condition.BlockHash != nil { + params = fmt.Sprintf(`blockHash: "%s"`, *condition.BlockHash) + } + if condition.BlockNumber != nil { + params += fmt.Sprintf(`blockNumber: "%s"`, condition.BlockNumber.String()) + } + + getLogsQuery := fmt.Sprintf(` + query{ + allEthHeaderCids(condition: { %s }) { + nodes { + cid + blockNumber + blockHash + parentHash + timestamp + stateRoot + td + txRoot + receiptRoot + uncleRoot + bloom + blockByMhKey { + key + data + } + ethTransactionCidsByHeaderId { + nodes { + cid + txHash + index + src + dst + } + } + } + } + } + `, params) + + req := gqlclient.NewRequest(getLogsQuery) + req.Header.Set("Cache-Control", "no-cache") + + var respData map[string]interface{} + err := c.client.Run(ctx, req, &respData) + if err != nil { + return nil, err + } + + jsonStr, err := json.Marshal(respData) + if err != nil { + return nil, err + } + + var allEthHeaderCids AllEthHeaderCids + err = json.Unmarshal(jsonStr, &allEthHeaderCids) + if err != nil { + return nil, err + } + return &allEthHeaderCids.Response, nil +} diff --git a/pkg/graphql/graphql_test.go b/pkg/graphql/graphql_test.go index 50375b3a..031ddb70 100644 --- a/pkg/graphql/graphql_test.go +++ b/pkg/graphql/graphql_test.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "math/big" + "strconv" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -30,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/statediff" + "github.com/ethereum/go-ethereum/statediff/indexer/models" sdtypes "github.com/ethereum/go-ethereum/statediff/types" "github.com/jmoiron/sqlx" . "github.com/onsi/ginkgo" @@ -250,4 +252,101 @@ var _ = Describe("GraphQL", func() { Expect(storageRes.Value).To(Equal(common.Hash{})) }) }) + + Describe("allEthHeaderCids", func() { + It("Retrieves header_cids that matches the provided blockNumber", func() { + allEthHeaderCidsResp, err := client.AllEthHeaderCids(ctx, graphql.EthHeaderCidCondition{BlockNumber: new(graphql.BigInt).SetUint64(2)}) + Expect(err).ToNot(HaveOccurred()) + + headerCIDs, txCIDs, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockNumber(2) + Expect(err).ToNot(HaveOccurred()) + + // Begin tx + tx, err := backend.DB.Beginx() + Expect(err).ToNot(HaveOccurred()) + defer func() { + if p := recover(); p != nil { + shared.Rollback(tx) + panic(p) + } else if err != nil { + shared.Rollback(tx) + } else { + err = tx.Commit() + } + }() + + headerIPLDs, err := backend.Fetcher.FetchHeaders(tx, headerCIDs) + Expect(err).ToNot(HaveOccurred()) + + for idx, headerCID := range headerCIDs { + ethHeaderCid := allEthHeaderCidsResp.Nodes[idx] + + compareEthHeaderCid(ethHeaderCid, headerCID, txCIDs[idx], headerIPLDs[idx]) + } + }) + + It("Retrieves header_cids that matches the provided blockHash", func() { + blockHash := blocks[2].Hash().String() + allEthHeaderCidsResp, err := client.AllEthHeaderCids(ctx, graphql.EthHeaderCidCondition{BlockHash: &blockHash}) + Expect(err).ToNot(HaveOccurred()) + + headerCID, txCIDs, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(blocks[2].Hash()) + Expect(err).ToNot(HaveOccurred()) + + // Begin tx + tx, err := backend.DB.Beginx() + Expect(err).ToNot(HaveOccurred()) + defer func() { + if p := recover(); p != nil { + shared.Rollback(tx) + panic(p) + } else if err != nil { + shared.Rollback(tx) + } else { + err = tx.Commit() + } + }() + + headerIPLDs, err := backend.Fetcher.FetchHeaders(tx, []models.HeaderModel{headerCID}) + Expect(err).ToNot(HaveOccurred()) + Expect(len(allEthHeaderCidsResp.Nodes)).To(Equal(1)) + + Expect(len(allEthHeaderCidsResp.Nodes)).To(Equal(1)) + ethHeaderCid := allEthHeaderCidsResp.Nodes[0] + compareEthHeaderCid(ethHeaderCid, headerCID, txCIDs, headerIPLDs[0]) + }) + }) }) + +func compareEthHeaderCid(ethHeaderCid graphql.EthHeaderCidResp, headerCID models.HeaderModel, txCIDs []models.TxModel, headerIPLD models.IPLDModel) { + blockNumber, err := strconv.ParseInt(headerCID.BlockNumber, 10, 64) + Expect(err).ToNot(HaveOccurred()) + + td, err := strconv.ParseInt(headerCID.TotalDifficulty, 10, 64) + Expect(err).ToNot(HaveOccurred()) + + Expect(ethHeaderCid.Cid).To(Equal(headerCID.CID)) + Expect(ethHeaderCid.BlockNumber).To(Equal(*new(graphql.BigInt).SetUint64(uint64(blockNumber)))) + Expect(ethHeaderCid.BlockHash).To(Equal(headerCID.BlockHash)) + Expect(ethHeaderCid.ParentHash).To(Equal(headerCID.ParentHash)) + Expect(ethHeaderCid.Timestamp).To(Equal(*new(graphql.BigInt).SetUint64(headerCID.Timestamp))) + Expect(ethHeaderCid.StateRoot).To(Equal(headerCID.StateRoot)) + Expect(ethHeaderCid.Td).To(Equal(*new(graphql.BigInt).SetUint64(uint64(td)))) + Expect(ethHeaderCid.TxRoot).To(Equal(headerCID.TxRoot)) + Expect(ethHeaderCid.ReceiptRoot).To(Equal(headerCID.RctRoot)) + Expect(ethHeaderCid.UncleRoot).To(Equal(headerCID.UncleRoot)) + Expect(ethHeaderCid.Bloom).To(Equal(graphql.Bytes(headerCID.Bloom).String())) + + for tIdx, txCID := range txCIDs { + ethTxCid := ethHeaderCid.EthTransactionCidsByHeaderId.Nodes[tIdx] + + Expect(ethTxCid.Cid).To(Equal(txCID.CID)) + Expect(ethTxCid.TxHash).To(Equal(txCID.TxHash)) + Expect(ethTxCid.Index).To(Equal(int32(txCID.Index))) + Expect(ethTxCid.Src).To(Equal(txCID.Src)) + Expect(ethTxCid.Dst).To(Equal(txCID.Dst)) + } + + Expect(ethHeaderCid.BlockByMhKey.Data).To(Equal(graphql.Bytes(headerIPLD.Data).String())) + Expect(ethHeaderCid.BlockByMhKey.Key).To(Equal(headerIPLD.Key)) +} -- 2.45.2 From b3d9e01d67a8cffe9ad8b38daec77834ec31bceb Mon Sep 17 00:00:00 2001 From: nabarun Date: Wed, 1 Jun 2022 16:45:02 +0530 Subject: [PATCH 09/13] Add test for ethTransactionCidByTxHash query --- pkg/graphql/client.go | 46 +++++++++++++++++++++++++++++++-- pkg/graphql/graphql_test.go | 51 +++++++++++++++++++++++++++++++------ 2 files changed, 87 insertions(+), 10 deletions(-) diff --git a/pkg/graphql/client.go b/pkg/graphql/client.go index 255c0951..53420db8 100644 --- a/pkg/graphql/client.go +++ b/pkg/graphql/client.go @@ -50,6 +50,10 @@ type EthTransactionCidResp struct { BlockByMhKey IPFSBlockResp `json:"blockByMhKey"` } +type EthTransactionCidByTxHash struct { + Response EthTransactionCidResp `json:"ethTransactionCidByTxHash"` +} + type EthTransactionCidsByHeaderIdResp struct { Nodes []EthTransactionCidResp `json:"nodes"` } @@ -169,7 +173,7 @@ func (c *Client) AllEthHeaderCids(ctx context.Context, condition EthHeaderCidCon params += fmt.Sprintf(`blockNumber: "%s"`, condition.BlockNumber.String()) } - getLogsQuery := fmt.Sprintf(` + getHeadersQuery := fmt.Sprintf(` query{ allEthHeaderCids(condition: { %s }) { nodes { @@ -202,7 +206,7 @@ func (c *Client) AllEthHeaderCids(ctx context.Context, condition EthHeaderCidCon } `, params) - req := gqlclient.NewRequest(getLogsQuery) + req := gqlclient.NewRequest(getHeadersQuery) req.Header.Set("Cache-Control", "no-cache") var respData map[string]interface{} @@ -223,3 +227,41 @@ func (c *Client) AllEthHeaderCids(ctx context.Context, condition EthHeaderCidCon } return &allEthHeaderCids.Response, nil } + +func (c *Client) EthTransactionCidByTxHash(ctx context.Context, txHash string) (*EthTransactionCidResp, error) { + getTxQuery := fmt.Sprintf(` + query{ + ethTransactionCidByTxHash(txHash: "%s") { + cid + txHash + index + src + dst + blockByMhKey { + data + } + } + } + `, txHash) + + req := gqlclient.NewRequest(getTxQuery) + req.Header.Set("Cache-Control", "no-cache") + + var respData map[string]interface{} + err := c.client.Run(ctx, req, &respData) + if err != nil { + return nil, err + } + + jsonStr, err := json.Marshal(respData) + if err != nil { + return nil, err + } + + var ethTxCid EthTransactionCidByTxHash + err = json.Unmarshal(jsonStr, ðTxCid) + if err != nil { + return nil, err + } + return ðTxCid.Response, nil +} diff --git a/pkg/graphql/graphql_test.go b/pkg/graphql/graphql_test.go index 031ddb70..fc8259a4 100644 --- a/pkg/graphql/graphql_test.go +++ b/pkg/graphql/graphql_test.go @@ -286,11 +286,11 @@ var _ = Describe("GraphQL", func() { }) It("Retrieves header_cids that matches the provided blockHash", func() { - blockHash := blocks[2].Hash().String() + blockHash := blocks[1].Hash().String() allEthHeaderCidsResp, err := client.AllEthHeaderCids(ctx, graphql.EthHeaderCidCondition{BlockHash: &blockHash}) Expect(err).ToNot(HaveOccurred()) - headerCID, txCIDs, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(blocks[2].Hash()) + headerCID, txCIDs, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(blocks[1].Hash()) Expect(err).ToNot(HaveOccurred()) // Begin tx @@ -316,6 +316,38 @@ var _ = Describe("GraphQL", func() { compareEthHeaderCid(ethHeaderCid, headerCID, txCIDs, headerIPLDs[0]) }) }) + + Describe("ethTransactionCidByTxHash", func() { + It("Retrieves tx_cid that matches the provided txHash", func() { + txHash := blocks[2].Transactions()[0].Hash().String() + ethTransactionCidResp, err := client.EthTransactionCidByTxHash(ctx, txHash) + Expect(err).ToNot(HaveOccurred()) + + txCID, err := backend.Retriever.RetrieveTxCIDByHash(txHash) + Expect(err).ToNot(HaveOccurred()) + + compareEthTxCid(*ethTransactionCidResp, txCID) + + // Begin tx + tx, err := backend.DB.Beginx() + Expect(err).ToNot(HaveOccurred()) + defer func() { + if p := recover(); p != nil { + shared.Rollback(tx) + panic(p) + } else if err != nil { + shared.Rollback(tx) + } else { + err = tx.Commit() + } + }() + + txIPLDs, err := backend.Fetcher.FetchTrxs(tx, []models.TxModel{txCID}) + Expect(err).ToNot(HaveOccurred()) + Expect(len(txIPLDs)).To(Equal(1)) + Expect(ethTransactionCidResp.BlockByMhKey.Data).To(Equal(graphql.Bytes(txIPLDs[0].Data).String())) + }) + }) }) func compareEthHeaderCid(ethHeaderCid graphql.EthHeaderCidResp, headerCID models.HeaderModel, txCIDs []models.TxModel, headerIPLD models.IPLDModel) { @@ -339,14 +371,17 @@ func compareEthHeaderCid(ethHeaderCid graphql.EthHeaderCidResp, headerCID models for tIdx, txCID := range txCIDs { ethTxCid := ethHeaderCid.EthTransactionCidsByHeaderId.Nodes[tIdx] - - Expect(ethTxCid.Cid).To(Equal(txCID.CID)) - Expect(ethTxCid.TxHash).To(Equal(txCID.TxHash)) - Expect(ethTxCid.Index).To(Equal(int32(txCID.Index))) - Expect(ethTxCid.Src).To(Equal(txCID.Src)) - Expect(ethTxCid.Dst).To(Equal(txCID.Dst)) + compareEthTxCid(ethTxCid, txCID) } Expect(ethHeaderCid.BlockByMhKey.Data).To(Equal(graphql.Bytes(headerIPLD.Data).String())) Expect(ethHeaderCid.BlockByMhKey.Key).To(Equal(headerIPLD.Key)) } + +func compareEthTxCid(ethTxCid graphql.EthTransactionCidResp, txCID models.TxModel) { + Expect(ethTxCid.Cid).To(Equal(txCID.CID)) + Expect(ethTxCid.TxHash).To(Equal(txCID.TxHash)) + Expect(ethTxCid.Index).To(Equal(int32(txCID.Index))) + Expect(ethTxCid.Src).To(Equal(txCID.Src)) + Expect(ethTxCid.Dst).To(Equal(txCID.Dst)) +} -- 2.45.2 From 6bd563e3d5002959924a838651f2883cc5ecc010 Mon Sep 17 00:00:00 2001 From: nabarun Date: Fri, 3 Jun 2022 14:30:20 +0530 Subject: [PATCH 10/13] Use GORM to retrieve data from database --- go.mod | 19 ++-- go.sum | 29 +++-- pkg/eth/cid_retriever.go | 217 ++++++++++++++---------------------- pkg/eth/ipld_fetcher.go | 35 ------ pkg/graphql/graphql.go | 53 ++------- pkg/graphql/graphql_test.go | 73 ++---------- pkg/shared/functions.go | 14 --- 7 files changed, 138 insertions(+), 302 deletions(-) diff --git a/go.mod b/go.mod index cfc23a2b..a6ef0b0b 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/ipfs/go-ipfs-blockstore v1.0.1 github.com/ipfs/go-ipfs-ds-help v1.0.0 github.com/ipfs/go-ipld-format v0.2.0 + github.com/jinzhu/now v1.1.5 // indirect github.com/jmoiron/sqlx v1.3.5 github.com/joho/godotenv v1.4.0 github.com/lib/pq v1.10.5 @@ -22,10 +23,13 @@ require ( github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.11.0 + github.com/thoas/go-funk v0.9.2 // indirect github.com/vulcanize/eth-ipfs-state-validator/v3 v3.0.2 - github.com/thoas/go-funk v0.9.2 github.com/vulcanize/gap-filler v0.3.1 github.com/vulcanize/ipfs-ethdb/v3 v3.0.3 + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + gorm.io/driver/postgres v1.3.7 + gorm.io/gorm v1.23.5 ) require ( @@ -124,18 +128,19 @@ require ( github.com/ipld/go-codec-dagpb v1.3.0 // indirect github.com/ipld/go-ipld-prime v0.12.2 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.10.0 // indirect + github.com/jackc/pgconn v1.12.1 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.1.1 // indirect + github.com/jackc/pgproto3/v2 v2.3.0 // indirect github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect - github.com/jackc/pgtype v1.8.1 // indirect - github.com/jackc/pgx/v4 v4.13.0 // indirect - github.com/jackc/puddle v1.1.3 // indirect + github.com/jackc/pgtype v1.11.0 // indirect + github.com/jackc/pgx/v4 v4.16.1 // indirect + github.com/jackc/puddle v1.2.1 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/jinzhu/copier v0.2.4 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect github.com/klauspost/compress v1.11.7 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/koron/go-ssdp v0.0.2 // indirect @@ -244,7 +249,6 @@ require ( github.com/stretchr/testify v1.7.1 // indirect github.com/subosito/gotenv v1.2.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect - github.com/thoas/go-funk v0.9.2 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef // indirect @@ -266,7 +270,6 @@ require ( go.uber.org/multierr v1.7.0 // indirect go.uber.org/zap v1.19.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect - golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 // indirect golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect diff --git a/go.sum b/go.sum index 8df04b33..eb2c8782 100644 --- a/go.sum +++ b/go.sum @@ -76,6 +76,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= @@ -788,8 +789,9 @@ github.com/jackc/pgconn v1.7.0/go.mod h1:sF/lPpNEMEOp+IYhyQGdAvrG20gWf6A1tKlr0v7 github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.10.0 h1:4EYhlDVEMsJ30nNj0mmgwIUXoq7e9sMJrVC2ED6QlCU= github.com/jackc/pgconn v1.10.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.12.1 h1:rsDFzIpRk7xT4B8FufgpCCeyjdNpKyghZeSefViE5W8= +github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= @@ -807,8 +809,9 @@ github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwX github.com/jackc/pgproto3/v2 v2.0.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.0.5/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.0 h1:brH0pCGBDkBW07HWlN/oSBXrmo3WB0UvZd1pIuDcL8Y= +github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= @@ -821,8 +824,9 @@ github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkAL github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= github.com/jackc/pgtype v1.4.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.8.1 h1:9k0IXtdJXHJbyAWQgbWr1lU+MEhPXZz6RIXxfR5oxXs= github.com/jackc/pgtype v1.8.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.11.0 h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs= +github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= @@ -833,15 +837,17 @@ github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6 github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= github.com/jackc/pgx/v4 v4.8.1/go.mod h1:4HOLxrl8wToZJReD04/yB20GDwf4KBYETvlHciCnwW0= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.13.0 h1:JCjhT5vmhMAf/YwBHLvrBn4OGdIQBiFG6ym8Zmdx570= github.com/jackc/pgx/v4 v4.13.0/go.mod h1:9P4X524sErlaxj0XSGZk7s+LD0eOyu1ZDUrrpznYDF0= +github.com/jackc/pgx/v4 v4.16.1 h1:JzTglcal01DrghUqt+PmzWsZx/Yh7SC/CTQmSBMTd0Y= +github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.2/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.3 h1:JnPg/5Q9xVJGfjsO5CPUOjnJps1JaRUm8I9FXVCFK94= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.2.1 h1:gI8os0wpRXFd4FiAY2dWiqRK037tjj3t7rKFeO4X5iw= +github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= @@ -866,8 +872,12 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS github.com/jinzhu/copier v0.2.4 h1:dT3tI+8GzU8DjJFCj9mLYtjfRtUmK7edauduQdcZCpI= github.com/jinzhu/copier v0.2.4/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro= github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= @@ -1920,8 +1930,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -2423,6 +2433,11 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/postgres v1.3.7 h1:FKF6sIMDHDEvvMF/XJvbnCl0nu6KSKUaPXevJ4r+VYQ= +gorm.io/driver/postgres v1.3.7/go.mod h1:f02ympjIcgtHEGFMZvdgTxODZ9snAHDb4hXfigBVuNI= +gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.23.5 h1:TnlF26wScKSvknUC/Rn8t0NLLM22fypYBlvj1+aH6dM= +gorm.io/gorm v1.23.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index 789ad459..04a5c719 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -26,7 +26,8 @@ import ( "github.com/jmoiron/sqlx" "github.com/lib/pq" log "github.com/sirupsen/logrus" - "github.com/thoas/go-funk" + "gorm.io/driver/postgres" + "gorm.io/gorm" "github.com/vulcanize/ipld-eth-server/v3/pkg/shared" ) @@ -40,13 +41,70 @@ type Retriever interface { // CIDRetriever satisfies the CIDRetriever interface for ethereum type CIDRetriever struct { - db *sqlx.DB + db *sqlx.DB + gormDB *gorm.DB +} + +type IPLD struct { + models.IPLDModel +} + +// TableName overrides the table name used by IPLD +func (IPLD) TableName() string { + return "public.blocks" +} + +type HeaderCid struct { + CID string `gorm:"column:cid"` + BlockHash string `gorm:"primaryKey"` + BlockNumber string + ParentHash string + Timestamp uint64 + StateRoot string + TotalDifficulty string `gorm:"column:td"` + TxRoot string + RctRoot string `gorm:"column:receipt_root"` + UncleRoot string + Bloom []byte + MhKey string + TransactionCids []TransactionCid `gorm:"foreignKey:HeaderID;references:BlockHash"` + IPLD IPLD `gorm:"foreignKey:MhKey;references:Key"` +} + +// TableName overrides the table name used by HeaderCid +func (HeaderCid) TableName() string { + return "eth.header_cids" +} + +type TransactionCid struct { + CID string `gorm:"column:cid"` + TxHash string `gorm:"primaryKey"` + HeaderID string `gorm:"column:header_id"` + Index int64 + Src string + Dst string + MhKey string + IPLD IPLD `gorm:"foreignKey:MhKey;references:Key"` +} + +// TableName overrides the table name used by TransactionCid +func (TransactionCid) TableName() string { + return "eth.transaction_cids" } // NewCIDRetriever returns a pointer to a new CIDRetriever which supports the CIDRetriever interface func NewCIDRetriever(db *sqlx.DB) *CIDRetriever { + gormDB, err := gorm.Open(postgres.New(postgres.Config{ + Conn: db, + }), &gorm.Config{}) + if err != nil { + log.Error(err) + return nil + } + return &CIDRetriever{ - db: db, + db: db, + gormDB: gormDB, } } @@ -594,29 +652,6 @@ func (ecr *CIDRetriever) RetrieveTxCIDsByHeaderID(tx *sqlx.Tx, headerID string) return txCIDs, tx.Select(&txCIDs, pgStr, headerID) } -// RetrieveTxCIDsByHeaderIDs retrieves all tx CIDs for the given headerIDs -func (ecr *CIDRetriever) RetrieveTxCIDsByHeaderIDs(tx *sqlx.Tx, headerIDs []string) ([]models.TxModel, error) { - log.Debug("retrieving tx cids for headerIDs ", headerIDs) - pgStr := `SELECT header_id, index, tx_hash, cid, mh_key, - dst, src, tx_data, tx_type, value - FROM eth.transaction_cids - WHERE header_id in (?) - ORDER BY index` - - var txCIDs []models.TxModel - if len(headerIDs) < 1 { - return txCIDs, nil - } - - query, args, err := sqlx.In(pgStr, headerIDs) - if err != nil { - return txCIDs, err - } - query = tx.Rebind(query) - - return txCIDs, tx.Select(&txCIDs, query, args...) -} - // RetrieveReceiptCIDsByTxIDs retrieves receipt CIDs by their associated tx IDs func (ecr *CIDRetriever) RetrieveReceiptCIDsByTxIDs(tx *sqlx.Tx, txHashes []string) ([]models.ReceiptModel, error) { log.Debugf("retrieving receipt cids for tx hashes %v", txHashes) @@ -631,134 +666,50 @@ func (ecr *CIDRetriever) RetrieveReceiptCIDsByTxIDs(tx *sqlx.Tx, txHashes []stri } // RetrieveHeaderAndTxCIDsByBlockNumber retrieves header CIDs and their associated tx CIDs by block number -func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]models.HeaderModel, [][]models.TxModel, error) { +func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]HeaderCid, error) { log.Debug("retrieving header cids and tx cids for block number ", blockNumber) - // Begin new db tx - tx, err := ecr.db.Beginx() - if err != nil { - return nil, nil, err - } - defer func() { - if p := recover(); p != nil { - shared.Rollback(tx) - panic(p) - } else if err != nil { - shared.Rollback(tx) - } else { - err = tx.Commit() - } - }() + var headerCIDs []HeaderCid - var headerCIDs []models.HeaderModel - headerCIDs, err = ecr.RetrieveHeaderCIDs(tx, blockNumber) + // 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").Joins("IPLD").Find(&headerCIDs, "block_number = ?", blockNumber).Error if err != nil { log.Error("header cid retrieval error") - return nil, nil, err + return nil, err } - var allTxCIDs [][]models.TxModel - txHeaderIDs := funk.Map( - headerCIDs, - func(headerCID models.HeaderModel) string { - return headerCID.BlockHash - }, - ) - txCIDs, err := ecr.RetrieveTxCIDsByHeaderIDs(tx, txHeaderIDs.([]string)) - if err != nil { - log.Error("tx cid retrieval error") - return nil, nil, err - } - - txCIDsByHeaderID := funk.Reduce( - txCIDs, - func(acc map[string][]models.TxModel, txCID models.TxModel) map[string][]models.TxModel { - if _, ok := acc[txCID.HeaderID]; !ok { - acc[txCID.HeaderID] = []models.TxModel{} - } - - txCIDs = append(acc[txCID.HeaderID], txCID) - acc[txCID.HeaderID] = txCIDs - return acc - }, - make(map[string][]models.TxModel), - ) - - txCIDsByHeaderIDMap := txCIDsByHeaderID.(map[string][]models.TxModel) - - for _, headerCID := range headerCIDs { - txCIDs := txCIDsByHeaderIDMap[headerCID.BlockHash] - allTxCIDs = append(allTxCIDs, txCIDs) - } - - return headerCIDs, allTxCIDs, nil + return headerCIDs, nil } // RetrieveHeaderAndTxCIDsByBlockHash retrieves header CID and their associated tx CIDs by block hash -func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash) (models.HeaderModel, []models.TxModel, error) { +func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash) (HeaderCid, error) { log.Debug("retrieving header cid and tx cids for block hash ", blockHash.String()) - // Begin new db tx - tx, err := ecr.db.Beginx() - if err != nil { - return models.HeaderModel{}, nil, err - } - defer func() { - if p := recover(); p != nil { - shared.Rollback(tx) - panic(p) - } else if err != nil { - shared.Rollback(tx) - } else { - err = tx.Commit() - } - }() + var headerCID HeaderCid - var headerCID models.HeaderModel - headerCID, err = ecr.RetrieveHeaderCIDByHash(tx, blockHash) + // 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").Joins("IPLD").First(&headerCID, "block_hash = ?", blockHash.String()).Error if err != nil { log.Error("header cid retrieval error") - return models.HeaderModel{}, nil, err - } - if err != nil { - return models.HeaderModel{}, nil, err + return headerCID, err } - var txCIDs []models.TxModel - txCIDs, err = ecr.RetrieveTxCIDsByHeaderID(tx, headerCID.BlockHash) - if err != nil { - log.Error("tx cid retrieval error") - return models.HeaderModel{}, nil, err - } - - return headerCID, txCIDs, nil + return headerCID, nil } // RetrieveTxCIDByHash returns the tx for the given tx hash -func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string) (models.TxModel, error) { +func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string) (TransactionCid, error) { log.Debug("retrieving tx cid for tx hash ", txHash) - // Begin new db tx - tx, err := ecr.db.Beginx() - if err != nil { - return models.TxModel{}, err - } - defer func() { - if p := recover(); p != nil { - shared.Rollback(tx) - panic(p) - } else if err != nil { - shared.Rollback(tx) - } else { - err = tx.Commit() - } - }() + var txCID TransactionCid - pgStr := `SELECT header_id, index, tx_hash, cid, mh_key, - dst, src, tx_data, tx_type, value - FROM eth.transaction_cids - WHERE tx_hash = $1 - ORDER BY index` - var txCID models.TxModel - return txCID, tx.Get(&txCID, pgStr, txHash) + err := ecr.gormDB.Joins("IPLD").First(&txCID, "tx_hash = ?", txHash).Error + if err != nil { + log.Error("header cid retrieval error") + return txCID, err + } + + return txCID, nil } diff --git a/pkg/eth/ipld_fetcher.go b/pkg/eth/ipld_fetcher.go index fa0d4c57..751f03f5 100644 --- a/pkg/eth/ipld_fetcher.go +++ b/pkg/eth/ipld_fetcher.go @@ -25,7 +25,6 @@ import ( "github.com/ethereum/go-ethereum/statediff/indexer/models" "github.com/jmoiron/sqlx" log "github.com/sirupsen/logrus" - "github.com/thoas/go-funk" "github.com/vulcanize/ipld-eth-server/v3/pkg/shared" ) @@ -113,40 +112,6 @@ func (f *IPLDFetcher) FetchHeader(tx *sqlx.Tx, c models.HeaderModel) (models.IPL }, nil } -// FetchHeaders fetches headers -func (f *IPLDFetcher) FetchHeaders(tx *sqlx.Tx, cids []models.HeaderModel) ([]models.IPLDModel, error) { - log.Debug("fetching header iplds") - headerIPLDs := make([]models.IPLDModel, len(cids)) - - if len(cids) < 1 { - return headerIPLDs, nil - } - - mhKeys := make([]string, len(cids)) - for i, c := range cids { - var err error - mhKeys[i] = c.MhKey - if err != nil { - return nil, err - } - } - - fetchedIPLDs, err := shared.FetchIPLDsByMhKeys(tx, mhKeys) - if err != nil { - return nil, err - } - - for i, c := range cids { - headerIPLD := funk.Find(fetchedIPLDs, func(ipld models.IPLDModel) bool { - return ipld.Key == c.MhKey - }).(models.IPLDModel) - - headerIPLDs[i] = headerIPLD - } - - return headerIPLDs, nil -} - // FetchUncles fetches uncles func (f *IPLDFetcher) FetchUncles(tx *sqlx.Tx, cids []models.UncleModel) ([]models.IPLDModel, error) { log.Debug("fetching uncle iplds") diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 1c8cc31b..b42de133 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -33,7 +33,6 @@ import ( "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/statediff/indexer/models" "github.com/vulcanize/ipld-eth-server/v3/pkg/eth" "github.com/vulcanize/ipld-eth-server/v3/pkg/shared" @@ -1264,19 +1263,17 @@ type EthHeaderCidCondition struct { func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { Condition *EthHeaderCidCondition }) (*EthHeaderCidsConnection, error) { - var headerCIDs []models.HeaderModel - var allTxCIDs [][]models.TxModel + var headerCIDs []eth.HeaderCid var err error if args.Condition.BlockHash != nil { - headerCID, txCIDs, err := r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(common.HexToHash(*args.Condition.BlockHash)) + headerCID, err := r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(common.HexToHash(*args.Condition.BlockHash)) if err != nil { return nil, err } headerCIDs = append(headerCIDs, headerCID) - allTxCIDs = append(allTxCIDs, txCIDs) } else if args.Condition.BlockNumber != nil { - headerCIDs, allTxCIDs, err = r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockNumber(args.Condition.BlockNumber.ToInt().Int64()) + headerCIDs, err = r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockNumber(args.Condition.BlockNumber.ToInt().Int64()) if err != nil { return nil, err } @@ -1300,13 +1297,8 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { } }() - headerIPLDs, err := r.backend.Fetcher.FetchHeaders(tx, headerCIDs) - if err != nil { - return nil, err - } - var resultNodes []*EthHeaderCid - for idx, headerCID := range headerCIDs { + for _, headerCID := range headerCIDs { var blockNumber BigInt blockNumber.UnmarshalText([]byte(headerCID.BlockNumber)) @@ -1328,10 +1320,13 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { receiptRoot: headerCID.RctRoot, uncleRoot: headerCID.UncleRoot, bloom: Bytes(headerCID.Bloom).String(), + ipfsBlock: IPFSBlock{ + key: headerCID.IPLD.Key, + data: Bytes(headerCID.IPLD.Data).String(), + }, } - txCIDs := allTxCIDs[idx] - for _, txCID := range txCIDs { + for _, txCID := range headerCID.TransactionCids { ethHeaderCidNode.transactions = append(ethHeaderCidNode.transactions, &EthTransactionCid{ cid: txCID.CID, txHash: txCID.TxHash, @@ -1341,11 +1336,6 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { }) } - ethHeaderCidNode.ipfsBlock = IPFSBlock{ - key: headerIPLDs[idx].Key, - data: Bytes(headerIPLDs[idx].Data).String(), - } - resultNodes = append(resultNodes, ðHeaderCidNode) } @@ -1363,27 +1353,6 @@ func (r *Resolver) EthTransactionCidByTxHash(ctx context.Context, args struct { return nil, err } - // Begin tx - tx, err := r.backend.DB.Beginx() - if err != nil { - return nil, err - } - defer func() { - if p := recover(); p != nil { - shared.Rollback(tx) - panic(p) - } else if err != nil { - shared.Rollback(tx) - } else { - err = tx.Commit() - } - }() - - txIPLDs, err := r.backend.Fetcher.FetchTrxs(tx, []models.TxModel{txCID}) - if err != nil { - return nil, err - } - return &EthTransactionCid{ cid: txCID.CID, txHash: txCID.TxHash, @@ -1391,8 +1360,8 @@ func (r *Resolver) EthTransactionCidByTxHash(ctx context.Context, args struct { src: txCID.Src, dst: txCID.Dst, ipfsBlock: IPFSBlock{ - key: txIPLDs[0].Key, - data: Bytes(txIPLDs[0].Data).String(), + key: txCID.IPLD.Key, + data: Bytes(txCID.IPLD.Data).String(), }, }, nil } diff --git a/pkg/graphql/graphql_test.go b/pkg/graphql/graphql_test.go index fc8259a4..4744005b 100644 --- a/pkg/graphql/graphql_test.go +++ b/pkg/graphql/graphql_test.go @@ -31,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/statediff" - "github.com/ethereum/go-ethereum/statediff/indexer/models" sdtypes "github.com/ethereum/go-ethereum/statediff/types" "github.com/jmoiron/sqlx" . "github.com/onsi/ginkgo" @@ -258,30 +257,13 @@ var _ = Describe("GraphQL", func() { allEthHeaderCidsResp, err := client.AllEthHeaderCids(ctx, graphql.EthHeaderCidCondition{BlockNumber: new(graphql.BigInt).SetUint64(2)}) Expect(err).ToNot(HaveOccurred()) - headerCIDs, txCIDs, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockNumber(2) - Expect(err).ToNot(HaveOccurred()) - - // Begin tx - tx, err := backend.DB.Beginx() - Expect(err).ToNot(HaveOccurred()) - defer func() { - if p := recover(); p != nil { - shared.Rollback(tx) - panic(p) - } else if err != nil { - shared.Rollback(tx) - } else { - err = tx.Commit() - } - }() - - headerIPLDs, err := backend.Fetcher.FetchHeaders(tx, headerCIDs) + headerCIDs, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockNumber(2) Expect(err).ToNot(HaveOccurred()) for idx, headerCID := range headerCIDs { ethHeaderCid := allEthHeaderCidsResp.Nodes[idx] - compareEthHeaderCid(ethHeaderCid, headerCID, txCIDs[idx], headerIPLDs[idx]) + compareEthHeaderCid(ethHeaderCid, headerCID) } }) @@ -290,30 +272,12 @@ var _ = Describe("GraphQL", func() { allEthHeaderCidsResp, err := client.AllEthHeaderCids(ctx, graphql.EthHeaderCidCondition{BlockHash: &blockHash}) Expect(err).ToNot(HaveOccurred()) - headerCID, txCIDs, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(blocks[1].Hash()) + headerCID, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(blocks[1].Hash()) Expect(err).ToNot(HaveOccurred()) - // Begin tx - tx, err := backend.DB.Beginx() - Expect(err).ToNot(HaveOccurred()) - defer func() { - if p := recover(); p != nil { - shared.Rollback(tx) - panic(p) - } else if err != nil { - shared.Rollback(tx) - } else { - err = tx.Commit() - } - }() - - headerIPLDs, err := backend.Fetcher.FetchHeaders(tx, []models.HeaderModel{headerCID}) - Expect(err).ToNot(HaveOccurred()) - Expect(len(allEthHeaderCidsResp.Nodes)).To(Equal(1)) - Expect(len(allEthHeaderCidsResp.Nodes)).To(Equal(1)) ethHeaderCid := allEthHeaderCidsResp.Nodes[0] - compareEthHeaderCid(ethHeaderCid, headerCID, txCIDs, headerIPLDs[0]) + compareEthHeaderCid(ethHeaderCid, headerCID) }) }) @@ -328,29 +292,12 @@ var _ = Describe("GraphQL", func() { compareEthTxCid(*ethTransactionCidResp, txCID) - // Begin tx - tx, err := backend.DB.Beginx() - Expect(err).ToNot(HaveOccurred()) - defer func() { - if p := recover(); p != nil { - shared.Rollback(tx) - panic(p) - } else if err != nil { - shared.Rollback(tx) - } else { - err = tx.Commit() - } - }() - - txIPLDs, err := backend.Fetcher.FetchTrxs(tx, []models.TxModel{txCID}) - Expect(err).ToNot(HaveOccurred()) - Expect(len(txIPLDs)).To(Equal(1)) - Expect(ethTransactionCidResp.BlockByMhKey.Data).To(Equal(graphql.Bytes(txIPLDs[0].Data).String())) + Expect(ethTransactionCidResp.BlockByMhKey.Data).To(Equal(graphql.Bytes(txCID.IPLD.Data).String())) }) }) }) -func compareEthHeaderCid(ethHeaderCid graphql.EthHeaderCidResp, headerCID models.HeaderModel, txCIDs []models.TxModel, headerIPLD models.IPLDModel) { +func compareEthHeaderCid(ethHeaderCid graphql.EthHeaderCidResp, headerCID eth.HeaderCid) { blockNumber, err := strconv.ParseInt(headerCID.BlockNumber, 10, 64) Expect(err).ToNot(HaveOccurred()) @@ -369,16 +316,16 @@ func compareEthHeaderCid(ethHeaderCid graphql.EthHeaderCidResp, headerCID models Expect(ethHeaderCid.UncleRoot).To(Equal(headerCID.UncleRoot)) Expect(ethHeaderCid.Bloom).To(Equal(graphql.Bytes(headerCID.Bloom).String())) - for tIdx, txCID := range txCIDs { + for tIdx, txCID := range headerCID.TransactionCids { ethTxCid := ethHeaderCid.EthTransactionCidsByHeaderId.Nodes[tIdx] compareEthTxCid(ethTxCid, txCID) } - Expect(ethHeaderCid.BlockByMhKey.Data).To(Equal(graphql.Bytes(headerIPLD.Data).String())) - Expect(ethHeaderCid.BlockByMhKey.Key).To(Equal(headerIPLD.Key)) + Expect(ethHeaderCid.BlockByMhKey.Data).To(Equal(graphql.Bytes(headerCID.IPLD.Data).String())) + Expect(ethHeaderCid.BlockByMhKey.Key).To(Equal(headerCID.IPLD.Key)) } -func compareEthTxCid(ethTxCid graphql.EthTransactionCidResp, txCID models.TxModel) { +func compareEthTxCid(ethTxCid graphql.EthTransactionCidResp, txCID eth.TransactionCid) { Expect(ethTxCid.Cid).To(Equal(txCID.CID)) Expect(ethTxCid.TxHash).To(Equal(txCID.TxHash)) Expect(ethTxCid.Index).To(Equal(int32(txCID.Index))) diff --git a/pkg/shared/functions.go b/pkg/shared/functions.go index eede20bc..b1ac4550 100644 --- a/pkg/shared/functions.go +++ b/pkg/shared/functions.go @@ -19,7 +19,6 @@ package shared import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/statediff/indexer/ipld" - "github.com/ethereum/go-ethereum/statediff/indexer/models" "github.com/ipfs/go-cid" blockstore "github.com/ipfs/go-ipfs-blockstore" dshelp "github.com/ipfs/go-ipfs-ds-help" @@ -78,19 +77,6 @@ func FetchIPLDByMhKey(tx *sqlx.Tx, mhKey string) ([]byte, error) { return block, tx.Get(&block, pgStr, mhKey) } -// FetchIPLDByMhKeysAndBlockNumbers is used to retrieve iplds from Postgres blockstore with the provided tx, mhkey strings and blockNumbers -func FetchIPLDsByMhKeys(tx *sqlx.Tx, mhKeys []string) ([]models.IPLDModel, error) { - var blocks []models.IPLDModel - pgStr := `SELECT key, data FROM public.blocks WHERE key IN (?)` - query, args, err := sqlx.In(pgStr, mhKeys) - if err != nil { - return blocks, err - } - query = tx.Rebind(query) - - return blocks, tx.Select(&blocks, query, args...) -} - // MultihashKeyFromCID converts a cid into a blockstore-prefixed multihash db key string func MultihashKeyFromCID(c cid.Cid) string { dbKey := dshelp.MultihashToDsKey(c.Hash()) -- 2.45.2 From c19cc5c44d823ff62944decb5cf6ee1fe3dd5f89 Mon Sep 17 00:00:00 2001 From: nabarun Date: Fri, 3 Jun 2022 14:45:52 +0530 Subject: [PATCH 11/13] Select required fields in transaction_cids --- pkg/eth/cid_retriever.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index 04a5c719..c554be75 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -673,7 +673,9 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(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").Joins("IPLD").Find(&headerCIDs, "block_number = ?", blockNumber).Error + err := ecr.gormDB.Preload("TransactionCids", func(tx *gorm.DB) *gorm.DB { + return tx.Select("cid", "tx_hash", "index", "src", "dst", "header_id") + }).Joins("IPLD").Find(&headerCIDs, "block_number = ?", blockNumber).Error if err != nil { log.Error("header cid retrieval error") return nil, err @@ -690,7 +692,9 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Has // 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").Joins("IPLD").First(&headerCID, "block_hash = ?", blockHash.String()).Error + err := ecr.gormDB.Preload("TransactionCids", func(tx *gorm.DB) *gorm.DB { + return tx.Select("cid", "tx_hash", "index", "src", "dst", "header_id") + }).Joins("IPLD").First(&headerCID, "block_hash = ?", blockHash.String()).Error if err != nil { log.Error("header cid retrieval error") return headerCID, err -- 2.45.2 From 31e9a7dc5ec7accf128dc8fa7b7a0e69f9069e3d Mon Sep 17 00:00:00 2001 From: nikugogoi <95nikass@gmail.com> Date: Mon, 6 Jun 2022 15:36:29 +0530 Subject: [PATCH 12/13] Review changes --- pkg/eth/cid_retriever.go | 40 ++++++++++++--------- pkg/graphql/client.go | 72 ++++++++++++++++++------------------- pkg/graphql/graphql.go | 2 +- pkg/graphql/graphql_test.go | 8 ++--- 4 files changed, 64 insertions(+), 58 deletions(-) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index c554be75..5da663a3 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -45,16 +45,16 @@ type CIDRetriever struct { gormDB *gorm.DB } -type IPLD struct { +type IPLDModelRecord struct { models.IPLDModel } // TableName overrides the table name used by IPLD -func (IPLD) TableName() string { +func (IPLDModelRecord) TableName() string { return "public.blocks" } -type HeaderCid struct { +type HeaderCidRecord struct { CID string `gorm:"column:cid"` BlockHash string `gorm:"primaryKey"` BlockNumber string @@ -67,16 +67,19 @@ type HeaderCid struct { UncleRoot string Bloom []byte MhKey string - TransactionCids []TransactionCid `gorm:"foreignKey:HeaderID;references:BlockHash"` - IPLD IPLD `gorm:"foreignKey:MhKey;references:Key"` + + // gorm doesn't check if foreign key exists in database. + // It is required to eager load relations using preload. + TransactionCids []TransactionCidRecord `gorm:"foreignKey:HeaderID;references:BlockHash"` + IPLD IPLDModelRecord `gorm:"foreignKey:MhKey;references:Key"` } // TableName overrides the table name used by HeaderCid -func (HeaderCid) TableName() string { +func (HeaderCidRecord) TableName() string { return "eth.header_cids" } -type TransactionCid struct { +type TransactionCidRecord struct { CID string `gorm:"column:cid"` TxHash string `gorm:"primaryKey"` HeaderID string `gorm:"column:header_id"` @@ -84,11 +87,11 @@ type TransactionCid struct { Src string Dst string MhKey string - IPLD IPLD `gorm:"foreignKey:MhKey;references:Key"` + IPLD IPLDModelRecord `gorm:"foreignKey:MhKey;references:Key"` } // TableName overrides the table name used by TransactionCid -func (TransactionCid) TableName() string { +func (TransactionCidRecord) TableName() string { return "eth.transaction_cids" } @@ -97,6 +100,7 @@ func NewCIDRetriever(db *sqlx.DB) *CIDRetriever { gormDB, err := gorm.Open(postgres.New(postgres.Config{ Conn: db, }), &gorm.Config{}) + if err != nil { log.Error(err) return nil @@ -227,7 +231,7 @@ func (ecr *CIDRetriever) RetrieveHeaderCIDs(tx *sqlx.Tx, blockNumber int64) ([]m log.Debug("retrieving header cids for block ", blockNumber) headers := make([]models.HeaderModel, 0) pgStr := `SELECT CAST(block_number as Text), block_hash,parent_hash,cid,mh_key,CAST(td as Text),node_id, - CAST(reward as Text), state_root,uncle_root,tx_root,receipt_root,bloom,timestamp,times_validated, + CAST(reward as Text), state_root, uncle_root, tx_root, receipt_root, bloom, timestamp, times_validated, coinbase FROM eth.header_cids WHERE block_number = $1` return headers, tx.Select(&headers, pgStr, blockNumber) @@ -636,7 +640,7 @@ func (ecr *CIDRetriever) RetrieveBlockByNumber(blockNumber int64) (models.Header func (ecr *CIDRetriever) RetrieveHeaderCIDByHash(tx *sqlx.Tx, blockHash common.Hash) (models.HeaderModel, error) { log.Debug("retrieving header cids for block hash ", blockHash.String()) pgStr := `SELECT block_hash, CAST(block_number as Text), parent_hash, cid, mh_key, CAST(td as Text), - state_root,uncle_root,tx_root,receipt_root,bloom,timestamp FROM eth.header_cids + state_root, uncle_root, tx_root, receipt_root, bloom, timestamp FROM eth.header_cids WHERE block_hash = $1` var headerCID models.HeaderModel return headerCID, tx.Get(&headerCID, pgStr, blockHash.String()) @@ -666,16 +670,17 @@ func (ecr *CIDRetriever) RetrieveReceiptCIDsByTxIDs(tx *sqlx.Tx, txHashes []stri } // RetrieveHeaderAndTxCIDsByBlockNumber retrieves header CIDs and their associated tx CIDs by block number -func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]HeaderCid, error) { +func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]HeaderCidRecord, error) { log.Debug("retrieving header cids and tx cids for block number ", blockNumber) - var headerCIDs []HeaderCid + var headerCIDs []HeaderCidRecord // 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") }).Joins("IPLD").Find(&headerCIDs, "block_number = ?", blockNumber).Error + if err != nil { log.Error("header cid retrieval error") return nil, err @@ -685,16 +690,17 @@ 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) (HeaderCid, error) { +func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash) (HeaderCidRecord, error) { log.Debug("retrieving header cid and tx cids for block hash ", blockHash.String()) - var headerCID HeaderCid + var headerCID HeaderCidRecord // 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") }).Joins("IPLD").First(&headerCID, "block_hash = ?", blockHash.String()).Error + if err != nil { log.Error("header cid retrieval error") return headerCID, err @@ -704,10 +710,10 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Has } // RetrieveTxCIDByHash returns the tx for the given tx hash -func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string) (TransactionCid, error) { +func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string) (TransactionCidRecord, error) { log.Debug("retrieving tx cid for tx hash ", txHash) - var txCID TransactionCid + var txCID TransactionCidRecord err := ecr.gormDB.Joins("IPLD").First(&txCID, "tx_hash = ?", txHash).Error if err != nil { diff --git a/pkg/graphql/client.go b/pkg/graphql/client.go index 53420db8..80b32c96 100644 --- a/pkg/graphql/client.go +++ b/pkg/graphql/client.go @@ -21,14 +21,14 @@ type GetStorageAt struct { } type LogResponse struct { - Topics []common.Hash `json:"topics"` - Data hexutil.Bytes `json:"data"` - Transaction TransactionResp `json:"transaction"` - ReceiptCID string `json:"receiptCID"` - Status int32 `json:"status"` + Topics []common.Hash `json:"topics"` + Data hexutil.Bytes `json:"data"` + Transaction TransactionResponse `json:"transaction"` + ReceiptCID string `json:"receiptCID"` + Status int32 `json:"status"` } -type TransactionResp struct { +type TransactionResponse struct { Hash common.Hash `json:"hash"` } @@ -36,50 +36,50 @@ type GetLogs struct { Responses []LogResponse `json:"getLogs"` } -type IPFSBlockResp struct { +type IPFSBlockResponse struct { Key string `json:"key"` Data string `json:"data"` } -type EthTransactionCidResp struct { - Cid string `json:"cid"` - TxHash string `json:"txHash"` - Index int32 `json:"index"` - Src string `json:"src"` - Dst string `json:"dst"` - BlockByMhKey IPFSBlockResp `json:"blockByMhKey"` +type EthTransactionCidResponse struct { + Cid string `json:"cid"` + TxHash string `json:"txHash"` + Index int32 `json:"index"` + Src string `json:"src"` + Dst string `json:"dst"` + BlockByMhKey IPFSBlockResponse `json:"blockByMhKey"` } type EthTransactionCidByTxHash struct { - Response EthTransactionCidResp `json:"ethTransactionCidByTxHash"` + Response EthTransactionCidResponse `json:"ethTransactionCidByTxHash"` } -type EthTransactionCidsByHeaderIdResp struct { - Nodes []EthTransactionCidResp `json:"nodes"` +type EthTransactionCidsByHeaderIdResponse struct { + Nodes []EthTransactionCidResponse `json:"nodes"` } -type EthHeaderCidResp struct { - Cid string `json:"cid"` - BlockNumber BigInt `json:"blockNumber"` - BlockHash string `json:"blockHash"` - ParentHash string `json:"parentHash"` - Timestamp BigInt `json:"timestamp"` - StateRoot string `json:"stateRoot"` - Td BigInt `json:"td"` - TxRoot string `json:"txRoot"` - ReceiptRoot string `json:"receiptRoot"` - UncleRoot string `json:"uncleRoot"` - Bloom string `json:"bloom"` - EthTransactionCidsByHeaderId EthTransactionCidsByHeaderIdResp `json:"ethTransactionCidsByHeaderId"` - BlockByMhKey IPFSBlockResp `json:"blockByMhKey"` +type EthHeaderCidResponse struct { + Cid string `json:"cid"` + BlockNumber BigInt `json:"blockNumber"` + BlockHash string `json:"blockHash"` + ParentHash string `json:"parentHash"` + Timestamp BigInt `json:"timestamp"` + StateRoot string `json:"stateRoot"` + Td BigInt `json:"td"` + TxRoot string `json:"txRoot"` + ReceiptRoot string `json:"receiptRoot"` + UncleRoot string `json:"uncleRoot"` + Bloom string `json:"bloom"` + EthTransactionCidsByHeaderId EthTransactionCidsByHeaderIdResponse `json:"ethTransactionCidsByHeaderId"` + BlockByMhKey IPFSBlockResponse `json:"blockByMhKey"` } -type AllEthHeaderCidsResp struct { - Nodes []EthHeaderCidResp `json:"nodes"` +type AllEthHeaderCidsResponse struct { + Nodes []EthHeaderCidResponse `json:"nodes"` } type AllEthHeaderCids struct { - Response AllEthHeaderCidsResp `json:"allEthHeaderCids"` + Response AllEthHeaderCidsResponse `json:"allEthHeaderCids"` } type Client struct { @@ -164,7 +164,7 @@ func (c *Client) GetStorageAt(ctx context.Context, hash common.Hash, address com return &storageAt.Response, nil } -func (c *Client) AllEthHeaderCids(ctx context.Context, condition EthHeaderCidCondition) (*AllEthHeaderCidsResp, error) { +func (c *Client) AllEthHeaderCids(ctx context.Context, condition EthHeaderCidCondition) (*AllEthHeaderCidsResponse, error) { var params string if condition.BlockHash != nil { params = fmt.Sprintf(`blockHash: "%s"`, *condition.BlockHash) @@ -228,7 +228,7 @@ func (c *Client) AllEthHeaderCids(ctx context.Context, condition EthHeaderCidCon return &allEthHeaderCids.Response, nil } -func (c *Client) EthTransactionCidByTxHash(ctx context.Context, txHash string) (*EthTransactionCidResp, error) { +func (c *Client) EthTransactionCidByTxHash(ctx context.Context, txHash string) (*EthTransactionCidResponse, error) { getTxQuery := fmt.Sprintf(` query{ ethTransactionCidByTxHash(txHash: "%s") { diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index b42de133..137409d7 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -1263,7 +1263,7 @@ type EthHeaderCidCondition struct { func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { Condition *EthHeaderCidCondition }) (*EthHeaderCidsConnection, error) { - var headerCIDs []eth.HeaderCid + var headerCIDs []eth.HeaderCidRecord var err error if args.Condition.BlockHash != nil { headerCID, err := r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(common.HexToHash(*args.Condition.BlockHash)) diff --git a/pkg/graphql/graphql_test.go b/pkg/graphql/graphql_test.go index 4744005b..f61c9b65 100644 --- a/pkg/graphql/graphql_test.go +++ b/pkg/graphql/graphql_test.go @@ -181,7 +181,7 @@ var _ = Describe("GraphQL", func() { { Topics: test_helpers.MockLog1.Topics, Data: hexutil.Bytes(test_helpers.MockLog1.Data), - Transaction: graphql.TransactionResp{Hash: test_helpers.MockTransactions[0].Hash()}, + Transaction: graphql.TransactionResponse{Hash: test_helpers.MockTransactions[0].Hash()}, ReceiptCID: test_helpers.Rct1CID.String(), Status: int32(test_helpers.MockReceipts[0].Status), }, @@ -198,7 +198,7 @@ var _ = Describe("GraphQL", func() { { Topics: test_helpers.MockLog6.Topics, Data: hexutil.Bytes(test_helpers.MockLog6.Data), - Transaction: graphql.TransactionResp{Hash: test_helpers.MockTransactions[3].Hash()}, + Transaction: graphql.TransactionResponse{Hash: test_helpers.MockTransactions[3].Hash()}, ReceiptCID: test_helpers.Rct4CID.String(), Status: int32(test_helpers.MockReceipts[3].Status), }, @@ -297,7 +297,7 @@ var _ = Describe("GraphQL", func() { }) }) -func compareEthHeaderCid(ethHeaderCid graphql.EthHeaderCidResp, headerCID eth.HeaderCid) { +func compareEthHeaderCid(ethHeaderCid graphql.EthHeaderCidResponse, headerCID eth.HeaderCidRecord) { blockNumber, err := strconv.ParseInt(headerCID.BlockNumber, 10, 64) Expect(err).ToNot(HaveOccurred()) @@ -325,7 +325,7 @@ func compareEthHeaderCid(ethHeaderCid graphql.EthHeaderCidResp, headerCID eth.He Expect(ethHeaderCid.BlockByMhKey.Key).To(Equal(headerCID.IPLD.Key)) } -func compareEthTxCid(ethTxCid graphql.EthTransactionCidResp, txCID eth.TransactionCid) { +func compareEthTxCid(ethTxCid graphql.EthTransactionCidResponse, txCID eth.TransactionCidRecord) { Expect(ethTxCid.Cid).To(Equal(txCID.CID)) Expect(ethTxCid.TxHash).To(Equal(txCID.TxHash)) Expect(ethTxCid.Index).To(Equal(int32(txCID.Index))) -- 2.45.2 From 1fc53ccab159bf935dd7cce1023b5a81d8cecc27 Mon Sep 17 00:00:00 2001 From: nikugogoi <95nikass@gmail.com> Date: Mon, 6 Jun 2022 16:46:53 +0530 Subject: [PATCH 13/13] Rename Cid to CID --- pkg/eth/cid_retriever.go | 42 +++++++++---------- pkg/graphql/client.go | 44 ++++++++++---------- pkg/graphql/graphql.go | 82 ++++++++++++++++++------------------- pkg/graphql/graphql_test.go | 66 ++++++++++++++--------------- 4 files changed, 117 insertions(+), 117 deletions(-) diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go index 5da663a3..7e27342b 100644 --- a/pkg/eth/cid_retriever.go +++ b/pkg/eth/cid_retriever.go @@ -54,7 +54,7 @@ func (IPLDModelRecord) TableName() string { return "public.blocks" } -type HeaderCidRecord struct { +type HeaderCIDRecord struct { CID string `gorm:"column:cid"` BlockHash string `gorm:"primaryKey"` BlockNumber string @@ -70,16 +70,16 @@ type HeaderCidRecord struct { // gorm doesn't check if foreign key exists in database. // It is required to eager load relations using preload. - TransactionCids []TransactionCidRecord `gorm:"foreignKey:HeaderID;references:BlockHash"` + TransactionCIDs []TransactionCIDRecord `gorm:"foreignKey:HeaderID;references:BlockHash"` IPLD IPLDModelRecord `gorm:"foreignKey:MhKey;references:Key"` } -// TableName overrides the table name used by HeaderCid -func (HeaderCidRecord) TableName() string { +// TableName overrides the table name used by HeaderCIDRecord +func (HeaderCIDRecord) TableName() string { return "eth.header_cids" } -type TransactionCidRecord struct { +type TransactionCIDRecord struct { CID string `gorm:"column:cid"` TxHash string `gorm:"primaryKey"` HeaderID string `gorm:"column:header_id"` @@ -90,8 +90,8 @@ type TransactionCidRecord struct { IPLD IPLDModelRecord `gorm:"foreignKey:MhKey;references:Key"` } -// TableName overrides the table name used by TransactionCid -func (TransactionCidRecord) TableName() string { +// TableName overrides the table name used by TransactionCIDRecord +func (TransactionCIDRecord) TableName() string { return "eth.transaction_cids" } @@ -367,8 +367,8 @@ func (ecr *CIDRetriever) RetrieveRctCIDsByHeaderID(tx *sqlx.Tx, rctFilter Receip pgStr, args = receiptFilterConditions(&id, pgStr, args, rctFilter, trxHashes) pgStr += ` ORDER BY transaction_cids.index` - receiptCids := make([]models.ReceiptModel, 0) - return receiptCids, tx.Select(&receiptCids, pgStr, args...) + receiptCIDs := make([]models.ReceiptModel, 0) + return receiptCIDs, tx.Select(&receiptCIDs, pgStr, args...) } // RetrieveFilteredGQLLogs retrieves and returns all the log cIDs provided blockHash that conform to the provided @@ -462,8 +462,8 @@ func (ecr *CIDRetriever) RetrieveRctCIDs(tx *sqlx.Tx, rctFilter ReceiptFilter, b pgStr, args = receiptFilterConditions(&id, pgStr, args, rctFilter, txHashes) pgStr += ` ORDER BY transaction_cids.index` - receiptCids := make([]models.ReceiptModel, 0) - return receiptCids, tx.Select(&receiptCids, pgStr, args...) + receiptCIDs := make([]models.ReceiptModel, 0) + return receiptCIDs, tx.Select(&receiptCIDs, pgStr, args...) } func hasTopics(topics [][]string) bool { @@ -670,14 +670,14 @@ func (ecr *CIDRetriever) RetrieveReceiptCIDsByTxIDs(tx *sqlx.Tx, txHashes []stri } // RetrieveHeaderAndTxCIDsByBlockNumber retrieves header CIDs and their associated tx CIDs by block number -func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]HeaderCidRecord, error) { +func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]HeaderCIDRecord, error) { log.Debug("retrieving header cids and tx cids for block number ", blockNumber) - var headerCIDs []HeaderCidRecord + var headerCIDs []HeaderCIDRecord // 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 { + // 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") }).Joins("IPLD").Find(&headerCIDs, "block_number = ?", blockNumber).Error @@ -690,14 +690,14 @@ 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) (HeaderCIDRecord, error) { log.Debug("retrieving header cid and tx cids for block hash ", blockHash.String()) - var headerCID HeaderCidRecord + var headerCID HeaderCIDRecord // 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 { + // 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") }).Joins("IPLD").First(&headerCID, "block_hash = ?", blockHash.String()).Error @@ -710,10 +710,10 @@ func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Has } // RetrieveTxCIDByHash returns the tx for the given tx hash -func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string) (TransactionCidRecord, error) { +func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string) (TransactionCIDRecord, error) { log.Debug("retrieving tx cid for tx hash ", txHash) - var txCID TransactionCidRecord + var txCID TransactionCIDRecord err := ecr.gormDB.Joins("IPLD").First(&txCID, "tx_hash = ?", txHash).Error if err != nil { diff --git a/pkg/graphql/client.go b/pkg/graphql/client.go index 80b32c96..096b7a06 100644 --- a/pkg/graphql/client.go +++ b/pkg/graphql/client.go @@ -11,7 +11,7 @@ import ( ) type StorageResponse struct { - Cid string `json:"cid"` + CID string `json:"cid"` Value common.Hash `json:"value"` IpldBlock hexutil.Bytes `json:"ipldBlock"` } @@ -41,8 +41,8 @@ type IPFSBlockResponse struct { Data string `json:"data"` } -type EthTransactionCidResponse struct { - Cid string `json:"cid"` +type EthTransactionCIDResponse struct { + CID string `json:"cid"` TxHash string `json:"txHash"` Index int32 `json:"index"` Src string `json:"src"` @@ -50,16 +50,16 @@ type EthTransactionCidResponse struct { BlockByMhKey IPFSBlockResponse `json:"blockByMhKey"` } -type EthTransactionCidByTxHash struct { - Response EthTransactionCidResponse `json:"ethTransactionCidByTxHash"` +type EthTransactionCIDByTxHash struct { + Response EthTransactionCIDResponse `json:"ethTransactionCidByTxHash"` } -type EthTransactionCidsByHeaderIdResponse struct { - Nodes []EthTransactionCidResponse `json:"nodes"` +type EthTransactionCIDsByHeaderIdResponse struct { + Nodes []EthTransactionCIDResponse `json:"nodes"` } -type EthHeaderCidResponse struct { - Cid string `json:"cid"` +type EthHeaderCIDResponse struct { + CID string `json:"cid"` BlockNumber BigInt `json:"blockNumber"` BlockHash string `json:"blockHash"` ParentHash string `json:"parentHash"` @@ -70,16 +70,16 @@ type EthHeaderCidResponse struct { ReceiptRoot string `json:"receiptRoot"` UncleRoot string `json:"uncleRoot"` Bloom string `json:"bloom"` - EthTransactionCidsByHeaderId EthTransactionCidsByHeaderIdResponse `json:"ethTransactionCidsByHeaderId"` + EthTransactionCIDsByHeaderId EthTransactionCIDsByHeaderIdResponse `json:"ethTransactionCidsByHeaderId"` BlockByMhKey IPFSBlockResponse `json:"blockByMhKey"` } -type AllEthHeaderCidsResponse struct { - Nodes []EthHeaderCidResponse `json:"nodes"` +type AllEthHeaderCIDsResponse struct { + Nodes []EthHeaderCIDResponse `json:"nodes"` } -type AllEthHeaderCids struct { - Response AllEthHeaderCidsResponse `json:"allEthHeaderCids"` +type AllEthHeaderCIDs struct { + Response AllEthHeaderCIDsResponse `json:"allEthHeaderCids"` } type Client struct { @@ -164,7 +164,7 @@ func (c *Client) GetStorageAt(ctx context.Context, hash common.Hash, address com return &storageAt.Response, nil } -func (c *Client) AllEthHeaderCids(ctx context.Context, condition EthHeaderCidCondition) (*AllEthHeaderCidsResponse, error) { +func (c *Client) AllEthHeaderCIDs(ctx context.Context, condition EthHeaderCIDCondition) (*AllEthHeaderCIDsResponse, error) { var params string if condition.BlockHash != nil { params = fmt.Sprintf(`blockHash: "%s"`, *condition.BlockHash) @@ -220,15 +220,15 @@ func (c *Client) AllEthHeaderCids(ctx context.Context, condition EthHeaderCidCon return nil, err } - var allEthHeaderCids AllEthHeaderCids - err = json.Unmarshal(jsonStr, &allEthHeaderCids) + var allEthHeaderCIDs AllEthHeaderCIDs + err = json.Unmarshal(jsonStr, &allEthHeaderCIDs) if err != nil { return nil, err } - return &allEthHeaderCids.Response, nil + return &allEthHeaderCIDs.Response, nil } -func (c *Client) EthTransactionCidByTxHash(ctx context.Context, txHash string) (*EthTransactionCidResponse, error) { +func (c *Client) EthTransactionCIDByTxHash(ctx context.Context, txHash string) (*EthTransactionCIDResponse, error) { getTxQuery := fmt.Sprintf(` query{ ethTransactionCidByTxHash(txHash: "%s") { @@ -258,10 +258,10 @@ func (c *Client) EthTransactionCidByTxHash(ctx context.Context, txHash string) ( return nil, err } - var ethTxCid EthTransactionCidByTxHash - err = json.Unmarshal(jsonStr, ðTxCid) + var ethTxCID EthTransactionCIDByTxHash + err = json.Unmarshal(jsonStr, ðTxCID) if err != nil { return nil, err } - return ðTxCid.Response, nil + return ðTxCID.Response, nil } diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 137409d7..853afec9 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -1125,7 +1125,7 @@ func decomposeGQLLogs(logCIDs []eth.LogResult) []logsCID { return logs } -type EthTransactionCid struct { +type EthTransactionCID struct { cid string txHash string index int32 @@ -1134,35 +1134,35 @@ type EthTransactionCid struct { ipfsBlock IPFSBlock } -func (t EthTransactionCid) Cid(ctx context.Context) string { +func (t EthTransactionCID) Cid(ctx context.Context) string { return t.cid } -func (t EthTransactionCid) TxHash(ctx context.Context) string { +func (t EthTransactionCID) TxHash(ctx context.Context) string { return t.txHash } -func (t EthTransactionCid) Index(ctx context.Context) int32 { +func (t EthTransactionCID) Index(ctx context.Context) int32 { return t.index } -func (t EthTransactionCid) Src(ctx context.Context) string { +func (t EthTransactionCID) Src(ctx context.Context) string { return t.src } -func (t EthTransactionCid) Dst(ctx context.Context) string { +func (t EthTransactionCID) Dst(ctx context.Context) string { return t.dst } -func (t EthTransactionCid) BlockByMhKey(ctx context.Context) IPFSBlock { +func (t EthTransactionCID) BlockByMhKey(ctx context.Context) IPFSBlock { return t.ipfsBlock } -type EthTransactionCidsConnection struct { - nodes []*EthTransactionCid +type EthTransactionCIDsConnection struct { + nodes []*EthTransactionCID } -func (transactionCIDResult EthTransactionCidsConnection) Nodes(ctx context.Context) []*EthTransactionCid { +func (transactionCIDResult EthTransactionCIDsConnection) Nodes(ctx context.Context) []*EthTransactionCID { return transactionCIDResult.nodes } @@ -1179,7 +1179,7 @@ func (b IPFSBlock) Data(ctx context.Context) string { return b.data } -type EthHeaderCid struct { +type EthHeaderCID struct { cid string blockNumber BigInt blockHash string @@ -1191,79 +1191,79 @@ type EthHeaderCid struct { receiptRoot string uncleRoot string bloom string - transactions []*EthTransactionCid + transactions []*EthTransactionCID ipfsBlock IPFSBlock } -func (h EthHeaderCid) Cid(ctx context.Context) string { +func (h EthHeaderCID) Cid(ctx context.Context) string { return h.cid } -func (h EthHeaderCid) BlockNumber(ctx context.Context) BigInt { +func (h EthHeaderCID) BlockNumber(ctx context.Context) BigInt { return h.blockNumber } -func (h EthHeaderCid) BlockHash(ctx context.Context) string { +func (h EthHeaderCID) BlockHash(ctx context.Context) string { return h.blockHash } -func (h EthHeaderCid) ParentHash(ctx context.Context) string { +func (h EthHeaderCID) ParentHash(ctx context.Context) string { return h.parentHash } -func (h EthHeaderCid) Timestamp(ctx context.Context) BigInt { +func (h EthHeaderCID) Timestamp(ctx context.Context) BigInt { return h.timestamp } -func (h EthHeaderCid) StateRoot(ctx context.Context) string { +func (h EthHeaderCID) StateRoot(ctx context.Context) string { return h.stateRoot } -func (h EthHeaderCid) Td(ctx context.Context) BigInt { +func (h EthHeaderCID) Td(ctx context.Context) BigInt { return h.td } -func (h EthHeaderCid) TxRoot(ctx context.Context) string { +func (h EthHeaderCID) TxRoot(ctx context.Context) string { return h.txRoot } -func (h EthHeaderCid) ReceiptRoot(ctx context.Context) string { +func (h EthHeaderCID) ReceiptRoot(ctx context.Context) string { return h.receiptRoot } -func (h EthHeaderCid) UncleRoot(ctx context.Context) string { +func (h EthHeaderCID) UncleRoot(ctx context.Context) string { return h.uncleRoot } -func (h EthHeaderCid) Bloom(ctx context.Context) string { +func (h EthHeaderCID) Bloom(ctx context.Context) string { return h.bloom } -func (h EthHeaderCid) EthTransactionCidsByHeaderId(ctx context.Context) EthTransactionCidsConnection { - return EthTransactionCidsConnection{nodes: h.transactions} +func (h EthHeaderCID) EthTransactionCidsByHeaderId(ctx context.Context) EthTransactionCIDsConnection { + return EthTransactionCIDsConnection{nodes: h.transactions} } -func (h EthHeaderCid) BlockByMhKey(ctx context.Context) IPFSBlock { +func (h EthHeaderCID) BlockByMhKey(ctx context.Context) IPFSBlock { return h.ipfsBlock } -type EthHeaderCidsConnection struct { - nodes []*EthHeaderCid +type EthHeaderCIDsConnection struct { + nodes []*EthHeaderCID } -func (headerCIDResult EthHeaderCidsConnection) Nodes(ctx context.Context) []*EthHeaderCid { +func (headerCIDResult EthHeaderCIDsConnection) Nodes(ctx context.Context) []*EthHeaderCID { return headerCIDResult.nodes } -type EthHeaderCidCondition struct { +type EthHeaderCIDCondition struct { BlockNumber *BigInt BlockHash *string } func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { - Condition *EthHeaderCidCondition -}) (*EthHeaderCidsConnection, error) { - var headerCIDs []eth.HeaderCidRecord + Condition *EthHeaderCIDCondition +}) (*EthHeaderCIDsConnection, error) { + var headerCIDs []eth.HeaderCIDRecord var err error if args.Condition.BlockHash != nil { headerCID, err := r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(common.HexToHash(*args.Condition.BlockHash)) @@ -1297,7 +1297,7 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { } }() - var resultNodes []*EthHeaderCid + var resultNodes []*EthHeaderCID for _, headerCID := range headerCIDs { var blockNumber BigInt blockNumber.UnmarshalText([]byte(headerCID.BlockNumber)) @@ -1308,7 +1308,7 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { var td BigInt td.UnmarshalText([]byte(headerCID.TotalDifficulty)) - ethHeaderCidNode := EthHeaderCid{ + ethHeaderCIDNode := EthHeaderCID{ cid: headerCID.CID, blockNumber: blockNumber, blockHash: headerCID.BlockHash, @@ -1326,8 +1326,8 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { }, } - for _, txCID := range headerCID.TransactionCids { - ethHeaderCidNode.transactions = append(ethHeaderCidNode.transactions, &EthTransactionCid{ + for _, txCID := range headerCID.TransactionCIDs { + ethHeaderCIDNode.transactions = append(ethHeaderCIDNode.transactions, &EthTransactionCID{ cid: txCID.CID, txHash: txCID.TxHash, index: int32(txCID.Index), @@ -1336,24 +1336,24 @@ func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct { }) } - resultNodes = append(resultNodes, ðHeaderCidNode) + resultNodes = append(resultNodes, ðHeaderCIDNode) } - return &EthHeaderCidsConnection{ + return &EthHeaderCIDsConnection{ nodes: resultNodes, }, nil } func (r *Resolver) EthTransactionCidByTxHash(ctx context.Context, args struct { TxHash string -}) (*EthTransactionCid, error) { +}) (*EthTransactionCID, error) { txCID, err := r.backend.Retriever.RetrieveTxCIDByHash(args.TxHash) if err != nil { return nil, err } - return &EthTransactionCid{ + return &EthTransactionCID{ cid: txCID.CID, txHash: txCID.TxHash, index: int32(txCID.Index), diff --git a/pkg/graphql/graphql_test.go b/pkg/graphql/graphql_test.go index f61c9b65..33397572 100644 --- a/pkg/graphql/graphql_test.go +++ b/pkg/graphql/graphql_test.go @@ -254,81 +254,81 @@ var _ = Describe("GraphQL", func() { Describe("allEthHeaderCids", func() { It("Retrieves header_cids that matches the provided blockNumber", func() { - allEthHeaderCidsResp, err := client.AllEthHeaderCids(ctx, graphql.EthHeaderCidCondition{BlockNumber: new(graphql.BigInt).SetUint64(2)}) + allEthHeaderCIDsResp, err := client.AllEthHeaderCIDs(ctx, graphql.EthHeaderCIDCondition{BlockNumber: new(graphql.BigInt).SetUint64(2)}) Expect(err).ToNot(HaveOccurred()) headerCIDs, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockNumber(2) Expect(err).ToNot(HaveOccurred()) for idx, headerCID := range headerCIDs { - ethHeaderCid := allEthHeaderCidsResp.Nodes[idx] + ethHeaderCID := allEthHeaderCIDsResp.Nodes[idx] - compareEthHeaderCid(ethHeaderCid, headerCID) + compareEthHeaderCID(ethHeaderCID, headerCID) } }) It("Retrieves header_cids that matches the provided blockHash", func() { blockHash := blocks[1].Hash().String() - allEthHeaderCidsResp, err := client.AllEthHeaderCids(ctx, graphql.EthHeaderCidCondition{BlockHash: &blockHash}) + allEthHeaderCIDsResp, err := client.AllEthHeaderCIDs(ctx, graphql.EthHeaderCIDCondition{BlockHash: &blockHash}) Expect(err).ToNot(HaveOccurred()) headerCID, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(blocks[1].Hash()) Expect(err).ToNot(HaveOccurred()) - Expect(len(allEthHeaderCidsResp.Nodes)).To(Equal(1)) - ethHeaderCid := allEthHeaderCidsResp.Nodes[0] - compareEthHeaderCid(ethHeaderCid, headerCID) + Expect(len(allEthHeaderCIDsResp.Nodes)).To(Equal(1)) + ethHeaderCID := allEthHeaderCIDsResp.Nodes[0] + compareEthHeaderCID(ethHeaderCID, headerCID) }) }) Describe("ethTransactionCidByTxHash", func() { It("Retrieves tx_cid that matches the provided txHash", func() { txHash := blocks[2].Transactions()[0].Hash().String() - ethTransactionCidResp, err := client.EthTransactionCidByTxHash(ctx, txHash) + ethTransactionCIDResp, err := client.EthTransactionCIDByTxHash(ctx, txHash) Expect(err).ToNot(HaveOccurred()) txCID, err := backend.Retriever.RetrieveTxCIDByHash(txHash) Expect(err).ToNot(HaveOccurred()) - compareEthTxCid(*ethTransactionCidResp, txCID) + compareEthTxCID(*ethTransactionCIDResp, txCID) - Expect(ethTransactionCidResp.BlockByMhKey.Data).To(Equal(graphql.Bytes(txCID.IPLD.Data).String())) + Expect(ethTransactionCIDResp.BlockByMhKey.Data).To(Equal(graphql.Bytes(txCID.IPLD.Data).String())) }) }) }) -func compareEthHeaderCid(ethHeaderCid graphql.EthHeaderCidResponse, headerCID eth.HeaderCidRecord) { +func compareEthHeaderCID(ethHeaderCID graphql.EthHeaderCIDResponse, headerCID eth.HeaderCIDRecord) { blockNumber, err := strconv.ParseInt(headerCID.BlockNumber, 10, 64) Expect(err).ToNot(HaveOccurred()) td, err := strconv.ParseInt(headerCID.TotalDifficulty, 10, 64) Expect(err).ToNot(HaveOccurred()) - Expect(ethHeaderCid.Cid).To(Equal(headerCID.CID)) - Expect(ethHeaderCid.BlockNumber).To(Equal(*new(graphql.BigInt).SetUint64(uint64(blockNumber)))) - Expect(ethHeaderCid.BlockHash).To(Equal(headerCID.BlockHash)) - Expect(ethHeaderCid.ParentHash).To(Equal(headerCID.ParentHash)) - Expect(ethHeaderCid.Timestamp).To(Equal(*new(graphql.BigInt).SetUint64(headerCID.Timestamp))) - Expect(ethHeaderCid.StateRoot).To(Equal(headerCID.StateRoot)) - Expect(ethHeaderCid.Td).To(Equal(*new(graphql.BigInt).SetUint64(uint64(td)))) - Expect(ethHeaderCid.TxRoot).To(Equal(headerCID.TxRoot)) - Expect(ethHeaderCid.ReceiptRoot).To(Equal(headerCID.RctRoot)) - Expect(ethHeaderCid.UncleRoot).To(Equal(headerCID.UncleRoot)) - Expect(ethHeaderCid.Bloom).To(Equal(graphql.Bytes(headerCID.Bloom).String())) + Expect(ethHeaderCID.CID).To(Equal(headerCID.CID)) + Expect(ethHeaderCID.BlockNumber).To(Equal(*new(graphql.BigInt).SetUint64(uint64(blockNumber)))) + Expect(ethHeaderCID.BlockHash).To(Equal(headerCID.BlockHash)) + Expect(ethHeaderCID.ParentHash).To(Equal(headerCID.ParentHash)) + Expect(ethHeaderCID.Timestamp).To(Equal(*new(graphql.BigInt).SetUint64(headerCID.Timestamp))) + Expect(ethHeaderCID.StateRoot).To(Equal(headerCID.StateRoot)) + Expect(ethHeaderCID.Td).To(Equal(*new(graphql.BigInt).SetUint64(uint64(td)))) + Expect(ethHeaderCID.TxRoot).To(Equal(headerCID.TxRoot)) + Expect(ethHeaderCID.ReceiptRoot).To(Equal(headerCID.RctRoot)) + Expect(ethHeaderCID.UncleRoot).To(Equal(headerCID.UncleRoot)) + Expect(ethHeaderCID.Bloom).To(Equal(graphql.Bytes(headerCID.Bloom).String())) - for tIdx, txCID := range headerCID.TransactionCids { - ethTxCid := ethHeaderCid.EthTransactionCidsByHeaderId.Nodes[tIdx] - compareEthTxCid(ethTxCid, txCID) + for tIdx, txCID := range headerCID.TransactionCIDs { + ethTxCID := ethHeaderCID.EthTransactionCIDsByHeaderId.Nodes[tIdx] + compareEthTxCID(ethTxCID, txCID) } - Expect(ethHeaderCid.BlockByMhKey.Data).To(Equal(graphql.Bytes(headerCID.IPLD.Data).String())) - Expect(ethHeaderCid.BlockByMhKey.Key).To(Equal(headerCID.IPLD.Key)) + Expect(ethHeaderCID.BlockByMhKey.Data).To(Equal(graphql.Bytes(headerCID.IPLD.Data).String())) + Expect(ethHeaderCID.BlockByMhKey.Key).To(Equal(headerCID.IPLD.Key)) } -func compareEthTxCid(ethTxCid graphql.EthTransactionCidResponse, txCID eth.TransactionCidRecord) { - Expect(ethTxCid.Cid).To(Equal(txCID.CID)) - Expect(ethTxCid.TxHash).To(Equal(txCID.TxHash)) - Expect(ethTxCid.Index).To(Equal(int32(txCID.Index))) - Expect(ethTxCid.Src).To(Equal(txCID.Src)) - Expect(ethTxCid.Dst).To(Equal(txCID.Dst)) +func compareEthTxCID(ethTxCID graphql.EthTransactionCIDResponse, txCID eth.TransactionCIDRecord) { + Expect(ethTxCID.CID).To(Equal(txCID.CID)) + Expect(ethTxCID.TxHash).To(Equal(txCID.TxHash)) + Expect(ethTxCID.Index).To(Equal(int32(txCID.Index))) + Expect(ethTxCID.Src).To(Equal(txCID.Src)) + Expect(ethTxCID.Dst).To(Equal(txCID.Dst)) } -- 2.45.2