Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a6b4239
update nim-eth module for new Log type
vineetpant Jul 28, 2025
db258b5
update submodules for nim-eth
vineetpant Jul 29, 2025
8224d2e
merge master branch
vineetpant Jul 31, 2025
0f4cc63
Fix errors for new Log type
vineetpant Aug 3, 2025
e1aa84d
fix rpc_utils and filters for new Log type
vineetpant Aug 4, 2025
136d741
add log container types
vineetpant Aug 5, 2025
6dbd700
update logindex and filterRow types
vineetpant Aug 5, 2025
3443aa8
Update helper functions
vineetpant Aug 6, 2025
e433b1b
add fnv1a_hash and update helper functions
vineetpant Aug 7, 2025
0da9db9
integrate logIndex in block processing
vineetpant Aug 15, 2025
652b43c
add basic logIndex test
vineetpant Aug 25, 2025
2e3a4ef
test: add test for log index edge cases
vineetpant Aug 28, 2025
68b8389
feat: add eip activation block and tests
vineetpant Sep 1, 2025
b6691f1
feat: implement filter maps and hash tree root
vineetpant Sep 3, 2025
b95afee
merge master branch
vineetpant Sep 8, 2025
1696574
test: fix breaking tests
vineetpant Sep 8, 2025
bb7d06d
merge master
vineetpant Sep 12, 2025
5bad257
fix: update activation of EIP 7745 to use timestamp
vineetpant Sep 16, 2025
5ed044d
feat: add eip7745Time fork
vineetpant Sep 16, 2025
0b06918
feat: update eip7745 fork details
vineetpant Sep 18, 2025
4f83fb1
update nim-eth submodule to fix index error
vineetpant Oct 25, 2025
a366881
add debug logs for eip activation
vineetpant Nov 4, 2025
ab29d1f
chore: merge master into eip-7745-log-value-index
vineetpant Nov 6, 2025
701ed43
chore: update nim-eth submodule to latest adjust-log-types
vineetpant Nov 6, 2025
1038399
feat: implement logIndex accumulation across blocks for EIP-7745
vineetpant Nov 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
branch = master
[submodule "vendor/nim-eth"]
path = vendor/nim-eth
url = https://github.com/status-im/nim-eth.git
url = https://github.com/vineetpant/nim-eth
ignore = dirty
branch = master
branch = adjust-log-types
[submodule "vendor/nim-http-utils"]
path = vendor/nim-http-utils
url = https://github.com/status-im/nim-http-utils.git
Expand Down
2 changes: 2 additions & 0 deletions execution_chain/common/chain_config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ const
"bpo4",
"bpo5",
"amsterdam",
"eip7745",
]

func ofStmt(fork: HardFork, keyName: string, reader: NimNode, value: NimNode): NimNode =
Expand Down Expand Up @@ -509,6 +510,7 @@ func defaultBlobSchedule*(): array[Cancun..HardFork.high, Opt[BlobSchedule]] =
Bpo4 : Opt.none(BlobSchedule),
Bpo5 : Opt.none(BlobSchedule),
Amsterdam: Opt.none(BlobSchedule),
Eip7745: Opt.none(BlobSchedule),
]

func chainConfigForNetwork*(id: NetworkId): ChainConfig =
Expand Down
3 changes: 3 additions & 0 deletions execution_chain/common/common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,9 @@ func isOsakaOrLater*(com: CommonRef, t: EthTime): bool =
func isAmsterdamOrLater*(com: CommonRef, t: EthTime): bool =
com.config.amsterdamTime.isSome and t >= com.config.amsterdamTime.value

func isEip7745OrLater*(com: CommonRef, t: EthTime): bool =
com.config.eip7745Time.isSome and t >= com.config.eip7745Time.value

proc proofOfStake*(com: CommonRef, header: Header, txFrame: CoreDbTxRef): bool =
if com.config.posBlock.isSome:
# see comments of posBlock in common/hardforks.nim
Expand Down
1 change: 1 addition & 0 deletions execution_chain/common/evmforks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type
FkBpo4
FkBpo5
FkAmsterdam
FkEip7745

const
FkLatest* = EVMFork.high
4 changes: 4 additions & 0 deletions execution_chain/common/hardforks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type
Bpo4
Bpo5
Amsterdam
Eip7745

const lastPurelyBlockNumberBasedFork* = GrayGlacier
# MergeFork is special because of TTD.
Expand Down Expand Up @@ -188,6 +189,7 @@ type
bpo4Time* : Opt[EthTime]
bpo5Time* : Opt[EthTime]
amsterdamTime* : Opt[EthTime]
eip7745Time* : Opt[EthTime]

terminalTotalDifficulty*: Opt[UInt256]
depositContractAddress*: Opt[Address]
Expand Down Expand Up @@ -308,6 +310,7 @@ func populateFromForkTransitionTable*(conf: ChainConfig, t: ForkTransitionTable)
conf.bpo4Time = t.timeThresholds[HardFork.Bpo4]
conf.bpo5Time = t.timeThresholds[HardFork.Bpo5]
conf.amsterdamTime = t.timeThresholds[HardFork.Amsterdam]
conf.eip7745Time = t.timeThresholds[HardFork.Eip7745]

# ------------------------------------------------------------------------------
# Map HardFork to EVM Fork
Expand Down Expand Up @@ -340,6 +343,7 @@ const
FkBpo4, # Bpo4
FkBpo5, # Bpo5
FkAmsterdam, # Amsterdam
FkEip7745, # Eip7745
]

# ------------------------------------------------------------------------------
Expand Down
10 changes: 7 additions & 3 deletions execution_chain/core/chain/forked_chain.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import
../../evm/types,
../../evm/state,
../validate,
../log_index,
../../portal/portal,
./forked_chain/[
chain_desc,
Expand Down Expand Up @@ -54,14 +55,16 @@ func appendBlock(c: ForkedChainRef,
blk: Block,
blkHash: Hash32,
txFrame: CoreDbTxRef,
receipts: sink seq[StoredReceipt]): BlockRef =
receipts: sink seq[StoredReceipt],
logIndex: LogIndex): BlockRef =

let newBlock = BlockRef(
blk : blk,
txFrame : txFrame,
receipts: move(receipts),
hash : blkHash,
parent : parent,
logIndex: logIndex, # EIP-7745: Store accumulated log index
index : 0, # Only finalized segment have finalized marker
)

Expand Down Expand Up @@ -509,7 +512,8 @@ proc validateBlock(c: ForkedChainRef,
parentTxFrame=cast[uint](parentFrame),
txFrame=cast[uint](txFrame)

var receipts = c.processBlock(parent, txFrame, blk, blkHash, finalized).valueOr:
# EIP-7745: processBlock returns (receipts, logIndex) tuple
var (receipts, logIndex) = c.processBlock(parent, txFrame, blk, blkHash, finalized).valueOr:
txFrame.dispose()
return err(error)

Expand All @@ -520,7 +524,7 @@ proc validateBlock(c: ForkedChainRef,
# is being applied to a block that is currently not a head).
txFrame.checkpoint(blk.header.number, skipSnapshot = false)

let newBlock = c.appendBlock(parent, blk, blkHash, txFrame, move(receipts))
let newBlock = c.appendBlock(parent, blk, blkHash, txFrame, move(receipts), logIndex)

for i, tx in blk.transactions:
c.txRecords[computeRlpHash(tx)] = (blkHash, uint64(i))
Expand Down
5 changes: 4 additions & 1 deletion execution_chain/core/chain/forked_chain/chain_branch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
import
eth/common/blocks,
eth/common/receipts,
../../../db/core_db
../../../db/core_db,
../../log_index

type
BlockRef* = ref object
Expand All @@ -22,6 +23,8 @@ type
receipts*: seq[StoredReceipt]
hash* : Hash32
parent* : BlockRef
logIndex*: LogIndex
# EIP-7745: Accumulated log index state after this block

index* : uint
# Alias to parent when serializing
Expand Down
9 changes: 6 additions & 3 deletions execution_chain/core/chain/forked_chain/chain_private.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import
./chain_desc,
../../validate,
../../executor/process_block,
../../log_index,
../../../common,
../../../db/core_db,
../../../evm/types,
Expand Down Expand Up @@ -40,12 +41,13 @@ proc processBlock*(c: ForkedChainRef,
txFrame: CoreDbTxRef,
blk: Block,
blkHash: Hash32,
finalized: bool): Result[seq[StoredReceipt], string] =
finalized: bool): Result[(seq[StoredReceipt], LogIndex), string] =
template header(): Header =
blk.header

let vmState = BaseVMState()
vmState.init(parentBlk.header, header, c.com, txFrame)
# EIP-7745: Pass parent's logIndex to accumulate across blocks
vmState.init(parentBlk.header, header, c.com, txFrame, logIndex = parentBlk.logIndex)

?c.com.validateHeaderAndKinship(blk, vmState.parent, txFrame)

Expand Down Expand Up @@ -89,4 +91,5 @@ proc processBlock*(c: ForkedChainRef,
# because validateUncles still need it
?txFrame.persistHeader(blkHash, header, c.com.startOfHistory)

ok(move(vmState.receipts))
# EIP-7745: Return both receipts and logIndex
ok((move(vmState.receipts), vmState.logIndex))
6 changes: 5 additions & 1 deletion execution_chain/core/chain/forked_chain/chain_serialize.nim
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,14 @@ proc replayBlock(fc: ForkedChainRef;
# Set finalized to true in order to skip the stateroot check when replaying the
# block because the blocks should have already been checked previously during
# the initial block execution.
var receipts = fc.processBlock(parent, txFrame, blk.blk, blk.hash, finalized = true).valueOr:
# EIP-7745: processBlock returns (receipts, logIndex) tuple
var (receipts, logIndex) = fc.processBlock(parent, txFrame, blk.blk, blk.hash, finalized = true).valueOr:
txFrame.dispose()
return err(error)

# Update parent's logIndex for next iteration
parent.logIndex = logIndex

fc.writeBaggage(blk.blk, blk.hash, txFrame, receipts)

# Checkpoint creates a snapshot of ancestor changes in txFrame - it is an
Expand Down
9 changes: 5 additions & 4 deletions execution_chain/core/eip6110.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import
eth/common/receipts,
ssz_serialization,
stew/assign2,
stew/arrayops,
results
Expand Down Expand Up @@ -74,12 +75,12 @@ func depositLogToRequest(data: openArray[byte]): DepositRequest =
func parseDepositLogs*(logs: openArray[Log], depositContractAddress: Address): Result[seq[byte], string] =
var res = newSeqOfCap[byte](logs.len*depositRequestSize)
for i, log in logs:
let isDepositEvent = log.topics.len > 0 and
let isDepositEvent = len(log.topics) > 0 and
log.topics[0] == DEPOSIT_EVENT_SIGNATURE_HASH
if not(log.address == depositContractAddress and isDepositEvent):
continue
if log.data.len != 576:
return err("deposit wrong length: want 576, have " & $log.data.len)
res.add depositLogToRequest(log.data)
if len(log.topics) != 576:
return err("deposit wrong length: want 576, have " & $len(log.topics))
res.add depositLogToRequest(log.data.asSeq())

ok(move(res))
1 change: 1 addition & 0 deletions execution_chain/core/eip7691.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const
Bpo4,
Bpo5,
Amsterdam,
Eip7745,
]

func getMaxBlobsPerBlock*(com: CommonRef, fork: EVMFork): uint64 =
Expand Down
1 change: 1 addition & 0 deletions execution_chain/core/executor/calculate_reward.nim
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const
eth0, # Bpo4
eth0, # Bpo5
eth0, # Amsterdam
eth0, # Eip7745
]

proc calculateReward*(vmState: BaseVMState; account: Address;
Expand Down
1 change: 1 addition & 0 deletions execution_chain/core/executor/executor_helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import
../../evm/state,
../../evm/types,
../../common/common,
ssz_serialization,
../../transaction/call_types

type
Expand Down
86 changes: 77 additions & 9 deletions execution_chain/core/executor/process_block.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import
../../evm/types,
../dao,
../eip6110,
../log_index,
./calculate_reward,
./executor_helpers,
./process_transaction,
eth/common/[keys, transaction_utils],
chronicles,
results,
taskpools
taskpools,
ssz_serialization

template withSender(txs: openArray[Transaction], body: untyped) =
# Execute transactions offloading the signature checking to the task pool if
Expand Down Expand Up @@ -81,6 +83,12 @@ proc processTransactions*(
vmState.receipts.setLen(if skipReceipts: 0 else: transactions.len)
vmState.cumulativeGasUsed = 0
vmState.allLogs = @[]

# NEW: Debug logging for EIP-7745
debug "Processing transactions for block",
blockNumber = header.number,
txCount = transactions.len,
currentIndex = vmState.logIndex.next_index

withSender(transactions):
if sender == default(Address):
Expand Down Expand Up @@ -229,13 +237,73 @@ proc procBlkEpilogue(
err("stateRoot mismatch, expect: " & $header.stateRoot & ", got: " & $stateRoot)

if not skipReceipts:
let bloom = createBloom(vmState.receipts)

if header.logsBloom != bloom:
debug "wrong logsBloom in block",
blockNumber = header.number, actual = bloom, expected = header.logsBloom
return err("bloom mismatch")

# =========================================================================
# EIP-7745 INTEGRATION: Replace bloom filter with LogIndex
# =========================================================================

# Debug logging before LogIndex update
debug "Updating LogIndex for block",
blockNumber = header.number,
receiptsCount = vmState.receipts.len,
currentIndex = vmState.logIndex.next_index

# EIP-7745: Add current block's logs to accumulated logIndex from parent
vmState.logIndex.add_block_logs(header, vmState.receipts)
debug "LogIndex updated in process_block",
blockNumber = header.number,
totalEntries = vmState.logIndex.next_index

# Choose validation method based on activation timestamp
# DEBUG: Log the activation check details
let eip7745Active = vmState.com.isEip7745OrLater(header.timestamp)
debug "EIP-7745 activation check in process_block",
blockNumber = header.number,
blockTimestamp = header.timestamp,
isActive = eip7745Active

if eip7745Active:
# Validate using LogIndexSummary for EIP-7745 blocks
let summary = createLogIndexSummary(vmState.logIndex)

# Encode to 256 bytes using manual encoding
# SSZ encoding causes stack overflow with complex LogIndexSummary
var encoded = encodeLogIndexSummary(summary)

# Verify the encoded size
if encoded.len != 256:
return err("LogIndexSummary encoding size mismatch: got " &
$encoded.len & " bytes, expected 256")

# Convert encoded bytes to Bloom
var bloomData: array[256, byte]
for i in 0..<256:
bloomData[i] = encoded[i]
let bloom = Bloom(bloomData)

if header.logsBloom != bloom:
debug "wrong logsBloom (LogIndexSummary) in block",
expected = header.logsBloom,
calculated = bloom
return err("logsBloom (LogIndexSummary) mismatch")

debug "LogIndexSummary validated successfully",
blockNumber = header.number,
summarySize = encoded.len,
receiptsCount = vmState.receipts.len,
nextIndex = vmState.logIndex.next_index
else:
# Validate using traditional bloom filter for pre-EIP-7745 blocks
let bloom = vmState.receipts.createBloom()
if header.logsBloom != bloom:
debug "wrong logsBloom (traditional) in block",
expected = header.logsBloom,
calculated = bloom
return err("traditional bloom mismatch")

debug "Traditional bloom validated successfully",
blockNumber = header.number,
receiptsCount = vmState.receipts.len

let receiptsRoot = calcReceiptsRoot(vmState.receipts)
if header.receiptsRoot != receiptsRoot:
# TODO replace logging with better error
Expand Down Expand Up @@ -296,4 +364,4 @@ proc processBlock*(

# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
Loading
Loading