Skip to content

Commit

Permalink
fetch txHash from txRecord + reduce blockHash call
Browse files Browse the repository at this point in the history
  • Loading branch information
advaita-saha committed Feb 11, 2025
1 parent 577e355 commit 94c9093
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 10 deletions.
14 changes: 13 additions & 1 deletion nimbus/core/chain/forked_chain.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import
chronicles,
std/tables,
std/[tables, algorithm],
../../common,
../../db/core_db,
../../evm/types,
Expand All @@ -21,6 +21,8 @@ import
../executor/process_block,
./forked_chain/[chain_desc, chain_kvt, chain_branch]

from std/sequtils import mapIt

logScope:
topics = "forked chain"

Expand Down Expand Up @@ -632,6 +634,16 @@ func memoryTransaction*(c: ForkedChainRef, txHash: Hash32): Opt[(Transaction, Bl
return Opt.some( (loc[].tx(index), loc[].number) )
return Opt.none((Transaction, BlockNumber))

func memoryTxHashesForBlock*(c: ForkedChainRef, blockHash: Hash32): seq[Hash32] =
var cachedTxHashes = newSeq[(Hash32, uint64)]()
for txHash, (blkHash, txIdx) in c.txRecords.pairs:
if blkHash == blockHash:
cachedTxHashes.add((txHash, txIdx))

cachedTxHashes.sorted(proc(a, b: (Hash32, uint64)): int =
cmp(a[1], b[1])
).mapIt(it[0])

proc latestBlock*(c: ForkedChainRef): Block =
if c.activeBranch.headNumber == c.baseBranch.tailNumber:
# It's a base block
Expand Down
15 changes: 13 additions & 2 deletions nimbus/rpc/filters.nim
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,30 @@ proc deriveLogs*(
transactions: openArray[Transaction],
receipts: openArray[Receipt],
filterOptions: FilterOptions,
txHashes: Opt[seq[Hash32]] = Opt.none(seq[Hash32])
): seq[FilterLog] =
## Derive log fields, does not deal with pending log, only the logs with
## full data set
doAssert(len(transactions) == len(receipts))

# Verify that txHashes is consistent with transactions
if txHashes.isSome:
doAssert(txHashes.get.len == len(transactions))

let blkHash = header.blockHash
var resLogs: seq[FilterLog] = @[]
var logIndex = 0'u64

for i, receipt in receipts:
let logs = receipt.logs.filterIt(it.match(filterOptions.address, filterOptions.topics))
if logs.len > 0:
# TODO avoid recomputing entirely - we should have this cached somewhere
let txHash = transactions[i].rlpHash
let txHash =
if txHashes.isSome:
txHashes.get[i] # cached txHashes
else:
transactions[i].rlpHash

for log in logs:
let filterLog = FilterLog(
# TODO investigate how to handle this field
Expand All @@ -89,7 +100,7 @@ proc deriveLogs*(
logIndex: Opt.some(Quantity(logIndex)),
transactionIndex: Opt.some(Quantity(i)),
transactionHash: Opt.some(txHash),
blockHash: Opt.some(header.blockHash),
blockHash: Opt.some(blkHash),
blockNumber: Opt.some(Quantity(header.number)),
address: log.address,
data: log.data,
Expand Down
15 changes: 8 additions & 7 deletions nimbus/rpc/server_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -226,26 +226,27 @@ proc setupServerAPI*(api: ServerAPIRef, server: RpcServer, ctx: EthContext) =
chain: ForkedChainRef, header: Header, opts: FilterOptions
): Opt[seq[FilterLog]] {.gcsafe, raises: [].} =
if headerBloomFilter(header, opts.address, opts.topics):
let (receipts, txs) =
if api.chain.isInMemory(header.blockHash):
let blk = api.chain.memoryBlock(header.blockHash)
(blk.receipts, blk.blk.transactions)
let blkHash = header.blockHash
let (receipts, txs, cachedHashes) =
if api.chain.isInMemory(blkHash):
let blk = api.chain.memoryBlock(blkHash)
(blk.receipts, blk.blk.transactions, Opt.some(chain.memoryTxHashesForBlock(blkHash)))
else:
let rcs = chain.baseTxFrame.getReceipts(header.receiptsRoot).valueOr:
return Opt.some(newSeq[FilterLog](0))
let txs = chain.baseTxFrame.getTransactions(header.txRoot).valueOr:
return Opt.some(newSeq[FilterLog](0))
(rcs, txs)
(rcs, txs, Opt.none(seq[Hash32]))
# Note: this will hit assertion error if number of block transactions
# do not match block receipts.
# Although this is fine as number of receipts should always match number
# of transactions
if txs.len != receipts.len:
warn "Transactions and receipts length mismatch",
number = header.number, hash = header.blockHash.short,
number = header.number, hash = blkHash.short,
txs = txs.len, receipts = receipts.len
return Opt.none(seq[FilterLog])
let logs = deriveLogs(header, txs, receipts, opts)
let logs = deriveLogs(header, txs, receipts, opts, cachedHashes)
return Opt.some(logs)
else:
return Opt.some(newSeq[FilterLog](0))
Expand Down

0 comments on commit 94c9093

Please sign in to comment.