@@ -24,6 +24,7 @@ import (
2424
2525 "github.com/CortexFoundation/CortexTheseus/common"
2626 "github.com/CortexFoundation/CortexTheseus/core/types"
27+ "github.com/CortexFoundation/CortexTheseus/crypto"
2728 "github.com/CortexFoundation/CortexTheseus/ctxcdb"
2829 "github.com/CortexFoundation/CortexTheseus/log"
2930 "github.com/CortexFoundation/CortexTheseus/params"
@@ -128,6 +129,46 @@ func DeleteAllTxLookupEntries(db ctxcdb.KeyValueStore, condition func(common.Has
128129 }
129130}
130131
132+ // findTxInBlockBody traverses the given RLP-encoded block body, searching for
133+ // the transaction specified by its hash.
134+ func findTxInBlockBody (blockbody rlp.RawValue , target common.Hash ) (* types.Transaction , uint64 , error ) {
135+ txnListRLP , _ , err := rlp .SplitList (blockbody )
136+ if err != nil {
137+ return nil , 0 , err
138+ }
139+ iter , err := rlp .NewListIterator (txnListRLP )
140+ if err != nil {
141+ return nil , 0 , err
142+ }
143+ txIndex := uint64 (0 )
144+ for iter .Next () {
145+ if iter .Err () != nil {
146+ return nil , 0 , err
147+ }
148+ // The preimage for the hash calculation of legacy transactions
149+ // is just their RLP encoding. For typed (EIP-2718) transactions,
150+ // which are encoded as byte arrays, the preimage is the content of
151+ // the byte array, so trim their prefix here.
152+ txRLP := iter .Value ()
153+ kind , txHashPayload , _ , err := rlp .Split (txRLP )
154+ if err != nil {
155+ return nil , 0 , err
156+ }
157+ if kind == rlp .List { // Legacy transaction
158+ txHashPayload = txRLP
159+ }
160+ if crypto .Keccak256Hash (txHashPayload ) == target {
161+ var tx types.Transaction
162+ if err := rlp .DecodeBytes (txRLP , & tx ); err != nil {
163+ return nil , 0 , err
164+ }
165+ return & tx , txIndex , nil
166+ }
167+ txIndex ++
168+ }
169+ return nil , 0 , errors .New ("transaction not found" )
170+ }
171+
131172// ReadTransaction retrieves a specific transaction from the database, along with
132173// its added positional metadata.
133174func ReadTransaction (db ctxcdb.Reader , hash common.Hash ) (* types.Transaction , common.Hash , uint64 , uint64 ) {
@@ -139,18 +180,17 @@ func ReadTransaction(db ctxcdb.Reader, hash common.Hash) (*types.Transaction, co
139180 if blockHash == (common.Hash {}) {
140181 return nil , common.Hash {}, 0 , 0
141182 }
142- body := ReadBody (db , blockHash , * blockNumber )
143- if body == nil {
183+ bodyRLP := ReadBodyRLP (db , blockHash , * blockNumber )
184+ if bodyRLP == nil {
144185 log .Error ("Transaction referenced missing" , "number" , * blockNumber , "hash" , blockHash )
145186 return nil , common.Hash {}, 0 , 0
146187 }
147- for txIndex , tx := range body . Transactions {
148- if tx . Hash () == hash {
149- return tx , blockHash , * blockNumber , uint64 ( txIndex )
150- }
188+ tx , txIndex , err := findTxInBlockBody ( bodyRLP , hash )
189+ if err != nil {
190+ log . Error ( "Transaction not found" , "number" , * blockNumber , "hash" , blockHash , "txhash" , hash , "err" , err )
191+ return nil , common. Hash {}, 0 , 0
151192 }
152- log .Error ("Transaction not found" , "number" , * blockNumber , "hash" , blockHash , "txhash" , hash )
153- return nil , common.Hash {}, 0 , 0
193+ return tx , blockHash , * blockNumber , txIndex
154194}
155195
156196// ReadReceipt retrieves a specific transaction receipt from the database, along with
0 commit comments