From 954e028306a826f4ec878f0be56d3a4b8cb64db8 Mon Sep 17 00:00:00 2001 From: ramil Date: Thu, 29 Apr 2021 16:33:27 +0300 Subject: [PATCH] custom comparation for tx and block (exclude time) enrich receipts and logs with non-rlp encoded data (block number, block hash, etc) --- pkg/eth/api.go | 23 ++++++++++++++++++----- pkg/eth/backend_utils.go | 24 ++++++++++++++++++------ test/integration_test.go | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 68 insertions(+), 17 deletions(-) diff --git a/pkg/eth/api.go b/pkg/eth/api.go index b70fbca6..cf4b1322 100644 --- a/pkg/eth/api.go +++ b/pkg/eth/api.go @@ -170,15 +170,15 @@ func (pea *PublicEthAPI) GetBlockByHash(ctx context.Context, hash common.Hash, f } // ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config. -func (api *PublicEthAPI) ChainId() hexutil.Uint64 { +func (pea *PublicEthAPI) ChainId() hexutil.Uint64 { chainID := new(big.Int) - block, err := api.B.CurrentBlock() + block, err := pea.B.CurrentBlock() if err != nil { logrus.Errorf("ChainId failed with err %s", err.Error()) return 0 } - if config := api.B.Config.ChainConfig; config.IsEIP155(block.Number()) { + if config := pea.B.Config.ChainConfig; config.IsEIP155(block.Number()) { chainID = config.ChainID } return (hexutil.Uint64)(chainID.Uint64()) @@ -457,6 +457,14 @@ func (pea *PublicEthAPI) localGetTransactionReceipt(ctx context.Context, hash co if err != nil { return nil, err } + block, err := pea.B.BlockByHash(ctx, blockHash) + if err != nil { + return nil, err + } + err = receipts.DeriveFields(pea.B.Config.ChainConfig, blockHash, blockNumber, block.Transactions()) + if err != nil { + return nil, err + } if len(receipts) <= int(index) { return nil, nil } @@ -586,7 +594,11 @@ func (pea *PublicEthAPI) localGetLogs(crit filters.FilterCriteria) ([]*types.Log if err := tx.Commit(); err != nil { return nil, err } - return extractLogsOfInterest(rctIPLDs, filter.Topics) + block, err := pea.B.BlockByHash(context.Background(), *crit.BlockHash) + if err != nil { + return nil, err + } + return extractLogsOfInterest(pea.B.Config.ChainConfig, *crit.BlockHash, block.NumberU64(), block.Transactions(), rctIPLDs, filter.Topics) } // Otherwise, create block range from criteria // nil values are filled in; to request a single block have both ToBlock and FromBlock equal that number @@ -619,7 +631,8 @@ func (pea *PublicEthAPI) localGetLogs(crit filters.FilterCriteria) ([]*types.Log if err := tx.Commit(); err != nil { return nil, err } - logs, err := extractLogsOfInterest(rctIPLDs, filter.Topics) + // @TODO refactor this and pass actual block hash and block number + logs, err := extractLogsOfInterest(pea.B.Config.ChainConfig, common.Hash{}, 0, types.Transactions{}, rctIPLDs, filter.Topics) return logs, err // need to return err variable so that we return the err = tx.Commit() assignment in the defer } diff --git a/pkg/eth/backend_utils.go b/pkg/eth/backend_utils.go index 98b1e33c..0341b2a8 100644 --- a/pkg/eth/backend_utils.go +++ b/pkg/eth/backend_utils.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/ethereum/go-ethereum/params" "math/big" "github.com/ethereum/go-ethereum" @@ -244,20 +245,31 @@ func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransacti } // extractLogsOfInterest returns logs from the receipt IPLD -func extractLogsOfInterest(rctIPLDs []ipfs.BlockModel, wantedTopics [][]string) ([]*types.Log, error) { +func extractLogsOfInterest(config *params.ChainConfig, blockHash common.Hash, blockNumber uint64, txs types.Transactions, rctIPLDs []ipfs.BlockModel, wantedTopics [][]string) ([]*types.Log, error) { var logs []*types.Log - for _, rctIPLD := range rctIPLDs { - rctRLP := rctIPLD - var rct types.Receipt - if err := rlp.DecodeBytes(rctRLP.Data, &rct); err != nil { + receipts := make(types.Receipts, len(rctIPLDs)) + + for i, rctBytes := range rctIPLDs { + rct := new(types.Receipt) + if err := rlp.DecodeBytes(rctBytes.Data, rct); err != nil { return nil, err } - for _, log := range rct.Logs { + receipts[i] = rct + } + + err := receipts.DeriveFields(config, blockHash, blockNumber, txs) + if err != nil { + return nil, err + } + + for _, receipt := range receipts { + for _, log := range receipt.Logs { if wanted := wantedLog(wantedTopics, log.Topics); wanted == true { logs = append(logs, log) } } } + return logs, nil } diff --git a/test/integration_test.go b/test/integration_test.go index 448d02e4..243185c3 100644 --- a/test/integration_test.go +++ b/test/integration_test.go @@ -97,8 +97,7 @@ var _ = Describe("Integration test", func() { Expect(err).ToNot(HaveOccurred()) // check headers are equals - Expect(gethBlock).To(Equal(ipldBlock)) - Expect(gethBlock.Header()).To(Equal(ipldBlock.Header())) + compareBlocks(gethBlock, ipldBlock) gethTxs := gethBlock.Transactions() ipldTxs := ipldBlock.Transactions() @@ -123,7 +122,7 @@ var _ = Describe("Integration test", func() { ipldTx, _, err := ipldClient.TransactionByHash(ctx, common.HexToHash(contract.TransactionHash)) Expect(err).ToNot(HaveOccurred()) - Expect(gethTx).To(Equal(ipldTx)) + compareTxs(gethTx, ipldTx) Expect(gethTx.Hash()).To(Equal(ipldTx.Hash())) }) @@ -135,9 +134,7 @@ var _ = Describe("Integration test", func() { ipldTx, err := ipldClient.TransactionInBlock(ctx, common.HexToHash(contract.BlockHash), 0) Expect(err).ToNot(HaveOccurred()) - Expect(gethTx).To(Equal(ipldTx)) - - Expect(gethTx.Hash()).To(Equal(ipldTx.Hash())) + compareTxs(gethTx, ipldTx) }) }) @@ -414,3 +411,32 @@ var _ = Describe("Integration test", func() { }) }) }) + +func compareBlocks(block1 *types.Block, block2 *types.Block) { + Expect(block1.Header()).To(Equal(block2.Header())) + Expect(block1.Uncles()).To(Equal(block2.Uncles())) + + txs1 := block1.Transactions() + txs2 := block2.Transactions() + + Expect(len(txs1)).To(Equal(len(txs2))) + for i, tx := range txs1 { + compareTxs(tx, txs2[i]) + } +} + +func compareTxs(tx1 *types.Transaction, tx2 *types.Transaction) { + Expect(tx1.Data()).To(Equal(tx2.Data())) + Expect(tx1.Hash()).To(Equal(tx2.Hash())) + Expect(tx1.Size()).To(Equal(tx2.Size())) + + signer := types.NewEIP155Signer(big.NewInt(4)) + + gethSender, err := types.Sender(signer, tx1) + Expect(err).ToNot(HaveOccurred()) + + ipldSender, err := types.Sender(signer, tx2) + Expect(err).ToNot(HaveOccurred()) + + Expect(gethSender).To(Equal(ipldSender)) +}