Implement postgraphile graphql queries in V3 #160
@ -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
|
||||||
|
}
|
||||||
|
@ -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))
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user