Add status field for pre-byzantium blocks.

This commit is contained in:
Arijit Das 2021-09-13 17:43:42 +05:30
parent 458aae1c1e
commit 04a0f9a751
14 changed files with 258 additions and 121 deletions

View File

@ -10,6 +10,7 @@ CREATE TABLE eth.transaction_cids (
src VARCHAR(66) NOT NULL,
tx_data BYTEA,
tx_type BYTEA,
gas INTEGER NOT NULL,
UNIQUE (header_id, tx_hash)
);

View File

@ -9,6 +9,7 @@ CREATE TABLE eth.receipt_cids (
post_state VARCHAR(66),
post_status INTEGER,
log_root VARCHAR(66),
gas_used INTEGER NOT NULL,
UNIQUE (tx_id)
);

2
go.mod
View File

@ -27,6 +27,6 @@ require (
github.com/vulcanize/ipfs-ethdb v0.0.4-0.20210824131459-7bb49801fc12
)
replace github.com/ethereum/go-ethereum v1.10.8 => github.com/vulcanize/go-ethereum v1.10.8-statediff-0.0.26
replace github.com/ethereum/go-ethereum v1.10.8 => /Users/arijitdas/go/src/github.com/ethereum/go-ethereum
replace github.com/vulcanize/ipfs-ethdb v0.0.2-alpha => github.com/vulcanize/pg-ipfs-ethdb v0.0.2-alpha

2
go.sum
View File

@ -711,8 +711,6 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/vulcanize/gap-filler v0.3.1 h1:N5d+jCJo/VTWFvBSbTD7biRhK/OqDZzi1tgA85SIBKs=
github.com/vulcanize/gap-filler v0.3.1/go.mod h1:qowG1cgshVpBqMokiWro/1xhh0uypw7oAu8FQ42JMy4=
github.com/vulcanize/go-ethereum v1.10.8-statediff-0.0.26 h1:1UBVQpeJnHkmSKxXanbNGE8w+LR0iZhfGr0QrQ62+C4=
github.com/vulcanize/go-ethereum v1.10.8-statediff-0.0.26/go.mod h1:nXs5fPBjAVzBmIGtrc0f7akQwkXI5Mi+6I1QcbD2br0=
github.com/vulcanize/ipfs-ethdb v0.0.4-0.20210824131459-7bb49801fc12 h1:IKqHA89qA+VZBYt1nZ1EInVrAgB3iA5U+klkF4l8mn4=
github.com/vulcanize/ipfs-ethdb v0.0.4-0.20210824131459-7bb49801fc12/go.mod h1:IueWysMbZu0uFmu+ia6mEnyWsTvwe2q2lbYdy2muRUM=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=

View File

@ -524,12 +524,18 @@ func (pea *PublicEthAPI) localGetTransactionReceipt(ctx context.Context, hash co
"logsBloom": receipt.Bloom,
}
// Assign receipt status or post state.
if len(receipt.PostState) > 0 {
if blockNumber <= pea.B.Config.ChainConfig.ByzantiumBlock.Uint64() {
if receipt.GasUsed > tx.Gas() {
fields["status"] = hexutil.Uint(types.ReceiptStatusFailed)
} else {
fields["status"] = hexutil.Uint(types.ReceiptStatusSuccessful)
}
} else if len(receipt.PostState) > 0 {
fields["root"] = hexutil.Bytes(receipt.PostState)
} else {
fields["status"] = hexutil.Uint(receipt.Status)
}
if receipt.Logs == nil {
fields["logs"] = []*types.Log{}
}

View File

@ -43,15 +43,16 @@ import (
)
var (
randomAddr = common.HexToAddress("0x1C3ab14BBaD3D99F4203bd7a11aCB94882050E6f")
randomHash = crypto.Keccak256Hash(randomAddr.Bytes())
number = rpc.BlockNumber(test_helpers.BlockNumber.Int64())
londonBlockNum = rpc.BlockNumber(test_helpers.LondonBlockNum.Int64())
wrongNumber = number + 1
blockHash = test_helpers.MockBlock.Header().Hash()
baseFee = test_helpers.MockLondonBlock.BaseFee()
ctx = context.Background()
expectedBlock = map[string]interface{}{
randomAddr = common.HexToAddress("0x1C3ab14BBaD3D99F4203bd7a11aCB94882050E6f")
randomHash = crypto.Keccak256Hash(randomAddr.Bytes())
number = rpc.BlockNumber(test_helpers.BlockNumber.Int64())
londonBlockNum = rpc.BlockNumber(test_helpers.LondonBlockNum.Int64())
byzantiumBlockNum = rpc.BlockNumber(test_helpers.ByzantiumBlockNum.Int64())
wrongNumber = number + 1
blockHash = test_helpers.MockBlock.Header().Hash()
baseFee = test_helpers.MockLondonBlock.BaseFee()
ctx = context.Background()
expectedBlock = map[string]interface{}{
"number": (*hexutil.Big)(test_helpers.MockBlock.Number()),
"hash": test_helpers.MockBlock.Hash(),
"parentHash": test_helpers.MockBlock.ParentHash(),
@ -131,14 +132,15 @@ var (
"receiptsRoot": test_helpers.MockUncles[1].ReceiptHash,
"uncles": []common.Hash{},
}
expectedTransaction = eth.NewRPCTransaction(test_helpers.MockTransactions[0], test_helpers.MockBlock.Hash(), test_helpers.MockBlock.NumberU64(), 0, test_helpers.MockBlock.BaseFee())
expectedTransaction2 = eth.NewRPCTransaction(test_helpers.MockTransactions[1], test_helpers.MockBlock.Hash(), test_helpers.MockBlock.NumberU64(), 1, test_helpers.MockBlock.BaseFee())
expectedTransaction3 = eth.NewRPCTransaction(test_helpers.MockTransactions[2], test_helpers.MockBlock.Hash(), test_helpers.MockBlock.NumberU64(), 2, test_helpers.MockBlock.BaseFee())
expectedLondonTransaction = eth.NewRPCTransaction(test_helpers.MockLondonTransactions[0], test_helpers.MockLondonBlock.Hash(), test_helpers.MockLondonBlock.NumberU64(), 0, test_helpers.MockLondonBlock.BaseFee())
expectRawTx, _ = rlp.EncodeToBytes(test_helpers.MockTransactions[0])
expectRawTx2, _ = rlp.EncodeToBytes(test_helpers.MockTransactions[1])
expectRawTx3, _ = rlp.EncodeToBytes(test_helpers.MockTransactions[2])
expectedReceipt = map[string]interface{}{
expectedTransaction = eth.NewRPCTransaction(test_helpers.MockTransactions[0], test_helpers.MockBlock.Hash(), test_helpers.MockBlock.NumberU64(), 0, test_helpers.MockBlock.BaseFee())
expectedTransaction2 = eth.NewRPCTransaction(test_helpers.MockTransactions[1], test_helpers.MockBlock.Hash(), test_helpers.MockBlock.NumberU64(), 1, test_helpers.MockBlock.BaseFee())
expectedTransaction3 = eth.NewRPCTransaction(test_helpers.MockTransactions[2], test_helpers.MockBlock.Hash(), test_helpers.MockBlock.NumberU64(), 2, test_helpers.MockBlock.BaseFee())
expectedLondonTransaction = eth.NewRPCTransaction(test_helpers.MockLondonTransactions[0], test_helpers.MockLondonBlock.Hash(), test_helpers.MockLondonBlock.NumberU64(), 0, test_helpers.MockLondonBlock.BaseFee())
expectedByzantiumTransaction = eth.NewRPCTransaction(test_helpers.MockByzantiumTransactions[0], test_helpers.MockByzantiumBlock.Hash(), test_helpers.MockByzantiumBlock.NumberU64(), 0, test_helpers.MockByzantiumBlock.BaseFee())
expectRawTx, _ = rlp.EncodeToBytes(test_helpers.MockTransactions[0])
expectRawTx2, _ = rlp.EncodeToBytes(test_helpers.MockTransactions[1])
expectRawTx3, _ = rlp.EncodeToBytes(test_helpers.MockTransactions[2])
expectedReceipt = map[string]interface{}{
"blockHash": blockHash,
"blockNumber": hexutil.Uint64(uint64(number.Int64())),
"transactionHash": expectedTransaction.Hash,
@ -180,6 +182,20 @@ var (
"logsBloom": test_helpers.MockReceipts[2].Bloom,
"root": hexutil.Bytes(test_helpers.MockReceipts[2].PostState),
}
expectedByzantiumReceipt = map[string]interface{}{
"blockHash": test_helpers.MockByzantiumBlock.Hash(),
"blockNumber": hexutil.Uint64(uint64(byzantiumBlockNum)),
"transactionHash": expectedByzantiumTransaction.Hash,
"transactionIndex": hexutil.Uint64(0),
"from": expectedByzantiumTransaction.From,
"to": expectedByzantiumTransaction.To,
"gasUsed": hexutil.Uint64(test_helpers.MockByzantiumReceipts[0].GasUsed),
"cumulativeGasUsed": hexutil.Uint64(test_helpers.MockByzantiumReceipts[0].CumulativeGasUsed),
"contractAddress": nil,
"logs": test_helpers.MockByzantiumReceipts[0].Logs,
"logsBloom": test_helpers.MockByzantiumReceipts[0].Bloom,
"status": hexutil.Uint(test_helpers.MockByzantiumReceipts[0].Status),
}
)
// SetupDB is use to setup a db for watcher tests
@ -210,6 +226,13 @@ var _ = Describe("API", func() {
db, err = SetupDB()
Expect(err).ToNot(HaveOccurred())
// setting chain config to for byzantium block
chainConfig.ByzantiumBlock = big.NewInt(1)
// setting chain config to for london block
chainConfig.LondonBlock = big.NewInt(3)
indexAndPublisher := indexer.NewStateDiffIndexer(chainConfig, db)
backend, err := eth.NewEthBackend(db, &eth.Config{
ChainConfig: chainConfig,
@ -249,14 +272,17 @@ var _ = Describe("API", func() {
}
expectedBlock["uncles"] = uncleHashes
// setting chain config to for london block
chainConfig.LondonBlock = big.NewInt(2)
indexAndPublisher = indexer.NewStateDiffIndexer(chainConfig, db)
tx, err = indexAndPublisher.PushBlock(test_helpers.MockLondonBlock, test_helpers.MockLondonReceipts, test_helpers.MockLondonBlock.Difficulty())
Expect(err).ToNot(HaveOccurred())
err = tx.Close(err)
Expect(err).ToNot(HaveOccurred())
tx, err = indexAndPublisher.PushBlock(test_helpers.MockByzantiumBlock, test_helpers.MockByzantiumReceipts, test_helpers.MockByzantiumBlock.Difficulty())
Expect(err).ToNot(HaveOccurred())
err = tx.Close(err)
Expect(err).ToNot(HaveOccurred())
})
// Single test db tear down at end of all tests
@ -644,6 +670,13 @@ var _ = Describe("API", func() {
_, err := api.GetTransactionReceipt(ctx, randomHash)
Expect(err).To(HaveOccurred())
})
It("Retrieve receipt for pre byzantium block transaction", func() {
hash := test_helpers.MockByzantiumTransactions[0].Hash()
tx, err := api.GetTransactionReceipt(ctx, hash)
Expect(err).ToNot(HaveOccurred())
Expect(tx).To(Equal(expectedByzantiumReceipt))
})
})
Describe("eth_getLogs", func() {

View File

@ -22,6 +22,7 @@ import (
"errors"
"fmt"
"math/big"
"strconv"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
@ -472,6 +473,7 @@ func (b *Backend) GetTransaction(ctx context.Context, txHash common.Hash) (*type
BlockHash string `db:"block_hash"`
BlockNumber uint64 `db:"block_number"`
Index uint64 `db:"index"`
Gas uint64 `db:"gas"`
}
if err := b.DB.Get(&tempTxStruct, RetrieveRPCTransaction, txHash.String()); err != nil {
return nil, common.Hash{}, 0, 0, err
@ -799,6 +801,67 @@ func (b *Backend) RPCGasCap() *big.Int {
return b.Config.RPCGasCap
}
type logsCID struct {
Log *types.Log
CID string
RctCID string
LogLeafData []byte
RctStatus uint64
}
// DecomposeGQLLogs return logs for graphql.
func (b *Backend) DecomposeGQLLogs(logCIDs []LogResult) ([]logsCID, error) {
logs := make([]logsCID, len(logCIDs))
for i, l := range logCIDs {
topics := make([]common.Hash, 0)
if l.Topic0 != "" {
topics = append(topics, common.HexToHash(l.Topic0))
}
if l.Topic1 != "" {
topics = append(topics, common.HexToHash(l.Topic1))
}
if l.Topic2 != "" {
topics = append(topics, common.HexToHash(l.Topic2))
}
if l.Topic3 != "" {
topics = append(topics, common.HexToHash(l.Topic3))
}
// TODO: should we convert string to uint ?
blockNum, err := strconv.ParseUint(l.BlockNumber, 10, 64)
if err != nil {
return nil, err
}
var status uint64
if blockNum <= b.Config.ChainConfig.ByzantiumBlock.Uint64() {
if l.RctGasUsed > l.Gas {
status = types.ReceiptStatusFailed
} else {
status = types.ReceiptStatusSuccessful
}
} else {
status = l.RctStatus
}
logs[i] = logsCID{
Log: &types.Log{
Address: common.HexToAddress(l.Address),
Topics: topics,
Data: l.Data,
Index: uint(l.Index),
TxHash: common.HexToHash(l.TxHash),
},
CID: l.LeafCID,
RctCID: l.RctCID,
LogLeafData: l.LogLeafData,
RctStatus: status,
}
}
return logs, nil
}
func (b *Backend) SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription {
panic("implement me")
}

View File

@ -316,7 +316,8 @@ func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptF
id := 1
pgStr := `SELECT eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.receipt_id,
eth.log_cids.address, eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3,
eth.log_cids.log_data, eth.transaction_cids.tx_hash, data, eth.receipt_cids.cid, eth.receipt_cids.post_status
eth.log_cids.log_data, eth.transaction_cids.tx_hash, eth.transaction_cids.gas, data, eth.receipt_cids.cid, eth.receipt_cids.post_status,
eth.receipt_cids.gas_used,header_cids.block_number
FROM eth.log_cids, eth.receipt_cids, eth.transaction_cids, eth.header_cids, public.blocks
WHERE eth.log_cids.receipt_id = receipt_cids.id
AND receipt_cids.tx_id = transaction_cids.id
@ -375,7 +376,7 @@ func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilte
return logCIDs, nil
}
// RetrieveRctCIDs retrieves and returns all of the rct cids at the provided blockheight or block hash that conform to the provided
// RetrieveRctCIDs retrieves and returns all the rct cIDs at the provided blockHeight or block hash that conform to the provided
// filter parameters and correspond to the provided tx ids
func (ecr *CIDRetriever) RetrieveRctCIDs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash, trxIds []int64) ([]models.ReceiptModel, error) {
log.Debug("retrieving receipt cids for block ", blockNumber)

View File

@ -37,7 +37,7 @@ import (
var (
openFilter = eth.SubscriptionSettings{
Start: big.NewInt(0),
End: big.NewInt(1),
End: big.NewInt(number.Int64()),
HeaderFilter: eth.HeaderFilter{},
TxFilter: eth.TxFilter{},
ReceiptFilter: eth.ReceiptFilter{},
@ -46,7 +46,7 @@ var (
}
rctAddressFilter = eth.SubscriptionSettings{
Start: big.NewInt(0),
End: big.NewInt(1),
End: big.NewInt(number.Int64()),
HeaderFilter: eth.HeaderFilter{
Off: true,
},
@ -65,7 +65,7 @@ var (
}
rctTopicsFilter = eth.SubscriptionSettings{
Start: big.NewInt(0),
End: big.NewInt(1),
End: big.NewInt(number.Int64()),
HeaderFilter: eth.HeaderFilter{
Off: true,
},
@ -84,7 +84,7 @@ var (
}
rctTopicsAndAddressFilter = eth.SubscriptionSettings{
Start: big.NewInt(0),
End: big.NewInt(1),
End: big.NewInt(number.Int64()),
HeaderFilter: eth.HeaderFilter{
Off: true,
},
@ -107,7 +107,7 @@ var (
}
rctTopicsAndAddressFilterFail = eth.SubscriptionSettings{
Start: big.NewInt(0),
End: big.NewInt(1),
End: big.NewInt(number.Int64()),
HeaderFilter: eth.HeaderFilter{
Off: true,
},
@ -130,7 +130,7 @@ var (
}
rctAddressesAndTopicFilter = eth.SubscriptionSettings{
Start: big.NewInt(0),
End: big.NewInt(1),
End: big.NewInt(number.Int64()),
HeaderFilter: eth.HeaderFilter{
Off: true,
},
@ -150,7 +150,7 @@ var (
}
rctsForAllCollectedTrxs = eth.SubscriptionSettings{
Start: big.NewInt(0),
End: big.NewInt(1),
End: big.NewInt(number.Int64()),
HeaderFilter: eth.HeaderFilter{
Off: true,
},
@ -169,7 +169,7 @@ var (
}
rctsForSelectCollectedTrxs = eth.SubscriptionSettings{
Start: big.NewInt(0),
End: big.NewInt(1),
End: big.NewInt(number.Int64()),
HeaderFilter: eth.HeaderFilter{
Off: true,
},
@ -190,7 +190,7 @@ var (
}
stateFilter = eth.SubscriptionSettings{
Start: big.NewInt(0),
End: big.NewInt(1),
End: big.NewInt(number.Int64()),
HeaderFilter: eth.HeaderFilter{
Off: true,
},
@ -239,7 +239,7 @@ var _ = Describe("Retriever", func() {
Expect(err).ToNot(HaveOccurred())
})
It("Retrieves all CIDs for the given blocknumber when provided an open filter", func() {
cids, empty, err := retriever.Retrieve(openFilter, 1)
cids, empty, err := retriever.Retrieve(openFilter, number.Int64())
Expect(err).ToNot(HaveOccurred())
Expect(empty).ToNot(BeTrue())
Expect(len(cids)).To(Equal(1))
@ -279,7 +279,7 @@ var _ = Describe("Retriever", func() {
})
It("Applies filters from the provided config.Subscription", func() {
cids1, empty, err := retriever.Retrieve(rctAddressFilter, 1)
cids1, empty, err := retriever.Retrieve(rctAddressFilter, number.Int64())
Expect(err).ToNot(HaveOccurred())
Expect(empty).ToNot(BeTrue())
Expect(len(cids1)).To(Equal(1))
@ -294,7 +294,7 @@ var _ = Describe("Retriever", func() {
expectedReceiptCID.TxID = cids1[0].Receipts[0].TxID
Expect(cids1[0].Receipts[0]).To(Equal(expectedReceiptCID))
cids2, empty, err := retriever.Retrieve(rctTopicsFilter, 1)
cids2, empty, err := retriever.Retrieve(rctTopicsFilter, number.Int64())
Expect(err).ToNot(HaveOccurred())
Expect(empty).ToNot(BeTrue())
Expect(len(cids2)).To(Equal(1))
@ -309,7 +309,7 @@ var _ = Describe("Retriever", func() {
expectedReceiptCID.TxID = cids2[0].Receipts[0].TxID
Expect(cids2[0].Receipts[0]).To(Equal(expectedReceiptCID))
cids3, empty, err := retriever.Retrieve(rctTopicsAndAddressFilter, 1)
cids3, empty, err := retriever.Retrieve(rctTopicsAndAddressFilter, number.Int64())
Expect(err).ToNot(HaveOccurred())
Expect(empty).ToNot(BeTrue())
Expect(len(cids3)).To(Equal(1))
@ -324,7 +324,7 @@ var _ = Describe("Retriever", func() {
expectedReceiptCID.TxID = cids3[0].Receipts[0].TxID
Expect(cids3[0].Receipts[0]).To(Equal(expectedReceiptCID))
cids4, empty, err := retriever.Retrieve(rctAddressesAndTopicFilter, 1)
cids4, empty, err := retriever.Retrieve(rctAddressesAndTopicFilter, number.Int64())
Expect(err).ToNot(HaveOccurred())
Expect(empty).ToNot(BeTrue())
Expect(len(cids4)).To(Equal(1))
@ -339,7 +339,7 @@ var _ = Describe("Retriever", func() {
expectedReceiptCID.TxID = cids4[0].Receipts[0].TxID
Expect(cids4[0].Receipts[0]).To(Equal(expectedReceiptCID))
cids5, empty, err := retriever.Retrieve(rctsForAllCollectedTrxs, 1)
cids5, empty, err := retriever.Retrieve(rctsForAllCollectedTrxs, number.Int64())
Expect(err).ToNot(HaveOccurred())
Expect(empty).ToNot(BeTrue())
Expect(len(cids5)).To(Equal(1))
@ -356,7 +356,7 @@ var _ = Describe("Retriever", func() {
Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct2CID.String())).To(BeTrue())
Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct3CID.String())).To(BeTrue())
cids6, empty, err := retriever.Retrieve(rctsForSelectCollectedTrxs, 1)
cids6, empty, err := retriever.Retrieve(rctsForSelectCollectedTrxs, number.Int64())
Expect(err).ToNot(HaveOccurred())
Expect(empty).ToNot(BeTrue())
Expect(len(cids6)).To(Equal(1))
@ -375,7 +375,7 @@ var _ = Describe("Retriever", func() {
expectedReceiptCID.TxID = cids6[0].Receipts[0].TxID
Expect(cids6[0].Receipts[0]).To(Equal(expectedReceiptCID))
cids7, empty, err := retriever.Retrieve(stateFilter, 1)
cids7, empty, err := retriever.Retrieve(stateFilter, number.Int64())
Expect(err).ToNot(HaveOccurred())
Expect(empty).ToNot(BeTrue())
Expect(len(cids7)).To(Equal(1))
@ -415,7 +415,7 @@ var _ = Describe("Retriever", func() {
num, err := retriever.RetrieveFirstBlockNumber()
Expect(err).ToNot(HaveOccurred())
Expect(num).To(Equal(int64(1)))
Expect(num).To(Equal(number.Int64()))
})
It("Gets the number of the first block that has data in the database", func() {
@ -466,7 +466,7 @@ var _ = Describe("Retriever", func() {
num, err := retriever.RetrieveLastBlockNumber()
Expect(err).ToNot(HaveOccurred())
Expect(num).To(Equal(int64(1)))
Expect(num).To(Equal(number.Int64()))
})
It("Gets the number of the latest block that has data in the database", func() {

View File

@ -97,7 +97,7 @@ var _ = Describe("eth state reading tests", func() {
IntermediateStateNodes: true,
IntermediateStorageNodes: true,
}
canonicalHeader := blocks[1].Header()
canonicalHeader := blocks[2].Header()
expectedCanonicalHeader = map[string]interface{}{
"number": (*hexutil.Big)(canonicalHeader.Number),
"hash": canonicalHeader.Hash(),

View File

@ -47,7 +47,7 @@ import (
// Test variables
var (
// block data
BlockNumber = big.NewInt(1)
BlockNumber = big.NewInt(2)
MockHeader = types.Header{
Time: 0,
Number: new(big.Int).Set(BlockNumber),
@ -110,6 +110,7 @@ var (
mockTopic43 = common.HexToHash("0x0b")
mockTopic51 = common.HexToHash("0x0c")
mockTopic61 = common.HexToHash("0x0d")
mockTopic71 = common.HexToHash("0x0e")
MockLog1 = &types.Log{
Address: Address,
Topics: []common.Hash{mockTopic11, mockTopic12},
@ -159,6 +160,14 @@ var (
TxIndex: 3,
Index: 5,
}
MockLog7 = &types.Log{
Address: AnotherAddress2,
Topics: []common.Hash{mockTopic71},
Data: []byte{},
BlockNumber: BlockNumber.Uint64(),
TxIndex: 1,
Index: 6,
}
Tx1 = GetTxnRlp(0, MockTransactions)
Tx2 = GetTxnRlp(1, MockTransactions)
@ -170,31 +179,32 @@ var (
Rct3 = GetRctRlp(2, MockReceipts)
Rct4 = GetRctRlp(3, MockReceipts)
HeaderCID, _ = ipld.RawdataToCid(ipld.MEthHeader, MockHeaderRlp, multihash.KECCAK_256)
HeaderMhKey = shared.MultihashKeyFromCID(HeaderCID)
Trx1CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx1, multihash.KECCAK_256)
Trx1MhKey = shared.MultihashKeyFromCID(Trx1CID)
Trx2CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx2, multihash.KECCAK_256)
Trx2MhKey = shared.MultihashKeyFromCID(Trx2CID)
Trx3CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx3, multihash.KECCAK_256)
Trx3MhKey = shared.MultihashKeyFromCID(Trx3CID)
Trx4CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx4, multihash.KECCAK_256)
Trx4MhKey = shared.MultihashKeyFromCID(Trx4CID)
Rct1CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct1, multihash.KECCAK_256)
Rct1MhKey = shared.MultihashKeyFromCID(Rct1CID)
Rct2CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct2, multihash.KECCAK_256)
Rct2MhKey = shared.MultihashKeyFromCID(Rct2CID)
Rct3CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct3, multihash.KECCAK_256)
Rct3MhKey = shared.MultihashKeyFromCID(Rct3CID)
Rct4CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct4, multihash.KECCAK_256)
Rct4MhKey = shared.MultihashKeyFromCID(Rct4CID)
State1CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, ContractLeafNode, multihash.KECCAK_256)
State1MhKey = shared.MultihashKeyFromCID(State1CID)
State2CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, AccountLeafNode, multihash.KECCAK_256)
State2MhKey = shared.MultihashKeyFromCID(State2CID)
StorageCID, _ = ipld.RawdataToCid(ipld.MEthStorageTrie, StorageLeafNode, multihash.KECCAK_256)
StorageMhKey = shared.MultihashKeyFromCID(StorageCID)
MockTrxMeta = []models.TxModel{
HeaderCID, _ = ipld.RawdataToCid(ipld.MEthHeader, MockHeaderRlp, multihash.KECCAK_256)
HeaderMhKey = shared.MultihashKeyFromCID(HeaderCID)
Trx1CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx1, multihash.KECCAK_256)
Trx1MhKey = shared.MultihashKeyFromCID(Trx1CID)
Trx2CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx2, multihash.KECCAK_256)
Trx2MhKey = shared.MultihashKeyFromCID(Trx2CID)
Trx3CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx3, multihash.KECCAK_256)
Trx3MhKey = shared.MultihashKeyFromCID(Trx3CID)
Trx4CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx4, multihash.KECCAK_256)
Trx4MhKey = shared.MultihashKeyFromCID(Trx4CID)
Rct1CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct1, multihash.KECCAK_256)
Rct1MhKey = shared.MultihashKeyFromCID(Rct1CID)
Rct2CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct2, multihash.KECCAK_256)
Rct2MhKey = shared.MultihashKeyFromCID(Rct2CID)
Rct3CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct3, multihash.KECCAK_256)
Rct3MhKey = shared.MultihashKeyFromCID(Rct3CID)
Rct4CID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, Rct4, multihash.KECCAK_256)
Rct4MhKey = shared.MultihashKeyFromCID(Rct4CID)
ByzantiumRctCID, _ = ipld.RawdataToCid(ipld.MEthTxReceipt, GetRctRlp(0, MockByzantiumReceipts), multihash.KECCAK_256)
State1CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, ContractLeafNode, multihash.KECCAK_256)
State1MhKey = shared.MultihashKeyFromCID(State1CID)
State2CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, AccountLeafNode, multihash.KECCAK_256)
State2MhKey = shared.MultihashKeyFromCID(State2CID)
StorageCID, _ = ipld.RawdataToCid(ipld.MEthStorageTrie, StorageLeafNode, multihash.KECCAK_256)
StorageMhKey = shared.MultihashKeyFromCID(StorageCID)
MockTrxMeta = []models.TxModel{
{
CID: "", // This is empty until we go to publish to ipfs
MhKey: "",
@ -442,7 +452,7 @@ var (
MockCIDWrapper = &eth.CIDWrapper{
BlockNumber: new(big.Int).Set(BlockNumber),
Header: models.HeaderModel{
BlockNumber: "1",
BlockNumber: "2",
BlockHash: MockBlock.Hash().String(),
ParentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
CID: HeaderCID.String(),
@ -574,6 +584,19 @@ var (
MockLondonTransactions, MockLondonReceipts, _ = createDynamicTransactionsAndReceipts(LondonBlockNum)
MockLondonBlock = createNewBlock(&MockLondonHeader, MockLondonTransactions, nil, MockLondonReceipts, new(trie.Trie))
ByzantiumBlockNum = big.NewInt(1)
MockByzantiumHeader = types.Header{
Time: 0,
Number: ByzantiumBlockNum,
Root: common.HexToHash("0x00"),
Difficulty: big.NewInt(5000000),
Extra: []byte{},
BaseFee: big.NewInt(params.InitialBaseFee),
}
MockByzantiumTransactions, MockByzantiumReceipts, _ = createByzantiumTransactionsAndReceipts(ByzantiumBlockNum)
MockByzantiumBlock = createNewBlock(&MockByzantiumHeader, MockByzantiumTransactions, nil, MockByzantiumReceipts, new(trie.Trie))
)
func createNewBlock(header *types.Header, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, hasher types.TrieHasher) *types.Block {
@ -614,13 +637,12 @@ func createDynamicTransactionsAndReceipts(blockNumber *big.Int) (types.Transacti
log.Fatal(err.Error())
}
senderAddr, err := types.Sender(transactionSigner, signedTrx1) // same for both trx
senderAddr, err := types.Sender(transactionSigner, signedTrx1)
if err != nil {
log.Fatal(err.Error())
}
// make receipts
// TODO: Change the receipt type to DynamicFeeTxType once this PR is merged.
// https://github.com/ethereum/go-ethereum/pull/22806
mockReceipt1 := &types.Receipt{
Type: types.DynamicFeeTxType,
@ -634,6 +656,39 @@ func createDynamicTransactionsAndReceipts(blockNumber *big.Int) (types.Transacti
return types.Transactions{signedTrx1}, types.Receipts{mockReceipt1}, senderAddr
}
// createByzantiumTransactionsAndReceipts is a helper function to generate signed mock transactions and mock receipts with mock logs
func createByzantiumTransactionsAndReceipts(blockNumber *big.Int) (types.Transactions, types.Receipts, common.Address) {
// make transactions
trx1 := types.NewTransaction(0, AnotherAddress1, big.NewInt(1000), 50, big.NewInt(100), []byte{})
config := params.TestChainConfig
config.ByzantiumBlock = blockNumber
transactionSigner := types.MakeSigner(config, new(big.Int).Set(BlockNumber))
mockCurve := elliptic.P256()
mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader)
if err != nil {
log.Fatal(err)
}
signedTrx, err := types.SignTx(trx1, transactionSigner, mockPrvKey)
if err != nil {
log.Fatal(err)
}
SenderAddr, err = types.Sender(transactionSigner, signedTrx)
if err != nil {
log.Fatal(err)
}
// make receipts
mockReceipt := types.NewReceipt(common.HexToHash("0x1").Bytes(), false, 50)
hash := signedTrx.Hash()
MockLog7.TxHash = hash
mockReceipt.Logs = []*types.Log{MockLog7}
mockReceipt.TxHash = hash
mockReceipt.GasUsed = mockReceipt.CumulativeGasUsed
return types.Transactions{signedTrx}, types.Receipts{mockReceipt}, SenderAddr
}
// createLegacyTransactionsAndReceipts is a helper function to generate signed mock transactions and mock receipts with mock logs
func createLegacyTransactionsAndReceipts() (types.Transactions, types.Receipts, common.Address) {
// make transactions

View File

@ -181,8 +181,10 @@ type LogResult struct {
LogLeafData []byte `db:"data"`
RctCID string `db:"cid"`
RctStatus uint64 `db:"post_status"`
RctGasUsed uint64 `db:"gas_used"`
BlockNumber string `db:"block_number"`
BlockHash string `db:"block_hash"`
TxnIndex int64 `db:"txn_index"`
TxHash string `db:"tx_hash"`
Gas uint64 `db:"gas"`
}

View File

@ -1046,7 +1046,7 @@ func (r *Resolver) GetLogs(ctx context.Context, args struct {
return nil, err
}
rctLog := decomposeGQLLogs(filteredLogs)
rctLog, err := r.backend.DecomposeGQLLogs(filteredLogs)
if err != nil {
return nil, err
}
@ -1068,47 +1068,3 @@ func (r *Resolver) GetLogs(ctx context.Context, args struct {
return &ret, nil
}
type logsCID struct {
Log *types.Log
CID string
RctCID string
LogLeafData []byte
RctStatus uint64
}
// decomposeGQLLogs return logs for graphql.
func decomposeGQLLogs(logCIDs []eth.LogResult) []logsCID {
logs := make([]logsCID, len(logCIDs))
for i, l := range logCIDs {
topics := make([]common.Hash, 0)
if l.Topic0 != "" {
topics = append(topics, common.HexToHash(l.Topic0))
}
if l.Topic1 != "" {
topics = append(topics, common.HexToHash(l.Topic1))
}
if l.Topic2 != "" {
topics = append(topics, common.HexToHash(l.Topic2))
}
if l.Topic3 != "" {
topics = append(topics, common.HexToHash(l.Topic3))
}
logs[i] = logsCID{
Log: &types.Log{
Address: common.HexToAddress(l.Address),
Topics: topics,
Data: l.Data,
Index: uint(l.Index),
TxHash: common.HexToHash(l.TxHash),
},
CID: l.LeafCID,
RctCID: l.RctCID,
LogLeafData: l.LogLeafData,
RctStatus: l.RctStatus,
}
}
return logs
}

View File

@ -167,6 +167,11 @@ var _ = Describe("GraphQL", func() {
err = tx.Close(err)
Expect(err).ToNot(HaveOccurred())
tx, err = indexAndPublisher.PushBlock(test_helpers.MockByzantiumBlock, test_helpers.MockByzantiumReceipts, test_helpers.MockByzantiumBlock.Difficulty())
Expect(err).ToNot(HaveOccurred())
err = tx.Close(err)
Expect(err).ToNot(HaveOccurred())
graphQLServer, err = graphql.New(backend, gqlEndPoint, nil, []string{"*"}, rpc.HTTPTimeouts{})
Expect(err).ToNot(HaveOccurred())
@ -216,6 +221,22 @@ var _ = Describe("GraphQL", func() {
Expect(logs).To(Equal(expectedLogs))
})
It("Retrieve logs for pre byzantium block", func() {
logs, err := client.GetLogs(ctx, test_helpers.MockByzantiumBlock.Hash(), nil)
Expect(err).ToNot(HaveOccurred())
expectedLogs := []graphql.LogResponse{
{
Topics: test_helpers.MockLog7.Topics,
Data: hexutil.Bytes(test_helpers.MockLog1.Data),
Transaction: graphql.TransactionResp{Hash: test_helpers.MockByzantiumTransactions[0].Hash()},
ReceiptCID: test_helpers.ByzantiumRctCID.String(),
Status: int32(test_helpers.MockByzantiumReceipts[0].Status),
},
}
Expect(logs).To(Equal(expectedLogs))
})
It("Retrieves all the logs for the receipt that matches the provided blockHash and nil contract address", func() {
logs, err := client.GetLogs(ctx, blockHash, nil)
Expect(err).ToNot(HaveOccurred())