EIP-2935 Nyota updates (#7120)

Bring implementation up to nyota version of the EIP,
and remove invasive change into the EVM code.

Signed-off-by: Danno Ferrin <danno@numisight.com>

Co-authored-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
Co-authored-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
Co-authored-by: Justin Florentine <justin+github@florentine.us>
Co-authored-by: Jason Frame <jason.frame@consensys.net>
Co-authored-by: Jason Frame <jasonwframe@gmail.com>
pull/7126/head 24.5.2
Danno Ferrin 6 months ago committed by GitHub
parent d7123ce5b4
commit 0cca642bc5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/06_prague_getPayloadV4.json
  2. 8
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposits_execute_payload.json
  3. 8
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/09_prague_newPayloadV4.json
  4. 12
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/10_prague_forkchoiceUpdatedV3.json
  5. 8
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/11_prague_getPayloadV4.json
  6. 8
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV4.json
  7. 12
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_forkchoiceUpdatedV3.json
  8. 10
      acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_getPayloadV4.json
  9. 3
      besu/src/main/java/org/hyperledger/besu/services/TraceServiceImpl.java
  10. 6
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/ExecuteTransactionStep.java
  11. 12
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockReplay.java
  12. 6
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/BlockTracer.java
  13. 6
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracer.java
  14. 3
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracerTest.java
  15. 7
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java
  16. 2
      ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java
  17. 13
      ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java
  18. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java
  19. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java
  20. 9
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
  21. 14
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
  22. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/BlockHashProcessor.java
  23. 9
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/CancunBlockHashProcessor.java
  24. 9
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/FrontierBlockHashProcessor.java
  25. 72
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/blockhash/PragueBlockHashProcessor.java
  26. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateStateRehydration.java
  27. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionSimulator.java
  28. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/storage/migration/PrivateStorageMigration.java
  29. 5
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java
  30. 22
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/CachingBlockHashLookup.java
  31. 1
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java
  32. 3
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java
  33. 65
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/blockhash/BlockHashProcessorTest.java
  34. 49
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/CachingBlockHashLookupTest.java
  35. 6
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java
  36. 23
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java
  37. 18
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nExecutor.java
  38. 2
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java
  39. 5
      ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java
  40. 2
      evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java
  41. 5
      evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java
  42. 2
      evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java
  43. 3
      evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java
  44. 22
      evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java
  45. 49
      evm/src/main/java/org/hyperledger/besu/evm/operation/BlockHashOperation.java
  46. 2
      evm/src/test/java/org/hyperledger/besu/evm/code/CodeV0Test.java
  47. 2
      evm/src/test/java/org/hyperledger/besu/evm/fluent/EVMExecutorTest.java
  48. 2
      evm/src/test/java/org/hyperledger/besu/evm/frame/MessageFrameTest.java
  49. 2
      evm/src/test/java/org/hyperledger/besu/evm/operation/AbstractCreateOperationTest.java
  50. 37
      evm/src/test/java/org/hyperledger/besu/evm/operations/BlockHashOperationTest.java
  51. 4
      evm/src/test/java/org/hyperledger/besu/evm/operations/Create2OperationTest.java
  52. 2
      evm/src/test/java/org/hyperledger/besu/evm/operations/CreateOperationTest.java
  53. 2
      evm/src/test/java/org/hyperledger/besu/evm/operations/SelfDestructOperationTest.java
  54. 2
      evm/src/test/java/org/hyperledger/besu/evm/precompile/Benchmarks.java
  55. 4
      evm/src/test/java/org/hyperledger/besu/evm/testutils/TestMessageFrameBuilder.java
  56. 2
      evm/src/test/java/org/hyperledger/besu/evm/toy/EvmToyCommand.java

@ -14,7 +14,7 @@
"executionPayload": { "executionPayload": {
"parentHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", "parentHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x3057566307e82861160cd217c71c18a93023a752d268113a4e50148fe6f19be6", "stateRoot": "0x546ac65b9d37c72d7185f8dd67419803c636dd4e5ddf9b325fb64e9ecf570871",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380", "gasLimit": "0x1c9c380",
@ -30,14 +30,14 @@
"withdrawalRequests": [ "withdrawalRequests": [
{ {
"sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb", "sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb",
"amount" : "0x0", "validatorPublicKey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e",
"validatorPublicKey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e" "amount": "0x0"
} }
], ],
"blockNumber": "0x2", "blockNumber": "0x2",
"blockHash": "0xdce2f62925b5ebb218943e71fa87af2aaeb6dab2d8aee12ea7f9f24eeae7b4c7", "blockHash": "0xa7a92cc82e1d876476ad6433538599b0d592f88ba0823c23e80af93fb1748f14",
"blobGasUsed": "0x0", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" "blobGasUsed": "0x0"
}, },
"blockValue": "0x0", "blockValue": "0x0",
"blobsBundle": { "blobsBundle": {

@ -4,7 +4,7 @@
"method": "engine_newPayloadV4", "method": "engine_newPayloadV4",
"params": [ "params": [
{ {
"parentHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356", "parentHash": "0xa7a92cc82e1d876476ad6433538599b0d592f88ba0823c23e80af93fb1748f14",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x9b8c4a9a86cb49252075c0db2f0e72fb1e49350a0f70ea36f26f700201961e62", "stateRoot": "0x9b8c4a9a86cb49252075c0db2f0e72fb1e49350a0f70ea36f26f700201961e62",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
@ -17,9 +17,9 @@
"excessBlobGas": "0x0", "excessBlobGas": "0x0",
"transactions": [], "transactions": [],
"withdrawals": [], "withdrawals": [],
"depositRequests" : null, "depositRequests": null,
"blockNumber": "0x2", "blockNumber": "0x2",
"blockHash": "0xf6c3f1180ba58d6ea4c69c9328c7afb1fda41df06c368741c1f8310567879de7", "blockHash": "0x2331b2dc9c453e9a33685099742cbbcd529d42bd5681969f45754f06866c6766",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"blobGasUsed": "0x0" "blobGasUsed": "0x0"
}, },
@ -34,7 +34,7 @@
"error": { "error": {
"code": -32602, "code": -32602,
"message": "Invalid params", "message": "Invalid params",
"data" : "Missing deposit field" "data": "Missing deposit field"
} }
}, },
"statusCode": 200 "statusCode": 200

@ -6,7 +6,7 @@
{ {
"parentHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", "parentHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x778ccbc3adc59876b76489cdc1a2ff76ef2a31ae9d3bf761bc55bbab7d59c489", "stateRoot": "0xdb2a9bb9097dd6946525203a14437cd925ef549289e1fe17c6ed845c53647a26",
"logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000", "logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380", "gasLimit": "0x1c9c380",
@ -31,12 +31,12 @@
"withdrawalRequests": [ "withdrawalRequests": [
{ {
"sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb", "sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb",
"amount" : "0x0", "amount": "0x0",
"validatorPublicKey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e" "validatorPublicKey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"
} }
], ],
"blockNumber": "0x2", "blockNumber": "0x2",
"blockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "blockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
"receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9", "receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9",
"blobGasUsed": "0x0" "blobGasUsed": "0x0"
}, },
@ -50,7 +50,7 @@
"id": 67, "id": 67,
"result": { "result": {
"status": "VALID", "status": "VALID",
"latestValidHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "latestValidHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
"validationError": null "validationError": null
} }
}, },

@ -4,9 +4,9 @@
"method": "engine_forkchoiceUpdatedV3", "method": "engine_forkchoiceUpdatedV3",
"params": [ "params": [
{ {
"headBlockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "headBlockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
"safeBlockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "safeBlockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
"finalizedBlockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852" "finalizedBlockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d"
}, },
{ {
"timestamp": "0x30", "timestamp": "0x30",
@ -24,11 +24,11 @@
"result": { "result": {
"payloadStatus": { "payloadStatus": {
"status": "VALID", "status": "VALID",
"latestValidHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "latestValidHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
"validationError": null "validationError": null
}, },
"payloadId": "0x282643ead6ad5331" "payloadId": "0x282643e2da21a7cf"
} }
}, },
"statusCode" : 200 "statusCode": 200
} }

@ -3,7 +3,7 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "engine_getPayloadV4", "method": "engine_getPayloadV4",
"params": [ "params": [
"0x282643ead6ad5331" "0x282643e2da21a7cf"
], ],
"id": 67 "id": 67
}, },
@ -12,9 +12,9 @@
"id": 67, "id": 67,
"result": { "result": {
"executionPayload": { "executionPayload": {
"parentHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "parentHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x61d2011dc13b003c48193f0902653fd4f7b67fa949dc0fa6eab9e69e349700fd", "stateRoot": "0xcd9f15de5f17cf87a02bf795a0dc98c108eead4651eca57fc7195bda0d9c20ee",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380", "gasLimit": "0x1c9c380",
@ -29,7 +29,7 @@
"depositRequests": [], "depositRequests": [],
"withdrawalRequests": [], "withdrawalRequests": [],
"blockNumber": "0x3", "blockNumber": "0x3",
"blockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "blockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"blobGasUsed": "0x0" "blobGasUsed": "0x0"
}, },

@ -4,9 +4,9 @@
"method": "engine_newPayloadV3", "method": "engine_newPayloadV3",
"params": [ "params": [
{ {
"parentHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "parentHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x61d2011dc13b003c48193f0902653fd4f7b67fa949dc0fa6eab9e69e349700fd", "stateRoot": "0xcd9f15de5f17cf87a02bf795a0dc98c108eead4651eca57fc7195bda0d9c20ee",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380", "gasLimit": "0x1c9c380",
@ -19,7 +19,7 @@
"depositRequests": [], "depositRequests": [],
"withdrawalRequests": [], "withdrawalRequests": [],
"blockNumber": "0x3", "blockNumber": "0x3",
"blockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "blockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"excessBlobGas": "0x0", "excessBlobGas": "0x0",
"blobGasUsed": "0x0" "blobGasUsed": "0x0"
@ -34,7 +34,7 @@
"id": 67, "id": 67,
"result": { "result": {
"status": "VALID", "status": "VALID",
"latestValidHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "latestValidHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
"validationError": null "validationError": null
} }
}, },

@ -4,9 +4,9 @@
"method": "engine_forkchoiceUpdatedV3", "method": "engine_forkchoiceUpdatedV3",
"params": [ "params": [
{ {
"headBlockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "headBlockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
"safeBlockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "safeBlockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
"finalizedBlockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9" "finalizedBlockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42"
}, },
{ {
"timestamp": "0x40", "timestamp": "0x40",
@ -24,11 +24,11 @@
"result": { "result": {
"payloadStatus": { "payloadStatus": {
"status": "VALID", "status": "VALID",
"latestValidHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "latestValidHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
"validationError": null "validationError": null
}, },
"payloadId": "0x2826438a3f8a7741" "payloadId": "0x282643de0e3d43bf"
} }
}, },
"statusCode" : 200 "statusCode": 200
} }

@ -3,7 +3,7 @@
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "engine_getPayloadV4", "method": "engine_getPayloadV4",
"params": [ "params": [
"0x2826438a3f8a7741" "0x282643de0e3d43bf"
], ],
"id": 67 "id": 67
}, },
@ -12,9 +12,9 @@
"id": 67, "id": 67,
"result": { "result": {
"executionPayload": { "executionPayload": {
"parentHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "parentHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x847db08c6b9e6dcc91288bd963eb5623aea5387232016ef81fddb3ebc994c72f", "stateRoot": "0xe4642cc58d61f2392fe056042c226e286f22a25e3104f4a4acb423dad9a43311",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380", "gasLimit": "0x1c9c380",
@ -37,9 +37,9 @@
} }
], ],
"blockNumber": "0x4", "blockNumber": "0x4",
"blobGasUsed": "0x0",
"receiptsRoot": "0x765bd9d63cc10fa47117d6cc0958f15e55a3bde540d4ed15d220f573fbb82cba", "receiptsRoot": "0x765bd9d63cc10fa47117d6cc0958f15e55a3bde540d4ed15d220f573fbb82cba",
"blockHash": "0xd0b81acdb3016abbc05599b083c8b090323efaf0b2aeab8d0755780e20214159" "blobGasUsed": "0x0",
"blockHash": "0xb2d60adb2a0c73313ebdacf425b1d6bbd810c3ec6b28ad0d62a73cdc34cb696a"
}, },
"blockValue": "0x12855dcd153473b", "blockValue": "0x12855dcd153473b",
"blobsBundle": { "blobsBundle": {

@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.Unstable; import org.hyperledger.besu.plugin.Unstable;
import org.hyperledger.besu.plugin.data.BlockTraceResult; import org.hyperledger.besu.plugin.data.BlockTraceResult;
@ -216,7 +217,7 @@ public class TraceServiceImpl implements TraceService {
transaction, transaction,
protocolSpec.getMiningBeneficiaryCalculator().calculateBeneficiary(header), protocolSpec.getMiningBeneficiaryCalculator().calculateBeneficiary(header),
tracer, tracer,
protocolSpec.getBlockHashProcessor().getBlockHashLookup(header, blockchain), new CachingBlockHashLookup(header, blockchain),
false, false,
blobGasPrice); blobGasPrice);

@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods; package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator.calculateExcessBlobGasForParent; import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator.calculateExcessBlobGasForParent;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.datatypes.BlobGas; import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
@ -27,7 +26,9 @@ import org.hyperledger.besu.ethereum.debug.TraceFrame;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -94,8 +95,7 @@ public class ExecuteTransactionStep implements Function<TransactionTrace, Transa
maybeParentHeader maybeParentHeader
.map(parent -> calculateExcessBlobGasForParent(protocolSpec, parent)) .map(parent -> calculateExcessBlobGasForParent(protocolSpec, parent))
.orElse(BlobGas.ZERO)); .orElse(BlobGas.ZERO));
final BlockHashLookup blockHashLookup = final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(header, blockchain);
protocolSpec.getBlockHashProcessor().getBlockHashLookup(header, blockchain);
result = result =
transactionProcessor.processTransaction( transactionProcessor.processTransaction(
chainUpdater.getNextUpdater(), chainUpdater.getNextUpdater(),

@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor; package org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor;
import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator.calculateExcessBlobGasForParent; import static org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator.calculateExcessBlobGasForParent;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.datatypes.BlobGas; import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
@ -31,6 +30,8 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -89,8 +90,7 @@ public class BlockReplay {
return performActionWithBlock( return performActionWithBlock(
blockHash, blockHash,
(body, header, blockchain, transactionProcessor, protocolSpec) -> { (body, header, blockchain, transactionProcessor, protocolSpec) -> {
final BlockHashLookup blockHashLookup = final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(header, blockchain);
protocolSpec.getBlockHashProcessor().getBlockHashLookup(header, blockchain);
final Wei blobGasPrice = final Wei blobGasPrice =
protocolSpec protocolSpec
.getFeeMarket() .getFeeMarket()
@ -137,7 +137,7 @@ public class BlockReplay {
blockHeader, blockHeader,
transaction, transaction,
spec.getMiningBeneficiaryCalculator().calculateBeneficiary(blockHeader), spec.getMiningBeneficiaryCalculator().calculateBeneficiary(blockHeader),
spec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain), new CachingBlockHashLookup(blockHeader, blockchain),
false, false,
TransactionValidationParams.blockReplay(), TransactionValidationParams.blockReplay(),
blobGasPrice); blobGasPrice);
@ -180,10 +180,6 @@ public class BlockReplay {
return Optional.empty(); return Optional.empty();
} }
public ProtocolSpec getProtocolSpec(final BlockHeader header) {
return protocolSchedule.getByBlockHeader(header);
}
@FunctionalInterface @FunctionalInterface
public interface BlockAction<T> { public interface BlockAction<T> {
Optional<T> perform( Optional<T> perform(

@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.debug.TraceFrame; import org.hyperledger.besu.ethereum.debug.TraceFrame;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
@ -68,10 +69,7 @@ public class BlockTracer {
transaction, transaction,
header.getCoinbase(), header.getCoinbase(),
tracer, tracer,
blockReplay new CachingBlockHashLookup(header, blockchain),
.getProtocolSpec(header)
.getBlockHashProcessor()
.getBlockHashLookup(header, blockchain),
false, false,
blobGasPrice); blobGasPrice);
final List<TraceFrame> traceFrames = tracer.copyTraceFrames(); final List<TraceFrame> traceFrames = tracer.copyTraceFrames();

@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.debug.TraceOptions;
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams; import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.tracing.StandardJsonTracer; import org.hyperledger.besu.evm.tracing.StandardJsonTracer;
@ -191,10 +192,7 @@ public class TransactionTracer {
transaction, transaction,
header.getCoinbase(), header.getCoinbase(),
tracer, tracer,
blockReplay new CachingBlockHashLookup(header, blockchain),
.getProtocolSpec(header)
.getBlockHashProcessor()
.getBlockHashLookup(header, blockchain),
false, false,
ImmutableTransactionValidationParams.builder().isAllowFutureNonce(true).build(), ImmutableTransactionValidationParams.builder().isAllowFutureNonce(true).build(),
blobGasPrice); blobGasPrice);

@ -36,7 +36,6 @@ import org.hyperledger.besu.ethereum.debug.TraceFrame;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
@ -88,7 +87,6 @@ public class TransactionTracerTest {
@Mock private ProtocolSpec protocolSpec; @Mock private ProtocolSpec protocolSpec;
@Mock private GasCalculator gasCalculator; @Mock private GasCalculator gasCalculator;
@Mock private BlockHashProcessor blockHashProcessor;
@Mock private Tracer.TraceableState mutableWorldState; @Mock private Tracer.TraceableState mutableWorldState;
@ -125,7 +123,6 @@ public class TransactionTracerTest {
when(protocolSpec.getFeeMarket()).thenReturn(FeeMarket.london(0L)); when(protocolSpec.getFeeMarket()).thenReturn(FeeMarket.london(0L));
when(blockchain.getChainHeadHeader()).thenReturn(blockHeader); when(blockchain.getChainHeadHeader()).thenReturn(blockHeader);
when(protocolSpec.getGasCalculator()).thenReturn(gasCalculator); when(protocolSpec.getGasCalculator()).thenReturn(gasCalculator);
when(protocolSpec.getBlockHashProcessor()).thenReturn(blockHashProcessor);
when(protocolContext.getBadBlockManager()).thenReturn(badBlockManager); when(protocolContext.getBadBlockManager()).thenReturn(badBlockManager);
lenient().when(gasCalculator.computeExcessBlobGas(anyLong(), anyInt())).thenReturn(0L); lenient().when(gasCalculator.computeExcessBlobGas(anyLong(), anyInt())).thenReturn(0L);
} }

@ -14,7 +14,6 @@
*/ */
package org.hyperledger.besu.ethereum.blockcreation.txselection; package org.hyperledger.besu.ethereum.blockcreation.txselection;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.BLOCK_SELECTION_TIMEOUT; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.BLOCK_SELECTION_TIMEOUT;
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.SELECTED; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.SELECTED;
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.TX_EVALUATION_TOO_LONG; import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.TX_EVALUATION_TOO_LONG;
@ -43,7 +42,9 @@ import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor; import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.data.TransactionSelectionResult; import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer; import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer;
@ -326,9 +327,7 @@ public class BlockTransactionSelector {
private TransactionProcessingResult processTransaction( private TransactionProcessingResult processTransaction(
final PendingTransaction pendingTransaction, final WorldUpdater worldStateUpdater) { final PendingTransaction pendingTransaction, final WorldUpdater worldStateUpdater) {
final BlockHashLookup blockHashLookup = final BlockHashLookup blockHashLookup =
blockSelectionContext new CachingBlockHashLookup(blockSelectionContext.processableBlockHeader(), blockchain);
.blockHashProcessor()
.getBlockHashLookup(blockSelectionContext.processableBlockHeader(), blockchain);
return transactionProcessor.processTransaction( return transactionProcessor.processTransaction(
worldStateUpdater, worldStateUpdater,
blockSelectionContext.processableBlockHeader(), blockSelectionContext.processableBlockHeader(),

@ -16,7 +16,6 @@ package org.hyperledger.besu.ethereum.mainnet.precompiles.privacy;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable; import static org.assertj.core.api.Assertions.catchThrowable;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
@ -47,6 +46,7 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator;
import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.evm.precompile.PrecompiledContract; import org.hyperledger.besu.evm.precompile.PrecompiledContract;
import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;

@ -33,7 +33,6 @@ import org.hyperledger.besu.ethereum.debug.TraceFrame;
import org.hyperledger.besu.ethereum.debug.TraceOptions; import org.hyperledger.besu.ethereum.debug.TraceOptions;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
@ -74,13 +73,11 @@ public class TraceTransactionIntegrationTest {
blockchain = contextTestFixture.getBlockchain(); blockchain = contextTestFixture.getBlockchain();
worldStateArchive = contextTestFixture.getStateArchive(); worldStateArchive = contextTestFixture.getStateArchive();
final ProtocolSchedule protocolSchedule = contextTestFixture.getProtocolSchedule(); final ProtocolSchedule protocolSchedule = contextTestFixture.getProtocolSchedule();
ProtocolSpec protocolSpec = transactionProcessor =
protocolSchedule.getByBlockHeader(new BlockHeaderTestFixture().number(0L).buildHeader()); protocolSchedule
transactionProcessor = protocolSpec.getTransactionProcessor(); .getByBlockHeader(new BlockHeaderTestFixture().number(0L).buildHeader())
blockHashLookup = .getTransactionProcessor();
protocolSpec blockHashLookup = new CachingBlockHashLookup(genesisBlock.getHeader(), blockchain);
.getBlockHashProcessor()
.getBlockHashLookup(genesisBlock.getHeader(), blockchain);
} }
@Test @Test

@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.hyperledger.besu.ethereum.trie.MerkleTrieException;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldStateUpdateAccumulator; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldStateUpdateAccumulator;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator;
import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.worldstate.WorldState; import org.hyperledger.besu.evm.worldstate.WorldState;
@ -114,8 +115,7 @@ public abstract class AbstractBlockProcessor implements BlockProcessor {
final WorldUpdater worldStateUpdater = worldState.updater(); final WorldUpdater worldStateUpdater = worldState.updater();
final BlockHashLookup blockHashLookup = final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(blockHeader, blockchain);
protocolSpec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain);
final Address miningBeneficiary = final Address miningBeneficiary =
miningBeneficiaryCalculator.calculateBeneficiary(blockHeader); miningBeneficiaryCalculator.calculateBeneficiary(blockHeader);

@ -183,7 +183,6 @@ public class ClassicProtocolSpecs {
messageCallProcessor, messageCallProcessor,
true, true,
false, false,
false,
stackSizeLimit, stackSizeLimit,
feeMarket, feeMarket,
CoinbaseFeePriceCalculator.frontier())) CoinbaseFeePriceCalculator.frontier()))
@ -373,7 +372,6 @@ public class ClassicProtocolSpecs {
messageCallProcessor, messageCallProcessor,
true, true,
true, true,
false,
stackSizeLimit, stackSizeLimit,
feeMarket, feeMarket,
CoinbaseFeePriceCalculator.frontier())) CoinbaseFeePriceCalculator.frontier()))

@ -143,7 +143,6 @@ public abstract class MainnetProtocolSpecs {
messageCallProcessor, messageCallProcessor,
false, false,
false, false,
false,
stackSizeLimit, stackSizeLimit,
FeeMarket.legacy(), FeeMarket.legacy(),
CoinbaseFeePriceCalculator.frontier())) CoinbaseFeePriceCalculator.frontier()))
@ -298,7 +297,6 @@ public abstract class MainnetProtocolSpecs {
messageCallProcessor, messageCallProcessor,
true, true,
false, false,
false,
stackSizeLimit, stackSizeLimit,
feeMarket, feeMarket,
CoinbaseFeePriceCalculator.frontier())) CoinbaseFeePriceCalculator.frontier()))
@ -492,7 +490,6 @@ public abstract class MainnetProtocolSpecs {
messageCallProcessor, messageCallProcessor,
true, true,
false, false,
false,
stackSizeLimit, stackSizeLimit,
feeMarket, feeMarket,
CoinbaseFeePriceCalculator.eip1559())) CoinbaseFeePriceCalculator.eip1559()))
@ -630,7 +627,6 @@ public abstract class MainnetProtocolSpecs {
messageCallProcessor, messageCallProcessor,
true, true,
true, true,
false,
stackSizeLimit, stackSizeLimit,
feeMarket, feeMarket,
CoinbaseFeePriceCalculator.eip1559())) CoinbaseFeePriceCalculator.eip1559()))
@ -707,7 +703,6 @@ public abstract class MainnetProtocolSpecs {
messageCallProcessor, messageCallProcessor,
true, true,
true, true,
false,
stackSizeLimit, stackSizeLimit,
feeMarket, feeMarket,
CoinbaseFeePriceCalculator.eip1559())) CoinbaseFeePriceCalculator.eip1559()))
@ -786,7 +781,6 @@ public abstract class MainnetProtocolSpecs {
messageCallProcessor, messageCallProcessor,
true, true,
true, true,
true,
stackSizeLimit, stackSizeLimit,
feeMarket, feeMarket,
CoinbaseFeePriceCalculator.eip1559())) CoinbaseFeePriceCalculator.eip1559()))
@ -795,8 +789,7 @@ public abstract class MainnetProtocolSpecs {
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::prague) .precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::prague)
.requestsValidator(pragueRequestsValidator(depositContractAddress)) .requestsValidator(pragueRequestsValidator(depositContractAddress))
.requestProcessorCoordinator(pragueRequestsProcessors(depositContractAddress)) .requestProcessorCoordinator(pragueRequestsProcessors(depositContractAddress))
.blockHashProcessor( .blockHashProcessor(new PragueBlockHashProcessor())
new PragueBlockHashProcessor(genesisConfigOptions.getPragueTime().orElse(0)))
.name("Prague"); .name("Prague");
} }

@ -27,7 +27,6 @@ import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.feemarket.CoinbaseFeePriceCalculator; import org.hyperledger.besu.ethereum.core.feemarket.CoinbaseFeePriceCalculator;
import org.hyperledger.besu.ethereum.mainnet.blockhash.PragueBlockHashProcessor;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
@ -53,7 +52,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.units.bigints.UInt256;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -74,7 +72,6 @@ public class MainnetTransactionProcessor {
private final boolean clearEmptyAccounts; private final boolean clearEmptyAccounts;
protected final boolean warmCoinbase; protected final boolean warmCoinbase;
protected final boolean warmBlockhash;
protected final FeeMarket feeMarket; protected final FeeMarket feeMarket;
private final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator; private final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator;
@ -86,7 +83,6 @@ public class MainnetTransactionProcessor {
final AbstractMessageProcessor messageCallProcessor, final AbstractMessageProcessor messageCallProcessor,
final boolean clearEmptyAccounts, final boolean clearEmptyAccounts,
final boolean warmCoinbase, final boolean warmCoinbase,
final boolean warmBlockhash,
final int maxStackSize, final int maxStackSize,
final FeeMarket feeMarket, final FeeMarket feeMarket,
final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator) { final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator) {
@ -96,7 +92,6 @@ public class MainnetTransactionProcessor {
this.messageCallProcessor = messageCallProcessor; this.messageCallProcessor = messageCallProcessor;
this.clearEmptyAccounts = clearEmptyAccounts; this.clearEmptyAccounts = clearEmptyAccounts;
this.warmCoinbase = warmCoinbase; this.warmCoinbase = warmCoinbase;
this.warmBlockhash = warmBlockhash;
this.maxStackSize = maxStackSize; this.maxStackSize = maxStackSize;
this.feeMarket = feeMarket; this.feeMarket = feeMarket;
this.coinbaseFeePriceCalculator = coinbaseFeePriceCalculator; this.coinbaseFeePriceCalculator = coinbaseFeePriceCalculator;
@ -327,15 +322,6 @@ public class MainnetTransactionProcessor {
if (warmCoinbase) { if (warmCoinbase) {
addressList.add(miningBeneficiary); addressList.add(miningBeneficiary);
} }
if (warmBlockhash) {
addressList.add(PragueBlockHashProcessor.HISTORY_STORAGE_ADDRESS);
storageList.putAll(
PragueBlockHashProcessor.HISTORY_STORAGE_ADDRESS,
List.of(
UInt256.valueOf(
(blockHeader.getNumber() - 1)
% PragueBlockHashProcessor.HISTORY_SERVE_WINDOW)));
}
final long intrinsicGas = final long intrinsicGas =
gasCalculator.transactionIntrinsicGasCost( gasCalculator.transactionIntrinsicGasCost(

@ -14,8 +14,6 @@
*/ */
package org.hyperledger.besu.ethereum.mainnet.blockhash; package org.hyperledger.besu.ethereum.mainnet.blockhash;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;
@ -26,6 +24,4 @@ public interface BlockHashProcessor {
Blockchain blockchain, Blockchain blockchain,
MutableWorldState worldState, MutableWorldState worldState,
ProcessableBlockHeader currentBlockHeader); ProcessableBlockHeader currentBlockHeader);
BlockHashLookup getBlockHashLookup(ProcessableBlockHeader currentHeader, Blockchain blockchain);
} }

@ -14,24 +14,15 @@
*/ */
package org.hyperledger.besu.ethereum.mainnet.blockhash; package org.hyperledger.besu.ethereum.mainnet.blockhash;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.mainnet.ParentBeaconBlockRootHelper; import org.hyperledger.besu.ethereum.mainnet.ParentBeaconBlockRootHelper;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;
/** Processes the beacon block storage if it is present in the block header. */ /** Processes the beacon block storage if it is present in the block header. */
public class CancunBlockHashProcessor implements BlockHashProcessor { public class CancunBlockHashProcessor implements BlockHashProcessor {
@Override
public BlockHashLookup getBlockHashLookup(
final ProcessableBlockHeader currentHeader, final Blockchain blockchain) {
return new CachingBlockHashLookup(currentHeader, blockchain);
}
@Override @Override
public void processBlockHashes( public void processBlockHashes(
final Blockchain blockchain, final Blockchain blockchain,

@ -14,11 +14,8 @@
*/ */
package org.hyperledger.besu.ethereum.mainnet.blockhash; package org.hyperledger.besu.ethereum.mainnet.blockhash;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;
public class FrontierBlockHashProcessor implements BlockHashProcessor { public class FrontierBlockHashProcessor implements BlockHashProcessor {
@ -29,10 +26,4 @@ public class FrontierBlockHashProcessor implements BlockHashProcessor {
final ProcessableBlockHeader currentBlockHeader) { final ProcessableBlockHeader currentBlockHeader) {
// do nothing // do nothing
} }
@Override
public BlockHashLookup getBlockHashLookup(
final ProcessableBlockHeader currentHeader, final Blockchain blockchain) {
return new CachingBlockHashLookup(currentHeader, blockchain);
}
} }

@ -14,12 +14,9 @@
*/ */
package org.hyperledger.besu.ethereum.mainnet.blockhash; package org.hyperledger.besu.ethereum.mainnet.blockhash;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
@ -44,53 +41,28 @@ public class PragueBlockHashProcessor extends CancunBlockHashProcessor {
/** The HISTORY_SERVE_WINDOW */ /** The HISTORY_SERVE_WINDOW */
public static final long HISTORY_SERVE_WINDOW = 8192; public static final long HISTORY_SERVE_WINDOW = 8192;
private final long forkTimestamp;
private final long historySaveWindow; private final long historySaveWindow;
private final Address historyStorageAddress; private final Address historyStorageAddress;
/** /** Constructs a BlockHashProcessor. */
* Constructs a BlockHashProcessor with a specified fork timestamp. public PragueBlockHashProcessor() {
* this(HISTORY_STORAGE_ADDRESS, HISTORY_SERVE_WINDOW);
* @param forkTimestamp The timestamp at which the fork becomes active.
*/
public PragueBlockHashProcessor(final long forkTimestamp) {
this(forkTimestamp, HISTORY_STORAGE_ADDRESS, HISTORY_SERVE_WINDOW);
} }
/** /**
* Constructs a BlockHashProcessor with a specified fork timestamp and history save window. This * Constructs a BlockHashProcessor with a specified history save window. This constructor is
* constructor is primarily used for testing. * primarily used for testing.
* *
* @param forkTimestamp The timestamp at which the fork becomes active.
* @param historyStorageAddress the address of the contract storing the history * @param historyStorageAddress the address of the contract storing the history
* @param historySaveWindow The number of blocks for which history should be saved. * @param historySaveWindow The number of blocks for which history should be saved.
*/ */
@VisibleForTesting @VisibleForTesting
public PragueBlockHashProcessor( public PragueBlockHashProcessor(
final long forkTimestamp, final Address historyStorageAddress, final long historySaveWindow) { final Address historyStorageAddress, final long historySaveWindow) {
this.forkTimestamp = forkTimestamp;
this.historyStorageAddress = historyStorageAddress; this.historyStorageAddress = historyStorageAddress;
this.historySaveWindow = historySaveWindow; this.historySaveWindow = historySaveWindow;
} }
@Override
public BlockHashLookup getBlockHashLookup(
final ProcessableBlockHeader currentHeader, final Blockchain blockchain) {
return (frame, blockNumber) -> {
long currentBlockNumber = frame.getBlockValues().getNumber();
if (currentBlockNumber <= blockNumber
|| currentBlockNumber - blockNumber > historySaveWindow
|| blockNumber < 0) {
return Hash.ZERO;
}
return Hash.wrap(
frame
.getWorldUpdater()
.get(historyStorageAddress)
.getStorageValue(UInt256.valueOf(blockNumber % historySaveWindow)));
};
}
@Override @Override
public void processBlockHashes( public void processBlockHashes(
final Blockchain blockchain, final Blockchain blockchain,
@ -99,21 +71,10 @@ public class PragueBlockHashProcessor extends CancunBlockHashProcessor {
super.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader); super.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader);
WorldUpdater worldUpdater = mutableWorldState.updater(); WorldUpdater worldUpdater = mutableWorldState.updater();
final MutableAccount historyStorageAccount = worldUpdater.getOrCreate(HISTORY_STORAGE_ADDRESS); final MutableAccount historyStorageAccount = worldUpdater.getOrCreate(historyStorageAddress);
if (currentBlockHeader.getNumber() > 0) { if (currentBlockHeader.getNumber() > 0) {
storeParentHash(historyStorageAccount, currentBlockHeader); storeParentHash(historyStorageAccount, currentBlockHeader);
BlockHeader ancestor =
blockchain.getBlockHeader(currentBlockHeader.getParentHash()).orElseThrow();
// If fork block, add the parent's direct `HISTORY_SERVE_WINDOW - 1`
if (ancestor.getTimestamp() < forkTimestamp) {
for (int i = 0; i < (historySaveWindow - 1) && ancestor.getNumber() > 0; i++) {
ancestor = blockchain.getBlockHeader(ancestor.getParentHash()).orElseThrow();
storeBlockHeaderHash(historyStorageAccount, ancestor);
}
}
} }
worldUpdater.commit(); worldUpdater.commit();
} }
@ -128,16 +89,6 @@ public class PragueBlockHashProcessor extends CancunBlockHashProcessor {
storeHash(account, header.getNumber() - 1, header.getParentHash()); storeHash(account, header.getNumber() - 1, header.getParentHash());
} }
/**
* Stores the hash of a block in the world state.
*
* @param account The account associated with the historical block hash storage.
* @param header The block header whose hash is to be stored.
*/
private void storeBlockHeaderHash(final MutableAccount account, final BlockHeader header) {
storeHash(account, header.getNumber(), header.getHash());
}
/** /**
* Stores the hash in the world state. * Stores the hash in the world state.
* *
@ -146,11 +97,10 @@ public class PragueBlockHashProcessor extends CancunBlockHashProcessor {
* @param hash The hash to be stored. * @param hash The hash to be stored.
*/ */
private void storeHash(final MutableAccount account, final long number, final Hash hash) { private void storeHash(final MutableAccount account, final long number, final Hash hash) {
UInt256 slot = UInt256.valueOf(number % historySaveWindow);
UInt256 value = UInt256.fromBytes(hash);
LOG.trace( LOG.trace(
"Writing to {} {}=%{}", "Writing to {} {}=%{}", account.getAddress(), slot.toDecimalString(), value.toHexString());
account.getAddress(), account.setStorageValue(slot, value);
UInt256.valueOf(number % historySaveWindow).toDecimalString(),
UInt256.fromBytes(hash).toHexString());
account.setStorageValue(UInt256.valueOf(number % historySaveWindow), UInt256.fromBytes(hash));
} }
} }

@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap; import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -166,7 +167,7 @@ public class PrivateStateRehydration {
privateStateStorage, privateStateStorage,
privateStateRootResolver, privateStateRootResolver,
block, block,
protocolSpec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain), new CachingBlockHashLookup(blockHeader, blockchain),
pmtHashToPrivateTransactionMap, pmtHashToPrivateTransactionMap,
block.getBody().getOmmers()); block.getBody().getOmmers());

@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.transaction.CallParameter; import org.hyperledger.besu.ethereum.transaction.CallParameter;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.tracing.OperationTracer;
@ -139,7 +140,7 @@ public class PrivateTransactionSimulator {
transaction, transaction,
protocolSpec.getMiningBeneficiaryCalculator().calculateBeneficiary(header), protocolSpec.getMiningBeneficiaryCalculator().calculateBeneficiary(header),
OperationTracer.NO_TRACING, OperationTracer.NO_TRACING,
protocolSpec.getBlockHashProcessor().getBlockHashLookup(header, blockchain), new CachingBlockHashLookup(header, blockchain),
privacyGroupId); privacyGroupId);
return Optional.of(result); return Optional.of(result);

@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver;
import org.hyperledger.besu.ethereum.privacy.storage.LegacyPrivateStateStorage; import org.hyperledger.besu.ethereum.privacy.storage.LegacyPrivateStateStorage;
import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap; import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import java.util.List; import java.util.List;
@ -112,7 +113,7 @@ public class PrivateStorageMigration {
privateMigrationBlockProcessor.processBlock( privateMigrationBlockProcessor.processBlock(
blockchain, blockchain,
publicWorldState, publicWorldState,
protocolSpec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain), new CachingBlockHashLookup(blockHeader, blockchain),
blockHeader, blockHeader,
transactionsToProcess, transactionsToProcess,
ommers); ommers);

@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer; import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
@ -279,9 +280,7 @@ public class TransactionSimulator {
protocolSpec protocolSpec
.getMiningBeneficiaryCalculator() .getMiningBeneficiaryCalculator()
.calculateBeneficiary(blockHeaderToProcess), .calculateBeneficiary(blockHeaderToProcess),
protocolSpec new CachingBlockHashLookup(blockHeaderToProcess, blockchain),
.getBlockHashProcessor()
.getBlockHashLookup(blockHeaderToProcess, blockchain),
false, false,
transactionValidationParams, transactionValidationParams,
operationTracer, operationTracer,

@ -15,13 +15,12 @@
package org.hyperledger.besu.ethereum.vm; package org.hyperledger.besu.ethereum.vm;
import static org.hyperledger.besu.datatypes.Hash.ZERO; import static org.hyperledger.besu.datatypes.Hash.ZERO;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import org.hyperledger.besu.evm.operation.BlockHashOperation; import org.hyperledger.besu.evm.operation.BlockHashOperation;
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -38,32 +37,17 @@ public class CachingBlockHashLookup implements BlockHashLookup {
private ProcessableBlockHeader searchStartHeader; private ProcessableBlockHeader searchStartHeader;
private final Blockchain blockchain; private final Blockchain blockchain;
private final long maxLookback;
private final Map<Long, Hash> hashByNumber = new HashMap<>(); private final Map<Long, Hash> hashByNumber = new HashMap<>();
public CachingBlockHashLookup( public CachingBlockHashLookup(
final ProcessableBlockHeader currentBlock, final Blockchain blockchain) { final ProcessableBlockHeader currentBlock, final Blockchain blockchain) {
this(currentBlock, blockchain, BlockHashOperation.MAX_RELATIVE_BLOCK);
}
public CachingBlockHashLookup(
final ProcessableBlockHeader currentBlock,
final Blockchain blockchain,
final int maxLookback) {
this.searchStartHeader = currentBlock; this.searchStartHeader = currentBlock;
this.blockchain = blockchain; this.blockchain = blockchain;
this.maxLookback = maxLookback;
hashByNumber.put(currentBlock.getNumber() - 1, currentBlock.getParentHash()); hashByNumber.put(currentBlock.getNumber() - 1, currentBlock.getParentHash());
} }
@Override @Override
public Hash apply(final MessageFrame frame, final Long blockNumber) { public Hash apply(final Long blockNumber) {
long currentBlockNumber = frame.getBlockValues().getNumber();
long lookback = currentBlockNumber - blockNumber;
if (currentBlockNumber <= blockNumber || lookback > maxLookback) {
return Hash.ZERO;
}
final Hash cachedHash = hashByNumber.get(blockNumber); final Hash cachedHash = hashByNumber.get(blockNumber);
if (cachedHash != null) { if (cachedHash != null) {
return cachedHash; return cachedHash;

@ -84,7 +84,6 @@ class MainnetTransactionProcessorTest {
messageCallProcessor, messageCallProcessor,
false, false,
warmCoinbase, warmCoinbase,
false,
MAX_STACK_SIZE, MAX_STACK_SIZE,
FeeMarket.legacy(), FeeMarket.legacy(),
CoinbaseFeePriceCalculator.frontier()); CoinbaseFeePriceCalculator.frontier());

@ -34,7 +34,6 @@ import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.PrivateTransactionDataFixture; import org.hyperledger.besu.ethereum.core.PrivateTransactionDataFixture;
import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor;
import org.hyperledger.besu.ethereum.privacy.PrivateStateGenesisAllocator; import org.hyperledger.besu.ethereum.privacy.PrivateStateGenesisAllocator;
import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor;
@ -222,8 +221,6 @@ class PrivacyBlockProcessorTest {
when(protocolSpec.getMiningBeneficiaryCalculator()) when(protocolSpec.getMiningBeneficiaryCalculator())
.thenReturn(mock(MiningBeneficiaryCalculator.class)); .thenReturn(mock(MiningBeneficiaryCalculator.class));
when(protocolSpec.isSkipZeroBlockRewards()).thenReturn(true); when(protocolSpec.isSkipZeroBlockRewards()).thenReturn(true);
BlockHashProcessor blockHashProcessor = mock(BlockHashProcessor.class);
when(protocolSpec.getBlockHashProcessor()).thenReturn(blockHashProcessor);
return protocolSpec; return protocolSpec;
} }
} }

@ -42,7 +42,7 @@ class BlockHashProcessorTest {
private MutableAccount account; private MutableAccount account;
private BlockHashProcessor processor; private BlockHashProcessor processor;
private long historicalWindow = 8192; private final long historicalWindow = 255;
@BeforeEach @BeforeEach
void setUp() { void setUp() {
@ -57,9 +57,8 @@ class BlockHashProcessorTest {
@Test @Test
void shouldStoreParentBlockHash() { void shouldStoreParentBlockHash() {
long forkTimestamp = 0;
long currentBlock = 3; long currentBlock = 3;
processor = new PragueBlockHashProcessor(forkTimestamp); processor = new PragueBlockHashProcessor();
BlockHeader currentBlockHeader = mockBlockHeader(currentBlock); BlockHeader currentBlockHeader = mockBlockHeader(currentBlock);
mockAncestorHeaders(currentBlockHeader, 3); mockAncestorHeaders(currentBlockHeader, 3);
processor.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader); processor.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader);
@ -72,9 +71,8 @@ class BlockHashProcessorTest {
void shouldNotStoreBlockHashForGenesisBlock() { void shouldNotStoreBlockHashForGenesisBlock() {
// For the fork to be activated at genesis, no history is written to the genesis state, and at // For the fork to be activated at genesis, no history is written to the genesis state, and at
// the start of block 1, genesis hash will be written as a normal operation to slot 0. // the start of block 1, genesis hash will be written as a normal operation to slot 0.
long forkTimestamp = 0;
long currentBlock = 0; long currentBlock = 0;
processor = new PragueBlockHashProcessor(forkTimestamp); processor = new PragueBlockHashProcessor();
BlockHeader currentBlockHeader = mockBlockHeader(currentBlock); BlockHeader currentBlockHeader = mockBlockHeader(currentBlock);
mockAncestorHeaders(currentBlockHeader, 0); mockAncestorHeaders(currentBlockHeader, 0);
@ -86,9 +84,8 @@ class BlockHashProcessorTest {
void shouldStoreAncestorBlockHashesAtForkCorrectlyParentIsGenesis() { void shouldStoreAncestorBlockHashesAtForkCorrectlyParentIsGenesis() {
// for activation at block 1, only genesis hash will be written at slot 0 as there is no // for activation at block 1, only genesis hash will be written at slot 0 as there is no
// additional history that needs to be persisted. // additional history that needs to be persisted.
long forkTimestamp = 1;
long currentBlock = 1; long currentBlock = 1;
processor = new PragueBlockHashProcessor(forkTimestamp); processor = new PragueBlockHashProcessor();
BlockHeader currentBlockHeader = mockBlockHeader(currentBlock); BlockHeader currentBlockHeader = mockBlockHeader(currentBlock);
mockAncestorHeaders(currentBlockHeader, 10); mockAncestorHeaders(currentBlockHeader, 10);
@ -97,46 +94,9 @@ class BlockHashProcessorTest {
verifyAccount(0, historicalWindow); verifyAccount(0, historicalWindow);
} }
@Test
void shouldStoreAncestorBlockHashesAtForkCorrectly() {
// for activation at block 32, block 31’s hash will be written to slot 31 and additional history
// for 0..30’s hashes will be persisted, so all in all 0..31’s hashes.
long forkTimestamp = 32;
long currentBlock = 32;
processor = new PragueBlockHashProcessor(forkTimestamp);
BlockHeader currentBlockHeader = mockBlockHeader(currentBlock);
mockAncestorHeaders(currentBlockHeader, 32);
processor.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader);
verifyAncestor(currentBlock, 32, historicalWindow);
}
@Test
void shouldStoreAncestorBlockHashesAtForkCorrectlyMaxWindows() {
long forkTimestamp = 10000;
long currentBlock = 10000;
historicalWindow = 8192;
processor =
new PragueBlockHashProcessor(
forkTimestamp, PragueBlockHashProcessor.HISTORY_STORAGE_ADDRESS, historicalWindow);
BlockHeader currentBlockHeader = mockBlockHeader(currentBlock);
mockAncestorHeaders(currentBlockHeader, 10000);
processor.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader);
// Total of historicalWindow hashes were stored
verify(account, times((int) historicalWindow)).setStorageValue(any(), any());
// for activation at block 10000, block 1808-9999’s hashes will be presisted in the slot
verifyAccount(1808, historicalWindow);
verifyAccount(9999, historicalWindow);
// BLOCKHASH for 1807 or less would resolve to 0 as only HISTORY_SERVE_WINDOW are persisted.
verifyAccountNoIteraction(1807, historicalWindow);
verifyAccountNoIteraction(10000, historicalWindow);
}
@Test @Test
void shouldWriteGenesisHashAtSlot0() { void shouldWriteGenesisHashAtSlot0() {
processor = new PragueBlockHashProcessor(0); processor = new PragueBlockHashProcessor();
BlockHeader header = mockBlockHeader(1); BlockHeader header = mockBlockHeader(1);
mockAncestorHeaders(header, 1); mockAncestorHeaders(header, 1);
processor.processBlockHashes(blockchain, mutableWorldState, header); processor.processBlockHashes(blockchain, mutableWorldState, header);
@ -144,26 +104,11 @@ class BlockHashProcessorTest {
.setStorageValue(UInt256.valueOf(0), UInt256.fromHexString(Hash.ZERO.toHexString())); .setStorageValue(UInt256.valueOf(0), UInt256.fromHexString(Hash.ZERO.toHexString()));
} }
private void verifyAncestor(
final long blockNumber, final int count, final long historicalWindow) {
int totalTouchedSlots = (int) (blockNumber - count <= 0 ? blockNumber : count);
long firstAncestor = Math.max(blockNumber - count - 1, 0);
verify(account, times(totalTouchedSlots)).setStorageValue(any(), any());
for (long i = firstAncestor; i < blockNumber; i++) {
verifyAccount(i, historicalWindow);
}
}
private void verifyAccount(final long number, final long historicalWindow) { private void verifyAccount(final long number, final long historicalWindow) {
verify(account) verify(account)
.setStorageValue(UInt256.valueOf(number % historicalWindow), UInt256.valueOf(number)); .setStorageValue(UInt256.valueOf(number % historicalWindow), UInt256.valueOf(number));
} }
private void verifyAccountNoIteraction(final long number, final long historicalWindow) {
verify(account, times(0))
.setStorageValue(UInt256.valueOf(number % historicalWindow), UInt256.valueOf(number));
}
private void mockAncestorHeaders(final BlockHeader blockHeader, final int count) { private void mockAncestorHeaders(final BlockHeader blockHeader, final int count) {
long firstAncestor = Math.max(blockHeader.getNumber() - count, 0); long firstAncestor = Math.max(blockHeader.getNumber() - count, 0);
var block = blockHeader; var block = blockHeader;

@ -14,9 +14,8 @@
*/ */
package org.hyperledger.besu.ethereum.vm; package org.hyperledger.besu.ethereum.vm;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoInteractions;
@ -27,8 +26,7 @@ import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.evm.frame.BlockValues; import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.evm.frame.MessageFrame;
import java.util.Optional; import java.util.Optional;
@ -37,17 +35,13 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class CachingBlockHashLookupTest { class CachingBlockHashLookupTest {
@Mock private Blockchain blockchain; private static final int CURRENT_BLOCK_NUMBER = 256;
@Mock private MessageFrame messageFrame; private final Blockchain blockchain = mock(Blockchain.class);
@Mock private BlockValues blockValues;
private static final int CURRENT_BLOCK_NUMBER = 300;
private final BlockHeader[] headers = new BlockHeader[CURRENT_BLOCK_NUMBER]; private final BlockHeader[] headers = new BlockHeader[CURRENT_BLOCK_NUMBER];
private BlockHashLookup lookup; private BlockHashLookup lookup;
@ -56,13 +50,10 @@ class CachingBlockHashLookupTest {
BlockHeader parentHeader = null; BlockHeader parentHeader = null;
for (int i = 0; i < headers.length; i++) { for (int i = 0; i < headers.length; i++) {
final BlockHeader header = createHeader(i, parentHeader); final BlockHeader header = createHeader(i, parentHeader);
lenient().when(blockchain.getBlockHeader(header.getHash())).thenReturn(Optional.of(header)); when(blockchain.getBlockHeader(header.getHash())).thenReturn(Optional.of(header));
headers[i] = header; headers[i] = header;
parentHeader = headers[i]; parentHeader = headers[i];
} }
when(messageFrame.getBlockValues()).thenReturn(blockValues);
when(blockValues.getNumber()).thenReturn((long) CURRENT_BLOCK_NUMBER);
lookup = lookup =
new CachingBlockHashLookup( new CachingBlockHashLookup(
createHeader(CURRENT_BLOCK_NUMBER, headers[headers.length - 1]), blockchain); createHeader(CURRENT_BLOCK_NUMBER, headers[headers.length - 1]), blockchain);
@ -81,32 +72,19 @@ class CachingBlockHashLookupTest {
} }
@Test @Test
void shouldGetHashForRecentBlockAfterOlderBlock() { void shouldGetHashOfGenesisBlock() {
assertHashForBlockNumber(100); assertHashForBlockNumber(0);
assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 1);
}
@Test
void shouldReturnEmptyHashWhenRequestedGenesis() {
Assertions.assertThat(lookup.apply(messageFrame, 0L)).isEqualTo(Hash.ZERO);
} }
@Test @Test
void shouldReturnEmptyHashWhenRequestedTooFarBack() { void shouldGetHashForRecentBlockAfterOlderBlock() {
Assertions.assertThat(lookup.apply(messageFrame, CURRENT_BLOCK_NUMBER - 260L)) assertHashForBlockNumber(10);
.isEqualTo(Hash.ZERO); assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 1);
}
@Test
void shouldReturnEmptyHashWhenRequestedCurrentBlock() {
Assertions.assertThat(lookup.apply(messageFrame, (long) CURRENT_BLOCK_NUMBER))
.isEqualTo(Hash.ZERO);
} }
@Test @Test
void shouldReturnEmptyHashWhenRequestedBlockNotOnchain() { void shouldReturnEmptyHashWhenRequestedBlockNotOnchain() {
Assertions.assertThat(lookup.apply(messageFrame, CURRENT_BLOCK_NUMBER + 20L)) Assertions.assertThat(lookup.apply(CURRENT_BLOCK_NUMBER + 20L)).isEqualTo(Hash.ZERO);
.isEqualTo(Hash.ZERO);
} }
@Test @Test
@ -115,8 +93,7 @@ class CachingBlockHashLookupTest {
new CachingBlockHashLookup( new CachingBlockHashLookup(
new BlockHeaderTestFixture().number(CURRENT_BLOCK_NUMBER + 20).buildHeader(), new BlockHeaderTestFixture().number(CURRENT_BLOCK_NUMBER + 20).buildHeader(),
blockchain); blockchain);
Assertions.assertThat( Assertions.assertThat(lookupWithUnavailableParent.apply((long) CURRENT_BLOCK_NUMBER))
lookupWithUnavailableParent.apply(messageFrame, (long) CURRENT_BLOCK_NUMBER))
.isEqualTo(Hash.ZERO); .isEqualTo(Hash.ZERO);
} }
@ -137,7 +114,7 @@ class CachingBlockHashLookupTest {
} }
private void assertHashForBlockNumber(final int blockNumber) { private void assertHashForBlockNumber(final int blockNumber) {
Assertions.assertThat(lookup.apply(messageFrame, (long) blockNumber)) Assertions.assertThat(lookup.apply((long) blockNumber))
.isEqualTo(headers[blockNumber].getHash()); .isEqualTo(headers[blockNumber].getHash());
} }

@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.Code; import org.hyperledger.besu.evm.Code;
import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.EVM;
import org.hyperledger.besu.evm.EvmSpecVersion; import org.hyperledger.besu.evm.EvmSpecVersion;
@ -429,10 +430,7 @@ public class EvmToolCommand implements Runnable {
.blockValues(blockHeader) .blockValues(blockHeader)
.completer(c -> {}) .completer(c -> {})
.miningBeneficiary(blockHeader.getCoinbase()) .miningBeneficiary(blockHeader.getCoinbase())
.blockHashLookup( .blockHashLookup(new CachingBlockHashLookup(blockHeader, component.getBlockchain()))
protocolSpec
.getBlockHashProcessor()
.getBlockHashLookup(blockHeader, component.getBlockchain()))
.accessListWarmAddresses(addressList) .accessListWarmAddresses(addressList)
.build(); .build();
Deque<MessageFrame> messageFrameStack = initialMessageFrame.getMessageFrameStack(); Deque<MessageFrame> messageFrameStack = initialMessageFrame.getMessageFrameStack();

@ -32,13 +32,10 @@ import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.referencetests.GeneralStateTestCaseEipSpec; import org.hyperledger.besu.ethereum.referencetests.GeneralStateTestCaseEipSpec;
import org.hyperledger.besu.ethereum.referencetests.GeneralStateTestCaseSpec; import org.hyperledger.besu.ethereum.referencetests.GeneralStateTestCaseSpec;
import org.hyperledger.besu.ethereum.referencetests.ReferenceTestBlockchain;
import org.hyperledger.besu.ethereum.referencetests.ReferenceTestProtocolSchedules; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestProtocolSchedules;
import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.log.Log;
import org.hyperledger.besu.evm.operation.BlockHashOperation;
import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.tracing.StandardJsonTracer; import org.hyperledger.besu.evm.tracing.StandardJsonTracer;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
@ -251,31 +248,13 @@ public class StateTestSubCommand implements Runnable {
final Stopwatch timer = Stopwatch.createStarted(); final Stopwatch timer = Stopwatch.createStarted();
// Todo: EIP-4844 use the excessBlobGas of the parent instead of BlobGas.ZERO // Todo: EIP-4844 use the excessBlobGas of the parent instead of BlobGas.ZERO
final Wei blobGasPrice = protocolSpec.getFeeMarket().blobGasPricePerGas(BlobGas.ZERO); final Wei blobGasPrice = protocolSpec.getFeeMarket().blobGasPricePerGas(BlobGas.ZERO);
BlockHashOperation.BlockHashLookup blockHashLookup =
protocolSpec
.getBlockHashProcessor()
.getBlockHashLookup(
blockHeader, new ReferenceTestBlockchain(blockHeader.getNumber()));
if (blockHashLookup instanceof CachingBlockHashLookup) {
blockHashLookup =
(messageFrame, number) -> {
long lookback = messageFrame.getBlockValues().getNumber() - number;
if (lookback <= 0 || lookback > BlockHashOperation.MAX_RELATIVE_BLOCK) {
return Hash.ZERO;
} else {
return Hash.hash(Bytes.wrap(Long.toString(number).getBytes(UTF_8)));
}
};
}
final TransactionProcessingResult result = final TransactionProcessingResult result =
processor.processTransaction( processor.processTransaction(
worldStateUpdater, worldStateUpdater,
blockHeader, blockHeader,
transaction, transaction,
blockHeader.getCoinbase(), blockHeader.getCoinbase(),
blockHashLookup, blockNumber -> Hash.hash(Bytes.wrap(Long.toString(blockNumber).getBytes(UTF_8))),
false, false,
TransactionValidationParams.processingBlock(), TransactionValidationParams.processingBlock(),
tracer, tracer,

@ -47,11 +47,9 @@ import org.hyperledger.besu.ethereum.referencetests.ReferenceTestWorldState;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.log.Log;
import org.hyperledger.besu.evm.operation.BlockHashOperation;
import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.evmtool.exception.UnsupportedForkException; import org.hyperledger.besu.evmtool.exception.UnsupportedForkException;
@ -291,27 +289,13 @@ public class T8nExecutor {
tracer = tracerManager.getManagedTracer(i, transaction.getHash()); tracer = tracerManager.getManagedTracer(i, transaction.getHash());
tracer.tracePrepareTransaction(worldStateUpdater, transaction); tracer.tracePrepareTransaction(worldStateUpdater, transaction);
tracer.traceStartTransaction(worldStateUpdater, transaction); tracer.traceStartTransaction(worldStateUpdater, transaction);
BlockHashOperation.BlockHashLookup blockHashLookup =
protocolSpec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain);
if (blockHashLookup instanceof CachingBlockHashLookup) {
// caching lookup won't work, use our own secret sauce
blockHashLookup =
(frame, number) -> {
long lookback = frame.getBlockValues().getNumber() - number;
if (lookback <= 0 || lookback > BlockHashOperation.MAX_RELATIVE_BLOCK) {
return Hash.ZERO;
} else {
return referenceTestEnv.getBlockhashByNumber(number).orElse(Hash.ZERO);
}
};
}
result = result =
processor.processTransaction( processor.processTransaction(
worldStateUpdater, worldStateUpdater,
blockHeader, blockHeader,
transaction, transaction,
blockHeader.getCoinbase(), blockHeader.getCoinbase(),
blockHashLookup, number -> referenceTestEnv.getBlockhashByNumber(number).orElse(Hash.ZERO),
false, false,
TransactionValidationParams.processingBlock(), TransactionValidationParams.processingBlock(),
tracer, tracer,

@ -62,7 +62,7 @@ public abstract class BenchmarkExecutor {
.code(CodeV0.EMPTY_CODE) .code(CodeV0.EMPTY_CODE)
.completer(__ -> {}) .completer(__ -> {})
.address(Address.ZERO) .address(Address.ZERO)
.blockHashLookup((f, n) -> null) .blockHashLookup(n -> null)
.blockValues(new SimpleBlockValues()) .blockValues(new SimpleBlockValues())
.gasPrice(Wei.ZERO) .gasPrice(Wei.ZERO)
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)

@ -106,9 +106,6 @@ public class GeneralStateReferenceTestTools {
// EOF tests are written against an older version of the spec // EOF tests are written against an older version of the spec
params.ignore("/stEOF/"); params.ignore("/stEOF/");
// None of the Prague tests have withdrawls and deposits handling
params.ignore("-Prague$");
} }
private GeneralStateReferenceTestTools() { private GeneralStateReferenceTestTools() {
@ -160,7 +157,7 @@ public class GeneralStateReferenceTestTools {
blockHeader, blockHeader,
transaction, transaction,
blockHeader.getCoinbase(), blockHeader.getCoinbase(),
protocolSpec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain), new CachingBlockHashLookup(blockHeader, blockchain),
false, false,
TransactionValidationParams.processingBlock(), TransactionValidationParams.processingBlock(),
blobGasPrice); blobGasPrice);

@ -72,7 +72,7 @@ public class EVMExecutor {
private Wei ethValue = Wei.ZERO; private Wei ethValue = Wei.ZERO;
private Code code = CodeV0.EMPTY_CODE; private Code code = CodeV0.EMPTY_CODE;
private BlockValues blockValues = new SimpleBlockValues(); private BlockValues blockValues = new SimpleBlockValues();
private BlockHashLookup blockHashLookup = (h, n) -> null; private BlockHashLookup blockHashLookup = n -> null;
private Optional<List<VersionedHash>> versionedHashes = Optional.empty(); private Optional<List<VersionedHash>> versionedHashes = Optional.empty();
private OperationTracer tracer = OperationTracer.NO_TRACING; private OperationTracer tracer = OperationTracer.NO_TRACING;
private boolean requireDeposit = true; private boolean requireDeposit = true;

@ -16,7 +16,6 @@ package org.hyperledger.besu.evm.frame;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static java.util.Collections.emptySet; import static java.util.Collections.emptySet;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.collections.trie.BytesTrieSet; import org.hyperledger.besu.collections.trie.BytesTrieSet;
import org.hyperledger.besu.collections.undo.UndoScalar; import org.hyperledger.besu.collections.undo.UndoScalar;
@ -33,6 +32,7 @@ import org.hyperledger.besu.evm.internal.ReturnStack;
import org.hyperledger.besu.evm.internal.StorageEntry; import org.hyperledger.besu.evm.internal.StorageEntry;
import org.hyperledger.besu.evm.internal.UnderflowException; import org.hyperledger.besu.evm.internal.UnderflowException;
import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.log.Log;
import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.operation.Operation;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
@ -1427,9 +1427,6 @@ public class MessageFrame {
private Optional<List<VersionedHash>> versionedHashes = Optional.empty(); private Optional<List<VersionedHash>> versionedHashes = Optional.empty();
/** Instantiates a new Builder. */
public Builder() {}
/** /**
* The "parent" message frame. When present some fields will be populated from the parent and * The "parent" message frame. When present some fields will be populated from the parent and
* ignored if passed in via builder * ignored if passed in via builder

@ -392,7 +392,7 @@ public class FrontierGasCalculator implements GasCalculator {
} }
@Override @Override
public long getBlockHashOperationGasCost(final MessageFrame frame) { public long getBlockHashOperationGasCost() {
return BLOCKHASH_OPERATION_GAS_COST; return BLOCKHASH_OPERATION_GAS_COST;
} }

@ -345,10 +345,9 @@ public interface GasCalculator {
/** /**
* Returns the cost for executing a {@link BlockHashOperation}. * Returns the cost for executing a {@link BlockHashOperation}.
* *
* @param frame The current frame
* @return the cost for executing the block hash operation * @return the cost for executing the block hash operation
*/ */
long getBlockHashOperationGasCost(MessageFrame frame); long getBlockHashOperationGasCost();
/** /**
* Returns the cost for executing a {@link ExpOperation}. * Returns the cost for executing a {@link ExpOperation}.

@ -21,8 +21,6 @@ import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame;
import org.apache.tuweni.units.bigints.UInt256;
/** /**
* Gas Calculator for Prague * Gas Calculator for Prague
* *
@ -101,24 +99,4 @@ public class PragueGasCalculator extends CancunGasCalculator {
return cost; return cost;
} }
/** Address of the contract historic block hashes are stored in. */
public static final Address HISTORY_STORAGE_ADDRESS =
Address.fromHexString("0x25a219378dad9b3503c8268c9ca836a52427a4fb");
/** The HISTORY_SERVE_WINDOW */
public static final long HISTORY_SERVE_WINDOW = 8192;
@Override
public long getBlockHashOperationGasCost(final MessageFrame frame) {
if (frame == null) {
return super.getBlockHashOperationGasCost(null);
} else {
UInt256 slot = UInt256.valueOf(frame.getBlockValues().getNumber() % HISTORY_SERVE_WINDOW);
return BLOCKHASH_OPERATION_GAS_COST
+ (frame.warmUpStorage(HISTORY_STORAGE_ADDRESS, slot)
? getWarmStorageReadCost()
: getColdSloadCost());
}
}
} }

@ -16,27 +16,29 @@ package org.hyperledger.besu.evm.operation;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.EVM;
import org.hyperledger.besu.evm.frame.BlockValues;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import java.util.function.BiFunction; import java.util.function.Function;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.units.bigints.UInt256; import org.apache.tuweni.units.bigints.UInt256;
/** The Block hash operation. */ /** The Block hash operation. */
public class BlockHashOperation extends AbstractOperation { public class BlockHashOperation extends AbstractFixedCostOperation {
/** Frontier maximum relative block delta */
public static final int MAX_RELATIVE_BLOCK = 256;
/** /**
* Function that gets the block hash, passed in as part of TxValues. * Function that gets the block hash, passed in as part of TxValues.
* *
* <p>First arg is the current block number, second is the block argument from the stack. The * <p>Arg is the current block number. The Result is the Hash, which may be zero based on lookup
* Result is the Hash, which may be zero based on lookup rules. * rules.
*/ */
public interface BlockHashLookup extends BiFunction<MessageFrame, Long, Hash> {} public interface BlockHashLookup extends Function<Long, Hash> {}
/** Frontier maximum relative block delta */
public static final int MAX_RELATIVE_BLOCK = 256;
private static final int MAX_BLOCK_ARG_SIZE = 8; private static final int MAX_BLOCK_ARG_SIZE = 8;
@ -46,25 +48,36 @@ public class BlockHashOperation extends AbstractOperation {
* @param gasCalculator the gas calculator * @param gasCalculator the gas calculator
*/ */
public BlockHashOperation(final GasCalculator gasCalculator) { public BlockHashOperation(final GasCalculator gasCalculator) {
super(0x40, "BLOCKHASH", 1, 1, gasCalculator); super(0x40, "BLOCKHASH", 1, 1, gasCalculator, gasCalculator.getBlockHashOperationGasCost());
} }
@Override @Override
public OperationResult execute(MessageFrame frame, EVM evm) { public Operation.OperationResult executeFixedCostOperation(
final MessageFrame frame, final EVM evm) {
final Bytes blockArg = frame.popStackItem().trimLeadingZeros(); final Bytes blockArg = frame.popStackItem().trimLeadingZeros();
// Short-circuit if value exceeds long // Short-circuit if value is unreasonably large
if (blockArg.size() > MAX_BLOCK_ARG_SIZE) { if (blockArg.size() > MAX_BLOCK_ARG_SIZE) {
frame.pushStackItem(UInt256.ZERO); frame.pushStackItem(UInt256.ZERO);
return new OperationResult(gasCalculator().getBlockHashOperationGasCost(null), null); return successResponse;
} }
final long soughtBlock = blockArg.toLong(); final long soughtBlock = blockArg.toLong();
final BlockHashLookup blockHashLookup = frame.getBlockHashLookup(); final BlockValues blockValues = frame.getBlockValues();
final Hash blockHash = blockHashLookup.apply(frame, soughtBlock); final long currentBlockNumber = blockValues.getNumber();
frame.pushStackItem(blockHash);
return new OperationResult( // If the current block is the genesis block or the sought block is
gasCalculator().getBlockHashOperationGasCost(Hash.ZERO.equals(blockHash) ? null : frame), // not within the last 256 completed blocks, zero is returned.
null); if (currentBlockNumber == 0
|| soughtBlock >= currentBlockNumber
|| soughtBlock < (currentBlockNumber - MAX_RELATIVE_BLOCK)) {
frame.pushStackItem(Bytes32.ZERO);
} else {
final BlockHashLookup blockHashLookup = frame.getBlockHashLookup();
final Hash blockHash = blockHashLookup.apply(soughtBlock);
frame.pushStackItem(blockHash);
}
return successResponse;
} }
} }

@ -97,7 +97,7 @@ class CodeV0Test {
.blockValues(mock(BlockValues.class)) .blockValues(mock(BlockValues.class))
.completer(f -> {}) .completer(f -> {})
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)
.blockHashLookup((f, n) -> Hash.EMPTY) .blockHashLookup(l -> Hash.EMPTY)
.build(); .build();
frame.setPC(CURRENT_PC); frame.setPC(CURRENT_PC);

@ -188,7 +188,7 @@ class EVMExecutorTest {
.number(1) .number(1)
.timestamp(100L) .timestamp(100L)
.gasLimit(15_000_000L) .gasLimit(15_000_000L)
.blockHashLookup((height, number) -> Hash.ZERO) .blockHashLookup(number -> Hash.ZERO)
.versionedHashes(Optional.empty()) .versionedHashes(Optional.empty())
.precompileContractRegistry(new PrecompileContractRegistry()) .precompileContractRegistry(new PrecompileContractRegistry())
.requireDeposit(false) .requireDeposit(false)

@ -48,7 +48,7 @@ class MessageFrameTest {
.blobGasPrice(Wei.ONE) .blobGasPrice(Wei.ONE)
.blockValues(new ToyBlockValues()) .blockValues(new ToyBlockValues())
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)
.blockHashLookup((f, n) -> Hash.ZERO) .blockHashLookup((l) -> Hash.ZERO)
.type(MessageFrame.Type.MESSAGE_CALL) .type(MessageFrame.Type.MESSAGE_CALL)
.initialGas(1) .initialGas(1)
.address(Address.ZERO) .address(Address.ZERO)

@ -169,7 +169,7 @@ class AbstractCreateOperationTest {
.code(CodeFactory.createCode(SIMPLE_CREATE, 0, true)) .code(CodeFactory.createCode(SIMPLE_CREATE, 0, true))
.completer(__ -> {}) .completer(__ -> {})
.address(Address.fromHexString(SENDER)) .address(Address.fromHexString(SENDER))
.blockHashLookup((f, n) -> Hash.hash(Words.longBytes(n))) .blockHashLookup(n -> Hash.hash(Words.longBytes(n)))
.blockValues(mock(BlockValues.class)) .blockValues(mock(BlockValues.class))
.gasPrice(Wei.ZERO) .gasPrice(Wei.ZERO)
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)

@ -15,12 +15,12 @@
package org.hyperledger.besu.evm.operations; package org.hyperledger.besu.evm.operations;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.FrontierGasCalculator; import org.hyperledger.besu.evm.gascalculator.FrontierGasCalculator;
import org.hyperledger.besu.evm.operation.BlockHashOperation; import org.hyperledger.besu.evm.operation.BlockHashOperation;
import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.evm.testutils.FakeBlockValues; import org.hyperledger.besu.evm.testutils.FakeBlockValues;
import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder; import org.hyperledger.besu.evm.testutils.TestMessageFrameBuilder;
@ -31,20 +31,49 @@ import org.junit.jupiter.api.Test;
class BlockHashOperationTest { class BlockHashOperationTest {
private static final int MAXIMUM_COMPLETE_BLOCKS_BEHIND = 256;
private final BlockHashOperation blockHashOperation = private final BlockHashOperation blockHashOperation =
new BlockHashOperation(new FrontierGasCalculator()); new BlockHashOperation(new FrontierGasCalculator());
@Test @Test
void shouldReturnZeroWhenArgIsBiggerThanALong() { void shouldReturnZeroWhenArgIsBiggerThanALong() {
assertBlockHash( assertBlockHash(
Bytes32.fromHexString("F".repeat(64)), Bytes32.ZERO, 100, (h, n) -> Hash.EMPTY_LIST_HASH); Bytes32.fromHexString("F".repeat(64)), Bytes32.ZERO, 100, n -> Hash.EMPTY_LIST_HASH);
}
@Test
void shouldReturnZeroWhenCurrentBlockIsGenesis() {
assertBlockHash(Bytes32.ZERO, Bytes32.ZERO, 0, block -> Hash.EMPTY_LIST_HASH);
}
@Test
void shouldReturnZeroWhenRequestedBlockAheadOfCurrent() {
assertBlockHash(250, Bytes32.ZERO, 100, block -> Hash.EMPTY_LIST_HASH);
}
@Test
void shouldReturnZeroWhenRequestedBlockTooFarBehindCurrent() {
final int requestedBlock = 10;
// Our block is the one after the chain head (it's a new block), hence the + 1.
final int importingBlockNumber = MAXIMUM_COMPLETE_BLOCKS_BEHIND + requestedBlock + 1;
assertBlockHash(
requestedBlock, Bytes32.ZERO, importingBlockNumber, block -> Hash.EMPTY_LIST_HASH);
}
@Test
void shouldReturnZeroWhenRequestedBlockGreaterThanImportingBlock() {
assertBlockHash(101, Bytes32.ZERO, 100, block -> Hash.EMPTY_LIST_HASH);
}
@Test
void shouldReturnZeroWhenRequestedBlockEqualToImportingBlock() {
assertBlockHash(100, Bytes32.ZERO, 100, block -> Hash.EMPTY_LIST_HASH);
} }
@Test @Test
void shouldReturnBlockHashUsingLookupFromFrameWhenItIsWithinTheAllowedRange() { void shouldReturnBlockHashUsingLookupFromFrameWhenItIsWithinTheAllowedRange() {
final Hash blockHash = Hash.hash(Bytes.fromHexString("0x1293487297")); final Hash blockHash = Hash.hash(Bytes.fromHexString("0x1293487297"));
assertBlockHash( assertBlockHash(100, blockHash, 200, block -> block == 100 ? blockHash : Hash.EMPTY_LIST_HASH);
100, blockHash, 200, (h, block) -> block == 100 ? blockHash : Hash.EMPTY_LIST_HASH);
} }
private void assertBlockHash( private void assertBlockHash(

@ -155,7 +155,7 @@ public class Create2OperationTest {
.code(CodeFactory.createCode(codeBytes, 0, true)) .code(CodeFactory.createCode(codeBytes, 0, true))
.completer(__ -> {}) .completer(__ -> {})
.address(Address.fromHexString(sender)) .address(Address.fromHexString(sender))
.blockHashLookup((f, n) -> Hash.hash(Words.longBytes(n))) .blockHashLookup(n -> Hash.hash(Words.longBytes(n)))
.blockValues(mock(BlockValues.class)) .blockValues(mock(BlockValues.class))
.gasPrice(Wei.ZERO) .gasPrice(Wei.ZERO)
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)
@ -269,7 +269,7 @@ public class Create2OperationTest {
.code(CodeFactory.createCode(SIMPLE_CREATE, 0, true)) .code(CodeFactory.createCode(SIMPLE_CREATE, 0, true))
.completer(__ -> {}) .completer(__ -> {})
.address(Address.fromHexString(SENDER)) .address(Address.fromHexString(SENDER))
.blockHashLookup((f, n) -> Hash.hash(Words.longBytes(n))) .blockHashLookup(n -> Hash.hash(Words.longBytes(n)))
.blockValues(mock(BlockValues.class)) .blockValues(mock(BlockValues.class))
.gasPrice(Wei.ZERO) .gasPrice(Wei.ZERO)
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)

@ -289,7 +289,7 @@ class CreateOperationTest {
.code(CodeFactory.createCode(SIMPLE_CREATE, 0, true)) .code(CodeFactory.createCode(SIMPLE_CREATE, 0, true))
.completer(__ -> {}) .completer(__ -> {})
.address(Address.fromHexString(SENDER)) .address(Address.fromHexString(SENDER))
.blockHashLookup((f, n) -> Hash.hash(Words.longBytes(n))) .blockHashLookup(n -> Hash.hash(Words.longBytes(n)))
.blockValues(mock(BlockValues.class)) .blockValues(mock(BlockValues.class))
.gasPrice(Wei.ZERO) .gasPrice(Wei.ZERO)
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)

@ -82,7 +82,7 @@ public class SelfDestructOperationTest {
.code(CodeFactory.createCode(SELFDESTRUCT_CODE, 0, true)) .code(CodeFactory.createCode(SELFDESTRUCT_CODE, 0, true))
.completer(__ -> {}) .completer(__ -> {})
.address(originatorAddress) .address(originatorAddress)
.blockHashLookup((f, n) -> Hash.hash(Words.longBytes(n))) .blockHashLookup(n -> Hash.hash(Words.longBytes(n)))
.blockValues(mock(BlockValues.class)) .blockValues(mock(BlockValues.class))
.gasPrice(Wei.ZERO) .gasPrice(Wei.ZERO)
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)

@ -65,7 +65,7 @@ public class Benchmarks {
.code(CodeV0.EMPTY_CODE) .code(CodeV0.EMPTY_CODE)
.completer(__ -> {}) .completer(__ -> {})
.address(Address.ZERO) .address(Address.ZERO)
.blockHashLookup((f, n) -> null) .blockHashLookup(n -> null)
.blockValues(new SimpleBlockValues()) .blockValues(new SimpleBlockValues())
.gasPrice(Wei.ZERO) .gasPrice(Wei.ZERO)
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)

@ -15,7 +15,6 @@
package org.hyperledger.besu.evm.testutils; package org.hyperledger.besu.evm.testutils;
import static org.hyperledger.besu.evm.frame.MessageFrame.DEFAULT_MAX_STACK_SIZE; import static org.hyperledger.besu.evm.frame.MessageFrame.DEFAULT_MAX_STACK_SIZE;
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Hash;
@ -25,6 +24,7 @@ import org.hyperledger.besu.evm.code.CodeV0;
import org.hyperledger.besu.evm.frame.BlockValues; import org.hyperledger.besu.evm.frame.BlockValues;
import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.internal.Words; import org.hyperledger.besu.evm.internal.Words;
import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
import org.hyperledger.besu.evm.toy.ToyWorld; import org.hyperledger.besu.evm.toy.ToyWorld;
import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evm.worldstate.WorldUpdater;
@ -161,7 +161,7 @@ public class TestMessageFrameBuilder {
.blockValues(blockValues.orElseGet(() -> new FakeBlockValues(1337))) .blockValues(blockValues.orElseGet(() -> new FakeBlockValues(1337)))
.completer(c -> {}) .completer(c -> {})
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)
.blockHashLookup(blockHashLookup.orElse((f, n) -> Hash.hash(Words.longBytes(n)))) .blockHashLookup(blockHashLookup.orElse(number -> Hash.hash(Words.longBytes(number))))
.maxStackSize(maxStackSize) .maxStackSize(maxStackSize)
.build(); .build();
frame.setPC(pc); frame.setPC(pc);

@ -190,7 +190,7 @@ public class EvmToyCommand implements Runnable {
.blockValues(new ToyBlockValues()) .blockValues(new ToyBlockValues())
.completer(c -> {}) .completer(c -> {})
.miningBeneficiary(Address.ZERO) .miningBeneficiary(Address.ZERO)
.blockHashLookup((f, n) -> null) .blockHashLookup(n -> null)
.build(); .build();
final MessageCallProcessor mcp = new MessageCallProcessor(evm, precompileContractRegistry); final MessageCallProcessor mcp = new MessageCallProcessor(evm, precompileContractRegistry);

Loading…
Cancel
Save