mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-08 20:47:59 -05:00
Merge branch 'main' into zkbesu
# Conflicts: # build.gradle
This commit is contained in:
@@ -22,7 +22,9 @@ import org.hyperledger.besu.tests.acceptance.dsl.transaction.eth.EthTransactions
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.MediaType;
|
||||
@@ -74,17 +76,15 @@ public class PragueAcceptanceTestHelper {
|
||||
final Call getPayloadRequest = createEngineCall(createGetPayloadRequest(payloadId));
|
||||
|
||||
final ObjectNode executionPayload;
|
||||
final ArrayNode executionRequests;
|
||||
final String newBlockHash;
|
||||
final String parentBeaconBlockRoot;
|
||||
try (final Response getPayloadResponse = getPayloadRequest.execute()) {
|
||||
assertThat(getPayloadResponse.code()).isEqualTo(200);
|
||||
|
||||
executionPayload =
|
||||
(ObjectNode)
|
||||
mapper
|
||||
.readTree(getPayloadResponse.body().string())
|
||||
.get("result")
|
||||
.get("executionPayload");
|
||||
JsonNode result = mapper.readTree(getPayloadResponse.body().string()).get("result");
|
||||
executionPayload = (ObjectNode) result.get("executionPayload");
|
||||
executionRequests = (ArrayNode) result.get("executionRequests");
|
||||
|
||||
newBlockHash = executionPayload.get("blockHash").asText();
|
||||
parentBeaconBlockRoot = executionPayload.remove("parentBeaconBlockRoot").asText();
|
||||
@@ -94,7 +94,8 @@ public class PragueAcceptanceTestHelper {
|
||||
|
||||
final Call newPayloadRequest =
|
||||
createEngineCall(
|
||||
createNewPayloadRequest(executionPayload.toString(), parentBeaconBlockRoot));
|
||||
createNewPayloadRequest(
|
||||
executionPayload.toString(), parentBeaconBlockRoot, executionRequests.toString()));
|
||||
try (final Response newPayloadResponse = newPayloadRequest.execute()) {
|
||||
assertThat(newPayloadResponse.code()).isEqualTo(200);
|
||||
}
|
||||
@@ -168,7 +169,9 @@ public class PragueAcceptanceTestHelper {
|
||||
}
|
||||
|
||||
private String createNewPayloadRequest(
|
||||
final String executionPayload, final String parentBeaconBlockRoot) {
|
||||
final String executionPayload,
|
||||
final String parentBeaconBlockRoot,
|
||||
final String executionRequests) {
|
||||
return "{"
|
||||
+ " \"jsonrpc\": \"2.0\","
|
||||
+ " \"method\": \"engine_newPayloadV4\","
|
||||
@@ -178,6 +181,8 @@ public class PragueAcceptanceTestHelper {
|
||||
+ "\""
|
||||
+ parentBeaconBlockRoot
|
||||
+ "\""
|
||||
+ ","
|
||||
+ executionRequests
|
||||
+ "],"
|
||||
+ " \"id\": 67"
|
||||
+ "}";
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -12,14 +12,14 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"number": "0x0",
|
||||
"hash" : "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5",
|
||||
"hash" : "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896",
|
||||
"mixHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"nonce" : "0x0000000000000042",
|
||||
"sha3Uncles" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactionsRoot" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"stateRoot" : "0x3ed8435adb5f3526144e6babdd3fc8c661a86097cf7e743441b41fda096fc4dd",
|
||||
"stateRoot" : "0x860be6ab5a8fc2003c3739bfe2cdbcd9dbb273c8ea42951b832a8e1f22fb3a60",
|
||||
"receiptsRoot" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"miner" : "0x0000000000000000000000000000000000000000",
|
||||
"difficulty" : "0x400000000",
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"method": "engine_forkchoiceUpdatedV3",
|
||||
"params": [
|
||||
{
|
||||
"headBlockHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5",
|
||||
"safeBlockHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5",
|
||||
"headBlockHash": "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896",
|
||||
"safeBlockHash": "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896",
|
||||
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
},
|
||||
{
|
||||
@@ -24,10 +24,10 @@
|
||||
"result": {
|
||||
"payloadStatus": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5",
|
||||
"latestValidHash": "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896",
|
||||
"validationError": null
|
||||
},
|
||||
"payloadId": "0x28264396eca1deef"
|
||||
"payloadId": "0x282643b677b85211"
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"jsonrpc": "2.0",
|
||||
"method": "engine_getPayloadV3",
|
||||
"params": [
|
||||
"0x28264396eca1deef"
|
||||
"0x282643b677b85211"
|
||||
],
|
||||
"id": 67
|
||||
},
|
||||
@@ -12,9 +12,9 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"executionPayload": {
|
||||
"parentHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5",
|
||||
"parentHash": "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x3ed8435adb5f3526144e6babdd3fc8c661a86097cf7e743441b41fda096fc4dd",
|
||||
"stateRoot": "0x860be6ab5a8fc2003c3739bfe2cdbcd9dbb273c8ea42951b832a8e1f22fb3a60",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -29,7 +29,7 @@
|
||||
"blockNumber": "0x1",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"blobGasUsed": "0x0",
|
||||
"blockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593"
|
||||
"blockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e"
|
||||
},
|
||||
"blockValue": "0x0",
|
||||
"blobsBundle": {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"method": "engine_newPayloadV3",
|
||||
"params": [
|
||||
{
|
||||
"parentHash": "0x38d7daa68e8bac41a0a237b7cbfcef480cb9bd9adc7b282d7b0d23ff4eb8d6e5",
|
||||
"parentHash": "0x01f5cbf33268c161f1526d704268db760bf82c9772a8f8ca412e0c6ce5684896",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x3ed8435adb5f3526144e6babdd3fc8c661a86097cf7e743441b41fda096fc4dd",
|
||||
"stateRoot": "0x860be6ab5a8fc2003c3739bfe2cdbcd9dbb273c8ea42951b832a8e1f22fb3a60",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -14,13 +14,13 @@
|
||||
"timestamp": "0x10",
|
||||
"extraData": "0x",
|
||||
"baseFeePerGas": "0x7",
|
||||
"excessBlobGas": "0x0",
|
||||
"transactions": [],
|
||||
"withdrawals": [],
|
||||
"blockNumber": "0x1",
|
||||
"blockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"excessBlobGas": "0x0",
|
||||
"blobGasUsed": "0x0"
|
||||
"blobGasUsed": "0x0",
|
||||
"blockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
||||
},
|
||||
[],
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
@@ -32,7 +32,7 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593",
|
||||
"latestValidHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e",
|
||||
"validationError": null
|
||||
}
|
||||
},
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"method": "engine_forkchoiceUpdatedV3",
|
||||
"params": [
|
||||
{
|
||||
"headBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593",
|
||||
"safeBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593",
|
||||
"finalizedBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593"
|
||||
"headBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e",
|
||||
"safeBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e",
|
||||
"finalizedBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e"
|
||||
},
|
||||
null
|
||||
],
|
||||
@@ -18,7 +18,7 @@
|
||||
"result": {
|
||||
"payloadStatus": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593",
|
||||
"latestValidHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e",
|
||||
"validationError": null
|
||||
},
|
||||
"payloadId": null
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"method": "engine_forkchoiceUpdatedV3",
|
||||
"params": [
|
||||
{
|
||||
"headBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593",
|
||||
"safeBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593",
|
||||
"finalizedBlockHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593"
|
||||
"headBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e",
|
||||
"safeBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e",
|
||||
"finalizedBlockHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e"
|
||||
},
|
||||
{
|
||||
"timestamp": "0x20",
|
||||
@@ -24,10 +24,10 @@
|
||||
"result": {
|
||||
"payloadStatus": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593",
|
||||
"latestValidHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e",
|
||||
"validationError": null
|
||||
},
|
||||
"payloadId": "0x282643d3a905e721"
|
||||
"payloadId": "0x282643fdcbcb1ddf"
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"jsonrpc": "2.0",
|
||||
"method": "engine_getPayloadV4",
|
||||
"params": [
|
||||
"0x282643d3a905e721"
|
||||
"0x282643fdcbcb1ddf"
|
||||
],
|
||||
"id": 67
|
||||
},
|
||||
@@ -12,9 +12,9 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"executionPayload": {
|
||||
"parentHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593",
|
||||
"parentHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x2e59916a57b535875bcd80d8472aeaa0027aa685d159804e8caa2f12d060155e",
|
||||
"stateRoot": "0xed4093bcd157ba955245906a1cda7695d3b3f233af709f0adf17689abb4d93b4",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -23,22 +23,13 @@
|
||||
"extraData": "0x",
|
||||
"baseFeePerGas": "0x7",
|
||||
"excessBlobGas": "0x0",
|
||||
"blobGasUsed": "0x0",
|
||||
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactions": [],
|
||||
"withdrawals": [],
|
||||
"depositRequests": [],
|
||||
"withdrawalRequests": [
|
||||
{
|
||||
"sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb",
|
||||
"validatorPubkey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e",
|
||||
"amount": "0x0"
|
||||
}
|
||||
],
|
||||
"consolidationRequests" : [],
|
||||
"blockNumber": "0x2",
|
||||
"blockHash": "0x27a2bc2ac21b3fc796f636bec1ec9cba100435f9a793176a83a5d4fa7cc13006",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"blobGasUsed": "0x0"
|
||||
"blockHash": "0x303fb51567c090ed3fb7ac50a082ae3a0bcb8ff522d071011a1ca433561a4569"
|
||||
},
|
||||
"blockValue": "0x0",
|
||||
"blobsBundle": {
|
||||
@@ -46,7 +37,12 @@
|
||||
"proofs": [],
|
||||
"blobs": []
|
||||
},
|
||||
"shouldOverrideBuilder": false
|
||||
"shouldOverrideBuilder": false,
|
||||
"executionRequests": [
|
||||
"0x",
|
||||
"0xa4664c40aacebd82a2db79f0ea36c06bc6a19adbb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0000000000000000",
|
||||
"0x"
|
||||
]
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
|
||||
@@ -17,24 +17,24 @@
|
||||
"excessBlobGas": "0x0",
|
||||
"transactions": [],
|
||||
"withdrawals": [],
|
||||
"depositRequests": null,
|
||||
"blockNumber": "0x2",
|
||||
"blockHash": "0x2331b2dc9c453e9a33685099742cbbcd529d42bd5681969f45754f06866c6766",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"blobGasUsed": "0x0"
|
||||
},
|
||||
[],
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
null
|
||||
],
|
||||
"id": 67
|
||||
},
|
||||
"response": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 67,
|
||||
"error": {
|
||||
"code": -32602,
|
||||
"message": "Invalid params",
|
||||
"data": "Missing deposit field"
|
||||
"jsonrpc" : "2.0",
|
||||
"id" : 67,
|
||||
"error" : {
|
||||
"code" : -32602,
|
||||
"message" : "Invalid execution requests params",
|
||||
"data" : "Missing execution requests field"
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
@@ -4,9 +4,9 @@
|
||||
"method": "engine_newPayloadV4",
|
||||
"params": [
|
||||
{
|
||||
"parentHash": "0x8082deff44f79489ea92415be59afb48b6f46b939553f855479828a6f87f9593",
|
||||
"parentHash": "0x7cccf6d9ce3e5acaeac9058959c27ace53af3a30b15763e1703bab2d0ae9438e",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x961878fdcdff52ea42db0026f59aa414a5ec2835e56ed1a8ae50c80a9fe3a04b",
|
||||
"stateRoot": "0x176ea6dfa3b8efb148a025f759cccfaab02db38427b12a4ede73491eda397196",
|
||||
"logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -15,34 +15,22 @@
|
||||
"extraData": "0x",
|
||||
"baseFeePerGas": "0x7",
|
||||
"excessBlobGas": "0x0",
|
||||
"blobGasUsed": "0x0",
|
||||
"transactions": [
|
||||
"0x02f9021c8217de808459682f008459682f0e830271009442424242424242424242424242424242424242428901bc16d674ec800000b901a422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120749715de5d1226545c6b3790f515d551a5cc5bf1d49c87a696860554d2fc4f14000000000000000000000000000000000000000000000000000000000000003096a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef20000000000000000000000000000000000000000000000000000000000000060b1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9c080a09f597089338d7f44f5c59f8230bb38f243849228a8d4e9d2e2956e6050f5b2c7a076486996c7e62802b8f95eee114783e4b403fd11093ba96286ff42c595f24452"
|
||||
],
|
||||
"withdrawals": [],
|
||||
"depositRequests": [
|
||||
{
|
||||
"amount": "0x773594000",
|
||||
"index": "0x0",
|
||||
"pubkey": "0x96a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9",
|
||||
"signature": "0xb1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9",
|
||||
"withdrawalCredentials": "0x003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef2"
|
||||
}
|
||||
],
|
||||
"withdrawalRequests": [
|
||||
{
|
||||
"sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb",
|
||||
"amount": "0x0",
|
||||
"validatorPubkey": "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"
|
||||
}
|
||||
],
|
||||
"consolidationRequests": [],
|
||||
"blockNumber": "0x2",
|
||||
"blockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca",
|
||||
"receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9",
|
||||
"blobGasUsed": "0x0"
|
||||
"blockHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6"
|
||||
},
|
||||
[],
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
[
|
||||
"0xf84794a4664c40aacebd82a2db79f0ea36c06bc6a19adbb0b10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e80",
|
||||
"0xa4664c40aacebd82a2db79f0ea36c06bc6a19adbb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0000000000000000",
|
||||
"0x"
|
||||
]
|
||||
],
|
||||
"id": 67
|
||||
},
|
||||
@@ -51,7 +39,7 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca",
|
||||
"latestValidHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6",
|
||||
"validationError": null
|
||||
}
|
||||
},
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"method": "engine_forkchoiceUpdatedV3",
|
||||
"params": [
|
||||
{
|
||||
"headBlockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca",
|
||||
"safeBlockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca",
|
||||
"finalizedBlockHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca"
|
||||
"headBlockHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6",
|
||||
"safeBlockHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6",
|
||||
"finalizedBlockHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6"
|
||||
},
|
||||
{
|
||||
"timestamp": "0x30",
|
||||
@@ -24,10 +24,10 @@
|
||||
"result": {
|
||||
"payloadStatus": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca",
|
||||
"latestValidHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6",
|
||||
"validationError": null
|
||||
},
|
||||
"payloadId": "0x282643a16a58b5cf"
|
||||
"payloadId": "0x282643aeecfdbccf"
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"jsonrpc": "2.0",
|
||||
"method": "engine_getPayloadV4",
|
||||
"params": [
|
||||
"0x282643a16a58b5cf"
|
||||
"0x282643aeecfdbccf"
|
||||
],
|
||||
"id": 67
|
||||
},
|
||||
@@ -12,9 +12,9 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"executionPayload": {
|
||||
"parentHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca",
|
||||
"parentHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x5fc31c01a451fe02f0e938de7ec7044aaba1159a81a1be64357bc70af226f304",
|
||||
"stateRoot": "0xade3c29cae771ddfa994d3d2994f3bcbe084bc7bb23cdbb9bd7e35b39f007841",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -23,16 +23,13 @@
|
||||
"extraData": "0x",
|
||||
"baseFeePerGas": "0x7",
|
||||
"excessBlobGas": "0x0",
|
||||
"blobGasUsed": "0x0",
|
||||
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactions": [],
|
||||
"withdrawals": [],
|
||||
"depositRequests": [],
|
||||
"withdrawalRequests": [],
|
||||
"consolidationRequests" : [],
|
||||
"blockNumber": "0x3",
|
||||
"blockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"blobGasUsed": "0x0"
|
||||
"blockHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929"
|
||||
},
|
||||
"blockValue": "0x0",
|
||||
"blobsBundle": {
|
||||
@@ -40,7 +37,12 @@
|
||||
"proofs": [],
|
||||
"blobs": []
|
||||
},
|
||||
"shouldOverrideBuilder": false
|
||||
"shouldOverrideBuilder": false,
|
||||
"executionRequests": [
|
||||
"0x",
|
||||
"0x",
|
||||
"0x"
|
||||
]
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"method": "engine_newPayloadV3",
|
||||
"params": [
|
||||
{
|
||||
"parentHash": "0xc67a660f5d3c20ee603911bdff1e409e976f306883dff8ef4999dca3176f7dca",
|
||||
"parentHash": "0x14ba5ec415d827d9cab33e6097b307131e8119a1cd7dc1f6a4de088ebfa4c1b6",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x5fc31c01a451fe02f0e938de7ec7044aaba1159a81a1be64357bc70af226f304",
|
||||
"stateRoot": "0xade3c29cae771ddfa994d3d2994f3bcbe084bc7bb23cdbb9bd7e35b39f007841",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
@@ -14,18 +14,21 @@
|
||||
"timestamp": "0x30",
|
||||
"extraData": "0x",
|
||||
"baseFeePerGas": "0x7",
|
||||
"excessBlobGas": "0x0",
|
||||
"blobGasUsed": "0x0",
|
||||
"transactions": [],
|
||||
"withdrawals": [],
|
||||
"depositRequests": [],
|
||||
"withdrawalRequests": [],
|
||||
"blockNumber": "0x3",
|
||||
"blockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"excessBlobGas": "0x0",
|
||||
"blobGasUsed": "0x0"
|
||||
"blockHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929"
|
||||
},
|
||||
[],
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
[
|
||||
"0x",
|
||||
"0x",
|
||||
"0x"
|
||||
]
|
||||
],
|
||||
"id": 67
|
||||
},
|
||||
@@ -34,7 +37,7 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634",
|
||||
"latestValidHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929",
|
||||
"validationError": null
|
||||
}
|
||||
},
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"method": "engine_forkchoiceUpdatedV3",
|
||||
"params": [
|
||||
{
|
||||
"headBlockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634",
|
||||
"safeBlockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634",
|
||||
"finalizedBlockHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634"
|
||||
"headBlockHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929",
|
||||
"safeBlockHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929",
|
||||
"finalizedBlockHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929"
|
||||
},
|
||||
{
|
||||
"timestamp": "0x40",
|
||||
@@ -24,10 +24,10 @@
|
||||
"result": {
|
||||
"payloadStatus": {
|
||||
"status": "VALID",
|
||||
"latestValidHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634",
|
||||
"latestValidHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929",
|
||||
"validationError": null
|
||||
},
|
||||
"payloadId": "0x28264396a9634d41"
|
||||
"payloadId": "0x282643ae671b03bf"
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"jsonrpc": "2.0",
|
||||
"method": "engine_getPayloadV4",
|
||||
"params": [
|
||||
"0x28264396a9634d41"
|
||||
"0x282643ae671b03bf"
|
||||
],
|
||||
"id": 67
|
||||
},
|
||||
@@ -12,50 +12,40 @@
|
||||
"id": 67,
|
||||
"result": {
|
||||
"executionPayload": {
|
||||
"parentHash": "0xdbb55a049f14b8152695bf3bbd754aa1fd55bbe10b306eb49caa4bd7d7fcb634",
|
||||
"parentHash": "0x9f157012bdc439f5fe2bb3b4236eb07043e35d16256557d73e80a95d20054929",
|
||||
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"stateRoot": "0x49df1f1a1d28a23fa752230d442077768787d392e9edb70c83d727d31e55eaac",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"stateRoot": "0xc7dbe7764cb5edd271a3e7fc4ffad23736aa1b8d4a5703e05a58db88d4ecbdc3",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000100000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000",
|
||||
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"gasLimit": "0x1c9c380",
|
||||
"gasUsed": "0x3ad4d",
|
||||
"gasUsed": "0x3b6c5",
|
||||
"timestamp": "0x40",
|
||||
"extraData": "0x",
|
||||
"baseFeePerGas": "0x7",
|
||||
"excessBlobGas": "0x0",
|
||||
"blobGasUsed": "0x0",
|
||||
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactions": [
|
||||
"0xf8a08085e8d4a51000832dc6c09400a3ca265ebcb825b45f985a16cefb49958ce01702b8388706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf2430000000000000000822fdfa00476c1a81f80f4c130acb5f8b8075468ba0893d766b7ec51a8d9723c573ad034a03bd3eaedabbaaf745f15023185ba66584ad3ee8bb40b9bef8c0b9ed27f8b1959",
|
||||
"0xf8c80185e8d4a51000832dc6c09400b42dbf2194e931e80326d950320f7d9dbeac0201b860fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe822fe0a05b88b593926d340f448918ef1c6263356c37f2434774e0fdb1cb9d90cfa5a23ba003a86aac4adb774181ba51eda17efb5fbed99ad57895e6eb56ccdf508a88a7cc"
|
||||
],
|
||||
"withdrawals": [],
|
||||
"depositRequests": [],
|
||||
"withdrawalRequests": [
|
||||
{
|
||||
"sourceAddress": "0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f",
|
||||
"amount": "0x0",
|
||||
"validatorPubkey": "0x8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243"
|
||||
}
|
||||
],
|
||||
"consolidationRequests": [
|
||||
{
|
||||
"sourceAddress": "0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f",
|
||||
"sourcePubkey": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"targetPubkey": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
|
||||
}
|
||||
],
|
||||
"blockNumber": "0x4",
|
||||
"receiptsRoot": "0x970fc81bb3e7fb21435f9a65a184aa9e3fd2f52b89fd859302b46954354266b5",
|
||||
"blobGasUsed": "0x0",
|
||||
"blockHash": "0x93df6f3484202f24c692354e2ab96e9948ae45eea6ad85faea121a389e468ea8"
|
||||
"receiptsRoot": "0x640f4036d53782ca4c5e9273ba6d657db4f5ff4fe526a8ed1997af9d0b8ae2d3",
|
||||
"blockHash": "0x61642311e6c1e0af50abf17be1fcb6de8bd75af2ca2d188031d074f6e71bf5e6"
|
||||
},
|
||||
"blockValue": "0x3581baab15c12e5",
|
||||
"blockValue": "0x360b8482c4b509d",
|
||||
"blobsBundle": {
|
||||
"commitments": [],
|
||||
"proofs": [],
|
||||
"blobs": []
|
||||
},
|
||||
"shouldOverrideBuilder": false
|
||||
"shouldOverrideBuilder": false,
|
||||
"executionRequests": [
|
||||
"0x",
|
||||
"0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf2430000000000000000",
|
||||
"0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
|
||||
]
|
||||
}
|
||||
},
|
||||
"statusCode": 200,
|
||||
|
||||
@@ -68,20 +68,21 @@ dependencies {
|
||||
implementation 'com.google.guava:guava'
|
||||
implementation 'com.google.dagger:dagger'
|
||||
implementation 'com.graphql-java:graphql-java'
|
||||
implementation 'commons-net:commons-net'
|
||||
implementation 'info.picocli:picocli'
|
||||
implementation 'io.vertx:vertx-core'
|
||||
implementation 'io.vertx:vertx-web'
|
||||
implementation 'org.apache.commons:commons-lang3'
|
||||
implementation 'org.apache.logging.log4j:log4j-core'
|
||||
implementation 'io.tmio:tuweni-bytes'
|
||||
implementation 'io.tmio:tuweni-config'
|
||||
implementation 'io.tmio:tuweni-toml'
|
||||
implementation 'io.tmio:tuweni-units'
|
||||
implementation 'org.apache.commons:commons-lang3'
|
||||
implementation 'org.apache.logging.log4j:log4j-core'
|
||||
implementation 'org.hibernate.validator:hibernate-validator'
|
||||
implementation 'org.rocksdb:rocksdbjni'
|
||||
implementation 'org.springframework.security:spring-security-crypto'
|
||||
implementation 'org.xerial.snappy:snappy-java'
|
||||
implementation 'tech.pegasys:jc-kzg-4844'
|
||||
implementation 'org.rocksdb:rocksdbjni'
|
||||
implementation 'commons-net:commons-net'
|
||||
|
||||
runtimeOnly 'org.apache.logging.log4j:log4j-jul'
|
||||
runtimeOnly 'com.splunk.logging:splunk-library-javalogging'
|
||||
|
||||
@@ -1421,7 +1421,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
}
|
||||
|
||||
private void validateOptions() {
|
||||
validateRequiredOptions();
|
||||
issueOptionWarnings();
|
||||
validateP2PInterface(p2PDiscoveryOptions.p2pInterface);
|
||||
validateMiningParams();
|
||||
@@ -1475,19 +1474,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
dataStorageOptions.validate(commandLine);
|
||||
}
|
||||
|
||||
private void validateRequiredOptions() {
|
||||
commandLine
|
||||
.getCommandSpec()
|
||||
.options()
|
||||
.forEach(
|
||||
option -> {
|
||||
if (option.required() && option.stringValues().isEmpty()) {
|
||||
throw new ParameterException(
|
||||
this.commandLine, "Missing required option: " + option.longestName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void validateMiningParams() {
|
||||
miningOptions.validate(
|
||||
commandLine, genesisConfigOptionsSupplier.get(), isMergeEnabled(), logger);
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.hyperledger.besu.cli.util.VersionProvider;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import org.springframework.security.crypto.bcrypt.BCrypt;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.Model.CommandSpec;
|
||||
@@ -75,6 +76,7 @@ public class PasswordSubCommand implements Runnable {
|
||||
static class HashSubCommand implements Runnable {
|
||||
|
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||
@NotEmpty
|
||||
@Option(
|
||||
names = "--password",
|
||||
arity = "1..1",
|
||||
|
||||
@@ -54,6 +54,7 @@ import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.vertx.core.Vertx;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -335,6 +336,7 @@ public class BlocksSubCommand implements Runnable {
|
||||
arity = "1..1")
|
||||
private final BlockExportFormat format = BlockExportFormat.RLP;
|
||||
|
||||
@NotBlank
|
||||
@Option(
|
||||
names = "--to",
|
||||
required = true,
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.Option;
|
||||
import picocli.CommandLine.ParentCommand;
|
||||
@@ -55,6 +56,7 @@ public class BackupState implements Runnable {
|
||||
arity = "1..1")
|
||||
private final Long block = Long.MAX_VALUE;
|
||||
|
||||
@NotBlank
|
||||
@Option(
|
||||
names = "--backup-path",
|
||||
required = true,
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.io.Resources;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -70,6 +71,7 @@ class GenerateBlockchainConfig implements Runnable {
|
||||
private final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
|
||||
@NotBlank
|
||||
@Option(
|
||||
required = true,
|
||||
names = "--config-file",
|
||||
@@ -78,6 +80,7 @@ class GenerateBlockchainConfig implements Runnable {
|
||||
arity = "1..1")
|
||||
private final File configurationFile = null;
|
||||
|
||||
@NotBlank
|
||||
@Option(
|
||||
required = true,
|
||||
names = "--to",
|
||||
|
||||
@@ -46,6 +46,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.slf4j.Logger;
|
||||
@@ -64,6 +65,7 @@ public class RestoreState implements Runnable {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RestoreState.class);
|
||||
|
||||
@NotBlank
|
||||
@Option(
|
||||
names = "--backup-path",
|
||||
required = true,
|
||||
|
||||
@@ -717,7 +717,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
ethPeers.snapServerPeersNeeded(false);
|
||||
}
|
||||
|
||||
protocolContext.setSynchronizer(Optional.of(synchronizer));
|
||||
protocolContext.setSynchronizer(synchronizer);
|
||||
|
||||
final Optional<SnapProtocolManager> maybeSnapProtocolManager =
|
||||
createSnapProtocolManager(
|
||||
|
||||
@@ -113,6 +113,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.core.VertxOptions;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
@@ -621,6 +622,7 @@ public abstract class CommandTestAbstract {
|
||||
@CommandLine.Command
|
||||
public static class TestBesuCommandWithRequiredOption extends TestBesuCommand {
|
||||
|
||||
@NotEmpty
|
||||
@CommandLine.Option(
|
||||
names = {"--accept-terms-and-conditions"},
|
||||
description = "You must explicitly accept terms and conditions",
|
||||
|
||||
@@ -38,7 +38,7 @@ public class RlpConverterServiceImplTest {
|
||||
new BlockHeaderTestFixture()
|
||||
.timestamp(1710338135 + 1)
|
||||
.baseFeePerGas(Wei.of(1000))
|
||||
.requestsRoot(Hash.ZERO)
|
||||
.requestsHash(Hash.ZERO)
|
||||
.withdrawalsRoot(Hash.ZERO)
|
||||
.blobGasUsed(500L)
|
||||
.excessBlobGas(BlobGas.of(500L))
|
||||
|
||||
@@ -514,7 +514,8 @@ subprojects {
|
||||
return result
|
||||
}
|
||||
|
||||
if (sourceSetIsPopulated("main") || sourceSetIsPopulated("testSupport")) {
|
||||
|
||||
if (sourceSetIsPopulated("main") || sourceSetIsPopulated("testSupport") || project.name == "platform") {
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
publishing {
|
||||
|
||||
@@ -18,12 +18,17 @@ import org.hyperledger.besu.consensus.merge.blockcreation.PayloadIdentifier;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.core.BlockValueCalculator;
|
||||
import org.hyperledger.besu.ethereum.core.BlockWithReceipts;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/** Wrapper for payload plus extra info. */
|
||||
public class PayloadWrapper {
|
||||
private final PayloadIdentifier payloadIdentifier;
|
||||
private final BlockWithReceipts blockWithReceipts;
|
||||
private final Wei blockValue;
|
||||
private final Optional<List<Request>> requests;
|
||||
|
||||
/**
|
||||
* Construct a wrapper with the following fields.
|
||||
@@ -32,10 +37,13 @@ public class PayloadWrapper {
|
||||
* @param blockWithReceipts Block with receipts
|
||||
*/
|
||||
public PayloadWrapper(
|
||||
final PayloadIdentifier payloadIdentifier, final BlockWithReceipts blockWithReceipts) {
|
||||
final PayloadIdentifier payloadIdentifier,
|
||||
final BlockWithReceipts blockWithReceipts,
|
||||
final Optional<List<Request>> requests) {
|
||||
this.blockWithReceipts = blockWithReceipts;
|
||||
this.payloadIdentifier = payloadIdentifier;
|
||||
this.blockValue = BlockValueCalculator.calculateBlockValue(blockWithReceipts);
|
||||
this.requests = requests;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,4 +72,13 @@ public class PayloadWrapper {
|
||||
public BlockWithReceipts blockWithReceipts() {
|
||||
return blockWithReceipts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the requests
|
||||
*
|
||||
* @return requests
|
||||
*/
|
||||
public Optional<List<Request>> requests() {
|
||||
return requests;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +302,9 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
|
||||
if (result.isSuccessful()) {
|
||||
mergeContext.putPayloadById(
|
||||
new PayloadWrapper(
|
||||
payloadIdentifier, new BlockWithReceipts(emptyBlock, result.getReceipts())));
|
||||
payloadIdentifier,
|
||||
new BlockWithReceipts(emptyBlock, result.getReceipts()),
|
||||
result.getRequests()));
|
||||
LOG.info(
|
||||
"Start building proposals for block {} identified by {}",
|
||||
emptyBlock.getHeader().getNumber(),
|
||||
@@ -469,7 +471,9 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
|
||||
|
||||
mergeContext.putPayloadById(
|
||||
new PayloadWrapper(
|
||||
payloadIdentifier, new BlockWithReceipts(bestBlock, resultBest.getReceipts())));
|
||||
payloadIdentifier,
|
||||
new BlockWithReceipts(bestBlock, resultBest.getReceipts()),
|
||||
resultBest.getRequests()));
|
||||
LOG.atDebug()
|
||||
.setMessage(
|
||||
"Successfully built block {} for proposal identified by {}, with {} transactions, in {}ms")
|
||||
|
||||
@@ -59,6 +59,7 @@ import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.MutableInitValues;
|
||||
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.Unstable;
|
||||
import org.hyperledger.besu.ethereum.core.MiningParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
@@ -189,6 +190,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
|
||||
|
||||
protocolContext =
|
||||
new ProtocolContext(blockchain, worldStateArchive, mergeContext, badBlockManager);
|
||||
protocolContext.setSynchronizer(mock(Synchronizer.class));
|
||||
var mutable = worldStateArchive.getMutable();
|
||||
genesisState.writeStateTo(mutable);
|
||||
mutable.persist(null);
|
||||
|
||||
@@ -54,8 +54,7 @@ public class ProposalTest {
|
||||
new BlockBody(
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Optional.of(Collections.emptyList()),
|
||||
Optional.empty()));
|
||||
Optional.of(Collections.emptyList())));
|
||||
|
||||
@Test
|
||||
public void canRoundTripProposalMessage() {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package org.hyperledger.besu.datatypes;
|
||||
|
||||
import static org.hyperledger.besu.crypto.Hash.keccak256;
|
||||
import static org.hyperledger.besu.crypto.Hash.sha256;
|
||||
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
|
||||
@@ -50,6 +51,17 @@ public class Hash extends DelegatingBytes32 {
|
||||
*/
|
||||
public static final Hash EMPTY = hash(Bytes.EMPTY);
|
||||
|
||||
/**
|
||||
* Hash of empty requests or "0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f"
|
||||
*/
|
||||
public static final Hash EMPTY_REQUESTS_HASH =
|
||||
Hash.wrap(
|
||||
sha256(
|
||||
Bytes.concatenate(
|
||||
sha256(Bytes.of(RequestType.DEPOSIT.getSerializedType())),
|
||||
sha256(Bytes.of(RequestType.WITHDRAWAL.getSerializedType())),
|
||||
sha256(Bytes.of(RequestType.CONSOLIDATION.getSerializedType())))));
|
||||
|
||||
/**
|
||||
* Instantiates a new Hash.
|
||||
*
|
||||
|
||||
@@ -26,4 +26,12 @@ public class HashTest {
|
||||
.isEqualTo(
|
||||
Hash.fromHexString("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetExpectedValueForEmptyRequestsHash() {
|
||||
assertThat(Hash.EMPTY_REQUESTS_HASH)
|
||||
.isEqualTo(
|
||||
Hash.fromHexString(
|
||||
"0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,5 +38,5 @@ public enum JsonRpcResponseKey {
|
||||
TRANSACTION_ROOT,
|
||||
BASEFEE,
|
||||
WITHDRAWALS_ROOT,
|
||||
REQUESTS_ROOT
|
||||
REQUESTS_HASH
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.NUMBE
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.OMMERS_HASH;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.PARENT_HASH;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.RECEIPTS_ROOT;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.REQUESTS_ROOT;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.REQUESTS_HASH;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.SIZE;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.STATE_ROOT;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.TIMESTAMP;
|
||||
@@ -104,8 +104,8 @@ public class JsonRpcResponseUtils {
|
||||
final int size = unsignedInt(values.get(SIZE));
|
||||
final Hash withdrawalsRoot =
|
||||
values.containsKey(WITHDRAWALS_ROOT) ? hash(values.get(WITHDRAWALS_ROOT)) : null;
|
||||
final Hash requestsRoot =
|
||||
values.containsKey(REQUESTS_ROOT) ? hash(values.get(REQUESTS_ROOT)) : null;
|
||||
final Hash requestsHash =
|
||||
values.containsKey(REQUESTS_HASH) ? hash(values.get(REQUESTS_HASH)) : null;
|
||||
final List<JsonNode> ommers = new ArrayList<>();
|
||||
|
||||
final BlockHeader header =
|
||||
@@ -130,7 +130,7 @@ public class JsonRpcResponseUtils {
|
||||
null, // ToDo 4844: set with the value of blob_gas_used field
|
||||
null, // ToDo 4844: set with the value of excess_blob_gas field
|
||||
null, // TODO 4788: set with the value of the parent beacon block root field
|
||||
requestsRoot,
|
||||
requestsHash,
|
||||
blockHeaderFunctions);
|
||||
|
||||
return new JsonRpcSuccessResponse(
|
||||
|
||||
@@ -79,6 +79,7 @@ public class TracedJsonRpcProcessor implements JsonRpcProcessor {
|
||||
case INVALID_ENGINE_PREPARE_PAYLOAD_PARAMS:
|
||||
case INVALID_ENODE_PARAMS:
|
||||
case INVALID_EXCESS_BLOB_GAS_PARAMS:
|
||||
case INVALID_EXECUTION_REQUESTS_PARAMS:
|
||||
case INVALID_EXTRA_DATA_PARAMS:
|
||||
case INVALID_FILTER_PARAMS:
|
||||
case INVALID_GAS_PRICE_PARAMS:
|
||||
|
||||
@@ -20,15 +20,14 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.Executi
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID_BLOCK_HASH;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.SYNCING;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.VALID;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getConsolidationRequestValidator;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getDepositRequestValidator;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getWithdrawalRequestValidator;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getRequestsValidator;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalsValidatorProvider.getWithdrawalsValidator;
|
||||
|
||||
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BlobGas;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
import org.hyperledger.besu.datatypes.VersionedHash;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.BlockProcessingResult;
|
||||
@@ -36,12 +35,9 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.ConsolidationRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
@@ -64,7 +60,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPException;
|
||||
import org.hyperledger.besu.ethereum.trie.MerkleTrieException;
|
||||
import org.hyperledger.besu.plugin.services.exception.StorageException;
|
||||
@@ -75,6 +70,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.core.json.Json;
|
||||
@@ -141,8 +137,22 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
final Optional<Bytes32> maybeParentBeaconBlockRoot =
|
||||
maybeParentBeaconBlockRootParam.map(Bytes32::fromHexString);
|
||||
|
||||
final Optional<List<String>> maybeRequestsParam;
|
||||
try {
|
||||
maybeRequestsParam = requestContext.getOptionalList(3, String.class);
|
||||
} catch (JsonRpcParameterException e) {
|
||||
throw new InvalidJsonRpcRequestException(
|
||||
"Invalid execution request parameters (index 3)",
|
||||
RpcErrorType.INVALID_EXECUTION_REQUESTS_PARAMS,
|
||||
e);
|
||||
}
|
||||
|
||||
final ValidationResult<RpcErrorType> parameterValidationResult =
|
||||
validateParameters(blockParam, maybeVersionedHashParam, maybeParentBeaconBlockRootParam);
|
||||
validateParameters(
|
||||
blockParam,
|
||||
maybeVersionedHashParam,
|
||||
maybeParentBeaconBlockRootParam,
|
||||
maybeRequestsParam);
|
||||
if (!parameterValidationResult.isValid()) {
|
||||
return new JsonRpcErrorResponse(reqId, parameterValidationResult);
|
||||
}
|
||||
@@ -183,45 +193,24 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS);
|
||||
}
|
||||
|
||||
final Optional<List<Request>> maybeDepositRequests =
|
||||
Optional.ofNullable(blockParam.getDepositRequests())
|
||||
.map(ds -> ds.stream().map(DepositRequestParameter::toDeposit).collect(toList()));
|
||||
if (!getDepositRequestValidator(
|
||||
protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber())
|
||||
.validateParameter(maybeDepositRequests)) {
|
||||
return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_DEPOSIT_REQUEST_PARAMS);
|
||||
final Optional<List<Request>> maybeRequests;
|
||||
try {
|
||||
maybeRequests = extractRequests(maybeRequestsParam);
|
||||
} catch (RuntimeException ex) {
|
||||
return respondWithInvalid(
|
||||
reqId,
|
||||
blockParam,
|
||||
mergeCoordinator.getLatestValidAncestor(blockParam.getParentHash()).orElse(null),
|
||||
INVALID,
|
||||
"Invalid execution requests");
|
||||
}
|
||||
|
||||
final Optional<List<Request>> maybeWithdrawalRequests =
|
||||
Optional.ofNullable(blockParam.getWithdrawalRequests())
|
||||
.map(
|
||||
withdrawalRequest ->
|
||||
withdrawalRequest.stream()
|
||||
.map(WithdrawalRequestParameter::toWithdrawalRequest)
|
||||
.collect(toList()));
|
||||
if (!getWithdrawalRequestValidator(
|
||||
if (!getRequestsValidator(
|
||||
protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber())
|
||||
.validateParameter(maybeWithdrawalRequests)) {
|
||||
return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_WITHDRAWALS_PARAMS);
|
||||
.validate(maybeRequests)) {
|
||||
return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_EXECUTION_REQUESTS_PARAMS);
|
||||
}
|
||||
|
||||
final Optional<List<Request>> maybeConsolidationRequests =
|
||||
Optional.ofNullable(blockParam.getConsolidationRequests())
|
||||
.map(
|
||||
consolidationRequest ->
|
||||
consolidationRequest.stream()
|
||||
.map(ConsolidationRequestParameter::toConsolidationRequest)
|
||||
.collect(toList()));
|
||||
if (!getConsolidationRequestValidator(
|
||||
protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber())
|
||||
.validateParameter(maybeConsolidationRequests)) {
|
||||
return new JsonRpcErrorResponse(reqId, RpcErrorType.INVALID_CONSOLIDATION_REQUEST_PARAMS);
|
||||
}
|
||||
|
||||
Optional<List<Request>> maybeRequests =
|
||||
RequestUtil.combine(
|
||||
maybeDepositRequests, maybeWithdrawalRequests, maybeConsolidationRequests);
|
||||
|
||||
if (mergeContext.get().isSyncing()) {
|
||||
LOG.debug("We are syncing");
|
||||
return respondWith(reqId, blockParam, null, SYNCING);
|
||||
@@ -289,7 +278,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
? null
|
||||
: BlobGas.fromHexString(blockParam.getExcessBlobGas()),
|
||||
maybeParentBeaconBlockRoot.orElse(null),
|
||||
maybeRequests.map(BodyValidation::requestsRoot).orElse(null),
|
||||
maybeRequests.map(BodyValidation::requestsHash).orElse(null),
|
||||
headerFunctions);
|
||||
|
||||
// ensure the block hash matches the blockParam hash
|
||||
@@ -351,8 +340,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
|
||||
final var block =
|
||||
new Block(
|
||||
newBlockHeader,
|
||||
new BlockBody(transactions, Collections.emptyList(), maybeWithdrawals, maybeRequests));
|
||||
newBlockHeader, new BlockBody(transactions, Collections.emptyList(), maybeWithdrawals));
|
||||
|
||||
if (maybeParentHeader.isEmpty()) {
|
||||
LOG.atDebug()
|
||||
@@ -466,7 +454,8 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
protected ValidationResult<RpcErrorType> validateParameters(
|
||||
final EnginePayloadParameter parameter,
|
||||
final Optional<List<String>> maybeVersionedHashParam,
|
||||
final Optional<String> maybeBeaconBlockRootParam) {
|
||||
final Optional<String> maybeBeaconBlockRootParam,
|
||||
final Optional<List<String>> maybeRequestsParam) {
|
||||
return ValidationResult.valid();
|
||||
}
|
||||
|
||||
@@ -562,6 +551,18 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private Optional<List<Request>> extractRequests(final Optional<List<String>> maybeRequestsParam) {
|
||||
if (maybeRequestsParam.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return maybeRequestsParam.map(
|
||||
requests ->
|
||||
IntStream.range(0, requests.size())
|
||||
.mapToObj(i -> new Request(RequestType.of(i), Bytes.fromHexString(requests.get(i))))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private void logImportedBlockInfo(final Block block, final int blobCount, final double timeInS) {
|
||||
final StringBuilder message = new StringBuilder();
|
||||
message.append("Imported #%,d / %d tx");
|
||||
@@ -572,10 +573,6 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
message.append(" / %d ws");
|
||||
messageArgs.add(block.getBody().getWithdrawals().get().size());
|
||||
}
|
||||
if (block.getBody().getRequests().isPresent()) {
|
||||
message.append(" / %d rs");
|
||||
messageArgs.add(block.getBody().getRequests().get().size());
|
||||
}
|
||||
message.append(" / %d blobs / base fee %s / %,d (%01.1f%%) gas / (%s) in %01.3fs. Peers: %d");
|
||||
messageArgs.addAll(
|
||||
List.of(
|
||||
|
||||
@@ -57,7 +57,8 @@ public class EngineNewPayloadV2 extends AbstractEngineNewPayload {
|
||||
protected ValidationResult<RpcErrorType> validateParameters(
|
||||
final EnginePayloadParameter payloadParameter,
|
||||
final Optional<List<String>> maybeVersionedHashParam,
|
||||
final Optional<String> maybeBeaconBlockRootParam) {
|
||||
final Optional<String> maybeBeaconBlockRootParam,
|
||||
final Optional<List<String>> maybeRequestsParam) {
|
||||
if (payloadParameter.getBlobGasUsed() != null) {
|
||||
return ValidationResult.invalid(
|
||||
RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field");
|
||||
|
||||
@@ -55,7 +55,8 @@ public class EngineNewPayloadV3 extends AbstractEngineNewPayload {
|
||||
protected ValidationResult<RpcErrorType> validateParameters(
|
||||
final EnginePayloadParameter payloadParameter,
|
||||
final Optional<List<String>> maybeVersionedHashParam,
|
||||
final Optional<String> maybeBeaconBlockRootParam) {
|
||||
final Optional<String> maybeBeaconBlockRootParam,
|
||||
final Optional<List<String>> maybeRequestsParam) {
|
||||
if (payloadParameter.getBlobGasUsed() == null) {
|
||||
return ValidationResult.invalid(
|
||||
RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field");
|
||||
|
||||
@@ -55,7 +55,8 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload {
|
||||
protected ValidationResult<RpcErrorType> validateParameters(
|
||||
final EnginePayloadParameter payloadParameter,
|
||||
final Optional<List<String>> maybeVersionedHashParam,
|
||||
final Optional<String> maybeBeaconBlockRootParam) {
|
||||
final Optional<String> maybeBeaconBlockRootParam,
|
||||
final Optional<List<String>> maybeRequestsParam) {
|
||||
if (payloadParameter.getBlobGasUsed() == null) {
|
||||
return ValidationResult.invalid(
|
||||
RpcErrorType.INVALID_BLOB_GAS_USED_PARAMS, "Missing blob gas used field");
|
||||
@@ -69,8 +70,9 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload {
|
||||
return ValidationResult.invalid(
|
||||
RpcErrorType.INVALID_PARENT_BEACON_BLOCK_ROOT_PARAMS,
|
||||
"Missing parent beacon block root field");
|
||||
} else if (payloadParameter.getDepositRequests() == null) {
|
||||
return ValidationResult.invalid(RpcErrorType.INVALID_PARAMS, "Missing deposit field");
|
||||
} else if (maybeRequestsParam.isEmpty()) {
|
||||
return ValidationResult.invalid(
|
||||
RpcErrorType.INVALID_EXECUTION_REQUESTS_PARAMS, "Missing execution requests field");
|
||||
} else {
|
||||
return ValidationResult.valid();
|
||||
}
|
||||
|
||||
@@ -14,64 +14,25 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
|
||||
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestsValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidator;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class RequestValidatorProvider {
|
||||
|
||||
public static RequestValidator getDepositRequestValidator(
|
||||
public static RequestsValidator getRequestsValidator(
|
||||
final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) {
|
||||
return getRequestValidator(protocolSchedule, blockTimestamp, blockNumber, RequestType.DEPOSIT);
|
||||
}
|
||||
|
||||
public static RequestValidator getWithdrawalRequestValidator(
|
||||
final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) {
|
||||
return getRequestValidator(
|
||||
protocolSchedule, blockTimestamp, blockNumber, RequestType.WITHDRAWAL);
|
||||
}
|
||||
|
||||
public static RequestValidator getConsolidationRequestValidator(
|
||||
final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) {
|
||||
return getRequestValidator(
|
||||
protocolSchedule, blockTimestamp, blockNumber, RequestType.CONSOLIDATION);
|
||||
}
|
||||
|
||||
private static RequestValidator getRequestValidator(
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final long blockTimestamp,
|
||||
final long blockNumber,
|
||||
final RequestType requestType) {
|
||||
|
||||
RequestsValidatorCoordinator requestsValidatorCoordinator =
|
||||
getRequestValidatorCoordinator(protocolSchedule, blockTimestamp, blockNumber);
|
||||
return requestsValidatorCoordinator
|
||||
.getRequestValidator(requestType)
|
||||
.orElse(new ProhibitedRequestsValidator());
|
||||
}
|
||||
|
||||
private static RequestsValidatorCoordinator getRequestValidatorCoordinator(
|
||||
final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) {
|
||||
|
||||
final BlockHeader blockHeader =
|
||||
BlockHeaderBuilder.createDefault()
|
||||
.timestamp(blockTimestamp)
|
||||
.number(blockNumber)
|
||||
.buildBlockHeader();
|
||||
return getRequestValidatorCoordinator(protocolSchedule.getByBlockHeader(blockHeader));
|
||||
}
|
||||
|
||||
private static RequestsValidatorCoordinator getRequestValidatorCoordinator(
|
||||
final ProtocolSpec protocolSchedule) {
|
||||
return Optional.ofNullable(protocolSchedule)
|
||||
.map(ProtocolSpec::getRequestsValidatorCoordinator)
|
||||
.orElseGet(RequestsValidatorCoordinator::empty);
|
||||
return Optional.ofNullable(protocolSchedule.getByBlockHeader(blockHeader))
|
||||
.map(ProtocolSpec::getRequestsValidator)
|
||||
.orElse(v -> true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.ethereum.core.ConsolidationRequest;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class ConsolidationRequestParameter {
|
||||
|
||||
private final String sourceAddress;
|
||||
private final String sourcePubkey;
|
||||
private final String targetPubkey;
|
||||
|
||||
@JsonCreator
|
||||
public ConsolidationRequestParameter(
|
||||
@JsonProperty("sourceAddress") final String sourceAddress,
|
||||
@JsonProperty("sourcePubkey") final String sourcePubkey,
|
||||
@JsonProperty("targetPubkey") final String targetPubkey) {
|
||||
this.sourceAddress = sourceAddress;
|
||||
this.sourcePubkey = sourcePubkey;
|
||||
this.targetPubkey = targetPubkey;
|
||||
}
|
||||
|
||||
public static ConsolidationRequestParameter fromConsolidationRequest(
|
||||
final ConsolidationRequest consolidationRequest) {
|
||||
return new ConsolidationRequestParameter(
|
||||
consolidationRequest.getSourceAddress().toHexString(),
|
||||
consolidationRequest.getSourcePubkey().toHexString(),
|
||||
consolidationRequest.getTargetPubkey().toHexString());
|
||||
}
|
||||
|
||||
public ConsolidationRequest toConsolidationRequest() {
|
||||
return new ConsolidationRequest(
|
||||
Address.fromHexString(sourceAddress),
|
||||
BLSPublicKey.fromHexString(sourcePubkey),
|
||||
BLSPublicKey.fromHexString(targetPubkey));
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getSourceAddress() {
|
||||
return sourceAddress;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getSourcePubkey() {
|
||||
return sourcePubkey;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getTargetPubkey() {
|
||||
return targetPubkey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final ConsolidationRequestParameter that = (ConsolidationRequestParameter) o;
|
||||
return Objects.equals(sourceAddress, that.sourceAddress)
|
||||
&& Objects.equals(sourcePubkey, that.sourcePubkey)
|
||||
&& Objects.equals(targetPubkey, that.targetPubkey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(sourceAddress, sourcePubkey, targetPubkey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConsolidationRequestParameter{"
|
||||
+ "sourceAddress='"
|
||||
+ sourceAddress
|
||||
+ '\''
|
||||
+ ", sourcePubkey='"
|
||||
+ sourcePubkey
|
||||
+ '\''
|
||||
+ ", targetPubkey='"
|
||||
+ targetPubkey
|
||||
+ '\''
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters;
|
||||
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.datatypes.BLSSignature;
|
||||
import org.hyperledger.besu.datatypes.GWei;
|
||||
import org.hyperledger.besu.ethereum.core.DepositRequest;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt64;
|
||||
|
||||
public class DepositRequestParameter {
|
||||
|
||||
private final String pubkey;
|
||||
|
||||
private final String withdrawalCredentials;
|
||||
private final String amount;
|
||||
|
||||
private final String signature;
|
||||
private final String index;
|
||||
|
||||
@JsonCreator
|
||||
public DepositRequestParameter(
|
||||
@JsonProperty("pubkey") final String pubkey,
|
||||
@JsonProperty("withdrawalCredentials") final String withdrawalCredentials,
|
||||
@JsonProperty("amount") final String amount,
|
||||
@JsonProperty("signature") final String signature,
|
||||
@JsonProperty("index") final String index) {
|
||||
this.pubkey = pubkey;
|
||||
this.withdrawalCredentials = withdrawalCredentials;
|
||||
this.amount = amount;
|
||||
this.signature = signature;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public static DepositRequestParameter fromDeposit(final DepositRequest depositRequest) {
|
||||
return new DepositRequestParameter(
|
||||
depositRequest.getPubkey().toString(),
|
||||
depositRequest.getWithdrawalCredentials().toString(),
|
||||
depositRequest.getAmount().toShortHexString(),
|
||||
depositRequest.getSignature().toString(),
|
||||
depositRequest.getIndex().toBytes().toQuantityHexString());
|
||||
}
|
||||
|
||||
public DepositRequest toDeposit() {
|
||||
return new DepositRequest(
|
||||
BLSPublicKey.fromHexString(pubkey),
|
||||
Bytes32.fromHexString(withdrawalCredentials),
|
||||
GWei.fromHexString(amount),
|
||||
BLSSignature.fromHexString(signature),
|
||||
UInt64.fromHexString(index));
|
||||
}
|
||||
|
||||
public JsonObject asJsonObject() {
|
||||
return new JsonObject()
|
||||
.put("pubkey", pubkey)
|
||||
.put("withdrawalCredentials", withdrawalCredentials)
|
||||
.put("amount", amount)
|
||||
.put("signature", signature)
|
||||
.put("index", index);
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getPubkey() {
|
||||
return pubkey;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getWithdrawalCredentials() {
|
||||
return withdrawalCredentials;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final DepositRequestParameter that = (DepositRequestParameter) o;
|
||||
return Objects.equals(pubkey, that.pubkey)
|
||||
&& Objects.equals(withdrawalCredentials, that.withdrawalCredentials)
|
||||
&& Objects.equals(amount, that.amount)
|
||||
&& Objects.equals(signature, that.signature)
|
||||
&& Objects.equals(index, that.index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(pubkey, withdrawalCredentials, amount, signature, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DepositRequestParameter{"
|
||||
+ "pubKey='"
|
||||
+ pubkey
|
||||
+ '\''
|
||||
+ ", withdrawalCredentials='"
|
||||
+ withdrawalCredentials
|
||||
+ '\''
|
||||
+ ", amount='"
|
||||
+ amount
|
||||
+ '\''
|
||||
+ ", signature='"
|
||||
+ signature
|
||||
+ '\''
|
||||
+ ", index='"
|
||||
+ index
|
||||
+ '\''
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -43,9 +43,6 @@ public class EnginePayloadParameter {
|
||||
private final List<WithdrawalParameter> withdrawals;
|
||||
private final Long blobGasUsed;
|
||||
private final String excessBlobGas;
|
||||
private final List<DepositRequestParameter> depositRequests;
|
||||
private final List<WithdrawalRequestParameter> withdrawalRequests;
|
||||
private final List<ConsolidationRequestParameter> consolidationRequests;
|
||||
|
||||
/**
|
||||
* Creates an instance of EnginePayloadParameter.
|
||||
@@ -67,9 +64,6 @@ public class EnginePayloadParameter {
|
||||
* @param withdrawals Array of Withdrawal
|
||||
* @param blobGasUsed QUANTITY, 64 Bits
|
||||
* @param excessBlobGas QUANTITY, 64 Bits
|
||||
* @param depositRequests List of deposit parameters.
|
||||
* @param withdrawalRequestParameters List of withdrawal requests parameters.
|
||||
* @param consolidationRequests List of consolidation requests parameters.
|
||||
*/
|
||||
@JsonCreator
|
||||
public EnginePayloadParameter(
|
||||
@@ -89,12 +83,7 @@ public class EnginePayloadParameter {
|
||||
@JsonProperty("transactions") final List<String> transactions,
|
||||
@JsonProperty("withdrawals") final List<WithdrawalParameter> withdrawals,
|
||||
@JsonProperty("blobGasUsed") final UnsignedLongParameter blobGasUsed,
|
||||
@JsonProperty("excessBlobGas") final String excessBlobGas,
|
||||
@JsonProperty("depositRequests") final List<DepositRequestParameter> depositRequests,
|
||||
@JsonProperty("withdrawalRequests")
|
||||
final List<WithdrawalRequestParameter> withdrawalRequestParameters,
|
||||
@JsonProperty("consolidationRequests")
|
||||
final List<ConsolidationRequestParameter> consolidationRequests) {
|
||||
@JsonProperty("excessBlobGas") final String excessBlobGas) {
|
||||
this.blockHash = blockHash;
|
||||
this.parentHash = parentHash;
|
||||
this.feeRecipient = feeRecipient;
|
||||
@@ -112,9 +101,6 @@ public class EnginePayloadParameter {
|
||||
this.withdrawals = withdrawals;
|
||||
this.blobGasUsed = blobGasUsed == null ? null : blobGasUsed.getValue();
|
||||
this.excessBlobGas = excessBlobGas;
|
||||
this.depositRequests = depositRequests;
|
||||
this.withdrawalRequests = withdrawalRequestParameters;
|
||||
this.consolidationRequests = consolidationRequests;
|
||||
}
|
||||
|
||||
public Hash getBlockHash() {
|
||||
@@ -184,16 +170,4 @@ public class EnginePayloadParameter {
|
||||
public String getExcessBlobGas() {
|
||||
return excessBlobGas;
|
||||
}
|
||||
|
||||
public List<DepositRequestParameter> getDepositRequests() {
|
||||
return depositRequests;
|
||||
}
|
||||
|
||||
public List<WithdrawalRequestParameter> getWithdrawalRequests() {
|
||||
return withdrawalRequests;
|
||||
}
|
||||
|
||||
public List<ConsolidationRequestParameter> getConsolidationRequests() {
|
||||
return consolidationRequests;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.datatypes.GWei;
|
||||
import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class WithdrawalRequestParameter {
|
||||
|
||||
private final String sourceAddress;
|
||||
private final String validatorPubkey;
|
||||
private final String amount;
|
||||
|
||||
@JsonCreator
|
||||
public WithdrawalRequestParameter(
|
||||
@JsonProperty("sourceAddress") final String sourceAddress,
|
||||
@JsonProperty("validatorPubkey") final String validatorPubkey,
|
||||
@JsonProperty("amount") final String amount) {
|
||||
this.sourceAddress = sourceAddress;
|
||||
this.validatorPubkey = validatorPubkey;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public static WithdrawalRequestParameter fromWithdrawalRequest(
|
||||
final WithdrawalRequest withdrawalRequest) {
|
||||
return new WithdrawalRequestParameter(
|
||||
withdrawalRequest.getSourceAddress().toHexString(),
|
||||
withdrawalRequest.getValidatorPubkey().toHexString(),
|
||||
withdrawalRequest.getAmount().toShortHexString());
|
||||
}
|
||||
|
||||
public WithdrawalRequest toWithdrawalRequest() {
|
||||
return new WithdrawalRequest(
|
||||
Address.fromHexString(sourceAddress),
|
||||
BLSPublicKey.fromHexString(validatorPubkey),
|
||||
GWei.fromHexString(amount));
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getSourceAddress() {
|
||||
return sourceAddress;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getValidatorPubkey() {
|
||||
return validatorPubkey;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final WithdrawalRequestParameter that = (WithdrawalRequestParameter) o;
|
||||
return Objects.equals(sourceAddress, that.sourceAddress)
|
||||
&& Objects.equals(validatorPubkey, that.validatorPubkey)
|
||||
&& Objects.equals(amount, that.amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(sourceAddress, validatorPubkey, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WithdrawalRequestParameter{"
|
||||
+ "sourceAddress='"
|
||||
+ sourceAddress
|
||||
+ '\''
|
||||
+ ", validatorPubkey='"
|
||||
+ validatorPubkey
|
||||
+ '\''
|
||||
+ ", amount='"
|
||||
+ amount
|
||||
+ '\''
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ public enum RpcErrorType implements RpcMethodError {
|
||||
INVALID_ENODE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid enode params"),
|
||||
INVALID_EXCESS_BLOB_GAS_PARAMS(
|
||||
INVALID_PARAMS_ERROR_CODE, "Invalid excess blob gas params (missing or invalid)"),
|
||||
INVALID_EXECUTION_REQUESTS_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid execution requests params"),
|
||||
INVALID_EXTRA_DATA_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid extra data params"),
|
||||
INVALID_FILTER_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid filter params"),
|
||||
INVALID_GAS_PRICE_PARAMS(INVALID_PARAMS_ERROR_CODE, "Invalid gas price params"),
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;
|
||||
|
||||
import static org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil.getConsolidationRequests;
|
||||
import static org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil.getDepositRequests;
|
||||
import static org.hyperledger.besu.ethereum.mainnet.requests.RequestUtil.getWithdrawalRequests;
|
||||
|
||||
import org.hyperledger.besu.consensus.merge.PayloadWrapper;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetPayloadBodiesResultV1.PayloadBody;
|
||||
@@ -26,10 +22,12 @@ import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.EncodingContext;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -162,6 +160,15 @@ public class BlockResultFactory {
|
||||
TransactionEncoder.encodeOpaqueBytes(transaction, EncodingContext.BLOCK_BODY))
|
||||
.map(Bytes::toHexString)
|
||||
.collect(Collectors.toList());
|
||||
final Optional<List<String>> requestsWithoutRequestId =
|
||||
payload
|
||||
.requests()
|
||||
.map(
|
||||
rqs ->
|
||||
rqs.stream()
|
||||
.sorted(Comparator.comparing(Request::getType))
|
||||
.map(r -> r.getData().toHexString())
|
||||
.toList());
|
||||
|
||||
final BlobsBundleV1 blobsBundleV1 =
|
||||
new BlobsBundleV1(blockWithReceipts.getBlock().getBody().getTransactions());
|
||||
@@ -169,9 +176,7 @@ public class BlockResultFactory {
|
||||
blockWithReceipts.getHeader(),
|
||||
txs,
|
||||
blockWithReceipts.getBlock().getBody().getWithdrawals(),
|
||||
getDepositRequests(blockWithReceipts.getBlock().getBody().getRequests()),
|
||||
getWithdrawalRequests(blockWithReceipts.getBlock().getBody().getRequests()),
|
||||
getConsolidationRequests(blockWithReceipts.getBlock().getBody().getRequests()),
|
||||
requestsWithoutRequestId,
|
||||
Quantity.create(payload.blockValue()),
|
||||
blobsBundleV1);
|
||||
}
|
||||
|
||||
@@ -14,15 +14,9 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;
|
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.ConsolidationRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.ConsolidationRequest;
|
||||
import org.hyperledger.besu.ethereum.core.DepositRequest;
|
||||
import org.hyperledger.besu.ethereum.core.Withdrawal;
|
||||
import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -33,33 +27,32 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
|
||||
@JsonPropertyOrder({"executionPayload", "blockValue", "blobsBundle", "shouldOverrideBuilder"})
|
||||
@JsonPropertyOrder({
|
||||
"executionPayload",
|
||||
"blockValue",
|
||||
"blobsBundle",
|
||||
"shouldOverrideBuilder",
|
||||
"executionRequests"
|
||||
})
|
||||
public class EngineGetPayloadResultV4 {
|
||||
protected final PayloadResult executionPayload;
|
||||
private final String blockValue;
|
||||
private final BlobsBundleV1 blobsBundle;
|
||||
private final boolean shouldOverrideBuilder;
|
||||
private final List<String> executionRequests;
|
||||
|
||||
public EngineGetPayloadResultV4(
|
||||
final BlockHeader header,
|
||||
final List<String> transactions,
|
||||
final Optional<List<Withdrawal>> withdrawals,
|
||||
final Optional<List<DepositRequest>> depositRequests,
|
||||
final Optional<List<WithdrawalRequest>> withdrawalRequests,
|
||||
final Optional<List<ConsolidationRequest>> consolidationRequests,
|
||||
final Optional<List<String>> executionRequests,
|
||||
final String blockValue,
|
||||
final BlobsBundleV1 blobsBundle) {
|
||||
this.executionPayload =
|
||||
new PayloadResult(
|
||||
header,
|
||||
transactions,
|
||||
withdrawals,
|
||||
depositRequests,
|
||||
withdrawalRequests,
|
||||
consolidationRequests);
|
||||
this.executionPayload = new PayloadResult(header, transactions, withdrawals);
|
||||
this.blockValue = blockValue;
|
||||
this.blobsBundle = blobsBundle;
|
||||
this.shouldOverrideBuilder = false;
|
||||
this.executionRequests = executionRequests.orElse(null);
|
||||
}
|
||||
|
||||
@JsonGetter(value = "executionPayload")
|
||||
@@ -82,6 +75,11 @@ public class EngineGetPayloadResultV4 {
|
||||
return shouldOverrideBuilder;
|
||||
}
|
||||
|
||||
@JsonGetter(value = "executionRequests")
|
||||
public List<String> getExecutionRequests() {
|
||||
return executionRequests;
|
||||
}
|
||||
|
||||
public static class PayloadResult {
|
||||
|
||||
protected final String blockHash;
|
||||
@@ -103,17 +101,11 @@ public class EngineGetPayloadResultV4 {
|
||||
|
||||
protected final List<String> transactions;
|
||||
private final List<WithdrawalParameter> withdrawals;
|
||||
private final List<DepositRequestParameter> depositRequests;
|
||||
private final List<WithdrawalRequestParameter> withdrawalRequests;
|
||||
private final List<ConsolidationRequestParameter> consolidationRequests;
|
||||
|
||||
public PayloadResult(
|
||||
final BlockHeader header,
|
||||
final List<String> transactions,
|
||||
final Optional<List<Withdrawal>> withdrawals,
|
||||
final Optional<List<DepositRequest>> depositRequests,
|
||||
final Optional<List<WithdrawalRequest>> withdrawalRequests,
|
||||
final Optional<List<ConsolidationRequest>> consolidationRequests) {
|
||||
final Optional<List<Withdrawal>> withdrawals) {
|
||||
this.blockNumber = Quantity.create(header.getNumber());
|
||||
this.blockHash = header.getHash().toString();
|
||||
this.parentHash = header.getParentHash().toString();
|
||||
@@ -136,30 +128,6 @@ public class EngineGetPayloadResultV4 {
|
||||
.map(WithdrawalParameter::fromWithdrawal)
|
||||
.collect(Collectors.toList()))
|
||||
.orElse(null);
|
||||
this.depositRequests =
|
||||
depositRequests
|
||||
.map(
|
||||
ds ->
|
||||
ds.stream()
|
||||
.map(DepositRequestParameter::fromDeposit)
|
||||
.collect(Collectors.toList()))
|
||||
.orElse(null);
|
||||
this.withdrawalRequests =
|
||||
withdrawalRequests
|
||||
.map(
|
||||
wr ->
|
||||
wr.stream()
|
||||
.map(WithdrawalRequestParameter::fromWithdrawalRequest)
|
||||
.collect(Collectors.toList()))
|
||||
.orElse(null);
|
||||
this.consolidationRequests =
|
||||
consolidationRequests
|
||||
.map(
|
||||
wr ->
|
||||
wr.stream()
|
||||
.map(ConsolidationRequestParameter::fromConsolidationRequest)
|
||||
.collect(Collectors.toList()))
|
||||
.orElse(null);
|
||||
this.blobGasUsed = header.getBlobGasUsed().map(Quantity::create).orElse(Quantity.HEX_ZERO);
|
||||
this.excessBlobGas =
|
||||
header.getExcessBlobGas().map(Quantity::create).orElse(Quantity.HEX_ZERO);
|
||||
@@ -237,21 +205,6 @@ public class EngineGetPayloadResultV4 {
|
||||
return withdrawals;
|
||||
}
|
||||
|
||||
@JsonGetter(value = "depositRequests")
|
||||
public List<DepositRequestParameter> getDepositRequests() {
|
||||
return depositRequests;
|
||||
}
|
||||
|
||||
@JsonGetter(value = "withdrawalRequests")
|
||||
public List<WithdrawalRequestParameter> getWithdrawalRequests() {
|
||||
return withdrawalRequests;
|
||||
}
|
||||
|
||||
@JsonGetter(value = "consolidationRequests")
|
||||
public List<ConsolidationRequestParameter> getConsolidationRequests() {
|
||||
return consolidationRequests;
|
||||
}
|
||||
|
||||
@JsonGetter(value = "feeRecipient")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public String getFeeRecipient() {
|
||||
|
||||
@@ -99,32 +99,27 @@ public abstract class AbstractEngineGetPayloadTest extends AbstractScheduledApiT
|
||||
protected static final BlockWithReceipts mockBlockWithReceipts =
|
||||
new BlockWithReceipts(mockBlock, Collections.emptyList());
|
||||
protected static final PayloadWrapper mockPayload =
|
||||
new PayloadWrapper(mockPid, mockBlockWithReceipts);
|
||||
new PayloadWrapper(mockPid, mockBlockWithReceipts, Optional.empty());
|
||||
private static final Block mockBlockWithWithdrawals =
|
||||
new Block(
|
||||
mockHeader,
|
||||
new BlockBody(
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Optional.of(Collections.emptyList()),
|
||||
Optional.empty()));
|
||||
Optional.of(Collections.emptyList())));
|
||||
private static final Block mockBlockWithDepositRequests =
|
||||
new Block(
|
||||
mockHeader,
|
||||
new BlockBody(
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Optional.empty(),
|
||||
Optional.of(Collections.emptyList())));
|
||||
new BlockBody(Collections.emptyList(), Collections.emptyList(), Optional.empty()));
|
||||
protected static final BlockWithReceipts mockBlockWithReceiptsAndWithdrawals =
|
||||
new BlockWithReceipts(mockBlockWithWithdrawals, Collections.emptyList());
|
||||
protected static final PayloadWrapper mockPayloadWithWithdrawals =
|
||||
new PayloadWrapper(mockPid, mockBlockWithReceiptsAndWithdrawals);
|
||||
new PayloadWrapper(mockPid, mockBlockWithReceiptsAndWithdrawals, Optional.empty());
|
||||
|
||||
protected static final BlockWithReceipts mockBlockWithReceiptsAndDepositRequests =
|
||||
new BlockWithReceipts(mockBlockWithDepositRequests, Collections.emptyList());
|
||||
protected static final PayloadWrapper mockPayloadWithDepositRequests =
|
||||
new PayloadWrapper(mockPid, mockBlockWithReceiptsAndDepositRequests);
|
||||
new PayloadWrapper(mockPid, mockBlockWithReceiptsAndDepositRequests, Optional.empty());
|
||||
|
||||
@Mock protected ProtocolContext protocolContext;
|
||||
|
||||
|
||||
@@ -38,12 +38,9 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.ConsolidationRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.UnsignedLongParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
@@ -54,20 +51,17 @@ import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.DepositRequest;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.Withdrawal;
|
||||
import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
||||
import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.mainnet.WithdrawalsValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestValidator;
|
||||
import org.hyperledger.besu.ethereum.trie.MerkleTrieException;
|
||||
import org.hyperledger.besu.plugin.services.exception.StorageException;
|
||||
import org.hyperledger.besu.plugin.services.rpc.RpcResponseType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -130,7 +124,6 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
lenient()
|
||||
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
@@ -144,10 +137,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
public void shouldReturnInvalidOnBlockExecutionError() {
|
||||
BlockHeader mockHeader =
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult("error 42"),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
new BlockProcessingResult("error 42"), Optional.empty(), Optional.empty());
|
||||
lenient()
|
||||
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
.thenReturn(Optional.of(mock(BlockHeader.class)));
|
||||
@@ -162,8 +152,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
@Test
|
||||
public void shouldReturnAcceptedOnLatestValidAncestorEmpty() {
|
||||
BlockHeader mockHeader =
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
|
||||
when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
|
||||
when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
.thenReturn(Optional.of(mock(BlockHeader.class)));
|
||||
@@ -181,8 +170,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
@Test
|
||||
public void shouldReturnSuccessOnAlreadyPresent() {
|
||||
BlockHeader mockHeader =
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
|
||||
Block mockBlock =
|
||||
new Block(mockHeader, new BlockBody(Collections.emptyList(), Collections.emptyList()));
|
||||
|
||||
@@ -195,8 +183,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
@Test
|
||||
public void shouldReturnInvalidWithLatestValidHashIsABadBlock() {
|
||||
BlockHeader mockHeader =
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
|
||||
Hash latestValidHash = Hash.hash(Bytes32.fromHexStringLenient("0xcafebabe"));
|
||||
|
||||
when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
|
||||
@@ -218,7 +205,6 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(Optional.empty(), new StorageException("database bedlam")),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
lenient()
|
||||
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
@@ -235,7 +221,6 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(Optional.empty(), new MerkleTrieException("missing leaf")),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
|
||||
lenient()
|
||||
@@ -250,8 +235,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
@Test
|
||||
public void shouldNotReturnInvalidOnThrownMerkleTrieException() {
|
||||
BlockHeader mockHeader =
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
|
||||
when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
|
||||
when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
.thenReturn(Optional.of(mock(BlockHeader.class)));
|
||||
@@ -268,8 +252,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
@Test
|
||||
public void shouldReturnInvalidBlockHashOnBadHashParameter() {
|
||||
BlockHeader mockHeader =
|
||||
spy(createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty()));
|
||||
BlockHeader mockHeader = spy(createBlockHeader(Optional.empty(), Optional.empty()));
|
||||
lenient()
|
||||
.when(mergeCoordinator.getLatestValidAncestor(mockHeader.getBlockHash()))
|
||||
.thenReturn(Optional.empty());
|
||||
@@ -286,8 +269,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
@Test
|
||||
public void shouldCheckBlockValidityBeforeCheckingByHashForExisting() {
|
||||
BlockHeader realHeader =
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
BlockHeader realHeader = createBlockHeader(Optional.empty(), Optional.empty());
|
||||
BlockHeader paramHeader = spy(realHeader);
|
||||
when(paramHeader.getHash()).thenReturn(Hash.fromHexStringLenient("0x1337"));
|
||||
|
||||
@@ -301,8 +283,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
@Test
|
||||
public void shouldReturnInvalidOnMalformedTransactions() {
|
||||
BlockHeader mockHeader =
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
|
||||
when(mergeCoordinator.getLatestValidAncestor(any(Hash.class)))
|
||||
.thenReturn(Optional.of(mockHash));
|
||||
|
||||
@@ -317,8 +298,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
@Test
|
||||
public void shouldRespondWithSyncingDuringForwardSync() {
|
||||
BlockHeader mockHeader =
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
|
||||
when(mergeContext.isSyncing()).thenReturn(Boolean.TRUE);
|
||||
var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
|
||||
|
||||
@@ -331,8 +311,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
@Test
|
||||
public void shouldRespondWithSyncingDuringBackwardsSync() {
|
||||
BlockHeader mockHeader =
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
|
||||
when(mergeCoordinator.appendNewPayloadToSync(any()))
|
||||
.thenReturn(CompletableFuture.completedFuture(null));
|
||||
var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
|
||||
@@ -346,8 +325,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
@Test
|
||||
public void shouldRespondWithInvalidIfExtraDataIsNull() {
|
||||
BlockHeader realHeader =
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
BlockHeader realHeader = createBlockHeader(Optional.empty(), Optional.empty());
|
||||
BlockHeader paramHeader = spy(realHeader);
|
||||
when(paramHeader.getHash()).thenReturn(Hash.fromHexStringLenient("0x1337"));
|
||||
when(paramHeader.getExtraData().toHexString()).thenReturn(null);
|
||||
@@ -364,8 +342,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
@Test
|
||||
public void shouldReturnInvalidWhenBadBlock() {
|
||||
when(mergeCoordinator.isBadBlock(any(Hash.class))).thenReturn(true);
|
||||
BlockHeader mockHeader =
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
BlockHeader mockHeader = createBlockHeader(Optional.empty(), Optional.empty());
|
||||
var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
|
||||
when(protocolSpec.getWithdrawalsValidator())
|
||||
.thenReturn(new WithdrawalsValidator.AllowedWithdrawals());
|
||||
@@ -383,7 +360,6 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
lenient()
|
||||
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
@@ -404,16 +380,13 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
protected EnginePayloadParameter mockEnginePayload(
|
||||
final BlockHeader header, final List<String> txs) {
|
||||
return mockEnginePayload(header, txs, null, null, null, null);
|
||||
return mockEnginePayload(header, txs, null);
|
||||
}
|
||||
|
||||
protected EnginePayloadParameter mockEnginePayload(
|
||||
final BlockHeader header,
|
||||
final List<String> txs,
|
||||
final List<WithdrawalParameter> withdrawals,
|
||||
final List<DepositRequestParameter> depositRequests,
|
||||
final List<WithdrawalRequestParameter> withdrawalRequests,
|
||||
final List<ConsolidationRequestParameter> consolidationRequests) {
|
||||
final List<WithdrawalParameter> withdrawals) {
|
||||
return new EnginePayloadParameter(
|
||||
header.getHash(),
|
||||
header.getParentHash(),
|
||||
@@ -431,23 +404,16 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
txs,
|
||||
withdrawals,
|
||||
header.getBlobGasUsed().map(UnsignedLongParameter::new).orElse(null),
|
||||
header.getExcessBlobGas().map(BlobGas::toHexString).orElse(null),
|
||||
depositRequests,
|
||||
withdrawalRequests,
|
||||
consolidationRequests);
|
||||
header.getExcessBlobGas().map(BlobGas::toHexString).orElse(null));
|
||||
}
|
||||
|
||||
protected BlockHeader setupValidPayload(
|
||||
final BlockProcessingResult value,
|
||||
final Optional<List<Withdrawal>> maybeWithdrawals,
|
||||
final Optional<List<DepositRequest>> maybeDepositRequests,
|
||||
final Optional<List<WithdrawalRequest>> maybeWithdrawalRequests) {
|
||||
final Optional<List<Request>> maybeRequests) {
|
||||
|
||||
BlockHeader mockHeader =
|
||||
createBlockHeader(maybeWithdrawals, maybeDepositRequests, maybeWithdrawalRequests);
|
||||
BlockHeader mockHeader = createBlockHeader(maybeWithdrawals, maybeRequests);
|
||||
when(blockchain.getBlockByHash(mockHeader.getHash())).thenReturn(Optional.empty());
|
||||
// when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
// .thenReturn(Optional.of(mock(BlockHeader.class)));
|
||||
when(mergeCoordinator.getLatestValidAncestor(any(BlockHeader.class)))
|
||||
.thenReturn(Optional.of(mockHash));
|
||||
when(mergeCoordinator.rememberBlock(any())).thenReturn(value);
|
||||
@@ -477,27 +443,8 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
|
||||
protected BlockHeader createBlockHeader(
|
||||
final Optional<List<Withdrawal>> maybeWithdrawals,
|
||||
final Optional<List<DepositRequest>> maybeDepositRequests,
|
||||
final Optional<List<WithdrawalRequest>> maybeWithdrawalRequests) {
|
||||
return createBlockHeaderFixture(maybeWithdrawals, maybeDepositRequests, maybeWithdrawalRequests)
|
||||
.buildHeader();
|
||||
}
|
||||
|
||||
protected BlockHeaderTestFixture createBlockHeaderFixture(
|
||||
final Optional<List<Withdrawal>> maybeWithdrawals,
|
||||
final Optional<List<DepositRequest>> maybeDepositRequests,
|
||||
final Optional<List<WithdrawalRequest>> maybeWithdrawalRequests) {
|
||||
|
||||
Optional<List<Request>> maybeRequests;
|
||||
if (maybeDepositRequests.isPresent() || maybeWithdrawalRequests.isPresent()) {
|
||||
List<Request> requests = new ArrayList<>();
|
||||
maybeDepositRequests.ifPresent(requests::addAll);
|
||||
maybeWithdrawalRequests.ifPresent(requests::addAll);
|
||||
maybeRequests = Optional.of(requests);
|
||||
} else {
|
||||
maybeRequests = Optional.empty();
|
||||
}
|
||||
return createBlockHeaderFixture(maybeWithdrawals, maybeRequests);
|
||||
final Optional<List<Request>> maybeRequests) {
|
||||
return createBlockHeaderFixture(maybeWithdrawals, maybeRequests).buildHeader();
|
||||
}
|
||||
|
||||
protected BlockHeaderTestFixture createBlockHeaderFixture(
|
||||
@@ -512,7 +459,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
.timestamp(parentBlockHeader.getTimestamp() + 1)
|
||||
.withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null))
|
||||
.parentBeaconBlockRoot(maybeParentBeaconBlockRoot)
|
||||
.requestsRoot(maybeRequests.map(BodyValidation::requestsRoot).orElse(null));
|
||||
.requestsHash(maybeRequests.map(BodyValidation::requestsHash).orElse(null));
|
||||
}
|
||||
|
||||
protected void assertValidResponse(final BlockHeader mockHeader, final JsonRpcResponse resp) {
|
||||
@@ -524,7 +471,7 @@ public abstract class AbstractEngineNewPayloadTest extends AbstractScheduledApiT
|
||||
}
|
||||
|
||||
private void mockProhibitedRequestsValidator() {
|
||||
var validator = RequestsValidatorCoordinator.empty();
|
||||
when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(validator);
|
||||
var validator = new ProhibitedRequestValidator();
|
||||
when(protocolSpec.getRequestsValidator()).thenReturn(validator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +180,6 @@ public class EngineGetPayloadBodiesByHashV1Test {
|
||||
new BlockBody(
|
||||
List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
|
||||
Collections.emptyList(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(preShanghaiBlockBody));
|
||||
when(blockchain.getBlockBody(blockHash2)).thenReturn(Optional.of(preShanghaiBlockBody2));
|
||||
@@ -211,15 +210,13 @@ public class EngineGetPayloadBodiesByHashV1Test {
|
||||
new TransactionTestFixture().createTransaction(sig.generateKeyPair()),
|
||||
new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
|
||||
Collections.emptyList(),
|
||||
Optional.of(List.of(withdrawal)),
|
||||
Optional.empty());
|
||||
Optional.of(List.of(withdrawal)));
|
||||
|
||||
final BlockBody shanghaiBlockBody2 =
|
||||
new BlockBody(
|
||||
List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
|
||||
Collections.emptyList(),
|
||||
Optional.of(List.of(withdrawal2)),
|
||||
Optional.empty());
|
||||
Optional.of(List.of(withdrawal2)));
|
||||
when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody));
|
||||
when(blockchain.getBlockBody(blockHash2)).thenReturn(Optional.of(shanghaiBlockBody2));
|
||||
|
||||
|
||||
@@ -179,7 +179,6 @@ public class EngineGetPayloadBodiesByRangeV1Test {
|
||||
new BlockBody(
|
||||
List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
|
||||
Collections.emptyList(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(130));
|
||||
when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(preShanghaiBlockBody));
|
||||
@@ -214,15 +213,13 @@ public class EngineGetPayloadBodiesByRangeV1Test {
|
||||
new TransactionTestFixture().createTransaction(sig.generateKeyPair()),
|
||||
new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
|
||||
Collections.emptyList(),
|
||||
Optional.of(List.of(withdrawal)),
|
||||
Optional.empty());
|
||||
Optional.of(List.of(withdrawal)));
|
||||
|
||||
final BlockBody shanghaiBlockBody2 =
|
||||
new BlockBody(
|
||||
List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
|
||||
Collections.emptyList(),
|
||||
Optional.of(List.of(withdrawal2)),
|
||||
Optional.empty());
|
||||
Optional.of(List.of(withdrawal2)));
|
||||
when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(130));
|
||||
when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody));
|
||||
when(blockchain.getBlockBody(blockHash2)).thenReturn(Optional.of(shanghaiBlockBody2));
|
||||
@@ -252,8 +249,7 @@ public class EngineGetPayloadBodiesByRangeV1Test {
|
||||
new TransactionTestFixture().createTransaction(sig.generateKeyPair()),
|
||||
new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
|
||||
Collections.emptyList(),
|
||||
Optional.of(List.of(withdrawal)),
|
||||
Optional.empty());
|
||||
Optional.of(List.of(withdrawal)));
|
||||
when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(123));
|
||||
when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody));
|
||||
when(blockchain.getBlockHashByNumber(123)).thenReturn(Optional.of(blockHash1));
|
||||
@@ -276,20 +272,17 @@ public class EngineGetPayloadBodiesByRangeV1Test {
|
||||
new BlockBody(
|
||||
List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
|
||||
Collections.emptyList(),
|
||||
Optional.of(List.of(withdrawal)),
|
||||
Optional.empty());
|
||||
Optional.of(List.of(withdrawal)));
|
||||
final BlockBody shanghaiBlockBody2 =
|
||||
new BlockBody(
|
||||
List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
|
||||
Collections.emptyList(),
|
||||
Optional.of(List.of(withdrawal)),
|
||||
Optional.empty());
|
||||
Optional.of(List.of(withdrawal)));
|
||||
final BlockBody shanghaiBlockBody3 =
|
||||
new BlockBody(
|
||||
List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())),
|
||||
Collections.emptyList(),
|
||||
Optional.of(List.of(withdrawal)),
|
||||
Optional.empty());
|
||||
Optional.of(List.of(withdrawal)));
|
||||
when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(125));
|
||||
when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody));
|
||||
when(blockchain.getBlockBody(blockHash2)).thenReturn(Optional.of(shanghaiBlockBody2));
|
||||
|
||||
@@ -124,7 +124,8 @@ public class EngineGetPayloadV2Test extends AbstractEngineGetPayloadTest {
|
||||
new Block(mockHeader, new BlockBody(Collections.emptyList(), Collections.emptyList()));
|
||||
final BlockWithReceipts mockBlockWithReceipts =
|
||||
new BlockWithReceipts(mockBlock, Collections.emptyList());
|
||||
final PayloadWrapper mockPayload = new PayloadWrapper(mockPid, mockBlockWithReceipts);
|
||||
final PayloadWrapper mockPayload =
|
||||
new PayloadWrapper(mockPid, mockBlockWithReceipts, Optional.empty());
|
||||
|
||||
when(mergeContext.retrievePayloadById(mockPid)).thenReturn(Optional.of(mockPayload));
|
||||
|
||||
|
||||
@@ -128,10 +128,10 @@ public class EngineGetPayloadV3Test extends AbstractEngineGetPayloadTest {
|
||||
new BlockBody(
|
||||
List.of(blobTx),
|
||||
Collections.emptyList(),
|
||||
Optional.of(Collections.emptyList()),
|
||||
Optional.of(Collections.emptyList()))),
|
||||
List.of(blobReceipt));
|
||||
PayloadWrapper payloadPostCancun = new PayloadWrapper(postCancunPid, postCancunBlock);
|
||||
PayloadWrapper payloadPostCancun =
|
||||
new PayloadWrapper(postCancunPid, postCancunBlock, Optional.empty());
|
||||
|
||||
when(mergeContext.retrievePayloadById(postCancunPid))
|
||||
.thenReturn(Optional.of(payloadPostCancun));
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -27,6 +28,7 @@ import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BlobGas;
|
||||
import org.hyperledger.besu.datatypes.BlobsWithCommitments;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
import org.hyperledger.besu.datatypes.TransactionType;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
|
||||
@@ -41,12 +43,13 @@ import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.BlockWithReceipts;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -128,19 +131,24 @@ public class EngineGetPayloadV4Test extends AbstractEngineGetPayloadTest {
|
||||
BlockWithReceipts block =
|
||||
new BlockWithReceipts(
|
||||
new Block(
|
||||
header,
|
||||
new BlockBody(
|
||||
List.of(blobTx),
|
||||
Collections.emptyList(),
|
||||
Optional.of(Collections.emptyList()),
|
||||
Optional.of(Collections.emptyList()))),
|
||||
header, new BlockBody(List.of(blobTx), emptyList(), Optional.of(emptyList()))),
|
||||
List.of(blobReceipt));
|
||||
PayloadWrapper payload = new PayloadWrapper(payloadIdentifier, block);
|
||||
final List<Request> requests =
|
||||
List.of(
|
||||
new Request(RequestType.DEPOSIT, Bytes.of(1)),
|
||||
new Request(RequestType.WITHDRAWAL, Bytes.of(1)),
|
||||
new Request(RequestType.CONSOLIDATION, Bytes.of(1)));
|
||||
PayloadWrapper payload = new PayloadWrapper(payloadIdentifier, block, Optional.of(requests));
|
||||
|
||||
when(mergeContext.retrievePayloadById(payloadIdentifier)).thenReturn(Optional.of(payload));
|
||||
|
||||
final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V4.getMethodName(), payloadIdentifier);
|
||||
assertThat(resp).isInstanceOf(JsonRpcSuccessResponse.class);
|
||||
final List<String> requestsWithoutRequestId =
|
||||
requests.stream()
|
||||
.sorted(Comparator.comparing(Request::getType))
|
||||
.map(r -> r.getData().toHexString())
|
||||
.toList();
|
||||
Optional.of(resp)
|
||||
.map(JsonRpcSuccessResponse.class::cast)
|
||||
.ifPresent(
|
||||
@@ -148,9 +156,6 @@ public class EngineGetPayloadV4Test extends AbstractEngineGetPayloadTest {
|
||||
assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV4.class);
|
||||
final EngineGetPayloadResultV4 res = (EngineGetPayloadResultV4) r.getResult();
|
||||
assertThat(res.getExecutionPayload().getWithdrawals()).isNotNull();
|
||||
assertThat(res.getExecutionPayload().getDepositRequests()).isNotNull();
|
||||
assertThat(res.getExecutionPayload().getWithdrawalRequests()).isNotNull();
|
||||
assertThat(res.getExecutionPayload().getConsolidationRequests()).isNotNull();
|
||||
assertThat(res.getExecutionPayload().getHash())
|
||||
.isEqualTo(header.getHash().toString());
|
||||
assertThat(res.getBlockValue()).isEqualTo(Quantity.create(0));
|
||||
@@ -161,6 +166,8 @@ public class EngineGetPayloadV4Test extends AbstractEngineGetPayloadTest {
|
||||
assertThat(res.getExecutionPayload().getExcessBlobGas()).isNotEmpty();
|
||||
assertThat(res.getExecutionPayload().getExcessBlobGas())
|
||||
.isEqualTo(expectedQuantityOf10);
|
||||
assertThat(res.getExecutionRequests()).isNotEmpty();
|
||||
assertThat(res.getExecutionRequests()).isEqualTo(requestsWithoutRequestId);
|
||||
});
|
||||
verify(engineCallListener, times(1)).executionEngineCalled();
|
||||
}
|
||||
|
||||
@@ -83,15 +83,11 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
|
||||
Optional.of(withdrawals),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
lenient()
|
||||
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
.thenReturn(Optional.of(mock(BlockHeader.class)));
|
||||
var resp =
|
||||
resp(
|
||||
mockEnginePayload(
|
||||
mockHeader, Collections.emptyList(), withdrawalsParam, null, null, null));
|
||||
var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList(), withdrawalsParam));
|
||||
|
||||
assertValidResponse(mockHeader, resp);
|
||||
}
|
||||
@@ -105,13 +101,11 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
lenient()
|
||||
.when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
.thenReturn(Optional.of(mock(BlockHeader.class)));
|
||||
var resp =
|
||||
resp(mockEnginePayload(mockHeader, Collections.emptyList(), withdrawals, null, null, null));
|
||||
var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList(), withdrawals));
|
||||
|
||||
assertValidResponse(mockHeader, resp);
|
||||
}
|
||||
@@ -126,13 +120,9 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
|
||||
var resp =
|
||||
resp(
|
||||
mockEnginePayload(
|
||||
createBlockHeader(
|
||||
Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty()),
|
||||
createBlockHeader(Optional.of(Collections.emptyList()), Optional.empty()),
|
||||
Collections.emptyList(),
|
||||
withdrawals,
|
||||
null,
|
||||
null,
|
||||
null));
|
||||
withdrawals));
|
||||
|
||||
final JsonRpcError jsonRpcError = fromErrorResp(resp);
|
||||
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
|
||||
@@ -143,13 +133,11 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
|
||||
public void shouldValidateBlobGasUsedCorrectly() {
|
||||
// V2 should return error if non-null blobGasUsed
|
||||
BlockHeader blockHeader =
|
||||
createBlockHeaderFixture(
|
||||
Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty())
|
||||
createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
|
||||
.blobGasUsed(100L)
|
||||
.buildHeader();
|
||||
|
||||
var resp =
|
||||
resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null));
|
||||
var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of()));
|
||||
final JsonRpcError jsonRpcError = fromErrorResp(resp);
|
||||
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_BLOB_GAS_USED_PARAMS.getCode());
|
||||
assertThat(jsonRpcError.getData()).isEqualTo("Missing blob gas used field");
|
||||
@@ -160,13 +148,11 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
|
||||
public void shouldValidateExcessBlobGasCorrectly() {
|
||||
// V2 should return error if non-null ExcessBlobGas
|
||||
BlockHeader blockHeader =
|
||||
createBlockHeaderFixture(
|
||||
Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty())
|
||||
createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
|
||||
.excessBlobGas(BlobGas.MAX_BLOB_GAS)
|
||||
.buildHeader();
|
||||
|
||||
var resp =
|
||||
resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null));
|
||||
var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of()));
|
||||
|
||||
final JsonRpcError jsonRpcError = fromErrorResp(resp);
|
||||
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
|
||||
@@ -183,12 +169,9 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
|
||||
var resp =
|
||||
resp(
|
||||
mockEnginePayload(
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty()),
|
||||
createBlockHeader(Optional.empty(), Optional.empty()),
|
||||
Collections.emptyList(),
|
||||
withdrawals,
|
||||
null,
|
||||
null,
|
||||
null));
|
||||
withdrawals));
|
||||
|
||||
assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode());
|
||||
verify(engineCallListener, times(1)).executionEngineCalled();
|
||||
@@ -199,13 +182,11 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
|
||||
// Cancun starte at timestamp 30
|
||||
final long blockTimestamp = 31L;
|
||||
BlockHeader blockHeader =
|
||||
createBlockHeaderFixture(
|
||||
Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty())
|
||||
createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
|
||||
.timestamp(blockTimestamp)
|
||||
.buildHeader();
|
||||
|
||||
var resp =
|
||||
resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null));
|
||||
var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of()));
|
||||
|
||||
final JsonRpcError jsonRpcError = fromErrorResp(resp);
|
||||
assertThat(jsonRpcError.getCode()).isEqualTo(UNSUPPORTED_FORK.getCode());
|
||||
|
||||
@@ -44,11 +44,10 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EnginePayloadS
|
||||
import org.hyperledger.besu.ethereum.core.BlobTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.DepositRequest;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.Withdrawal;
|
||||
import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.EncodingContext;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;
|
||||
import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
|
||||
@@ -135,24 +134,23 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
final EnginePayloadParameter payload =
|
||||
mockEnginePayload(mockHeader, Collections.emptyList(), null, null, null, null);
|
||||
mockEnginePayload(mockHeader, Collections.emptyList(), null);
|
||||
|
||||
ValidationResult<RpcErrorType> res =
|
||||
method.validateParameters(
|
||||
payload,
|
||||
Optional.of(List.of()),
|
||||
Optional.of("0x0000000000000000000000000000000000000000000000000000000000000000"));
|
||||
Optional.of("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
Optional.empty());
|
||||
assertThat(res.isValid()).isTrue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockHeader createBlockHeader(
|
||||
final Optional<List<Withdrawal>> maybeWithdrawals,
|
||||
final Optional<List<DepositRequest>> maybeDepositRequests,
|
||||
final Optional<List<WithdrawalRequest>> maybeWithdrawalRequests) {
|
||||
final Optional<List<Request>> maybeRequests) {
|
||||
BlockHeader parentBlockHeader =
|
||||
new BlockHeaderTestFixture()
|
||||
.baseFeePerGas(Wei.ONE)
|
||||
@@ -188,14 +186,12 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
|
||||
public void shouldValidateBlobGasUsedCorrectly() {
|
||||
// V3 must return error if null blobGasUsed
|
||||
BlockHeader blockHeader =
|
||||
createBlockHeaderFixture(
|
||||
Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty())
|
||||
createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
|
||||
.excessBlobGas(BlobGas.MAX_BLOB_GAS)
|
||||
.blobGasUsed(null)
|
||||
.buildHeader();
|
||||
|
||||
var resp =
|
||||
resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null));
|
||||
var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of()));
|
||||
|
||||
final JsonRpcError jsonRpcError = fromErrorResp(resp);
|
||||
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
|
||||
@@ -208,14 +204,12 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
|
||||
public void shouldValidateExcessBlobGasCorrectly() {
|
||||
// V3 must return error if null excessBlobGas
|
||||
BlockHeader blockHeader =
|
||||
createBlockHeaderFixture(
|
||||
Optional.of(Collections.emptyList()), Optional.empty(), Optional.empty())
|
||||
createBlockHeaderFixture(Optional.of(Collections.emptyList()), Optional.empty())
|
||||
.excessBlobGas(null)
|
||||
.blobGasUsed(100L)
|
||||
.buildHeader();
|
||||
|
||||
var resp =
|
||||
resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of(), null, null, null));
|
||||
var resp = resp(mockEnginePayload(blockHeader, Collections.emptyList(), List.of()));
|
||||
|
||||
final JsonRpcError jsonRpcError = fromErrorResp(resp);
|
||||
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
|
||||
@@ -236,7 +230,6 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
var resp = resp(mockEnginePayload(mockHeader, transactions));
|
||||
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositParameterTestFixture.DEPOSIT_PARAM_1;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestTestFixture.WITHDRAWAL_REQUEST_PARAMETER_1;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_PARAMS;
|
||||
import static org.hyperledger.besu.ethereum.api.graphql.internal.response.GraphQLError.INVALID_PARAMS;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -25,7 +23,6 @@ import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BlobGas;
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
@@ -33,28 +30,24 @@ import org.hyperledger.besu.ethereum.BlockProcessingOutputs;
|
||||
import org.hyperledger.besu.ethereum.BlockProcessingResult;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.DepositRequest;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.Withdrawal;
|
||||
import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
|
||||
import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestValidator;
|
||||
import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -63,8 +56,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
|
||||
private static final Address depositContractAddress =
|
||||
Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa");
|
||||
|
||||
public EngineNewPayloadV4Test() {}
|
||||
|
||||
@@ -92,8 +83,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnValidIfDepositRequestsIsNull_WhenDepositRequestsProhibited() {
|
||||
final List<DepositRequestParameter> depositRequests = null;
|
||||
public void shouldReturnValidIfRequestsIsNull_WhenRequestsProhibited() {
|
||||
mockProhibitedRequestsValidator();
|
||||
|
||||
BlockHeader mockHeader =
|
||||
@@ -101,170 +91,69 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
|
||||
new BlockProcessingResult(
|
||||
Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.empty()))),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
.thenReturn(Optional.of(mock(BlockHeader.class)));
|
||||
when(mergeCoordinator.getLatestValidAncestor(mockHeader))
|
||||
.thenReturn(Optional.of(mockHeader.getHash()));
|
||||
|
||||
var resp =
|
||||
resp(
|
||||
mockEnginePayload(
|
||||
mockHeader, Collections.emptyList(), null, depositRequests, null, null));
|
||||
var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()));
|
||||
|
||||
assertValidResponse(mockHeader, resp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnInvalidIfDepositRequestsIsNull_WhenDepositRequestsAllowed() {
|
||||
final List<DepositRequestParameter> depositRequests = null;
|
||||
mockAllowedDepositRequestsRequestValidator();
|
||||
public void shouldReturnInvalidIfRequestsIsNull_WhenRequestsAllowed() {
|
||||
mockAllowedRequestsValidator();
|
||||
var resp =
|
||||
resp(
|
||||
mockEnginePayload(
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty()),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
depositRequests,
|
||||
null,
|
||||
null));
|
||||
createBlockHeader(Optional.empty(), Optional.empty()), Collections.emptyList()));
|
||||
|
||||
assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode());
|
||||
verify(engineCallListener, times(1)).executionEngineCalled();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnValidIfDepositRequestsIsNotNull_WhenDepositRequestsAllowed() {
|
||||
final List<DepositRequestParameter> depositRequestsParam = List.of(DEPOSIT_PARAM_1);
|
||||
final List<Request> depositRequests = List.of(DEPOSIT_PARAM_1.toDeposit());
|
||||
public void shouldReturnValidIfRequestsIsNotNull_WhenRequestsAllowed() {
|
||||
final List<Request> requests =
|
||||
List.of(
|
||||
new Request(RequestType.DEPOSIT, Bytes.of(1)),
|
||||
new Request(RequestType.WITHDRAWAL, Bytes.of(1)),
|
||||
new Request(RequestType.CONSOLIDATION, Bytes.of(1)));
|
||||
|
||||
mockAllowedDepositRequestsRequestValidator();
|
||||
mockAllowedRequestsValidator();
|
||||
BlockHeader mockHeader =
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(
|
||||
Optional.of(
|
||||
new BlockProcessingOutputs(null, List.of(), Optional.of(depositRequests)))),
|
||||
Optional.empty(),
|
||||
Optional.of(List.of(DEPOSIT_PARAM_1.toDeposit())),
|
||||
Optional.empty());
|
||||
when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
.thenReturn(Optional.of(mock(BlockHeader.class)));
|
||||
when(mergeCoordinator.getLatestValidAncestor(mockHeader))
|
||||
.thenReturn(Optional.of(mockHeader.getHash()));
|
||||
var resp =
|
||||
resp(
|
||||
mockEnginePayload(
|
||||
mockHeader, Collections.emptyList(), null, depositRequestsParam, null, null));
|
||||
|
||||
assertValidResponse(mockHeader, resp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnInvalidIfDepositRequestsIsNotNull_WhenDepositRequestsProhibited() {
|
||||
final List<DepositRequestParameter> depositRequests = List.of();
|
||||
lenient()
|
||||
.when(protocolSpec.getRequestsValidatorCoordinator())
|
||||
.thenReturn(RequestsValidatorCoordinator.empty());
|
||||
|
||||
var resp =
|
||||
resp(
|
||||
mockEnginePayload(
|
||||
createBlockHeader(
|
||||
Optional.empty(), Optional.of(Collections.emptyList()), Optional.empty()),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
depositRequests,
|
||||
null,
|
||||
null));
|
||||
|
||||
final JsonRpcError jsonRpcError = fromErrorResp(resp);
|
||||
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
|
||||
verify(engineCallListener, times(1)).executionEngineCalled();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnValidIfWithdrawalRequestsIsNull_WhenWithdrawalRequestsAreProhibited() {
|
||||
mockProhibitedRequestsValidator();
|
||||
|
||||
BlockHeader mockHeader =
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(
|
||||
Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.empty()))),
|
||||
Optional.empty(),
|
||||
Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.of(requests)))),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
.thenReturn(Optional.of(mock(BlockHeader.class)));
|
||||
when(mergeCoordinator.getLatestValidAncestor(mockHeader))
|
||||
.thenReturn(Optional.of(mockHeader.getHash()));
|
||||
|
||||
var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList(), null, null, null, null));
|
||||
var resp = resp(mockEnginePayload(mockHeader, Collections.emptyList()), requests);
|
||||
|
||||
assertValidResponse(mockHeader, resp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnInvalidIfWithdrawalRequestsIsNull_WhenWithdrawalRequestsAreAllowed() {
|
||||
mockAllowedWithdrawalsRequestValidator();
|
||||
public void shouldReturnInvalidIfRequestsIsNotNull_WhenRequestsProhibited() {
|
||||
final List<Request> requests =
|
||||
List.of(
|
||||
new Request(RequestType.DEPOSIT, Bytes.of(1)),
|
||||
new Request(RequestType.WITHDRAWAL, Bytes.of(1)),
|
||||
new Request(RequestType.CONSOLIDATION, Bytes.of(1)));
|
||||
|
||||
var resp =
|
||||
resp(
|
||||
mockEnginePayload(
|
||||
createBlockHeader(Optional.empty(), Optional.empty(), Optional.empty()),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null));
|
||||
|
||||
assertThat(fromErrorResp(resp).getCode()).isEqualTo(INVALID_PARAMS.getCode());
|
||||
verify(engineCallListener, times(1)).executionEngineCalled();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnValidIfWithdrawalRequestsIsNotNull_WhenWithdrawalRequestsAreAllowed() {
|
||||
final List<WithdrawalRequestParameter> withdrawalRequestsParams =
|
||||
List.of(WITHDRAWAL_REQUEST_PARAMETER_1);
|
||||
final List<Request> withdrawalRequests =
|
||||
List.of(WITHDRAWAL_REQUEST_PARAMETER_1.toWithdrawalRequest());
|
||||
mockAllowedWithdrawalsRequestValidator();
|
||||
BlockHeader mockHeader =
|
||||
setupValidPayload(
|
||||
new BlockProcessingResult(
|
||||
Optional.of(
|
||||
new BlockProcessingOutputs(null, List.of(), Optional.of(withdrawalRequests)))),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.of(List.of(WITHDRAWAL_REQUEST_PARAMETER_1.toWithdrawalRequest())));
|
||||
when(blockchain.getBlockHeader(mockHeader.getParentHash()))
|
||||
.thenReturn(Optional.of(mock(BlockHeader.class)));
|
||||
when(mergeCoordinator.getLatestValidAncestor(mockHeader))
|
||||
.thenReturn(Optional.of(mockHeader.getHash()));
|
||||
var resp =
|
||||
resp(
|
||||
mockEnginePayload(
|
||||
mockHeader, Collections.emptyList(), null, null, withdrawalRequestsParams, null));
|
||||
|
||||
assertValidResponse(mockHeader, resp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void
|
||||
shouldReturnInvalidIfWithdrawalRequestsIsNotNull_WhenWithdrawalRequestsAreProhibited() {
|
||||
final List<WithdrawalRequestParameter> withdrawalRequests = List.of();
|
||||
mockProhibitedRequestsValidator();
|
||||
|
||||
var resp =
|
||||
resp(
|
||||
mockEnginePayload(
|
||||
createBlockHeader(
|
||||
Optional.empty(), Optional.empty(), Optional.of(Collections.emptyList())),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
null,
|
||||
withdrawalRequests,
|
||||
null));
|
||||
createBlockHeader(Optional.empty(), Optional.of(Collections.emptyList())),
|
||||
Collections.emptyList()),
|
||||
requests);
|
||||
|
||||
final JsonRpcError jsonRpcError = fromErrorResp(resp);
|
||||
assertThat(jsonRpcError.getCode()).isEqualTo(INVALID_PARAMS.getCode());
|
||||
@@ -274,8 +163,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
|
||||
@Override
|
||||
protected BlockHeader createBlockHeader(
|
||||
final Optional<List<Withdrawal>> maybeWithdrawals,
|
||||
final Optional<List<DepositRequest>> maybeDepositRequests,
|
||||
final Optional<List<WithdrawalRequest>> maybeWithdrawalRequests) {
|
||||
final Optional<List<Request>> maybeRequests) {
|
||||
BlockHeader parentBlockHeader =
|
||||
new BlockHeaderTestFixture()
|
||||
.baseFeePerGas(Wei.ONE)
|
||||
@@ -284,16 +172,6 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
|
||||
.blobGasUsed(0L)
|
||||
.buildHeader();
|
||||
|
||||
Optional<List<Request>> maybeRequests;
|
||||
if (maybeDepositRequests.isPresent() || maybeWithdrawalRequests.isPresent()) {
|
||||
List<Request> requests = new ArrayList<>();
|
||||
maybeDepositRequests.ifPresent(requests::addAll);
|
||||
maybeWithdrawalRequests.ifPresent(requests::addAll);
|
||||
maybeRequests = Optional.of(requests);
|
||||
} else {
|
||||
maybeRequests = Optional.empty();
|
||||
}
|
||||
|
||||
BlockHeader mockHeader =
|
||||
new BlockHeaderTestFixture()
|
||||
.baseFeePerGas(Wei.ONE)
|
||||
@@ -303,7 +181,7 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
|
||||
.withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null))
|
||||
.excessBlobGas(BlobGas.ZERO)
|
||||
.blobGasUsed(0L)
|
||||
.requestsRoot(maybeRequests.map(BodyValidation::requestsRoot).orElse(null))
|
||||
.requestsHash(maybeRequests.map(BodyValidation::requestsHash).orElse(null))
|
||||
.parentBeaconBlockRoot(
|
||||
maybeParentBeaconBlockRoot.isPresent() ? maybeParentBeaconBlockRoot : null)
|
||||
.buildHeader();
|
||||
@@ -320,24 +198,35 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
|
||||
new JsonRpcRequestContext(new JsonRpcRequest("2.0", this.method.getName(), params)));
|
||||
}
|
||||
|
||||
protected JsonRpcResponse resp(
|
||||
final EnginePayloadParameter payload, final List<Request> requests) {
|
||||
final List<String> requestsWithoutRequestId =
|
||||
requests.stream()
|
||||
.sorted(Comparator.comparing(Request::getType))
|
||||
.map(r -> r.getData().toHexString())
|
||||
.toList();
|
||||
Object[] params =
|
||||
maybeParentBeaconBlockRoot
|
||||
.map(
|
||||
bytes32 ->
|
||||
new Object[] {
|
||||
payload,
|
||||
Collections.emptyList(),
|
||||
bytes32.toHexString(),
|
||||
requestsWithoutRequestId
|
||||
})
|
||||
.orElseGet(() -> new Object[] {payload});
|
||||
return method.response(
|
||||
new JsonRpcRequestContext(new JsonRpcRequest("2.0", this.method.getName(), params)));
|
||||
}
|
||||
|
||||
private void mockProhibitedRequestsValidator() {
|
||||
var validator = RequestsValidatorCoordinator.empty();
|
||||
when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(validator);
|
||||
var validator = new ProhibitedRequestValidator();
|
||||
when(protocolSpec.getRequestsValidator()).thenReturn(validator);
|
||||
}
|
||||
|
||||
private void mockAllowedDepositRequestsRequestValidator() {
|
||||
var validator =
|
||||
new RequestsValidatorCoordinator.Builder()
|
||||
.addValidator(RequestType.DEPOSIT, new DepositRequestValidator(depositContractAddress))
|
||||
.build();
|
||||
when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(validator);
|
||||
}
|
||||
|
||||
private void mockAllowedWithdrawalsRequestValidator() {
|
||||
var validator =
|
||||
new RequestsValidatorCoordinator.Builder()
|
||||
.addValidator(RequestType.WITHDRAWAL, new WithdrawalRequestValidator())
|
||||
.build();
|
||||
when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(validator);
|
||||
private void mockAllowedRequestsValidator() {
|
||||
var validator = new MainnetRequestsValidator();
|
||||
when(protocolSpec.getRequestsValidator()).thenReturn(validator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters;
|
||||
|
||||
public class DepositParameterTestFixture {
|
||||
|
||||
public static final DepositRequestParameter DEPOSIT_PARAM_1 =
|
||||
createDeposit(
|
||||
"0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e",
|
||||
"0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483",
|
||||
"0x773594000",
|
||||
"0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5",
|
||||
"0x1");
|
||||
static final DepositRequestParameter DEPOSIT_PARAM_2 =
|
||||
createDeposit(
|
||||
"0x8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243",
|
||||
"0x006a8dc800c6d8dd6977ef53264e2d030350f0145a91bcd167b4f1c3ea21b271",
|
||||
"0x773594000",
|
||||
"0x801b08ca107b623eca32ee9f9111b4e50eb9cfe19e38204b72de7dc04c5a5e00f61bab96f10842576f66020ce851083f1583dd9a6b73301bea6c245cf51f27cf96aeb018852c5f70bf485d16b957cfe49ca008913346b431e7653ae3ddb23b07",
|
||||
"0x3");
|
||||
|
||||
private static DepositRequestParameter createDeposit(
|
||||
final String pubKey,
|
||||
final String withdrawalCredentials,
|
||||
final String amount,
|
||||
final String signature,
|
||||
final String index) {
|
||||
return new DepositRequestParameter(pubKey, withdrawalCredentials, amount, signature, index);
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositParameterTestFixture.DEPOSIT_PARAM_1;
|
||||
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.datatypes.BLSSignature;
|
||||
import org.hyperledger.besu.datatypes.GWei;
|
||||
import org.hyperledger.besu.ethereum.core.DepositRequest;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt64;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class DepositRequestRequestParameterTest {
|
||||
|
||||
@Test
|
||||
public void toDeposit() {
|
||||
DepositRequest expected =
|
||||
new DepositRequest(
|
||||
BLSPublicKey.fromHexString(
|
||||
"0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"),
|
||||
Bytes32.fromHexString(
|
||||
"0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"),
|
||||
GWei.of(32000000000L),
|
||||
BLSSignature.fromHexString(
|
||||
"0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"),
|
||||
UInt64.ONE);
|
||||
assertThat(DEPOSIT_PARAM_1.toDeposit()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromDeposit() {
|
||||
DepositRequest depositRequest =
|
||||
new DepositRequest(
|
||||
BLSPublicKey.fromHexString(
|
||||
"0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"),
|
||||
Bytes32.fromHexString(
|
||||
"0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"),
|
||||
GWei.of(32000000000L),
|
||||
BLSSignature.fromHexString(
|
||||
"0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"),
|
||||
UInt64.ONE);
|
||||
|
||||
assertThat(DepositRequestParameter.fromDeposit(depositRequest)).isEqualTo(DEPOSIT_PARAM_1);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalRequestTestFixture.WITHDRAWAL_REQUEST_PARAMETER_1;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.datatypes.GWei;
|
||||
import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class WithdrawalRequestParameterTest {
|
||||
|
||||
@Test
|
||||
public void toWithdrawalRequest() {
|
||||
WithdrawalRequest expected =
|
||||
new WithdrawalRequest(
|
||||
Address.fromHexString("0x814FaE9f487206471B6B0D713cD51a2D35980000"),
|
||||
BLSPublicKey.fromHexString(
|
||||
"0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"),
|
||||
GWei.ONE);
|
||||
assertThat(WITHDRAWAL_REQUEST_PARAMETER_1.toWithdrawalRequest()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromWithdrawalRequest() {
|
||||
WithdrawalRequest withdrawalRequest =
|
||||
new WithdrawalRequest(
|
||||
Address.fromHexString("0x814FaE9f487206471B6B0D713cD51a2D35980000"),
|
||||
BLSPublicKey.fromHexString(
|
||||
"0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"),
|
||||
GWei.ONE);
|
||||
|
||||
assertThat(WithdrawalRequestParameter.fromWithdrawalRequest(withdrawalRequest))
|
||||
.isEqualTo(WITHDRAWAL_REQUEST_PARAMETER_1);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters;
|
||||
|
||||
import org.hyperledger.besu.datatypes.GWei;
|
||||
|
||||
public class WithdrawalRequestTestFixture {
|
||||
|
||||
public static final WithdrawalRequestParameter WITHDRAWAL_REQUEST_PARAMETER_1 =
|
||||
new WithdrawalRequestParameter(
|
||||
"0x814fae9f487206471b6b0d713cd51a2d35980000",
|
||||
"0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e",
|
||||
GWei.ONE.toShortHexString());
|
||||
static final WithdrawalRequestParameter WITHDRAWAL_REQUEST_PARAMETER_2 =
|
||||
new WithdrawalRequestParameter(
|
||||
"0x758b8178a9a4b7206d1f648c4a77c515cbac7000",
|
||||
"0x8706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf243",
|
||||
GWei.ONE.toShortHexString());
|
||||
}
|
||||
@@ -265,7 +265,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
operationTracer);
|
||||
|
||||
Optional<List<Request>> maybeRequests =
|
||||
requestProcessor.flatMap(processor -> processor.process(context));
|
||||
requestProcessor.map(processor -> processor.process(context));
|
||||
|
||||
throwIfStopped();
|
||||
|
||||
@@ -304,7 +304,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
withdrawalsCanBeProcessed
|
||||
? BodyValidation.withdrawalsRoot(maybeWithdrawals.get())
|
||||
: null)
|
||||
.requestsRoot(maybeRequests.map(BodyValidation::requestsRoot).orElse(null));
|
||||
.requestsHash(maybeRequests.map(BodyValidation::requestsHash).orElse(null));
|
||||
if (usage != null) {
|
||||
builder.blobGasUsed(usage.used.toLong()).excessBlobGas(usage.excessBlobGas);
|
||||
}
|
||||
@@ -316,8 +316,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
final Optional<List<Withdrawal>> withdrawals =
|
||||
withdrawalsCanBeProcessed ? maybeWithdrawals : Optional.empty();
|
||||
final BlockBody blockBody =
|
||||
new BlockBody(
|
||||
transactionResults.getSelectedTransactions(), ommers, withdrawals, maybeRequests);
|
||||
new BlockBody(transactionResults.getSelectedTransactions(), ommers, withdrawals);
|
||||
final Block block = new Block(blockHeader, blockBody);
|
||||
|
||||
operationTracer.traceEndBlock(blockHeader, blockBody);
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.blockcreation;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor.DEFAULT_DEPOSIT_CONTRACT_ADDRESS;
|
||||
import static org.hyperledger.besu.ethereum.mainnet.requests.RequestContractAddresses.DEFAULT_DEPOSIT_CONTRACT_ADDRESS;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
@@ -31,8 +30,6 @@ import org.hyperledger.besu.crypto.SECPPrivateKey;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithm;
|
||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.datatypes.BLSSignature;
|
||||
import org.hyperledger.besu.datatypes.BlobGas;
|
||||
import org.hyperledger.besu.datatypes.BlobsWithCommitments;
|
||||
import org.hyperledger.besu.datatypes.GWei;
|
||||
@@ -48,7 +45,6 @@ import org.hyperledger.besu.ethereum.core.BlobTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
|
||||
import org.hyperledger.besu.ethereum.core.DepositRequest;
|
||||
import org.hyperledger.besu.ethereum.core.Difficulty;
|
||||
import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters;
|
||||
@@ -81,10 +77,7 @@ import org.hyperledger.besu.ethereum.mainnet.TransactionValidatorFactory;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.ethereum.mainnet.WithdrawalsProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.ProcessRequestContext;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
|
||||
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
@@ -141,83 +134,16 @@ abstract class AbstractBlockCreatorTest {
|
||||
List<TransactionReceipt> receipts =
|
||||
List.of(receiptWithoutDeposit1, receiptWithDeposit, receiptWithoutDeposit2);
|
||||
|
||||
DepositRequest expectedDepositRequest =
|
||||
new DepositRequest(
|
||||
BLSPublicKey.fromHexString(
|
||||
"0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"),
|
||||
Bytes32.fromHexString(
|
||||
"0x0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa35589483"),
|
||||
GWei.of(32000000000L),
|
||||
BLSSignature.fromHexString(
|
||||
"0xa889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb5"),
|
||||
UInt64.valueOf(539967));
|
||||
final List<DepositRequest> expectedDepositRequests = List.of(expectedDepositRequest);
|
||||
Request expectedDepositRequest =
|
||||
new Request(
|
||||
RequestType.DEPOSIT,
|
||||
Bytes.fromHexString(
|
||||
"0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e0017a7fcf06faf493d30bbe2632ea7c2383cd86825e12797165de7aa355894830040597307000000a889db8300194050a2636c92a95bc7160515867614b7971a9500cdb62f9c0890217d2901c3241f86fac029428fc106930606154bd9e406d7588934a5f15b837180b17194d6e44bd6de23e43b163dfe12e369dcc75a3852cd997963f158217eb53f3d080000000000"));
|
||||
|
||||
var depositRequestsFromReceipts =
|
||||
new DepositRequestProcessor(DEFAULT_DEPOSIT_CONTRACT_ADDRESS)
|
||||
.process(new ProcessRequestContext(null, null, null, receipts, null, null));
|
||||
assertThat(depositRequestsFromReceipts.get()).isEqualTo(expectedDepositRequests);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withAllowedDepositRequestsAndContractAddress_DepositRequestsAreParsed() {
|
||||
final CreateOn miningOn =
|
||||
blockCreatorWithAllowedDepositRequests(DEFAULT_DEPOSIT_CONTRACT_ADDRESS);
|
||||
|
||||
final BlockCreationResult blockCreationResult =
|
||||
miningOn.blockCreator.createBlock(
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.of(emptyList()),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
|
||||
List<Request> depositRequests = emptyList();
|
||||
final Hash requestsRoot = BodyValidation.requestsRoot(depositRequests);
|
||||
assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).hasValue(requestsRoot);
|
||||
assertThat(blockCreationResult.getBlock().getBody().getRequests()).hasValue(depositRequests);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withAllowedDepositRequestsAndNoContractAddress_DepositRequestsAreNotParsed() {
|
||||
final CreateOn miningOn = blockCreatorWithAllowedDepositRequests(null);
|
||||
|
||||
final BlockCreationResult blockCreationResult =
|
||||
miningOn.blockCreator.createBlock(
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.of(emptyList()),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
|
||||
assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).isEmpty();
|
||||
assertThat(blockCreationResult.getBlock().getBody().getRequests()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void withProhibitedDepositRequests_DepositRequestsAreNotParsed() {
|
||||
|
||||
final CreateOn miningOn = blockCreatorWithProhibitedDepositRequests();
|
||||
|
||||
final BlockCreationResult blockCreationResult =
|
||||
miningOn.blockCreator.createBlock(
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.of(emptyList()),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
1L,
|
||||
false,
|
||||
miningOn.parentHeader);
|
||||
|
||||
assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).isEmpty();
|
||||
assertThat(blockCreationResult.getBlock().getBody().getRequests()).isEmpty();
|
||||
assertThat(depositRequestsFromReceipts).isEqualTo(expectedDepositRequest);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -355,12 +281,6 @@ abstract class AbstractBlockCreatorTest {
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
private CreateOn blockCreatorWithProhibitedDepositRequests() {
|
||||
final ProtocolSpecAdapters protocolSpecAdapters =
|
||||
ProtocolSpecAdapters.create(0, specBuilder -> specBuilder);
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
private CreateOn blockCreatorWithWithdrawalsProcessor() {
|
||||
final ProtocolSpecAdapters protocolSpecAdapters =
|
||||
ProtocolSpecAdapters.create(
|
||||
@@ -374,27 +294,6 @@ abstract class AbstractBlockCreatorTest {
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
private CreateOn blockCreatorWithAllowedDepositRequests(final Address depositContractAddress) {
|
||||
final ProtocolSpecAdapters protocolSpecAdapters =
|
||||
ProtocolSpecAdapters.create(
|
||||
0,
|
||||
specBuilder ->
|
||||
specBuilder
|
||||
.requestsValidator(
|
||||
new RequestsValidatorCoordinator.Builder()
|
||||
.addValidator(
|
||||
RequestType.DEPOSIT,
|
||||
new DepositRequestValidator((depositContractAddress)))
|
||||
.build())
|
||||
.requestProcessorCoordinator(
|
||||
new RequestProcessorCoordinator.Builder()
|
||||
.addProcessor(
|
||||
RequestType.DEPOSIT,
|
||||
new DepositRequestProcessor(depositContractAddress))
|
||||
.build()));
|
||||
return createBlockCreator(protocolSpecAdapters);
|
||||
}
|
||||
|
||||
record CreateOn(AbstractBlockCreator blockCreator, BlockHeader parentHeader) {}
|
||||
|
||||
private CreateOn createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum;
|
||||
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -134,4 +135,13 @@ public class BlockProcessingResult extends BlockValidationResult {
|
||||
return yield.get().getReceipts();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the requests of the result.
|
||||
*
|
||||
* @return the requests of the result
|
||||
*/
|
||||
public Optional<List<Request>> getRequests() {
|
||||
return yield.flatMap(BlockProcessingOutputs::getRequests);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,11 @@
|
||||
package org.hyperledger.besu.ethereum;
|
||||
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.mainnet.BodyValidationMode;
|
||||
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* The BlockValidator interface defines the methods for validating and processing blocks in the
|
||||
@@ -90,7 +88,6 @@ public interface BlockValidator {
|
||||
* @param context the protocol context
|
||||
* @param block the block to validate
|
||||
* @param receipts the transaction receipts
|
||||
* @param requests the requests
|
||||
* @param headerValidationMode the header validation mode
|
||||
* @param ommerValidationMode the ommer validation mode
|
||||
* @param bodyValidationMode the body validation mode
|
||||
@@ -100,7 +97,6 @@ public interface BlockValidator {
|
||||
final ProtocolContext context,
|
||||
final Block block,
|
||||
final List<TransactionReceipt> receipts,
|
||||
final Optional<List<Request>> requests,
|
||||
final HeaderValidationMode headerValidationMode,
|
||||
final HeaderValidationMode ommerValidationMode,
|
||||
final BodyValidationMode bodyValidationMode);
|
||||
|
||||
@@ -171,7 +171,7 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
Optional<List<Request>> maybeRequests =
|
||||
result.getYield().flatMap(BlockProcessingOutputs::getRequests);
|
||||
if (!blockBodyValidator.validateBody(
|
||||
context, block, receipts, maybeRequests, worldState.rootHash(), ommerValidationMode)) {
|
||||
context, block, receipts, worldState.rootHash(), ommerValidationMode)) {
|
||||
result = new BlockProcessingResult("failed to validate output of imported block");
|
||||
handleFailedBlockProcessing(block, result, shouldRecordBadBlock);
|
||||
return result;
|
||||
@@ -181,16 +181,7 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests)));
|
||||
}
|
||||
} catch (MerkleTrieException ex) {
|
||||
context
|
||||
.getSynchronizer()
|
||||
.ifPresentOrElse(
|
||||
synchronizer -> synchronizer.healWorldState(ex.getMaybeAddress(), ex.getLocation()),
|
||||
() ->
|
||||
handleFailedBlockProcessing(
|
||||
block,
|
||||
new BlockProcessingResult(Optional.empty(), ex),
|
||||
// Do not record bad black due to missing data
|
||||
false));
|
||||
context.getSynchronizer().healWorldState(ex.getMaybeAddress(), ex.getLocation());
|
||||
return new BlockProcessingResult(Optional.empty(), ex);
|
||||
} catch (StorageException ex) {
|
||||
var retval = new BlockProcessingResult(Optional.empty(), ex);
|
||||
@@ -252,7 +243,6 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
final ProtocolContext context,
|
||||
final Block block,
|
||||
final List<TransactionReceipt> receipts,
|
||||
final Optional<List<Request>> requests,
|
||||
final HeaderValidationMode headerValidationMode,
|
||||
final HeaderValidationMode ommerValidationMode,
|
||||
final BodyValidationMode bodyValidationMode) {
|
||||
@@ -264,7 +254,7 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
}
|
||||
|
||||
if (!blockBodyValidator.validateBodyLight(
|
||||
context, block, receipts, requests, ommerValidationMode, bodyValidationMode)) {
|
||||
context, block, receipts, ommerValidationMode, bodyValidationMode)) {
|
||||
badBlockManager.addBadBlock(
|
||||
block, BadBlockCause.fromValidationFailure("Failed body validation (light)"));
|
||||
return false;
|
||||
|
||||
@@ -32,8 +32,7 @@ public class ProtocolContext {
|
||||
private final WorldStateArchive worldStateArchive;
|
||||
private final BadBlockManager badBlockManager;
|
||||
private final ConsensusContext consensusContext;
|
||||
|
||||
private Optional<Synchronizer> synchronizer;
|
||||
private Synchronizer synchronizer;
|
||||
|
||||
/**
|
||||
* Constructs a new ProtocolContext with the given blockchain, world state archive, consensus
|
||||
@@ -52,7 +51,6 @@ public class ProtocolContext {
|
||||
this.blockchain = blockchain;
|
||||
this.worldStateArchive = worldStateArchive;
|
||||
this.consensusContext = consensusContext;
|
||||
this.synchronizer = Optional.empty();
|
||||
this.badBlockManager = badBlockManager;
|
||||
}
|
||||
|
||||
@@ -85,7 +83,7 @@ public class ProtocolContext {
|
||||
*
|
||||
* @return the synchronizer of the protocol context
|
||||
*/
|
||||
public Optional<Synchronizer> getSynchronizer() {
|
||||
public Synchronizer getSynchronizer() {
|
||||
return synchronizer;
|
||||
}
|
||||
|
||||
@@ -94,7 +92,7 @@ public class ProtocolContext {
|
||||
*
|
||||
* @param synchronizer the synchronizer to set
|
||||
*/
|
||||
public void setSynchronizer(final Optional<Synchronizer> synchronizer) {
|
||||
public void setSynchronizer(final Synchronizer synchronizer) {
|
||||
this.synchronizer = synchronizer;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
|
||||
import org.hyperledger.besu.ethereum.core.Difficulty;
|
||||
import org.hyperledger.besu.ethereum.core.MutableWorldState;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.Withdrawal;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
|
||||
@@ -145,10 +144,8 @@ public final class GenesisState {
|
||||
private static BlockBody buildBody(final GenesisConfigFile config) {
|
||||
final Optional<List<Withdrawal>> withdrawals =
|
||||
isShanghaiAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty();
|
||||
final Optional<List<Request>> requests =
|
||||
isPragueAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty();
|
||||
|
||||
return new BlockBody(emptyList(), emptyList(), withdrawals, requests);
|
||||
return new BlockBody(emptyList(), emptyList(), withdrawals);
|
||||
}
|
||||
|
||||
public Block getBlock() {
|
||||
@@ -220,7 +217,7 @@ public final class GenesisState {
|
||||
.excessBlobGas(isCancunAtGenesis(genesis) ? parseExcessBlobGas(genesis) : null)
|
||||
.parentBeaconBlockRoot(
|
||||
(isCancunAtGenesis(genesis) ? parseParentBeaconBlockRoot(genesis) : null))
|
||||
.requestsRoot(isPragueAtGenesis(genesis) ? Hash.EMPTY_TRIE_HASH : null)
|
||||
.requestsHash(isPragueAtGenesis(genesis) ? Hash.EMPTY_REQUESTS_HASH : null)
|
||||
.buildBlockHeader();
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ public class Block {
|
||||
out.writeList(body.getTransactions(), Transaction::writeTo);
|
||||
out.writeList(body.getOmmers(), BlockHeader::writeTo);
|
||||
body.getWithdrawals().ifPresent(withdrawals -> out.writeList(withdrawals, Withdrawal::writeTo));
|
||||
body.getRequests().ifPresent(requests -> out.writeList(requests, Request::writeTo));
|
||||
|
||||
out.endList();
|
||||
}
|
||||
@@ -74,11 +73,9 @@ public class Block {
|
||||
final List<BlockHeader> ommers = in.readList(rlp -> BlockHeader.readFrom(rlp, hashFunction));
|
||||
final Optional<List<Withdrawal>> withdrawals =
|
||||
in.isEndOfCurrentList() ? Optional.empty() : Optional.of(in.readList(Withdrawal::readFrom));
|
||||
final Optional<List<Request>> requests =
|
||||
in.isEndOfCurrentList() ? Optional.empty() : Optional.of(in.readList(Request::readFrom));
|
||||
in.leaveList();
|
||||
|
||||
return new Block(header, new BlockBody(transactions, ommers, withdrawals, requests));
|
||||
return new Block(header, new BlockBody(transactions, ommers, withdrawals));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -37,24 +37,20 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
|
||||
|
||||
private final List<BlockHeader> ommers;
|
||||
private final Optional<List<Withdrawal>> withdrawals;
|
||||
private final Optional<List<Request>> requests;
|
||||
|
||||
public BlockBody(final List<Transaction> transactions, final List<BlockHeader> ommers) {
|
||||
this.transactions = transactions;
|
||||
this.ommers = ommers;
|
||||
this.withdrawals = Optional.empty();
|
||||
this.requests = Optional.empty();
|
||||
}
|
||||
|
||||
public BlockBody(
|
||||
final List<Transaction> transactions,
|
||||
final List<BlockHeader> ommers,
|
||||
final Optional<List<Withdrawal>> withdrawals,
|
||||
final Optional<List<Request>> requests) {
|
||||
final Optional<List<Withdrawal>> withdrawals) {
|
||||
this.transactions = transactions;
|
||||
this.ommers = ommers;
|
||||
this.withdrawals = withdrawals;
|
||||
this.requests = requests;
|
||||
}
|
||||
|
||||
public static BlockBody empty() {
|
||||
@@ -87,16 +83,6 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
|
||||
return withdrawals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the withdrawal requests of the block.
|
||||
*
|
||||
* @return The optional list of withdrawal requests included in the block.
|
||||
*/
|
||||
@Override
|
||||
public Optional<List<Request>> getRequests() {
|
||||
return requests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes Block to {@link RLPOutput}.
|
||||
*
|
||||
@@ -112,7 +98,6 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
|
||||
output.writeList(getTransactions(), Transaction::writeTo);
|
||||
output.writeList(getOmmers(), BlockHeader::writeTo);
|
||||
withdrawals.ifPresent(withdrawals -> output.writeList(withdrawals, Withdrawal::writeTo));
|
||||
requests.ifPresent(requests -> output.writeList(requests, Request::writeTo));
|
||||
}
|
||||
|
||||
public static BlockBody readWrappedBodyFrom(
|
||||
@@ -161,10 +146,7 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
|
||||
input.readList(rlp -> BlockHeader.readFrom(rlp, blockHeaderFunctions)),
|
||||
input.isEndOfCurrentList()
|
||||
? Optional.empty()
|
||||
: Optional.of(input.readList(Withdrawal::readFrom)),
|
||||
input.isEndOfCurrentList()
|
||||
? Optional.empty()
|
||||
: Optional.of(input.readList(Request::readFrom)));
|
||||
: Optional.of(input.readList(Withdrawal::readFrom)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -174,20 +156,16 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
|
||||
BlockBody blockBody = (BlockBody) o;
|
||||
return Objects.equals(transactions, blockBody.transactions)
|
||||
&& Objects.equals(ommers, blockBody.ommers)
|
||||
&& Objects.equals(withdrawals, blockBody.withdrawals)
|
||||
&& Objects.equals(requests, blockBody.requests);
|
||||
&& Objects.equals(withdrawals, blockBody.withdrawals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(transactions, ommers, withdrawals, requests);
|
||||
return Objects.hash(transactions, ommers, withdrawals);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return transactions.isEmpty()
|
||||
&& ommers.isEmpty()
|
||||
&& withdrawals.isEmpty()
|
||||
&& requests.isEmpty();
|
||||
return transactions.isEmpty() && ommers.isEmpty() && withdrawals.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -199,8 +177,6 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody {
|
||||
+ ommers
|
||||
+ ", withdrawals="
|
||||
+ withdrawals
|
||||
+ ", withdrawal_requests="
|
||||
+ requests
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public class BlockHeader extends SealableBlockHeader
|
||||
final Long blobGasUsed,
|
||||
final BlobGas excessBlobGas,
|
||||
final Bytes32 parentBeaconBlockRoot,
|
||||
final Hash requestsRoot,
|
||||
final Hash requestsHash,
|
||||
final BlockHeaderFunctions blockHeaderFunctions) {
|
||||
super(
|
||||
parentHash,
|
||||
@@ -86,7 +86,7 @@ public class BlockHeader extends SealableBlockHeader
|
||||
blobGasUsed,
|
||||
excessBlobGas,
|
||||
parentBeaconBlockRoot,
|
||||
requestsRoot);
|
||||
requestsHash);
|
||||
this.nonce = nonce;
|
||||
this.hash = Suppliers.memoize(() -> blockHeaderFunctions.hash(this));
|
||||
this.parsedExtraData = Suppliers.memoize(() -> blockHeaderFunctions.parseExtraData(this));
|
||||
@@ -100,8 +100,8 @@ public class BlockHeader extends SealableBlockHeader
|
||||
.map(wsRoot -> wsRoot.equals(Hash.EMPTY_TRIE_HASH))
|
||||
.orElse(true)
|
||||
&& blockHeader
|
||||
.getRequestsRoot()
|
||||
.map(reqRoot -> reqRoot.equals(Hash.EMPTY_TRIE_HASH))
|
||||
.getRequestsHash()
|
||||
.map(reqHash -> reqHash.equals(Hash.EMPTY_REQUESTS_HASH))
|
||||
.orElse(true);
|
||||
}
|
||||
|
||||
@@ -185,8 +185,8 @@ public class BlockHeader extends SealableBlockHeader
|
||||
if (parentBeaconBlockRoot == null) break;
|
||||
out.writeBytes(parentBeaconBlockRoot);
|
||||
|
||||
if (requestsRoot == null) break;
|
||||
out.writeBytes(requestsRoot);
|
||||
if (requestsHash == null) break;
|
||||
out.writeBytes(requestsHash);
|
||||
} while (false);
|
||||
out.endList();
|
||||
}
|
||||
@@ -218,7 +218,7 @@ public class BlockHeader extends SealableBlockHeader
|
||||
final BlobGas excessBlobGas =
|
||||
!input.isEndOfCurrentList() ? BlobGas.of(input.readUInt64Scalar()) : null;
|
||||
final Bytes32 parentBeaconBlockRoot = !input.isEndOfCurrentList() ? input.readBytes32() : null;
|
||||
final Hash requestsRoot = !input.isEndOfCurrentList() ? Hash.wrap(input.readBytes32()) : null;
|
||||
final Hash requestsHash = !input.isEndOfCurrentList() ? Hash.wrap(input.readBytes32()) : null;
|
||||
input.leaveList();
|
||||
return new BlockHeader(
|
||||
parentHash,
|
||||
@@ -241,7 +241,7 @@ public class BlockHeader extends SealableBlockHeader
|
||||
blobGasUsed,
|
||||
excessBlobGas,
|
||||
parentBeaconBlockRoot,
|
||||
requestsRoot,
|
||||
requestsHash,
|
||||
blockHeaderFunctions);
|
||||
}
|
||||
|
||||
@@ -292,8 +292,8 @@ public class BlockHeader extends SealableBlockHeader
|
||||
if (parentBeaconBlockRoot != null) {
|
||||
sb.append("parentBeaconBlockRoot=").append(parentBeaconBlockRoot).append(", ");
|
||||
}
|
||||
if (requestsRoot != null) {
|
||||
sb.append("requestsRoot=").append(requestsRoot);
|
||||
if (requestsHash != null) {
|
||||
sb.append("requestsHash=").append(requestsHash);
|
||||
}
|
||||
return sb.append("}").toString();
|
||||
}
|
||||
@@ -326,7 +326,7 @@ public class BlockHeader extends SealableBlockHeader
|
||||
pluginBlockHeader.getExcessBlobGas().map(BlobGas.class::cast).orElse(null),
|
||||
pluginBlockHeader.getParentBeaconBlockRoot().orElse(null),
|
||||
pluginBlockHeader
|
||||
.getRequestsRoot()
|
||||
.getRequestsHash()
|
||||
.map(h -> Hash.fromHexString(h.toHexString()))
|
||||
.orElse(null),
|
||||
blockHeaderFunctions);
|
||||
|
||||
@@ -45,7 +45,7 @@ public class BlockHeaderBuilder {
|
||||
private Hash transactionsRoot;
|
||||
|
||||
private Hash withdrawalsRoot = null;
|
||||
private Hash requestsRoot = null;
|
||||
private Hash requestsHash = null;
|
||||
|
||||
private Hash receiptsRoot;
|
||||
|
||||
@@ -124,7 +124,7 @@ public class BlockHeaderBuilder {
|
||||
.blobGasUsed(header.getBlobGasUsed().orElse(null))
|
||||
.excessBlobGas(header.getExcessBlobGas().orElse(null))
|
||||
.parentBeaconBlockRoot(header.getParentBeaconBlockRoot().orElse(null))
|
||||
.requestsRoot(header.getRequestsRoot().orElse(null));
|
||||
.requestsHash(header.getRequestsHash().orElse(null));
|
||||
}
|
||||
|
||||
public static BlockHeaderBuilder fromBuilder(final BlockHeaderBuilder fromBuilder) {
|
||||
@@ -148,7 +148,7 @@ public class BlockHeaderBuilder {
|
||||
.withdrawalsRoot(fromBuilder.withdrawalsRoot)
|
||||
.excessBlobGas(fromBuilder.excessBlobGas)
|
||||
.parentBeaconBlockRoot(fromBuilder.parentBeaconBlockRoot)
|
||||
.requestsRoot(fromBuilder.requestsRoot)
|
||||
.requestsHash(fromBuilder.requestsHash)
|
||||
.blockHeaderFunctions(fromBuilder.blockHeaderFunctions);
|
||||
toBuilder.nonce = fromBuilder.nonce;
|
||||
return toBuilder;
|
||||
@@ -178,7 +178,7 @@ public class BlockHeaderBuilder {
|
||||
blobGasUsed,
|
||||
excessBlobGas,
|
||||
parentBeaconBlockRoot,
|
||||
requestsRoot,
|
||||
requestsHash,
|
||||
blockHeaderFunctions);
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public class BlockHeaderBuilder {
|
||||
blobGasUsed,
|
||||
excessBlobGas,
|
||||
parentBeaconBlockRoot,
|
||||
requestsRoot);
|
||||
requestsHash);
|
||||
}
|
||||
|
||||
private void validateBlockHeader() {
|
||||
@@ -284,7 +284,7 @@ public class BlockHeaderBuilder {
|
||||
sealableBlockHeader.getBlobGasUsed().ifPresent(this::blobGasUsed);
|
||||
sealableBlockHeader.getExcessBlobGas().ifPresent(this::excessBlobGas);
|
||||
sealableBlockHeader.getParentBeaconBlockRoot().ifPresent(this::parentBeaconBlockRoot);
|
||||
requestsRoot(sealableBlockHeader.getRequestsRoot().orElse(null));
|
||||
requestsHash(sealableBlockHeader.getRequestsHash().orElse(null));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -399,8 +399,8 @@ public class BlockHeaderBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockHeaderBuilder requestsRoot(final Hash hash) {
|
||||
this.requestsRoot = hash;
|
||||
public BlockHeaderBuilder requestsHash(final Hash hash) {
|
||||
this.requestsHash = hash;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.datatypes.PublicKey;
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ConsolidationRequest extends Request
|
||||
implements org.hyperledger.besu.plugin.data.ConsolidationRequest {
|
||||
|
||||
private final Address sourceAddress;
|
||||
private final BLSPublicKey sourcePubkey;
|
||||
private final BLSPublicKey targetPubkey;
|
||||
|
||||
public ConsolidationRequest(
|
||||
final Address sourceAddress,
|
||||
final BLSPublicKey sourcePubkey,
|
||||
final BLSPublicKey targetPubkey) {
|
||||
this.sourceAddress = sourceAddress;
|
||||
this.sourcePubkey = sourcePubkey;
|
||||
this.targetPubkey = targetPubkey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestType getType() {
|
||||
return RequestType.CONSOLIDATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Address getSourceAddress() {
|
||||
return sourceAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getSourcePubkey() {
|
||||
return sourcePubkey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getTargetPubkey() {
|
||||
return targetPubkey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConsolidationRequest{"
|
||||
+ "sourceAddress="
|
||||
+ sourceAddress
|
||||
+ " sourcePubkey="
|
||||
+ sourcePubkey
|
||||
+ " targetPubkey="
|
||||
+ targetPubkey
|
||||
+ '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final ConsolidationRequest that = (ConsolidationRequest) o;
|
||||
return Objects.equals(sourceAddress, that.sourceAddress)
|
||||
&& Objects.equals(sourcePubkey, that.sourcePubkey)
|
||||
&& Objects.equals(targetPubkey, that.targetPubkey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(sourceAddress, sourcePubkey, targetPubkey);
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core;
|
||||
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.datatypes.BLSSignature;
|
||||
import org.hyperledger.besu.datatypes.GWei;
|
||||
import org.hyperledger.besu.datatypes.PublicKey;
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt64;
|
||||
|
||||
public class DepositRequest extends Request
|
||||
implements org.hyperledger.besu.plugin.data.DepositRequest {
|
||||
|
||||
private final BLSPublicKey pubkey;
|
||||
private final Bytes32 depositWithdrawalCredentials;
|
||||
private final GWei amount;
|
||||
private final BLSSignature signature;
|
||||
private final UInt64 index;
|
||||
|
||||
public DepositRequest(
|
||||
final BLSPublicKey pubkey,
|
||||
final Bytes32 depositWithdrawalCredentials,
|
||||
final GWei amount,
|
||||
final BLSSignature signature,
|
||||
final UInt64 index) {
|
||||
this.pubkey = pubkey;
|
||||
this.depositWithdrawalCredentials = depositWithdrawalCredentials;
|
||||
this.amount = amount;
|
||||
this.signature = signature;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestType getType() {
|
||||
return RequestType.DEPOSIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getPubkey() {
|
||||
return pubkey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bytes32 getWithdrawalCredentials() {
|
||||
return depositWithdrawalCredentials;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GWei getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BLSSignature getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UInt64 getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Deposit{"
|
||||
+ "pubKey="
|
||||
+ pubkey
|
||||
+ ", withdrawalCredentials="
|
||||
+ depositWithdrawalCredentials
|
||||
+ ", amount="
|
||||
+ amount
|
||||
+ ", signature="
|
||||
+ signature
|
||||
+ ", index="
|
||||
+ index
|
||||
+ '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final DepositRequest that = (DepositRequest) o;
|
||||
return Objects.equals(pubkey, that.pubkey)
|
||||
&& Objects.equals(depositWithdrawalCredentials, that.depositWithdrawalCredentials)
|
||||
&& Objects.equals(amount, that.amount)
|
||||
&& Objects.equals(signature, that.signature)
|
||||
&& Objects.equals(index, that.index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(pubkey, depositWithdrawalCredentials, amount, signature, index);
|
||||
}
|
||||
}
|
||||
@@ -15,27 +15,18 @@
|
||||
package org.hyperledger.besu.ethereum.core;
|
||||
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.RequestDecoder;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.RequestEncoder;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public abstract class Request implements org.hyperledger.besu.plugin.data.Request {
|
||||
public record Request(RequestType type, Bytes data)
|
||||
implements org.hyperledger.besu.plugin.data.Request {
|
||||
@Override
|
||||
public abstract RequestType getType();
|
||||
|
||||
public static Request readFrom(final Bytes rlpBytes) {
|
||||
return readFrom(RLP.input(rlpBytes));
|
||||
public RequestType getType() {
|
||||
return type();
|
||||
}
|
||||
|
||||
public static Request readFrom(final RLPInput rlpInput) {
|
||||
return RequestDecoder.decode(rlpInput);
|
||||
}
|
||||
|
||||
public void writeTo(final RLPOutput out) {
|
||||
RequestEncoder.encode(this, out);
|
||||
@Override
|
||||
public Bytes getData() {
|
||||
return data();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class SealableBlockHeader extends ProcessableBlockHeader {
|
||||
|
||||
protected final Hash withdrawalsRoot;
|
||||
|
||||
protected final Hash requestsRoot;
|
||||
protected final Hash requestsHash;
|
||||
|
||||
protected final Long blobGasUsed;
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SealableBlockHeader extends ProcessableBlockHeader {
|
||||
final Long blobGasUsed,
|
||||
final BlobGas excessBlobGas,
|
||||
final Bytes32 parentBeaconBlockRoot,
|
||||
final Hash requestsRoot) {
|
||||
final Hash requestsHash) {
|
||||
super(
|
||||
parentHash,
|
||||
coinbase,
|
||||
@@ -85,7 +85,7 @@ public class SealableBlockHeader extends ProcessableBlockHeader {
|
||||
this.transactionsRoot = transactionsRoot;
|
||||
this.withdrawalsRoot = withdrawalsRoot;
|
||||
this.receiptsRoot = receiptsRoot;
|
||||
this.requestsRoot = requestsRoot;
|
||||
this.requestsHash = requestsHash;
|
||||
this.logsBloom = logsBloom;
|
||||
this.gasUsed = gasUsed;
|
||||
this.extraData = extraData;
|
||||
@@ -166,12 +166,12 @@ public class SealableBlockHeader extends ProcessableBlockHeader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block requests root hash.
|
||||
* Returns the block requests hash.
|
||||
*
|
||||
* @return the block requests root hash
|
||||
* @return the block requests hash
|
||||
*/
|
||||
public Optional<Hash> getRequestsRoot() {
|
||||
return Optional.ofNullable(requestsRoot);
|
||||
public Optional<Hash> getRequestsHash() {
|
||||
return Optional.ofNullable(requestsHash);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.core;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.plugin.data.SyncStatus;
|
||||
import org.hyperledger.besu.plugin.services.BesuEvents;
|
||||
import org.hyperledger.besu.plugin.services.BesuEvents.InitialSyncCompletionListener;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -82,6 +83,22 @@ public interface Synchronizer {
|
||||
*/
|
||||
boolean unsubscribeInSync(final long listenerId);
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when this node initial sync status changes.
|
||||
*
|
||||
* @param listener The callback to invoke when the initial sync status changes
|
||||
* @return A subscription id that can be used to unsubscribe from these events
|
||||
*/
|
||||
long subscribeInitialSync(final InitialSyncCompletionListener listener);
|
||||
|
||||
/**
|
||||
* Unsubscribe from initial sync events.
|
||||
*
|
||||
* @param listenerId The id returned when subscribing
|
||||
* @return {@code true} if a subscription was cancelled
|
||||
*/
|
||||
boolean unsubscribeInitialSync(final long listenerId);
|
||||
|
||||
@FunctionalInterface
|
||||
interface InSyncListener {
|
||||
void onInSyncStatusChange(boolean newSyncStatus);
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.datatypes.GWei;
|
||||
import org.hyperledger.besu.datatypes.PublicKey;
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class WithdrawalRequest extends Request
|
||||
implements org.hyperledger.besu.plugin.data.WithdrawalRequest {
|
||||
|
||||
private final Address sourceAddress;
|
||||
private final BLSPublicKey validatorPubkey;
|
||||
private final GWei amount;
|
||||
|
||||
public WithdrawalRequest(
|
||||
final Address sourceAddress, final BLSPublicKey validatorPubkey, final GWei amount) {
|
||||
this.sourceAddress = sourceAddress;
|
||||
this.validatorPubkey = validatorPubkey;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestType getType() {
|
||||
return RequestType.WITHDRAWAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Address getSourceAddress() {
|
||||
return sourceAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getValidatorPubkey() {
|
||||
return validatorPubkey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GWei getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WithdrawalRequest{"
|
||||
+ "sourceAddress="
|
||||
+ sourceAddress
|
||||
+ " validatorPubkey="
|
||||
+ validatorPubkey
|
||||
+ " amount="
|
||||
+ amount
|
||||
+ '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final WithdrawalRequest that = (WithdrawalRequest) o;
|
||||
return Objects.equals(sourceAddress, that.sourceAddress)
|
||||
&& Objects.equals(validatorPubkey, that.validatorPubkey)
|
||||
&& Objects.equals(amount, that.amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(sourceAddress, validatorPubkey, amount);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core.encoding;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.ethereum.core.ConsolidationRequest;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public class ConsolidationRequestDecoder {
|
||||
|
||||
public static ConsolidationRequest decode(final RLPInput rlpInput) {
|
||||
rlpInput.enterList();
|
||||
final Address sourceAddress = Address.readFrom(rlpInput);
|
||||
final BLSPublicKey sourcePublicKey = BLSPublicKey.readFrom(rlpInput);
|
||||
final BLSPublicKey targetPublicKey = BLSPublicKey.readFrom(rlpInput);
|
||||
rlpInput.leaveList();
|
||||
|
||||
return new ConsolidationRequest(sourceAddress, sourcePublicKey, targetPublicKey);
|
||||
}
|
||||
|
||||
public static ConsolidationRequest decodeOpaqueBytes(final Bytes input) {
|
||||
return decode(RLP.input(input));
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core.encoding;
|
||||
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
import org.hyperledger.besu.ethereum.core.ConsolidationRequest;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public class ConsolidationRequestEncoder {
|
||||
|
||||
/**
|
||||
* Encodes a Request into RLP format if it is a ConsolidationRequest.
|
||||
*
|
||||
* @param request The Request to encode, which must be a ConsolidationRequest.
|
||||
* @param rlpOutput The RLPOutput to write the encoded data to.
|
||||
* @throws IllegalArgumentException if the provided request is not a ConsolidationRequest.
|
||||
*/
|
||||
public static void encode(final Request request, final RLPOutput rlpOutput) {
|
||||
if (!request.getType().equals(RequestType.CONSOLIDATION)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The provided request is not of type ConsolidationRequest.");
|
||||
}
|
||||
encodeConsolidationRequest((ConsolidationRequest) request, rlpOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the details of a ConsolidationRequest into RLP format.
|
||||
*
|
||||
* @param consolidationRequest The ConsolidationRequest to encode.
|
||||
* @param rlpOutput The RLPOutput to write the encoded data to.
|
||||
*/
|
||||
private static void encodeConsolidationRequest(
|
||||
final ConsolidationRequest consolidationRequest, final RLPOutput rlpOutput) {
|
||||
rlpOutput.startList();
|
||||
rlpOutput.writeBytes(consolidationRequest.getSourceAddress());
|
||||
rlpOutput.writeBytes(consolidationRequest.getSourcePubkey());
|
||||
rlpOutput.writeBytes(consolidationRequest.getTargetPubkey());
|
||||
rlpOutput.endList();
|
||||
}
|
||||
|
||||
public static Bytes encodeOpaqueBytes(final Request consolidationRequest) {
|
||||
return RLP.encode(rlpOutput -> encode(consolidationRequest, rlpOutput));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core.encoding;
|
||||
|
||||
import org.hyperledger.besu.ethereum.core.DepositContract;
|
||||
import org.hyperledger.besu.evm.log.Log;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.web3j.tx.Contract;
|
||||
|
||||
public class DepositLogDecoder {
|
||||
|
||||
public static Bytes decodeFromLog(final Log log) {
|
||||
Contract.EventValuesWithLog eventValues = DepositContract.staticExtractDepositEventWithLog(log);
|
||||
final Bytes rawPublicKey =
|
||||
Bytes.wrap((byte[]) eventValues.getNonIndexedValues().get(0).getValue());
|
||||
final Bytes rawWithdrawalCredential =
|
||||
Bytes.wrap((byte[]) eventValues.getNonIndexedValues().get(1).getValue());
|
||||
final Bytes rawAmount =
|
||||
Bytes.wrap((byte[]) eventValues.getNonIndexedValues().get(2).getValue());
|
||||
final Bytes rawSignature =
|
||||
Bytes.wrap((byte[]) eventValues.getNonIndexedValues().get(3).getValue());
|
||||
final Bytes rawIndex = Bytes.wrap((byte[]) eventValues.getNonIndexedValues().get(4).getValue());
|
||||
|
||||
return Bytes.concatenate(
|
||||
rawPublicKey, rawWithdrawalCredential, rawAmount, rawSignature, rawIndex);
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core.encoding;
|
||||
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.datatypes.BLSSignature;
|
||||
import org.hyperledger.besu.datatypes.GWei;
|
||||
import org.hyperledger.besu.ethereum.core.DepositContract;
|
||||
import org.hyperledger.besu.ethereum.core.DepositRequest;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
import org.hyperledger.besu.evm.log.Log;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt64;
|
||||
import org.web3j.tx.Contract;
|
||||
|
||||
public class DepositRequestDecoder {
|
||||
|
||||
public static DepositRequest decode(final RLPInput rlpInput) {
|
||||
rlpInput.enterList();
|
||||
final BLSPublicKey publicKey = BLSPublicKey.readFrom(rlpInput);
|
||||
final Bytes32 depositWithdrawalCredential = Bytes32.wrap(rlpInput.readBytes());
|
||||
final GWei amount = GWei.of(rlpInput.readUInt64Scalar());
|
||||
final BLSSignature signature = BLSSignature.readFrom(rlpInput);
|
||||
final UInt64 index = UInt64.valueOf(rlpInput.readBigIntegerScalar());
|
||||
rlpInput.leaveList();
|
||||
|
||||
return new DepositRequest(publicKey, depositWithdrawalCredential, amount, signature, index);
|
||||
}
|
||||
|
||||
public static DepositRequest decodeFromLog(final Log log) {
|
||||
Contract.EventValuesWithLog eventValues = DepositContract.staticExtractDepositEventWithLog(log);
|
||||
final byte[] rawPublicKey = (byte[]) eventValues.getNonIndexedValues().get(0).getValue();
|
||||
final byte[] rawWithdrawalCredential =
|
||||
(byte[]) eventValues.getNonIndexedValues().get(1).getValue();
|
||||
final byte[] rawAmount = (byte[]) eventValues.getNonIndexedValues().get(2).getValue();
|
||||
final byte[] rawSignature = (byte[]) eventValues.getNonIndexedValues().get(3).getValue();
|
||||
final byte[] rawIndex = (byte[]) eventValues.getNonIndexedValues().get(4).getValue();
|
||||
|
||||
return new DepositRequest(
|
||||
BLSPublicKey.wrap(Bytes.wrap(rawPublicKey)),
|
||||
Bytes32.wrap(Bytes.wrap(rawWithdrawalCredential)),
|
||||
GWei.of(
|
||||
Bytes.wrap(rawAmount)
|
||||
.toLong(
|
||||
ByteOrder.LITTLE_ENDIAN)), // Amount is little endian as per Deposit Contract
|
||||
BLSSignature.wrap(Bytes.wrap(rawSignature)),
|
||||
UInt64.valueOf(Bytes.wrap(rawIndex).reverse().toLong()));
|
||||
}
|
||||
|
||||
public static DepositRequest decodeOpaqueBytes(final Bytes input) {
|
||||
return decode(RLP.input(input));
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core.encoding;
|
||||
|
||||
import org.hyperledger.besu.ethereum.core.DepositRequest;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public class DepositRequestEncoder {
|
||||
|
||||
public static void encode(final Request request, final RLPOutput rlpOutput) {
|
||||
if (!(request instanceof DepositRequest depositRequest)) {
|
||||
throw new IllegalArgumentException("The provided request is not of type deposit.");
|
||||
}
|
||||
rlpOutput.startList();
|
||||
rlpOutput.writeBytes(depositRequest.getPubkey());
|
||||
rlpOutput.writeBytes(depositRequest.getWithdrawalCredentials());
|
||||
rlpOutput.writeUInt64Scalar(depositRequest.getAmount());
|
||||
rlpOutput.writeBytes(depositRequest.getSignature());
|
||||
rlpOutput.writeUInt64Scalar(depositRequest.getIndex());
|
||||
rlpOutput.endList();
|
||||
}
|
||||
|
||||
public static Bytes encodeOpaqueBytes(final Request deposit) {
|
||||
return RLP.encode(rlpOutput -> encode(deposit, rlpOutput));
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core.encoding;
|
||||
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
/**
|
||||
* Decodes a request from its RLP encoded form.
|
||||
*
|
||||
* <p>This class provides functionality to decode requests based on their type.
|
||||
*/
|
||||
public class RequestDecoder {
|
||||
|
||||
@FunctionalInterface
|
||||
interface Decoder {
|
||||
Request decode(RLPInput input);
|
||||
}
|
||||
|
||||
private static final ImmutableMap<RequestType, Decoder> DECODERS =
|
||||
ImmutableMap.of(
|
||||
RequestType.WITHDRAWAL,
|
||||
WithdrawalRequestDecoder::decode,
|
||||
RequestType.DEPOSIT,
|
||||
DepositRequestDecoder::decode,
|
||||
RequestType.CONSOLIDATION,
|
||||
ConsolidationRequestDecoder::decode);
|
||||
|
||||
/**
|
||||
* Decodes a request from its RLP encoded bytes.
|
||||
*
|
||||
* <p>This method first determines the type of the request and then decodes the request data
|
||||
* according to the request type.
|
||||
*
|
||||
* @param rlpInput The RLP encoded request.
|
||||
* @return The decoded Request object.
|
||||
* @throws IllegalArgumentException if the request type is unsupported or invalid.
|
||||
*/
|
||||
public static Request decode(final RLPInput rlpInput) {
|
||||
final Bytes requestBytes = rlpInput.readBytes();
|
||||
return getRequestType(requestBytes)
|
||||
.map(type -> decodeRequest(requestBytes, type))
|
||||
.orElseThrow(() -> new IllegalArgumentException("Unsupported or invalid request type"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the request data according to the request type.
|
||||
*
|
||||
* @param requestBytes The bytes representing the request, including the request type byte.
|
||||
* @param requestType The type of the request to decode.
|
||||
* @return The decoded Request.
|
||||
* @throws IllegalStateException if no decoder is found for the specified request type.
|
||||
*/
|
||||
private static Request decodeRequest(final Bytes requestBytes, final RequestType requestType) {
|
||||
// Skip the first byte which is the request type
|
||||
RLPInput requestInput = RLP.input(requestBytes.slice(1));
|
||||
Decoder decoder =
|
||||
Optional.ofNullable(DECODERS.get(requestType))
|
||||
.orElseThrow(
|
||||
() ->
|
||||
new IllegalStateException(
|
||||
"Decoder not found for request type: " + requestType));
|
||||
return decoder.decode(requestInput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the request type from the given bytes.
|
||||
*
|
||||
* @param bytes The bytes from which to extract the request type.
|
||||
* @return An Optional containing the RequestType if it could be determined, or an empty Optional
|
||||
* otherwise.
|
||||
*/
|
||||
private static Optional<RequestType> getRequestType(final Bytes bytes) {
|
||||
try {
|
||||
byte typeByte = bytes.get(0);
|
||||
return Optional.of(RequestType.of(typeByte));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public static Request decodeOpaqueBytes(final Bytes input) {
|
||||
|
||||
RequestType type = getRequestType(input).orElseThrow();
|
||||
return decodeRequest(input.slice(1), type);
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core.encoding;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
/** Encodes Request objects into RLP format. */
|
||||
public class RequestEncoder {
|
||||
|
||||
@FunctionalInterface
|
||||
interface Encoder {
|
||||
void encode(Request request, RLPOutput output);
|
||||
}
|
||||
|
||||
private static final ImmutableMap<RequestType, RequestEncoder.Encoder> ENCODERS =
|
||||
ImmutableMap.of(
|
||||
RequestType.WITHDRAWAL,
|
||||
WithdrawalRequestEncoder::encode,
|
||||
RequestType.DEPOSIT,
|
||||
DepositRequestEncoder::encode,
|
||||
RequestType.CONSOLIDATION,
|
||||
ConsolidationRequestEncoder::encode);
|
||||
|
||||
/**
|
||||
* Encodes a Request into the provided RLPOutput.
|
||||
*
|
||||
* @param request The Request to encode.
|
||||
* @param rlpOutput The RLPOutput to write the encoded data to.
|
||||
*/
|
||||
public static void encode(final Request request, final RLPOutput rlpOutput) {
|
||||
final RequestEncoder.Encoder encoder = getEncoder(request.getType());
|
||||
Bytes requestBytes = RLP.encode(out -> encoder.encode(request, out));
|
||||
rlpOutput.writeBytes(
|
||||
Bytes.concatenate(Bytes.of(request.getType().getSerializedType()), requestBytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a Request into a Bytes object representing the RLP-encoded data.
|
||||
*
|
||||
* @param request The Request to encode.
|
||||
* @return The RLP-encoded data as a Bytes object.
|
||||
*/
|
||||
public static Bytes encodeOpaqueBytes(final Request request) {
|
||||
final RequestEncoder.Encoder encoder = getEncoder(request.getType());
|
||||
final BytesValueRLPOutput out = new BytesValueRLPOutput();
|
||||
out.writeByte(request.getType().getSerializedType());
|
||||
encoder.encode(request, out);
|
||||
return out.encoded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the encoder for the specified RequestType.
|
||||
*
|
||||
* @param requestType The type of the request.
|
||||
* @return The encoder for the specified type.
|
||||
* @throws NullPointerException if no encoder is found for the specified type.
|
||||
*/
|
||||
private static RequestEncoder.Encoder getEncoder(final RequestType requestType) {
|
||||
return checkNotNull(
|
||||
ENCODERS.get(requestType), "Encoder not found for request type: %s", requestType);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core.encoding;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BLSPublicKey;
|
||||
import org.hyperledger.besu.datatypes.GWei;
|
||||
import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public class WithdrawalRequestDecoder {
|
||||
|
||||
public static WithdrawalRequest decode(final RLPInput rlpInput) {
|
||||
rlpInput.enterList();
|
||||
final Address sourceAddress = Address.readFrom(rlpInput);
|
||||
final BLSPublicKey validatorPubkey = BLSPublicKey.readFrom(rlpInput);
|
||||
final GWei amount = GWei.of(rlpInput.readUInt64Scalar());
|
||||
rlpInput.leaveList();
|
||||
|
||||
return new WithdrawalRequest(sourceAddress, validatorPubkey, amount);
|
||||
}
|
||||
|
||||
public static WithdrawalRequest decodeOpaqueBytes(final Bytes input) {
|
||||
return decode(RLP.input(input));
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core.encoding;
|
||||
|
||||
import org.hyperledger.besu.datatypes.RequestType;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.WithdrawalRequest;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public class WithdrawalRequestEncoder {
|
||||
|
||||
/**
|
||||
* Encodes a Request into RLP format if it is a WithdrawalRequest.
|
||||
*
|
||||
* @param request The Request to encode, which must be a WithdrawalRequest.
|
||||
* @param rlpOutput The RLPOutput to write the encoded data to.
|
||||
* @throws IllegalArgumentException if the provided request is not a WithdrawalRequest.
|
||||
*/
|
||||
public static void encode(final Request request, final RLPOutput rlpOutput) {
|
||||
if (!request.getType().equals(RequestType.WITHDRAWAL)) {
|
||||
throw new IllegalArgumentException("The provided request is not of type WithdrawalRequest.");
|
||||
}
|
||||
encodeWithdrawalRequest((WithdrawalRequest) request, rlpOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the details of a WithdrawalRequest into RLP format.
|
||||
*
|
||||
* @param withdrawalRequest The WithdrawalRequest to encode.
|
||||
* @param rlpOutput The RLPOutput to write the encoded data to.
|
||||
*/
|
||||
private static void encodeWithdrawalRequest(
|
||||
final WithdrawalRequest withdrawalRequest, final RLPOutput rlpOutput) {
|
||||
rlpOutput.startList();
|
||||
rlpOutput.writeBytes(withdrawalRequest.getSourceAddress());
|
||||
rlpOutput.writeBytes(withdrawalRequest.getValidatorPubkey());
|
||||
rlpOutput.writeUInt64Scalar(withdrawalRequest.getAmount());
|
||||
rlpOutput.endList();
|
||||
}
|
||||
|
||||
public static Bytes encodeOpaqueBytes(final Request withdrawalRequest) {
|
||||
return RLP.encode(rlpOutput -> encode(withdrawalRequest, rlpOutput));
|
||||
}
|
||||
}
|
||||
@@ -218,7 +218,7 @@ public abstract class AbstractBlockProcessor implements BlockProcessor {
|
||||
blockHashLookup,
|
||||
OperationTracer.NO_TRACING);
|
||||
|
||||
maybeRequests = requestProcessor.get().process(context);
|
||||
maybeRequests = Optional.of(requestProcessor.get().process(context));
|
||||
}
|
||||
|
||||
if (!rewardCoinbase(worldState, blockHeader, ommers, skipZeroBlockRewards)) {
|
||||
|
||||
@@ -18,7 +18,6 @@ import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.core.feemarket.TransactionPriceCalculator;
|
||||
@@ -42,12 +41,11 @@ public class BaseFeeBlockBodyValidator extends MainnetBlockBodyValidator {
|
||||
final ProtocolContext context,
|
||||
final Block block,
|
||||
final List<TransactionReceipt> receipts,
|
||||
final Optional<List<Request>> requests,
|
||||
final HeaderValidationMode ommerValidationMode,
|
||||
final BodyValidationMode bodyValidationMode) {
|
||||
|
||||
return super.validateBodyLight(
|
||||
context, block, receipts, requests, ommerValidationMode, bodyValidationMode)
|
||||
context, block, receipts, ommerValidationMode, bodyValidationMode)
|
||||
&& validateTransactionGasPrice(block);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,9 @@ package org.hyperledger.besu.ethereum.mainnet;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/** Validates block bodies. */
|
||||
public interface BlockBodyValidator {
|
||||
@@ -41,7 +39,6 @@ public interface BlockBodyValidator {
|
||||
ProtocolContext context,
|
||||
Block block,
|
||||
List<TransactionReceipt> receipts,
|
||||
Optional<List<Request>> requests,
|
||||
Hash worldStateRootHash,
|
||||
final HeaderValidationMode ommerValidationMode);
|
||||
|
||||
@@ -58,7 +55,6 @@ public interface BlockBodyValidator {
|
||||
ProtocolContext context,
|
||||
Block block,
|
||||
List<TransactionReceipt> receipts,
|
||||
final Optional<List<Request>> requests,
|
||||
final HeaderValidationMode ommerValidationMode,
|
||||
final BodyValidationMode bodyValidationMode);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package org.hyperledger.besu.ethereum.mainnet;
|
||||
|
||||
import static org.hyperledger.besu.crypto.Hash.keccak256;
|
||||
import static org.hyperledger.besu.crypto.Hash.sha256;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
@@ -23,7 +24,6 @@ import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.core.Withdrawal;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.EncodingContext;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.RequestEncoder;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.WithdrawalEncoder;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
@@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.trie.MerkleTrie;
|
||||
import org.hyperledger.besu.ethereum.trie.patricia.SimpleMerklePatriciaTrie;
|
||||
import org.hyperledger.besu.evm.log.LogsBloomFilter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@@ -89,16 +90,24 @@ public final class BodyValidation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the requests root for a list of requests
|
||||
* Generates the requests hash for a list of requests
|
||||
*
|
||||
* @param requests list of request
|
||||
* @return the requests root
|
||||
* @return the requests hash
|
||||
*/
|
||||
public static Hash requestsRoot(final List<Request> requests) {
|
||||
final MerkleTrie<Bytes, Bytes> trie = trie();
|
||||
public static Hash requestsHash(final List<Request> requests) {
|
||||
List<Bytes> requestHashes = new ArrayList<>();
|
||||
IntStream.range(0, requests.size())
|
||||
.forEach(i -> trie.put(indexKey(i), RequestEncoder.encodeOpaqueBytes(requests.get(i))));
|
||||
return Hash.wrap(trie.getRootHash());
|
||||
.forEach(
|
||||
i -> {
|
||||
final Request request = requests.get(i);
|
||||
final Bytes requestBytes =
|
||||
Bytes.concatenate(
|
||||
Bytes.of(request.getType().getSerializedType()), request.getData());
|
||||
requestHashes.add(sha256(requestBytes));
|
||||
});
|
||||
|
||||
return Hash.wrap(sha256(Bytes.wrap(requestHashes)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,14 +19,11 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Request;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
|
||||
import org.hyperledger.besu.evm.log.LogsBloomFilter;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
@@ -52,12 +49,11 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator {
|
||||
final ProtocolContext context,
|
||||
final Block block,
|
||||
final List<TransactionReceipt> receipts,
|
||||
final Optional<List<Request>> requests,
|
||||
final Hash worldStateRootHash,
|
||||
final HeaderValidationMode ommerValidationMode) {
|
||||
|
||||
if (!validateBodyLight(
|
||||
context, block, receipts, requests, ommerValidationMode, BodyValidationMode.FULL)) {
|
||||
context, block, receipts, ommerValidationMode, BodyValidationMode.FULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -78,7 +74,6 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator {
|
||||
final ProtocolContext context,
|
||||
final Block block,
|
||||
final List<TransactionReceipt> receipts,
|
||||
final Optional<List<Request>> requests,
|
||||
final HeaderValidationMode ommerValidationMode,
|
||||
final BodyValidationMode bodyValidationMode) {
|
||||
if (bodyValidationMode == BodyValidationMode.NONE) {
|
||||
@@ -119,9 +114,6 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!validateRequests(block, requests, receipts)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -324,13 +316,4 @@ public class MainnetBlockBodyValidator implements BlockBodyValidator {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean validateRequests(
|
||||
final Block block,
|
||||
final Optional<List<Request>> requests,
|
||||
final List<TransactionReceipt> receipts) {
|
||||
final RequestsValidatorCoordinator requestValidator =
|
||||
protocolSchedule.getByBlockHeader(block.getHeader()).getRequestsValidatorCoordinator();
|
||||
return requestValidator.validate(block, requests, receipts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,13 +66,7 @@ public class MainnetBlockImporter implements BlockImporter {
|
||||
final BodyValidationMode bodyValidationMode) {
|
||||
|
||||
if (blockValidator.validateBlockForSyncing(
|
||||
context,
|
||||
block,
|
||||
receipts,
|
||||
block.getBody().getRequests(),
|
||||
headerValidationMode,
|
||||
ommerValidationMode,
|
||||
bodyValidationMode)) {
|
||||
context, block, receipts, headerValidationMode, ommerValidationMode, bodyValidationMode)) {
|
||||
context.getBlockchain().appendBlock(block, receipts);
|
||||
return new BlockImportResult(true);
|
||||
}
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.mainnet;
|
||||
|
||||
import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator.pragueRequestsProcessors;
|
||||
import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator.pragueRequestsValidator;
|
||||
import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsProcessor.pragueRequestsProcessors;
|
||||
|
||||
import org.hyperledger.besu.config.GenesisConfigOptions;
|
||||
import org.hyperledger.besu.config.PowAlgorithm;
|
||||
@@ -39,6 +38,7 @@ import org.hyperledger.besu.ethereum.mainnet.blockhash.PragueBlockHashProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
import org.hyperledger.besu.ethereum.mainnet.parallelization.MainnetParallelBlockProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestContractAddresses;
|
||||
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor;
|
||||
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator;
|
||||
@@ -789,7 +789,7 @@ public abstract class MainnetProtocolSpecs {
|
||||
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::prague)
|
||||
|
||||
// EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests
|
||||
.requestsValidator(pragueRequestsValidator(requestContractAddresses))
|
||||
.requestsValidator(new MainnetRequestsValidator())
|
||||
// EIP-7002 Withdrawals / EIP-6610 Deposits / EIP-7685 Requests
|
||||
.requestProcessorCoordinator(pragueRequestsProcessors(requestContractAddresses))
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.hyperledger.besu.ethereum.core.BlockImporter;
|
||||
import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidator;
|
||||
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor;
|
||||
import org.hyperledger.besu.evm.EVM;
|
||||
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
||||
@@ -78,7 +78,7 @@ public class ProtocolSpec {
|
||||
|
||||
private final WithdrawalsValidator withdrawalsValidator;
|
||||
private final Optional<WithdrawalsProcessor> withdrawalsProcessor;
|
||||
private final RequestsValidatorCoordinator requestsValidatorCoordinator;
|
||||
private final RequestsValidator requestsValidator;
|
||||
private final Optional<RequestProcessorCoordinator> requestProcessorCoordinator;
|
||||
private final BlockHashProcessor blockHashProcessor;
|
||||
private final boolean isPoS;
|
||||
@@ -110,7 +110,7 @@ public class ProtocolSpec {
|
||||
* @param feeMarket an {@link Optional} wrapping {@link FeeMarket} class if appropriate.
|
||||
* @param powHasher the proof-of-work hasher
|
||||
* @param withdrawalsProcessor the Withdrawals processor to use
|
||||
* @param requestsValidatorCoordinator the request validator to use
|
||||
* @param requestsValidator the request validator to use
|
||||
* @param requestProcessorCoordinator the request processor to use
|
||||
* @param blockHashProcessor the blockHash processor to use
|
||||
* @param isPoS indicates whether the current spec is PoS
|
||||
@@ -142,7 +142,7 @@ public class ProtocolSpec {
|
||||
final Optional<PoWHasher> powHasher,
|
||||
final WithdrawalsValidator withdrawalsValidator,
|
||||
final Optional<WithdrawalsProcessor> withdrawalsProcessor,
|
||||
final RequestsValidatorCoordinator requestsValidatorCoordinator,
|
||||
final RequestsValidator requestsValidator,
|
||||
final Optional<RequestProcessorCoordinator> requestProcessorCoordinator,
|
||||
final BlockHashProcessor blockHashProcessor,
|
||||
final boolean isPoS,
|
||||
@@ -171,7 +171,7 @@ public class ProtocolSpec {
|
||||
this.powHasher = powHasher;
|
||||
this.withdrawalsValidator = withdrawalsValidator;
|
||||
this.withdrawalsProcessor = withdrawalsProcessor;
|
||||
this.requestsValidatorCoordinator = requestsValidatorCoordinator;
|
||||
this.requestsValidator = requestsValidator;
|
||||
this.requestProcessorCoordinator = requestProcessorCoordinator;
|
||||
this.blockHashProcessor = blockHashProcessor;
|
||||
this.isPoS = isPoS;
|
||||
@@ -375,8 +375,8 @@ public class ProtocolSpec {
|
||||
return withdrawalsProcessor;
|
||||
}
|
||||
|
||||
public RequestsValidatorCoordinator getRequestsValidatorCoordinator() {
|
||||
return requestsValidatorCoordinator;
|
||||
public RequestsValidator getRequestsValidator() {
|
||||
return requestsValidator;
|
||||
}
|
||||
|
||||
public Optional<RequestProcessorCoordinator> getRequestProcessorCoordinator() {
|
||||
|
||||
@@ -31,8 +31,9 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.FlexiblePrivacyPrecompiledContract;
|
||||
import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.PrivacyPluginPrecompiledContract;
|
||||
import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.PrivacyPrecompiledContract;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidator;
|
||||
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor;
|
||||
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator;
|
||||
import org.hyperledger.besu.evm.EVM;
|
||||
@@ -80,8 +81,7 @@ public class ProtocolSpecBuilder {
|
||||
private WithdrawalsValidator withdrawalsValidator =
|
||||
new WithdrawalsValidator.ProhibitedWithdrawals();
|
||||
private WithdrawalsProcessor withdrawalsProcessor;
|
||||
private RequestsValidatorCoordinator requestsValidatorCoordinator =
|
||||
RequestsValidatorCoordinator.empty();
|
||||
private RequestsValidator requestsValidator = new ProhibitedRequestValidator();
|
||||
private RequestProcessorCoordinator requestProcessorCoordinator;
|
||||
protected BlockHashProcessor blockHashProcessor;
|
||||
private FeeMarket feeMarket = FeeMarket.legacy();
|
||||
@@ -268,8 +268,8 @@ public class ProtocolSpecBuilder {
|
||||
}
|
||||
|
||||
public ProtocolSpecBuilder requestsValidator(
|
||||
final RequestsValidatorCoordinator requestsValidatorCoordinator) {
|
||||
this.requestsValidatorCoordinator = requestsValidatorCoordinator;
|
||||
final RequestsValidator requestsValidatorCoordinator) {
|
||||
this.requestsValidator = requestsValidatorCoordinator;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -402,7 +402,7 @@ public class ProtocolSpecBuilder {
|
||||
Optional.ofNullable(powHasher),
|
||||
withdrawalsValidator,
|
||||
Optional.ofNullable(withdrawalsProcessor),
|
||||
requestsValidatorCoordinator,
|
||||
requestsValidator,
|
||||
Optional.ofNullable(requestProcessorCoordinator),
|
||||
blockHashProcessor,
|
||||
isPoS,
|
||||
|
||||
@@ -56,7 +56,8 @@ public class SystemCallProcessor {
|
||||
* @param blockHeader the current block header.
|
||||
* @param operationTracer the operation tracer for tracing EVM operations.
|
||||
* @param blockHashLookup the block hash lookup function.
|
||||
* @return the output data from the call
|
||||
* @return the output data from the call. If no code exists at the callAddress then an empty Bytes
|
||||
* is returned.
|
||||
*/
|
||||
public Bytes process(
|
||||
final Address callAddress,
|
||||
@@ -69,7 +70,7 @@ public class SystemCallProcessor {
|
||||
final Account maybeContract = worldState.get(callAddress);
|
||||
if (maybeContract == null) {
|
||||
LOG.trace("System call address not found {}", callAddress);
|
||||
return null;
|
||||
return Bytes.EMPTY;
|
||||
}
|
||||
|
||||
final AbstractMessageProcessor messageProcessor =
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user