From b073787f1dbbc997dca991e9760a258727b835cb Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sun, 21 Nov 2021 09:22:29 +0000 Subject: [PATCH] eth_getTransactionReceipt not to return unrelated txs (#2998) * Cleanup * Restore * Fix for existing tx * Cleanup Co-authored-by: Alex Sharp --- cmd/rpcdaemon/commands/eth_receipts.go | 5 ++ core/state/database_test.go | 67 ++++++++++++++++++++++++++ eth/stagedsync/stage_txlookup.go | 4 +- 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go index e246cc01a..535d821b3 100644 --- a/cmd/rpcdaemon/commands/eth_receipts.go +++ b/cmd/rpcdaemon/commands/eth_receipts.go @@ -265,12 +265,17 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash) return nil, fmt.Errorf("could not find block %d", *blockNumber) } var txIndex uint64 + var found bool for idx, txn := range block.Transactions() { if txn.Hash() == hash { txIndex = uint64(idx) + found = true break } } + if !found { + return nil, nil + } cc, err := api.chainConfig(tx) if err != nil { diff --git a/core/state/database_test.go b/core/state/database_test.go index 0a1068f8c..4f71ab255 100644 --- a/core/state/database_test.go +++ b/core/state/database_test.go @@ -1593,3 +1593,70 @@ func TestRecreateAndRewind(t *testing.T) { require.NoError(t, err) } +func TestTxLookupUnwind(t *testing.T) { + var ( + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + address = crypto.PubkeyToAddress(key.PublicKey) + funds = big.NewInt(1000000000) + gspec = &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: new(big.Int), + EIP150Block: new(big.Int), + EIP155Block: new(big.Int), + EIP158Block: big.NewInt(1), + ByzantiumBlock: big.NewInt(1), + ConstantinopleBlock: big.NewInt(1), + }, + Alloc: core.GenesisAlloc{ + address: {Balance: funds}, + }, + } + signer = types.LatestSignerForChainID(nil) + ) + + m := stages.MockWithGenesis(t, gspec, key) + chain1, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, block *core.BlockGen) { + var tx types.Transaction + var e error + switch i { + case 1: + tx, e = types.SignTx(types.NewTransaction(block.TxNonce(address), address, uint256.NewInt(0), 1000000, new(uint256.Int), nil), *signer, key) + if e != nil { + t.Fatal(e) + } + block.AddTx(tx) + } + }, false) + if err != nil { + t.Fatal(err) + } + chain2, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 3, func(i int, block *core.BlockGen) { + }, false) + if err != nil { + t.Fatal(err) + } + if err = m.InsertChain(chain1); err != nil { + t.Fatal(err) + } + if err = m.InsertChain(chain2); err != nil { + t.Fatal(err) + } + var count uint64 + if err = m.DB.View(context.Background(), func(tx kv.Tx) error { + c, e := tx.Cursor(kv.TxLookup) + if e != nil { + return e + } + defer c.Close() + if count, e = c.Count(); e != nil { + return e + } + return nil + }); err != nil { + t.Fatal(err) + } + if count != 0 { + t.Errorf("txlookup record expected to be deleted, got %d", count) + } +} diff --git a/eth/stagedsync/stage_txlookup.go b/eth/stagedsync/stage_txlookup.go index 6b283a5ac..c3016410b 100644 --- a/eth/stagedsync/stage_txlookup.go +++ b/eth/stagedsync/stage_txlookup.go @@ -152,7 +152,9 @@ func unwindTxLookup(u *UnwindState, s *StageState, tx kv.RwTx, cfg TxLookupCfg, }, etl.IdentityLoadFunc, etl.TransformArgs{ Quit: quitCh, ExtractStartKey: dbutils.EncodeBlockNumber(u.UnwindPoint + 1), - ExtractEndKey: dbutils.EncodeBlockNumber(s.BlockNumber), + // end key needs to be s.BlockNumber + 1 and not s.BlockNumber, because + // the keys in BlockBody table always have hash after the block number + ExtractEndKey: dbutils.EncodeBlockNumber(s.BlockNumber + 1), LogDetailsExtract: func(k, v []byte) (additionalLogArguments []interface{}) { return []interface{}{"block", binary.BigEndian.Uint64(k)} },