diff --git a/execution_chain/common/common.nim b/execution_chain/common/common.nim index 933cc4803f..65504685f0 100644 --- a/execution_chain/common/common.nim +++ b/execution_chain/common/common.nim @@ -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 @@ -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)) @@ -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) diff --git a/execution_chain/core/tx_pool/tx_desc.nim b/execution_chain/core/tx_pool/tx_desc.nim index cb2d48c74a..c6b3a51fe7 100644 --- a/execution_chain/core/tx_pool/tx_desc.nim +++ b/execution_chain/core/tx_pool/tx_desc.nim @@ -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 diff --git a/execution_chain/evm/precompiles.nim b/execution_chain/evm/precompiles.nim index 7bbd7feed5..98ef8e6678 100644 --- a/execution_chain/evm/precompiles.nim +++ b/execution_chain/evm/precompiles.nim @@ -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 @@ -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: diff --git a/execution_chain/rpc/rpc_utils.nim b/execution_chain/rpc/rpc_utils.nim index 8b79b0b32e..935bf82050 100644 --- a/execution_chain/rpc/rpc_utils.nim +++ b/execution_chain/rpc/rpc_utils.nim @@ -10,6 +10,7 @@ {.push raises: [].} import + stew/endians2, std/[sequtils, algorithm], ./rpc_types, ./params, @@ -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 + diff --git a/execution_chain/rpc/server_api.nim b/execution_chain/rpc/server_api.nim index 5258e69470..82b07c1e0f 100644 --- a/execution_chain/rpc/server_api.nim +++ b/execution_chain/rpc/server_api.nim @@ -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) \ No newline at end of file diff --git a/execution_chain/sync/beacon/worker_const.nim b/execution_chain/sync/beacon/worker_const.nim index 63bf86f22a..1f3fcb0735 100644 --- a/execution_chain/sync/beacon/worker_const.nim +++ b/execution_chain/sync/beacon/worker_const.nim @@ -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 diff --git a/tests/customgenesis/cancun123.json b/tests/customgenesis/cancun123.json index 4eec9f6cae..f87e7ea37b 100644 --- a/tests/customgenesis/cancun123.json +++ b/tests/customgenesis/cancun123.json @@ -27,6 +27,14 @@ "alloc": { "0x73cf19657412508833f618a15e8251306b3e6ee5": { "balance": "0x6d6172697573766477000000" + }, + "0x00000961Ef480Eb55e80D19ad83579A64c007002": { + "balance": "0", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd" + }, + "0x0000BBdDc7CE488642fb579F8B00f3a590007251": { + "balance": "0", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd" } }, "number": "0x0", diff --git a/tests/test_rpc.nim b/tests/test_rpc.nim index b7f7b4de95..cd5eb3285d 100644 --- a/tests/test_rpc.nim +++ b/tests/test_rpc.nim @@ -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)])) @@ -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) @@ -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 @@ -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: diff --git a/tests/test_txpool.nim b/tests/test_txpool.nim index b0ec0f2196..db9e0c5e2a 100644 --- a/tests/test_txpool.nim +++ b/tests/test_txpool.nim @@ -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) diff --git a/vendor/nim-web3 b/vendor/nim-web3 index 304afd1897..54ed9d56a6 160000 --- a/vendor/nim-web3 +++ b/vendor/nim-web3 @@ -1 +1 @@ -Subproject commit 304afd1897bc62f7078d10810683f1f7af5f24f1 +Subproject commit 54ed9d56a65589b399978ff3014302dce04cf2c3