Fix getLog
API to use log_cids
table
#92
@ -24,6 +24,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@ -120,12 +121,7 @@ func (pea *PublicEthAPI) GetHeaderByHash(ctx context.Context, hash common.Hash)
|
||||
|
||||
// rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field
|
||||
func (pea *PublicEthAPI) rpcMarshalHeader(header *types.Header) (map[string]interface{}, error) {
|
||||
var extractMiner bool
|
||||
if pea.B.Config.ChainConfig.Clique != nil {
|
||||
extractMiner = true
|
||||
}
|
||||
|
||||
fields := RPCMarshalHeader(header, extractMiner)
|
||||
fields := RPCMarshalHeader(header, pea.B.Config.ChainConfig.Clique != nil)
|
||||
td, err := pea.B.GetTd(header.Hash())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -628,7 +624,7 @@ func (pea *PublicEthAPI) localGetLogs(crit filters.FilterCriteria) ([]*types.Log
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pea.B.Fetcher.FetchLogs(filteredLogs)
|
||||
return decomposeLogs(filteredLogs)
|
||||
}
|
||||
|
||||
// Otherwise, create block range from criteria
|
||||
@ -651,12 +647,12 @@ func (pea *PublicEthAPI) localGetLogs(crit filters.FilterCriteria) ([]*types.Log
|
||||
end := endingBlock.Int64()
|
||||
var logs []*types.Log
|
||||
for i := start; i <= end; i++ {
|
||||
filteredLog, err := pea.B.Retriever.RetrieveFilteredLog(tx, filter, i, nil)
|
||||
filteredLogs, err := pea.B.Retriever.RetrieveFilteredLog(tx, filter, i, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logCIDs, err := pea.B.Fetcher.FetchLogs(filteredLog)
|
||||
logCIDs, err := decomposeLogs(filteredLogs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1084,12 +1080,7 @@ func (pea *PublicEthAPI) writeStateDiffFor(blockHash common.Hash) {
|
||||
|
||||
// rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field
|
||||
func (pea *PublicEthAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
||||
var extractMiner bool
|
||||
if pea.B.Config.ChainConfig.Clique != nil {
|
||||
extractMiner = true
|
||||
}
|
||||
|
||||
fields, err := RPCMarshalBlock(b, inclTx, fullTx, extractMiner)
|
||||
fields, err := RPCMarshalBlock(b, inclTx, fullTx, pea.B.Config.ChainConfig.Clique != nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1105,12 +1096,7 @@ func (pea *PublicEthAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx boo
|
||||
|
||||
// rpcMarshalBlockWithUncleHashes uses the generalized output filler, then adds the total difficulty field
|
||||
func (pea *PublicEthAPI) rpcMarshalBlockWithUncleHashes(b *types.Block, uncleHashes []common.Hash, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
||||
var extractMiner bool
|
||||
if pea.B.Config.ChainConfig.Clique != nil {
|
||||
extractMiner = true
|
||||
}
|
||||
|
||||
fields, err := RPCMarshalBlockWithUncleHashes(b, uncleHashes, inclTx, fullTx, extractMiner)
|
||||
fields, err := RPCMarshalBlockWithUncleHashes(b, uncleHashes, inclTx, fullTx, pea.B.Config.ChainConfig.Clique != nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1130,3 +1116,42 @@ func toHexSlice(b [][]byte) []string {
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// decomposeLogs return logs from LogResult.
|
||||
func decomposeLogs(logCIDs []LogResult) ([]*types.Log, error) {
|
||||
logs := make([]*types.Log, len(logCIDs))
|
||||
for i, l := range logCIDs {
|
||||
topics := make([]common.Hash, 0)
|
||||
if l.Topic0 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic0))
|
||||
}
|
||||
if l.Topic1 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic1))
|
||||
}
|
||||
if l.Topic2 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic2))
|
||||
}
|
||||
if l.Topic3 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic3))
|
||||
}
|
||||
|
||||
// TODO: should we convert string to uint ?
|
||||
blockNum, err := strconv.ParseUint(l.BlockNumber, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logs[i] = &types.Log{
|
||||
Address: common.HexToAddress(l.Address),
|
||||
Topics: topics,
|
||||
Data: l.Data,
|
||||
BlockNumber: blockNum,
|
||||
TxHash: common.HexToHash(l.TxHash),
|
||||
TxIndex: uint(l.TxnIndex),
|
||||
BlockHash: common.HexToHash(l.BlockHash),
|
||||
Index: uint(l.Index),
|
||||
}
|
||||
}
|
||||
|
||||
return logs, nil
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/statediff/indexer"
|
||||
"github.com/ethereum/go-ethereum/statediff/indexer/node"
|
||||
"github.com/ethereum/go-ethereum/statediff/indexer/postgres"
|
||||
"github.com/ethereum/go-ethereum/statediff/indexer/shared"
|
||||
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@ -48,7 +47,7 @@ var (
|
||||
randomHash = crypto.Keccak256Hash(randomAddr.Bytes())
|
||||
number = rpc.BlockNumber(test_helpers.BlockNumber.Int64())
|
||||
londonBlockNum = rpc.BlockNumber(test_helpers.LondonBlockNum.Int64())
|
||||
wrongNumber = rpc.BlockNumber(number + 1)
|
||||
wrongNumber = number + 1
|
||||
blockHash = test_helpers.MockBlock.Header().Hash()
|
||||
baseFee = test_helpers.MockLondonBlock.BaseFee()
|
||||
ctx = context.Background()
|
||||
@ -482,14 +481,14 @@ var _ = Describe("API", func() {
|
||||
Describe("eth_getBlockTransactionCountByNumber", func() {
|
||||
It("Retrieves the number of transactions in the canonical block with the provided number", func() {
|
||||
count := api.GetBlockTransactionCountByNumber(ctx, number)
|
||||
Expect(uint64(*count)).To(Equal(uint64(3)))
|
||||
Expect(uint64(*count)).To(Equal(uint64(4)))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("eth_getBlockTransactionCountByHash", func() {
|
||||
It("Retrieves the number of transactions in the block with the provided hash ", func() {
|
||||
count := api.GetBlockTransactionCountByHash(ctx, blockHash)
|
||||
Expect(uint64(*count)).To(Equal(uint64(3)))
|
||||
Expect(uint64(*count)).To(Equal(uint64(4)))
|
||||
})
|
||||
})
|
||||
|
||||
@ -875,8 +874,8 @@ var _ = Describe("API", func() {
|
||||
}
|
||||
logs, err = api.GetLogs(ctx, crit)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len(logs)).To(Equal(5))
|
||||
Expect(logs).To(Equal([]*types.Log{test_helpers.MockLog1, test_helpers.MockLog2, test_helpers.MockLog3, test_helpers.MockLog4, test_helpers.MockLog5}))
|
||||
Expect(len(logs)).To(Equal(6))
|
||||
Expect(logs).To(Equal([]*types.Log{test_helpers.MockLog1, test_helpers.MockLog2, test_helpers.MockLog3, test_helpers.MockLog4, test_helpers.MockLog5, test_helpers.MockLog6}))
|
||||
})
|
||||
|
||||
It("Uses the provided blockhash if one is provided", func() {
|
||||
@ -1011,8 +1010,8 @@ var _ = Describe("API", func() {
|
||||
}
|
||||
logs, err = api.GetLogs(ctx, crit)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len(logs)).To(Equal(5))
|
||||
Expect(logs).To(Equal([]*types.Log{test_helpers.MockLog1, test_helpers.MockLog2, test_helpers.MockLog3, test_helpers.MockLog4, test_helpers.MockLog5}))
|
||||
Expect(len(logs)).To(Equal(6))
|
||||
Expect(logs).To(Equal([]*types.Log{test_helpers.MockLog1, test_helpers.MockLog2, test_helpers.MockLog3, test_helpers.MockLog4, test_helpers.MockLog5, test_helpers.MockLog6}))
|
||||
})
|
||||
|
||||
It("Filters on contract address if any are provided", func() {
|
||||
@ -1134,20 +1133,3 @@ var _ = Describe("API", func() {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
func publishCode(db *postgres.DB, codeHash common.Hash, code []byte) error {
|
||||
tx, err := db.Beginx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mhKey, err := shared.MultihashKeyFromKeccak256(codeHash)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
if err := shared.PublishDirect(tx, mhKey, code); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ func (ecr *CIDRetriever) RetrieveRctCIDsByHeaderID(tx *sqlx.Tx, rctFilter Receip
|
||||
|
||||
// RetrieveFilteredGQLLogs retrieves and returns all the log cIDs provided blockHash that conform to the provided
|
||||
// filter parameters.
|
||||
func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockHash *common.Hash) ([]logResult, error) {
|
||||
func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockHash *common.Hash) ([]LogResult, error) {
|
||||
log.Debug("retrieving log cids for receipt ids")
|
||||
args := make([]interface{}, 0, 4)
|
||||
id := 1
|
||||
@ -321,7 +321,7 @@ func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptF
|
||||
WHERE eth.log_cids.receipt_id = receipt_cids.id
|
||||
AND receipt_cids.tx_id = transaction_cids.id
|
||||
AND transaction_cids.header_id = header_cids.id
|
||||
AND receipt_cids.mh_key = blocks.key AND header_cids.block_hash = $1`
|
||||
AND log_cids.leaf_mh_key = blocks.key AND header_cids.block_hash = $1`
|
||||
|
||||
args = append(args, blockHash.String())
|
||||
id++
|
||||
@ -329,7 +329,7 @@ func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptF
|
||||
pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter)
|
||||
pgStr += ` ORDER BY log_cids.index`
|
||||
|
||||
logCIDs := make([]logResult, 0)
|
||||
logCIDs := make([]LogResult, 0)
|
||||
err := tx.Select(&logCIDs, pgStr, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -340,7 +340,7 @@ func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptF
|
||||
|
||||
// RetrieveFilteredLog retrieves and returns all the log cIDs provided blockHeight or blockHash that conform to the provided
|
||||
// filter parameters.
|
||||
func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash) ([]logResult, error) {
|
||||
func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash) ([]LogResult, error) {
|
||||
log.Debug("retrieving log cids for receipt ids")
|
||||
args := make([]interface{}, 0, 4)
|
||||
pgStr := `SELECT eth.log_cids.id,eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.receipt_id,
|
||||
@ -366,7 +366,7 @@ func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilte
|
||||
pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter)
|
||||
pgStr += ` ORDER BY log_cids.index`
|
||||
|
||||
logCIDs := make([]logResult, 0)
|
||||
logCIDs := make([]LogResult, 0)
|
||||
err := tx.Select(&logCIDs, pgStr, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -249,11 +249,11 @@ var _ = Describe("Retriever", func() {
|
||||
expectedHeaderCID.ID = cids[0].Header.ID
|
||||
expectedHeaderCID.NodeID = cids[0].Header.NodeID
|
||||
Expect(cids[0].Header).To(Equal(expectedHeaderCID))
|
||||
Expect(len(cids[0].Transactions)).To(Equal(3))
|
||||
Expect(len(cids[0].Transactions)).To(Equal(4))
|
||||
Expect(eth.TxModelsContainsCID(cids[0].Transactions, test_helpers.MockCIDWrapper.Transactions[0].CID)).To(BeTrue())
|
||||
Expect(eth.TxModelsContainsCID(cids[0].Transactions, test_helpers.MockCIDWrapper.Transactions[1].CID)).To(BeTrue())
|
||||
Expect(eth.TxModelsContainsCID(cids[0].Transactions, test_helpers.MockCIDWrapper.Transactions[2].CID)).To(BeTrue())
|
||||
Expect(len(cids[0].Receipts)).To(Equal(3))
|
||||
Expect(len(cids[0].Receipts)).To(Equal(4))
|
||||
Expect(eth.ReceiptModelsContainsCID(cids[0].Receipts, test_helpers.MockCIDWrapper.Receipts[0].CID)).To(BeTrue())
|
||||
Expect(eth.ReceiptModelsContainsCID(cids[0].Receipts, test_helpers.MockCIDWrapper.Receipts[1].CID)).To(BeTrue())
|
||||
Expect(eth.ReceiptModelsContainsCID(cids[0].Receipts, test_helpers.MockCIDWrapper.Receipts[2].CID)).To(BeTrue())
|
||||
@ -345,13 +345,13 @@ var _ = Describe("Retriever", func() {
|
||||
Expect(len(cids5)).To(Equal(1))
|
||||
Expect(cids5[0].BlockNumber).To(Equal(test_helpers.MockCIDWrapper.BlockNumber))
|
||||
Expect(cids5[0].Header).To(Equal(models.HeaderModel{}))
|
||||
Expect(len(cids5[0].Transactions)).To(Equal(3))
|
||||
Expect(len(cids5[0].Transactions)).To(Equal(4))
|
||||
Expect(eth.TxModelsContainsCID(cids5[0].Transactions, test_helpers.Trx1CID.String())).To(BeTrue())
|
||||
Expect(eth.TxModelsContainsCID(cids5[0].Transactions, test_helpers.Trx2CID.String())).To(BeTrue())
|
||||
Expect(eth.TxModelsContainsCID(cids5[0].Transactions, test_helpers.Trx3CID.String())).To(BeTrue())
|
||||
Expect(len(cids5[0].StateNodes)).To(Equal(0))
|
||||
Expect(len(cids5[0].StorageNodes)).To(Equal(0))
|
||||
Expect(len(cids5[0].Receipts)).To(Equal(3))
|
||||
Expect(len(cids5[0].Receipts)).To(Equal(4))
|
||||
Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct1CID.String())).To(BeTrue())
|
||||
Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct2CID.String())).To(BeTrue())
|
||||
Expect(eth.ReceiptModelsContainsCID(cids5[0].Receipts, test_helpers.Rct3CID.String())).To(BeTrue())
|
||||
|
@ -48,11 +48,11 @@ var _ = Describe("Filterer", func() {
|
||||
Expect(iplds.Header).To(Equal(test_helpers.MockIPLDs.Header))
|
||||
var expectedEmptyUncles []ipfs.BlockModel
|
||||
Expect(iplds.Uncles).To(Equal(expectedEmptyUncles))
|
||||
Expect(len(iplds.Transactions)).To(Equal(3))
|
||||
Expect(len(iplds.Transactions)).To(Equal(4))
|
||||
Expect(shared.IPLDsContainBytes(iplds.Transactions, test_helpers.Tx1)).To(BeTrue())
|
||||
Expect(shared.IPLDsContainBytes(iplds.Transactions, test_helpers.Tx2)).To(BeTrue())
|
||||
Expect(shared.IPLDsContainBytes(iplds.Transactions, test_helpers.Tx3)).To(BeTrue())
|
||||
Expect(len(iplds.Receipts)).To(Equal(3))
|
||||
Expect(len(iplds.Receipts)).To(Equal(4))
|
||||
Expect(shared.IPLDsContainBytes(iplds.Receipts, test_helpers.Rct1)).To(BeTrue())
|
||||
Expect(shared.IPLDsContainBytes(iplds.Receipts, test_helpers.Rct2)).To(BeTrue())
|
||||
Expect(shared.IPLDsContainBytes(iplds.Receipts, test_helpers.Rct3)).To(BeTrue())
|
||||
@ -142,13 +142,13 @@ var _ = Describe("Filterer", func() {
|
||||
Expect(iplds5.BlockNumber.Int64()).To(Equal(test_helpers.MockIPLDs.BlockNumber.Int64()))
|
||||
Expect(iplds5.Header).To(Equal(ipfs.BlockModel{}))
|
||||
Expect(len(iplds5.Uncles)).To(Equal(0))
|
||||
Expect(len(iplds5.Transactions)).To(Equal(3))
|
||||
Expect(len(iplds5.Transactions)).To(Equal(4))
|
||||
Expect(shared.IPLDsContainBytes(iplds5.Transactions, test_helpers.Tx1)).To(BeTrue())
|
||||
Expect(shared.IPLDsContainBytes(iplds5.Transactions, test_helpers.Tx2)).To(BeTrue())
|
||||
Expect(shared.IPLDsContainBytes(iplds5.Transactions, test_helpers.Tx3)).To(BeTrue())
|
||||
Expect(len(iplds5.StorageNodes)).To(Equal(0))
|
||||
Expect(len(iplds5.StateNodes)).To(Equal(0))
|
||||
Expect(len(iplds5.Receipts)).To(Equal(3))
|
||||
Expect(len(iplds5.Receipts)).To(Equal(4))
|
||||
Expect(shared.IPLDsContainBytes(iplds5.Receipts, test_helpers.Rct1)).To(BeTrue())
|
||||
Expect(shared.IPLDsContainBytes(iplds5.Receipts, test_helpers.Rct2)).To(BeTrue())
|
||||
Expect(shared.IPLDsContainBytes(iplds5.Receipts, test_helpers.Rct3)).To(BeTrue())
|
||||
|
@ -20,10 +20,8 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/statediff/indexer/ipfs"
|
||||
"github.com/ethereum/go-ethereum/statediff/indexer/models"
|
||||
"github.com/ethereum/go-ethereum/statediff/indexer/postgres"
|
||||
@ -167,93 +165,6 @@ func (f *IPLDFetcher) FetchRcts(tx *sqlx.Tx, cids []models.ReceiptModel) ([]ipfs
|
||||
return rctIPLDs, nil
|
||||
}
|
||||
|
||||
|
||||
// FetchLogs fetches logs.
|
||||
func (f *IPLDFetcher) FetchLogs(logCIDs []logResult) ([]*types.Log, error) {
|
||||
log.Debug("fetching logs")
|
||||
|
||||
logs := make([]*types.Log, len(logCIDs))
|
||||
for i, l := range logCIDs {
|
||||
topics := make([]common.Hash, 0)
|
||||
if l.Topic0 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic0))
|
||||
}
|
||||
if l.Topic1 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic1))
|
||||
}
|
||||
if l.Topic2 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic2))
|
||||
}
|
||||
if l.Topic3 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic3))
|
||||
}
|
||||
|
||||
// TODO: should we convert string to uint ?
|
||||
blockNum, err := strconv.ParseUint(l.BlockNumber, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logs[i] = &types.Log{
|
||||
Address: common.HexToAddress(l.Address),
|
||||
Topics: topics,
|
||||
Data: l.Data,
|
||||
BlockNumber: blockNum,
|
||||
TxHash: common.HexToHash(l.TxHash),
|
||||
TxIndex: uint(l.TxnIndex),
|
||||
BlockHash: common.HexToHash(l.BlockHash),
|
||||
Index: uint(l.Index),
|
||||
}
|
||||
}
|
||||
|
||||
return logs, nil
|
||||
}
|
||||
|
||||
type logsCID struct {
|
||||
Log *types.Log
|
||||
CID string
|
||||
RctCID string
|
||||
RctData []byte
|
||||
RctStatus uint64
|
||||
}
|
||||
|
||||
// FetchGQLLogs fetches logs for graphql.
|
||||
func (f *IPLDFetcher) FetchGQLLogs(logCIDs []logResult) ([]logsCID, error) {
|
||||
log.Debug("fetching logs")
|
||||
|
||||
logs := make([]logsCID, len(logCIDs))
|
||||
for i, l := range logCIDs {
|
||||
topics := make([]common.Hash, 0)
|
||||
if l.Topic0 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic0))
|
||||
}
|
||||
if l.Topic1 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic1))
|
||||
}
|
||||
if l.Topic2 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic2))
|
||||
}
|
||||
if l.Topic3 != "" {
|
||||
topics = append(topics, common.HexToHash(l.Topic3))
|
||||
}
|
||||
|
||||
logs[i] = logsCID{
|
||||
Log: &types.Log{
|
||||
Address: common.HexToAddress(l.Address),
|
||||
Topics: topics,
|
||||
Data: l.Data,
|
||||
Index: uint(l.Index),
|
||||
TxHash: common.HexToHash(l.TxHash),
|
||||
},
|
||||
CID: l.LeafCID,
|
||||
RctCID: l.RctCID,
|
||||
RctData: l.RctData,
|
||||
RctStatus: l.RctStatus,
|
||||
}
|
||||
}
|
||||
|
||||
return logs, nil
|
||||
}
|
||||
|
||||
// FetchState fetches state nodes
|
||||
func (f *IPLDFetcher) FetchState(tx *sqlx.Tx, cids []models.StateNodeModel) ([]StateNode, error) {
|
||||
log.Debug("fetching state iplds")
|
||||
|
@ -96,6 +96,7 @@ var (
|
||||
Address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592")
|
||||
AnotherAddress = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476593")
|
||||
AnotherAddress1 = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476594")
|
||||
AnotherAddress2 = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476596")
|
||||
ContractAddress = crypto.CreateAddress(SenderAddr, MockTransactions[2].Nonce())
|
||||
ContractHash = crypto.Keccak256Hash(ContractAddress.Bytes()).String()
|
||||
MockContractByteCode = []byte{0, 1, 2, 3, 4, 5}
|
||||
@ -108,6 +109,7 @@ var (
|
||||
mockTopic42 = common.HexToHash("0x0a")
|
||||
mockTopic43 = common.HexToHash("0x0b")
|
||||
mockTopic51 = common.HexToHash("0x0c")
|
||||
mockTopic61 = common.HexToHash("0x0d")
|
||||
MockLog1 = &types.Log{
|
||||
Address: Address,
|
||||
Topics: []common.Hash{mockTopic11, mockTopic12},
|
||||
@ -129,8 +131,8 @@ var (
|
||||
Topics: []common.Hash{mockTopic31},
|
||||
Data: []byte{},
|
||||
BlockNumber: BlockNumber.Uint64(),
|
||||
TxIndex: 1,
|
||||
Index: 1,
|
||||
TxIndex: 2,
|
||||
Index: 2,
|
||||
}
|
||||
|
||||
MockLog4 = &types.Log{
|
||||
@ -138,25 +140,35 @@ var (
|
||||
Topics: []common.Hash{mockTopic41, mockTopic42, mockTopic43},
|
||||
Data: []byte{},
|
||||
BlockNumber: BlockNumber.Uint64(),
|
||||
TxIndex: 1,
|
||||
Index: 1,
|
||||
TxIndex: 2,
|
||||
Index: 3,
|
||||
}
|
||||
MockLog5 = &types.Log{
|
||||
Address: AnotherAddress1,
|
||||
Topics: []common.Hash{mockTopic51},
|
||||
Data: []byte{},
|
||||
BlockNumber: BlockNumber.Uint64(),
|
||||
TxIndex: 1,
|
||||
Index: 1,
|
||||
TxIndex: 2,
|
||||
Index: 4,
|
||||
}
|
||||
MockLog6 = &types.Log{
|
||||
Address: AnotherAddress2,
|
||||
Topics: []common.Hash{mockTopic61},
|
||||
Data: []byte{},
|
||||
BlockNumber: BlockNumber.Uint64(),
|
||||
TxIndex: 3,
|
||||
Index: 5,
|
||||
}
|
||||
|
||||
Tx1 = GetTxnRlp(0, MockTransactions)
|
||||
Tx2 = GetTxnRlp(1, MockTransactions)
|
||||
Tx3 = GetTxnRlp(2, MockTransactions)
|
||||
Tx4 = GetTxnRlp(3, MockTransactions)
|
||||
|
||||
Rct1 = GetRctRlp(0, MockReceipts)
|
||||
Rct2 = GetRctRlp(1, MockReceipts)
|
||||
Rct3 = GetRctRlp(2, MockReceipts)
|
||||
Rct4 = GetRctRlp(3, MockReceipts)
|
||||
|
||||
HeaderCID, _ = ipld.RawdataToCid(ipld.MEthHeader, MockHeaderRlp, multihash.KECCAK_256)
|
||||
HeaderMhKey = shared.MultihashKeyFromCID(HeaderCID)
|
||||
@ -166,12 +178,16 @@ var (
|
||||
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)
|
||||
@ -206,6 +222,15 @@ var (
|
||||
TxHash: MockTransactions[2].Hash().String(),
|
||||
Data: MockContractByteCode,
|
||||
},
|
||||
{
|
||||
CID: "",
|
||||
MhKey: "",
|
||||
Src: SenderAddr.Hex(),
|
||||
Dst: "",
|
||||
Index: 3,
|
||||
TxHash: MockTransactions[3].Hash().String(),
|
||||
Data: []byte{},
|
||||
},
|
||||
}
|
||||
MockTrxMetaPostPublsh = []models.TxModel{
|
||||
{
|
||||
@ -235,6 +260,15 @@ var (
|
||||
TxHash: MockTransactions[2].Hash().String(),
|
||||
Data: MockContractByteCode,
|
||||
},
|
||||
{
|
||||
CID: Trx4CID.String(),
|
||||
MhKey: Trx4MhKey,
|
||||
Src: SenderAddr.Hex(),
|
||||
Dst: "",
|
||||
Index: 2,
|
||||
TxHash: MockTransactions[2].Hash().String(),
|
||||
Data: MockContractByteCode,
|
||||
},
|
||||
}
|
||||
MockRctMeta = []models.ReceiptModel{
|
||||
{
|
||||
@ -255,6 +289,12 @@ var (
|
||||
Contract: ContractAddress.String(),
|
||||
ContractHash: ContractHash,
|
||||
},
|
||||
{
|
||||
CID: "",
|
||||
MhKey: "",
|
||||
Contract: "",
|
||||
ContractHash: "",
|
||||
},
|
||||
}
|
||||
MockRctMetaPostPublish = []models.ReceiptModel{
|
||||
{
|
||||
@ -275,6 +315,12 @@ var (
|
||||
Contract: ContractAddress.String(),
|
||||
ContractHash: ContractHash,
|
||||
},
|
||||
{
|
||||
CID: Rct4CID.String(),
|
||||
MhKey: Rct4MhKey,
|
||||
Contract: "",
|
||||
ContractHash: "",
|
||||
},
|
||||
}
|
||||
|
||||
// statediff data
|
||||
@ -431,9 +477,11 @@ var (
|
||||
Trx1IPLD, _ = blocks.NewBlockWithCid(Tx1, Trx1CID)
|
||||
Trx2IPLD, _ = blocks.NewBlockWithCid(Tx2, Trx2CID)
|
||||
Trx3IPLD, _ = blocks.NewBlockWithCid(Tx3, Trx3CID)
|
||||
Trx4IPLD, _ = blocks.NewBlockWithCid(Tx4, Trx4CID)
|
||||
Rct1IPLD, _ = blocks.NewBlockWithCid(Rct1, Rct1CID)
|
||||
Rct2IPLD, _ = blocks.NewBlockWithCid(Rct2, Rct2CID)
|
||||
Rct3IPLD, _ = blocks.NewBlockWithCid(Rct3, Rct3CID)
|
||||
Rct4IPLD, _ = blocks.NewBlockWithCid(Rct4, Rct4CID)
|
||||
State1IPLD, _ = blocks.NewBlockWithCid(ContractLeafNode, State1CID)
|
||||
State2IPLD, _ = blocks.NewBlockWithCid(AccountLeafNode, State2CID)
|
||||
StorageIPLD, _ = blocks.NewBlockWithCid(StorageLeafNode, StorageCID)
|
||||
@ -457,6 +505,10 @@ var (
|
||||
Data: Trx3IPLD.RawData(),
|
||||
CID: Trx3IPLD.Cid().String(),
|
||||
},
|
||||
{
|
||||
Data: Trx4IPLD.RawData(),
|
||||
CID: Trx4IPLD.Cid().String(),
|
||||
},
|
||||
},
|
||||
Receipts: []ipfs.BlockModel{
|
||||
{
|
||||
@ -471,6 +523,10 @@ var (
|
||||
Data: Rct3IPLD.RawData(),
|
||||
CID: Rct3IPLD.Cid().String(),
|
||||
},
|
||||
{
|
||||
Data: Rct4IPLD.RawData(),
|
||||
CID: Rct4IPLD.Cid().String(),
|
||||
},
|
||||
},
|
||||
StateNodes: []eth.StateNode{
|
||||
{
|
||||
@ -584,6 +640,7 @@ func createLegacyTransactionsAndReceipts() (types.Transactions, types.Receipts,
|
||||
trx1 := types.NewTransaction(0, Address, big.NewInt(1000), 50, big.NewInt(100), []byte{})
|
||||
trx2 := types.NewTransaction(1, AnotherAddress, big.NewInt(2000), 100, big.NewInt(200), []byte{})
|
||||
trx3 := types.NewContractCreation(2, big.NewInt(1500), 75, big.NewInt(150), MockContractByteCode)
|
||||
trx4 := types.NewTransaction(3, AnotherAddress1, big.NewInt(2000), 100, big.NewInt(200), []byte{})
|
||||
transactionSigner := types.MakeSigner(params.MainnetChainConfig, new(big.Int).Set(BlockNumber))
|
||||
mockCurve := elliptic.P256()
|
||||
mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader)
|
||||
@ -602,6 +659,10 @@ func createLegacyTransactionsAndReceipts() (types.Transactions, types.Receipts,
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
signedTrx4, err := types.SignTx(trx4, transactionSigner, mockPrvKey)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
SenderAddr, err := types.Sender(transactionSigner, signedTrx1) // same for both trx
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -629,7 +690,13 @@ func createLegacyTransactionsAndReceipts() (types.Transactions, types.Receipts,
|
||||
mockReceipt3.TxHash = signedTrx3.Hash()
|
||||
mockReceipt3.GasUsed = mockReceipt3.CumulativeGasUsed - mockReceipt2.CumulativeGasUsed
|
||||
|
||||
return types.Transactions{signedTrx1, signedTrx2, signedTrx3}, types.Receipts{mockReceipt1, mockReceipt2, mockReceipt3}, SenderAddr
|
||||
// Receipt with failed status.
|
||||
mockReceipt4 := types.NewReceipt(nil, true, 250)
|
||||
mockReceipt4.Logs = []*types.Log{MockLog6}
|
||||
mockReceipt4.TxHash = signedTrx4.Hash()
|
||||
mockReceipt4.GasUsed = mockReceipt4.CumulativeGasUsed - mockReceipt3.CumulativeGasUsed
|
||||
|
||||
return types.Transactions{signedTrx1, signedTrx2, signedTrx3, signedTrx4}, types.Receipts{mockReceipt1, mockReceipt2, mockReceipt3, mockReceipt4}, SenderAddr
|
||||
}
|
||||
|
||||
func GetTxnRlp(num int, txs types.Transactions) []byte {
|
||||
|
@ -167,8 +167,8 @@ type ConvertedPayload struct {
|
||||
StorageNodes map[string][]sdtypes.StorageNode
|
||||
}
|
||||
|
||||
// logResult represent a log.
|
||||
type logResult struct {
|
||||
// LogResult represent a log.
|
||||
type LogResult struct {
|
||||
ID int64 `db:"id"`
|
||||
LeafCID string `db:"leaf_cid"`
|
||||
LeafMhKey string `db:"leaf_mh_key"`
|
||||
@ -180,7 +180,7 @@ type logResult struct {
|
||||
Topic1 string `db:"topic1"`
|
||||
Topic2 string `db:"topic2"`
|
||||
Topic3 string `db:"topic3"`
|
||||
RctData []byte `db:"data"`
|
||||
LogLeafData []byte `db:"data"`
|
||||
RctCID string `db:"cid"`
|
||||
RctStatus uint64 `db:"post_status"`
|
||||
BlockNumber string `db:"block_number"`
|
||||
|
@ -24,6 +24,7 @@ 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"`
|
||||
}
|
||||
|
||||
@ -54,6 +55,7 @@ func (c *Client) GetLogs(ctx context.Context, hash common.Hash, address common.A
|
||||
hash
|
||||
}
|
||||
status
|
||||
receiptCID
|
||||
}
|
||||
}
|
||||
`, hash.String(), address.String())
|
||||
|
@ -94,15 +94,17 @@ type Log struct {
|
||||
log *types.Log
|
||||
cid string
|
||||
receiptCID string
|
||||
ipldBlock []byte
|
||||
ipldBlock []byte // log leaf node IPLD block data
|
||||
status uint64
|
||||
}
|
||||
|
||||
func (l *Log) Transaction(ctx context.Context) *Transaction {
|
||||
// Transaction returns transaction that generated this log entry.
|
||||
func (l *Log) Transaction(_ context.Context) *Transaction {
|
||||
return l.transaction
|
||||
}
|
||||
|
||||
func (l *Log) Account(ctx context.Context, args BlockNumberArgs) *Account {
|
||||
// Account returns the contract account which generated this log.
|
||||
func (l *Log) Account(_ context.Context, args BlockNumberArgs) *Account {
|
||||
return &Account{
|
||||
backend: l.backend,
|
||||
address: l.log.Address,
|
||||
@ -110,30 +112,41 @@ func (l *Log) Account(ctx context.Context, args BlockNumberArgs) *Account {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Log) Index(ctx context.Context) int32 {
|
||||
// Index returns the index of this log in the block
|
||||
func (l *Log) Index(_ context.Context) int32 {
|
||||
return int32(l.log.Index)
|
||||
}
|
||||
|
||||
func (l *Log) Topics(ctx context.Context) []common.Hash {
|
||||
// Topics returns the list of 0-4 indexed topics for the log.
|
||||
func (l *Log) Topics(_ context.Context) []common.Hash {
|
||||
return l.log.Topics
|
||||
}
|
||||
|
||||
func (l *Log) Data(ctx context.Context) hexutil.Bytes {
|
||||
return hexutil.Bytes(l.log.Data)
|
||||
// Data returns data of this log.
|
||||
func (l *Log) Data(_ context.Context) hexutil.Bytes {
|
||||
return l.log.Data
|
||||
}
|
||||
|
||||
func (l *Log) Cid(ctx context.Context) string {
|
||||
// Cid returns cid of the leaf node of this log.
|
||||
func (l *Log) Cid(_ context.Context) string {
|
||||
return l.cid
|
||||
}
|
||||
|
||||
func (l *Log) IpldBlock(ctx context.Context) hexutil.Bytes {
|
||||
return hexutil.Bytes(l.ipldBlock)
|
||||
// IpldBlock returns IPLD block of the leaf node of this log.
|
||||
func (l *Log) IpldBlock(_ context.Context) hexutil.Bytes {
|
||||
return l.ipldBlock
|
||||
}
|
||||
|
||||
func (l *Log) Status(ctx context.Context) int32 {
|
||||
// Status returns the status of the receipt IPLD block this Log exists in.
|
||||
func (l *Log) Status(_ context.Context) int32 {
|
||||
return int32(l.status)
|
||||
}
|
||||
|
||||
// ReceiptCID returns the receipt CID of the receipt IPLD block this Log exists in.
|
||||
func (l *Log) ReceiptCID(_ context.Context) string {
|
||||
return l.receiptCID
|
||||
}
|
||||
|
||||
// Transaction represents an Ethereum transaction.
|
||||
// backend and hash are mandatory; all others will be fetched when required.
|
||||
type Transaction struct {
|
||||
@ -1033,7 +1046,7 @@ func (r *Resolver) GetLogs(ctx context.Context, args struct {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rctLog, err := r.backend.Fetcher.FetchGQLLogs(filteredLogs)
|
||||
rctLog := decomposeGQLLogs(filteredLogs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1044,7 +1057,7 @@ func (r *Resolver) GetLogs(ctx context.Context, args struct {
|
||||
log: l.Log,
|
||||
cid: l.CID,
|
||||
receiptCID: l.RctCID,
|
||||
ipldBlock: l.RctData,
|
||||
ipldBlock: l.LogLeafData,
|
||||
transaction: &Transaction{
|
||||
hash: l.Log.TxHash,
|
||||
},
|
||||
@ -1054,3 +1067,47 @@ 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
|
||||
}
|
||||
|
@ -191,9 +191,28 @@ 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()},
|
||||
ReceiptCID: test_helpers.Rct1CID.String(),
|
||||
Status: int32(test_helpers.MockReceipts[0].Status),
|
||||
},
|
||||
}
|
||||
|
||||
Expect(logs).To(Equal(expectedLogs))
|
||||
})
|
||||
|
||||
It("Retrieves logs for the failed receipt status that matches the provided blockHash and another contract address", func() {
|
||||
logs, err := client.GetLogs(ctx, blockHash, test_helpers.AnotherAddress2)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
expectedLogs := []graphql.LogResponse{
|
||||
{
|
||||
Topics: test_helpers.MockLog6.Topics,
|
||||
Data: hexutil.Bytes(test_helpers.MockLog6.Data),
|
||||
Transaction: graphql.TransactionResp{Hash: test_helpers.MockTransactions[3].Hash()},
|
||||
ReceiptCID: test_helpers.Rct4CID.String(),
|
||||
Status: int32(test_helpers.MockReceipts[3].Status),
|
||||
},
|
||||
}
|
||||
|
||||
Expect(logs).To(Equal(expectedLogs))
|
||||
})
|
||||
|
||||
|
@ -67,14 +67,17 @@ const schema string = `
|
||||
# Transaction is the transaction that generated this log entry.
|
||||
transaction: Transaction
|
||||
|
||||
# CID for the Receipt IPLD block this Log exists in.
|
||||
# CID for the Receipt IPLD block of leaf node.
|
||||
cid: String!
|
||||
Nit: Indentation is different from above. Nit: Indentation is different from above.
Done Done
|
||||
|
||||
This is always returning an empty string. This is always returning an empty string.
Done Done
|
||||
# IPLD block data for the Receipt this Log exists in.
|
||||
# ReceiptCID for the Receipt IPLD block this Log exists in.
|
||||
receiptCID: String!
|
||||
|
||||
# IPLD block data for the Log Leaf node.
|
||||
ipldBlock: Bytes!
|
||||
|
||||
# Status of the Receipt IPLD block this Log exists in.
|
||||
status: Int!
|
||||
# Status of the Receipt IPLD block this Log exists in.
|
||||
status: Int!
|
||||
}
|
||||
|
||||
What will this return for pre-byzantium fork records? What will this return for pre-byzantium fork records?
https://ethereum.stackexchange.com/questions/28889/what-is-the-exact-meaning-of-a-transactions-new-receipt-status-field
@ashwinphatak ```
// Assign receipt status or post state.
if len(receipt.PostState) > 0 {
fields["root"] = hexutil.Bytes(receipt.PostState)
} else {
fields["status"] = hexutil.Uint(receipt.Status)
}
```
@ashwinphatak
As per my understanding pre-byzantium fork, we used to return `PostState` which is the root and if it is not present then we return the `status`.
For GQL we need to change the type of status to `Bytes!` so it can accommodate both. Or should I add two separate fields `root` and `status`
Root of what? Is there some notion of success/failure by inspecting the > `PostState` which is the root
Root of what? Is there some notion of success/failure by inspecting the `PostState`?
Intermediate state root when the transaction is being applied if the transaction fails Intermediate state root when the transaction is being applied if the transaction fails
Source: https://github.com/ethereum/EIPs/issues/98#issue-151094725
But then they removed the `root` field and add `status` in [EIP-658](https://eips.ethereum.org/EIPS/eip-658) this field was replaced by `status`
As per https://eips.ethereum.org/EIPS/eip-658, "With the introduction of the REVERT opcode in EIP140, it is no longer possible for users to assume that a transaction failed iff it consumed all gas". So, we may be able to return 1 or 0 based on whether the tx consumed all gas for pre-byzantium blocks? @i-norden what do you think? As per https://eips.ethereum.org/EIPS/eip-658, "With the introduction of the REVERT opcode in EIP140, it is no longer possible for users to assume that a transaction failed iff it consumed all gas".
So, we may be able to return 1 or 0 based on whether the tx consumed all gas for pre-byzantium blocks?
@i-norden what do you think?
i-norden
commented
I don't think we can assume whether or not a tx failed based on how much of the gas limit was used. If a tx is reverted early on in its execution, due to some programmatic failure of an OPCODE execution, then it can be reverted early on and the amount of gas used can be much lower than the limit allocated. But, if a tx reverts because there is not enough gas allocated, then it will only revert after the miner has executed all of the OPCODEs it can afford to before bumping up against the limit and realizing there is not enough left to finish execution. In this case the reverted tx may use all or most of the gas limit. Another edge cases that make this approach infeasible is, for example, if someone vastly overestimated the gas limit needed for a tx. The tx is properly executed but done so far below the allocated limit, so using this heuristic the tx would look like it failed when it didn't. I don't think we can assume whether or not a tx failed based on how much of the gas limit was used.
If a tx is reverted early on in its execution, due to some programmatic failure of an OPCODE execution, then it can be reverted early on and the amount of gas used can be much lower than the limit allocated. But, if a tx reverts *because* there is not enough gas allocated, then it will only revert after the miner has executed all of the OPCODEs it can afford to before bumping up against the limit and realizing there is not enough left to finish execution. In this case the reverted tx may use all or most of the gas limit.
Another edge cases that make this approach infeasible is, for example, if someone vastly overestimated the gas limit needed for a tx. The tx is properly executed but done so far below the allocated limit, so using this heuristic the tx would look like it failed when it didn't.
i-norden
commented
Oh I misread, you meant for pre-byzantium blocks. So I just stated the obvious. Oh I misread, you meant for pre-byzantium blocks. So I just stated the obvious.
i-norden
commented
Theoretically it is possible that a tx uses up the entire gas limit during normal, successful execution- no? But the statement in that EIP makes it sound like it is a safe assumption. Theoretically it is possible that a tx uses up the entire gas limit during normal, successful execution- no? But the statement in that EIP makes it sound like it is a safe assumption.
Done Done
|
||||
# Transaction is an Ethereum transaction.
|
||||
|
This isn't fetching anything, it's decomposing the already fetched logResults.
Same here, not actually fetching IPLDs
Updated the function name.
Updated the function name.