mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-09 23:47:57 -05:00
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>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
"executionPayload": {
|
||||
"parentHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x3057566307e82861160cd217c71c18a93023a752d268113a4e50148fe6f19be6",
|
||||
"stateRoot": "0x546ac65b9d37c72d7185f8dd67419803c636dd4e5ddf9b325fb64e9ecf570871",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -30,14 +30,14 @@
|
||||
"withdrawalRequests": [
|
||||
{
|
||||
"sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb",
|
||||
"amount" : "0x0",
|
||||
"validatorPublicKey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"
|
||||
"validatorPublicKey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e",
|
||||
"amount": "0x0"
|
||||
}
|
||||
],
|
||||
"blockNumber": "0x2",
|
||||
"blockHash": "0xdce2f62925b5ebb218943e71fa87af2aaeb6dab2d8aee12ea7f9f24eeae7b4c7",
|
||||
"blobGasUsed": "0x0",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
||||
"blockHash": "0xa7a92cc82e1d876476ad6433538599b0d592f88ba0823c23e80af93fb1748f14",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"blobGasUsed": "0x0"
|
||||
},
|
||||
"blockValue": "0x0",
|
||||
"blobsBundle": {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"method": "engine_newPayloadV4",
|
||||
"params": [
|
||||
{
|
||||
"parentHash": "0x45811fa27a100ce9035e5e086b9669275041a4ec0ebbd920be028fd7b0aa2356",
|
||||
"parentHash": "0xa7a92cc82e1d876476ad6433538599b0d592f88ba0823c23e80af93fb1748f14",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x9b8c4a9a86cb49252075c0db2f0e72fb1e49350a0f70ea36f26f700201961e62",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -17,9 +17,9 @@
|
||||
"excessBlobGas": "0x0",
|
||||
"transactions": [],
|
||||
"withdrawals": [],
|
||||
"depositRequests" : null,
|
||||
"depositRequests": null,
|
||||
"blockNumber": "0x2",
|
||||
"blockHash": "0xf6c3f1180ba58d6ea4c69c9328c7afb1fda41df06c368741c1f8310567879de7",
|
||||
"blockHash": "0x2331b2dc9c453e9a33685099742cbbcd529d42bd5681969f45754f06866c6766",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"blobGasUsed": "0x0"
|
||||
},
|
||||
@@ -34,7 +34,7 @@
|
||||
"error": {
|
||||
"code": -32602,
|
||||
"message": "Invalid params",
|
||||
"data" : "Missing deposit field"
|
||||
"data": "Missing deposit field"
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{
|
||||
"parentHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x778ccbc3adc59876b76489cdc1a2ff76ef2a31ae9d3bf761bc55bbab7d59c489",
|
||||
"stateRoot": "0xdb2a9bb9097dd6946525203a14437cd925ef549289e1fe17c6ed845c53647a26",
|
||||
"logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -31,12 +31,12 @@
|
||||
"withdrawalRequests": [
|
||||
{
|
||||
"sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb",
|
||||
"amount" : "0x0",
|
||||
"amount": "0x0",
|
||||
"validatorPublicKey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"
|
||||
}
|
||||
],
|
||||
"blockNumber": "0x2",
|
||||
"blockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852",
|
||||
"blockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
|
||||
"receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9",
|
||||
"blobGasUsed": "0x0"
|
||||
},
|
||||
@@ -50,7 +50,7 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852",
|
||||
"latestValidHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
|
||||
"validationError": null
|
||||
}
|
||||
},
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"method": "engine_forkchoiceUpdatedV3",
|
||||
"params": [
|
||||
{
|
||||
"headBlockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852",
|
||||
"safeBlockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852",
|
||||
"finalizedBlockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852"
|
||||
"headBlockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
|
||||
"safeBlockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
|
||||
"finalizedBlockHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d"
|
||||
},
|
||||
{
|
||||
"timestamp": "0x30",
|
||||
@@ -24,11 +24,11 @@
|
||||
"result": {
|
||||
"payloadStatus": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852",
|
||||
"latestValidHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
|
||||
"validationError": null
|
||||
},
|
||||
"payloadId": "0x282643ead6ad5331"
|
||||
"payloadId": "0x282643e2da21a7cf"
|
||||
}
|
||||
},
|
||||
"statusCode" : 200
|
||||
"statusCode": 200
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"jsonrpc": "2.0",
|
||||
"method": "engine_getPayloadV4",
|
||||
"params": [
|
||||
"0x282643ead6ad5331"
|
||||
"0x282643e2da21a7cf"
|
||||
],
|
||||
"id": 67
|
||||
},
|
||||
@@ -12,9 +12,9 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"executionPayload": {
|
||||
"parentHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852",
|
||||
"parentHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x61d2011dc13b003c48193f0902653fd4f7b67fa949dc0fa6eab9e69e349700fd",
|
||||
"stateRoot": "0xcd9f15de5f17cf87a02bf795a0dc98c108eead4651eca57fc7195bda0d9c20ee",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -29,7 +29,7 @@
|
||||
"depositRequests": [],
|
||||
"withdrawalRequests": [],
|
||||
"blockNumber": "0x3",
|
||||
"blockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9",
|
||||
"blockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"blobGasUsed": "0x0"
|
||||
},
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"method": "engine_newPayloadV3",
|
||||
"params": [
|
||||
{
|
||||
"parentHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852",
|
||||
"parentHash": "0x5200df2eb24d08e7bceec64194d073e81a6e9c00c4f61d323fad5d70b40e6d6d",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x61d2011dc13b003c48193f0902653fd4f7b67fa949dc0fa6eab9e69e349700fd",
|
||||
"stateRoot": "0xcd9f15de5f17cf87a02bf795a0dc98c108eead4651eca57fc7195bda0d9c20ee",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -19,7 +19,7 @@
|
||||
"depositRequests": [],
|
||||
"withdrawalRequests": [],
|
||||
"blockNumber": "0x3",
|
||||
"blockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9",
|
||||
"blockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"excessBlobGas": "0x0",
|
||||
"blobGasUsed": "0x0"
|
||||
@@ -34,7 +34,7 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9",
|
||||
"latestValidHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
|
||||
"validationError": null
|
||||
}
|
||||
},
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"method": "engine_forkchoiceUpdatedV3",
|
||||
"params": [
|
||||
{
|
||||
"headBlockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9",
|
||||
"safeBlockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9",
|
||||
"finalizedBlockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9"
|
||||
"headBlockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
|
||||
"safeBlockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
|
||||
"finalizedBlockHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42"
|
||||
},
|
||||
{
|
||||
"timestamp": "0x40",
|
||||
@@ -24,11 +24,11 @@
|
||||
"result": {
|
||||
"payloadStatus": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9",
|
||||
"latestValidHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
|
||||
"validationError": null
|
||||
},
|
||||
"payloadId": "0x2826438a3f8a7741"
|
||||
"payloadId": "0x282643de0e3d43bf"
|
||||
}
|
||||
},
|
||||
"statusCode" : 200
|
||||
"statusCode": 200
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"jsonrpc": "2.0",
|
||||
"method": "engine_getPayloadV4",
|
||||
"params": [
|
||||
"0x2826438a3f8a7741"
|
||||
"0x282643de0e3d43bf"
|
||||
],
|
||||
"id": 67
|
||||
},
|
||||
@@ -12,9 +12,9 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"executionPayload": {
|
||||
"parentHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9",
|
||||
"parentHash": "0x79858f6eb8e82f0ec11087983ce4eb8c7edc10c9363a2a124dd78fd2c305dc42",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x847db08c6b9e6dcc91288bd963eb5623aea5387232016ef81fddb3ebc994c72f",
|
||||
"stateRoot": "0xe4642cc58d61f2392fe056042c226e286f22a25e3104f4a4acb423dad9a43311",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -37,9 +37,9 @@
|
||||
}
|
||||
],
|
||||
"blockNumber": "0x4",
|
||||
"blobGasUsed": "0x0",
|
||||
"receiptsRoot": "0x765bd9d63cc10fa47117d6cc0958f15e55a3bde540d4ed15d220f573fbb82cba",
|
||||
"blockHash": "0xd0b81acdb3016abbc05599b083c8b090323efaf0b2aeab8d0755780e20214159"
|
||||
"blobGasUsed": "0x0",
|
||||
"blockHash": "0xb2d60adb2a0c73313ebdacf425b1d6bbd810c3ec6b28ad0d62a73cdc34cb696a"
|
||||
},
|
||||
"blockValue": "0x12855dcd153473b",
|
||||
"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.ProtocolSpec;
|
||||
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.plugin.Unstable;
|
||||
import org.hyperledger.besu.plugin.data.BlockTraceResult;
|
||||
@@ -216,7 +217,7 @@ public class TraceServiceImpl implements TraceService {
|
||||
transaction,
|
||||
protocolSpec.getMiningBeneficiaryCalculator().calculateBeneficiary(header),
|
||||
tracer,
|
||||
protocolSpec.getBlockHashProcessor().getBlockHashLookup(header, blockchain),
|
||||
new CachingBlockHashLookup(header, blockchain),
|
||||
false,
|
||||
blobGasPrice);
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
|
||||
|
||||
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.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.ProtocolSpec;
|
||||
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.evm.operation.BlockHashOperation.BlockHashLookup;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -94,8 +95,7 @@ public class ExecuteTransactionStep implements Function<TransactionTrace, Transa
|
||||
maybeParentHeader
|
||||
.map(parent -> calculateExcessBlobGasForParent(protocolSpec, parent))
|
||||
.orElse(BlobGas.ZERO));
|
||||
final BlockHashLookup blockHashLookup =
|
||||
protocolSpec.getBlockHashProcessor().getBlockHashLookup(header, blockchain);
|
||||
final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(header, blockchain);
|
||||
result =
|
||||
transactionProcessor.processTransaction(
|
||||
chainUpdater.getNextUpdater(),
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor;
|
||||
|
||||
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.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.ProtocolSpec;
|
||||
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.Optional;
|
||||
@@ -89,8 +90,7 @@ public class BlockReplay {
|
||||
return performActionWithBlock(
|
||||
blockHash,
|
||||
(body, header, blockchain, transactionProcessor, protocolSpec) -> {
|
||||
final BlockHashLookup blockHashLookup =
|
||||
protocolSpec.getBlockHashProcessor().getBlockHashLookup(header, blockchain);
|
||||
final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(header, blockchain);
|
||||
final Wei blobGasPrice =
|
||||
protocolSpec
|
||||
.getFeeMarket()
|
||||
@@ -137,7 +137,7 @@ public class BlockReplay {
|
||||
blockHeader,
|
||||
transaction,
|
||||
spec.getMiningBeneficiaryCalculator().calculateBeneficiary(blockHeader),
|
||||
spec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain),
|
||||
new CachingBlockHashLookup(blockHeader, blockchain),
|
||||
false,
|
||||
TransactionValidationParams.blockReplay(),
|
||||
blobGasPrice);
|
||||
@@ -180,10 +180,6 @@ public class BlockReplay {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public ProtocolSpec getProtocolSpec(final BlockHeader header) {
|
||||
return protocolSchedule.getByBlockHeader(header);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BlockAction<T> {
|
||||
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.debug.TraceFrame;
|
||||
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.evm.worldstate.WorldUpdater;
|
||||
|
||||
@@ -68,10 +69,7 @@ public class BlockTracer {
|
||||
transaction,
|
||||
header.getCoinbase(),
|
||||
tracer,
|
||||
blockReplay
|
||||
.getProtocolSpec(header)
|
||||
.getBlockHashProcessor()
|
||||
.getBlockHashLookup(header, blockchain),
|
||||
new CachingBlockHashLookup(header, blockchain),
|
||||
false,
|
||||
blobGasPrice);
|
||||
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.MainnetTransactionProcessor;
|
||||
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.evm.tracing.OperationTracer;
|
||||
import org.hyperledger.besu.evm.tracing.StandardJsonTracer;
|
||||
@@ -191,10 +192,7 @@ public class TransactionTracer {
|
||||
transaction,
|
||||
header.getCoinbase(),
|
||||
tracer,
|
||||
blockReplay
|
||||
.getProtocolSpec(header)
|
||||
.getBlockHashProcessor()
|
||||
.getBlockHashLookup(header, blockchain),
|
||||
new CachingBlockHashLookup(header, blockchain),
|
||||
false,
|
||||
ImmutableTransactionValidationParams.builder().isAllowFutureNonce(true).build(),
|
||||
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.ProtocolSchedule;
|
||||
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.processing.TransactionProcessingResult;
|
||||
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
|
||||
@@ -88,7 +87,6 @@ public class TransactionTracerTest {
|
||||
|
||||
@Mock private ProtocolSpec protocolSpec;
|
||||
@Mock private GasCalculator gasCalculator;
|
||||
@Mock private BlockHashProcessor blockHashProcessor;
|
||||
|
||||
@Mock private Tracer.TraceableState mutableWorldState;
|
||||
|
||||
@@ -125,7 +123,6 @@ public class TransactionTracerTest {
|
||||
when(protocolSpec.getFeeMarket()).thenReturn(FeeMarket.london(0L));
|
||||
when(blockchain.getChainHeadHeader()).thenReturn(blockHeader);
|
||||
when(protocolSpec.getGasCalculator()).thenReturn(gasCalculator);
|
||||
when(protocolSpec.getBlockHashProcessor()).thenReturn(blockHashProcessor);
|
||||
when(protocolContext.getBadBlockManager()).thenReturn(badBlockManager);
|
||||
lenient().when(gasCalculator.computeExcessBlobGas(anyLong(), anyInt())).thenReturn(0L);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
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.SELECTED;
|
||||
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.feemarket.FeeMarket;
|
||||
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.operation.BlockHashOperation.BlockHashLookup;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
|
||||
import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer;
|
||||
@@ -326,9 +327,7 @@ public class BlockTransactionSelector {
|
||||
private TransactionProcessingResult processTransaction(
|
||||
final PendingTransaction pendingTransaction, final WorldUpdater worldStateUpdater) {
|
||||
final BlockHashLookup blockHashLookup =
|
||||
blockSelectionContext
|
||||
.blockHashProcessor()
|
||||
.getBlockHashLookup(blockSelectionContext.processableBlockHeader(), blockchain);
|
||||
new CachingBlockHashLookup(blockSelectionContext.processableBlockHeader(), blockchain);
|
||||
return transactionProcessor.processTransaction(
|
||||
worldStateUpdater,
|
||||
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.catchThrowable;
|
||||
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
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.evm.frame.MessageFrame;
|
||||
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.tracing.OperationTracer;
|
||||
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.mainnet.MainnetTransactionProcessor;
|
||||
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.processing.TransactionProcessingResult;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
|
||||
@@ -74,13 +73,11 @@ public class TraceTransactionIntegrationTest {
|
||||
blockchain = contextTestFixture.getBlockchain();
|
||||
worldStateArchive = contextTestFixture.getStateArchive();
|
||||
final ProtocolSchedule protocolSchedule = contextTestFixture.getProtocolSchedule();
|
||||
ProtocolSpec protocolSpec =
|
||||
protocolSchedule.getByBlockHeader(new BlockHeaderTestFixture().number(0L).buildHeader());
|
||||
transactionProcessor = protocolSpec.getTransactionProcessor();
|
||||
blockHashLookup =
|
||||
protocolSpec
|
||||
.getBlockHashProcessor()
|
||||
.getBlockHashLookup(genesisBlock.getHeader(), blockchain);
|
||||
transactionProcessor =
|
||||
protocolSchedule
|
||||
.getByBlockHeader(new BlockHeaderTestFixture().number(0L).buildHeader())
|
||||
.getTransactionProcessor();
|
||||
blockHashLookup = new CachingBlockHashLookup(genesisBlock.getHeader(), blockchain);
|
||||
}
|
||||
|
||||
@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.diffbased.bonsai.worldview.BonsaiWorldState;
|
||||
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.tracing.OperationTracer;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldState;
|
||||
@@ -114,8 +115,7 @@ public abstract class AbstractBlockProcessor implements BlockProcessor {
|
||||
|
||||
final WorldUpdater worldStateUpdater = worldState.updater();
|
||||
|
||||
final BlockHashLookup blockHashLookup =
|
||||
protocolSpec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain);
|
||||
final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(blockHeader, blockchain);
|
||||
final Address miningBeneficiary =
|
||||
miningBeneficiaryCalculator.calculateBeneficiary(blockHeader);
|
||||
|
||||
|
||||
@@ -183,7 +183,6 @@ public class ClassicProtocolSpecs {
|
||||
messageCallProcessor,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
stackSizeLimit,
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.frontier()))
|
||||
@@ -373,7 +372,6 @@ public class ClassicProtocolSpecs {
|
||||
messageCallProcessor,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
stackSizeLimit,
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.frontier()))
|
||||
|
||||
@@ -143,7 +143,6 @@ public abstract class MainnetProtocolSpecs {
|
||||
messageCallProcessor,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
stackSizeLimit,
|
||||
FeeMarket.legacy(),
|
||||
CoinbaseFeePriceCalculator.frontier()))
|
||||
@@ -298,7 +297,6 @@ public abstract class MainnetProtocolSpecs {
|
||||
messageCallProcessor,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
stackSizeLimit,
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.frontier()))
|
||||
@@ -492,7 +490,6 @@ public abstract class MainnetProtocolSpecs {
|
||||
messageCallProcessor,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
stackSizeLimit,
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.eip1559()))
|
||||
@@ -630,7 +627,6 @@ public abstract class MainnetProtocolSpecs {
|
||||
messageCallProcessor,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
stackSizeLimit,
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.eip1559()))
|
||||
@@ -707,7 +703,6 @@ public abstract class MainnetProtocolSpecs {
|
||||
messageCallProcessor,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
stackSizeLimit,
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.eip1559()))
|
||||
@@ -786,7 +781,6 @@ public abstract class MainnetProtocolSpecs {
|
||||
messageCallProcessor,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
stackSizeLimit,
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.eip1559()))
|
||||
@@ -795,8 +789,7 @@ public abstract class MainnetProtocolSpecs {
|
||||
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::prague)
|
||||
.requestsValidator(pragueRequestsValidator(depositContractAddress))
|
||||
.requestProcessorCoordinator(pragueRequestsProcessors(depositContractAddress))
|
||||
.blockHashProcessor(
|
||||
new PragueBlockHashProcessor(genesisConfigOptions.getPragueTime().orElse(0)))
|
||||
.blockHashProcessor(new PragueBlockHashProcessor())
|
||||
.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.Transaction;
|
||||
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.privacy.storage.PrivateMetadataUpdater;
|
||||
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
|
||||
@@ -53,7 +52,6 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -74,7 +72,6 @@ public class MainnetTransactionProcessor {
|
||||
private final boolean clearEmptyAccounts;
|
||||
|
||||
protected final boolean warmCoinbase;
|
||||
protected final boolean warmBlockhash;
|
||||
|
||||
protected final FeeMarket feeMarket;
|
||||
private final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator;
|
||||
@@ -86,7 +83,6 @@ public class MainnetTransactionProcessor {
|
||||
final AbstractMessageProcessor messageCallProcessor,
|
||||
final boolean clearEmptyAccounts,
|
||||
final boolean warmCoinbase,
|
||||
final boolean warmBlockhash,
|
||||
final int maxStackSize,
|
||||
final FeeMarket feeMarket,
|
||||
final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator) {
|
||||
@@ -96,7 +92,6 @@ public class MainnetTransactionProcessor {
|
||||
this.messageCallProcessor = messageCallProcessor;
|
||||
this.clearEmptyAccounts = clearEmptyAccounts;
|
||||
this.warmCoinbase = warmCoinbase;
|
||||
this.warmBlockhash = warmBlockhash;
|
||||
this.maxStackSize = maxStackSize;
|
||||
this.feeMarket = feeMarket;
|
||||
this.coinbaseFeePriceCalculator = coinbaseFeePriceCalculator;
|
||||
@@ -327,15 +322,6 @@ public class MainnetTransactionProcessor {
|
||||
if (warmCoinbase) {
|
||||
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 =
|
||||
gasCalculator.transactionIntrinsicGasCost(
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
*/
|
||||
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.core.MutableWorldState;
|
||||
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;
|
||||
@@ -26,6 +24,4 @@ public interface BlockHashProcessor {
|
||||
Blockchain blockchain,
|
||||
MutableWorldState worldState,
|
||||
ProcessableBlockHeader currentBlockHeader);
|
||||
|
||||
BlockHashLookup getBlockHashLookup(ProcessableBlockHeader currentHeader, Blockchain blockchain);
|
||||
}
|
||||
|
||||
@@ -14,24 +14,15 @@
|
||||
*/
|
||||
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.core.MutableWorldState;
|
||||
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.plugin.data.ProcessableBlockHeader;
|
||||
|
||||
/** Processes the beacon block storage if it is present in the block header. */
|
||||
public class CancunBlockHashProcessor implements BlockHashProcessor {
|
||||
|
||||
@Override
|
||||
public BlockHashLookup getBlockHashLookup(
|
||||
final ProcessableBlockHeader currentHeader, final Blockchain blockchain) {
|
||||
return new CachingBlockHashLookup(currentHeader, blockchain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processBlockHashes(
|
||||
final Blockchain blockchain,
|
||||
|
||||
@@ -14,11 +14,8 @@
|
||||
*/
|
||||
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.core.MutableWorldState;
|
||||
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
|
||||
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;
|
||||
|
||||
public class FrontierBlockHashProcessor implements BlockHashProcessor {
|
||||
@@ -29,10 +26,4 @@ public class FrontierBlockHashProcessor implements BlockHashProcessor {
|
||||
final ProcessableBlockHeader currentBlockHeader) {
|
||||
// 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;
|
||||
|
||||
import static org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
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.evm.account.MutableAccount;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
@@ -44,53 +41,28 @@ public class PragueBlockHashProcessor extends CancunBlockHashProcessor {
|
||||
/** The HISTORY_SERVE_WINDOW */
|
||||
public static final long HISTORY_SERVE_WINDOW = 8192;
|
||||
|
||||
private final long forkTimestamp;
|
||||
private final long historySaveWindow;
|
||||
private final Address historyStorageAddress;
|
||||
|
||||
/**
|
||||
* Constructs a BlockHashProcessor with a specified fork timestamp.
|
||||
*
|
||||
* @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. */
|
||||
public PragueBlockHashProcessor() {
|
||||
this(HISTORY_STORAGE_ADDRESS, HISTORY_SERVE_WINDOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a BlockHashProcessor with a specified fork timestamp and history save window. This
|
||||
* constructor is primarily used for testing.
|
||||
* Constructs a BlockHashProcessor with a specified history save window. This constructor is
|
||||
* 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 historySaveWindow The number of blocks for which history should be saved.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public PragueBlockHashProcessor(
|
||||
final long forkTimestamp, final Address historyStorageAddress, final long historySaveWindow) {
|
||||
this.forkTimestamp = forkTimestamp;
|
||||
final Address historyStorageAddress, final long historySaveWindow) {
|
||||
this.historyStorageAddress = historyStorageAddress;
|
||||
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
|
||||
public void processBlockHashes(
|
||||
final Blockchain blockchain,
|
||||
@@ -99,21 +71,10 @@ public class PragueBlockHashProcessor extends CancunBlockHashProcessor {
|
||||
super.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader);
|
||||
|
||||
WorldUpdater worldUpdater = mutableWorldState.updater();
|
||||
final MutableAccount historyStorageAccount = worldUpdater.getOrCreate(HISTORY_STORAGE_ADDRESS);
|
||||
final MutableAccount historyStorageAccount = worldUpdater.getOrCreate(historyStorageAddress);
|
||||
|
||||
if (currentBlockHeader.getNumber() > 0) {
|
||||
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();
|
||||
}
|
||||
@@ -128,16 +89,6 @@ public class PragueBlockHashProcessor extends CancunBlockHashProcessor {
|
||||
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.
|
||||
*
|
||||
@@ -146,11 +97,10 @@ public class PragueBlockHashProcessor extends CancunBlockHashProcessor {
|
||||
* @param hash The hash to be stored.
|
||||
*/
|
||||
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(
|
||||
"Writing to {} {}=%{}",
|
||||
account.getAddress(),
|
||||
UInt256.valueOf(number % historySaveWindow).toDecimalString(),
|
||||
UInt256.fromBytes(hash).toHexString());
|
||||
account.setStorageValue(UInt256.valueOf(number % historySaveWindow), UInt256.fromBytes(hash));
|
||||
"Writing to {} {}=%{}", account.getAddress(), slot.toDecimalString(), value.toHexString());
|
||||
account.setStorageValue(slot, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap;
|
||||
import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage;
|
||||
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -166,7 +167,7 @@ public class PrivateStateRehydration {
|
||||
privateStateStorage,
|
||||
privateStateRootResolver,
|
||||
block,
|
||||
protocolSpec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain),
|
||||
new CachingBlockHashLookup(blockHeader, blockchain),
|
||||
pmtHashToPrivateTransactionMap,
|
||||
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.processing.TransactionProcessingResult;
|
||||
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.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.tracing.OperationTracer;
|
||||
@@ -139,7 +140,7 @@ public class PrivateTransactionSimulator {
|
||||
transaction,
|
||||
protocolSpec.getMiningBeneficiaryCalculator().calculateBeneficiary(header),
|
||||
OperationTracer.NO_TRACING,
|
||||
protocolSpec.getBlockHashProcessor().getBlockHashLookup(header, blockchain),
|
||||
new CachingBlockHashLookup(header, blockchain),
|
||||
privacyGroupId);
|
||||
|
||||
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.PrivacyGroupHeadBlockMap;
|
||||
import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage;
|
||||
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
|
||||
import java.util.List;
|
||||
@@ -112,7 +113,7 @@ public class PrivateStorageMigration {
|
||||
privateMigrationBlockProcessor.processBlock(
|
||||
blockchain,
|
||||
publicWorldState,
|
||||
protocolSpec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain),
|
||||
new CachingBlockHashLookup(blockHeader, blockchain),
|
||||
blockHeader,
|
||||
transactionsToProcess,
|
||||
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.TransactionValidationParams;
|
||||
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.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
@@ -279,9 +280,7 @@ public class TransactionSimulator {
|
||||
protocolSpec
|
||||
.getMiningBeneficiaryCalculator()
|
||||
.calculateBeneficiary(blockHeaderToProcess),
|
||||
protocolSpec
|
||||
.getBlockHashProcessor()
|
||||
.getBlockHashLookup(blockHeaderToProcess, blockchain),
|
||||
new CachingBlockHashLookup(blockHeaderToProcess, blockchain),
|
||||
false,
|
||||
transactionValidationParams,
|
||||
operationTracer,
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
package org.hyperledger.besu.ethereum.vm;
|
||||
|
||||
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.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.plugin.data.ProcessableBlockHeader;
|
||||
import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -38,32 +37,17 @@ public class CachingBlockHashLookup implements BlockHashLookup {
|
||||
|
||||
private ProcessableBlockHeader searchStartHeader;
|
||||
private final Blockchain blockchain;
|
||||
private final long maxLookback;
|
||||
|
||||
private final Map<Long, Hash> hashByNumber = new HashMap<>();
|
||||
|
||||
public CachingBlockHashLookup(
|
||||
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.blockchain = blockchain;
|
||||
this.maxLookback = maxLookback;
|
||||
hashByNumber.put(currentBlock.getNumber() - 1, currentBlock.getParentHash());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hash apply(final MessageFrame frame, final Long blockNumber) {
|
||||
long currentBlockNumber = frame.getBlockValues().getNumber();
|
||||
long lookback = currentBlockNumber - blockNumber;
|
||||
if (currentBlockNumber <= blockNumber || lookback > maxLookback) {
|
||||
return Hash.ZERO;
|
||||
}
|
||||
public Hash apply(final Long blockNumber) {
|
||||
final Hash cachedHash = hashByNumber.get(blockNumber);
|
||||
if (cachedHash != null) {
|
||||
return cachedHash;
|
||||
|
||||
@@ -84,7 +84,6 @@ class MainnetTransactionProcessorTest {
|
||||
messageCallProcessor,
|
||||
false,
|
||||
warmCoinbase,
|
||||
false,
|
||||
MAX_STACK_SIZE,
|
||||
FeeMarket.legacy(),
|
||||
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.PrivateTransactionDataFixture;
|
||||
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.PrivateStateRootResolver;
|
||||
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor;
|
||||
@@ -222,8 +221,6 @@ class PrivacyBlockProcessorTest {
|
||||
when(protocolSpec.getMiningBeneficiaryCalculator())
|
||||
.thenReturn(mock(MiningBeneficiaryCalculator.class));
|
||||
when(protocolSpec.isSkipZeroBlockRewards()).thenReturn(true);
|
||||
BlockHashProcessor blockHashProcessor = mock(BlockHashProcessor.class);
|
||||
when(protocolSpec.getBlockHashProcessor()).thenReturn(blockHashProcessor);
|
||||
return protocolSpec;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class BlockHashProcessorTest {
|
||||
private MutableAccount account;
|
||||
private BlockHashProcessor processor;
|
||||
|
||||
private long historicalWindow = 8192;
|
||||
private final long historicalWindow = 255;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
@@ -57,9 +57,8 @@ class BlockHashProcessorTest {
|
||||
|
||||
@Test
|
||||
void shouldStoreParentBlockHash() {
|
||||
long forkTimestamp = 0;
|
||||
long currentBlock = 3;
|
||||
processor = new PragueBlockHashProcessor(forkTimestamp);
|
||||
processor = new PragueBlockHashProcessor();
|
||||
BlockHeader currentBlockHeader = mockBlockHeader(currentBlock);
|
||||
mockAncestorHeaders(currentBlockHeader, 3);
|
||||
processor.processBlockHashes(blockchain, mutableWorldState, currentBlockHeader);
|
||||
@@ -72,9 +71,8 @@ class BlockHashProcessorTest {
|
||||
void shouldNotStoreBlockHashForGenesisBlock() {
|
||||
// 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.
|
||||
long forkTimestamp = 0;
|
||||
long currentBlock = 0;
|
||||
processor = new PragueBlockHashProcessor(forkTimestamp);
|
||||
processor = new PragueBlockHashProcessor();
|
||||
BlockHeader currentBlockHeader = mockBlockHeader(currentBlock);
|
||||
mockAncestorHeaders(currentBlockHeader, 0);
|
||||
|
||||
@@ -86,9 +84,8 @@ class BlockHashProcessorTest {
|
||||
void shouldStoreAncestorBlockHashesAtForkCorrectlyParentIsGenesis() {
|
||||
// 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.
|
||||
long forkTimestamp = 1;
|
||||
long currentBlock = 1;
|
||||
processor = new PragueBlockHashProcessor(forkTimestamp);
|
||||
processor = new PragueBlockHashProcessor();
|
||||
BlockHeader currentBlockHeader = mockBlockHeader(currentBlock);
|
||||
mockAncestorHeaders(currentBlockHeader, 10);
|
||||
|
||||
@@ -97,46 +94,9 @@ class BlockHashProcessorTest {
|
||||
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
|
||||
void shouldWriteGenesisHashAtSlot0() {
|
||||
processor = new PragueBlockHashProcessor(0);
|
||||
processor = new PragueBlockHashProcessor();
|
||||
BlockHeader header = mockBlockHeader(1);
|
||||
mockAncestorHeaders(header, 1);
|
||||
processor.processBlockHashes(blockchain, mutableWorldState, header);
|
||||
@@ -144,26 +104,11 @@ class BlockHashProcessorTest {
|
||||
.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) {
|
||||
verify(account)
|
||||
.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) {
|
||||
long firstAncestor = Math.max(blockHeader.getNumber() - count, 0);
|
||||
var block = blockHeader;
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
*/
|
||||
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.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
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.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.evm.frame.BlockValues;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup;
|
||||
|
||||
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.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CachingBlockHashLookupTest {
|
||||
|
||||
@Mock private Blockchain blockchain;
|
||||
@Mock private MessageFrame messageFrame;
|
||||
@Mock private BlockValues blockValues;
|
||||
|
||||
private static final int CURRENT_BLOCK_NUMBER = 300;
|
||||
private static final int CURRENT_BLOCK_NUMBER = 256;
|
||||
private final Blockchain blockchain = mock(Blockchain.class);
|
||||
private final BlockHeader[] headers = new BlockHeader[CURRENT_BLOCK_NUMBER];
|
||||
private BlockHashLookup lookup;
|
||||
|
||||
@@ -56,13 +50,10 @@ class CachingBlockHashLookupTest {
|
||||
BlockHeader parentHeader = null;
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
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;
|
||||
parentHeader = headers[i];
|
||||
}
|
||||
when(messageFrame.getBlockValues()).thenReturn(blockValues);
|
||||
when(blockValues.getNumber()).thenReturn((long) CURRENT_BLOCK_NUMBER);
|
||||
|
||||
lookup =
|
||||
new CachingBlockHashLookup(
|
||||
createHeader(CURRENT_BLOCK_NUMBER, headers[headers.length - 1]), blockchain);
|
||||
@@ -80,33 +71,20 @@ class CachingBlockHashLookupTest {
|
||||
assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGetHashOfGenesisBlock() {
|
||||
assertHashForBlockNumber(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGetHashForRecentBlockAfterOlderBlock() {
|
||||
assertHashForBlockNumber(100);
|
||||
assertHashForBlockNumber(10);
|
||||
assertHashForBlockNumber(CURRENT_BLOCK_NUMBER - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnEmptyHashWhenRequestedGenesis() {
|
||||
Assertions.assertThat(lookup.apply(messageFrame, 0L)).isEqualTo(Hash.ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnEmptyHashWhenRequestedTooFarBack() {
|
||||
Assertions.assertThat(lookup.apply(messageFrame, CURRENT_BLOCK_NUMBER - 260L))
|
||||
.isEqualTo(Hash.ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnEmptyHashWhenRequestedCurrentBlock() {
|
||||
Assertions.assertThat(lookup.apply(messageFrame, (long) CURRENT_BLOCK_NUMBER))
|
||||
.isEqualTo(Hash.ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnEmptyHashWhenRequestedBlockNotOnchain() {
|
||||
Assertions.assertThat(lookup.apply(messageFrame, CURRENT_BLOCK_NUMBER + 20L))
|
||||
.isEqualTo(Hash.ZERO);
|
||||
Assertions.assertThat(lookup.apply(CURRENT_BLOCK_NUMBER + 20L)).isEqualTo(Hash.ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -115,8 +93,7 @@ class CachingBlockHashLookupTest {
|
||||
new CachingBlockHashLookup(
|
||||
new BlockHeaderTestFixture().number(CURRENT_BLOCK_NUMBER + 20).buildHeader(),
|
||||
blockchain);
|
||||
Assertions.assertThat(
|
||||
lookupWithUnavailableParent.apply(messageFrame, (long) CURRENT_BLOCK_NUMBER))
|
||||
Assertions.assertThat(lookupWithUnavailableParent.apply((long) CURRENT_BLOCK_NUMBER))
|
||||
.isEqualTo(Hash.ZERO);
|
||||
}
|
||||
|
||||
@@ -137,7 +114,7 @@ class CachingBlockHashLookupTest {
|
||||
}
|
||||
|
||||
private void assertHashForBlockNumber(final int blockNumber) {
|
||||
Assertions.assertThat(lookup.apply(messageFrame, (long) blockNumber))
|
||||
Assertions.assertThat(lookup.apply((long) blockNumber))
|
||||
.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.mainnet.MainnetBlockHeaderFunctions;
|
||||
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.EVM;
|
||||
import org.hyperledger.besu.evm.EvmSpecVersion;
|
||||
@@ -429,10 +430,7 @@ public class EvmToolCommand implements Runnable {
|
||||
.blockValues(blockHeader)
|
||||
.completer(c -> {})
|
||||
.miningBeneficiary(blockHeader.getCoinbase())
|
||||
.blockHashLookup(
|
||||
protocolSpec
|
||||
.getBlockHashProcessor()
|
||||
.getBlockHashLookup(blockHeader, component.getBlockchain()))
|
||||
.blockHashLookup(new CachingBlockHashLookup(blockHeader, component.getBlockchain()))
|
||||
.accessListWarmAddresses(addressList)
|
||||
.build();
|
||||
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.referencetests.GeneralStateTestCaseEipSpec;
|
||||
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.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
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.StandardJsonTracer;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
@@ -251,31 +248,13 @@ public class StateTestSubCommand implements Runnable {
|
||||
final Stopwatch timer = Stopwatch.createStarted();
|
||||
// Todo: EIP-4844 use the excessBlobGas of the parent instead of 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 =
|
||||
processor.processTransaction(
|
||||
worldStateUpdater,
|
||||
blockHeader,
|
||||
transaction,
|
||||
blockHeader.getCoinbase(),
|
||||
blockHashLookup,
|
||||
blockNumber -> Hash.hash(Bytes.wrap(Long.toString(blockNumber).getBytes(UTF_8))),
|
||||
false,
|
||||
TransactionValidationParams.processingBlock(),
|
||||
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.BytesValueRLPOutput;
|
||||
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.gascalculator.GasCalculator;
|
||||
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.worldstate.WorldUpdater;
|
||||
import org.hyperledger.besu.evmtool.exception.UnsupportedForkException;
|
||||
@@ -291,27 +289,13 @@ public class T8nExecutor {
|
||||
tracer = tracerManager.getManagedTracer(i, transaction.getHash());
|
||||
tracer.tracePrepareTransaction(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 =
|
||||
processor.processTransaction(
|
||||
worldStateUpdater,
|
||||
blockHeader,
|
||||
transaction,
|
||||
blockHeader.getCoinbase(),
|
||||
blockHashLookup,
|
||||
number -> referenceTestEnv.getBlockhashByNumber(number).orElse(Hash.ZERO),
|
||||
false,
|
||||
TransactionValidationParams.processingBlock(),
|
||||
tracer,
|
||||
|
||||
@@ -62,7 +62,7 @@ public abstract class BenchmarkExecutor {
|
||||
.code(CodeV0.EMPTY_CODE)
|
||||
.completer(__ -> {})
|
||||
.address(Address.ZERO)
|
||||
.blockHashLookup((f, n) -> null)
|
||||
.blockHashLookup(n -> null)
|
||||
.blockValues(new SimpleBlockValues())
|
||||
.gasPrice(Wei.ZERO)
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
|
||||
@@ -106,9 +106,6 @@ public class GeneralStateReferenceTestTools {
|
||||
|
||||
// EOF tests are written against an older version of the spec
|
||||
params.ignore("/stEOF/");
|
||||
|
||||
// None of the Prague tests have withdrawls and deposits handling
|
||||
params.ignore("-Prague$");
|
||||
}
|
||||
|
||||
private GeneralStateReferenceTestTools() {
|
||||
@@ -160,7 +157,7 @@ public class GeneralStateReferenceTestTools {
|
||||
blockHeader,
|
||||
transaction,
|
||||
blockHeader.getCoinbase(),
|
||||
protocolSpec.getBlockHashProcessor().getBlockHashLookup(blockHeader, blockchain),
|
||||
new CachingBlockHashLookup(blockHeader, blockchain),
|
||||
false,
|
||||
TransactionValidationParams.processingBlock(),
|
||||
blobGasPrice);
|
||||
|
||||
@@ -72,7 +72,7 @@ public class EVMExecutor {
|
||||
private Wei ethValue = Wei.ZERO;
|
||||
private Code code = CodeV0.EMPTY_CODE;
|
||||
private BlockValues blockValues = new SimpleBlockValues();
|
||||
private BlockHashLookup blockHashLookup = (h, n) -> null;
|
||||
private BlockHashLookup blockHashLookup = n -> null;
|
||||
private Optional<List<VersionedHash>> versionedHashes = Optional.empty();
|
||||
private OperationTracer tracer = OperationTracer.NO_TRACING;
|
||||
private boolean requireDeposit = true;
|
||||
|
||||
@@ -16,7 +16,6 @@ package org.hyperledger.besu.evm.frame;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
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.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.UnderflowException;
|
||||
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.worldstate.WorldUpdater;
|
||||
|
||||
@@ -1427,9 +1427,6 @@ public class MessageFrame {
|
||||
|
||||
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
|
||||
* ignored if passed in via builder
|
||||
|
||||
@@ -392,7 +392,7 @@ public class FrontierGasCalculator implements GasCalculator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBlockHashOperationGasCost(final MessageFrame frame) {
|
||||
public long getBlockHashOperationGasCost() {
|
||||
return BLOCKHASH_OPERATION_GAS_COST;
|
||||
}
|
||||
|
||||
|
||||
@@ -345,10 +345,9 @@ public interface GasCalculator {
|
||||
/**
|
||||
* Returns the cost for executing a {@link BlockHashOperation}.
|
||||
*
|
||||
* @param frame The current frame
|
||||
* @return the cost for executing the block hash operation
|
||||
*/
|
||||
long getBlockHashOperationGasCost(MessageFrame frame);
|
||||
long getBlockHashOperationGasCost();
|
||||
|
||||
/**
|
||||
* 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.frame.MessageFrame;
|
||||
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
|
||||
/**
|
||||
* Gas Calculator for Prague
|
||||
*
|
||||
@@ -101,24 +99,4 @@ public class PragueGasCalculator extends CancunGasCalculator {
|
||||
|
||||
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.evm.EVM;
|
||||
import org.hyperledger.besu.evm.frame.BlockValues;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
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.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
|
||||
/** The Block hash operation. */
|
||||
public class BlockHashOperation extends AbstractOperation {
|
||||
|
||||
/** Frontier maximum relative block delta */
|
||||
public static final int MAX_RELATIVE_BLOCK = 256;
|
||||
public class BlockHashOperation extends AbstractFixedCostOperation {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Result is the Hash, which may be zero based on lookup rules.
|
||||
* <p>Arg is the current block number. The Result is the Hash, which may be zero based on lookup
|
||||
* 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;
|
||||
|
||||
@@ -46,25 +48,36 @@ public class BlockHashOperation extends AbstractOperation {
|
||||
* @param gasCalculator the gas calculator
|
||||
*/
|
||||
public BlockHashOperation(final GasCalculator gasCalculator) {
|
||||
super(0x40, "BLOCKHASH", 1, 1, gasCalculator);
|
||||
super(0x40, "BLOCKHASH", 1, 1, gasCalculator, gasCalculator.getBlockHashOperationGasCost());
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationResult execute(MessageFrame frame, EVM evm) {
|
||||
public Operation.OperationResult executeFixedCostOperation(
|
||||
final MessageFrame frame, final EVM evm) {
|
||||
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) {
|
||||
frame.pushStackItem(UInt256.ZERO);
|
||||
return new OperationResult(gasCalculator().getBlockHashOperationGasCost(null), null);
|
||||
return successResponse;
|
||||
}
|
||||
|
||||
final long soughtBlock = blockArg.toLong();
|
||||
final BlockHashLookup blockHashLookup = frame.getBlockHashLookup();
|
||||
final Hash blockHash = blockHashLookup.apply(frame, soughtBlock);
|
||||
frame.pushStackItem(blockHash);
|
||||
return new OperationResult(
|
||||
gasCalculator().getBlockHashOperationGasCost(Hash.ZERO.equals(blockHash) ? null : frame),
|
||||
null);
|
||||
final BlockValues blockValues = frame.getBlockValues();
|
||||
final long currentBlockNumber = blockValues.getNumber();
|
||||
|
||||
// If the current block is the genesis block or the sought block is
|
||||
// not within the last 256 completed blocks, zero is returned.
|
||||
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))
|
||||
.completer(f -> {})
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
.blockHashLookup((f, n) -> Hash.EMPTY)
|
||||
.blockHashLookup(l -> Hash.EMPTY)
|
||||
.build();
|
||||
|
||||
frame.setPC(CURRENT_PC);
|
||||
|
||||
@@ -188,7 +188,7 @@ class EVMExecutorTest {
|
||||
.number(1)
|
||||
.timestamp(100L)
|
||||
.gasLimit(15_000_000L)
|
||||
.blockHashLookup((height, number) -> Hash.ZERO)
|
||||
.blockHashLookup(number -> Hash.ZERO)
|
||||
.versionedHashes(Optional.empty())
|
||||
.precompileContractRegistry(new PrecompileContractRegistry())
|
||||
.requireDeposit(false)
|
||||
|
||||
@@ -48,7 +48,7 @@ class MessageFrameTest {
|
||||
.blobGasPrice(Wei.ONE)
|
||||
.blockValues(new ToyBlockValues())
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
.blockHashLookup((f, n) -> Hash.ZERO)
|
||||
.blockHashLookup((l) -> Hash.ZERO)
|
||||
.type(MessageFrame.Type.MESSAGE_CALL)
|
||||
.initialGas(1)
|
||||
.address(Address.ZERO)
|
||||
|
||||
@@ -169,7 +169,7 @@ class AbstractCreateOperationTest {
|
||||
.code(CodeFactory.createCode(SIMPLE_CREATE, 0, true))
|
||||
.completer(__ -> {})
|
||||
.address(Address.fromHexString(SENDER))
|
||||
.blockHashLookup((f, n) -> Hash.hash(Words.longBytes(n)))
|
||||
.blockHashLookup(n -> Hash.hash(Words.longBytes(n)))
|
||||
.blockValues(mock(BlockValues.class))
|
||||
.gasPrice(Wei.ZERO)
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
package org.hyperledger.besu.evm.operations;
|
||||
|
||||
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.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.gascalculator.FrontierGasCalculator;
|
||||
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.TestMessageFrameBuilder;
|
||||
|
||||
@@ -31,20 +31,49 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
class BlockHashOperationTest {
|
||||
|
||||
private static final int MAXIMUM_COMPLETE_BLOCKS_BEHIND = 256;
|
||||
private final BlockHashOperation blockHashOperation =
|
||||
new BlockHashOperation(new FrontierGasCalculator());
|
||||
|
||||
@Test
|
||||
void shouldReturnZeroWhenArgIsBiggerThanALong() {
|
||||
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
|
||||
void shouldReturnBlockHashUsingLookupFromFrameWhenItIsWithinTheAllowedRange() {
|
||||
final Hash blockHash = Hash.hash(Bytes.fromHexString("0x1293487297"));
|
||||
assertBlockHash(
|
||||
100, blockHash, 200, (h, block) -> block == 100 ? blockHash : Hash.EMPTY_LIST_HASH);
|
||||
assertBlockHash(100, blockHash, 200, block -> block == 100 ? blockHash : Hash.EMPTY_LIST_HASH);
|
||||
}
|
||||
|
||||
private void assertBlockHash(
|
||||
|
||||
@@ -155,7 +155,7 @@ public class Create2OperationTest {
|
||||
.code(CodeFactory.createCode(codeBytes, 0, true))
|
||||
.completer(__ -> {})
|
||||
.address(Address.fromHexString(sender))
|
||||
.blockHashLookup((f, n) -> Hash.hash(Words.longBytes(n)))
|
||||
.blockHashLookup(n -> Hash.hash(Words.longBytes(n)))
|
||||
.blockValues(mock(BlockValues.class))
|
||||
.gasPrice(Wei.ZERO)
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
@@ -269,7 +269,7 @@ public class Create2OperationTest {
|
||||
.code(CodeFactory.createCode(SIMPLE_CREATE, 0, true))
|
||||
.completer(__ -> {})
|
||||
.address(Address.fromHexString(SENDER))
|
||||
.blockHashLookup((f, n) -> Hash.hash(Words.longBytes(n)))
|
||||
.blockHashLookup(n -> Hash.hash(Words.longBytes(n)))
|
||||
.blockValues(mock(BlockValues.class))
|
||||
.gasPrice(Wei.ZERO)
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
|
||||
@@ -289,7 +289,7 @@ class CreateOperationTest {
|
||||
.code(CodeFactory.createCode(SIMPLE_CREATE, 0, true))
|
||||
.completer(__ -> {})
|
||||
.address(Address.fromHexString(SENDER))
|
||||
.blockHashLookup((f, n) -> Hash.hash(Words.longBytes(n)))
|
||||
.blockHashLookup(n -> Hash.hash(Words.longBytes(n)))
|
||||
.blockValues(mock(BlockValues.class))
|
||||
.gasPrice(Wei.ZERO)
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
|
||||
@@ -82,7 +82,7 @@ public class SelfDestructOperationTest {
|
||||
.code(CodeFactory.createCode(SELFDESTRUCT_CODE, 0, true))
|
||||
.completer(__ -> {})
|
||||
.address(originatorAddress)
|
||||
.blockHashLookup((f, n) -> Hash.hash(Words.longBytes(n)))
|
||||
.blockHashLookup(n -> Hash.hash(Words.longBytes(n)))
|
||||
.blockValues(mock(BlockValues.class))
|
||||
.gasPrice(Wei.ZERO)
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
|
||||
@@ -65,7 +65,7 @@ public class Benchmarks {
|
||||
.code(CodeV0.EMPTY_CODE)
|
||||
.completer(__ -> {})
|
||||
.address(Address.ZERO)
|
||||
.blockHashLookup((f, n) -> null)
|
||||
.blockHashLookup(n -> null)
|
||||
.blockValues(new SimpleBlockValues())
|
||||
.gasPrice(Wei.ZERO)
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package org.hyperledger.besu.evm.testutils;
|
||||
|
||||
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.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.MessageFrame;
|
||||
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.worldstate.WorldUpdater;
|
||||
|
||||
@@ -161,7 +161,7 @@ public class TestMessageFrameBuilder {
|
||||
.blockValues(blockValues.orElseGet(() -> new FakeBlockValues(1337)))
|
||||
.completer(c -> {})
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
.blockHashLookup(blockHashLookup.orElse((f, n) -> Hash.hash(Words.longBytes(n))))
|
||||
.blockHashLookup(blockHashLookup.orElse(number -> Hash.hash(Words.longBytes(number))))
|
||||
.maxStackSize(maxStackSize)
|
||||
.build();
|
||||
frame.setPC(pc);
|
||||
|
||||
@@ -190,7 +190,7 @@ public class EvmToyCommand implements Runnable {
|
||||
.blockValues(new ToyBlockValues())
|
||||
.completer(c -> {})
|
||||
.miningBeneficiary(Address.ZERO)
|
||||
.blockHashLookup((f, n) -> null)
|
||||
.blockHashLookup(n -> null)
|
||||
.build();
|
||||
|
||||
final MessageCallProcessor mcp = new MessageCallProcessor(evm, precompileContractRegistry);
|
||||
|
||||
Reference in New Issue
Block a user