Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
1872007
Increase rpc server request body limit to 26MB
jangko Jul 14, 2025
62eddb1
update EIP-7825 https://github.com/ethereum/EIPs/pull/9986
advaita-saha Jul 21, 2025
bbe3a39
update eip-7918 to reduce blob base cost
advaita-saha Jul 21, 2025
ee8146f
increase clz gas cost to prevent DoS
advaita-saha Jul 21, 2025
b7870d2
increase gas cost to 6900
advaita-saha Jul 21, 2025
c5f5d89
fix: tests
advaita-saha Jul 21, 2025
411111b
add max blobs per tx
advaita-saha Jul 22, 2025
85c8beb
Update EIP-7883: Remove GasQuadDivisor from gacCalc equation
jangko Jul 22, 2025
014596b
shift to a cleaner approach
advaita-saha Jul 22, 2025
53abc8b
update txpool
advaita-saha Jul 22, 2025
2f26abb
Merge branch 'tx-gas-limit' into fusaka-devnet-3
advaita-saha Jul 22, 2025
85cc136
Merge branch 'decrease-blob-base-cose' into fusaka-devnet-3
advaita-saha Jul 22, 2025
7317912
Merge branch 'increase-clz-gascost' into fusaka-devnet-3
advaita-saha Jul 22, 2025
758ab31
Merge branch 'secp256r1-gas-increase' into fusaka-devnet-3
advaita-saha Jul 22, 2025
dd9feaf
Merge branch 'blob-tx-limit' into fusaka-devnet-3
advaita-saha Jul 22, 2025
f369550
Merge branch 'add-modexp-test' into fusaka-devnet-3
advaita-saha Jul 22, 2025
75339b5
Merge branch 'fusaka-22' into fusaka-devnet-3
advaita-saha Jul 22, 2025
c4c392e
increase blob pool size
advaita-saha Jul 22, 2025
560e010
txpool hotfix experimental
advaita-saha Jul 23, 2025
d5fc84d
Fix peering issue
jangko Jul 25, 2025
0c64f7e
debug log
jangko Jul 25, 2025
0e61018
fix: fc.reset and headerFetch error reset
advaita-saha Jul 25, 2025
7deaf0c
Merge branch 'peering-issue' into fusaka-devnet-3
advaita-saha Jul 25, 2025
d013b69
intial setup for eth_config
advaita-saha Aug 1, 2025
45b4ee0
basic impl without system contracts
advaita-saha Aug 2, 2025
1399eb8
add forkid support
advaita-saha Aug 2, 2025
b4d47ac
minute fixes
advaita-saha Aug 2, 2025
b7483e7
Merge branch 'master' into eth-config
advaita-saha Aug 2, 2025
3a85cba
fix crash
advaita-saha Aug 2, 2025
7e514aa
shift to header
advaita-saha Aug 3, 2025
fc2ceb0
add debug points
advaita-saha Aug 3, 2025
ca97130
more debug logs with fixes
advaita-saha Aug 3, 2025
47b2548
fix crashes due to nil pointer
advaita-saha Aug 3, 2025
35884df
shift to JsonNumber
advaita-saha Aug 3, 2025
81a8411
shift to timestamp
advaita-saha Aug 3, 2025
81becbf
fix: system contracts forking
advaita-saha Aug 3, 2025
9533714
shift to numbers
advaita-saha Aug 4, 2025
408fd57
fix forkId calculation
advaita-saha Aug 4, 2025
2bd8e97
Merge branch 'master' into eth-config
advaita-saha Aug 4, 2025
0b8fb9d
add tests
advaita-saha Aug 5, 2025
b4bb737
remove unwanted logscope
advaita-saha Aug 5, 2025
d504307
nim-web bump
advaita-saha Aug 5, 2025
52b0958
Merge branch 'master' into fusaka-devnet-3
advaita-saha Aug 5, 2025
f64dd02
Merge branch 'eth-config' into fusaka-devnet-3
advaita-saha Aug 5, 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
27 changes: 26 additions & 1 deletion execution_chain/common/common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ func toHardFork*(
toHardFork(com.forkTransitionTable, forkDeterminer)

func toHardFork*(com: CommonRef, timestamp: EthTime): HardFork =
for fork in countdown(com.forkTransitionTable.timeThresholds.high, Shanghai):
for fork in countdown(HardFork.high, Shanghai):
if com.forkTransitionTable.timeThresholds[fork].isSome and timestamp >= com.forkTransitionTable.timeThresholds[fork].get:
return fork

Expand All @@ -306,6 +306,27 @@ func toEVMFork*(com: CommonRef, forkDeterminer: ForkDeterminationInfo): EVMFork
let fork = com.toHardFork(forkDeterminer)
ToEVMFork[fork]

func nextFork*(com: CommonRef, currentFork: HardFork): Opt[HardFork] =
## Returns the next hard fork after the given one
## The next fork can also be the last fork
if currentFork < Shanghai:
return Opt.none(HardFork)
for fork in currentFork .. HardFork.high:
if fork > currentFork and com.forkTransitionTable.timeThresholds[fork].isSome:
return Opt.some(fork)
return Opt.none(HardFork)

func lastFork*(com: CommonRef, currentFork: HardFork): Opt[HardFork] =
## Returns the last hard fork before the given one
for fork in countdown(HardFork.high, currentFork):
if fork > currentFork and com.forkTransitionTable.timeThresholds[fork].isSome:
return Opt.some(HardFork(fork))
return Opt.none(HardFork)

func activationTime*(com: CommonRef, fork: HardFork): Opt[EthTime] =
## Returns the activation time of the given hard fork
com.forkTransitionTable.timeThresholds[fork]

func toEVMFork*(com: CommonRef, header: Header): EVMFork =
com.toEVMFork(forkDeterminationInfo(header))

Expand All @@ -323,6 +344,10 @@ func forkId*(com: CommonRef, head, time: uint64): ForkID {.gcsafe.} =
## EIP 2364/2124
com.forkIdCalculator.newID(head, time)

func forkId*(com: CommonRef, forkActivationTime: EthTime): ForkID {.gcsafe.} =
# Only works for timestamp based forks
com.forkIdCalculator.newID(0'u64, forkActivationTime.uint64)

func forkId*(com: CommonRef, head: BlockNumber, time: EthTime): ForkID {.gcsafe.} =
## EIP 2364/2124
com.forkIdCalculator.newID(head, time.uint64)
Expand Down
8 changes: 4 additions & 4 deletions execution_chain/core/tx_pool/tx_desc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ type
blobTab : BlobLookupTab

const
MAX_POOL_SIZE = 5000
MAX_TXS_PER_ACCOUNT = 100
TX_ITEM_LIFETIME = initDuration(minutes = 60)
MAX_POOL_SIZE = 8000
MAX_TXS_PER_ACCOUNT = 500
TX_ITEM_LIFETIME = initDuration(minutes = 5)
TX_MAX_SIZE* = 128 * 1024
# BLOB_TX_MAX_SIZE is the maximum size a single transaction can have, outside
# the included blobs. Since blob transactions are pulled instead of pushed,
# and only a small metadata is kept in ram, there is no critical limit that
# should be enforced. Still, capping it to some sane limit can never hurt.
BLOB_TX_MAX_SIZE* = 1024 * 1024
BLOB_TX_MAX_SIZE* = 1024 * 1024 * 2

# ------------------------------------------------------------------------------
# Private functions
Expand Down
37 changes: 29 additions & 8 deletions execution_chain/evm/precompiles.nim
Original file line number Diff line number Diff line change
Expand Up @@ -110,19 +110,32 @@ const
paP256VerifyAddress # paP256Verify
]

precompileNames*: array[Precompiles, string] = [
"ECREC",
"SHA256",
"RIPEMD160",
"ID",
"MODEXP",
"BN254_ADD",
"BN254_MUL",
"BN254_PAIRING",
"BLAKE2F",
"KZG_POINT_EVALUATION",
"BLS12_G1ADD",
"BLS12_G1MSM",
"BLS12_G2ADD",
"BLS12_G2MSM",
"BLS12_PAIRING_CHECK",
"BLS12_MAP_FP_TO_G1",
"BLS12_MAP_FP2_TO_G2",
"P256_VERIFY"
]


# ------------------------------------------------------------------------------
# Private functions
# ------------------------------------------------------------------------------

func getMaxPrecompile(fork: EVMFork): Precompiles =
if fork < FkByzantium: paIdentity
elif fork < FkIstanbul: paPairing
elif fork < FkCancun: paBlake2bf
elif fork < FkPrague: paPointEvaluation
elif fork < FkOsaka: paBlsMapG2
else: Precompiles.high

func getSignature(c: Computation): EvmResult[SigRes] =
# input is Hash, V, R, S
template data: untyped = c.msg.data
Expand Down Expand Up @@ -796,6 +809,14 @@ proc p256verify(c: Computation): EvmResultVoid =
# Public functions
# ------------------------------------------------------------------------------

func getMaxPrecompile*(fork: EVMFork): Precompiles =
if fork < FkByzantium: paIdentity
elif fork < FkIstanbul: paPairing
elif fork < FkCancun: paBlake2bf
elif fork < FkPrague: paPointEvaluation
elif fork < FkOsaka: paBlsMapG2
else: Precompiles.high

iterator activePrecompiles*(fork: EVMFork): Address =
let maxPrecompile = getMaxPrecompile(fork)
for c in Precompiles.low..maxPrecompile:
Expand Down
84 changes: 84 additions & 0 deletions execution_chain/rpc/rpc_utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
{.push raises: [].}

import
stew/endians2,
std/[sequtils, algorithm],
./rpc_types,
./params,
Expand Down Expand Up @@ -308,3 +309,86 @@ proc createAccessList*(header: Header,
)

prevTracer = tracer


proc populateConfigObject*(com: CommonRef, fork: HardFork): ConfigObject =
let
cancunSystemContracts: seq[SystemContractPair] = @[
SystemContractPair(
address: BEACON_ROOTS_ADDRESS,
name: "BEACON_ROOTS_ADDRESS"
)
]
pragueSystemContracts: seq[SystemContractPair] = @[
SystemContractPair(
address: SYSTEM_ADDRESS,
name: "CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS"
),
SystemContractPair(
address: com.depositContractAddress(),
name: "DEPOSIT_CONTRACT_ADDRESS"
),
SystemContractPair(
address: HISTORY_STORAGE_ADDRESS,
name: "HISTORY_STORAGE_ADDRESS"
),
SystemContractPair(
address: WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS,
name: "WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS"
)
]

var configObject = ConfigObject()

configObject.activationTime = Number com.activationTime(fork).get(EthTime(0))
configObject.chainId = com.chainId
configObject.forkId = FixedBytes[4] com.forkId(
com.activationTime(fork).get(EthTime(0))
).crc.toBytesBE
configObject.blobSchedule.max = Number com.maxBlobsPerBlock(fork)
configObject.blobSchedule.target = Number com.targetBlobsPerBlock(fork)
configObject.blobSchedule.baseFeeUpdateFraction = Number com.baseFeeUpdateFraction(fork)

# Precompiles
let
evmFork = ToEVMFork[fork]
lastPrecompile = getMaxPrecompile(evmFork)

for i in Precompiles.low..lastPrecompile:
configObject.precompiles.add PrecompilePair(
address: precompileAddrs[i],
name: precompileNames[i],
)

# System Contracts
if fork == Cancun:
configObject.systemContracts = cancunSystemContracts
elif fork >= Prague:
configObject.systemContracts = cancunSystemContracts & pragueSystemContracts
else:
configObject.systemContracts = @[]

return configObject

proc getEthConfigObject*(com: CommonRef,
chain: ForkedChainRef,
fork: HardFork,
nextFork: Opt[HardFork],
lastFork: Opt[HardFork]): EthConfigObject =
## Returns the EthConfigObject for the given chain.
## This is used to return the `eth_config` object in the JSON-RPC API.
var res = EthConfigObject()
res.current = com.populateConfigObject(fork)

if nextFork.isSome:
res.next = Opt.some(com.populateConfigObject(nextFork.get))
else:
res.next = Opt.none(ConfigObject)

if lastFork.isSome:
res.last = Opt.some(com.populateConfigObject(lastFork.get))
else:
res.last = Opt.none(ConfigObject)

return res

13 changes: 13 additions & 0 deletions execution_chain/rpc/server_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -714,3 +714,16 @@ proc setupServerAPI*(api: ServerAPIRef, server: RpcServer, ctx: EthContext) =
return populateBlockObject(
uncleHash, uncle, api.getTotalDifficulty(uncleHash), false, true
)

server.rpc("eth_config") do() -> EthConfigObject:
## Returns the current, next and last configuration
let currentFork = api.com.toHardFork(api.chain.latestHeader.forkDeterminationInfo)

if currentFork < Shanghai:
return nil

let
nextFork = api.com.nextFork(currentFork)
lastFork = api.com.lastFork(currentFork)

return api.com.getEthConfigObject(api.chain, currentFork, nextFork, lastFork)
2 changes: 1 addition & 1 deletion execution_chain/sync/beacon/worker_const.nim
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const

# ----------------------

nFetchHeadersFailedInitialPeersThreshold* = 30
nFetchHeadersFailedInitialPeersThreshold* = 15
## If there are more failing peers than this threshold right at the
## begining of a header chain download scrum (before any data received),
## then this session (scrum or sprint) is discarded and the suncer is
Expand Down
8 changes: 8 additions & 0 deletions tests/customgenesis/cancun123.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
"alloc": {
"0x73cf19657412508833f618a15e8251306b3e6ee5": {
"balance": "0x6d6172697573766477000000"
},
"0x00000961Ef480Eb55e80D19ad83579A64c007002": {
"balance": "0",
"code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd"
},
"0x0000BBdDc7CE488642fb579F8B00f3a590007251": {
"balance": "0",
"code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd"
}
},
"number": "0x0",
Expand Down
19 changes: 18 additions & 1 deletion tests/test_rpc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ proc makeBlobTx(env: var TestEnv, nonce: int): PooledTransaction =
PooledTransaction(
tx: tx,
blobsBundle: BlobsBundle(
wrapperVersion: WrapperVersionEIP4844,
blobs: blobs,
commitments: @[pooled_txs.KzgCommitment(commitment.bytes)],
proofs: @[pooled_txs.KzgProof(proof.bytes)]))
Expand Down Expand Up @@ -221,6 +222,9 @@ proc setupEnv(envFork: HardFork = MergeFork): TestEnv =

if envFork >= Prague:
conf.networkParams.config.pragueTime = Opt.some(0.EthTime)
conf.networkParams.config.osakaTime = Opt.some(3805601325.EthTime)
conf.networkParams.config.bpo1Time = Opt.some(3805701325.EthTime)
conf.networkParams.config.bpo2Time = Opt.some(3805801325.EthTime)

let
com = setupCom(conf)
Expand Down Expand Up @@ -313,7 +317,7 @@ createRpcSigsFromNim(RpcClient):

proc rpcMain*() =
suite "Remote Procedure Calls":
var env = setupEnv()
var env = setupEnv(Prague)
env.generateBlock()
let
client = env.client
Expand Down Expand Up @@ -372,6 +376,19 @@ proc rpcMain*() =
let res = await client.eth_chainId()
check res == com.chainId

test "eth_config":
let res = await client.eth_config()
check res.current.chainId == com.chainId
check res.current.activationTime.uint64 == 0'u64

check res.next.isSome() and res.last.isSome()

check res.next.get().chainId == com.chainId
check res.next.get().activationTime.uint64 == 3805601325'u64

check res.last.get().chainId == com.chainId
check res.last.get().activationTime.uint64 == 3805801325'u64

test "eth_syncing":
let res = await client.eth_syncing()
if res.syncing == false:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_txpool.nim
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ suite "TxPool test suite":
gasLimit: 75000
)

const MAX_TXS_GENERATED = 100
const MAX_TXS_GENERATED = 500
for i in 0..MAX_TXS_GENERATED-2:
let ptx = mx.makeTx(tc, acc, i.AccountNonce)
xp.checkAddTx(ptx)
Expand Down
Loading