Add pragueTime configuration (#6473)

Wire through configuration for the Prague fork, including speculative
PragueGasCalculator, precompiles, genesis options, and implied
forks in GenesisState.

Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
pull/6496/head
Danno Ferrin 10 months ago committed by GitHub
parent c913a69692
commit 098d9975ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 10
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/01_cancun_prepare_payload.json
  3. 8
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/02_cancun_getPayloadV3.json
  4. 6
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/03_cancun_newPayloadV3.json
  5. 8
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/04_cancun_forkchoiceUpdatedV3.json
  6. 8
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/05_eip6110_forkchoiceUpdatedV3.json
  7. 10
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/06_eip6110_getPayloadV6110.json
  8. 6
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/09_eip6110_newPayloadV6110.json
  9. 8
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/10_eip6110_forkchoiceUpdatedV3.json
  10. 6
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/eip6110/test-cases/11_eip6110_getPayloadV6110.json
  11. 4
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  12. 7
      config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java
  13. 22
      config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java
  14. 18
      config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java
  15. 88
      config/src/test/java/org/hyperledger/besu/config/GenesisConfigFileTest.java
  16. 83
      config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java
  17. 1
      config/src/test/resources/all_forks.json
  18. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java
  19. 8
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetPrecompiledContractRegistries.java
  20. 10
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java
  21. 44
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
  22. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java
  23. 79
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java
  24. 27
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java
  25. 4077
      ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague.json
  26. 3
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java
  27. 4
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java
  28. 3
      ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java
  29. 7
      ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java
  30. 1
      ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/methods/TestSetChainParams.java
  31. 2
      evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java
  32. 11
      evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java
  33. 6
      evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java
  34. 2
      evm/src/main/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculator.java
  35. 44
      evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java
  36. 25
      evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java
  37. 4
      evm/src/test/java/org/hyperledger/besu/evm/fluent/EVMExecutorTest.java

@ -19,6 +19,7 @@
- Log blob count when importing a block via Engine API [#6466](https://github.com/hyperledger/besu/pull/6466) - Log blob count when importing a block via Engine API [#6466](https://github.com/hyperledger/besu/pull/6466)
- Introduce `--Xbonsai-limit-trie-logs-enabled` experimental feature which by default will only retain the latest 512 trie logs, saving about 3GB per week in database growth [#5390](https://github.com/hyperledger/besu/issues/5390) - Introduce `--Xbonsai-limit-trie-logs-enabled` experimental feature which by default will only retain the latest 512 trie logs, saving about 3GB per week in database growth [#5390](https://github.com/hyperledger/besu/issues/5390)
- Introduce `besu storage x-trie-log prune` experimental offline subcommand which will prune all redundant trie logs except the latest 512 [#6303](https://github.com/hyperledger/besu/pull/6303) - Introduce `besu storage x-trie-log prune` experimental offline subcommand which will prune all redundant trie logs except the latest 512 [#6303](https://github.com/hyperledger/besu/pull/6303)
- Added configuration options for `pragueTime` to genesis file for Prague fork development [#6473](https://github.com/hyperledger/besu/pull/6473)
### Bug fixes ### Bug fixes
- Fix the way an advertised host configured with `--p2p-host` is treated when communicating with the originator of a PING packet [#6225](https://github.com/hyperledger/besu/pull/6225) - Fix the way an advertised host configured with `--p2p-host` is treated when communicating with the originator of a PING packet [#6225](https://github.com/hyperledger/besu/pull/6225)

@ -4,8 +4,8 @@
"method": "engine_forkchoiceUpdatedV3", "method": "engine_forkchoiceUpdatedV3",
"params": [ "params": [
{ {
"headBlockHash": "0x26118cf71453320edcebbc4ebb34af5b578087a32385b80108bf691fa23efc42", "headBlockHash": "0x78a301e0d846bd169889c9755c9aa4ce2972dfc4bd63de61f3303887d3e81f98",
"safeBlockHash": "0x26118cf71453320edcebbc4ebb34af5b578087a32385b80108bf691fa23efc42", "safeBlockHash": "0x78a301e0d846bd169889c9755c9aa4ce2972dfc4bd63de61f3303887d3e81f98",
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" "finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}, },
{ {
@ -24,11 +24,11 @@
"result": { "result": {
"payloadStatus": { "payloadStatus": {
"status": "VALID", "status": "VALID",
"latestValidHash": "0x26118cf71453320edcebbc4ebb34af5b578087a32385b80108bf691fa23efc42", "latestValidHash": "0x78a301e0d846bd169889c9755c9aa4ce2972dfc4bd63de61f3303887d3e81f98",
"validationError": null "validationError": null
}, },
"payloadId": "0x282643c14de2dfef" "payloadId": "0x282643d459a6f711"
} }
}, },
"statusCode" : 200 "statusCode": 200
} }

@ -3,7 +3,7 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "engine_getPayloadV3", "method": "engine_getPayloadV3",
"params": [ "params": [
"0x282643c14de2dfef" "0x282643d459a6f711"
], ],
"id": 67 "id": 67
}, },
@ -12,7 +12,7 @@
"id": 67, "id": 67,
"result": { "result": {
"executionPayload": { "executionPayload": {
"parentHash": "0x26118cf71453320edcebbc4ebb34af5b578087a32385b80108bf691fa23efc42", "parentHash": "0x78a301e0d846bd169889c9755c9aa4ce2972dfc4bd63de61f3303887d3e81f98",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x9b8c4a9a86cb49252075c0db2f0e72fb1e49350a0f70ea36f26f700201961e62", "stateRoot": "0x9b8c4a9a86cb49252075c0db2f0e72fb1e49350a0f70ea36f26f700201961e62",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
@ -28,8 +28,8 @@
"withdrawals": [], "withdrawals": [],
"blockNumber": "0x1", "blockNumber": "0x1",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"blockHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "blobGasUsed": "0x0",
"blobGasUsed": "0x0" "blockHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315"
}, },
"blockValue": "0x0", "blockValue": "0x0",
"blobsBundle": { "blobsBundle": {

@ -4,7 +4,7 @@
"method": "engine_newPayloadV3", "method": "engine_newPayloadV3",
"params": [ "params": [
{ {
"parentHash": "0x26118cf71453320edcebbc4ebb34af5b578087a32385b80108bf691fa23efc42", "parentHash": "0x78a301e0d846bd169889c9755c9aa4ce2972dfc4bd63de61f3303887d3e81f98",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x9b8c4a9a86cb49252075c0db2f0e72fb1e49350a0f70ea36f26f700201961e62", "stateRoot": "0x9b8c4a9a86cb49252075c0db2f0e72fb1e49350a0f70ea36f26f700201961e62",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
@ -17,7 +17,7 @@
"transactions": [], "transactions": [],
"withdrawals": [], "withdrawals": [],
"blockNumber": "0x1", "blockNumber": "0x1",
"blockHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "blockHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"excessBlobGas": "0x0", "excessBlobGas": "0x0",
"blobGasUsed": "0x0" "blobGasUsed": "0x0"
@ -32,7 +32,7 @@
"id": 67, "id": 67,
"result": { "result": {
"status": "VALID", "status": "VALID",
"latestValidHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "latestValidHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315",
"validationError": null "validationError": null
} }
}, },

@ -4,9 +4,9 @@
"method": "engine_forkchoiceUpdatedV3", "method": "engine_forkchoiceUpdatedV3",
"params": [ "params": [
{ {
"headBlockHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "headBlockHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315",
"safeBlockHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "safeBlockHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315",
"finalizedBlockHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356" "finalizedBlockHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315"
}, },
null null
], ],
@ -18,7 +18,7 @@
"result": { "result": {
"payloadStatus": { "payloadStatus": {
"status": "VALID", "status": "VALID",
"latestValidHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "latestValidHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315",
"validationError": null "validationError": null
}, },
"payloadId": null "payloadId": null

@ -4,8 +4,8 @@
"method": "engine_forkchoiceUpdatedV3", "method": "engine_forkchoiceUpdatedV3",
"params": [ "params": [
{ {
"headBlockHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "headBlockHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315",
"safeBlockHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "safeBlockHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315",
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" "finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}, },
{ {
@ -24,10 +24,10 @@
"result": { "result": {
"payloadStatus": { "payloadStatus": {
"status": "VALID", "status": "VALID",
"latestValidHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "latestValidHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315",
"validationError": null "validationError": null
}, },
"payloadId": "0x282643b9c2d2a4df" "payloadId": "0x282643b909febddf"
} }
}, },
"statusCode": 200 "statusCode": 200

@ -3,7 +3,7 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "engine_getPayloadV6110", "method": "engine_getPayloadV6110",
"params": [ "params": [
"0x282643b9c2d2a4df" "0x282643b909febddf"
], ],
"id": 67 "id": 67
}, },
@ -12,7 +12,7 @@
"id": 67, "id": 67,
"result": { "result": {
"executionPayload": { "executionPayload": {
"parentHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "parentHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x9b8c4a9a86cb49252075c0db2f0e72fb1e49350a0f70ea36f26f700201961e62", "stateRoot": "0x9b8c4a9a86cb49252075c0db2f0e72fb1e49350a0f70ea36f26f700201961e62",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
@ -28,9 +28,9 @@
"withdrawals": [], "withdrawals": [],
"depositReceipts": [], "depositReceipts": [],
"blockNumber": "0x2", "blockNumber": "0x2",
"blockHash": "0xf6c3f1180ba58d6ea4c69c9328c7afb1fda41df06c368741c1f8310567879de7", "blockHash": "0xc8255831601171a628ef17f6601d3d1d30ff9b382e77592ed1af32354f6dafbb",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "blobGasUsed": "0x0",
"blobGasUsed": "0x0" "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
}, },
"blockValue": "0x0", "blockValue": "0x0",
"blobsBundle": { "blobsBundle": {

@ -4,7 +4,7 @@
"method": "engine_newPayloadV6110", "method": "engine_newPayloadV6110",
"params": [ "params": [
{ {
"parentHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "parentHash": "0x1dd4f141551d53ce393845e2873754e43396101a8ebc0fd0eeb2e6798a591315",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x14208ac0e218167936e220b72d5d5887a963cb858ea2f2d268518f014a3da3fa", "stateRoot": "0x14208ac0e218167936e220b72d5d5887a963cb858ea2f2d268518f014a3da3fa",
"logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000", "logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000",
@ -23,7 +23,7 @@
{"amount":"0x773594000","index":"0x0","pubkey":"0x96a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9","signature":"0xb1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9","withdrawalCredentials":"0x003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef2"} {"amount":"0x773594000","index":"0x0","pubkey":"0x96a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9","signature":"0xb1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9","withdrawalCredentials":"0x003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef2"}
], ],
"blockNumber": "0x2", "blockNumber": "0x2",
"blockHash": "0xb3b483867217b83b1e4a2f95c84d2da30cbff12eb8636f2becbcc05f4507fa7a", "blockHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9", "receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9",
"blobGasUsed": "0x0" "blobGasUsed": "0x0"
}, },
@ -37,7 +37,7 @@
"id": 67, "id": 67,
"result": { "result": {
"status": "VALID", "status": "VALID",
"latestValidHash": "0xb3b483867217b83b1e4a2f95c84d2da30cbff12eb8636f2becbcc05f4507fa7a", "latestValidHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"validationError": null "validationError": null
} }
}, },

@ -4,8 +4,8 @@
"method": "engine_forkchoiceUpdatedV3", "method": "engine_forkchoiceUpdatedV3",
"params": [ "params": [
{ {
"headBlockHash": "0xb3b483867217b83b1e4a2f95c84d2da30cbff12eb8636f2becbcc05f4507fa7a", "headBlockHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"safeBlockHash": "0xb3b483867217b83b1e4a2f95c84d2da30cbff12eb8636f2becbcc05f4507fa7a", "safeBlockHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" "finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}, },
{ {
@ -24,10 +24,10 @@
"result": { "result": {
"payloadStatus": { "payloadStatus": {
"status": "VALID", "status": "VALID",
"latestValidHash": "0xb3b483867217b83b1e4a2f95c84d2da30cbff12eb8636f2becbcc05f4507fa7a", "latestValidHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"validationError": null "validationError": null
}, },
"payloadId": "0x282643daa04b7631" "payloadId": "0x282643db882670cf"
} }
}, },
"statusCode" : 200 "statusCode" : 200

@ -3,7 +3,7 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "engine_getPayloadV6110", "method": "engine_getPayloadV6110",
"params": [ "params": [
"0x282643daa04b7631" "0x282643db882670cf"
], ],
"id": 67 "id": 67
}, },
@ -12,7 +12,7 @@
"id": 67, "id": 67,
"result": { "result": {
"executionPayload": { "executionPayload": {
"parentHash": "0xb3b483867217b83b1e4a2f95c84d2da30cbff12eb8636f2becbcc05f4507fa7a", "parentHash": "0xddb65a684b9b8980b6231ee0e388566c10a9c4583bbddf16f8d68bbc0b8ed965",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x14208ac0e218167936e220b72d5d5887a963cb858ea2f2d268518f014a3da3fa", "stateRoot": "0x14208ac0e218167936e220b72d5d5887a963cb858ea2f2d268518f014a3da3fa",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
@ -28,7 +28,7 @@
"withdrawals": [], "withdrawals": [],
"depositReceipts": [], "depositReceipts": [],
"blockNumber": "0x3", "blockNumber": "0x3",
"blockHash": "0xa28bf4db3363ce5b67848eb2ad52dbfead62ddb2287ae7eed36daa002528d1af", "blockHash": "0xf1e7093b5d229885caab11a3acb95412af80f9077b742020a8014cf81c8c75f2",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"blobGasUsed": "0x0" "blobGasUsed": "0x0"
}, },

@ -359,6 +359,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
description = "Identification for this node in the Client ID", description = "Identification for this node in the Client ID",
arity = "1") arity = "1")
private final Optional<String> identityString = Optional.empty(); private final Optional<String> identityString = Optional.empty();
// P2P Discovery Option Group // P2P Discovery Option Group
@CommandLine.ArgGroup(validate = false, heading = "@|bold P2P Discovery Options|@%n") @CommandLine.ArgGroup(validate = false, heading = "@|bold P2P Discovery Options|@%n")
P2PDiscoveryOptionGroup p2PDiscoveryOptionGroup = new P2PDiscoveryOptionGroup(); P2PDiscoveryOptionGroup p2PDiscoveryOptionGroup = new P2PDiscoveryOptionGroup();
@ -1481,7 +1482,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
logger.info("Using the Java implementation of the blake2bf algorithm"); logger.info("Using the Java implementation of the blake2bf algorithm");
} }
if (getActualGenesisConfigOptions().getCancunTime().isPresent()) { if (getActualGenesisConfigOptions().getCancunTime().isPresent()
|| getActualGenesisConfigOptions().getPragueTime().isPresent()) {
if (kzgTrustedSetupFile != null) { if (kzgTrustedSetupFile != null) {
KZGPointEvalPrecompiledContract.init(kzgTrustedSetupFile); KZGPointEvalPrecompiledContract.init(kzgTrustedSetupFile);
} else { } else {

@ -242,6 +242,13 @@ public interface GenesisConfigOptions {
*/ */
OptionalLong getCancunTime(); OptionalLong getCancunTime();
/**
* Gets prague time.
*
* @return the prague time
*/
OptionalLong getPragueTime();
/** /**
* Gets future eips time. * Gets future eips time.
* *

@ -28,7 +28,6 @@ import java.util.Optional;
import java.util.OptionalInt; import java.util.OptionalInt;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
@ -292,6 +291,11 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
return getOptionalLong("cancuntime"); return getOptionalLong("cancuntime");
} }
@Override
public OptionalLong getPragueTime() {
return getOptionalLong("praguetime");
}
@Override @Override
public OptionalLong getFutureEipsTime() { public OptionalLong getFutureEipsTime() {
return getOptionalLong("futureeipstime"); return getOptionalLong("futureeipstime");
@ -304,10 +308,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
@Override @Override
public Optional<Wei> getBaseFeePerGas() { public Optional<Wei> getBaseFeePerGas() {
return Optional.ofNullable(configOverrides.get("baseFeePerGas")) return Optional.ofNullable(configOverrides.get("baseFeePerGas")).map(Wei::fromHexString);
.map(Wei::fromHexString)
.map(Optional::of)
.orElse(Optional.empty());
} }
@Override @Override
@ -448,6 +449,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
getMergeNetSplitBlockNumber().ifPresent(l -> builder.put("mergeNetSplitBlock", l)); getMergeNetSplitBlockNumber().ifPresent(l -> builder.put("mergeNetSplitBlock", l));
getShanghaiTime().ifPresent(l -> builder.put("shanghaiTime", l)); getShanghaiTime().ifPresent(l -> builder.put("shanghaiTime", l));
getCancunTime().ifPresent(l -> builder.put("cancunTime", l)); getCancunTime().ifPresent(l -> builder.put("cancunTime", l));
getPragueTime().ifPresent(l -> builder.put("pragueTime", l));
getTerminalBlockNumber().ifPresent(l -> builder.put("terminalBlockNumber", l)); getTerminalBlockNumber().ifPresent(l -> builder.put("terminalBlockNumber", l));
getTerminalBlockHash().ifPresent(h -> builder.put("terminalBlockHash", h.toHexString())); getTerminalBlockHash().ifPresent(h -> builder.put("terminalBlockHash", h.toHexString()));
getFutureEipsTime().ifPresent(l -> builder.put("futureEipsTime", l)); getFutureEipsTime().ifPresent(l -> builder.put("futureEipsTime", l));
@ -582,14 +584,18 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
.map(OptionalLong::getAsLong) .map(OptionalLong::getAsLong)
.distinct() .distinct()
.sorted() .sorted()
.collect(Collectors.toList()); .toList();
} }
@Override @Override
public List<Long> getForkBlockTimestamps() { public List<Long> getForkBlockTimestamps() {
Stream<OptionalLong> forkBlockTimestamps = Stream<OptionalLong> forkBlockTimestamps =
Stream.of( Stream.of(
getShanghaiTime(), getCancunTime(), getFutureEipsTime(), getExperimentalEipsTime()); getShanghaiTime(),
getCancunTime(),
getPragueTime(),
getFutureEipsTime(),
getExperimentalEipsTime());
// when adding forks add an entry to ${REPO_ROOT}/config/src/test/resources/all_forks.json // when adding forks add an entry to ${REPO_ROOT}/config/src/test/resources/all_forks.json
return forkBlockTimestamps return forkBlockTimestamps
@ -597,6 +603,6 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
.map(OptionalLong::getAsLong) .map(OptionalLong::getAsLong)
.distinct() .distinct()
.sorted() .sorted()
.collect(Collectors.toList()); .toList();
} }
} }

@ -48,6 +48,7 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
private OptionalLong mergeNetSplitBlockNumber = OptionalLong.empty(); private OptionalLong mergeNetSplitBlockNumber = OptionalLong.empty();
private OptionalLong shanghaiTime = OptionalLong.empty(); private OptionalLong shanghaiTime = OptionalLong.empty();
private OptionalLong cancunTime = OptionalLong.empty(); private OptionalLong cancunTime = OptionalLong.empty();
private OptionalLong pragueTime = OptionalLong.empty();
private OptionalLong futureEipsTime = OptionalLong.empty(); private OptionalLong futureEipsTime = OptionalLong.empty();
private OptionalLong experimentalEipsTime = OptionalLong.empty(); private OptionalLong experimentalEipsTime = OptionalLong.empty();
private OptionalLong terminalBlockNumber = OptionalLong.empty(); private OptionalLong terminalBlockNumber = OptionalLong.empty();
@ -232,6 +233,11 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
return cancunTime; return cancunTime;
} }
@Override
public OptionalLong getPragueTime() {
return pragueTime;
}
@Override @Override
public OptionalLong getFutureEipsTime() { public OptionalLong getFutureEipsTime() {
return futureEipsTime; return futureEipsTime;
@ -364,6 +370,7 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
getMergeNetSplitBlockNumber().ifPresent(l -> builder.put("mergeNetSplitBlock", l)); getMergeNetSplitBlockNumber().ifPresent(l -> builder.put("mergeNetSplitBlock", l));
getShanghaiTime().ifPresent(l -> builder.put("shanghaiTime", l)); getShanghaiTime().ifPresent(l -> builder.put("shanghaiTime", l));
getCancunTime().ifPresent(l -> builder.put("cancunTime", l)); getCancunTime().ifPresent(l -> builder.put("cancunTime", l));
getPragueTime().ifPresent(l -> builder.put("pragueTime", l));
getFutureEipsTime().ifPresent(l -> builder.put("futureEipsTime", l)); getFutureEipsTime().ifPresent(l -> builder.put("futureEipsTime", l));
getExperimentalEipsTime().ifPresent(l -> builder.put("experimentalEipsTime", l)); getExperimentalEipsTime().ifPresent(l -> builder.put("experimentalEipsTime", l));
getTerminalBlockNumber().ifPresent(l -> builder.put("terminalBlockNumber", l)); getTerminalBlockNumber().ifPresent(l -> builder.put("terminalBlockNumber", l));
@ -608,6 +615,17 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
return this; return this;
} }
/**
* Prague time.
*
* @param timestamp the timestamp
* @return the stub genesis config options
*/
public StubGenesisConfigOptions pragueTime(final long timestamp) {
pragueTime = OptionalLong.of(timestamp);
return this;
}
/** /**
* Future EIPs Time block. * Future EIPs Time block.
* *

@ -38,14 +38,14 @@ import org.apache.tuweni.units.bigints.UInt256;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class GenesisConfigFileTest { class GenesisConfigFileTest {
private static final BigInteger MAINNET_CHAIN_ID = BigInteger.ONE; private static final BigInteger MAINNET_CHAIN_ID = BigInteger.ONE;
private static final BigInteger DEVELOPMENT_CHAIN_ID = BigInteger.valueOf(1337); private static final BigInteger DEVELOPMENT_CHAIN_ID = BigInteger.valueOf(1337);
private static final GenesisConfigFile EMPTY_CONFIG = fromConfig("{}"); private static final GenesisConfigFile EMPTY_CONFIG = fromConfig("{}");
@Test @Test
public void shouldLoadMainnetConfigFile() { void shouldLoadMainnetConfigFile() {
final GenesisConfigFile config = GenesisConfigFile.mainnet(); final GenesisConfigFile config = GenesisConfigFile.mainnet();
// Sanity check some basic properties to confirm this is the mainnet file. // Sanity check some basic properties to confirm this is the mainnet file.
assertThat(config.getConfigOptions().isEthHash()).isTrue(); assertThat(config.getConfigOptions().isEthHash()).isTrue();
@ -58,7 +58,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldLoadDevelopmentConfigFile() { void shouldLoadDevelopmentConfigFile() {
final GenesisConfigFile config = GenesisConfigFile.development(); final GenesisConfigFile config = GenesisConfigFile.development();
// Sanity check some basic properties to confirm this is the dev file. // Sanity check some basic properties to confirm this is the dev file.
assertThat(config.getConfigOptions().isEthHash()).isTrue(); assertThat(config.getConfigOptions().isEthHash()).isTrue();
@ -71,82 +71,82 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldGetParentHash() { void shouldGetParentHash() {
assertThat(configWithProperty("parentHash", "844633").getParentHash()).isEqualTo("844633"); assertThat(configWithProperty("parentHash", "844633").getParentHash()).isEqualTo("844633");
} }
@Test @Test
public void shouldDefaultParentHashToEmptyString() { void shouldDefaultParentHashToEmptyString() {
assertThat(EMPTY_CONFIG.getParentHash()).isEmpty(); assertThat(EMPTY_CONFIG.getParentHash()).isEmpty();
} }
@Test @Test
public void shouldGetDifficulty() { void shouldGetDifficulty() {
assertThat(configWithProperty("difficulty", "1234").getDifficulty()).isEqualTo("1234"); assertThat(configWithProperty("difficulty", "1234").getDifficulty()).isEqualTo("1234");
} }
@Test @Test
public void shouldRequireDifficulty() { void shouldRequireDifficulty() {
assertInvalidConfiguration(EMPTY_CONFIG::getDifficulty); assertInvalidConfiguration(EMPTY_CONFIG::getDifficulty);
} }
@Test @Test
public void shouldGetExtraData() { void shouldGetExtraData() {
assertThat(configWithProperty("extraData", "yay").getExtraData()).isEqualTo("yay"); assertThat(configWithProperty("extraData", "yay").getExtraData()).isEqualTo("yay");
} }
@Test @Test
public void shouldDefaultExtraDataToEmptyString() { void shouldDefaultExtraDataToEmptyString() {
assertThat(EMPTY_CONFIG.getExtraData()).isEmpty(); assertThat(EMPTY_CONFIG.getExtraData()).isEmpty();
} }
@Test @Test
public void shouldGetGasLimit() { void shouldGetGasLimit() {
assertThat(configWithProperty("gasLimit", "1000").getGasLimit()).isEqualTo(1000); assertThat(configWithProperty("gasLimit", "1000").getGasLimit()).isEqualTo(1000);
} }
@Test @Test
public void shouldRequireGasLimit() { void shouldRequireGasLimit() {
assertInvalidConfiguration(EMPTY_CONFIG::getGasLimit); assertInvalidConfiguration(EMPTY_CONFIG::getGasLimit);
} }
@Test @Test
public void shouldGetMixHash() { void shouldGetMixHash() {
assertThat(configWithProperty("mixHash", "asdf").getMixHash()).isEqualTo("asdf"); assertThat(configWithProperty("mixHash", "asdf").getMixHash()).isEqualTo("asdf");
} }
@Test @Test
public void shouldDefaultMixHashToEmptyString() { void shouldDefaultMixHashToEmptyString() {
assertThat(EMPTY_CONFIG.getMixHash()).isEmpty(); assertThat(EMPTY_CONFIG.getMixHash()).isEmpty();
} }
@Test @Test
public void shouldGetNonce() { void shouldGetNonce() {
assertThat(configWithProperty("nonce", "0x10").getNonce()).isEqualTo("0x10"); assertThat(configWithProperty("nonce", "0x10").getNonce()).isEqualTo("0x10");
} }
@Test @Test
public void shouldDefaultNonceToZero() { void shouldDefaultNonceToZero() {
assertThat(EMPTY_CONFIG.getNonce()).isEqualTo("0x0"); assertThat(EMPTY_CONFIG.getNonce()).isEqualTo("0x0");
} }
@Test @Test
public void shouldGetCoinbase() { void shouldGetCoinbase() {
assertThat(configWithProperty("coinbase", "abcd").getCoinbase()).contains("abcd"); assertThat(configWithProperty("coinbase", "abcd").getCoinbase()).contains("abcd");
} }
@Test @Test
public void shouldReturnEmptyWhenCoinbaseNotSpecified() { void shouldReturnEmptyWhenCoinbaseNotSpecified() {
assertThat(EMPTY_CONFIG.getCoinbase()).isEmpty(); assertThat(EMPTY_CONFIG.getCoinbase()).isEmpty();
} }
@Test @Test
public void shouldGetTimestamp() { void shouldGetTimestamp() {
assertThat(configWithProperty("timestamp", "0x10").getTimestamp()).isEqualTo(16L); assertThat(configWithProperty("timestamp", "0x10").getTimestamp()).isEqualTo(16L);
} }
@Test @Test
public void shouldGetBaseFeeAtGenesis() { void shouldGetBaseFeeAtGenesis() {
GenesisConfigFile withBaseFeeAtGenesis = GenesisConfigFile withBaseFeeAtGenesis =
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":0},\"baseFeePerGas\":\"0xa\"}"); GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":0},\"baseFeePerGas\":\"0xa\"}");
assertThat(withBaseFeeAtGenesis.getBaseFeePerGas()).isPresent(); assertThat(withBaseFeeAtGenesis.getBaseFeePerGas()).isPresent();
@ -154,7 +154,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldGetDefaultBaseFeeAtGenesis() { void shouldGetDefaultBaseFeeAtGenesis() {
GenesisConfigFile withBaseFeeAtGenesis = GenesisConfigFile withBaseFeeAtGenesis =
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":0}}"); GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":0}}");
// no specified baseFeePerGas: // no specified baseFeePerGas:
@ -165,7 +165,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldGetBaseFeeExplicitlyAtGenesis() { void shouldGetBaseFeeExplicitlyAtGenesis() {
GenesisConfigFile withBaseFeeNotAtGenesis = GenesisConfigFile withBaseFeeNotAtGenesis =
GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":10},\"baseFeePerGas\":\"0xa\"}"); GenesisConfigFile.fromConfig("{\"config\":{\"londonBlock\":10},\"baseFeePerGas\":\"0xa\"}");
// specified baseFeePerGas: // specified baseFeePerGas:
@ -176,14 +176,14 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldOverrideConfigOptionsBaseFeeWhenSpecified() { void shouldOverrideConfigOptionsBaseFeeWhenSpecified() {
GenesisConfigOptions withOverrides = GenesisConfigOptions withOverrides =
EMPTY_CONFIG.getConfigOptions(Map.of("baseFeePerGas", Wei.of(8).toString())); EMPTY_CONFIG.getConfigOptions(Map.of("baseFeePerGas", Wei.of(8).toString()));
assertThat(withOverrides.getBaseFeePerGas()).contains(Wei.of(8L)); assertThat(withOverrides.getBaseFeePerGas()).contains(Wei.of(8L));
} }
@Test @Test
public void shouldGetTerminalTotalDifficultyAtGenesis() { void shouldGetTerminalTotalDifficultyAtGenesis() {
GenesisConfigFile withTerminalTotalDifficultyAtGenesis = GenesisConfigFile withTerminalTotalDifficultyAtGenesis =
fromConfig("{\"config\":{\"terminalTotalDifficulty\":1000}}"); fromConfig("{\"config\":{\"terminalTotalDifficulty\":1000}}");
assertThat(withTerminalTotalDifficultyAtGenesis.getConfigOptions().getTerminalTotalDifficulty()) assertThat(withTerminalTotalDifficultyAtGenesis.getConfigOptions().getTerminalTotalDifficulty())
@ -191,12 +191,12 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldGetEmptyTerminalTotalDifficultyAtGenesis() { void shouldGetEmptyTerminalTotalDifficultyAtGenesis() {
assertThat(EMPTY_CONFIG.getConfigOptions().getTerminalTotalDifficulty()).isNotPresent(); assertThat(EMPTY_CONFIG.getConfigOptions().getTerminalTotalDifficulty()).isNotPresent();
} }
@Test @Test
public void assertSepoliaTerminalTotalDifficulty() { void assertSepoliaTerminalTotalDifficulty() {
GenesisConfigOptions sepoliaOptions = GenesisConfigOptions sepoliaOptions =
GenesisConfigFile.genesisFileFromResources("/sepolia.json").getConfigOptions(); GenesisConfigFile.genesisFileFromResources("/sepolia.json").getConfigOptions();
@ -206,7 +206,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void assertGoerliTerminalTotalDifficulty() { void assertGoerliTerminalTotalDifficulty() {
GenesisConfigOptions goerliOptions = GenesisConfigOptions goerliOptions =
GenesisConfigFile.genesisFileFromResources("/goerli.json").getConfigOptions(); GenesisConfigFile.genesisFileFromResources("/goerli.json").getConfigOptions();
@ -216,7 +216,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void assertMainnetTerminalTotalDifficulty() { void assertMainnetTerminalTotalDifficulty() {
GenesisConfigOptions mainnetOptions = GenesisConfigOptions mainnetOptions =
GenesisConfigFile.genesisFileFromResources("/mainnet.json").getConfigOptions(); GenesisConfigFile.genesisFileFromResources("/mainnet.json").getConfigOptions();
@ -227,7 +227,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void assertTerminalTotalDifficultyOverride() { void assertTerminalTotalDifficultyOverride() {
GenesisConfigOptions sepoliaOverrideOptions = GenesisConfigOptions sepoliaOverrideOptions =
GenesisConfigFile.genesisFileFromResources("/sepolia.json") GenesisConfigFile.genesisFileFromResources("/sepolia.json")
.getConfigOptions(Map.of("terminalTotalDifficulty", String.valueOf(Long.MAX_VALUE))); .getConfigOptions(Map.of("terminalTotalDifficulty", String.valueOf(Long.MAX_VALUE)));
@ -238,7 +238,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldFindMergeNetSplitForkAndAlias() { void shouldFindMergeNetSplitForkAndAlias() {
GenesisConfigFile mergeNetSplitGenesis = GenesisConfigFile mergeNetSplitGenesis =
GenesisConfigFile.fromConfig( GenesisConfigFile.fromConfig(
"{\"config\":{\"mergeNetsplitBlock\":11},\"baseFeePerGas\":\"0xa\"}"); "{\"config\":{\"mergeNetsplitBlock\":11},\"baseFeePerGas\":\"0xa\"}");
@ -255,12 +255,12 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldDefaultTimestampToZero() { void shouldDefaultTimestampToZero() {
assertThat(EMPTY_CONFIG.getTimestamp()).isZero(); assertThat(EMPTY_CONFIG.getTimestamp()).isZero();
} }
@Test @Test
public void shouldGetAllocations() { void shouldGetAllocations() {
final GenesisConfigFile config = final GenesisConfigFile config =
fromConfig( fromConfig(
"{" "{"
@ -309,13 +309,13 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldGetEmptyAllocationsWhenAllocNotPresent() { void shouldGetEmptyAllocationsWhenAllocNotPresent() {
final GenesisConfigFile config = fromConfig("{}"); final GenesisConfigFile config = fromConfig("{}");
assertThat(config.streamAllocations()).isEmpty(); assertThat(config.streamAllocations()).isEmpty();
} }
@Test @Test
public void shouldGetLargeChainId() { void shouldGetLargeChainId() {
final GenesisConfigFile config = final GenesisConfigFile config =
fromConfig( fromConfig(
"{\"config\": { \"chainId\": 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095 }}"); "{\"config\": { \"chainId\": 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095 }}");
@ -326,7 +326,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void mustNotAcceptComments() { void mustNotAcceptComments() {
assertThatThrownBy( assertThatThrownBy(
() -> () ->
fromConfig( fromConfig(
@ -336,7 +336,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void testOverridePresent() { void testOverridePresent() {
final GenesisConfigFile config = GenesisConfigFile.development(); final GenesisConfigFile config = GenesisConfigFile.development();
final int bigBlock = 999_999_999; final int bigBlock = 999_999_999;
final String bigBlockString = Integer.toString(bigBlock); final String bigBlockString = Integer.toString(bigBlock);
@ -353,7 +353,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void testOverrideNull() { void testOverrideNull() {
final GenesisConfigFile config = GenesisConfigFile.development(); final GenesisConfigFile config = GenesisConfigFile.development();
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
override.put("istanbulBlock", null); override.put("istanbulBlock", null);
@ -367,7 +367,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void testOverrideCaseInsensitivity() { void testOverrideCaseInsensitivity() {
final GenesisConfigFile config = GenesisConfigFile.development(); final GenesisConfigFile config = GenesisConfigFile.development();
final int bigBlock = 999_999_999; final int bigBlock = 999_999_999;
final String bigBlockString = Integer.toString(bigBlock); final String bigBlockString = Integer.toString(bigBlock);
@ -386,7 +386,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void testOverrideEmptyString() { void testOverrideEmptyString() {
final GenesisConfigFile config = GenesisConfigFile.development(); final GenesisConfigFile config = GenesisConfigFile.development();
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
override.put("istanbulBlock", ""); override.put("istanbulBlock", "");
@ -399,7 +399,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void testNoOverride() { void testNoOverride() {
final GenesisConfigFile config = GenesisConfigFile.development(); final GenesisConfigFile config = GenesisConfigFile.development();
assertThat(config.getConfigOptions().getLondonBlockNumber()).hasValue(0); assertThat(config.getConfigOptions().getLondonBlockNumber()).hasValue(0);
@ -411,7 +411,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void testConstantinopleFixShouldNotBeSupportedAlongPetersburg() { void testConstantinopleFixShouldNotBeSupportedAlongPetersburg() {
// petersburg node // petersburg node
final GenesisConfigFile config = GenesisConfigFile.genesisFileFromResources("/all_forks.json"); final GenesisConfigFile config = GenesisConfigFile.genesisFileFromResources("/all_forks.json");
@ -428,7 +428,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldLoadForksInSortedOrder() throws IOException { void shouldLoadForksInSortedOrder() throws IOException {
final ObjectNode configNode = final ObjectNode configNode =
new ObjectMapper() new ObjectMapper()
.createObjectNode() .createObjectNode()
@ -449,7 +449,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldLoadForksIgnoreClassicForkBlock() throws IOException { void shouldLoadForksIgnoreClassicForkBlock() throws IOException {
final ObjectNode configNode = final ObjectNode configNode =
new ObjectMapper() new ObjectMapper()
.createObjectNode() .createObjectNode()
@ -469,7 +469,7 @@ public class GenesisConfigFileTest {
} }
@Test @Test
public void shouldLoadForksIgnoreUnexpectedValues() throws IOException { void shouldLoadForksIgnoreUnexpectedValues() throws IOException {
final ObjectNode configNoUnexpectedForks = final ObjectNode configNoUnexpectedForks =
new ObjectMapper() new ObjectMapper()
.createObjectNode() .createObjectNode()
@ -533,7 +533,7 @@ public class GenesisConfigFileTest {
* been case agnostic. * been case agnostic.
*/ */
@Test @Test
public void roundTripForkIdBlocks() throws IOException { void roundTripForkIdBlocks() throws IOException {
final String configText = final String configText =
Resources.toString(Resources.getResource("all_forks.json"), StandardCharsets.UTF_8); Resources.toString(Resources.getResource("all_forks.json"), StandardCharsets.UTF_8);
final ObjectNode genesisNode = JsonUtil.objectNodeFromString(configText); final ObjectNode genesisNode = JsonUtil.objectNodeFromString(configText);

@ -29,30 +29,30 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.tuweni.units.bigints.UInt256; import org.apache.tuweni.units.bigints.UInt256;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class GenesisConfigOptionsTest { class GenesisConfigOptionsTest {
@Test @Test
public void shouldUseEthHashWhenEthHashInConfig() { void shouldUseEthHashWhenEthHashInConfig() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("ethash", emptyMap())); final GenesisConfigOptions config = fromConfigOptions(singletonMap("ethash", emptyMap()));
assertThat(config.isEthHash()).isTrue(); assertThat(config.isEthHash()).isTrue();
assertThat(config.getConsensusEngine()).isEqualTo("ethash"); assertThat(config.getConsensusEngine()).isEqualTo("ethash");
} }
@Test @Test
public void shouldNotUseEthHashIfEthHashNotPresent() { void shouldNotUseEthHashIfEthHashNotPresent() {
final GenesisConfigOptions config = fromConfigOptions(emptyMap()); final GenesisConfigOptions config = fromConfigOptions(emptyMap());
assertThat(config.isEthHash()).isFalse(); assertThat(config.isEthHash()).isFalse();
} }
@Test @Test
public void shouldUseIbft2WhenIbft2InConfig() { void shouldUseIbft2WhenIbft2InConfig() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("ibft2", emptyMap())); final GenesisConfigOptions config = fromConfigOptions(singletonMap("ibft2", emptyMap()));
assertThat(config.isIbft2()).isTrue(); assertThat(config.isIbft2()).isTrue();
assertThat(config.isPoa()).isTrue(); assertThat(config.isPoa()).isTrue();
assertThat(config.getConsensusEngine()).isEqualTo("ibft2"); assertThat(config.getConsensusEngine()).isEqualTo("ibft2");
} }
public void shouldUseQbftWhenQbftInConfig() { void shouldUseQbftWhenQbftInConfig() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("qbft", emptyMap())); final GenesisConfigOptions config = fromConfigOptions(singletonMap("qbft", emptyMap()));
assertThat(config.isQbft()).isTrue(); assertThat(config.isQbft()).isTrue();
assertThat(config.isPoa()).isTrue(); assertThat(config.isPoa()).isTrue();
@ -60,7 +60,7 @@ public class GenesisConfigOptionsTest {
} }
@Test @Test
public void shouldUseCliqueWhenCliqueInConfig() { void shouldUseCliqueWhenCliqueInConfig() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("clique", emptyMap())); final GenesisConfigOptions config = fromConfigOptions(singletonMap("clique", emptyMap()));
assertThat(config.isClique()).isTrue(); assertThat(config.isClique()).isTrue();
assertThat(config.isPoa()).isTrue(); assertThat(config.isPoa()).isTrue();
@ -69,7 +69,7 @@ public class GenesisConfigOptionsTest {
} }
@Test @Test
public void shouldNotUseCliqueIfCliqueNotPresent() { void shouldNotUseCliqueIfCliqueNotPresent() {
final GenesisConfigOptions config = fromConfigOptions(emptyMap()); final GenesisConfigOptions config = fromConfigOptions(emptyMap());
assertThat(config.isClique()).isFalse(); assertThat(config.isClique()).isFalse();
assertThat(config.isPoa()).isFalse(); assertThat(config.isPoa()).isFalse();
@ -77,63 +77,63 @@ public class GenesisConfigOptionsTest {
} }
@Test @Test
public void shouldGetHomesteadBlockNumber() { void shouldGetHomesteadBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("homesteadBlock", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("homesteadBlock", 1000));
assertThat(config.getHomesteadBlockNumber()).hasValue(1000); assertThat(config.getHomesteadBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetDaoForkBlockNumber() { void shouldGetDaoForkBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("daoForkBlock", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("daoForkBlock", 1000));
assertThat(config.getDaoForkBlock()).hasValue(1000); assertThat(config.getDaoForkBlock()).hasValue(1000);
} }
@Test @Test
public void shouldNotHaveDaoForkBlockWhenSetToZero() { void shouldNotHaveDaoForkBlockWhenSetToZero() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("daoForkBlock", 0)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("daoForkBlock", 0));
assertThat(config.getDaoForkBlock()).isEmpty(); assertThat(config.getDaoForkBlock()).isEmpty();
} }
@Test @Test
public void shouldGetTangerineWhistleBlockNumber() { void shouldGetTangerineWhistleBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("eip150Block", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("eip150Block", 1000));
assertThat(config.getTangerineWhistleBlockNumber()).hasValue(1000); assertThat(config.getTangerineWhistleBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetSpuriousDragonBlockNumber() { void shouldGetSpuriousDragonBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("eip158Block", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("eip158Block", 1000));
assertThat(config.getSpuriousDragonBlockNumber()).hasValue(1000); assertThat(config.getSpuriousDragonBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetByzantiumBlockNumber() { void shouldGetByzantiumBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("byzantiumBlock", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("byzantiumBlock", 1000));
assertThat(config.getByzantiumBlockNumber()).hasValue(1000); assertThat(config.getByzantiumBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetConstantinopleBlockNumber() { void shouldGetConstantinopleBlockNumber() {
final GenesisConfigOptions config = final GenesisConfigOptions config =
fromConfigOptions(singletonMap("constantinopleBlock", 1000)); fromConfigOptions(singletonMap("constantinopleBlock", 1000));
assertThat(config.getConstantinopleBlockNumber()).hasValue(1000); assertThat(config.getConstantinopleBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetConstantinopleFixBlockNumber() { void shouldGetConstantinopleFixBlockNumber() {
final GenesisConfigOptions config = final GenesisConfigOptions config =
fromConfigOptions(singletonMap("constantinopleFixBlock", 1000)); fromConfigOptions(singletonMap("constantinopleFixBlock", 1000));
assertThat(config.getPetersburgBlockNumber()).hasValue(1000); assertThat(config.getPetersburgBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetPetersburgBlockNumber() { void shouldGetPetersburgBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("petersburgBlock", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("petersburgBlock", 1000));
assertThat(config.getPetersburgBlockNumber()).hasValue(1000); assertThat(config.getPetersburgBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldFailWithBothPetersburgAndConstantinopleFixBlockNumber() { void shouldFailWithBothPetersburgAndConstantinopleFixBlockNumber() {
Map<String, Object> configMap = new HashMap<>(); Map<String, Object> configMap = new HashMap<>();
configMap.put("constantinopleFixBlock", 1000); configMap.put("constantinopleFixBlock", 1000);
configMap.put("petersburgBlock", 1000); configMap.put("petersburgBlock", 1000);
@ -145,68 +145,74 @@ public class GenesisConfigOptionsTest {
} }
@Test @Test
public void shouldGetIstanbulBlockNumber() { void shouldGetIstanbulBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("istanbulBlock", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("istanbulBlock", 1000));
assertThat(config.getIstanbulBlockNumber()).hasValue(1000); assertThat(config.getIstanbulBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetMuirGlacierBlockNumber() { void shouldGetMuirGlacierBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("muirGlacierBlock", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("muirGlacierBlock", 1000));
assertThat(config.getMuirGlacierBlockNumber()).hasValue(1000); assertThat(config.getMuirGlacierBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetBerlinBlockNumber() { void shouldGetBerlinBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("berlinBlock", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("berlinBlock", 1000));
assertThat(config.getBerlinBlockNumber()).hasValue(1000); assertThat(config.getBerlinBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetLondonBlockNumber() { void shouldGetLondonBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("londonblock", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("londonblock", 1000));
assertThat(config.getLondonBlockNumber()).hasValue(1000); assertThat(config.getLondonBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetArrowGlacierBlockNumber() { void shouldGetArrowGlacierBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("arrowGlacierBlock", 1000)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("arrowGlacierBlock", 1000));
assertThat(config.getArrowGlacierBlockNumber()).hasValue(1000); assertThat(config.getArrowGlacierBlockNumber()).hasValue(1000);
} }
@Test @Test
public void shouldGetGrayGlacierBlockNumber() { void shouldGetGrayGlacierBlockNumber() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("grayGlacierBlock", 4242)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("grayGlacierBlock", 4242));
assertThat(config.getGrayGlacierBlockNumber()).hasValue(4242); assertThat(config.getGrayGlacierBlockNumber()).hasValue(4242);
} }
@Test @Test
public void shouldGetShanghaiTime() { void shouldGetShanghaiTime() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("shanghaiTime", 1670470141)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("shanghaiTime", 1670470141));
assertThat(config.getShanghaiTime()).hasValue(1670470141); assertThat(config.getShanghaiTime()).hasValue(1670470141);
} }
@Test @Test
public void shouldGetCancunTime() { void shouldGetCancunTime() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("cancunTime", 1670470142)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("cancunTime", 1670470142));
assertThat(config.getCancunTime()).hasValue(1670470142); assertThat(config.getCancunTime()).hasValue(1670470142);
} }
@Test @Test
public void shouldGetFutureEipsTime() { void shouldGetPragueTime() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("pragueTime", 1670470143));
assertThat(config.getPragueTime()).hasValue(1670470143);
}
@Test
void shouldGetFutureEipsTime() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("futureEipsTime", 1337)); final GenesisConfigOptions config = fromConfigOptions(singletonMap("futureEipsTime", 1337));
assertThat(config.getFutureEipsTime()).hasValue(1337); assertThat(config.getFutureEipsTime()).hasValue(1337);
} }
@Test @Test
public void shouldGetExperimentalEipsTime() { void shouldGetExperimentalEipsTime() {
final GenesisConfigOptions config = final GenesisConfigOptions config =
fromConfigOptions(singletonMap("experimentalEipsTime", 1337)); fromConfigOptions(singletonMap("experimentalEipsTime", 1337));
assertThat(config.getExperimentalEipsTime()).hasValue(1337); assertThat(config.getExperimentalEipsTime()).hasValue(1337);
} }
@Test @Test
public void shouldNotReturnEmptyOptionalWhenBlockNumberNotSpecified() { void shouldNotReturnEmptyOptionalWhenBlockNumberNotSpecified() {
final GenesisConfigOptions config = fromConfigOptions(emptyMap()); final GenesisConfigOptions config = fromConfigOptions(emptyMap());
assertThat(config.getHomesteadBlockNumber()).isEmpty(); assertThat(config.getHomesteadBlockNumber()).isEmpty();
assertThat(config.getDaoForkBlock()).isEmpty(); assertThat(config.getDaoForkBlock()).isEmpty();
@ -224,19 +230,20 @@ public class GenesisConfigOptionsTest {
assertThat(config.getMergeNetSplitBlockNumber()).isEmpty(); assertThat(config.getMergeNetSplitBlockNumber()).isEmpty();
assertThat(config.getShanghaiTime()).isEmpty(); assertThat(config.getShanghaiTime()).isEmpty();
assertThat(config.getCancunTime()).isEmpty(); assertThat(config.getCancunTime()).isEmpty();
assertThat(config.getPragueTime()).isEmpty();
assertThat(config.getFutureEipsTime()).isEmpty(); assertThat(config.getFutureEipsTime()).isEmpty();
assertThat(config.getExperimentalEipsTime()).isEmpty(); assertThat(config.getExperimentalEipsTime()).isEmpty();
} }
@Test @Test
public void shouldGetChainIdWhenSpecified() { void shouldGetChainIdWhenSpecified() {
final GenesisConfigOptions config = final GenesisConfigOptions config =
fromConfigOptions(singletonMap("chainId", BigInteger.valueOf(32))); fromConfigOptions(singletonMap("chainId", BigInteger.valueOf(32)));
assertThat(config.getChainId()).hasValue(BigInteger.valueOf(32)); assertThat(config.getChainId()).hasValue(BigInteger.valueOf(32));
} }
@Test @Test
public void shouldSupportEmptyGenesisConfig() { void shouldSupportEmptyGenesisConfig() {
final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions(); final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions();
assertThat(config.isEthHash()).isFalse(); assertThat(config.isEthHash()).isFalse();
assertThat(config.isClique()).isFalse(); assertThat(config.isClique()).isFalse();
@ -245,7 +252,7 @@ public class GenesisConfigOptionsTest {
} }
@Test @Test
public void shouldGetTerminalTotalDifficultyWhenSpecified() { void shouldGetTerminalTotalDifficultyWhenSpecified() {
final GenesisConfigOptions config = final GenesisConfigOptions config =
fromConfigOptions(singletonMap("terminalTotalDifficulty", BigInteger.valueOf(1000))); fromConfigOptions(singletonMap("terminalTotalDifficulty", BigInteger.valueOf(1000)));
assertThat(config.getTerminalTotalDifficulty()).isPresent(); assertThat(config.getTerminalTotalDifficulty()).isPresent();
@ -259,7 +266,7 @@ public class GenesisConfigOptionsTest {
} }
@Test @Test
public void shouldNotReturnTerminalTotalDifficultyWhenNotSpecified() { void shouldNotReturnTerminalTotalDifficultyWhenNotSpecified() {
final GenesisConfigOptions config = fromConfigOptions(emptyMap()); final GenesisConfigOptions config = fromConfigOptions(emptyMap());
assertThat(config.getTerminalTotalDifficulty()).isNotPresent(); assertThat(config.getTerminalTotalDifficulty()).isNotPresent();
// stubJsonGenesis // stubJsonGenesis
@ -267,28 +274,28 @@ public class GenesisConfigOptionsTest {
} }
@Test @Test
public void isZeroBaseFeeShouldDefaultToFalse() { void isZeroBaseFeeShouldDefaultToFalse() {
final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions(); final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions();
assertThat(config.isZeroBaseFee()).isFalse(); assertThat(config.isZeroBaseFee()).isFalse();
} }
@Test @Test
public void isZeroBaseFeeParsedCorrectly() { void isZeroBaseFeeParsedCorrectly() {
final GenesisConfigOptions config = fromConfigOptions(Map.of("zerobasefee", true)); final GenesisConfigOptions config = fromConfigOptions(Map.of("zerobasefee", true));
assertThat(config.isZeroBaseFee()).isTrue(); assertThat(config.isZeroBaseFee()).isTrue();
} }
@Test @Test
public void asMapIncludesZeroBaseFee() { void asMapIncludesZeroBaseFee() {
final GenesisConfigOptions config = fromConfigOptions(Map.of("zerobasefee", true)); final GenesisConfigOptions config = fromConfigOptions(Map.of("zerobasefee", true));
assertThat(config.asMap()).containsOnlyKeys("zeroBaseFee").containsValue(true); assertThat(config.asMap()).containsOnlyKeys("zeroBaseFee").containsValue(true);
} }
@Test @Test
public void shouldGetDepositContractAddress() { void shouldGetDepositContractAddress() {
final GenesisConfigOptions config = final GenesisConfigOptions config =
fromConfigOptions( fromConfigOptions(
singletonMap("depositContractAddress", "0x00000000219ab540356cbb839cbe05303d7705fa")); singletonMap("depositContractAddress", "0x00000000219ab540356cbb839cbe05303d7705fa"));
@ -297,13 +304,13 @@ public class GenesisConfigOptionsTest {
} }
@Test @Test
public void shouldNotHaveDepositContractAddressWhenEmpty() { void shouldNotHaveDepositContractAddressWhenEmpty() {
final GenesisConfigOptions config = fromConfigOptions(emptyMap()); final GenesisConfigOptions config = fromConfigOptions(emptyMap());
assertThat(config.getDepositContractAddress()).isEmpty(); assertThat(config.getDepositContractAddress()).isEmpty();
} }
@Test @Test
public void asMapIncludesDepositContractAddress() { void asMapIncludesDepositContractAddress() {
final GenesisConfigOptions config = fromConfigOptions(Map.of("depositContractAddress", "0x0")); final GenesisConfigOptions config = fromConfigOptions(Map.of("depositContractAddress", "0x0"));
assertThat(config.asMap()) assertThat(config.asMap())

@ -16,6 +16,7 @@
"mergeNetSplitBlock": 14, "mergeNetSplitBlock": 14,
"shanghaiTime": 15, "shanghaiTime": 15,
"cancunTime": 16, "cancunTime": 16,
"pragueTime": 17,
"futureEipsTime": 98, "futureEipsTime": 98,
"experimentalEipsTime": 99, "experimentalEipsTime": 99,
"ecip1015Block": 102, "ecip1015Block": 102,

@ -281,7 +281,7 @@ public final class GenesisState {
if (shanghaiTimestamp.isPresent()) { if (shanghaiTimestamp.isPresent()) {
return genesis.getTimestamp() >= shanghaiTimestamp.getAsLong(); return genesis.getTimestamp() >= shanghaiTimestamp.getAsLong();
} }
return false; return isCancunAtGenesis(genesis);
} }
private static boolean isCancunAtGenesis(final GenesisConfigFile genesis) { private static boolean isCancunAtGenesis(final GenesisConfigFile genesis) {
@ -289,7 +289,23 @@ public final class GenesisState {
if (cancunTimestamp.isPresent()) { if (cancunTimestamp.isPresent()) {
return genesis.getTimestamp() >= cancunTimestamp.getAsLong(); return genesis.getTimestamp() >= cancunTimestamp.getAsLong();
} }
return false; return isPragueAtGenesis(genesis);
}
private static boolean isPragueAtGenesis(final GenesisConfigFile genesis) {
final OptionalLong pragueTimestamp = genesis.getConfigOptions().getPragueTime();
if (pragueTimestamp.isPresent()) {
return genesis.getTimestamp() >= pragueTimestamp.getAsLong();
}
return isFutureEipsTimeAtGenesis(genesis);
}
private static boolean isFutureEipsTimeAtGenesis(final GenesisConfigFile genesis) {
final OptionalLong futureEipsTime = genesis.getConfigOptions().getFutureEipsTime();
if (futureEipsTime.isPresent()) {
return genesis.getTimestamp() >= futureEipsTime.getAsLong();
}
return isExperimentalEipsTimeAtGenesis(genesis);
} }
private static boolean isExperimentalEipsTimeAtGenesis(final GenesisConfigFile genesis) { private static boolean isExperimentalEipsTimeAtGenesis(final GenesisConfigFile genesis) {

@ -22,6 +22,7 @@ import static org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts.po
import static org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts.populateForFrontier; import static org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts.populateForFrontier;
import static org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts.populateForFutureEIPs; import static org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts.populateForFutureEIPs;
import static org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts.populateForIstanbul; import static org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts.populateForIstanbul;
import static org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts.populateForPrague;
import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.FlexiblePrivacyPrecompiledContract; import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.FlexiblePrivacyPrecompiledContract;
import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.PrivacyPluginPrecompiledContract; import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.PrivacyPluginPrecompiledContract;
@ -59,6 +60,13 @@ public interface MainnetPrecompiledContractRegistries {
return registry; return registry;
} }
static PrecompileContractRegistry prague(
final PrecompiledContractConfiguration precompiledContractConfiguration) {
final PrecompileContractRegistry registry = new PrecompileContractRegistry();
populateForPrague(registry, precompiledContractConfiguration.getGasCalculator());
return registry;
}
static PrecompileContractRegistry futureEips( static PrecompileContractRegistry futureEips(
final PrecompiledContractConfiguration precompiledContractConfiguration) { final PrecompiledContractConfiguration precompiledContractConfiguration) {
final PrecompileContractRegistry registry = new PrecompileContractRegistry(); final PrecompileContractRegistry registry = new PrecompileContractRegistry();

@ -168,6 +168,16 @@ public class MainnetProtocolSpecFactory {
evmConfiguration); evmConfiguration);
} }
public ProtocolSpecBuilder pragueDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.pragueDefinition(
chainId,
contractSizeLimit,
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
evmConfiguration);
}
/** /**
* The "future" fork consists of EIPs that have been approved for Ethereum Mainnet but not * The "future" fork consists of EIPs that have been approved for Ethereum Mainnet but not
* scheduled for a fork. This is also known as "Eligible For Inclusion" (EFI) or "Considered for * scheduled for a fork. This is also known as "Eligible For Inclusion" (EFI) or "Considered for

@ -51,6 +51,7 @@ import org.hyperledger.besu.evm.gascalculator.HomesteadGasCalculator;
import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator;
import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator;
import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator;
import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;
import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator; import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator;
import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator;
import org.hyperledger.besu.evm.gascalculator.TangerineWhistleGasCalculator; import org.hyperledger.besu.evm.gascalculator.TangerineWhistleGasCalculator;
@ -661,7 +662,7 @@ public abstract class MainnetProtocolSpecs {
feeMarket -> feeMarket ->
new CancunTargetingGasLimitCalculator( new CancunTargetingGasLimitCalculator(
londonForkBlockNumber, (BaseFeeMarket) feeMarket)) londonForkBlockNumber, (BaseFeeMarket) feeMarket))
// EVM changes to support EOF EIPs (3670, 4200, 4750, 5450) // EVM changes to support EIP-1153: TSTORE and EIP-5656: MCOPY
.evmBuilder( .evmBuilder(
(gasCalculator, jdCacheConfig) -> (gasCalculator, jdCacheConfig) ->
MainnetEVMs.cancun( MainnetEVMs.cancun(
@ -703,7 +704,7 @@ public abstract class MainnetProtocolSpecs {
.name("Cancun"); .name("Cancun");
} }
static ProtocolSpecBuilder futureEipsDefinition( static ProtocolSpecBuilder pragueDefinition(
final Optional<BigInteger> chainId, final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit, final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit, final OptionalInt configStackSizeLimit,
@ -712,6 +713,7 @@ public abstract class MainnetProtocolSpecs {
final EvmConfiguration evmConfiguration) { final EvmConfiguration evmConfiguration) {
final int contractSizeLimit = final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT); configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
return cancunDefinition( return cancunDefinition(
chainId, chainId,
configContractSizeLimit, configContractSizeLimit,
@ -719,6 +721,44 @@ public abstract class MainnetProtocolSpecs {
enableRevertReason, enableRevertReason,
genesisConfigOptions, genesisConfigOptions,
evmConfiguration) evmConfiguration)
// EVM changes to support EOF EIPs (3670, 4200, 4750, 5450)
.gasCalculator(PragueGasCalculator::new)
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
MainnetEVMs.prague(
gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration))
// change contract call creator to accept EOF code
.contractCreationProcessorBuilder(
(gasCalculator, evm) ->
new ContractCreationProcessor(
gasCalculator,
evm,
true,
List.of(
MaxCodeSizeRule.of(contractSizeLimit), EOFValidationCodeRule.of(1, false)),
1,
SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES))
// use prague precompiled contracts
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::prague)
.name("Prague");
}
static ProtocolSpecBuilder futureEipsDefinition(
final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration) {
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
return pragueDefinition(
chainId,
configContractSizeLimit,
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
evmConfiguration)
// Use Future EIP configured EVM // Use Future EIP configured EVM
.evmBuilder( .evmBuilder(
(gasCalculator, jdCacheConfig) -> (gasCalculator, jdCacheConfig) ->

@ -235,6 +235,7 @@ public class ProtocolScheduleBuilder {
// Begin timestamp forks // Begin timestamp forks
lastForkBlock = validateForkOrder("Shanghai", config.getShanghaiTime(), lastForkBlock); lastForkBlock = validateForkOrder("Shanghai", config.getShanghaiTime(), lastForkBlock);
lastForkBlock = validateForkOrder("Cancun", config.getCancunTime(), lastForkBlock); lastForkBlock = validateForkOrder("Cancun", config.getCancunTime(), lastForkBlock);
lastForkBlock = validateForkOrder("Prague", config.getPragueTime(), lastForkBlock);
lastForkBlock = validateForkOrder("FutureEips", config.getFutureEipsTime(), lastForkBlock); lastForkBlock = validateForkOrder("FutureEips", config.getFutureEipsTime(), lastForkBlock);
lastForkBlock = lastForkBlock =
validateForkOrder("ExperimentalEips", config.getExperimentalEipsTime(), lastForkBlock); validateForkOrder("ExperimentalEips", config.getExperimentalEipsTime(), lastForkBlock);
@ -313,6 +314,7 @@ public class ProtocolScheduleBuilder {
// Timestamp Forks // Timestamp Forks
timestampMilestone(config.getShanghaiTime(), specFactory.shanghaiDefinition(config)), timestampMilestone(config.getShanghaiTime(), specFactory.shanghaiDefinition(config)),
timestampMilestone(config.getCancunTime(), specFactory.cancunDefinition(config)), timestampMilestone(config.getCancunTime(), specFactory.cancunDefinition(config)),
timestampMilestone(config.getPragueTime(), specFactory.pragueDefinition(config)),
timestampMilestone(config.getFutureEipsTime(), specFactory.futureEipsDefinition(config)), timestampMilestone(config.getFutureEipsTime(), specFactory.futureEipsDefinition(config)),
timestampMilestone( timestampMilestone(
config.getExperimentalEipsTime(), specFactory.experimentalEipsDefinition(config)), config.getExperimentalEipsTime(), specFactory.experimentalEipsDefinition(config)),

@ -40,7 +40,7 @@ import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource; import org.junit.jupiter.params.provider.ArgumentsSource;
public final class GenesisStateTest { final class GenesisStateTest {
/** Known RLP encoded bytes of the Olympic Genesis Block. */ /** Known RLP encoded bytes of the Olympic Genesis Block. */
private static final String OLYMPIC_RLP = private static final String OLYMPIC_RLP =
@ -63,7 +63,7 @@ public final class GenesisStateTest {
@ParameterizedTest @ParameterizedTest
@ArgumentsSource(GenesisStateTestArguments.class) @ArgumentsSource(GenesisStateTestArguments.class)
public void createFromJsonWithAllocs(final DataStorageFormat dataStorageFormat) throws Exception { void createFromJsonWithAllocs(final DataStorageFormat dataStorageFormat) throws Exception {
final GenesisState genesisState = final GenesisState genesisState =
GenesisState.fromJson( GenesisState.fromJson(
dataStorageFormat, dataStorageFormat,
@ -93,7 +93,7 @@ public final class GenesisStateTest {
@ParameterizedTest @ParameterizedTest
@ArgumentsSource(GenesisStateTestArguments.class) @ArgumentsSource(GenesisStateTestArguments.class)
public void createFromJsonNoAllocs(final DataStorageFormat dataStorageFormat) throws Exception { void createFromJsonNoAllocs(final DataStorageFormat dataStorageFormat) throws Exception {
final GenesisState genesisState = final GenesisState genesisState =
GenesisState.fromJson( GenesisState.fromJson(
dataStorageFormat, dataStorageFormat,
@ -136,8 +136,7 @@ public final class GenesisStateTest {
@ParameterizedTest @ParameterizedTest
@ArgumentsSource(GenesisStateTestArguments.class) @ArgumentsSource(GenesisStateTestArguments.class)
public void createFromJsonWithContract(final DataStorageFormat dataStorageFormat) void createFromJsonWithContract(final DataStorageFormat dataStorageFormat) throws Exception {
throws Exception {
assertContractInvariants( assertContractInvariants(
dataStorageFormat, dataStorageFormat,
"genesis3.json", "genesis3.json",
@ -146,7 +145,7 @@ public final class GenesisStateTest {
@ParameterizedTest @ParameterizedTest
@ArgumentsSource(GenesisStateTestArguments.class) @ArgumentsSource(GenesisStateTestArguments.class)
public void createFromJsonWithNonce(final DataStorageFormat dataStorageFormat) throws Exception { void createFromJsonWithNonce(final DataStorageFormat dataStorageFormat) throws Exception {
final GenesisState genesisState = final GenesisState genesisState =
GenesisState.fromJson( GenesisState.fromJson(
dataStorageFormat, dataStorageFormat,
@ -162,7 +161,7 @@ public final class GenesisStateTest {
@ParameterizedTest @ParameterizedTest
@ArgumentsSource(GenesisStateTestArguments.class) @ArgumentsSource(GenesisStateTestArguments.class)
public void encodeOlympicBlock(final DataStorageFormat dataStorageFormat) throws Exception { void encodeOlympicBlock(final DataStorageFormat dataStorageFormat) throws Exception {
final GenesisState genesisState = final GenesisState genesisState =
GenesisState.fromJson( GenesisState.fromJson(
dataStorageFormat, dataStorageFormat,
@ -183,7 +182,7 @@ public final class GenesisStateTest {
@ParameterizedTest @ParameterizedTest
@ArgumentsSource(GenesisStateTestArguments.class) @ArgumentsSource(GenesisStateTestArguments.class)
public void genesisFromShanghai(final DataStorageFormat dataStorageFormat) throws Exception { void genesisFromShanghai(final DataStorageFormat dataStorageFormat) throws Exception {
final GenesisState genesisState = final GenesisState genesisState =
GenesisState.fromJson( GenesisState.fromJson(
dataStorageFormat, dataStorageFormat,
@ -196,8 +195,8 @@ public final class GenesisStateTest {
Hash.fromHexString( Hash.fromHexString(
"0xfdc41f92053811b877be43e61cab6b0d9ee55501ae2443df0970c753747f12d8")); "0xfdc41f92053811b877be43e61cab6b0d9ee55501ae2443df0970c753747f12d8"));
assertThat(header.getGasLimit()).isEqualTo(0x2fefd8); assertThat(header.getGasLimit()).isEqualTo(0x2fefd8);
assertThat(header.getGasUsed()).isEqualTo(0); assertThat(header.getGasUsed()).isZero();
assertThat(header.getNumber()).isEqualTo(0); assertThat(header.getNumber()).isZero();
assertThat(header.getReceiptsRoot()) assertThat(header.getReceiptsRoot())
.isEqualTo( .isEqualTo(
Hash.fromHexString( Hash.fromHexString(
@ -223,7 +222,7 @@ public final class GenesisStateTest {
final Account last = final Account last =
worldState.get(Address.fromHexString("fb289e2b2b65fb63299a682d000744671c50417b")); worldState.get(Address.fromHexString("fb289e2b2b65fb63299a682d000744671c50417b"));
assertThat(first).isNotNull(); assertThat(first).isNotNull();
assertThat(first.getBalance().toLong()).isEqualTo(0); assertThat(first.getBalance().toLong()).isZero();
assertThat(first.getCode()) assertThat(first.getCode())
.isEqualTo(Bytes.fromHexString("0x5f804955600180495560028049556003804955")); .isEqualTo(Bytes.fromHexString("0x5f804955600180495560028049556003804955"));
assertThat(last).isNotNull(); assertThat(last).isNotNull();
@ -233,7 +232,7 @@ public final class GenesisStateTest {
@ParameterizedTest @ParameterizedTest
@ArgumentsSource(GenesisStateTestArguments.class) @ArgumentsSource(GenesisStateTestArguments.class)
public void genesisFromCancun(final DataStorageFormat dataStorageFormat) throws Exception { void genesisFromCancun(final DataStorageFormat dataStorageFormat) throws Exception {
final GenesisState genesisState = final GenesisState genesisState =
GenesisState.fromJson( GenesisState.fromJson(
dataStorageFormat, dataStorageFormat,
@ -246,8 +245,58 @@ public final class GenesisStateTest {
Hash.fromHexString( Hash.fromHexString(
"0x87846b86c1026fa7d7be2da045716274231de1871065a320659c9b111287c688")); "0x87846b86c1026fa7d7be2da045716274231de1871065a320659c9b111287c688"));
assertThat(header.getGasLimit()).isEqualTo(0x2fefd8); assertThat(header.getGasLimit()).isEqualTo(0x2fefd8);
assertThat(header.getGasUsed()).isEqualTo(0); assertThat(header.getGasUsed()).isZero();
assertThat(header.getNumber()).isEqualTo(0); assertThat(header.getNumber()).isZero();
assertThat(header.getReceiptsRoot())
.isEqualTo(
Hash.fromHexString(
"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"));
assertThat(header.getTransactionsRoot()).isEqualTo(Hash.EMPTY_TRIE_HASH);
assertThat(header.getOmmersHash())
.isEqualTo(
Hash.fromHexString(
"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"));
assertThat(header.getExtraData()).isEqualTo(Bytes.EMPTY);
assertThat(header.getParentHash()).isEqualTo(Hash.ZERO);
final MutableWorldState worldState = InMemoryKeyValueStorageProvider.createInMemoryWorldState();
genesisState.writeStateTo(worldState);
Hash computedStateRoot = worldState.rootHash();
assertThat(computedStateRoot).isEqualTo(header.getStateRoot());
assertThat(header.getStateRoot())
.isEqualTo(
Hash.fromHexString(
"0x7f5cfe1375a61009a22d24512d18035bc8f855129452fa9c6a6be2ef4e9da7db"));
final Account first =
worldState.get(Address.fromHexString("0000000000000000000000000000000000000100"));
final Account last =
worldState.get(Address.fromHexString("fb289e2b2b65fb63299a682d000744671c50417b"));
assertThat(first).isNotNull();
assertThat(first.getBalance().toLong()).isZero();
assertThat(first.getCode())
.isEqualTo(Bytes.fromHexString("0x5f804955600180495560028049556003804955"));
assertThat(last).isNotNull();
Wei lastBalance = last.getBalance();
assertThat(lastBalance).isEqualTo(Wei.fromHexString("0x123450000000000000000"));
}
@ParameterizedTest
@ArgumentsSource(GenesisStateTestArguments.class)
void genesisFromPrague(final DataStorageFormat dataStorageFormat) throws Exception {
final GenesisState genesisState =
GenesisState.fromJson(
dataStorageFormat,
Resources.toString(
GenesisStateTest.class.getResource("genesis_prague.json"), Charsets.UTF_8),
ProtocolScheduleFixture.MAINNET);
final BlockHeader header = genesisState.getBlock().getHeader();
assertThat(header.getHash())
.isEqualTo(
Hash.fromHexString(
"0x87846b86c1026fa7d7be2da045716274231de1871065a320659c9b111287c688"));
assertThat(header.getGasLimit()).isEqualTo(0x2fefd8);
assertThat(header.getGasUsed()).isZero();
assertThat(header.getNumber()).isZero();
assertThat(header.getReceiptsRoot()) assertThat(header.getReceiptsRoot())
.isEqualTo( .isEqualTo(
Hash.fromHexString( Hash.fromHexString(
@ -273,7 +322,7 @@ public final class GenesisStateTest {
final Account last = final Account last =
worldState.get(Address.fromHexString("fb289e2b2b65fb63299a682d000744671c50417b")); worldState.get(Address.fromHexString("fb289e2b2b65fb63299a682d000744671c50417b"));
assertThat(first).isNotNull(); assertThat(first).isNotNull();
assertThat(first.getBalance().toLong()).isEqualTo(0); assertThat(first.getBalance().toLong()).isZero();
assertThat(first.getCode()) assertThat(first.getCode())
.isEqualTo(Bytes.fromHexString("0x5f804955600180495560028049556003804955")); .isEqualTo(Bytes.fromHexString("0x5f804955600180495560028049556003804955"));
assertThat(last).isNotNull(); assertThat(last).isNotNull();

@ -41,7 +41,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
public class ProtocolScheduleBuilderTest { class ProtocolScheduleBuilderTest {
private final long PRE_SHANGHAI_TIMESTAMP = 1680488620L; // Mon, 03 Apr 2023 02:23:40 UTC private final long PRE_SHANGHAI_TIMESTAMP = 1680488620L; // Mon, 03 Apr 2023 02:23:40 UTC
@Mock GenesisConfigOptions configOptions; @Mock GenesisConfigOptions configOptions;
@Mock private Function<ProtocolSpecBuilder, ProtocolSpecBuilder> modifier; @Mock private Function<ProtocolSpecBuilder, ProtocolSpecBuilder> modifier;
@ -61,13 +61,14 @@ public class ProtocolScheduleBuilderTest {
} }
@Test @Test
public void createProtocolScheduleInOrder() { void createProtocolScheduleInOrder() {
when(configOptions.getHomesteadBlockNumber()).thenReturn(OptionalLong.of(1L)); when(configOptions.getHomesteadBlockNumber()).thenReturn(OptionalLong.of(1L));
when(configOptions.getDaoForkBlock()).thenReturn(OptionalLong.of(2L)); when(configOptions.getDaoForkBlock()).thenReturn(OptionalLong.of(2L));
when(configOptions.getByzantiumBlockNumber()).thenReturn(OptionalLong.of(13L)); when(configOptions.getByzantiumBlockNumber()).thenReturn(OptionalLong.of(13L));
when(configOptions.getMergeNetSplitBlockNumber()).thenReturn(OptionalLong.of(15L)); when(configOptions.getMergeNetSplitBlockNumber()).thenReturn(OptionalLong.of(15L));
when(configOptions.getShanghaiTime()).thenReturn(OptionalLong.of(PRE_SHANGHAI_TIMESTAMP + 1)); when(configOptions.getShanghaiTime()).thenReturn(OptionalLong.of(PRE_SHANGHAI_TIMESTAMP + 1));
when(configOptions.getCancunTime()).thenReturn(OptionalLong.of(PRE_SHANGHAI_TIMESTAMP + 3)); when(configOptions.getCancunTime()).thenReturn(OptionalLong.of(PRE_SHANGHAI_TIMESTAMP + 3));
when(configOptions.getPragueTime()).thenReturn(OptionalLong.of(PRE_SHANGHAI_TIMESTAMP + 5));
final ProtocolSchedule protocolSchedule = builder.createProtocolSchedule(); final ProtocolSchedule protocolSchedule = builder.createProtocolSchedule();
assertThat(protocolSchedule.getChainId()).contains(CHAIN_ID); assertThat(protocolSchedule.getChainId()).contains(CHAIN_ID);
@ -102,10 +103,20 @@ public class ProtocolScheduleBuilderTest {
.getByBlockHeader(blockHeader(54, PRE_SHANGHAI_TIMESTAMP + 4)) .getByBlockHeader(blockHeader(54, PRE_SHANGHAI_TIMESTAMP + 4))
.getName()) .getName())
.isEqualTo("Cancun"); .isEqualTo("Cancun");
assertThat(
protocolSchedule
.getByBlockHeader(blockHeader(55, PRE_SHANGHAI_TIMESTAMP + 5))
.getName())
.isEqualTo("Prague");
assertThat(
protocolSchedule
.getByBlockHeader(blockHeader(56, PRE_SHANGHAI_TIMESTAMP + 6))
.getName())
.isEqualTo("Prague");
} }
@Test @Test
public void createProtocolScheduleOverlappingUsesLatestFork() { void createProtocolScheduleOverlappingUsesLatestFork() {
when(configOptions.getHomesteadBlockNumber()).thenReturn(OptionalLong.of(0L)); when(configOptions.getHomesteadBlockNumber()).thenReturn(OptionalLong.of(0L));
when(configOptions.getByzantiumBlockNumber()).thenReturn(OptionalLong.of(0L)); when(configOptions.getByzantiumBlockNumber()).thenReturn(OptionalLong.of(0L));
final ProtocolSchedule protocolSchedule = builder.createProtocolSchedule(); final ProtocolSchedule protocolSchedule = builder.createProtocolSchedule();
@ -116,7 +127,7 @@ public class ProtocolScheduleBuilderTest {
} }
@Test @Test
public void createProtocolScheduleOutOfOrderThrows() { void createProtocolScheduleOutOfOrderThrows() {
when(configOptions.getDaoForkBlock()).thenReturn(OptionalLong.of(0L)); when(configOptions.getDaoForkBlock()).thenReturn(OptionalLong.of(0L));
when(configOptions.getArrowGlacierBlockNumber()).thenReturn(OptionalLong.of(12L)); when(configOptions.getArrowGlacierBlockNumber()).thenReturn(OptionalLong.of(12L));
when(configOptions.getGrayGlacierBlockNumber()).thenReturn(OptionalLong.of(11L)); when(configOptions.getGrayGlacierBlockNumber()).thenReturn(OptionalLong.of(11L));
@ -127,7 +138,7 @@ public class ProtocolScheduleBuilderTest {
} }
@Test @Test
public void createProtocolScheduleWithTimestampsOutOfOrderThrows() { void createProtocolScheduleWithTimestampsOutOfOrderThrows() {
when(configOptions.getDaoForkBlock()).thenReturn(OptionalLong.of(0L)); when(configOptions.getDaoForkBlock()).thenReturn(OptionalLong.of(0L));
when(configOptions.getShanghaiTime()).thenReturn(OptionalLong.of(3L)); when(configOptions.getShanghaiTime()).thenReturn(OptionalLong.of(3L));
when(configOptions.getCancunTime()).thenReturn(OptionalLong.of(2L)); when(configOptions.getCancunTime()).thenReturn(OptionalLong.of(2L));
@ -138,7 +149,7 @@ public class ProtocolScheduleBuilderTest {
} }
@Test @Test
public void modifierInsertedBetweenBlocksIsAppliedToLaterAndCreatesInterimMilestone() { void modifierInsertedBetweenBlocksIsAppliedToLaterAndCreatesInterimMilestone() {
when(configOptions.getHomesteadBlockNumber()).thenReturn(OptionalLong.of(5L)); when(configOptions.getHomesteadBlockNumber()).thenReturn(OptionalLong.of(5L));
when(modifier.apply(any())) when(modifier.apply(any()))
@ -158,7 +169,7 @@ public class ProtocolScheduleBuilderTest {
} }
@Test @Test
public void modifierPastEndOfDefinedMilestonesGetsItsOwnMilestoneCreated() { void modifierPastEndOfDefinedMilestonesGetsItsOwnMilestoneCreated() {
when(modifier.apply(any())) when(modifier.apply(any()))
.thenAnswer((Answer<ProtocolSpecBuilder>) invocation -> invocation.getArgument(0)); .thenAnswer((Answer<ProtocolSpecBuilder>) invocation -> invocation.getArgument(0));
@ -175,7 +186,7 @@ public class ProtocolScheduleBuilderTest {
} }
@Test @Test
public void modifierOnDefinedMilestoneIsAppliedButDoesNotGetAnExtraMilestoneCreated() { void modifierOnDefinedMilestoneIsAppliedButDoesNotGetAnExtraMilestoneCreated() {
when(configOptions.getHomesteadBlockNumber()).thenReturn(OptionalLong.of(5L)); when(configOptions.getHomesteadBlockNumber()).thenReturn(OptionalLong.of(5L));
when(modifier.apply(any())) when(modifier.apply(any()))
.thenAnswer((Answer<ProtocolSpecBuilder>) invocation -> invocation.getArgument(0)); .thenAnswer((Answer<ProtocolSpecBuilder>) invocation -> invocation.getArgument(0));

@ -111,6 +111,9 @@ class MainnetGenesisFileModule extends GenesisFileModule {
Map.entry( Map.entry(
"cancun", "cancun",
createSchedule(new StubGenesisConfigOptions().cancunTime(0).baseFeePerGas(0x0a))), createSchedule(new StubGenesisConfigOptions().cancunTime(0).baseFeePerGas(0x0a))),
Map.entry(
"prague",
createSchedule(new StubGenesisConfigOptions().pragueTime(0).baseFeePerGas(0x0a))),
Map.entry( Map.entry(
"futureeips", "futureeips",
createSchedule(new StubGenesisConfigOptions().futureEipsTime(0).baseFeePerGas(0x0a))), createSchedule(new StubGenesisConfigOptions().futureEipsTime(0).baseFeePerGas(0x0a))),

@ -31,6 +31,7 @@ import org.hyperledger.besu.evm.gascalculator.HomesteadGasCalculator;
import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator;
import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator;
import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator;
import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;
import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator; import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator;
import org.hyperledger.besu.evm.precompile.PrecompiledContract; import org.hyperledger.besu.evm.precompile.PrecompiledContract;
@ -136,7 +137,8 @@ public abstract class BenchmarkExecutor {
case BERLIN -> new BerlinGasCalculator(); case BERLIN -> new BerlinGasCalculator();
case LONDON, PARIS -> new LondonGasCalculator(); case LONDON, PARIS -> new LondonGasCalculator();
case SHANGHAI -> new ShanghaiGasCalculator(); case SHANGHAI -> new ShanghaiGasCalculator();
default -> new CancunGasCalculator(); case CANCUN -> new CancunGasCalculator();
default -> new PragueGasCalculator();
}; };
} }

@ -78,8 +78,7 @@ public class ReferenceTestProtocolSchedules {
"ShanghaiToCancunAtTime15k", "ShanghaiToCancunAtTime15k",
createSchedule(genesisStub.clone().shanghaiTime(0).cancunTime(15000))); createSchedule(genesisStub.clone().shanghaiTime(0).cancunTime(15000)));
builder.put("Cancun", createSchedule(genesisStub.clone().cancunTime(0))); builder.put("Cancun", createSchedule(genesisStub.clone().cancunTime(0)));
// TODO remove this after execution-test-specs finalize builder.put("Prague", createSchedule(genesisStub.clone().pragueTime(0)));
builder.put("Prague", createSchedule(genesisStub.clone().futureEipsTime(0)));
builder.put("Future_EIPs", createSchedule(genesisStub.clone().futureEipsTime(0))); builder.put("Future_EIPs", createSchedule(genesisStub.clone().futureEipsTime(0)));
builder.put("Experimental_EIPs", createSchedule(genesisStub.clone().experimentalEipsTime(0))); builder.put("Experimental_EIPs", createSchedule(genesisStub.clone().experimentalEipsTime(0)));
return new ReferenceTestProtocolSchedules(builder.build()); return new ReferenceTestProtocolSchedules(builder.build());

@ -34,6 +34,7 @@ import org.hyperledger.besu.evm.gascalculator.HomesteadGasCalculator;
import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator;
import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator;
import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator;
import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;
import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator; import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator;
import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator;
import org.hyperledger.besu.evm.gascalculator.TangerineWhistleGasCalculator; import org.hyperledger.besu.evm.gascalculator.TangerineWhistleGasCalculator;
@ -148,6 +149,12 @@ public class TransactionTest {
milestone(spec, name, "Cancun", new CancunGasCalculator(), Optional.of(Wei.of(0))); milestone(spec, name, "Cancun", new CancunGasCalculator(), Optional.of(Wei.of(0)));
} }
@ParameterizedTest(name = "Name: {0}")
@MethodSource("getTestParametersForConfig")
public void prague(final String name, final TransactionTestCaseSpec spec) {
milestone(spec, name, "Prague", new PragueGasCalculator(), Optional.of(Wei.of(0)));
}
public void milestone( public void milestone(
final TransactionTestCaseSpec spec, final TransactionTestCaseSpec spec,
final String name, final String name,

@ -128,6 +128,7 @@ public class TestSetChainParams implements JsonRpcMethod {
maybeMoveToNumber(params, "mergeNetSplitForkBlock", config, "mergeNetSplitBlock"); maybeMoveToNumber(params, "mergeNetSplitForkBlock", config, "mergeNetSplitBlock");
maybeMoveToNumber(params, "shanghaiForkTime", config, "shanghaiTime"); maybeMoveToNumber(params, "shanghaiForkTime", config, "shanghaiTime");
maybeMoveToNumber(params, "cancunForkTime", config, "cancunTime"); maybeMoveToNumber(params, "cancunForkTime", config, "cancunTime");
maybeMoveToNumber(params, "pragueForkTime", config, "pragueTime");
maybeMoveToNumber(params, "futureEipsForkTime", config, "futureEipsTime"); maybeMoveToNumber(params, "futureEipsForkTime", config, "futureEipsTime");
maybeMoveToNumber(params, "experimentalEipsForkTime", config, "experimentalEipsTime"); maybeMoveToNumber(params, "experimentalEipsForkTime", config, "experimentalEipsTime");
maybeMoveToNumber(params, "chainID", config, "chainId", 1); maybeMoveToNumber(params, "chainID", config, "chainId", 1);

@ -50,7 +50,7 @@ public enum EvmSpecVersion {
/** Cancun evm spec version. */ /** Cancun evm spec version. */
CANCUN(0, true, "Cancun", "Finalized"), CANCUN(0, true, "Cancun", "Finalized"),
/** Prague evm spec version. */ /** Prague evm spec version. */
PRAGUE(0, false, "Prague", "Placeholder"), PRAGUE(0, false, "Prague", "In Development"),
/** Osaka evm spec version. */ /** Osaka evm spec version. */
OSAKA(0, false, "Osaka", "Placeholder"), OSAKA(0, false, "Osaka", "Placeholder"),
/** Bogota evm spec version. */ /** Bogota evm spec version. */

@ -24,6 +24,7 @@ import org.hyperledger.besu.evm.gascalculator.HomesteadGasCalculator;
import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator;
import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator;
import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator;
import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;
import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator; import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator;
import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator;
import org.hyperledger.besu.evm.gascalculator.TangerineWhistleGasCalculator; import org.hyperledger.besu.evm.gascalculator.TangerineWhistleGasCalculator;
@ -896,7 +897,7 @@ public class MainnetEVMs {
* @return the evm * @return the evm
*/ */
public static EVM prague(final BigInteger chainId, final EvmConfiguration evmConfiguration) { public static EVM prague(final BigInteger chainId, final EvmConfiguration evmConfiguration) {
return prague(new CancunGasCalculator(), chainId, evmConfiguration); return prague(new PragueGasCalculator(), chainId, evmConfiguration);
} }
/** /**
@ -963,7 +964,7 @@ public class MainnetEVMs {
* @return the evm * @return the evm
*/ */
public static EVM osaka(final BigInteger chainId, final EvmConfiguration evmConfiguration) { public static EVM osaka(final BigInteger chainId, final EvmConfiguration evmConfiguration) {
return osaka(new CancunGasCalculator(), chainId, evmConfiguration); return osaka(new PragueGasCalculator(), chainId, evmConfiguration);
} }
/** /**
@ -1030,7 +1031,7 @@ public class MainnetEVMs {
* @return the evm * @return the evm
*/ */
public static EVM bogota(final BigInteger chainId, final EvmConfiguration evmConfiguration) { public static EVM bogota(final BigInteger chainId, final EvmConfiguration evmConfiguration) {
return bogota(new CancunGasCalculator(), chainId, evmConfiguration); return bogota(new PragueGasCalculator(), chainId, evmConfiguration);
} }
/** /**
@ -1098,7 +1099,7 @@ public class MainnetEVMs {
* @return the evm * @return the evm
*/ */
public static EVM futureEips(final BigInteger chainId, final EvmConfiguration evmConfiguration) { public static EVM futureEips(final BigInteger chainId, final EvmConfiguration evmConfiguration) {
return futureEips(new CancunGasCalculator(), chainId, evmConfiguration); return futureEips(new PragueGasCalculator(), chainId, evmConfiguration);
} }
/** /**
@ -1174,7 +1175,7 @@ public class MainnetEVMs {
*/ */
public static EVM experimentalEips( public static EVM experimentalEips(
final BigInteger chainId, final EvmConfiguration evmConfiguration) { final BigInteger chainId, final EvmConfiguration evmConfiguration) {
return experimentalEips(new CancunGasCalculator(), chainId, evmConfiguration); return experimentalEips(new PragueGasCalculator(), chainId, evmConfiguration);
} }
/** /**

@ -499,7 +499,7 @@ public class EVMExecutor {
final BigInteger chainId, final EvmConfiguration evmConfiguration) { final BigInteger chainId, final EvmConfiguration evmConfiguration) {
final EVMExecutor executor = new EVMExecutor(MainnetEVMs.prague(chainId, evmConfiguration)); final EVMExecutor executor = new EVMExecutor(MainnetEVMs.prague(chainId, evmConfiguration));
executor.precompileContractRegistry = executor.precompileContractRegistry =
MainnetPrecompiledContracts.cancun(executor.evm.getGasCalculator()); MainnetPrecompiledContracts.prague(executor.evm.getGasCalculator());
return executor; return executor;
} }
@ -514,7 +514,7 @@ public class EVMExecutor {
final BigInteger chainId, final EvmConfiguration evmConfiguration) { final BigInteger chainId, final EvmConfiguration evmConfiguration) {
final EVMExecutor executor = new EVMExecutor(MainnetEVMs.osaka(chainId, evmConfiguration)); final EVMExecutor executor = new EVMExecutor(MainnetEVMs.osaka(chainId, evmConfiguration));
executor.precompileContractRegistry = executor.precompileContractRegistry =
MainnetPrecompiledContracts.cancun(executor.evm.getGasCalculator()); MainnetPrecompiledContracts.prague(executor.evm.getGasCalculator());
return executor; return executor;
} }
@ -529,7 +529,7 @@ public class EVMExecutor {
final BigInteger chainId, final EvmConfiguration evmConfiguration) { final BigInteger chainId, final EvmConfiguration evmConfiguration) {
final EVMExecutor executor = new EVMExecutor(MainnetEVMs.bogota(chainId, evmConfiguration)); final EVMExecutor executor = new EVMExecutor(MainnetEVMs.bogota(chainId, evmConfiguration));
executor.precompileContractRegistry = executor.precompileContractRegistry =
MainnetPrecompiledContracts.cancun(executor.evm.getGasCalculator()); MainnetPrecompiledContracts.prague(executor.evm.getGasCalculator());
return executor; return executor;
} }

@ -36,7 +36,7 @@ public class CancunGasCalculator extends ShanghaiGasCalculator {
* *
* @param maxPrecompile the max precompile * @param maxPrecompile the max precompile
*/ */
private CancunGasCalculator(final int maxPrecompile) { protected CancunGasCalculator(final int maxPrecompile) {
super(maxPrecompile); super(maxPrecompile);
} }

@ -0,0 +1,44 @@
/*
* Copyright Hyperledger Besu contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.evm.gascalculator;
import static org.hyperledger.besu.datatypes.Address.KZG_POINT_EVAL;
/**
* Gas Calculator for Prague
*
* <p>Placeholder for new gas schedule items. If Prague finalzies without changes this can be
* removed
*
* <UL>
* <LI>TBD
* </UL>
*/
public class PragueGasCalculator extends CancunGasCalculator {
/** Instantiates a new Prague Gas Calculator. */
public PragueGasCalculator() {
this(KZG_POINT_EVAL.toArrayUnsafe()[19]);
}
/**
* Instantiates a new Prague Gas Calculator
*
* @param maxPrecompile the max precompile
*/
protected PragueGasCalculator(final int maxPrecompile) {
super(maxPrecompile);
}
}

@ -140,6 +140,31 @@ public interface MainnetPrecompiledContracts {
registry.put(Address.KZG_POINT_EVAL, new KZGPointEvalPrecompiledContract()); registry.put(Address.KZG_POINT_EVAL, new KZGPointEvalPrecompiledContract());
} }
/**
* Prague precompile contract registry.
*
* @param gasCalculator the gas calculator
* @return the precompile contract registry
*/
static PrecompileContractRegistry prague(final GasCalculator gasCalculator) {
PrecompileContractRegistry precompileContractRegistry = new PrecompileContractRegistry();
populateForPrague(precompileContractRegistry, gasCalculator);
return precompileContractRegistry;
}
/**
* Populate registry for Prague.
*
* @param registry the registry
* @param gasCalculator the gas calculator
*/
static void populateForPrague(
final PrecompileContractRegistry registry, final GasCalculator gasCalculator) {
populateForCancun(registry, gasCalculator);
// TODO: add Prague precompiles here
}
/** /**
* FutureEIPs precompile contract registry. * FutureEIPs precompile contract registry.
* *

@ -127,6 +127,10 @@ class EVMExecutorTest {
EVMExecutor cancunEVM = EVMExecutor.cancun(EvmConfiguration.DEFAULT); EVMExecutor cancunEVM = EVMExecutor.cancun(EvmConfiguration.DEFAULT);
assertThat(cancunEVM.getChainId()).contains(defaultChainId); assertThat(cancunEVM.getChainId()).contains(defaultChainId);
EVMExecutor pragueEVM =
EVMExecutor.prague(defaultChainId.toBigInteger(), EvmConfiguration.DEFAULT);
assertThat(pragueEVM.getChainId()).contains(defaultChainId);
EVMExecutor futureEipsVM = EVMExecutor.futureEips(EvmConfiguration.DEFAULT); EVMExecutor futureEipsVM = EVMExecutor.futureEips(EvmConfiguration.DEFAULT);
assertThat(futureEipsVM.getChainId()).contains(defaultChainId); assertThat(futureEipsVM.getChainId()).contains(defaultChainId);
} }

Loading…
Cancel
Save