Implement postgraphile graphql queries in V3 #160

Merged
nikugogoi merged 13 commits from ng-watcher-queries-v3 into master 2022-06-07 05:05:40 +00:00
2 changed files with 205 additions and 0 deletions
Showing only changes of commit 0c44882cb2 - Show all commits

View File

@ -36,6 +36,48 @@ type GetLogs struct {
Responses []LogResponse `json:"getLogs"` 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 { type Client struct {
client *gqlclient.Client client *gqlclient.Client
} }
@ -117,3 +159,67 @@ func (c *Client) GetStorageAt(ctx context.Context, hash common.Hash, address com
} }
return &storageAt.Response, nil 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
}

View File

@ -20,6 +20,7 @@ import (
"context" "context"
"fmt" "fmt"
"math/big" "math/big"
"strconv"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
@ -30,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/statediff" "github.com/ethereum/go-ethereum/statediff"
"github.com/ethereum/go-ethereum/statediff/indexer/models"
sdtypes "github.com/ethereum/go-ethereum/statediff/types" sdtypes "github.com/ethereum/go-ethereum/statediff/types"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
@ -250,4 +252,101 @@ var _ = Describe("GraphQL", func() {
Expect(storageRes.Value).To(Equal(common.Hash{})) 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))
}