diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/BlockUtils.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/BlockUtils.java index 29f60dd74a6..3a4ca71002b 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/BlockUtils.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/BlockUtils.java @@ -58,7 +58,6 @@ public static BlockHeader createBlockHeader( null, null, null, - null, blockHeaderFunctions); } } diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/genesis.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/genesis.json index 8c6a3d41d5a..3f2645d4d3a 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/genesis.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/genesis.json @@ -36,7 +36,7 @@ "comment": "This is the account used to sign the transaction that creates a validator exit", "balance": "1000000000000000000000000000" }, - "0xEd8EA01d70Cb49726175BCf2778B9C982912e017": { + "0x00A3ca265EBcb825B45F985A16CEFB49958cE017": { "comment": "This is the runtime bytecode for the Withdrawal Request Smart Contract. It was created from the deployment transaction in EIP-7002 (https://eips.ethereum.org/EIPS/eip-7002#deployment)", "balance": "0", "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b36603814156101215760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012157600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f5460015460028282011161010f5750505f610115565b01600290035b5f555f600155604c025ff35b5f5ffd", diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/01_cancun_prepare_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/01_cancun_prepare_payload.json index e810b1cad33..21a2e70a48d 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/01_cancun_prepare_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/01_cancun_prepare_payload.json @@ -4,8 +4,8 @@ "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0x292042b10484fc182be8aba2a4c1863f6712cc7f0c74489c226792138134248f", - "safeBlockHash": "0x292042b10484fc182be8aba2a4c1863f6712cc7f0c74489c226792138134248f", + "headBlockHash": "0x3ca89f1d6b71aeb56389ac8270e9ae369d0bb8edeea747f2d868a5eb31892b04", + "safeBlockHash": "0x3ca89f1d6b71aeb56389ac8270e9ae369d0bb8edeea747f2d868a5eb31892b04", "finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000" }, { @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x292042b10484fc182be8aba2a4c1863f6712cc7f0c74489c226792138134248f", + "latestValidHash": "0x3ca89f1d6b71aeb56389ac8270e9ae369d0bb8edeea747f2d868a5eb31892b04", "validationError": null }, - "payloadId": "0x282643efdc841a11" + "payloadId": "0x282643d318bdab11" } }, "statusCode": 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/02_cancun_getPayloadV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/02_cancun_getPayloadV3.json index 8c7d4177c45..0c9281fc6a5 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/02_cancun_getPayloadV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/02_cancun_getPayloadV3.json @@ -3,7 +3,7 @@ "jsonrpc": "2.0", "method": "engine_getPayloadV3", "params": [ - "0x282643efdc841a11" + "0x282643d318bdab11" ], "id": 67 }, @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x292042b10484fc182be8aba2a4c1863f6712cc7f0c74489c226792138134248f", + "parentHash": "0x3ca89f1d6b71aeb56389ac8270e9ae369d0bb8edeea747f2d868a5eb31892b04", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0xf4e9cba3bdb0cf3aa214612d87f2a1ab18cdc604a0af18f71110754a85de5d15", + "stateRoot": "0x2b6a1166ce24fe0af741c7313e6049e9e19351742bfaf4179154bc594ca9eb90", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -29,7 +29,7 @@ "blockNumber": "0x1", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "blobGasUsed": "0x0", - "blockHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a" + "blockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950" }, "blockValue": "0x0", "blobsBundle": { diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/03_cancun_newPayloadV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/03_cancun_newPayloadV3.json index 3145cd5439f..583bdc1a20e 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/03_cancun_newPayloadV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/03_cancun_newPayloadV3.json @@ -4,9 +4,9 @@ "method": "engine_newPayloadV3", "params": [ { - "parentHash": "0x292042b10484fc182be8aba2a4c1863f6712cc7f0c74489c226792138134248f", + "parentHash": "0x3ca89f1d6b71aeb56389ac8270e9ae369d0bb8edeea747f2d868a5eb31892b04", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0xf4e9cba3bdb0cf3aa214612d87f2a1ab18cdc604a0af18f71110754a85de5d15", + "stateRoot": "0x2b6a1166ce24fe0af741c7313e6049e9e19351742bfaf4179154bc594ca9eb90", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -17,7 +17,7 @@ "transactions": [], "withdrawals": [], "blockNumber": "0x1", - "blockHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a", + "blockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "excessBlobGas": "0x0", "blobGasUsed": "0x0" @@ -32,7 +32,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a", + "latestValidHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", "validationError": null } }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/04_cancun_forkchoiceUpdatedV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/04_cancun_forkchoiceUpdatedV3.json index b578116448d..229ca2cf51c 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/04_cancun_forkchoiceUpdatedV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/04_cancun_forkchoiceUpdatedV3.json @@ -4,9 +4,9 @@ "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a", - "safeBlockHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a", - "finalizedBlockHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a" + "headBlockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", + "safeBlockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", + "finalizedBlockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950" }, null ], @@ -18,7 +18,7 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a", + "latestValidHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", "validationError": null }, "payloadId": null diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/05_prague_forkchoiceUpdatedV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/05_prague_forkchoiceUpdatedV3.json index 3e7d4b38595..721a625b6ab 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/05_prague_forkchoiceUpdatedV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/05_prague_forkchoiceUpdatedV3.json @@ -4,9 +4,9 @@ "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a", - "safeBlockHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a", - "finalizedBlockHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a" + "headBlockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", + "safeBlockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", + "finalizedBlockHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950" }, { "timestamp": "0x20", @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a", + "latestValidHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", "validationError": null }, - "payloadId": "0x282643882dfdc121" + "payloadId": "0x282643c6d89e12df" } }, "statusCode": 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/06_prague_getPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/06_prague_getPayloadV4.json index b8c8f0818a2..4d754df1ce9 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/06_prague_getPayloadV4.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/06_prague_getPayloadV4.json @@ -3,7 +3,7 @@ "jsonrpc": "2.0", "method": "engine_getPayloadV4", "params": [ - "0x282643882dfdc121" + "0x282643c6d89e12df" ], "id": 67 }, @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a", + "parentHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0xc809e88f0456bc45340fa03cedd1c1d658c1b947a7f23e6a17ed108af60d3afc", + "stateRoot": "0x3057566307e82861160cd217c71c18a93023a752d268113a4e50148fe6f19be6", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -26,7 +26,7 @@ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactions": [], "withdrawals": [], - "depositReceipts": [], + "depositRequests": [], "withdrawalRequests": [ { "sourceAddress": "0xa4664c40aacebd82a2db79f0ea36c06bc6a19adb", @@ -35,7 +35,7 @@ } ], "blockNumber": "0x2", - "blockHash": "0x41d9ad8707752c4e6c46eecc956e79fc1fafc44fc0cc5fd7a5b981b02e216932", + "blockHash": "0xdce2f62925b5ebb218943e71fa87af2aaeb6dab2d8aee12ea7f9f24eeae7b4c7", "blobGasUsed": "0x0", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposits_execute_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposits_execute_payload.json index 0294c6b8f21..3eeccb01b5d 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposits_execute_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/08_prague_invalid_null_deposits_execute_payload.json @@ -17,7 +17,7 @@ "excessBlobGas": "0x0", "transactions": [], "withdrawals": [], - "depositReceipts" : null, + "depositRequests" : null, "blockNumber": "0x2", "blockHash": "0xf6c3f1180ba58d6ea4c69c9328c7afb1fda41df06c368741c1f8310567879de7", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/09_prague_newPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/09_prague_newPayloadV4.json index 2a57e04ea7a..1c5c0c3b907 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/09_prague_newPayloadV4.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/09_prague_newPayloadV4.json @@ -4,9 +4,9 @@ "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x2b0ef8ec0a5f8b3bd5e64cde3f1ed7f61c472b79bea9e44598921c3c37890a6a", + "parentHash": "0x74e8ce9d96d325a605675a34175adfa34581f35091dcd7b107c525a82b0b9950", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0xb25de115723e262bb1d5da7e3576dea47c3fe7e8ca52c430e6f9def712de830d", + "stateRoot": "0x778ccbc3adc59876b76489cdc1a2ff76ef2a31ae9d3bf761bc55bbab7d59c489", "logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -19,7 +19,7 @@ "0x02f9021c8217de808459682f008459682f0e830271009442424242424242424242424242424242424242428901bc16d674ec800000b901a422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120749715de5d1226545c6b3790f515d551a5cc5bf1d49c87a696860554d2fc4f14000000000000000000000000000000000000000000000000000000000000003096a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef20000000000000000000000000000000000000000000000000000000000000060b1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9c080a09f597089338d7f44f5c59f8230bb38f243849228a8d4e9d2e2956e6050f5b2c7a076486996c7e62802b8f95eee114783e4b403fd11093ba96286ff42c595f24452" ], "withdrawals": [], - "depositReceipts": [ + "depositRequests": [ { "amount": "0x773594000", "index": "0x0", @@ -36,7 +36,7 @@ } ], "blockNumber": "0x2", - "blockHash": "0xcf161dd8d9811f119f7377aa7cccd933955d1a6deb538200785191fb938fec5e", + "blockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9", "blobGasUsed": "0x0" }, @@ -50,7 +50,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0xcf161dd8d9811f119f7377aa7cccd933955d1a6deb538200785191fb938fec5e", + "latestValidHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "validationError": null } }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/10_prague_forkchoiceUpdatedV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/10_prague_forkchoiceUpdatedV3.json index d764049f65e..c0eaebd2a41 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/10_prague_forkchoiceUpdatedV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/10_prague_forkchoiceUpdatedV3.json @@ -4,9 +4,9 @@ "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0xcf161dd8d9811f119f7377aa7cccd933955d1a6deb538200785191fb938fec5e", - "safeBlockHash": "0xcf161dd8d9811f119f7377aa7cccd933955d1a6deb538200785191fb938fec5e", - "finalizedBlockHash": "0xcf161dd8d9811f119f7377aa7cccd933955d1a6deb538200785191fb938fec5e" + "headBlockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", + "safeBlockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", + "finalizedBlockHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852" }, { "timestamp": "0x30", @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0xcf161dd8d9811f119f7377aa7cccd933955d1a6deb538200785191fb938fec5e", + "latestValidHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "validationError": null }, - "payloadId": "0x28264390264496cf" + "payloadId": "0x282643ead6ad5331" } }, "statusCode" : 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/11_prague_getPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/11_prague_getPayloadV4.json index f9b2aa8e467..f93425a7e16 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/11_prague_getPayloadV4.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/11_prague_getPayloadV4.json @@ -3,7 +3,7 @@ "jsonrpc": "2.0", "method": "engine_getPayloadV4", "params": [ - "0x28264390264496cf" + "0x282643ead6ad5331" ], "id": 67 }, @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0xcf161dd8d9811f119f7377aa7cccd933955d1a6deb538200785191fb938fec5e", + "parentHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0xf786274a52a498c61961f6faa82c8f2df6c65bf6f0cbdd53216821bc981494a4", + "stateRoot": "0x61d2011dc13b003c48193f0902653fd4f7b67fa949dc0fa6eab9e69e349700fd", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -26,10 +26,10 @@ "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactions": [], "withdrawals": [], - "depositReceipts": [], + "depositRequests": [], "withdrawalRequests": [], "blockNumber": "0x3", - "blockHash": "0xf1626764177578f1bf1f0fcce3f5ecab4bf7e4c8c7754d1d30e7c0b98334ad98", + "blockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "blobGasUsed": "0x0" }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV4.json index 7c8b36d9943..f5e1c6c2d4d 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV4.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/12_cancun_newPayloadV4.json @@ -4,9 +4,9 @@ "method": "engine_newPayloadV3", "params": [ { - "parentHash": "0xcf161dd8d9811f119f7377aa7cccd933955d1a6deb538200785191fb938fec5e", + "parentHash": "0xb56ecf32963d4160799d4db6fe3723f01226635d058ab86a11eaa9f8234af852", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0xf786274a52a498c61961f6faa82c8f2df6c65bf6f0cbdd53216821bc981494a4", + "stateRoot": "0x61d2011dc13b003c48193f0902653fd4f7b67fa949dc0fa6eab9e69e349700fd", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -16,10 +16,10 @@ "baseFeePerGas": "0x7", "transactions": [], "withdrawals": [], - "depositReceipts": [], + "depositRequests": [], "withdrawalRequests": [], "blockNumber": "0x3", - "blockHash": "0xf1626764177578f1bf1f0fcce3f5ecab4bf7e4c8c7754d1d30e7c0b98334ad98", + "blockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "excessBlobGas": "0x0", "blobGasUsed": "0x0" @@ -34,7 +34,7 @@ "id": 67, "result": { "status": "VALID", - "latestValidHash": "0xf1626764177578f1bf1f0fcce3f5ecab4bf7e4c8c7754d1d30e7c0b98334ad98", + "latestValidHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "validationError": null } }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/13_prague_send_raw_transaction_create_exit.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/13_prague_send_raw_transaction_create_exit.json index c9facbcc663..fca8dd88e41 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/13_prague_send_raw_transaction_create_exit.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/13_prague_send_raw_transaction_create_exit.json @@ -2,13 +2,13 @@ "request": { "jsonrpc": "2.0", "method": "eth_sendRawTransaction", - "params": ["0xf8a08085e8d4a51000832dc6c094ed8ea01d70cb49726175bcf2778b9c982912e01702b8388706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf2430000000000000000822fe0a008135b1be1734b1b446de871eba10dbc317437eff377a7444f2ff6c06b5e5345a01bc61e0d4dd6d8e0b1f41d843fd9e07260c8be8c664ec2fa8c364477fa021176"], + "params": ["0xf8a08085e8d4a51000832dc6c09400a3ca265ebcb825b45f985a16cefb49958ce01702b8388706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf2430000000000000000822fdfa00476c1a81f80f4c130acb5f8b8075468ba0893d766b7ec51a8d9723c573ad034a03bd3eaedabbaaf745f15023185ba66584ad3ee8bb40b9bef8c0b9ed27f8b1959"], "id": 67 }, "response": { "jsonrpc": "2.0", "id": 67, - "result": "0x764bfa879d0df4ff3962e32dfd45dc39ea18a35ccbd0dadf0bb58672537b1db2" + "result": "0x5878bb7458f51c06a121396769543bdc8b40221b7e214880b1e292fa04058f17" }, "statusCode": 200 } \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_forkchoiceUpdatedV3.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_forkchoiceUpdatedV3.json index 3c81beb3771..32fc288b0c0 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_forkchoiceUpdatedV3.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/14_prague_forkchoiceUpdatedV3.json @@ -4,9 +4,9 @@ "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0xf1626764177578f1bf1f0fcce3f5ecab4bf7e4c8c7754d1d30e7c0b98334ad98", - "safeBlockHash": "0xf1626764177578f1bf1f0fcce3f5ecab4bf7e4c8c7754d1d30e7c0b98334ad98", - "finalizedBlockHash": "0xf1626764177578f1bf1f0fcce3f5ecab4bf7e4c8c7754d1d30e7c0b98334ad98" + "headBlockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", + "safeBlockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", + "finalizedBlockHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9" }, { "timestamp": "0x40", @@ -24,10 +24,10 @@ "result": { "payloadStatus": { "status": "VALID", - "latestValidHash": "0xf1626764177578f1bf1f0fcce3f5ecab4bf7e4c8c7754d1d30e7c0b98334ad98", + "latestValidHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "validationError": null }, - "payloadId": "0x282643d998c41241" + "payloadId": "0x2826438a3f8a7741" } }, "statusCode" : 200 diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_getPayloadV4.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_getPayloadV4.json index 31d55af69e6..9af6ea45cc5 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_getPayloadV4.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/prague/test-cases/15_prague_getPayloadV4.json @@ -3,7 +3,7 @@ "jsonrpc": "2.0", "method": "engine_getPayloadV4", "params": [ - "0x282643d998c41241" + "0x2826438a3f8a7741" ], "id": 67 }, @@ -12,9 +12,9 @@ "id": 67, "result": { "executionPayload": { - "parentHash": "0xf1626764177578f1bf1f0fcce3f5ecab4bf7e4c8c7754d1d30e7c0b98334ad98", + "parentHash": "0x7a619ef406633a6d6589602009b5d242e1273fd8259cebcac4ab006edfdf81f9", "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "stateRoot": "0x4021e9832c7d9945cb681d670c238c6178bd2184e957a474a7989d06f7171349", + "stateRoot": "0x847db08c6b9e6dcc91288bd963eb5623aea5387232016ef81fddb3ebc994c72f", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0x1c9c380", @@ -25,10 +25,10 @@ "excessBlobGas": "0x0", "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "transactions": [ - "0xf8a08085e8d4a51000832dc6c094ed8ea01d70cb49726175bcf2778b9c982912e01702b8388706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf2430000000000000000822fe0a008135b1be1734b1b446de871eba10dbc317437eff377a7444f2ff6c06b5e5345a01bc61e0d4dd6d8e0b1f41d843fd9e07260c8be8c664ec2fa8c364477fa021176" + "0xf8a08085e8d4a51000832dc6c09400a3ca265ebcb825b45f985a16cefb49958ce01702b8388706d19a62f28a6a6549f96c5adaebac9124a61d44868ec94f6d2d707c6a2f82c9162071231dfeb40e24bfde4ffdf2430000000000000000822fdfa00476c1a81f80f4c130acb5f8b8075468ba0893d766b7ec51a8d9723c573ad034a03bd3eaedabbaaf745f15023185ba66584ad3ee8bb40b9bef8c0b9ed27f8b1959" ], "withdrawals": [], - "depositReceipts": [], + "depositRequests": [], "withdrawalRequests": [ { "sourceAddress": "0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f", @@ -39,7 +39,7 @@ "blockNumber": "0x4", "blobGasUsed": "0x0", "receiptsRoot": "0x765bd9d63cc10fa47117d6cc0958f15e55a3bde540d4ed15d220f573fbb82cba", - "blockHash": "0xc5c15f6a88d3576927b16de1c635cabf46bb9419a3bbb3be156ddbe229de5e64" + "blockHash": "0xd0b81acdb3016abbc05599b083c8b090323efaf0b2aeab8d0755780e20214159" }, "blockValue": "0x12855dcd153473b", "blobsBundle": { diff --git a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java index ee4799da965..731fd2ac568 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java @@ -192,7 +192,6 @@ public void miningParametersBlockPeriodSecondsIsUpdatedOnTransition() { null, null, null, - null, getBlockHeaderFunctions()); final Block block1 = new Block(header1, BlockBody.empty()); diff --git a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java index c4cce7f4c54..82f98ba8266 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java @@ -221,7 +221,6 @@ public void miningParametersBlockPeriodSecondsIsUpdatedOnTransition() { null, null, null, - null, new CliqueBlockHeaderFunctions()); final Block block1 = new Block(header1, BlockBody.empty()); diff --git a/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java b/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java index 80eae1af436..3673e78e312 100644 --- a/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java +++ b/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java @@ -218,7 +218,7 @@ private void setSyncTarget() { mock(EthPeer.class), new org.hyperledger.besu.ethereum.core.BlockHeader( null, null, null, null, null, null, null, null, 1, 1, 1, 1, null, null, null, 1, null, - null, null, null, null, null, null)); + null, null, null, null, null)); } private void clearSyncTarget() { diff --git a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java index e703aeb48f1..099d66dc9f4 100644 --- a/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java +++ b/consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueBlockCreator.java @@ -76,7 +76,6 @@ public CliqueBlockCreator( protocolContext, protocolSchedule, parentHeader, - Optional.empty(), ethScheduler); this.nodeKey = nodeKey; this.epochManager = epochManager; diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java index b84cd665f14..f461a77913e 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreator.java @@ -76,7 +76,6 @@ public BftBlockCreator( protocolContext, protocolSchedule, parentHeader, - Optional.empty(), ethScheduler); this.bftExtraDataCodec = bftExtraDataCodec; } diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java index f720d86a54c..10c21384adf 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeBlockCreator.java @@ -14,7 +14,6 @@ */ package org.hyperledger.besu.consensus.merge.blockcreation; -import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.blockcreation.AbstractBlockCreator; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -54,7 +53,6 @@ public MergeBlockCreator( final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, final BlockHeader parentHeader, - final Optional
depositContractAddress, final EthScheduler ethScheduler) { super( miningParameters, @@ -64,7 +62,6 @@ public MergeBlockCreator( protocolContext, protocolSchedule, parentHeader, - depositContractAddress, ethScheduler); } diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java index 68c5a16599a..4d4ca0638d3 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java @@ -149,7 +149,6 @@ public MergeCoordinator( protocolContext, protocolSchedule, parentHeader, - depositContractAddress, ethScheduler); }; diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java index 31aadde47d2..6ce8bcd8d0a 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java @@ -275,7 +275,6 @@ public void exceptionDuringBuildingBlockShouldNotBeInvalid() protocolContext, protocolSchedule, parentHeader, - Optional.empty(), ethScheduler)); doCallRealMethod() diff --git a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java index 2273b5a0f5a..b3c462656ac 100644 --- a/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java +++ b/consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/messagewrappers/ProposalTest.java @@ -55,7 +55,6 @@ public class ProposalTest { Collections.emptyList(), Collections.emptyList(), Optional.of(Collections.emptyList()), - Optional.empty(), Optional.empty())); @Test diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/RequestType.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/RequestType.java new file mode 100644 index 00000000000..b1cddb44040 --- /dev/null +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/RequestType.java @@ -0,0 +1,58 @@ +/* + * 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.datatypes; + +import java.util.Arrays; + +/** Enum representing different types of requests with associated serialized type values. */ +public enum RequestType { + /** DEPOSITS */ + DEPOSIT(0x00), + /** WITHDRAWAL */ + WITHDRAWAL(0x01); + + private final int typeValue; + + RequestType(final int typeValue) { + this.typeValue = typeValue; + } + + /** + * Gets the serialized type value of the request type. + * + * @return the serialized type value as a byte. + */ + public byte getSerializedType() { + return (byte) this.typeValue; + } + + /** + * Returns the {@link RequestType} corresponding to the given serialized type value. + * + * @param serializedTypeValue the serialized type value. + * @return the corresponding {@link RequestType}. + * @throws IllegalArgumentException if the serialized type value does not correspond to any {@link + * RequestType}. + */ + public static RequestType of(final int serializedTypeValue) { + return Arrays.stream(RequestType.values()) + .filter(requestType -> requestType.typeValue == serializedTypeValue) + .findFirst() + .orElseThrow( + () -> + new IllegalArgumentException( + String.format("Unsupported request type: 0x%02X", serializedTypeValue))); + } +} diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java index 749e96b11e8..a62cc06ec26 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseKey.java @@ -38,6 +38,5 @@ public enum JsonRpcResponseKey { TRANSACTION_ROOT, BASEFEE, WITHDRAWALS_ROOT, - DEPOSITS_ROOT, - WITHDRAWAL_REQUESTS_ROOT + REQUESTS_ROOT } diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java index 83bcece600d..4e067e6ec8a 100644 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java +++ b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcResponseUtils.java @@ -16,7 +16,6 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.BASEFEE; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.COINBASE; -import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.DEPOSITS_ROOT; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.DIFFICULTY; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.EXTRA_DATA; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.GAS_LIMIT; @@ -28,13 +27,13 @@ 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.SIZE; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.STATE_ROOT; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.TIMESTAMP; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.TOTAL_DIFFICULTY; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.TRANSACTION_ROOT; import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.WITHDRAWALS_ROOT; -import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.WITHDRAWAL_REQUESTS_ROOT; import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; import org.hyperledger.besu.datatypes.Address; @@ -105,12 +104,8 @@ public JsonRpcResponse response( final int size = unsignedInt(values.get(SIZE)); final Hash withdrawalsRoot = values.containsKey(WITHDRAWALS_ROOT) ? hash(values.get(WITHDRAWALS_ROOT)) : null; - final Hash depositsRoot = - values.containsKey(DEPOSITS_ROOT) ? hash(values.get(DEPOSITS_ROOT)) : null; - final Hash withdrawalRequestsRoot = - values.containsKey(WITHDRAWAL_REQUESTS_ROOT) - ? hash(values.get(WITHDRAWAL_REQUESTS_ROOT)) - : null; + final Hash requestsRoot = + values.containsKey(REQUESTS_ROOT) ? hash(values.get(REQUESTS_ROOT)) : null; final List ommers = new ArrayList<>(); final BlockHeader header = @@ -135,8 +130,7 @@ public JsonRpcResponse response( 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 - depositsRoot, - withdrawalRequestsRoot, + requestsRoot, blockHeaderFunctions); return new JsonRpcSuccessResponse( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java index 205ba8cf534..d2faf8e7d86 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java @@ -20,8 +20,8 @@ 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.DepositsValidatorProvider.getDepositsValidator; -import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalRequestValidatorProvider.getWithdrawalRequestValidator; +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.WithdrawalsValidatorProvider.getWithdrawalsValidator; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_PARAMS; @@ -49,11 +49,10 @@ import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; -import org.hyperledger.besu.ethereum.core.Deposit; import org.hyperledger.besu.ethereum.core.Difficulty; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.Transaction; 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.TransactionDecoder; import org.hyperledger.besu.ethereum.eth.manager.EthPeers; @@ -63,6 +62,7 @@ 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; @@ -161,16 +161,17 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) reqId, new JsonRpcError(INVALID_PARAMS, "Invalid withdrawals")); } - final Optional> maybeDeposits = + final Optional> maybeDeposits = Optional.ofNullable(blockParam.getDeposits()) .map(ds -> ds.stream().map(DepositParameter::toDeposit).collect(toList())); - if (!getDepositsValidator( + if (!getDepositRequestValidator( protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) - .validateDepositParameter(maybeDeposits)) { - return new JsonRpcErrorResponse(reqId, new JsonRpcError(INVALID_PARAMS, "Invalid deposits")); + .validateParameter(maybeDeposits)) { + return new JsonRpcErrorResponse( + reqId, new JsonRpcError(INVALID_PARAMS, "Invalid deposit request")); } - final Optional> maybeWithdrawalRequests = + final Optional> maybeWithdrawalRequests = Optional.ofNullable(blockParam.getWithdrawalRequests()) .map( withdrawalRequest -> @@ -179,11 +180,14 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) .collect(toList())); if (!getWithdrawalRequestValidator( protocolSchedule.get(), blockParam.getTimestamp(), blockParam.getBlockNumber()) - .validateWithdrawalRequestParameter(maybeWithdrawalRequests)) { + .validateParameter(maybeWithdrawalRequests)) { return new JsonRpcErrorResponse( - reqId, new JsonRpcError(INVALID_PARAMS, "Invalid withdrawal requests")); + reqId, new JsonRpcError(INVALID_PARAMS, "Invalid withdrawal request")); } + Optional> maybeRequests = + RequestUtil.combine(maybeDeposits, maybeWithdrawalRequests); + if (mergeContext.get().isSyncing()) { LOG.debug("We are syncing"); return respondWith(reqId, blockParam, null, SYNCING); @@ -251,8 +255,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) ? null : BlobGas.fromHexString(blockParam.getExcessBlobGas()), maybeParentBeaconBlockRoot.orElse(null), - maybeDeposits.map(BodyValidation::depositsRoot).orElse(null), - maybeWithdrawalRequests.map(BodyValidation::withdrawalRequestsRoot).orElse(null), + maybeRequests.map(BodyValidation::requestsRoot).orElse(null), headerFunctions); // ensure the block hash matches the blockParam hash @@ -315,12 +318,7 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) final var block = new Block( newBlockHeader, - new BlockBody( - transactions, - Collections.emptyList(), - maybeWithdrawals, - maybeDeposits, - maybeWithdrawalRequests)); + new BlockBody(transactions, Collections.emptyList(), maybeWithdrawals, maybeRequests)); if (maybeParentHeader.isEmpty()) { LOG.atDebug() @@ -539,9 +537,9 @@ private void logImportedBlockInfo(final Block block, final int blobCount, final message.append(" / %d ws"); messageArgs.add(block.getBody().getWithdrawals().get().size()); } - if (block.getBody().getDeposits().isPresent()) { - message.append(" / %d ds"); - messageArgs.add(block.getBody().getDeposits().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( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java deleted file mode 100644 index 51e23770684..00000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/DepositsValidatorProvider.java +++ /dev/null @@ -1,43 +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.methods.engine; - -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; -import org.hyperledger.besu.ethereum.mainnet.DepositsValidator; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; - -import java.util.Optional; - -public class DepositsValidatorProvider { - - static DepositsValidator getDepositsValidator( - final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) { - - final BlockHeader blockHeader = - BlockHeaderBuilder.createDefault() - .timestamp(blockTimestamp) - .number(blockNumber) - .buildBlockHeader(); - return getDepositsValidator(protocolSchedule.getByBlockHeader(blockHeader)); - } - - private static DepositsValidator getDepositsValidator(final ProtocolSpec protocolSchedule) { - return Optional.ofNullable(protocolSchedule) - .map(ProtocolSpec::getDepositsValidator) - .orElseGet(DepositsValidator.ProhibitedDeposits::new); - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/RequestValidatorProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/RequestValidatorProvider.java new file mode 100644 index 00000000000..a86f4ca5eac --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/RequestValidatorProvider.java @@ -0,0 +1,71 @@ +/* + * 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.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 java.util.Optional; + +public class RequestValidatorProvider { + + public static RequestValidator getDepositRequestValidator( + 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); + } + + 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(() -> new RequestsValidatorCoordinator.Builder().build()); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/WithdrawalRequestValidatorProvider.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/WithdrawalRequestValidatorProvider.java deleted file mode 100644 index 77261a70e53..00000000000 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/WithdrawalRequestValidatorProvider.java +++ /dev/null @@ -1,45 +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.methods.engine; - -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.WithdrawalRequestValidator; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidator.ProhibitedWithdrawalRequests; - -import java.util.Optional; - -public class WithdrawalRequestValidatorProvider { - - static WithdrawalRequestValidator getWithdrawalRequestValidator( - final ProtocolSchedule protocolSchedule, final long blockTimestamp, final long blockNumber) { - - final BlockHeader blockHeader = - BlockHeaderBuilder.createDefault() - .timestamp(blockTimestamp) - .number(blockNumber) - .buildBlockHeader(); - return getWithdrawalRequestValidator(protocolSchedule.getByBlockHeader(blockHeader)); - } - - private static WithdrawalRequestValidator getWithdrawalRequestValidator( - final ProtocolSpec protocolSchedule) { - return Optional.ofNullable(protocolSchedule) - .map(ProtocolSpec::getWithdrawalRequestValidator) - .orElseGet(ProhibitedWithdrawalRequests::new); - } -} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java index c1601a98afb..a264c60edf3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/EnginePayloadParameter.java @@ -88,7 +88,7 @@ public EnginePayloadParameter( @JsonProperty("withdrawals") final List withdrawals, @JsonProperty("blobGasUsed") final UnsignedLongParameter blobGasUsed, @JsonProperty("excessBlobGas") final String excessBlobGas, - @JsonProperty("depositReceipts") final List deposits, + @JsonProperty("depositRequests") final List deposits, @JsonProperty("withdrawalRequests") final List withdrawalRequestParameters) { this.blockHash = blockHash; diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java index b453c76d742..15b3a9c2c21 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/BlockResultFactory.java @@ -24,8 +24,12 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockValueCalculator; import org.hyperledger.besu.ethereum.core.BlockWithReceipts; +import org.hyperledger.besu.ethereum.core.Deposit; +import org.hyperledger.besu.ethereum.core.Request; +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.requests.RequestUtil; import java.util.ArrayList; import java.util.List; @@ -172,12 +176,23 @@ public EngineGetPayloadResultV4 payloadTransactionCompleteV4( blockWithReceipts.getHeader(), txs, blockWithReceipts.getBlock().getBody().getWithdrawals(), - blockWithReceipts.getBlock().getBody().getDeposits(), - blockWithReceipts.getBlock().getBody().getWithdrawalRequests(), + getDepositRequest(blockWithReceipts.getBlock().getBody().getRequests()), + getWithdrawalRequest(blockWithReceipts.getBlock().getBody().getRequests()), Quantity.create(blockValue), blobsBundleV1); } + private Optional> getDepositRequest(final Optional> requests) { + return requests.map( + requestList -> RequestUtil.filterRequestsOfType(requestList, Deposit.class)); + } + + private Optional> getWithdrawalRequest( + final Optional> requests) { + return requests.map( + requestList -> RequestUtil.filterRequestsOfType(requestList, WithdrawalRequest.class)); + } + public BlockResult transactionHash(final BlockWithMetadata blockWithMetadata) { return transactionHash(blockWithMetadata, false); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV4.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV4.java index 9a7cbcf3627..03a5082dad7 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV4.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/EngineGetPayloadResultV4.java @@ -215,7 +215,7 @@ public List getWithdrawals() { return withdrawals; } - @JsonGetter(value = "depositReceipts") + @JsonGetter(value = "depositRequests") public List getDeposits() { return deposits; } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java index 2d08bdfe593..cd1e890fd41 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGasPriceTest.java @@ -222,7 +222,6 @@ private Object createFakeBlock(final Long height) { null, null, null, - null, null), new BlockBody( List.of( @@ -260,7 +259,6 @@ private Object createEmptyBlock(final Long height) { null, null, null, - null, null), new BlockBody(List.of(), List.of()))); } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java index abd2904bd7c..476705f6775 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java @@ -147,7 +147,7 @@ public class EthGetTransactionReceiptTest { null, Optional.empty(), null, - null, + Optional.empty(), new FrontierBlockHashProcessor(), true, true); @@ -178,7 +178,7 @@ public class EthGetTransactionReceiptTest { null, Optional.empty(), null, - null, + Optional.empty(), new FrontierBlockHashProcessor(), true, true); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java index 683373be326..f0479bd7d2e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineGetPayloadTest.java @@ -104,7 +104,6 @@ public AbstractEngineGetPayloadTest() { Collections.emptyList(), Collections.emptyList(), Optional.of(Collections.emptyList()), - Optional.empty(), Optional.empty())); private static final Block mockBlockWithDeposits = new Block( @@ -113,7 +112,6 @@ public AbstractEngineGetPayloadTest() { Collections.emptyList(), Collections.emptyList(), Optional.empty(), - Optional.of(Collections.emptyList()), Optional.of(Collections.emptyList()))); protected static final BlockWithReceipts mockBlockWithReceiptsAndWithdrawals = new BlockWithReceipts(mockBlockWithWithdrawals, Collections.emptyList()); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java index e3165ff2f3b..dc40b164a4a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayloadTest.java @@ -55,16 +55,18 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.Deposit; +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.DepositsValidator; 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.trie.MerkleTrieException; import org.hyperledger.besu.plugin.services.exception.StorageException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -113,9 +115,7 @@ public void before() { lenient() .when(protocolSpec.getWithdrawalsValidator()) .thenReturn(new WithdrawalsValidator.ProhibitedWithdrawals()); - lenient() - .when(protocolSpec.getDepositsValidator()) - .thenReturn(new DepositsValidator.ProhibitedDeposits()); + mockProhibitedRequestsValidator(); lenient().when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); lenient().when(ethPeers.peerCount()).thenReturn(1); } @@ -484,6 +484,22 @@ protected BlockHeaderTestFixture createBlockHeaderFixture( final Optional> maybeWithdrawals, final Optional> maybeDeposits, final Optional> maybeWithdrawalRequests) { + + Optional> maybeRequests; + if (maybeDeposits.isPresent() || maybeWithdrawalRequests.isPresent()) { + List requests = new ArrayList<>(); + maybeDeposits.ifPresent(requests::addAll); + maybeWithdrawalRequests.ifPresent(requests::addAll); + maybeRequests = Optional.of(requests); + } else { + maybeRequests = Optional.empty(); + } + return createBlockHeaderFixture(maybeWithdrawals, maybeRequests); + } + + protected BlockHeaderTestFixture createBlockHeaderFixture( + final Optional> maybeWithdrawals, + final Optional> maybeRequests) { BlockHeader parentBlockHeader = new BlockHeaderTestFixture().baseFeePerGas(Wei.ONE).buildHeader(); return new BlockHeaderTestFixture() @@ -492,8 +508,8 @@ protected BlockHeaderTestFixture createBlockHeaderFixture( .number(parentBlockHeader.getNumber() + 1) .timestamp(parentBlockHeader.getTimestamp() + 1) .withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null)) - .depositsRoot(maybeDeposits.map(BodyValidation::depositsRoot).orElse(null)) - .parentBeaconBlockRoot(maybeParentBeaconBlockRoot); + .parentBeaconBlockRoot(maybeParentBeaconBlockRoot) + .requestsRoot(maybeRequests.map(BodyValidation::requestsRoot).orElse(null)); } protected void assertValidResponse(final BlockHeader mockHeader, final JsonRpcResponse resp) { @@ -503,4 +519,9 @@ protected void assertValidResponse(final BlockHeader mockHeader, final JsonRpcRe assertThat(res.getError()).isNull(); verify(engineCallListener, times(1)).executionEngineCalled(); } + + private void mockProhibitedRequestsValidator() { + var validator = new RequestsValidatorCoordinator.Builder().build(); + when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(validator); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java index f5928091c16..d3104670de8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineExchangeTransitionConfigurationTest.java @@ -254,7 +254,6 @@ private BlockHeader createBlockHeader(final Hash blockHash, final long blockNumb null, null, null, - null, new BlockHeaderFunctions() { @Override public Hash hash(final BlockHeader header) { diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1Test.java index be0a336f9f4..42f2a5df0be 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByHashV1Test.java @@ -181,7 +181,6 @@ public void shouldReturnWithdrawalNullWhenBlockIsPreShanghai() { List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())), Collections.emptyList(), Optional.empty(), - Optional.empty(), Optional.empty()); when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(preShanghaiBlockBody)); when(blockchain.getBlockBody(blockHash2)).thenReturn(Optional.of(preShanghaiBlockBody2)); @@ -213,7 +212,6 @@ public void shouldReturnWithdrawalsWhenBlockIsPostShanghai() { new TransactionTestFixture().createTransaction(sig.generateKeyPair())), Collections.emptyList(), Optional.of(List.of(withdrawal)), - Optional.empty(), Optional.empty()); final BlockBody shanghaiBlockBody2 = @@ -221,7 +219,6 @@ public void shouldReturnWithdrawalsWhenBlockIsPostShanghai() { List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())), Collections.emptyList(), Optional.of(List.of(withdrawal2)), - Optional.empty(), Optional.empty()); when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody)); when(blockchain.getBlockBody(blockHash2)).thenReturn(Optional.of(shanghaiBlockBody2)); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1Test.java index 614aa169c20..60fb2ed1f80 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadBodiesByRangeV1Test.java @@ -180,7 +180,6 @@ public void shouldReturnNullForWithdrawalsWhenBlockIsPreShanghai() { List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())), Collections.emptyList(), Optional.empty(), - Optional.empty(), Optional.empty()); when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(130)); when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(preShanghaiBlockBody)); @@ -216,7 +215,6 @@ public void shouldReturnWithdrawalsWhenBlockIsPostShanghai() { new TransactionTestFixture().createTransaction(sig.generateKeyPair())), Collections.emptyList(), Optional.of(List.of(withdrawal)), - Optional.empty(), Optional.empty()); final BlockBody shanghaiBlockBody2 = @@ -224,7 +222,6 @@ public void shouldReturnWithdrawalsWhenBlockIsPostShanghai() { List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())), Collections.emptyList(), Optional.of(List.of(withdrawal2)), - Optional.empty(), Optional.empty()); when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(130)); when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody)); @@ -256,7 +253,6 @@ public void shouldNotContainTrailingNullForBlocksPastTheCurrentHead() { new TransactionTestFixture().createTransaction(sig.generateKeyPair())), Collections.emptyList(), Optional.of(List.of(withdrawal)), - Optional.empty(), Optional.empty()); when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(123)); when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody)); @@ -281,21 +277,18 @@ public void shouldReturnUpUntilHeadWhenStartBlockPlusCountEqualsHeadNumber() { List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())), Collections.emptyList(), Optional.of(List.of(withdrawal)), - Optional.empty(), Optional.empty()); final BlockBody shanghaiBlockBody2 = new BlockBody( List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())), Collections.emptyList(), Optional.of(List.of(withdrawal)), - Optional.empty(), Optional.empty()); final BlockBody shanghaiBlockBody3 = new BlockBody( List.of(new TransactionTestFixture().createTransaction(sig.generateKeyPair())), Collections.emptyList(), Optional.of(List.of(withdrawal)), - Optional.empty(), Optional.empty()); when(blockchain.getChainHeadBlockNumber()).thenReturn(Long.valueOf(125)); when(blockchain.getBlockBody(blockHash1)).thenReturn(Optional.of(shanghaiBlockBody)); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3Test.java index 094e54bac25..00db0171b7d 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3Test.java @@ -130,8 +130,7 @@ public void shouldReturnBlockForKnownPayloadId() { List.of(blobTx), Collections.emptyList(), Optional.of(Collections.emptyList()), - Optional.of(Collections.emptyList()), - Optional.empty())), + Optional.of(Collections.emptyList()))), List.of(blobReceipt)); when(mergeContext.retrieveBlockById(postCancunPid)).thenReturn(Optional.of(postCancunBlock)); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4Test.java index 64b473caffc..68828619c90 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4Test.java @@ -132,7 +132,6 @@ public void shouldReturnBlockForKnownPayloadId() { List.of(blobTx), Collections.emptyList(), Optional.of(Collections.emptyList()), - Optional.of(Collections.emptyList()), Optional.of(Collections.emptyList()))), List.of(blobReceipt)); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java index 67e3709b91d..4604c8487c1 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV3Test.java @@ -168,7 +168,6 @@ protected BlockHeader createBlockHeader( .number(parentBlockHeader.getNumber() + 1) .timestamp(parentBlockHeader.getTimestamp() + 12) .withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null)) - .depositsRoot(maybeDeposits.map(BodyValidation::depositsRoot).orElse(null)) .excessBlobGas(BlobGas.ZERO) .blobGasUsed(0L) .parentBeaconBlockRoot( diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java index c06134af014..679a274cbc5 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV4Test.java @@ -27,6 +27,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.BlobGas; +import org.hyperledger.besu.datatypes.RequestType; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.BlockProcessingOutputs; import org.hyperledger.besu.ethereum.BlockProcessingResult; @@ -40,14 +41,16 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.Deposit; +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.DepositsValidator; -import org.hyperledger.besu.ethereum.mainnet.PragueWithdrawalRequestValidator; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidator.ProhibitedWithdrawalRequests; +import org.hyperledger.besu.ethereum.mainnet.requests.DepositsValidator; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; +import org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestValidator; import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -91,12 +94,12 @@ public void shouldReturnExpectedMethodName() { @Test public void shouldReturnValidIfDepositsIsNull_WhenDepositsProhibited() { final List deposits = null; - when(protocolSpec.getDepositsValidator()) - .thenReturn(new DepositsValidator.ProhibitedDeposits()); + mockProhibitedRequestsValidator(); BlockHeader mockHeader = setupValidPayload( - new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), + new BlockProcessingResult( + Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.empty()))), Optional.empty(), Optional.empty(), Optional.empty()); @@ -113,10 +116,7 @@ public void shouldReturnValidIfDepositsIsNull_WhenDepositsProhibited() { @Test public void shouldReturnInvalidIfDepositsIsNull_WhenDepositsAllowed() { final List deposits = null; - lenient() - .when(protocolSpec.getDepositsValidator()) - .thenReturn(new DepositsValidator.AllowedDeposits(depositContractAddress)); - + mockAllowedDepositsRequestValidator(); var resp = resp( mockEnginePayload( @@ -133,14 +133,15 @@ public void shouldReturnInvalidIfDepositsIsNull_WhenDepositsAllowed() { @Test public void shouldReturnValidIfDepositsIsNotNull_WhenDepositsAllowed() { final List depositsParam = List.of(DEPOSIT_PARAM_1); - final List deposits = List.of(DEPOSIT_PARAM_1.toDeposit()); - when(protocolSpec.getDepositsValidator()) - .thenReturn(new DepositsValidator.AllowedDeposits(depositContractAddress)); + final List deposits = List.of(DEPOSIT_PARAM_1.toDeposit()); + + mockAllowedDepositsRequestValidator(); BlockHeader mockHeader = setupValidPayload( - new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), + new BlockProcessingResult( + Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.of(deposits)))), Optional.empty(), - Optional.of(deposits), + Optional.of(List.of(DEPOSIT_PARAM_1.toDeposit())), Optional.empty()); when(blockchain.getBlockHeader(mockHeader.getParentHash())) .thenReturn(Optional.of(mock(BlockHeader.class))); @@ -156,8 +157,8 @@ public void shouldReturnValidIfDepositsIsNotNull_WhenDepositsAllowed() { public void shouldReturnInvalidIfDepositsIsNotNull_WhenDepositsProhibited() { final List deposits = List.of(); lenient() - .when(protocolSpec.getDepositsValidator()) - .thenReturn(new DepositsValidator.ProhibitedDeposits()); + .when(protocolSpec.getRequestsValidatorCoordinator()) + .thenReturn(new RequestsValidatorCoordinator.Builder().build()); var resp = resp( @@ -176,12 +177,12 @@ public void shouldReturnInvalidIfDepositsIsNotNull_WhenDepositsProhibited() { @Test public void shouldReturnValidIfWithdrawalRequestsIsNull_WhenWithdrawalRequestsAreProhibited() { - when(protocolSpec.getWithdrawalRequestValidator()) - .thenReturn(new ProhibitedWithdrawalRequests()); + mockProhibitedRequestsValidator(); BlockHeader mockHeader = setupValidPayload( - new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), + new BlockProcessingResult( + Optional.of(new BlockProcessingOutputs(null, List.of(), Optional.empty()))), Optional.empty(), Optional.empty(), Optional.empty()); @@ -197,8 +198,7 @@ public void shouldReturnValidIfWithdrawalRequestsIsNull_WhenWithdrawalRequestsAr @Test public void shouldReturnInvalidIfWithdrawalRequestsIsNull_WhenWithdrawalRequestsAreAllowed() { - when(protocolSpec.getWithdrawalRequestValidator()) - .thenReturn(new PragueWithdrawalRequestValidator()); + mockAllowedWithdrawalsRequestValidator(); var resp = resp( @@ -217,17 +217,17 @@ public void shouldReturnInvalidIfWithdrawalRequestsIsNull_WhenWithdrawalRequests public void shouldReturnValidIfWithdrawalRequestsIsNotNull_WhenWithdrawalRequestsAreAllowed() { final List withdrawalRequestsParams = List.of(WITHDRAWAL_REQUEST_PARAMETER_1); - final List withdrawalRequests = + final List withdrawalRequests = List.of(WITHDRAWAL_REQUEST_PARAMETER_1.toWithdrawalRequest()); - when(protocolSpec.getWithdrawalRequestValidator()) - .thenReturn(new PragueWithdrawalRequestValidator()); - + mockAllowedWithdrawalsRequestValidator(); BlockHeader mockHeader = setupValidPayload( - new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(null, List.of()))), + new BlockProcessingResult( + Optional.of( + new BlockProcessingOutputs(null, List.of(), Optional.of(withdrawalRequests)))), Optional.empty(), Optional.empty(), - Optional.of(withdrawalRequests)); + Optional.of(List.of(WITHDRAWAL_REQUEST_PARAMETER_1.toWithdrawalRequest()))); when(blockchain.getBlockHeader(mockHeader.getParentHash())) .thenReturn(Optional.of(mock(BlockHeader.class))); when(mergeCoordinator.getLatestValidAncestor(mockHeader)) @@ -244,8 +244,7 @@ public void shouldReturnValidIfWithdrawalRequestsIsNotNull_WhenWithdrawalRequest public void shouldReturnInvalidIfWithdrawalRequestsIsNotNull_WhenWithdrawalRequestsAreProhibited() { final List withdrawalRequests = List.of(); - when(protocolSpec.getWithdrawalRequestValidator()) - .thenReturn(new ProhibitedWithdrawalRequests()); + mockProhibitedRequestsValidator(); var resp = resp( @@ -275,6 +274,16 @@ protected BlockHeader createBlockHeader( .blobGasUsed(0L) .buildHeader(); + Optional> maybeRequests; + if (maybeDeposits.isPresent() || maybeWithdrawalRequests.isPresent()) { + List requests = new ArrayList<>(); + maybeDeposits.ifPresent(requests::addAll); + maybeWithdrawalRequests.ifPresent(requests::addAll); + maybeRequests = Optional.of(requests); + } else { + maybeRequests = Optional.empty(); + } + BlockHeader mockHeader = new BlockHeaderTestFixture() .baseFeePerGas(Wei.ONE) @@ -284,9 +293,7 @@ protected BlockHeader createBlockHeader( .withdrawalsRoot(maybeWithdrawals.map(BodyValidation::withdrawalsRoot).orElse(null)) .excessBlobGas(BlobGas.ZERO) .blobGasUsed(0L) - .depositsRoot(maybeDeposits.map(BodyValidation::depositsRoot).orElse(null)) - .withdrawalRequestsRoot( - maybeWithdrawalRequests.map(BodyValidation::withdrawalRequestsRoot).orElse(null)) + .requestsRoot(maybeRequests.map(BodyValidation::requestsRoot).orElse(null)) .parentBeaconBlockRoot( maybeParentBeaconBlockRoot.isPresent() ? maybeParentBeaconBlockRoot : null) .buildHeader(); @@ -302,4 +309,25 @@ protected JsonRpcResponse resp(final EnginePayloadParameter payload) { return method.response( new JsonRpcRequestContext(new JsonRpcRequest("2.0", this.method.getName(), params))); } + + private void mockProhibitedRequestsValidator() { + var validator = new RequestsValidatorCoordinator.Builder().build(); + when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(validator); + } + + private void mockAllowedDepositsRequestValidator() { + var validator = + new RequestsValidatorCoordinator.Builder() + .addValidator(RequestType.DEPOSIT, new DepositsValidator(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); + } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueriesLogCacheTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueriesLogCacheTest.java index 41abccf54b7..0d77d2ceb1a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueriesLogCacheTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueriesLogCacheTest.java @@ -117,7 +117,6 @@ public void setup() { null, null, null, - null, new MainnetBlockHeaderFunctions()); testHash = fakeHeader.getHash(); final BlockBody fakeBody = new BlockBody(Collections.emptyList(), Collections.emptyList()); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/cache/TransactionLogBloomCacherTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/cache/TransactionLogBloomCacherTest.java index 293c0b176ea..5772a04a49d 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/cache/TransactionLogBloomCacherTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/cache/TransactionLogBloomCacherTest.java @@ -108,7 +108,6 @@ public void setup() throws IOException { null, null, null, - null, new MainnetBlockHeaderFunctions()); testHash = fakeHeader.getHash(); when(blockchain.getBlockHeader(anyLong())).thenReturn(Optional.of(fakeHeader)); @@ -284,7 +283,6 @@ private BlockHeader createBlock(final long number, final Optional messag null, null, null, - null, new MainnetBlockHeaderFunctions()); testHash = fakeHeader.getHash(); when(blockchain.getBlockHeader(number)).thenReturn(Optional.of(fakeHeader)); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 9efc616286c..15f3b16d89a 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -29,32 +29,28 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; -import org.hyperledger.besu.ethereum.core.Deposit; import org.hyperledger.besu.ethereum.core.Difficulty; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.SealableBlockHeader; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Withdrawal; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; -import org.hyperledger.besu.ethereum.core.encoding.DepositDecoder; import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor; import org.hyperledger.besu.ethereum.mainnet.BodyValidation; -import org.hyperledger.besu.ethereum.mainnet.DepositsValidator; import org.hyperledger.besu.ethereum.mainnet.DifficultyCalculator; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestContractHelper; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidator; import org.hyperledger.besu.ethereum.mainnet.WithdrawalsProcessor; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator; import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.plugin.services.exception.StorageException; @@ -68,7 +64,6 @@ import java.util.concurrent.CancellationException; import java.util.concurrent.atomic.AtomicBoolean; -import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; @@ -92,7 +87,6 @@ public interface ExtraDataCalculator { protected final ProtocolSchedule protocolSchedule; protected final BlockHeaderFunctions blockHeaderFunctions; protected final BlockHeader parentHeader; - private final Optional
depositContractAddress; private final EthScheduler ethScheduler; private final AtomicBoolean isCancelled = new AtomicBoolean(false); @@ -104,7 +98,6 @@ protected AbstractBlockCreator( final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, final BlockHeader parentHeader, - final Optional
depositContractAddress, final EthScheduler ethScheduler) { this.miningParameters = miningParameters; this.miningBeneficiaryCalculator = miningBeneficiaryCalculator; @@ -113,7 +106,6 @@ protected AbstractBlockCreator( this.protocolContext = protocolContext; this.protocolSchedule = protocolSchedule; this.parentHeader = parentHeader; - this.depositContractAddress = depositContractAddress; this.ethScheduler = ethScheduler; blockHeaderFunctions = ScheduleBasedBlockHeaderFunctions.create(protocolSchedule); } @@ -246,24 +238,13 @@ protected BlockCreationResult createBlock( throwIfStopped(); - final DepositsValidator depositsValidator = newProtocolSpec.getDepositsValidator(); - Optional> maybeDeposits = Optional.empty(); - if (depositsValidator instanceof DepositsValidator.AllowedDeposits - && depositContractAddress.isPresent()) { - maybeDeposits = Optional.of(findDepositsFromReceipts(transactionResults)); - } - - throwIfStopped(); - - final WithdrawalRequestValidator withdrawalRequestsValidator = - newProtocolSpec.getWithdrawalRequestValidator(); - Optional> maybeWithdrawalRequests = Optional.empty(); - if (withdrawalRequestsValidator.allowWithdrawalRequests()) { - maybeWithdrawalRequests = - Optional.of( - WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue( - disposableWorldState)); - } + // EIP-7685: process EL requests + final Optional requestProcessor = + newProtocolSpec.getRequestProcessorCoordinator(); + Optional> maybeRequests = + requestProcessor.flatMap( + processor -> + processor.process(disposableWorldState, transactionResults.getReceipts())); throwIfStopped(); @@ -301,9 +282,7 @@ protected BlockCreationResult createBlock( withdrawalsCanBeProcessed ? BodyValidation.withdrawalsRoot(maybeWithdrawals.get()) : null) - .depositsRoot(maybeDeposits.map(BodyValidation::depositsRoot).orElse(null)) - .withdrawalRequestsRoot( - maybeWithdrawalRequests.map(BodyValidation::withdrawalRequestsRoot).orElse(null)); + .requestsRoot(maybeRequests.map(BodyValidation::requestsRoot).orElse(null)); if (usage != null) { builder.blobGasUsed(usage.used.toLong()).excessBlobGas(usage.excessBlobGas); } @@ -316,11 +295,7 @@ protected BlockCreationResult createBlock( withdrawalsCanBeProcessed ? maybeWithdrawals : Optional.empty(); final BlockBody blockBody = new BlockBody( - transactionResults.getSelectedTransactions(), - ommers, - withdrawals, - maybeDeposits, - maybeWithdrawalRequests); + transactionResults.getSelectedTransactions(), ommers, withdrawals, maybeRequests); final Block block = new Block(blockHeader, blockBody); operationTracer.traceEndBlock(blockHeader, blockBody); @@ -336,15 +311,6 @@ protected BlockCreationResult createBlock( } } - @VisibleForTesting - List findDepositsFromReceipts(final TransactionSelectionResults transactionResults) { - return transactionResults.getReceipts().stream() - .flatMap(receipt -> receipt.getLogsList().stream()) - .filter(log -> depositContractAddress.get().equals(log.getLogger())) - .map(DepositDecoder::decodeFromLog) - .toList(); - } - record GasUsage(BlobGas excessBlobGas, BlobGas used) {} private GasUsage computeExcessBlobGas( diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java index 9cf12920701..39b055e817c 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreator.java @@ -55,7 +55,6 @@ public PoWBlockCreator( protocolContext, protocolSchedule, parentHeader, - Optional.empty(), ethScheduler); this.nonceSolver = nonceSolver; diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java index 77270065763..00576d493f8 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java @@ -16,7 +16,7 @@ import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSpecs.DEFAULT_DEPOSIT_CONTRACT_ADDRESS; +import static org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor.DEFAULT_DEPOSIT_CONTRACT_ADDRESS; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; @@ -36,11 +36,11 @@ import org.hyperledger.besu.datatypes.BlobsWithCommitments; import org.hyperledger.besu.datatypes.GWei; 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.ProtocolContext; import org.hyperledger.besu.ethereum.blockcreation.BlockCreator.BlockCreationResult; -import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults; import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; import org.hyperledger.besu.ethereum.core.BlobTestFixture; @@ -54,6 +54,7 @@ import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters.MutableInitValues; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.SealableBlockHeader; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; @@ -69,12 +70,15 @@ import org.hyperledger.besu.ethereum.eth.transactions.sorter.AbstractPendingTransactionsSorter; import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter; import org.hyperledger.besu.ethereum.mainnet.BodyValidation; -import org.hyperledger.besu.ethereum.mainnet.DepositsValidator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; import org.hyperledger.besu.ethereum.mainnet.WithdrawalsProcessor; import org.hyperledger.besu.ethereum.mainnet.feemarket.CancunFeeMarket; +import org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor; +import org.hyperledger.besu.ethereum.mainnet.requests.DepositsValidator; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.log.LogTopic; @@ -98,15 +102,11 @@ @ExtendWith(MockitoExtension.class) abstract class AbstractBlockCreatorTest { - private static final Optional
EMPTY_DEPOSIT_CONTRACT_ADDRESS = Optional.empty(); @Mock private WithdrawalsProcessor withdrawalsProcessor; protected EthScheduler ethScheduler = new DeterministicEthScheduler(); @Test void findDepositsFromReceipts() { - final AbstractBlockCreator blockCreator = - blockCreatorWithAllowedDeposits(Optional.of(DEFAULT_DEPOSIT_CONTRACT_ADDRESS)); - final TransactionSelectionResults transactionResults = mock(TransactionSelectionResults.class); BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); TransactionReceipt receiptWithoutDeposit1 = blockDataGenerator.receipt(); TransactionReceipt receiptWithoutDeposit2 = blockDataGenerator.receipt(); @@ -119,8 +119,8 @@ void findDepositsFromReceipts() { LogTopic.fromHexString( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"))); final TransactionReceipt receiptWithDeposit = blockDataGenerator.receipt(List.of(depositLog)); - when(transactionResults.getReceipts()) - .thenReturn(List.of(receiptWithoutDeposit1, receiptWithDeposit, receiptWithoutDeposit2)); + List receipts = + List.of(receiptWithoutDeposit1, receiptWithDeposit, receiptWithoutDeposit2); Deposit expectedDeposit = new Deposit( @@ -134,16 +134,15 @@ void findDepositsFromReceipts() { UInt64.valueOf(539967)); final List expectedDeposits = List.of(expectedDeposit); - final List depositsFromReceipts = - blockCreator.findDepositsFromReceipts(transactionResults); - - assertThat(depositsFromReceipts).isEqualTo(expectedDeposits); + final Optional> depositsFromReceipts = + new DepositRequestProcessor(DEFAULT_DEPOSIT_CONTRACT_ADDRESS).process(null, receipts); + assertThat(depositsFromReceipts.get()).isEqualTo(expectedDeposits); } @Test void withAllowedDepositsAndContractAddress_DepositsAreParsed() { final AbstractBlockCreator blockCreator = - blockCreatorWithAllowedDeposits(Optional.of(DEFAULT_DEPOSIT_CONTRACT_ADDRESS)); + blockCreatorWithAllowedDeposits(DEFAULT_DEPOSIT_CONTRACT_ADDRESS); final BlockCreationResult blockCreationResult = blockCreator.createBlock( @@ -155,15 +154,15 @@ void withAllowedDepositsAndContractAddress_DepositsAreParsed() { 1L, false); - List deposits = emptyList(); - final Hash depositsRoot = BodyValidation.depositsRoot(deposits); - assertThat(blockCreationResult.getBlock().getHeader().getDepositsRoot()).hasValue(depositsRoot); - assertThat(blockCreationResult.getBlock().getBody().getDeposits()).hasValue(deposits); + List deposits = emptyList(); + final Hash requestsRoot = BodyValidation.requestsRoot(deposits); + assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).hasValue(requestsRoot); + assertThat(blockCreationResult.getBlock().getBody().getRequests()).hasValue(deposits); } @Test void withAllowedDepositsAndNoContractAddress_DepositsAreNotParsed() { - final AbstractBlockCreator blockCreator = blockCreatorWithAllowedDeposits(Optional.empty()); + final AbstractBlockCreator blockCreator = blockCreatorWithAllowedDeposits(null); final BlockCreationResult blockCreationResult = blockCreator.createBlock( @@ -175,8 +174,8 @@ void withAllowedDepositsAndNoContractAddress_DepositsAreNotParsed() { 1L, false); - assertThat(blockCreationResult.getBlock().getHeader().getDepositsRoot()).isEmpty(); - assertThat(blockCreationResult.getBlock().getBody().getDeposits()).isEmpty(); + assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).isEmpty(); + assertThat(blockCreationResult.getBlock().getBody().getRequests()).isEmpty(); } @Test @@ -193,28 +192,36 @@ void withProhibitedDeposits_DepositsAreNotParsed() { 1L, false); - assertThat(blockCreationResult.getBlock().getHeader().getDepositsRoot()).isEmpty(); - assertThat(blockCreationResult.getBlock().getBody().getDeposits()).isEmpty(); + assertThat(blockCreationResult.getBlock().getHeader().getRequestsRoot()).isEmpty(); + assertThat(blockCreationResult.getBlock().getBody().getRequests()).isEmpty(); } private AbstractBlockCreator blockCreatorWithAllowedDeposits( - final Optional
depositContractAddress) { + final Address depositContractAddress) { final ProtocolSpecAdapters protocolSpecAdapters = ProtocolSpecAdapters.create( 0, specBuilder -> - specBuilder.depositsValidator( - new DepositsValidator.AllowedDeposits(depositContractAddress.orElse(null)))); - return createBlockCreator(protocolSpecAdapters, depositContractAddress); + specBuilder + .requestsValidator( + new RequestsValidatorCoordinator.Builder() + .addValidator( + RequestType.DEPOSIT, + new DepositsValidator((depositContractAddress))) + .build()) + .requestProcessorCoordinator( + new RequestProcessorCoordinator.Builder() + .addProcessor( + RequestType.DEPOSIT, + new DepositRequestProcessor(depositContractAddress)) + .build())); + return createBlockCreator(protocolSpecAdapters); } private AbstractBlockCreator blockCreatorWithProhibitedDeposits() { final ProtocolSpecAdapters protocolSpecAdapters = - ProtocolSpecAdapters.create( - 0, - specBuilder -> - specBuilder.depositsValidator(new DepositsValidator.ProhibitedDeposits())); - return createBlockCreator(protocolSpecAdapters, Optional.of(DEFAULT_DEPOSIT_CONTRACT_ADDRESS)); + ProtocolSpecAdapters.create(0, specBuilder -> specBuilder); + return createBlockCreator(protocolSpecAdapters); } @Test @@ -336,23 +343,21 @@ private AbstractBlockCreator blockCreatorWithBlobGasSupport() { specBuilder.withdrawalsProcessor(withdrawalsProcessor); return specBuilder; }); - return createBlockCreator(protocolSpecAdapters, EMPTY_DEPOSIT_CONTRACT_ADDRESS); + return createBlockCreator(protocolSpecAdapters); } private AbstractBlockCreator blockCreatorWithWithdrawalsProcessor() { final ProtocolSpecAdapters protocolSpecAdapters = ProtocolSpecAdapters.create( 0, specBuilder -> specBuilder.withdrawalsProcessor(withdrawalsProcessor)); - return createBlockCreator(protocolSpecAdapters, EMPTY_DEPOSIT_CONTRACT_ADDRESS); + return createBlockCreator(protocolSpecAdapters); } private AbstractBlockCreator blockCreatorWithoutWithdrawalsProcessor() { - return createBlockCreator(new ProtocolSpecAdapters(Map.of()), EMPTY_DEPOSIT_CONTRACT_ADDRESS); + return createBlockCreator(new ProtocolSpecAdapters(Map.of())); } - private AbstractBlockCreator createBlockCreator( - final ProtocolSpecAdapters protocolSpecAdapters, - final Optional
depositContractAddress) { + private AbstractBlockCreator createBlockCreator(final ProtocolSpecAdapters protocolSpecAdapters) { final GenesisConfigOptions genesisConfigOptions = GenesisConfigFile.DEFAULT.getConfigOptions(); final ExecutionContextTestFixture executionContextTestFixture = ExecutionContextTestFixture.builder() @@ -409,7 +414,6 @@ private AbstractBlockCreator createBlockCreator( executionContextTestFixture.getProtocolContext(), executionContextTestFixture.getProtocolSchedule(), blockchain.getChainHeadHeader(), - depositContractAddress, ethScheduler); } @@ -423,7 +427,6 @@ protected TestBlockCreator( final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule, final BlockHeader parentHeader, - final Optional
depositContractAddress, final EthScheduler ethScheduler) { super( miningParameters, @@ -433,7 +436,6 @@ protected TestBlockCreator( protocolContext, protocolSchedule, parentHeader, - depositContractAddress, ethScheduler); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingOutputs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingOutputs.java index b72268c6b07..4064b1ef119 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingOutputs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockProcessingOutputs.java @@ -15,24 +15,30 @@ package org.hyperledger.besu.ethereum; import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import java.util.ArrayList; import java.util.List; +import java.util.Optional; public class BlockProcessingOutputs { private final MutableWorldState worldState; private final List receipts; + private final Optional> maybeRequests; public BlockProcessingOutputs( final MutableWorldState worldState, final List receipts) { - this.worldState = worldState; - this.receipts = receipts; + this(worldState, receipts, Optional.empty()); } - public static BlockProcessingOutputs empty() { - return new BlockProcessingOutputs(null, new ArrayList<>()); + public BlockProcessingOutputs( + final MutableWorldState worldState, + final List receipts, + final Optional> maybeRequests) { + this.worldState = worldState; + this.receipts = receipts; + this.maybeRequests = maybeRequests; } public MutableWorldState getWorldState() { @@ -42,4 +48,8 @@ public MutableWorldState getWorldState() { public List getReceipts() { return receipts; } + + public Optional> getRequests() { + return maybeRequests; + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidator.java index bed189c4935..dc4c071ec11 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/BlockValidator.java @@ -15,10 +15,12 @@ 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.HeaderValidationMode; import java.util.List; +import java.util.Optional; public interface BlockValidator { @@ -47,6 +49,7 @@ boolean fastBlockValidation( final ProtocolContext context, final Block block, final List receipts, + final Optional> requests, final HeaderValidationMode headerValidationMode, final HeaderValidationMode ommerValidationMode); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java index 4938b653534..1b2847d08c4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.mainnet.BlockBodyValidator; import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; @@ -144,15 +145,17 @@ public BlockProcessingResult validateAndProcessBlock( } else { List receipts = result.getYield().map(BlockProcessingOutputs::getReceipts).orElse(new ArrayList<>()); + Optional> maybeRequests = + result.getYield().flatMap(BlockProcessingOutputs::getRequests); if (!blockBodyValidator.validateBody( - context, block, receipts, worldState.rootHash(), ommerValidationMode)) { + context, block, receipts, maybeRequests, worldState.rootHash(), ommerValidationMode)) { result = new BlockProcessingResult("failed to validate output of imported block"); handleFailedBlockProcessing(block, result, shouldRecordBadBlock); return result; } return new BlockProcessingResult( - Optional.of(new BlockProcessingOutputs(worldState, receipts))); + Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests))); } } catch (MerkleTrieException ex) { context @@ -226,6 +229,7 @@ public boolean fastBlockValidation( final ProtocolContext context, final Block block, final List receipts, + final Optional> requests, final HeaderValidationMode headerValidationMode, final HeaderValidationMode ommerValidationMode) { final BlockHeader header = block.getHeader(); @@ -235,7 +239,8 @@ public boolean fastBlockValidation( return false; } - if (!blockBodyValidator.validateBodyLight(context, block, receipts, ommerValidationMode)) { + if (!blockBodyValidator.validateBodyLight( + context, block, receipts, requests, ommerValidationMode)) { badBlockManager.addBadBlock( block, BadBlockCause.fromValidationFailure("Failed body validation (light)")); return false; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java index 5b3bf4e4c3a..ae9acc89a69 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java @@ -27,11 +27,10 @@ import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; -import org.hyperledger.besu.ethereum.core.Deposit; 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.core.WithdrawalRequest; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; @@ -149,12 +148,10 @@ public static GenesisState fromConfig( private static BlockBody buildBody(final GenesisConfigFile config) { final Optional> withdrawals = isShanghaiAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty(); - final Optional> deposits = - isExperimentalEipsTimeAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty(); - final Optional> withdrawalRequests = + final Optional> requests = isPragueAtGenesis(config) ? Optional.of(emptyList()) : Optional.empty(); - return new BlockBody(emptyList(), emptyList(), withdrawals, deposits, withdrawalRequests); + return new BlockBody(emptyList(), emptyList(), withdrawals, requests); } public Block getBlock() { @@ -226,7 +223,7 @@ private static BlockHeader buildHeader( .excessBlobGas(isCancunAtGenesis(genesis) ? parseExcessBlobGas(genesis) : null) .parentBeaconBlockRoot( (isCancunAtGenesis(genesis) ? parseParentBeaconBlockRoot(genesis) : null)) - .depositsRoot(isExperimentalEipsTimeAtGenesis(genesis) ? Hash.EMPTY_TRIE_HASH : null) + .requestsRoot(isPragueAtGenesis(genesis) ? Hash.EMPTY_TRIE_HASH : null) .buildBlockHeader(); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Block.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Block.java index 70265f0de58..3c90f77d320 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Block.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Block.java @@ -62,10 +62,7 @@ public void writeTo(final RLPOutput out) { out.writeList(body.getTransactions(), Transaction::writeTo); out.writeList(body.getOmmers(), BlockHeader::writeTo); body.getWithdrawals().ifPresent(withdrawals -> out.writeList(withdrawals, Withdrawal::writeTo)); - body.getDeposits().ifPresent(deposits -> out.writeList(deposits, Deposit::writeTo)); - body.getWithdrawalRequests() - .ifPresent( - withdrawalRequests -> out.writeList(withdrawalRequests, WithdrawalRequest::writeTo)); + body.getRequests().ifPresent(requests -> out.writeList(requests, Request::writeTo)); out.endList(); } @@ -77,16 +74,11 @@ public static Block readFrom(final RLPInput in, final BlockHeaderFunctions hashF final List ommers = in.readList(rlp -> BlockHeader.readFrom(rlp, hashFunction)); final Optional> withdrawals = in.isEndOfCurrentList() ? Optional.empty() : Optional.of(in.readList(Withdrawal::readFrom)); - final Optional> deposits = - in.isEndOfCurrentList() ? Optional.empty() : Optional.of(in.readList(Deposit::readFrom)); - final Optional> withdrawalRequests = - in.isEndOfCurrentList() - ? Optional.empty() - : Optional.of(in.readList(WithdrawalRequest::readFrom)); + final Optional> requests = + in.isEndOfCurrentList() ? Optional.empty() : Optional.of(in.readList(Request::readFrom)); in.leaveList(); - return new Block( - header, new BlockBody(transactions, ommers, withdrawals, deposits, withdrawalRequests)); + return new Block(header, new BlockBody(transactions, ommers, withdrawals, requests)); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockBody.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockBody.java index 545a17ac3ef..c14722edc24 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockBody.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockBody.java @@ -37,28 +37,24 @@ public class BlockBody implements org.hyperledger.besu.plugin.data.BlockBody { private final List ommers; private final Optional> withdrawals; - private final Optional> deposits; - private final Optional> withdrawalRequests; + private final Optional> requests; public BlockBody(final List transactions, final List ommers) { this.transactions = transactions; this.ommers = ommers; this.withdrawals = Optional.empty(); - this.deposits = Optional.empty(); - this.withdrawalRequests = Optional.empty(); + this.requests = Optional.empty(); } public BlockBody( final List transactions, final List ommers, final Optional> withdrawals, - final Optional> deposits, - final Optional> withdrawalRequests) { + final Optional> requests) { this.transactions = transactions; this.ommers = ommers; this.withdrawals = withdrawals; - this.deposits = deposits; - this.withdrawalRequests = withdrawalRequests; + this.requests = requests; } public static BlockBody empty() { @@ -97,18 +93,8 @@ public Optional> getWithdrawals() { * @return The optional list of withdrawal requests included in the block. */ @Override - public Optional> getWithdrawalRequests() { - return withdrawalRequests; - } - - /** - * Returns the deposits of the block. - * - * @return The optional list of deposits included in the block. - */ - @Override - public Optional> getDeposits() { - return deposits; + public Optional> getRequests() { + return requests; } /** @@ -126,9 +112,7 @@ public void writeTo(final RLPOutput output) { output.writeList(getTransactions(), Transaction::writeTo); output.writeList(getOmmers(), BlockHeader::writeTo); withdrawals.ifPresent(withdrawals -> output.writeList(withdrawals, Withdrawal::writeTo)); - deposits.ifPresent(deposits -> output.writeList(deposits, Deposit::writeTo)); - withdrawalRequests.ifPresent( - withdrawalRequests -> output.writeList(withdrawalRequests, WithdrawalRequest::writeTo)); + requests.ifPresent(requests -> output.writeList(requests, Request::writeTo)); } public static BlockBody readWrappedBodyFrom( @@ -180,10 +164,7 @@ public static BlockBody readFrom( : Optional.of(input.readList(Withdrawal::readFrom)), input.isEndOfCurrentList() ? Optional.empty() - : Optional.of(input.readList(Deposit::readFrom)), - input.isEndOfCurrentList() - ? Optional.empty() - : Optional.of(input.readList(WithdrawalRequest::readFrom))); + : Optional.of(input.readList(Request::readFrom))); } @Override @@ -194,21 +175,19 @@ public boolean equals(final Object o) { return Objects.equals(transactions, blockBody.transactions) && Objects.equals(ommers, blockBody.ommers) && Objects.equals(withdrawals, blockBody.withdrawals) - && Objects.equals(deposits, blockBody.deposits) - && Objects.equals(withdrawalRequests, blockBody.withdrawalRequests); + && Objects.equals(requests, blockBody.requests); } @Override public int hashCode() { - return Objects.hash(transactions, ommers, withdrawals, deposits, withdrawalRequests); + return Objects.hash(transactions, ommers, withdrawals, requests); } public boolean isEmpty() { return transactions.isEmpty() && ommers.isEmpty() && withdrawals.isEmpty() - && deposits.isEmpty() - && withdrawalRequests.isEmpty(); + && requests.isEmpty(); } @Override @@ -220,11 +199,8 @@ public String toString() { + ommers + ", withdrawals=" + withdrawals - + ", deposits=" - + deposits - + ", withdrawal_requests=" + ", withdrawal_requests=" - + withdrawalRequests + + requests + '}'; } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java index 69625bf892e..f12024e11a1 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java @@ -64,8 +64,7 @@ public BlockHeader( final Long blobGasUsed, final BlobGas excessBlobGas, final Bytes32 parentBeaconBlockRoot, - final Hash depositsRoot, - final Hash exitsRoot, + final Hash requestsRoot, final BlockHeaderFunctions blockHeaderFunctions) { super( parentHash, @@ -87,8 +86,7 @@ public BlockHeader( blobGasUsed, excessBlobGas, parentBeaconBlockRoot, - depositsRoot, - exitsRoot); + requestsRoot); this.nonce = nonce; this.hash = Suppliers.memoize(() -> blockHeaderFunctions.hash(this)); this.parsedExtraData = Suppliers.memoize(() -> blockHeaderFunctions.parseExtraData(this)); @@ -173,11 +171,8 @@ public void writeTo(final RLPOutput out) { if (parentBeaconBlockRoot != null) { out.writeBytes(parentBeaconBlockRoot); } - if (depositsRoot != null) { - out.writeBytes(depositsRoot); - } - if (withdrawalRequestsRoot != null) { - out.writeBytes(withdrawalRequestsRoot); + if (requestsRoot != null) { + out.writeBytes(requestsRoot); } out.endList(); } @@ -209,9 +204,7 @@ public static BlockHeader readFrom( final BlobGas excessBlobGas = !input.isEndOfCurrentList() ? BlobGas.of(input.readUInt64Scalar()) : null; final Bytes32 parentBeaconBlockRoot = !input.isEndOfCurrentList() ? input.readBytes32() : null; - final Hash depositHashRoot = - !input.isEndOfCurrentList() ? Hash.wrap(input.readBytes32()) : null; - final Hash exitsHashRoot = !input.isEndOfCurrentList() ? Hash.wrap(input.readBytes32()) : null; + final Hash requestsRoot = !input.isEndOfCurrentList() ? Hash.wrap(input.readBytes32()) : null; input.leaveList(); return new BlockHeader( parentHash, @@ -234,8 +227,7 @@ public static BlockHeader readFrom( blobGasUsed, excessBlobGas, parentBeaconBlockRoot, - depositHashRoot, - exitsHashRoot, + requestsRoot, blockHeaderFunctions); } @@ -286,11 +278,8 @@ public String toString() { if (parentBeaconBlockRoot != null) { sb.append("parentBeaconBlockRoot=").append(parentBeaconBlockRoot).append(", "); } - if (depositsRoot != null) { - sb.append("depositsRoot=").append(depositsRoot); - } - if (withdrawalRequestsRoot != null) { - sb.append("exitsRoot=").append(withdrawalRequestsRoot); + if (requestsRoot != null) { + sb.append("requestsRoot=").append(requestsRoot); } return sb.append("}").toString(); } @@ -323,11 +312,7 @@ public static org.hyperledger.besu.ethereum.core.BlockHeader convertPluginBlockH pluginBlockHeader.getExcessBlobGas().map(BlobGas::fromQuantity).orElse(null), pluginBlockHeader.getParentBeaconBlockRoot().orElse(null), pluginBlockHeader - .getDepositsRoot() - .map(h -> Hash.fromHexString(h.toHexString())) - .orElse(null), - pluginBlockHeader - .getWithdrawalRequestsRoot() + .getRequestsRoot() .map(h -> Hash.fromHexString(h.toHexString())) .orElse(null), blockHeaderFunctions); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java index 42da0fd8758..6f485d19ced 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java @@ -45,8 +45,7 @@ public class BlockHeaderBuilder { private Hash transactionsRoot; private Hash withdrawalsRoot = null; - private Hash depositsRoot = null; - private Hash withdrawalRequests = null; + private Hash requestsRoot = null; private Hash receiptsRoot; @@ -125,8 +124,7 @@ public static BlockHeaderBuilder fromHeader(final BlockHeader header) { .blobGasUsed(header.getBlobGasUsed().orElse(null)) .excessBlobGas(header.getExcessBlobGas().orElse(null)) .parentBeaconBlockRoot(header.getParentBeaconBlockRoot().orElse(null)) - .depositsRoot(header.getDepositsRoot().orElse(null)) - .withdrawalRequestsRoot(header.getWithdrawalRequestsRoot().orElse(null)); + .requestsRoot(header.getRequestsRoot().orElse(null)); } public static BlockHeaderBuilder fromBuilder(final BlockHeaderBuilder fromBuilder) { @@ -150,8 +148,7 @@ public static BlockHeaderBuilder fromBuilder(final BlockHeaderBuilder fromBuilde .withdrawalsRoot(fromBuilder.withdrawalsRoot) .excessBlobGas(fromBuilder.excessBlobGas) .parentBeaconBlockRoot(fromBuilder.parentBeaconBlockRoot) - .depositsRoot(fromBuilder.depositsRoot) - .withdrawalRequestsRoot(fromBuilder.withdrawalRequests) + .requestsRoot(fromBuilder.requestsRoot) .blockHeaderFunctions(fromBuilder.blockHeaderFunctions); toBuilder.nonce = fromBuilder.nonce; return toBuilder; @@ -181,8 +178,7 @@ public BlockHeader buildBlockHeader() { blobGasUsed, excessBlobGas, parentBeaconBlockRoot, - depositsRoot, - withdrawalRequests, + requestsRoot, blockHeaderFunctions); } @@ -224,8 +220,7 @@ public SealableBlockHeader buildSealableBlockHeader() { blobGasUsed, excessBlobGas, parentBeaconBlockRoot, - depositsRoot, - withdrawalRequests); + requestsRoot); } private void validateBlockHeader() { @@ -289,8 +284,7 @@ public BlockHeaderBuilder populateFrom(final SealableBlockHeader sealableBlockHe sealableBlockHeader.getBlobGasUsed().ifPresent(this::blobGasUsed); sealableBlockHeader.getExcessBlobGas().ifPresent(this::excessBlobGas); sealableBlockHeader.getParentBeaconBlockRoot().ifPresent(this::parentBeaconBlockRoot); - depositsRoot(sealableBlockHeader.getDepositsRoot().orElse(null)); - withdrawalRequestsRoot(sealableBlockHeader.getWithdrawalRequestsRoot().orElse(null)); + requestsRoot(sealableBlockHeader.getRequestsRoot().orElse(null)); return this; } @@ -405,13 +399,8 @@ public BlockHeaderBuilder withdrawalsRoot(final Hash hash) { return this; } - public BlockHeaderBuilder depositsRoot(final Hash hash) { - this.depositsRoot = hash; - return this; - } - - public BlockHeaderBuilder withdrawalRequestsRoot(final Hash hash) { - this.withdrawalRequests = hash; + public BlockHeaderBuilder requestsRoot(final Hash hash) { + this.requestsRoot = hash; return this; } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Deposit.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Deposit.java index 02fd36ad5da..6a6476069e3 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Deposit.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Deposit.java @@ -18,19 +18,14 @@ import org.hyperledger.besu.datatypes.BLSSignature; import org.hyperledger.besu.datatypes.GWei; import org.hyperledger.besu.datatypes.PublicKey; -import org.hyperledger.besu.ethereum.core.encoding.DepositDecoder; -import org.hyperledger.besu.ethereum.core.encoding.DepositEncoder; -import org.hyperledger.besu.ethereum.rlp.RLP; -import org.hyperledger.besu.ethereum.rlp.RLPInput; -import org.hyperledger.besu.ethereum.rlp.RLPOutput; +import org.hyperledger.besu.datatypes.RequestType; import java.util.Objects; -import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt64; -public class Deposit implements org.hyperledger.besu.plugin.data.Deposit { +public class Deposit extends Request implements org.hyperledger.besu.plugin.data.Deposit { private final BLSPublicKey pubkey; private final Bytes32 depositWithdrawalCredentials; @@ -51,16 +46,9 @@ public Deposit( this.index = index; } - public static Deposit readFrom(final Bytes rlpBytes) { - return readFrom(RLP.input(rlpBytes)); - } - - public static Deposit readFrom(final RLPInput rlpInput) { - return DepositDecoder.decode(rlpInput); - } - - public void writeTo(final RLPOutput out) { - DepositEncoder.encode(this, out); + @Override + public RequestType getType() { + return RequestType.DEPOSIT; } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Request.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Request.java new file mode 100644 index 00000000000..8f4ea64e314 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Request.java @@ -0,0 +1,41 @@ +/* + * 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.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 { + @Override + public abstract RequestType getType(); + + public static Request readFrom(final Bytes rlpBytes) { + return readFrom(RLP.input(rlpBytes)); + } + + public static Request readFrom(final RLPInput rlpInput) { + return RequestDecoder.decode(rlpInput); + } + + public void writeTo(final RLPOutput out) { + RequestEncoder.encode(this, out); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java index 8368c55f896..df3859f2b7c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java @@ -43,9 +43,7 @@ public class SealableBlockHeader extends ProcessableBlockHeader { protected final Hash withdrawalsRoot; - protected final Hash depositsRoot; - - protected final Hash withdrawalRequestsRoot; + protected final Hash requestsRoot; protected final Long blobGasUsed; @@ -71,8 +69,7 @@ protected SealableBlockHeader( final Long blobGasUsed, final BlobGas excessBlobGas, final Bytes32 parentBeaconBlockRoot, - final Hash depositsRoot, - final Hash withdrawalRequestsRoot) { + final Hash requestsRoot) { super( parentHash, coinbase, @@ -87,9 +84,8 @@ protected SealableBlockHeader( this.stateRoot = stateRoot; this.transactionsRoot = transactionsRoot; this.withdrawalsRoot = withdrawalsRoot; - this.depositsRoot = depositsRoot; this.receiptsRoot = receiptsRoot; - this.withdrawalRequestsRoot = withdrawalRequestsRoot; + this.requestsRoot = requestsRoot; this.logsBloom = logsBloom; this.gasUsed = gasUsed; this.extraData = extraData; @@ -170,16 +166,12 @@ public Optional getWithdrawalsRoot() { } /** - * Returns the block deposits root hash. + * Returns the block requests root hash. * - * @return the block deposits root hash + * @return the block requests root hash */ - public Optional getDepositsRoot() { - return Optional.ofNullable(depositsRoot); - } - - public Optional getWithdrawalRequestsRoot() { - return Optional.ofNullable(withdrawalRequestsRoot); + public Optional getRequestsRoot() { + return Optional.ofNullable(requestsRoot); } /** diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/WithdrawalRequest.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/WithdrawalRequest.java index dc6f8ace110..c9dbd0df67b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/WithdrawalRequest.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/WithdrawalRequest.java @@ -18,17 +18,12 @@ import org.hyperledger.besu.datatypes.BLSPublicKey; import org.hyperledger.besu.datatypes.GWei; import org.hyperledger.besu.datatypes.PublicKey; -import org.hyperledger.besu.ethereum.core.encoding.WithdrawalRequestDecoder; -import org.hyperledger.besu.ethereum.core.encoding.WithdrawalRequestEncoder; -import org.hyperledger.besu.ethereum.rlp.RLP; -import org.hyperledger.besu.ethereum.rlp.RLPInput; -import org.hyperledger.besu.ethereum.rlp.RLPOutput; +import org.hyperledger.besu.datatypes.RequestType; import java.util.Objects; -import org.apache.tuweni.bytes.Bytes; - -public class WithdrawalRequest implements org.hyperledger.besu.plugin.data.WithdrawalRequest { +public class WithdrawalRequest extends Request + implements org.hyperledger.besu.plugin.data.WithdrawalRequest { private final Address sourceAddress; private final BLSPublicKey validatorPubKey; @@ -41,16 +36,9 @@ public WithdrawalRequest( this.amount = amount; } - public static WithdrawalRequest readFrom(final Bytes rlpBytes) { - return readFrom(RLP.input(rlpBytes)); - } - - public static WithdrawalRequest readFrom(final RLPInput rlpInput) { - return WithdrawalRequestDecoder.decode(rlpInput); - } - - public void writeTo(final RLPOutput out) { - WithdrawalRequestEncoder.encode(this, out); + @Override + public RequestType getType() { + return RequestType.WITHDRAWAL; } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositEncoder.java index 0abdcc4e3c3..f40a28a6320 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/DepositEncoder.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.core.encoding; import org.hyperledger.besu.ethereum.core.Deposit; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPOutput; @@ -22,7 +23,10 @@ public class DepositEncoder { - public static void encode(final Deposit deposit, final RLPOutput rlpOutput) { + public static void encode(final Request request, final RLPOutput rlpOutput) { + if (!(request instanceof Deposit deposit)) { + throw new IllegalArgumentException("The provided request is not of type deposit."); + } rlpOutput.startList(); rlpOutput.writeBytes(deposit.getPubkey()); rlpOutput.writeBytes(deposit.getWithdrawalCredentials()); @@ -32,7 +36,7 @@ public static void encode(final Deposit deposit, final RLPOutput rlpOutput) { rlpOutput.endList(); } - public static Bytes encodeOpaqueBytes(final Deposit deposit) { + public static Bytes encodeOpaqueBytes(final Request deposit) { return RLP.encode(rlpOutput -> encode(deposit, rlpOutput)); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestDecoder.java new file mode 100644 index 00000000000..1eb85cc4aa8 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestDecoder.java @@ -0,0 +1,104 @@ +/* + * 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. + * + *

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 DECODERS = + ImmutableMap.of( + RequestType.WITHDRAWAL, + WithdrawalRequestDecoder::decode, + RequestType.DEPOSIT, + DepositDecoder::decode); + + /** + * Decodes a request from its RLP encoded bytes. + * + *

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 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); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestEncoder.java new file mode 100644 index 00000000000..d62d924a3cb --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/RequestEncoder.java @@ -0,0 +1,81 @@ +/* + * 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 ENCODERS = + ImmutableMap.of( + RequestType.WITHDRAWAL, + WithdrawalRequestEncoder::encode, + RequestType.DEPOSIT, + DepositEncoder::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); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoder.java index f9c8c41222f..7ade9947b44 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoder.java @@ -18,8 +18,11 @@ 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) { @@ -31,4 +34,8 @@ public static WithdrawalRequest decode(final RLPInput rlpInput) { return new WithdrawalRequest(sourceAddress, validatorPublicKey, amount); } + + public static WithdrawalRequest decodeOpaqueBytes(final Bytes input) { + return decode(RLP.input(input)); + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoder.java index 79d13cdab31..2a8fbb6eee4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestEncoder.java @@ -14,6 +14,8 @@ */ 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; @@ -22,7 +24,28 @@ public class WithdrawalRequestEncoder { - public static void encode(final WithdrawalRequest withdrawalRequest, final RLPOutput rlpOutput) { + /** + * 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()); @@ -30,7 +53,7 @@ public static void encode(final WithdrawalRequest withdrawalRequest, final RLPOu rlpOutput.endList(); } - public static Bytes encodeOpaqueBytes(final WithdrawalRequest exit) { - return RLP.encode(rlpOutput -> encode(exit, rlpOutput)); + public static Bytes encodeOpaqueBytes(final Request withdrawalRequest) { + return RLP.encode(rlpOutput -> encode(withdrawalRequest, rlpOutput)); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java index 0a3d38e87cf..923b2bdf96d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java @@ -24,11 +24,12 @@ import org.hyperledger.besu.ethereum.BlockProcessingResult; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Deposit; import org.hyperledger.besu.ethereum.core.MutableWorldState; +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.Withdrawal; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestProcessorCoordinator; import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.trie.MerkleTrieException; @@ -97,7 +98,6 @@ public BlockProcessingResult processBlock( final List transactions, final List ommers, final Optional> maybeWithdrawals, - final Optional> maybeDeposits, final PrivateMetadataUpdater privateMetadataUpdater) { final List receipts = new ArrayList<>(); long currentGasUsed = 0; @@ -192,10 +192,12 @@ public BlockProcessingResult processBlock( } } - final WithdrawalRequestValidator exitsValidator = protocolSpec.getWithdrawalRequestValidator(); - if (exitsValidator.allowWithdrawalRequests()) { - // Performing system-call logic - WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState); + // EIP-7685: process EL requests + final Optional requestProcessor = + protocolSpec.getRequestProcessorCoordinator(); + Optional> maybeRequests = Optional.empty(); + if (requestProcessor.isPresent()) { + maybeRequests = requestProcessor.get().process(worldState, receipts); } if (!rewardCoinbase(worldState, blockHeader, ommers, skipZeroBlockRewards)) { @@ -219,7 +221,8 @@ public BlockProcessingResult processBlock( return new BlockProcessingResult(Optional.empty(), e); } - return new BlockProcessingResult(Optional.of(new BlockProcessingOutputs(worldState, receipts))); + return new BlockProcessingResult( + Optional.of(new BlockProcessingOutputs(worldState, receipts, maybeRequests))); } protected boolean hasAvailableBlockBudget( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BaseFeeBlockBodyValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BaseFeeBlockBodyValidator.java index 62629dde665..0e288185cfc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BaseFeeBlockBodyValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BaseFeeBlockBodyValidator.java @@ -18,6 +18,7 @@ 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; @@ -41,9 +42,10 @@ public boolean validateBodyLight( final ProtocolContext context, final Block block, final List receipts, + final Optional> requests, final HeaderValidationMode ommerValidationMode) { - return super.validateBodyLight(context, block, receipts, ommerValidationMode) + return super.validateBodyLight(context, block, receipts, requests, ommerValidationMode) && validateTransactionGasPrice(block); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockBodyValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockBodyValidator.java index e063c584fd2..62b4985f5ca 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockBodyValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockBodyValidator.java @@ -17,9 +17,11 @@ 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 { @@ -39,6 +41,7 @@ boolean validateBody( ProtocolContext context, Block block, List receipts, + Optional> requests, Hash worldStateRootHash, final HeaderValidationMode ommerValidationMode); @@ -55,5 +58,6 @@ boolean validateBodyLight( ProtocolContext context, Block block, List receipts, + final Optional> requests, final HeaderValidationMode ommerValidationMode); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockProcessor.java index 060bce5bd77..d9f2e7874cc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BlockProcessor.java @@ -19,7 +19,6 @@ import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Deposit; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; @@ -83,7 +82,6 @@ default BlockProcessingResult processBlock( block.getBody().getTransactions(), block.getBody().getOmmers(), block.getBody().getWithdrawals(), - block.getBody().getDeposits(), null); } @@ -104,14 +102,7 @@ default BlockProcessingResult processBlock( final List transactions, final List ommers) { return processBlock( - blockchain, - worldState, - blockHeader, - transactions, - ommers, - Optional.empty(), - Optional.empty(), - null); + blockchain, worldState, blockHeader, transactions, ommers, Optional.empty(), null); } /** @@ -123,7 +114,6 @@ default BlockProcessingResult processBlock( * @param transactions the transactions in the block * @param ommers the block ommers * @param withdrawals the withdrawals for the block - * @param deposits the deposits for the block * @param privateMetadataUpdater the updater used to update the private metadata for the block * @return the block processing result */ @@ -134,7 +124,6 @@ BlockProcessingResult processBlock( List transactions, List ommers, Optional> withdrawals, - Optional> deposits, PrivateMetadataUpdater privateMetadataUpdater); /** diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidation.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidation.java index fd00ad47649..86392b86d6b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidation.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BodyValidation.java @@ -18,16 +18,14 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Deposit; +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.Withdrawal; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; -import org.hyperledger.besu.ethereum.core.encoding.DepositEncoder; 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.core.encoding.WithdrawalRequestEncoder; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.trie.MerkleTrie; import org.hyperledger.besu.ethereum.trie.patricia.SimpleMerklePatriciaTrie; @@ -91,36 +89,15 @@ public static Hash withdrawalsRoot(final List withdrawals) { } /** - * Generates the deposits root for a list of deposits + * Generates the request root for a list of requests * - * @param deposits the transactions - * @return the transaction root - */ - public static Hash depositsRoot(final List deposits) { - final MerkleTrie trie = trie(); - - IntStream.range(0, deposits.size()) - .forEach(i -> trie.put(indexKey(i), DepositEncoder.encodeOpaqueBytes(deposits.get(i)))); - - return Hash.wrap(trie.getRootHash()); - } - - /** - * Generates the withdrawal request root for a list of withdrawal request - * - * @param withdrawalRequests list of withdrawal request - * @return the withdrawal request root + * @param requests list of request + * @return the requests root */ - public static Hash withdrawalRequestsRoot(final List withdrawalRequests) { + public static Hash requestsRoot(final List requests) { final MerkleTrie trie = trie(); - - IntStream.range(0, withdrawalRequests.size()) - .forEach( - i -> - trie.put( - indexKey(i), - WithdrawalRequestEncoder.encodeOpaqueBytes(withdrawalRequests.get(i)))); - + IntStream.range(0, requests.size()) + .forEach(i -> trie.put(indexKey(i), RequestEncoder.encodeOpaqueBytes(requests.get(i)))); return Hash.wrap(trie.getRootHash()); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java deleted file mode 100644 index 670446b49b2..00000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidator.java +++ /dev/null @@ -1,145 +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.mainnet; - -import static com.google.common.base.Preconditions.checkArgument; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.Deposit; -import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import org.hyperledger.besu.ethereum.core.encoding.DepositDecoder; -import org.hyperledger.besu.evm.log.Log; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public interface DepositsValidator { - - boolean validateDepositParameter(Optional> deposits); - - boolean validateDeposits(Block block, List receipts); - - boolean validateDepositsRoot(Block block); - - class ProhibitedDeposits implements DepositsValidator { - - private static final Logger LOG = LoggerFactory.getLogger(ProhibitedDeposits.class); - - @Override - public boolean validateDepositParameter(final Optional> deposits) { - return deposits.isEmpty(); - } - - @Override - public boolean validateDeposits(final Block block, final List receipts) { - Optional> deposits = block.getBody().getDeposits(); - final boolean isValid = deposits.isEmpty(); - if (!isValid) { - LOG.warn("Deposits must be empty when Deposits are prohibited but were: {}", deposits); - } - return isValid; - } - - @Override - public boolean validateDepositsRoot(final Block block) { - final Optional depositsRoot = block.getHeader().getDepositsRoot(); - if (depositsRoot.isPresent()) { - LOG.warn( - "DepositsRoot must be null when Deposits are prohibited but was: {}", - depositsRoot.get()); - return false; - } - - return true; - } - } - - class AllowedDeposits implements DepositsValidator { - - private static final Logger LOG = LoggerFactory.getLogger(AllowedDeposits.class); - private final Address depositContractAddress; - - public AllowedDeposits(final Address depositContractAddress) { - this.depositContractAddress = depositContractAddress; - } - - @Override - public boolean validateDepositParameter(final Optional> deposits) { - return deposits.isPresent(); - } - - @Override - public boolean validateDeposits(final Block block, final List receipts) { - if (block.getBody().getDeposits().isEmpty()) { - LOG.warn("Deposits must not be empty when Deposits are activated"); - return false; - } - - List actualDeposits = new ArrayList<>(block.getBody().getDeposits().get()); - List expectedDeposits = new ArrayList<>(); - - for (TransactionReceipt receipt : receipts) { - for (Log log : receipt.getLogsList()) { - if (depositContractAddress.equals(log.getLogger())) { - Deposit deposit = DepositDecoder.decodeFromLog(log); - expectedDeposits.add(deposit); - } - } - } - - boolean isValid = actualDeposits.equals(expectedDeposits); - - if (!isValid) { - LOG.warn( - "Deposits validation failed. Deposits from block body do not match deposits from logs. Block hash: {}", - block.getHash()); - LOG.debug( - "Deposits from logs: {}, deposits from block body: {}", - expectedDeposits, - actualDeposits); - } - - return isValid; - } - - @Override - public boolean validateDepositsRoot(final Block block) { - checkArgument(block.getBody().getDeposits().isPresent(), "Block body must contain deposits"); - final Optional depositsRoot = block.getHeader().getDepositsRoot(); - if (depositsRoot.isEmpty()) { - LOG.warn("depositsRoot must not be null when Deposits are activated"); - return false; - } - - final List deposits = block.getBody().getDeposits().get(); - final Hash expectedDepositsRoot = BodyValidation.depositsRoot(deposits); - if (!expectedDepositsRoot.equals(depositsRoot.get())) { - LOG.info( - "Invalid block: depositsRoot mismatch (expected={}, actual={})", - expectedDepositsRoot, - depositsRoot.get()); - return false; - } - - return true; - } - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java index 1a263d808fe..3202440dd89 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java @@ -19,12 +19,14 @@ 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.core.WithdrawalRequest; +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 org.apache.tuweni.bytes.Bytes32; @@ -49,10 +51,11 @@ public boolean validateBody( final ProtocolContext context, final Block block, final List receipts, + final Optional> requests, final Hash worldStateRootHash, final HeaderValidationMode ommerValidationMode) { - if (!validateBodyLight(context, block, receipts, ommerValidationMode)) { + if (!validateBodyLight(context, block, receipts, requests, ommerValidationMode)) { return false; } @@ -73,6 +76,7 @@ public boolean validateBodyLight( final ProtocolContext context, final Block block, final List receipts, + final Optional> requests, final HeaderValidationMode ommerValidationMode) { final BlockHeader header = block.getHeader(); final BlockBody body = block.getBody(); @@ -105,16 +109,9 @@ public boolean validateBodyLight( return false; } - if (!validateDeposits(block, receipts)) { + if (!validateRequests(block, requests, receipts)) { return false; } - - if (body.getWithdrawalRequests().isPresent()) { - if (!validateWithdrawalRequests(block, body.getWithdrawalRequests().get())) { - return false; - } - } - return true; } @@ -316,25 +313,12 @@ private boolean validateWithdrawals(final Block block) { return true; } - private boolean validateDeposits(final Block block, final List receipts) { - final DepositsValidator depositsValidator = - protocolSchedule.getByBlockHeader(block.getHeader()).getDepositsValidator(); - - if (!depositsValidator.validateDeposits(block, receipts)) { - return false; - } - - if (!depositsValidator.validateDepositsRoot(block)) { - return false; - } - - return true; - } - - private boolean validateWithdrawalRequests( - final Block block, final List withdrawalRequests) { - final WithdrawalRequestValidator withdrawalRequestValidator = - protocolSchedule.getByBlockHeader(block.getHeader()).getWithdrawalRequestValidator(); - return withdrawalRequestValidator.validateWithdrawalRequestsInBlock(block, withdrawalRequests); + private boolean validateRequests( + final Block block, + final Optional> requests, + final List receipts) { + final RequestsValidatorCoordinator requestValidator = + protocolSchedule.getByBlockHeader(block.getHeader()).getRequestsValidatorCoordinator(); + return requestValidator.validate(block, requests, receipts); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockImporter.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockImporter.java index 7af94d491de..62b708d33e6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockImporter.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockImporter.java @@ -65,7 +65,12 @@ public BlockImportResult fastImportBlock( final HeaderValidationMode ommerValidationMode) { if (blockValidator.fastBlockValidation( - context, block, receipts, headerValidationMode, ommerValidationMode)) { + context, + block, + receipts, + block.getBody().getRequests(), + headerValidationMode, + ommerValidationMode)) { context.getBlockchain().appendBlock(block, receipts); return new BlockImportResult(true); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java index 85d60c75598..ddfe263b266 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java @@ -14,6 +14,10 @@ */ package org.hyperledger.besu.ethereum.mainnet; +import static org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor.DEFAULT_DEPOSIT_CONTRACT_ADDRESS; +import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator.pragueRequestsProcessors; +import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator.pragueRequestsValidator; + import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.config.PowAlgorithm; import org.hyperledger.besu.datatypes.Address; @@ -23,7 +27,6 @@ import org.hyperledger.besu.ethereum.MainnetBlockValidator; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Deposit; import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.Transaction; @@ -101,9 +104,6 @@ public abstract class MainnetProtocolSpecs { private static final Wei CONSTANTINOPLE_BLOCK_REWARD = Wei.fromEth(2); - public static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS = - Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); - private MainnetProtocolSpecs() {} public static ProtocolSpecBuilder frontierDefinition( @@ -768,8 +768,8 @@ static ProtocolSpecBuilder pragueDefinition( SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES)) // use prague precompiled contracts .precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::prague) - .depositsValidator(new DepositsValidator.AllowedDeposits(depositContractAddress)) - .withdrawalRequestsValidator(new PragueWithdrawalRequestValidator()) + .requestsValidator(pragueRequestsValidator(depositContractAddress)) + .requestProcessorCoordinator(pragueRequestsProcessors(depositContractAddress)) .blockHashProcessor( new PragueBlockHashProcessor(genesisConfigOptions.getPragueTime().orElse(0))) .name("Prague"); @@ -913,7 +913,6 @@ public BlockProcessingResult processBlock( final List transactions, final List ommers, final Optional> withdrawals, - final Optional> deposits, final PrivateMetadataUpdater privateMetadataUpdater) { updateWorldStateForDao(worldState); return wrapped.processBlock( @@ -923,7 +922,6 @@ public BlockProcessingResult processBlock( transactions, ommers, withdrawals, - deposits, privateMetadataUpdater); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessor.java index 0db16f0c4db..abfdf3652e6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessor.java @@ -23,7 +23,6 @@ import org.hyperledger.besu.ethereum.BlockProcessingResult; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Deposit; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Withdrawal; @@ -90,7 +89,6 @@ public BlockProcessingResult processBlock( final List transactions, final List ommers, final Optional> withdrawals, - final Optional> deposits, final PrivateMetadataUpdater privateMetadataUpdater) { if (privateMetadataUpdater != null) { @@ -110,7 +108,6 @@ public BlockProcessingResult processBlock( transactions, ommers, withdrawals, - deposits, metadataUpdater); metadataUpdater.commit(); return result; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java index c8b4439a7c9..b364679aa8b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java @@ -21,6 +21,8 @@ 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.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.evm.EVM; import org.hyperledger.besu.evm.gascalculator.GasCalculator; @@ -76,8 +78,8 @@ public class ProtocolSpec { private final WithdrawalsValidator withdrawalsValidator; private final Optional withdrawalsProcessor; - private final DepositsValidator depositsValidator; - private final WithdrawalRequestValidator withdrawalRequestValidator; + private final RequestsValidatorCoordinator requestsValidatorCoordinator; + private final Optional requestProcessorCoordinator; private final BlockHashProcessor blockHashProcessor; private final boolean isPoS; private final boolean isReplayProtectionSupported; @@ -107,9 +109,9 @@ public class ProtocolSpec { * @param gasLimitCalculator the gas limit calculator to use. * @param feeMarket an {@link Optional} wrapping {@link FeeMarket} class if appropriate. * @param powHasher the proof-of-work hasher - * @param withdrawalsValidator the withdrawals validator to use * @param withdrawalsProcessor the Withdrawals processor to use - * @param depositsValidator the withdrawals validator to use + * @param requestsValidatorCoordinator 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 * @param isReplayProtectionSupported indicates whether the current spec supports replay @@ -140,8 +142,8 @@ public ProtocolSpec( final Optional powHasher, final WithdrawalsValidator withdrawalsValidator, final Optional withdrawalsProcessor, - final DepositsValidator depositsValidator, - final WithdrawalRequestValidator withdrawalRequestValidator, + final RequestsValidatorCoordinator requestsValidatorCoordinator, + final Optional requestProcessorCoordinator, final BlockHashProcessor blockHashProcessor, final boolean isPoS, final boolean isReplayProtectionSupported) { @@ -169,8 +171,8 @@ public ProtocolSpec( this.powHasher = powHasher; this.withdrawalsValidator = withdrawalsValidator; this.withdrawalsProcessor = withdrawalsProcessor; - this.depositsValidator = depositsValidator; - this.withdrawalRequestValidator = withdrawalRequestValidator; + this.requestsValidatorCoordinator = requestsValidatorCoordinator; + this.requestProcessorCoordinator = requestProcessorCoordinator; this.blockHashProcessor = blockHashProcessor; this.isPoS = isPoS; this.isReplayProtectionSupported = isReplayProtectionSupported; @@ -373,12 +375,12 @@ public Optional getWithdrawalsProcessor() { return withdrawalsProcessor; } - public DepositsValidator getDepositsValidator() { - return depositsValidator; + public RequestsValidatorCoordinator getRequestsValidatorCoordinator() { + return requestsValidatorCoordinator; } - public WithdrawalRequestValidator getWithdrawalRequestValidator() { - return withdrawalRequestValidator; + public Optional getRequestProcessorCoordinator() { + return requestProcessorCoordinator; } public BlockHashProcessor getBlockHashProcessor() { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java index 0d3b26e92b9..61fba7b1fdc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java @@ -26,12 +26,13 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; import org.hyperledger.besu.ethereum.core.BlockImporter; import org.hyperledger.besu.ethereum.core.PrivacyParameters; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidator.ProhibitedWithdrawalRequests; import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor; 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.RequestProcessorCoordinator; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator; import org.hyperledger.besu.evm.EVM; @@ -76,9 +77,9 @@ public class ProtocolSpecBuilder { private WithdrawalsValidator withdrawalsValidator = new WithdrawalsValidator.ProhibitedWithdrawals(); private WithdrawalsProcessor withdrawalsProcessor; - private DepositsValidator depositsValidator = new DepositsValidator.ProhibitedDeposits(); - private WithdrawalRequestValidator withdrawalRequestValidator = - new ProhibitedWithdrawalRequests(); + private RequestsValidatorCoordinator requestsValidatorCoordinator = + new RequestsValidatorCoordinator.Builder().build(); + private RequestProcessorCoordinator requestProcessorCoordinator; protected BlockHashProcessor blockHashProcessor; private FeeMarket feeMarket = FeeMarket.legacy(); private BadBlockManager badBlockManager; @@ -264,14 +265,15 @@ public ProtocolSpecBuilder withdrawalsProcessor(final WithdrawalsProcessor withd return this; } - public ProtocolSpecBuilder depositsValidator(final DepositsValidator depositsValidator) { - this.depositsValidator = depositsValidator; + public ProtocolSpecBuilder requestsValidator( + final RequestsValidatorCoordinator requestsValidatorCoordinator) { + this.requestsValidatorCoordinator = requestsValidatorCoordinator; return this; } - public ProtocolSpecBuilder withdrawalRequestsValidator( - final WithdrawalRequestValidator withdrawalRequestValidator) { - this.withdrawalRequestValidator = withdrawalRequestValidator; + public ProtocolSpecBuilder requestProcessorCoordinator( + final RequestProcessorCoordinator requestProcessorCoordinator) { + this.requestProcessorCoordinator = requestProcessorCoordinator; return this; } @@ -398,8 +400,8 @@ public ProtocolSpec build(final ProtocolSchedule protocolSchedule) { Optional.ofNullable(powHasher), withdrawalsValidator, Optional.ofNullable(withdrawalsProcessor), - depositsValidator, - withdrawalRequestValidator, + requestsValidatorCoordinator, + Optional.ofNullable(requestProcessorCoordinator), blockHashProcessor, isPoS, isReplayProtectionSupported); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java index 8a98c5dd8ad..5ef0a699893 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelper.java @@ -42,7 +42,7 @@ public class WithdrawalRequestContractHelper { public static final Address WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = - Address.fromHexString("0xEd8EA01d70Cb49726175BCf2778B9C982912e017"); + Address.fromHexString("0x00A3ca265EBcb825B45F985A16CEFB49958cE017"); @VisibleForTesting // Storage slot to store the difference between number of withdrawal requests since last block and @@ -65,10 +65,13 @@ public class WithdrawalRequestContractHelper { // How many slots each withdrawal request occupies in the account state private static final int WITHDRAWAL_REQUEST_STORAGE_SLOT_SIZE = 3; - @VisibleForTesting static final int MAX_WITHDRAWAL_REQUESTS_PER_BLOCK = 16; + public static final int MAX_WITHDRAWAL_REQUESTS_PER_BLOCK = 16; private static final int TARGET_WITHDRAWAL_REQUESTS_PER_BLOCK = 2; + private static final UInt256 INITIAL_EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT = + UInt256.valueOf(1181); + // TODO-lucas Add MIN_WITHDRAWAL_REQUEST_FEE and WITHDRAWAL_REQUEST_FEE_UPDATE_FRACTION /* @@ -166,8 +169,13 @@ private static List peekExpectedWithdrawalRequests( } private static void updateExcessWithdrawalRequests(final MutableAccount account) { - final UInt256 previousExcessRequests = + UInt256 previousExcessRequests = account.getStorageValue(EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT); + + if (previousExcessRequests.equals(INITIAL_EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT)) { + previousExcessRequests = UInt256.ZERO; + } + final UInt256 requestsCount = account.getStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT); UInt256 newExcessRequests = UInt256.valueOf(0L); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidator.java deleted file mode 100644 index 4423a5a3df4..00000000000 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidator.java +++ /dev/null @@ -1,80 +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.mainnet; - -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; - -import java.util.List; -import java.util.Optional; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public interface WithdrawalRequestValidator { - - boolean allowWithdrawalRequests(); - - boolean validateWithdrawalRequestParameter(Optional> withdrawalRequests); - - boolean validateWithdrawalRequestsInBlock( - Block block, List withdrawalRequests); - - /** Used before Prague */ - class ProhibitedWithdrawalRequests implements WithdrawalRequestValidator { - - private static final Logger LOG = LoggerFactory.getLogger(ProhibitedWithdrawalRequests.class); - - @Override - public boolean allowWithdrawalRequests() { - return false; - } - - /** - * Before Prague we do not expect to have execution layer withdrawal requests, so it is expected - * the optional parameter will be empty - * - * @param withdrawalRequests Optional list of withdrawal requests - * @return true, if valid, false otherwise - */ - @Override - public boolean validateWithdrawalRequestParameter( - final Optional> withdrawalRequests) { - return withdrawalRequests.isEmpty(); - } - - @Override - public boolean validateWithdrawalRequestsInBlock( - final Block block, final List withdrawalRequests) { - final Optional> maybeWithdrawalRequests = - block.getBody().getWithdrawalRequests(); - if (maybeWithdrawalRequests.isPresent()) { - LOG.warn( - "Block {} contains withdrawal requests but withdrawal requests are prohibited", - block.getHash()); - return false; - } - - if (block.getHeader().getWithdrawalRequestsRoot().isPresent()) { - LOG.warn( - "Block {} header contains withdrawal_requests_root but withdrawal requests are prohibited", - block.getHash()); - return false; - } - - return true; - } - } -} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestProcessor.java new file mode 100644 index 00000000000..16109946dfd --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositRequestProcessor.java @@ -0,0 +1,63 @@ +/* + * 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.mainnet.requests; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.ethereum.core.Deposit; +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.Request; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.core.encoding.DepositDecoder; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import com.google.common.annotations.VisibleForTesting; + +public class DepositRequestProcessor implements RequestProcessor { + + public static final Address DEFAULT_DEPOSIT_CONTRACT_ADDRESS = + Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); + + private final Optional

depositContractAddress; + + public DepositRequestProcessor(final Address depositContractAddress) { + this.depositContractAddress = Optional.ofNullable(depositContractAddress); + } + + @Override + public Optional> process( + final MutableWorldState ignored, final List transactionReceipts) { + if (depositContractAddress.isEmpty()) { + return Optional.empty(); + } + List deposits = findDepositsFromReceipts(transactionReceipts); + return Optional.of(deposits.stream().map(r -> (Request) r).toList()); + } + + @VisibleForTesting + List findDepositsFromReceipts(final List transactionReceipts) { + return depositContractAddress + .map( + address -> + transactionReceipts.stream() + .flatMap(receipt -> receipt.getLogsList().stream()) + .filter(log -> address.equals(log.getLogger())) + .map(DepositDecoder::decodeFromLog) + .toList()) + .orElse(Collections.emptyList()); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositsValidator.java new file mode 100644 index 00000000000..1c6c3ca21c8 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/DepositsValidator.java @@ -0,0 +1,81 @@ +/* + * 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.mainnet.requests; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.core.Deposit; +import org.hyperledger.besu.ethereum.core.Request; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.core.encoding.DepositDecoder; +import org.hyperledger.besu.evm.log.Log; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DepositsValidator implements RequestValidator { + + private static final Logger LOG = LoggerFactory.getLogger(DepositsValidator.class); + private final Address depositContractAddress; + + public DepositsValidator(final Address depositContractAddress) { + this.depositContractAddress = depositContractAddress; + } + + @Override + public boolean validateParameter(final Optional> deposits) { + return deposits.isPresent(); + } + + public boolean validateDeposits( + final Block block, + final List actualDeposits, + final List receipts) { + + List expectedDeposits = new ArrayList<>(); + + for (TransactionReceipt receipt : receipts) { + for (Log log : receipt.getLogsList()) { + if (depositContractAddress.equals(log.getLogger())) { + Deposit deposit = DepositDecoder.decodeFromLog(log); + expectedDeposits.add(deposit); + } + } + } + + boolean isValid = actualDeposits.equals(expectedDeposits); + + if (!isValid) { + LOG.warn( + "Deposits validation failed. Deposits from block body do not match deposits from logs. Block hash: {}", + block.getHash()); + LOG.debug( + "Deposits from logs: {}, deposits from block body: {}", expectedDeposits, actualDeposits); + } + + return isValid; + } + + @Override + public boolean validate( + final Block block, final List requests, final List receipts) { + var deposits = RequestUtil.filterRequestsOfType(requests, Deposit.class); + return validateDeposits(block, deposits, receipts); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java new file mode 100644 index 00000000000..9f9b4539d00 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/MainnetRequestsValidator.java @@ -0,0 +1,36 @@ +/* + * 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.mainnet.requests; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.RequestType; + +public class MainnetRequestsValidator { + public static RequestsValidatorCoordinator pragueRequestsValidator( + final Address depositContractAddress) { + return new RequestsValidatorCoordinator.Builder() + .addValidator(RequestType.WITHDRAWAL, new WithdrawalRequestValidator()) + .addValidator(RequestType.DEPOSIT, new DepositsValidator(depositContractAddress)) + .build(); + } + + public static RequestProcessorCoordinator pragueRequestsProcessors( + final Address depositContractAddress) { + return new RequestProcessorCoordinator.Builder() + .addProcessor(RequestType.WITHDRAWAL, new WithdrawalRequestProcessor()) + .addProcessor(RequestType.DEPOSIT, new DepositRequestProcessor(depositContractAddress)) + .build(); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestsValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestsValidator.java new file mode 100644 index 00000000000..362da527283 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/ProhibitedRequestsValidator.java @@ -0,0 +1,53 @@ +/* + * 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.mainnet.requests; + +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; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** Validates that a block does not contain any prohibited requests. */ +public class ProhibitedRequestsValidator implements RequestValidator { + private static final Logger LOG = LoggerFactory.getLogger(ProhibitedRequestsValidator.class); + + @Override + public boolean validate( + final Block block, final List request, final List receipts) { + boolean hasRequests = block.getBody().getRequests().isPresent(); + boolean hasRequestsRoot = block.getHeader().getRequestsRoot().isPresent(); + + if (hasRequests) { + LOG.warn("Block {} contains requests but requests are prohibited", block.getHash()); + } + + if (hasRequestsRoot) { + LOG.warn( + "Block {} header contains requests_root but requests are prohibited", block.getHash()); + } + + return !(hasRequests || hasRequestsRoot); + } + + @Override + public boolean validateParameter(final Optional> request) { + return request.isEmpty(); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessor.java new file mode 100644 index 00000000000..c365e0d754b --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessor.java @@ -0,0 +1,28 @@ +/* + * 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.mainnet.requests; + +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.Request; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; + +import java.util.List; +import java.util.Optional; + +public interface RequestProcessor { + Optional> process( + final MutableWorldState mutableWorldState, + final List transactionReceipts); +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessorCoordinator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessorCoordinator.java new file mode 100644 index 00000000000..b72674b4d24 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestProcessorCoordinator.java @@ -0,0 +1,71 @@ +/* + * 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.mainnet.requests; + +import org.hyperledger.besu.datatypes.RequestType; +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.Request; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import com.google.common.collect.ImmutableSortedMap; + +/** Processes various types of requests based on their RequestType. */ +public class RequestProcessorCoordinator { + private final ImmutableSortedMap processors; + + /** + * Constructs a RequestsProcessor with a given map of processors. + * + * @param processors A map associating RequestType with their corresponding RequestProcessor. + */ + private RequestProcessorCoordinator( + final ImmutableSortedMap processors) { + this.processors = processors; + } + + public Optional> process( + final MutableWorldState mutableWorldState, final List receipts) { + List requests = null; + for (RequestProcessor requestProcessor : processors.values()) { + var r = requestProcessor.process(mutableWorldState, receipts); + if (r.isPresent()) { + if (requests == null) { + requests = new ArrayList<>(); + } + requests.addAll(r.get()); + } + } + return Optional.ofNullable(requests); + } + + public static class Builder { + private final ImmutableSortedMap.Builder + requestProcessorBuilder = ImmutableSortedMap.naturalOrder(); + + public RequestProcessorCoordinator.Builder addProcessor( + final RequestType type, final RequestProcessor processor) { + this.requestProcessorBuilder.put(type, processor); + return this; + } + + public RequestProcessorCoordinator build() { + return new RequestProcessorCoordinator(requestProcessorBuilder.build()); + } + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestUtil.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestUtil.java new file mode 100644 index 00000000000..54478bfef85 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestUtil.java @@ -0,0 +1,54 @@ +/* + * 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.mainnet.requests; + +import org.hyperledger.besu.ethereum.core.Request; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +public class RequestUtil { + + /** + * Filters and returns a list of requests of a specific type from a given list of requests. + * + * @param The type of the request to filter by, extending Request. + * @param requests The list of requests to filter. + * @param requestType The class of the request type to filter for. + * @return A List containing only requests of the specified type, or an empty list if the input + * list is null or contains no requests of the specified type. + */ + public static List filterRequestsOfType( + final List requests, final Class requestType) { + if (requests == null) { + return Collections.emptyList(); + } + return requests.stream().filter(requestType::isInstance).map(requestType::cast).toList(); + } + + public static Optional> combine( + final Optional> maybeDeposits, + final Optional> maybeWithdrawalRequest) { + if (maybeDeposits.isEmpty() && maybeWithdrawalRequest.isEmpty()) { + return Optional.empty(); + } + List requests = new ArrayList<>(); + maybeDeposits.ifPresent(requests::addAll); + maybeWithdrawalRequest.ifPresent(requests::addAll); + return Optional.of(requests); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestValidator.java new file mode 100644 index 00000000000..74fd8cd7ebc --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestValidator.java @@ -0,0 +1,30 @@ +/* + * 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.mainnet.requests; + +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; + +/** Interface for request validation logic. */ +public interface RequestValidator { + boolean validate( + final Block block, final List request, final List receipts); + + boolean validateParameter(final Optional> request); +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestsValidatorCoordinator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestsValidatorCoordinator.java new file mode 100644 index 00000000000..f6800f95c3b --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/RequestsValidatorCoordinator.java @@ -0,0 +1,198 @@ +/* + * 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.mainnet.requests; + +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.RequestType; +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.BodyValidation; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import com.google.common.collect.ImmutableSortedMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Validates requests within a block against a set of predefined validators. This class delegates + * the validation of requests of specific types to corresponding validators. It ensures that + * requests are properly ordered, have a valid root, and meet the criteria defined by their + * validators. + */ +public class RequestsValidatorCoordinator { + private static final Logger LOG = LoggerFactory.getLogger(RequestsValidatorCoordinator.class); + private final ImmutableSortedMap validators; + + /** + * Constructs a new RequestsDelegateValidator with a mapping of request types to their respective + * validators. + * + * @param validators An immutable map of request types to their corresponding validators. + */ + private RequestsValidatorCoordinator( + final ImmutableSortedMap validators) { + this.validators = validators; + } + + /** + * Validates a block's requests by ensuring they are correctly ordered, have a valid root, and + * pass their respective type-specific validations. + * + * @param block The block containing the requests to be validated. + * @param maybeRequests The list of requests contained within the block. + * @param receipts The list of transaction receipts corresponding to the requests. + * @return true if all validations pass; false otherwise. + */ + public boolean validate( + final Block block, + final Optional> maybeRequests, + final List receipts) { + + if (validators.isEmpty()) { + return isRequestsEmpty(block, maybeRequests); + } + + if (!isRequestsRootValid(block, maybeRequests)) { + return false; + } + + if (!isRequestOrderValid(maybeRequests.get())) { + final Hash blockHash = block.getHash(); + LOG.warn("Block {} the ordering across requests must be ascending by type", blockHash); + return false; + } + return validateRequests(block, maybeRequests.get(), receipts); + } + + /** + * Validates the requests contained within a block against their respective type-specific + * validators. + * + * @param block The block containing the requests. + * @param requests The list of requests to be validated. + * @param receipts The list of transaction receipts corresponding to the requests. + * @return true if all requests pass their type-specific validations; false otherwise. + */ + private boolean validateRequests( + final Block block, final List requests, final List receipts) { + return requestTypes(requests).stream() + .allMatch(type -> validateRequestOfType(type, block, requests, receipts)); + } + + private boolean isRequestsRootValid(final Block block, final Optional> requests) { + final Hash blockHash = block.getHash(); + final Optional maybeRequestsRoot = block.getHeader().getRequestsRoot(); + + if (maybeRequestsRoot.isEmpty()) { + LOG.warn("Block {} must contain requests root", blockHash); + return false; + } + + if (block.getBody().getRequests().isEmpty()) { + LOG.warn("Block body {} must contain requests (even if empty list)", blockHash); + return false; + } + + if (requests.isEmpty()) { + LOG.warn("Block {} must contain requests (even if empty list)", blockHash); + return false; + } + + final Hash expectedRequestsRoot = BodyValidation.requestsRoot(requests.get()); + if (!expectedRequestsRoot.equals(maybeRequestsRoot.get())) { + LOG.warn( + "Block {} requests root does not match expected hash root for requests in block", + blockHash); + return false; + } + return true; + } + + private boolean isRequestsEmpty(final Block block, final Optional> requests) { + final Hash blockHash = block.getHash(); + final Optional maybeRequestsRoot = block.getHeader().getRequestsRoot(); + + if (maybeRequestsRoot.isPresent()) { + LOG.warn("Block {} must not contain requests root", blockHash); + return false; + } + + if (block.getBody().getRequests().isPresent()) { + LOG.warn("Block body {} must not contain requests", blockHash); + return false; + } + + if (requests.isPresent()) { + LOG.warn("Block {} must not contain requests", blockHash); + return false; + } + return true; + } + + private boolean validateRequestOfType( + final RequestType type, + final Block block, + final List requests, + final List receipts) { + + Optional requestValidator = getRequestValidator(type); + if (requestValidator.isEmpty()) { + LOG.warn("Block {} contains prohibited requests of type: {}", block.getHash(), type); + return false; + } + List typedRequests = filterRequestsOfType(requests, type); + return requestValidator.get().validate(block, typedRequests, receipts); + } + + public Optional getRequestValidator(final RequestType requestType) { + return Optional.ofNullable(validators.get(requestType)); + } + + private static Set requestTypes(final List requests) { + return requests.stream().map(Request::getType).collect(Collectors.toSet()); + } + + private static boolean isRequestOrderValid(final List requests) { + return IntStream.range(0, requests.size() - 1) + .allMatch(i -> requests.get(i).getType().compareTo(requests.get(i + 1).getType()) <= 0); + } + + private static List filterRequestsOfType( + final List requests, final RequestType type) { + return requests.stream() + .filter(request -> request.getType() == type) + .collect(Collectors.toList()); + } + + public static class Builder { + private final ImmutableSortedMap.Builder validatorsBuilder = + ImmutableSortedMap.naturalOrder(); + + public Builder addValidator(final RequestType type, final RequestValidator validator) { + this.validatorsBuilder.put(type, validator); + return this; + } + + public RequestsValidatorCoordinator build() { + return new RequestsValidatorCoordinator(validatorsBuilder.build()); + } + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java new file mode 100644 index 00000000000..f9c029d5153 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestProcessor.java @@ -0,0 +1,38 @@ +/* + * 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.mainnet.requests; + +import org.hyperledger.besu.ethereum.core.MutableWorldState; +import org.hyperledger.besu.ethereum.core.Request; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.core.WithdrawalRequest; +import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestContractHelper; + +import java.util.List; +import java.util.Optional; + +public class WithdrawalRequestProcessor implements RequestProcessor { + @Override + public Optional> process( + final MutableWorldState mutableWorldState, + final List transactionReceipts) { + + List withdrawalRequests = + WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(mutableWorldState).stream() + .toList(); + + return Optional.of(withdrawalRequests.stream().map(r -> (Request) r).toList()); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestValidator.java similarity index 60% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidator.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestValidator.java index dcebf313966..b1fc88196c9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/requests/WithdrawalRequestValidator.java @@ -12,50 +12,42 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.hyperledger.besu.ethereum.mainnet; +package org.hyperledger.besu.ethereum.mainnet.requests; import org.hyperledger.besu.datatypes.Hash; 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.core.WithdrawalRequest; +import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestContractHelper; +import java.util.Collections; import java.util.List; import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PragueWithdrawalRequestValidator implements WithdrawalRequestValidator { +public class WithdrawalRequestValidator implements RequestValidator { - private static final Logger LOG = LoggerFactory.getLogger(PragueWithdrawalRequestValidator.class); + private static final Logger LOG = LoggerFactory.getLogger(WithdrawalRequestValidator.class); - @Override - public boolean allowWithdrawalRequests() { - return true; - } - - @Override - public boolean validateWithdrawalRequestParameter( + private boolean validateWithdrawalRequestParameter( final Optional> withdrawalRequests) { return withdrawalRequests.isPresent(); } - @Override - public boolean validateWithdrawalRequestsInBlock( + private boolean validateWithdrawalRequestsInBlock( final Block block, final List withdrawalRequests) { final Hash blockHash = block.getHash(); - if (block.getHeader().getWithdrawalRequestsRoot().isEmpty()) { - LOG.warn("Block {} must contain withdrawal_requests_root", blockHash); - return false; - } - - if (block.getBody().getWithdrawalRequests().isEmpty()) { - LOG.warn("Block {} must contain withdrawal requests (even if empty list)", blockHash); - return false; - } - final List withdrawalRequestsInBlock = - block.getBody().getWithdrawalRequests().get(); + block + .getBody() + .getRequests() + .map(requests -> RequestUtil.filterRequestsOfType(requests, WithdrawalRequest.class)) + .orElse(Collections.emptyList()); + // TODO Do we need to allow for customization? (e.g. if the value changes in the next fork) if (withdrawalRequestsInBlock.size() > WithdrawalRequestContractHelper.MAX_WITHDRAWAL_REQUESTS_PER_BLOCK) { @@ -64,18 +56,7 @@ public boolean validateWithdrawalRequestsInBlock( return false; } - // Validate exits_root - final Hash expectedWithdrawalsRequestRoot = - BodyValidation.withdrawalRequestsRoot(withdrawalRequestsInBlock); - if (!expectedWithdrawalsRequestRoot.equals( - block.getHeader().getWithdrawalRequestsRoot().get())) { - LOG.warn( - "Block {} withdrawal_requests_root does not match expected hash root for withdrawal requests in block", - blockHash); - return false; - } - - // Validate exits + // Validate WithdrawalRequests final boolean expectedWithdrawalRequestMatch = withdrawalRequests.equals(withdrawalRequestsInBlock); if (!expectedWithdrawalRequestMatch) { @@ -87,7 +68,23 @@ public boolean validateWithdrawalRequestsInBlock( withdrawalRequests); return false; } - return true; } + + @Override + public boolean validate( + final Block block, final List requests, final List receipts) { + var withdrawalRequests = RequestUtil.filterRequestsOfType(requests, WithdrawalRequest.class); + return validateWithdrawalRequestsInBlock(block, withdrawalRequests); + } + + @Override + public boolean validateParameter(final Optional> request) { + if (request.isEmpty()) { + return false; + } + var withdrawalRequests = + RequestUtil.filterRequestsOfType(request.get(), WithdrawalRequest.class); + return validateWithdrawalRequestParameter(Optional.of(withdrawalRequests)); + } } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java index cafe8bb82e6..c5b797403a8 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java @@ -303,8 +303,7 @@ public BlockHeader header(final long number, final BlockBody body, final BlockOp .mixHash(hash()) .nonce(blockNonce) .withdrawalsRoot(options.getWithdrawalsRoot(null)) - .depositsRoot(options.getDepositsRoot(null)) - .withdrawalRequestsRoot(options.getWithdrawalRequestsRoot(null)) + .requestsRoot(options.getRequestsRoot(null)) .blockHeaderFunctions( options.getBlockHeaderFunctions(new MainnetBlockHeaderFunctions())); options.getBaseFee(Optional.of(Wei.of(uint256(2)))).ifPresent(blockHeaderBuilder::baseFee); @@ -333,8 +332,7 @@ public BlockBody body(final BlockOptions options) { options.getTransactions(defaultTxs), ommers, options.getWithdrawals(Optional.empty()), - options.getDeposits(Optional.empty()), - options.getWithdrawalRequests(Optional.empty())); + options.getRequests(Optional.empty())); } private BlockHeader ommer() { @@ -640,8 +638,7 @@ public static class BlockOptions { private final List ommers = new ArrayList<>(); private Optional>> withdrawals = Optional.empty(); - private Optional>> deposits = Optional.empty(); - private Optional>> withdrawalRequests = Optional.empty(); + private Optional>> requests = Optional.empty(); private Optional extraData = Optional.empty(); private Optional blockHeaderFunctions = Optional.empty(); private Optional receiptsRoot = Optional.empty(); @@ -657,8 +654,7 @@ public static class BlockOptions { private Optional> maybeBaseFee = Optional.empty(); private Optional withdrawalsRoot = Optional.empty(); - private Optional depositsRoot = Optional.empty(); - private Optional withdrawalRequestsRoot = Optional.empty(); + private Optional requestsRoot = Optional.empty(); private Optional> maybeMaxFeePerBlobGas = Optional.empty(); @@ -727,21 +723,12 @@ public Optional> getWithdrawals( return withdrawals.orElse(defaultValue); } - public Hash getDepositsRoot(final Hash defaultValue) { - return depositsRoot.orElse(defaultValue); + public Hash getRequestsRoot(final Hash defaultValue) { + return requestsRoot.orElse(defaultValue); } - public Optional> getDeposits(final Optional> defaultValue) { - return deposits.orElse(defaultValue); - } - - public Hash getWithdrawalRequestsRoot(final Hash defaultValue) { - return withdrawalRequestsRoot.orElse(defaultValue); - } - - public Optional> getWithdrawalRequests( - final Optional> defaultValue) { - return withdrawalRequests.orElse(defaultValue); + public Optional> getRequests(final Optional> defaultValue) { + return requests.orElse(defaultValue); } public boolean hasTransactions() { @@ -771,14 +758,8 @@ public BlockOptions setWithdrawals(final Optional> withdrawals) return this; } - public BlockOptions setDeposits(final Optional> deposits) { - this.deposits = Optional.of(deposits); - return this; - } - - public BlockOptions setWithdrawalRequests( - final Optional> withdrawalRequests) { - this.withdrawalRequests = Optional.of(withdrawalRequests); + public BlockOptions setRequests(final Optional> requests) { + this.requests = Optional.of(requests); return this; } @@ -870,13 +851,8 @@ public BlockOptions setWithdrawalsRoot(final Hash withdrawalsRoot) { return this; } - public BlockOptions setDepositsRoot(final Hash depositsRoot) { - this.depositsRoot = Optional.of(depositsRoot); - return this; - } - - public BlockOptions setWithdrawalRequestsRoot(final Hash withdrawalRequestsRoot) { - this.withdrawalRequestsRoot = Optional.of(withdrawalRequestsRoot); + public BlockOptions setRequestsRoot(final Hash requestsRoot) { + this.requestsRoot = Optional.of(requestsRoot); return this; } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java index 96ea9c2f783..44a4ffd0603 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java @@ -50,8 +50,7 @@ public class BlockHeaderTestFixture { private Hash mixHash = Hash.EMPTY; private long nonce = 0; private Optional withdrawalsRoot = Optional.empty(); - private Optional depositsRoot = Optional.empty(); - private Optional withdrawalsRequestRoot = Optional.empty(); + private Optional requestsRoot = Optional.empty(); private BlockHeaderFunctions blockHeaderFunctions = new MainnetBlockHeaderFunctions(); private Optional excessBlobGas = Optional.empty(); private Optional blobGasUsed = Optional.empty(); @@ -79,8 +78,7 @@ public BlockHeader buildHeader() { withdrawalsRoot.ifPresent(builder::withdrawalsRoot); excessBlobGas.ifPresent(builder::excessBlobGas); blobGasUsed.ifPresent(builder::blobGasUsed); - depositsRoot.ifPresent(builder::depositsRoot); - withdrawalsRequestRoot.ifPresent(builder::withdrawalRequestsRoot); + requestsRoot.ifPresent(builder::requestsRoot); parentBeaconBlockRoot.ifPresent(builder::parentBeaconBlockRoot); builder.blockHeaderFunctions(blockHeaderFunctions); @@ -177,13 +175,8 @@ public BlockHeaderTestFixture withdrawalsRoot(final Hash withdrawalsRoot) { return this; } - public BlockHeaderTestFixture depositsRoot(final Hash depositsRoot) { - this.depositsRoot = Optional.ofNullable(depositsRoot); - return this; - } - - public BlockHeaderTestFixture withdrawalRequestsRoot(final Hash withdrawalRequestsRoot) { - this.withdrawalsRequestRoot = Optional.ofNullable(withdrawalRequestsRoot); + public BlockHeaderTestFixture requestsRoot(final Hash requestsRoot) { + this.requestsRoot = Optional.ofNullable(requestsRoot); return this; } diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/NonBesuBlockHeader.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/NonBesuBlockHeader.java index 3c4397b3990..000e727db75 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/NonBesuBlockHeader.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/NonBesuBlockHeader.java @@ -115,12 +115,7 @@ public Optional getWithdrawalsRoot() { } @Override - public Optional getDepositsRoot() { - return Optional.empty(); - } - - @Override - public Optional getWithdrawalRequestsRoot() { + public Optional getRequestsRoot() { return Optional.empty(); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java index a66f02574bb..6af78e59903 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java @@ -40,8 +40,8 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidator.ProhibitedWithdrawalRequests; import org.hyperledger.besu.ethereum.mainnet.blockhash.FrontierBlockHashProcessor; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiWorldStateProvider; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; @@ -111,8 +111,8 @@ public void setup() { when(protocolContext.getBlockchain()).thenReturn(blockchain); when(protocolContext.getWorldStateArchive()).thenReturn(worldStateArchive); when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); - when(protocolSpec.getWithdrawalRequestValidator()) - .thenReturn(new ProhibitedWithdrawalRequests()); + when(protocolSpec.getRequestsValidatorCoordinator()) + .thenReturn(new RequestsValidatorCoordinator.Builder().build()); when(protocolSpec.getBlockHashProcessor()).thenReturn(new FrontierBlockHashProcessor()); mainnetBlockValidator = new MainnetBlockValidator( @@ -148,6 +148,7 @@ void shouldNotBadBlockWhenInternalErrorDuringPersisting() { eq(goodBlock), any(), any(), + any(), eq(HeaderValidationMode.DETACHED_ONLY))) .thenReturn(true); assertThat(badBlockManager.getBadBlocks()).isEmpty(); @@ -184,6 +185,7 @@ void shouldNotBadBlockWhenInternalErrorOnBlockLookup() { eq(goodBlock), any(), any(), + any(), eq(HeaderValidationMode.DETACHED_ONLY))) .thenReturn(true); assertThat(badBlockManager.getBadBlocks()).isEmpty(); @@ -252,6 +254,7 @@ void shouldNotBadBlockWhenInternalErrorDuringValidateBody() { eq(goodBlock), any(), any(), + any(), eq(HeaderValidationMode.DETACHED_ONLY))) .thenThrow(new StorageException("database problem")); assertThat(badBlockManager.getBadBlocks()).isEmpty(); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java index ccda0ccb807..361353ee2b2 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/MainnetBlockValidatorTest.java @@ -96,14 +96,15 @@ public void setup() { when(worldStateArchive.getMutable()).thenReturn(worldState); when(blockHeaderValidator.validateHeader(any(), any(), any())).thenReturn(true); when(blockHeaderValidator.validateHeader(any(), any(), any(), any())).thenReturn(true); - when(blockBodyValidator.validateBody(any(), any(), any(), any(), any())).thenReturn(true); - when(blockBodyValidator.validateBodyLight(any(), any(), any(), any())).thenReturn(true); + when(blockBodyValidator.validateBody(any(), any(), any(), any(), any(), any())) + .thenReturn(true); + when(blockBodyValidator.validateBodyLight(any(), any(), any(), any(), any())).thenReturn(true); when(blockProcessor.processBlock(any(), any(), any())).thenReturn(successfulProcessingResult); when(blockProcessor.processBlock(any(), any(), any(), any())) .thenReturn(successfulProcessingResult); when(blockProcessor.processBlock(any(), any(), any(), any(), any())) .thenReturn(successfulProcessingResult); - when(blockProcessor.processBlock(any(), any(), any(), any(), any(), any(), any(), any())) + when(blockProcessor.processBlock(any(), any(), any(), any(), any(), any(), any())) .thenReturn(successfulProcessingResult); assertNoBadBlocks(); @@ -162,7 +163,8 @@ public void validateAndProcessBlock_whenHeaderInvalid() { @Test public void validateAndProcessBlock_whenBlockBodyInvalid() { - when(blockBodyValidator.validateBody(any(), eq(block), any(), any(), any())).thenReturn(false); + when(blockBodyValidator.validateBody(any(), eq(block), any(), any(), any(), any())) + .thenReturn(false); BlockProcessingResult result = mainnetBlockValidator.validateAndProcessBlock( @@ -347,6 +349,7 @@ public void fastBlockValidation_onSuccess() { protocolContext, block, Collections.emptyList(), + block.getBody().getRequests(), HeaderValidationMode.FULL, HeaderValidationMode.FULL); @@ -363,7 +366,12 @@ public void fastBlockValidation_onFailedHeaderValidation() { final boolean isValid = mainnetBlockValidator.fastBlockValidation( - protocolContext, block, Collections.emptyList(), validationMode, validationMode); + protocolContext, + block, + Collections.emptyList(), + block.getBody().getRequests(), + validationMode, + validationMode); assertThat(isValid).isFalse(); assertBadBlockIsTracked(block); @@ -373,12 +381,17 @@ public void fastBlockValidation_onFailedHeaderValidation() { public void fastBlockValidation_onFailedBodyValidation() { final HeaderValidationMode validationMode = HeaderValidationMode.FULL; when(blockBodyValidator.validateBodyLight( - eq(protocolContext), eq(block), any(), eq(validationMode))) + eq(protocolContext), eq(block), any(), any(), eq(validationMode))) .thenReturn(false); final boolean isValid = mainnetBlockValidator.fastBlockValidation( - protocolContext, block, Collections.emptyList(), validationMode, validationMode); + protocolContext, + block, + Collections.emptyList(), + block.getBody().getRequests(), + validationMode, + validationMode); assertThat(isValid).isFalse(); assertBadBlockIsTracked(block); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java index ee69c7e3611..6e6217e08bc 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java @@ -287,6 +287,7 @@ void genesisFromCancun(final DataStorageConfiguration dataStorageConfiguration) assertThat(last).isNotNull(); Wei lastBalance = last.getBalance(); assertThat(lastBalance).isEqualTo(Wei.fromHexString("0x123450000000000000000")); + assertThat(header.getRequestsRoot().isPresent()).isFalse(); } @ParameterizedTest @@ -302,7 +303,7 @@ void genesisFromPrague(final DataStorageConfiguration dataStorageConfiguration) assertThat(header.getHash()) .isEqualTo( Hash.fromHexString( - "0x87846b86c1026fa7d7be2da045716274231de1871065a320659c9b111287c688")); + "0xaad700fd347070b47165c299dd5b843d0a47d4eaee12d3414a5cb58c5c8a8fe4")); assertThat(header.getGasLimit()).isEqualTo(0x2fefd8); assertThat(header.getGasUsed()).isZero(); assertThat(header.getNumber()).isZero(); @@ -337,5 +338,11 @@ void genesisFromPrague(final DataStorageConfiguration dataStorageConfiguration) assertThat(last).isNotNull(); Wei lastBalance = last.getBalance(); assertThat(lastBalance).isEqualTo(Wei.fromHexString("0x123450000000000000000")); + + assertThat(header.getRequestsRoot().isPresent()).isTrue(); + assertThat(header.getRequestsRoot().get()) + .isEqualTo( + Hash.fromHexString( + "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoderTest.java index a6e36063ed4..ad6da667c1e 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalRequestDecoderTest.java @@ -17,6 +17,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.BLSPublicKey; import org.hyperledger.besu.datatypes.GWei; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.WithdrawalRequest; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; import org.hyperledger.besu.ethereum.rlp.RLP; @@ -38,8 +39,7 @@ public void shouldDecodeWithdrawalRequest() { final BytesValueRLPOutput out = new BytesValueRLPOutput(); expectedWithdrawalRequest.writeTo(out); - final WithdrawalRequest decodedWithdrawalRequest = - WithdrawalRequestDecoder.decode(RLP.input(out.encoded())); + final Request decodedWithdrawalRequest = RequestDecoder.decode(RLP.input(out.encoded())); Assertions.assertThat(decodedWithdrawalRequest).isEqualTo(expectedWithdrawalRequest); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorTest.java index 58b42109f00..2db101ab659 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessorTest.java @@ -32,8 +32,8 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.Withdrawal; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidator.ProhibitedWithdrawalRequests; import org.hyperledger.besu.ethereum.mainnet.blockhash.FrontierBlockHashProcessor; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestBlockchain; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestWorldState; @@ -69,8 +69,8 @@ abstract class AbstractBlockProcessorTest { void baseSetup() { lenient().when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); lenient() - .when(protocolSpec.getWithdrawalRequestValidator()) - .thenReturn(new ProhibitedWithdrawalRequests()); + .when(protocolSpec.getRequestsValidatorCoordinator()) + .thenReturn(new RequestsValidatorCoordinator.Builder().build()); lenient() .when(protocolSpec.getBlockHashProcessor()) .thenReturn(new FrontierBlockHashProcessor()); @@ -88,14 +88,7 @@ void baseSetup() { void withProcessorAndEmptyWithdrawals_WithdrawalsAreNotProcessed() { when(protocolSpec.getWithdrawalsProcessor()).thenReturn(Optional.empty()); blockProcessor.processBlock( - blockchain, - worldState, - emptyBlockHeader, - emptyList(), - emptyList(), - Optional.empty(), - Optional.empty(), - null); + blockchain, worldState, emptyBlockHeader, emptyList(), emptyList(), Optional.empty(), null); verify(withdrawalsProcessor, never()).processWithdrawals(any(), any()); } @@ -103,14 +96,7 @@ void withProcessorAndEmptyWithdrawals_WithdrawalsAreNotProcessed() { void withNoProcessorAndEmptyWithdrawals_WithdrawalsAreNotProcessed() { when(protocolSpec.getWithdrawalsProcessor()).thenReturn(Optional.empty()); blockProcessor.processBlock( - blockchain, - worldState, - emptyBlockHeader, - emptyList(), - emptyList(), - Optional.empty(), - Optional.empty(), - null); + blockchain, worldState, emptyBlockHeader, emptyList(), emptyList(), Optional.empty(), null); verify(withdrawalsProcessor, never()).processWithdrawals(any(), any()); } @@ -126,7 +112,6 @@ void withProcessorAndWithdrawals_WithdrawalsAreProcessed() { emptyList(), emptyList(), Optional.of(withdrawals), - Optional.empty(), null); verify(withdrawalsProcessor).processWithdrawals(eq(withdrawals), any()); } @@ -144,7 +129,6 @@ void withNoProcessorAndWithdrawals_WithdrawalsAreNotProcessed() { emptyList(), emptyList(), Optional.of(withdrawals), - Optional.empty(), null); verify(withdrawalsProcessor, never()).processWithdrawals(any(), any()); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationTest.java index cd5c5d89631..fd5c4387ccd 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/BodyValidationTest.java @@ -23,7 +23,6 @@ import org.apache.tuweni.bytes.Bytes32; import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; /** Tests for {@link BodyValidation}. */ @@ -58,15 +57,4 @@ public void calculateWithdrawalsRoot() throws IOException { Assertions.assertThat(header.getWithdrawalsRoot()).hasValue(Hash.wrap(withdrawalsRoot)); } } - - @Disabled // TODO: RLP encoding has changed, so testdata needs to be updated - @Test - public void calculateDepositsRoot() throws IOException { - for (final int block : Arrays.asList(123, 124)) { - final BlockHeader header = ValidationTestUtils.readHeader(block); - final BlockBody body = ValidationTestUtils.readBody(block); - final Bytes32 depositsRoot = BodyValidation.depositsRoot(body.getDeposits().get()); - Assertions.assertThat(header.getDepositsRoot()).hasValue(Hash.wrap(depositsRoot)); - } - } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java index 47428ffe532..99eae1437a6 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DepositsValidatorTest.java @@ -20,15 +20,18 @@ import org.hyperledger.besu.datatypes.BLSPublicKey; import org.hyperledger.besu.datatypes.BLSSignature; import org.hyperledger.besu.datatypes.GWei; -import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.RequestType; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockDataGenerator; import org.hyperledger.besu.ethereum.core.Deposit; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.mainnet.requests.DepositsValidator; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; +import org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestValidator; import org.hyperledger.besu.evm.log.Log; import org.hyperledger.besu.evm.log.LogTopic; -import java.util.Collections; import java.util.List; import java.util.Optional; @@ -45,6 +48,8 @@ public class DepositsValidatorTest { private static Log LOG_1; private static Log LOG_2; private static Address DEPOSIT_CONTRACT_ADDRESS; + private static RequestsValidatorCoordinator requestsValidatorCoordinator; + private static DepositsValidator depositsValidator; @BeforeAll public static void setup() { @@ -88,59 +93,34 @@ public static void setup() { LogTopic.fromHexString( "0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"))); DEPOSIT_CONTRACT_ADDRESS = Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa"); - } - - @Test - public void validateProhibitedDeposits() { - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setDeposits(Optional.empty()); - final Block block = blockDataGenerator.block(blockOptions); - assertThat(new DepositsValidator.ProhibitedDeposits().validateDeposits(block, null)).isTrue(); - } - - @Test - public void validateProhibitedDepositsRoot() { - final Block block = blockDataGenerator.block(); - assertThat(new DepositsValidator.ProhibitedDeposits().validateDepositsRoot(block)).isTrue(); - } - - @Test - public void invalidateProhibitedDeposits() { - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setDeposits(Optional.of(List.of(DEPOSIT_1))); - final Block block = blockDataGenerator.block(blockOptions); - assertThat(new DepositsValidator.ProhibitedDeposits().validateDeposits(block, null)).isFalse(); - } - - @Test - public void invalidateProhibitedDepositsRoot() { - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setDepositsRoot(Hash.EMPTY_LIST_HASH); - final Block block = blockDataGenerator.block(blockOptions); - assertThat(new DepositsValidator.ProhibitedDeposits().validateDepositsRoot(block)).isFalse(); + requestsValidatorCoordinator = createAllowDepositValidator(); } @Test public void validateAllowedDeposits() { + final List request = List.of(DEPOSIT_1, DEPOSIT_2); final BlockDataGenerator.BlockOptions blockOptions = BlockDataGenerator.BlockOptions.create() - .setDeposits(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); + .setRequests(Optional.of(request)) + .setRequestsRoot(BodyValidation.requestsRoot(request)); final Block block = blockDataGenerator.block(blockOptions); final TransactionReceipt receipt = new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); - assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDeposits(block, List.of(receipt))) + assertThat(requestsValidatorCoordinator.validate(block, Optional.of(request), List.of(receipt))) .isTrue(); } @Test public void validateAllowedDepositsSeparateReceipts() { + + final List requests = List.of(DEPOSIT_1, DEPOSIT_2); + final BlockDataGenerator.BlockOptions blockOptions = BlockDataGenerator.BlockOptions.create() - .setDeposits(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); + .setRequests(Optional.of(requests)) + .setRequestsRoot(BodyValidation.requestsRoot(requests)); final Block block = blockDataGenerator.block(blockOptions); final TransactionReceipt receipt1 = @@ -149,36 +129,22 @@ public void validateAllowedDepositsSeparateReceipts() { new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDeposits(block, List.of(receipt1, receipt2))) - .isTrue(); - } - - @Test - public void validateAllowedDepositsRoot() { - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setDeposits(Optional.of(Collections.emptyList())) - .setDepositsRoot(Hash.EMPTY_TRIE_HASH); - final Block block = blockDataGenerator.block(blockOptions); - assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDepositsRoot(block)) + requestsValidatorCoordinator.validate( + block, Optional.of(requests), List.of(receipt1, receipt2))) .isTrue(); } @Test public void invalidateAllowedDeposits() { final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setDeposits(Optional.of(List.of(DEPOSIT_1))); + BlockDataGenerator.BlockOptions.create().setRequests(Optional.of(List.of(DEPOSIT_1))); final Block block = blockDataGenerator.block(blockOptions); final TransactionReceipt receipt1 = new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDeposits(block, List.of(receipt1))) + requestsValidatorCoordinator.validate(block, Optional.of(List.of()), List.of(receipt1))) .isFalse(); } @@ -186,30 +152,28 @@ public void invalidateAllowedDeposits() { public void invalidateAllowedDepositsMissingLogInReceipt() { final BlockDataGenerator.BlockOptions blockOptions = BlockDataGenerator.BlockOptions.create() - .setDeposits(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); + .setRequests(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); final Block block = blockDataGenerator.block(blockOptions); final TransactionReceipt receipt1 = new TransactionReceipt(null, 0L, List.of(LOG_2), Optional.empty()); assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDeposits(block, List.of(receipt1))) + requestsValidatorCoordinator.validate(block, Optional.of(List.of()), List.of(receipt1))) .isFalse(); } @Test public void invalidateAllowedDepositsExtraLogInReceipt() { final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setDeposits(Optional.of(List.of(DEPOSIT_1))); + BlockDataGenerator.BlockOptions.create().setRequests(Optional.of(List.of(DEPOSIT_1))); final Block block = blockDataGenerator.block(blockOptions); final TransactionReceipt receipt1 = new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDeposits(block, List.of(receipt1))) + requestsValidatorCoordinator.validate(block, Optional.of(List.of()), List.of(receipt1))) .isFalse(); } @@ -217,15 +181,14 @@ public void invalidateAllowedDepositsExtraLogInReceipt() { public void invalidateAllowedDepositsWrongOrder() { final BlockDataGenerator.BlockOptions blockOptions = BlockDataGenerator.BlockOptions.create() - .setDeposits(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); + .setRequests(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); final Block block = blockDataGenerator.block(blockOptions); final TransactionReceipt receipt1 = new TransactionReceipt(null, 0L, List.of(LOG_2, LOG_1), Optional.empty()); assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDeposits(block, List.of(receipt1))) + requestsValidatorCoordinator.validate(block, Optional.of(List.of()), List.of(receipt1))) .isFalse(); } @@ -234,66 +197,37 @@ public void invalidateAllowedDepositsMismatchContractAddress() { final BlockDataGenerator.BlockOptions blockOptions = BlockDataGenerator.BlockOptions.create() - .setDeposits(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); + .setRequests(Optional.of(List.of(DEPOSIT_1, DEPOSIT_2))); final Block block = blockDataGenerator.block(blockOptions); final TransactionReceipt receipt1 = new TransactionReceipt(null, 0L, List.of(LOG_1, LOG_2), Optional.empty()); assertThat( - new DepositsValidator.AllowedDeposits(Address.ZERO) - .validateDeposits(block, List.of(receipt1))) - .isFalse(); - } - - @Test - public void invalidateAllowedDepositsRoot() { - final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setDeposits(Optional.of(Collections.emptyList())) - .setDepositsRoot(Hash.ZERO); // this is invalid it should be empty trie hash - final Block block = blockDataGenerator.block(blockOptions); - assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDepositsRoot(block)) - .isFalse(); - } - - @Test - public void validateProhibitedDepositParams() { - final Optional> deposits = Optional.empty(); - assertThat(new DepositsValidator.ProhibitedDeposits().validateDepositParameter(deposits)) - .isTrue(); - } - - @Test - public void invalidateProhibitedDepositParams() { - final Optional> deposits = Optional.of(List.of(DEPOSIT_1, DEPOSIT_2)); - assertThat(new DepositsValidator.ProhibitedDeposits().validateDepositParameter(deposits)) + requestsValidatorCoordinator.validate(block, Optional.of(List.of()), List.of(receipt1))) .isFalse(); } @Test public void validateAllowedDepositParams() { - final Optional> deposits = Optional.of(List.of(DEPOSIT_1, DEPOSIT_2)); - assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDepositParameter(deposits)) - .isTrue(); + final Optional> deposits = Optional.of(List.of(DEPOSIT_1, DEPOSIT_2)); + assertThat(depositsValidator.validateParameter(deposits)).isTrue(); - final Optional> emptyDeposits = Optional.of(List.of()); - assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDepositParameter(emptyDeposits)) - .isTrue(); + final Optional> emptyDeposits = Optional.of(List.of()); + assertThat(depositsValidator.validateParameter(emptyDeposits)).isTrue(); } @Test public void invalidateAllowedDepositParams() { - final Optional> deposits = Optional.empty(); - assertThat( - new DepositsValidator.AllowedDeposits(DEPOSIT_CONTRACT_ADDRESS) - .validateDepositParameter(deposits)) - .isFalse(); + final Optional> deposits = Optional.empty(); + assertThat(depositsValidator.validateParameter(deposits)).isFalse(); + } + + static RequestsValidatorCoordinator createAllowDepositValidator() { + depositsValidator = new DepositsValidator(DEPOSIT_CONTRACT_ADDRESS); + return new RequestsValidatorCoordinator.Builder() + .addValidator(RequestType.WITHDRAWAL, new WithdrawalRequestValidator()) + .addValidator(RequestType.DEPOSIT, depositsValidator) + .build(); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java index 6c0b8b01165..dfc1f2d0436 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidatorTest.java @@ -28,6 +28,8 @@ import org.hyperledger.besu.ethereum.core.BlockDataGenerator.BlockOptions; import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; import org.hyperledger.besu.ethereum.core.Withdrawal; +import org.hyperledger.besu.ethereum.mainnet.requests.DepositsValidator; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.evm.log.LogsBloomFilter; import java.util.Collections; @@ -52,7 +54,7 @@ class MainnetBlockBodyValidatorTest { @Mock private ProtocolSpec protocolSpec; @Mock private WithdrawalsValidator withdrawalsValidator; @Mock private DepositsValidator depositsValidator; - @Mock private WithdrawalRequestValidator exitsValidator; + @Mock private RequestsValidatorCoordinator requestValidator; @BeforeEach public void setUp() { @@ -62,12 +64,10 @@ public void setUp() { lenient().when(withdrawalsValidator.validateWithdrawals(any())).thenReturn(true); lenient().when(withdrawalsValidator.validateWithdrawalsRoot(any())).thenReturn(true); - lenient().when(protocolSpec.getDepositsValidator()).thenReturn(depositsValidator); - lenient().when(depositsValidator.validateDeposits(any(), any())).thenReturn(true); - lenient().when(depositsValidator.validateDepositsRoot(any())).thenReturn(true); + lenient().when(depositsValidator.validateDeposits(any(), any(), any())).thenReturn(true); - lenient().when(protocolSpec.getWithdrawalRequestValidator()).thenReturn(exitsValidator); - lenient().when(exitsValidator.validateWithdrawalRequestsInBlock(any(), any())).thenReturn(true); + lenient().when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(requestValidator); + lenient().when(requestValidator.validate(any(), any(), any())).thenReturn(true); } @Test @@ -91,7 +91,7 @@ void validatesWithdrawals() { assertThat( new MainnetBlockBodyValidator(protocolSchedule) .validateBodyLight( - blockchainSetupUtil.getProtocolContext(), block, emptyList(), NONE)) + blockchainSetupUtil.getProtocolContext(), block, emptyList(), any(), NONE)) .isTrue(); } @@ -115,7 +115,7 @@ void validationFailsIfWithdrawalsValidationFails() { assertThat( new MainnetBlockBodyValidator(protocolSchedule) .validateBodyLight( - blockchainSetupUtil.getProtocolContext(), block, emptyList(), NONE)) + blockchainSetupUtil.getProtocolContext(), block, emptyList(), any(), NONE)) .isFalse(); } @@ -139,12 +139,12 @@ void validationFailsIfWithdrawalsRootValidationFails() { assertThat( new MainnetBlockBodyValidator(protocolSchedule) .validateBodyLight( - blockchainSetupUtil.getProtocolContext(), block, emptyList(), NONE)) + blockchainSetupUtil.getProtocolContext(), block, emptyList(), any(), NONE)) .isFalse(); } @Test - public void validationFailsIfExitsValidationFails() { + public void validationFailsIfWithdrawalRequestsValidationFails() { final Block block = blockDataGenerator.block( new BlockOptions() @@ -155,15 +155,15 @@ public void validationFailsIfExitsValidationFails() { .setReceiptsRoot(BodyValidation.receiptsRoot(emptyList())) .setLogsBloom(LogsBloomFilter.empty()) .setParentHash(blockchainSetupUtil.getBlockchain().getChainHeadHash()) - .setWithdrawalRequests(Optional.of(List.of()))); + .setRequests(Optional.of(List.of()))); blockchainSetupUtil.getBlockchain().appendBlock(block, Collections.emptyList()); - when(exitsValidator.validateWithdrawalRequestsInBlock(any(), any())).thenReturn(false); + when(requestValidator.validate(any(), any(), any())).thenReturn(false); assertThat( new MainnetBlockBodyValidator(protocolSchedule) .validateBodyLight( - blockchainSetupUtil.getProtocolContext(), block, emptyList(), NONE)) + blockchainSetupUtil.getProtocolContext(), block, emptyList(), any(), NONE)) .isFalse(); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessorTest.java index 7d27301a74e..9f2092ea81b 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessorTest.java @@ -27,8 +27,8 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.MutableWorldState; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidator.ProhibitedWithdrawalRequests; import org.hyperledger.besu.ethereum.mainnet.blockhash.FrontierBlockHashProcessor; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestBlockchain; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestWorldState; @@ -50,8 +50,8 @@ public class MainnetBlockProcessorTest extends AbstractBlockProcessorTest { @BeforeEach public void setup() { when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); - when(protocolSpec.getWithdrawalRequestValidator()) - .thenReturn(new ProhibitedWithdrawalRequests()); + when(protocolSpec.getRequestsValidatorCoordinator()) + .thenReturn(new RequestsValidatorCoordinator.Builder().build()); when(protocolSpec.getBlockHashProcessor()).thenReturn(new FrontierBlockHashProcessor()); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueRequestsValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueRequestsValidatorTest.java new file mode 100644 index 00000000000..833e692d7f4 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueRequestsValidatorTest.java @@ -0,0 +1,112 @@ +/* + * 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.mainnet; + +import static java.util.Collections.emptyList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode.NONE; +import static org.hyperledger.besu.ethereum.mainnet.requests.DepositRequestProcessor.DEFAULT_DEPOSIT_CONTRACT_ADDRESS; +import static org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator.pragueRequestsValidator; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.lenient; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.BLSPublicKey; +import org.hyperledger.besu.datatypes.GWei; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.core.BlockDataGenerator; +import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; +import org.hyperledger.besu.ethereum.core.Request; +import org.hyperledger.besu.ethereum.core.WithdrawalRequest; +import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; +import org.hyperledger.besu.evm.log.LogsBloomFilter; + +import java.util.List; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.bytes.Bytes48; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class PragueRequestsValidatorTest { + + private final BlockchainSetupUtil blockchainSetupUtil = BlockchainSetupUtil.forMainnet(); + @Mock private ProtocolSchedule protocolSchedule; + @Mock private ProtocolSpec protocolSpec; + @Mock private WithdrawalsValidator withdrawalsValidator; + + RequestsValidatorCoordinator requestValidator = + pragueRequestsValidator(DEFAULT_DEPOSIT_CONTRACT_ADDRESS); + + @BeforeEach + public void setUp() { + lenient().when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec); + lenient().when(protocolSpec.getWithdrawalsValidator()).thenReturn(withdrawalsValidator); + lenient().when(withdrawalsValidator.validateWithdrawals(any())).thenReturn(true); + lenient().when(withdrawalsValidator.validateWithdrawalsRoot(any())).thenReturn(true); + lenient().when(protocolSpec.getRequestsValidatorCoordinator()).thenReturn(requestValidator); + } + + private static final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); + + @Test + void shouldValidateRequestsTest() { + WithdrawalRequest request = + new WithdrawalRequest( + Address.extract(Bytes32.fromHexStringLenient("1")), + BLSPublicKey.wrap(Bytes48.fromHexStringLenient("1")), + GWei.ONE); + + WithdrawalRequest requestTwo = + new WithdrawalRequest( + Address.extract(Bytes32.fromHexStringLenient("1")), + BLSPublicKey.wrap(Bytes48.fromHexStringLenient("1")), + GWei.ZERO); + + Optional> blockRequests = Optional.of(List.of(request)); + Optional> expectedRequests = Optional.of(List.of(requestTwo)); + Hash requestsRoot = BodyValidation.requestsRoot(blockRequests.get()); + + final BlockDataGenerator.BlockOptions blockOptions = + BlockDataGenerator.BlockOptions.create() + .setRequestsRoot(requestsRoot) + .setRequests(blockRequests) + .setGasUsed(0) + .setReceiptsRoot(BodyValidation.receiptsRoot(emptyList())) + .hasTransactions(false) + .hasOmmers(false) + .setReceiptsRoot(BodyValidation.receiptsRoot(emptyList())) + .setLogsBloom(LogsBloomFilter.empty()) + .setParentHash(blockchainSetupUtil.getBlockchain().getChainHeadHash()); + + final Block block = blockDataGenerator.block(blockOptions); + assertThat(block).isNotNull(); + assertThat( + new MainnetBlockBodyValidator(protocolSchedule) + .validateBodyLight( + blockchainSetupUtil.getProtocolContext(), + block, + emptyList(), + expectedRequests, + NONE)) + .isFalse(); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidatorTest.java index afdd1a89ac2..1d53b4b19ce 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueWithdrawalRequestValidatorTest.java @@ -18,19 +18,16 @@ import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithMoreThanMaximumWithdrawalRequests; import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithWithdrawalRequestsAndWithdrawalRequestsRoot; import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithWithdrawalRequestsMismatch; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithWithdrawalRequestsRootMismatch; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithWithdrawalRequestsWithoutWithdrawalRequestsRoot; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithoutWithdrawalRequestsAndWithdrawalRequestsRoot; -import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithoutWithdrawalRequestsWithWithdrawalRequestsRoot; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.WithdrawalRequestTestParameter; +import org.hyperledger.besu.ethereum.mainnet.requests.WithdrawalRequestValidator; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Stream; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -41,17 +38,22 @@ class PragueWithdrawalRequestValidatorTest { @MethodSource("paramsForValidateWithdrawalRequestParameter") public void validateWithdrawalRequestParameter( final String description, - final Optional> maybeExits, + final Optional> maybeRequests, final boolean expectedValidity) { - assertThat( - new PragueWithdrawalRequestValidator().validateWithdrawalRequestParameter(maybeExits)) + assertThat(new WithdrawalRequestValidator().validateParameter(maybeRequests)) .isEqualTo(expectedValidity); } private static Stream paramsForValidateWithdrawalRequestParameter() { return Stream.of( - Arguments.of("Allowed exits - validating empty exits", Optional.empty(), false), - Arguments.of("Allowed exits - validating present exits", Optional.of(List.of()), true)); + Arguments.of( + "Allowed WithdrawalRequests - validating empty WithdrawalRequests", + Optional.empty(), + false), + Arguments.of( + "Allowed WithdrawalRequests - validating present WithdrawalRequests", + Optional.of(List.of()), + true)); } @ParameterizedTest(name = "{index}: {0}") @@ -59,24 +61,15 @@ private static Stream paramsForValidateWithdrawalRequestParameter() { public void validateWithdrawalRequestsInBlock_WhenPrague( final WithdrawalRequestTestParameter param, final boolean expectedValidity) { assertThat( - new PragueWithdrawalRequestValidator() - .validateWithdrawalRequestsInBlock(param.block, param.expectedWithdrawalRequest)) + new WithdrawalRequestValidator() + .validate(param.block, new ArrayList<>(param.expectedWithdrawalRequest), List.of())) .isEqualTo(expectedValidity); } private static Stream validateWithdrawalRequestsInBlockParamsForPrague() { return Stream.of( Arguments.of(blockWithWithdrawalRequestsAndWithdrawalRequestsRoot(), true), - Arguments.of(blockWithWithdrawalRequestsWithoutWithdrawalRequestsRoot(), false), - Arguments.of(blockWithoutWithdrawalRequestsWithWithdrawalRequestsRoot(), false), - Arguments.of(blockWithoutWithdrawalRequestsAndWithdrawalRequestsRoot(), false), - Arguments.of(blockWithWithdrawalRequestsRootMismatch(), false), Arguments.of(blockWithWithdrawalRequestsMismatch(), false), Arguments.of(blockWithMoreThanMaximumWithdrawalRequests(), false)); } - - @Test - public void allowExitsShouldReturnTrue() { - assertThat(new PragueWithdrawalRequestValidator().allowWithdrawalRequests()).isTrue(); - } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java index 2259099425f..a46943e5acb 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PrivacyBlockProcessorTest.java @@ -117,7 +117,6 @@ void mustCopyPreviousPrivacyGroupBlockHeadMap() { eq(firstBlock.getBody().getTransactions()), eq(firstBlock.getBody().getOmmers()), eq(Optional.empty()), - eq(Optional.empty()), any()); verify(blockProcessor) .processBlock( @@ -127,7 +126,6 @@ void mustCopyPreviousPrivacyGroupBlockHeadMap() { eq(secondBlock.getBody().getTransactions()), eq(secondBlock.getBody().getOmmers()), eq(Optional.empty()), - eq(Optional.empty()), any()); } @@ -184,7 +182,6 @@ void mustPerformRehydration() { eq(secondBlock.getBody().getTransactions()), eq(secondBlock.getBody().getOmmers()), eq(Optional.empty()), - eq(Optional.empty()), any()); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ValidationTestUtils.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ValidationTestUtils.java index 7eac8488dee..fa912a6de87 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ValidationTestUtils.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ValidationTestUtils.java @@ -17,10 +17,9 @@ 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.Deposit; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Withdrawal; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.rlp.RLPInput; @@ -60,15 +59,11 @@ public static BlockBody readBody(final long num) throws IOException { input.isEndOfCurrentList() ? Optional.empty() : Optional.of(input.readList(Withdrawal::readFrom)); - final Optional> deposits = + final Optional> requests = input.isEndOfCurrentList() ? Optional.empty() - : Optional.of(input.readList(Deposit::readFrom)); - final Optional> withdrawalRequests = - input.isEndOfCurrentList() - ? Optional.empty() - : Optional.of(input.readList(WithdrawalRequest::readFrom)); - return new BlockBody(transactions, ommers, withdrawals, deposits, withdrawalRequests); + : Optional.of(input.readList(Request::readFrom)); + return new BlockBody(transactions, ommers, withdrawals, requests); } public static Block readBlock(final long num) throws IOException { diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java index 46cf1182d33..1c0485b5982 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestContractHelperTest.java @@ -52,19 +52,20 @@ public void setUp() { } @Test - public void popExitsFromQueue_ReadWithdrawalRequestsCorrectly() { - final List validatorExits = + public void popWithdrawalRequestsFromQueue_ReadWithdrawalRequestsCorrectly() { + final List validatorWithdrawalRequests = List.of(createExit(), createExit(), createExit()); - loadContractStorage(worldState, validatorExits); + loadContractStorage(worldState, validatorWithdrawalRequests); - final List poppedExits = + final List poppedWithdrawalRequests = WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState); - assertThat(poppedExits).isEqualTo(validatorExits); + assertThat(poppedWithdrawalRequests).isEqualTo(validatorWithdrawalRequests); } @Test - public void popExitsFromQueue_whenContractCodeIsEmpty_ReturnsEmptyListOfWithdrawalRequests() { + public void + popWithdrawalRequestsFromQueue_whenContractCodeIsEmpty_ReturnsEmptyListOfWithdrawalRequests() { // Create account with empty code final WorldUpdater updater = worldState.updater(); updater.createAccount(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS); @@ -75,69 +76,72 @@ public void popExitsFromQueue_whenContractCodeIsEmpty_ReturnsEmptyListOfWithdraw } @Test - public void popExitsFromQueue_WhenMoreWithdrawalRequests_UpdatesQueuePointers() { - // Loading contract with more than 16 exits - final List validatorExits = + public void popWithdrawalRequestsFromQueue_WhenMoreWithdrawalRequests_UpdatesQueuePointers() { + // Loading contract with more than 16 WithdrawalRequests + final List validatorWithdrawalRequests = IntStream.range(0, 30).mapToObj(__ -> createExit()).collect(Collectors.toList()); - loadContractStorage(worldState, validatorExits); - // After loading the contract, the exit count since last block should match the size of the list - assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, validatorExits.size()); + loadContractStorage(worldState, validatorWithdrawalRequests); + // After loading the contract, the WithdrawalRequests count since last block should match the + // size of the list + assertContractStorageValue( + WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, validatorWithdrawalRequests.size()); - final List poppedExits = + final List poppedWithdrawalRequests = WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState); - assertThat(poppedExits).hasSize(16); + assertThat(poppedWithdrawalRequests).hasSize(16); // Check that queue pointers were updated successfully (head advanced to index 16) assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT, 16); assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT, 30); - // We had 30 exits in the queue, and target per block is 2, so we have 28 excess + // We had 30 WithdrawalRequests in the queue, and target per block is 2, so we have 28 excess assertContractStorageValue(EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT, 28); - // We always reset the exit count after processing the queue + // We always reset the WithdrawalRequests count after processing the queue assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, 0); } @Test - public void popExitsFromQueue_WhenNoMoreWithdrawalRequests_ZeroQueuePointers() { - final List validatorExits = + public void popWithdrawalRequestsFromQueue_WhenNoMoreWithdrawalRequests_ZeroQueuePointers() { + final List withdrawalRequests = List.of(createExit(), createExit(), createExit()); - loadContractStorage(worldState, validatorExits); + loadContractStorage(worldState, withdrawalRequests); // After loading the contract, the exit count since last block should match the size of the list - assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, validatorExits.size()); + assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, withdrawalRequests.size()); - final List poppedExits = + final List poppedWithdrawalRequests = WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState); - assertThat(poppedExits).hasSize(3); + assertThat(poppedWithdrawalRequests).hasSize(3); // Check that queue pointers were updated successfully (head and tail zero because queue is // empty) assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT, 0); assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT, 0); - // We had 3 exits in the queue, target per block is 2, so we have 1 excess + // We had 3 WithdrawalRequests in the queue, target per block is 2, so we have 1 excess assertContractStorageValue(EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT, 1); - // We always reset the exit count after processing the queue + // We always reset the WithdrawalRequests count after processing the queue assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, 0); } @Test - public void popExitsFromQueue_WhenNoWithdrawalRequests_DoesNothing() { - // Loading contract with 0 exits + public void popWithdrawalRequestsFromQueue_WhenNoWithdrawalRequests_DoesNothing() { + // Loading contract with 0 WithdrawalRequests loadContractStorage(worldState, List.of()); - // After loading storage, we have the exit count as zero because no exits were aded + // After loading storage, we have the WithdrawalRequests count as zero because no + // WithdrawalRequests were added assertContractStorageValue(WITHDRAWAL_REQUEST_COUNT_STORAGE_SLOT, 0); - final List poppedExits = + final List poppedWithdrawalRequests = WithdrawalRequestContractHelper.popWithdrawalRequestsFromQueue(worldState); - assertThat(poppedExits).hasSize(0); + assertThat(poppedWithdrawalRequests).hasSize(0); // Check that queue pointers are correct (head and tail are zero) assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_HEAD_STORAGE_SLOT, 0); assertContractStorageValue(WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT, 0); - // We had 0 exits in the queue, and target per block is 2, so we have 0 excess + // We had 0 WithdrawalRequests in the queue, and target per block is 2, so we have 0 excess assertContractStorageValue(EXCESS_WITHDRAWAL_REQUESTS_STORAGE_SLOT, 0); // We always reset the exit count after processing the queue diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTest.java index 8315e9db018..43797a6e0d6 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTest.java @@ -20,15 +20,15 @@ import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithoutWithdrawalRequestsAndWithdrawalRequestsRoot; import static org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.blockWithoutWithdrawalRequestsWithWithdrawalRequestsRoot; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; -import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidator.ProhibitedWithdrawalRequests; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.mainnet.WithdrawalRequestValidatorTestFixtures.WithdrawalRequestTestParameter; +import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestsValidator; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Stream; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -39,25 +39,33 @@ class WithdrawalRequestValidatorTest { @MethodSource("paramsForValidateWithdrawalRequestParameter") public void validateWithdrawalRequestParameter( final String description, - final Optional> maybeExits, + final Optional> maybeWithdrawalRequests, final boolean expectedValidity) { - assertThat(new ProhibitedWithdrawalRequests().validateWithdrawalRequestParameter(maybeExits)) + assertThat(new ProhibitedRequestsValidator().validateParameter(maybeWithdrawalRequests)) .isEqualTo(expectedValidity); } private static Stream paramsForValidateWithdrawalRequestParameter() { return Stream.of( - Arguments.of("Prohibited exits - validating empty exits", Optional.empty(), true), - Arguments.of("Prohibited exits - validating present exits", Optional.of(List.of()), false)); + Arguments.of( + "Prohibited WithdrawalRequests - validating empty WithdrawalRequests", + Optional.empty(), + true), + Arguments.of( + "Prohibited WithdrawalRequests - validating present WithdrawalRequests", + Optional.of(List.of()), + false)); } @ParameterizedTest(name = "{index}: {0}") @MethodSource("validateWithdrawalRequestsInBlockParamsForProhibited") public void validateWithdrawalRequestsInBlock_WhenProhibited( final WithdrawalRequestTestParameter param, final boolean expectedValidity) { - assertThat( - new ProhibitedWithdrawalRequests() - .validateWithdrawalRequestsInBlock(param.block, param.expectedWithdrawalRequest)) + + var list = param.expectedWithdrawalRequest; + var requests = new ArrayList(list).stream().toList(); + + assertThat(new ProhibitedRequestsValidator().validate(param.block, requests, List.of())) .isEqualTo(expectedValidity); } @@ -68,9 +76,4 @@ private static Stream validateWithdrawalRequestsInBlockParamsForProhi Arguments.of(blockWithoutWithdrawalRequestsWithWithdrawalRequestsRoot(), false), Arguments.of(blockWithoutWithdrawalRequestsAndWithdrawalRequestsRoot(), true)); } - - @Test - public void allowExitsShouldReturnFalse() { - assertThat(new ProhibitedWithdrawalRequests().allowWithdrawalRequests()).isFalse(); - } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTestFixtures.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTestFixtures.java index b44830df573..7b8b440bb64 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTestFixtures.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/WithdrawalRequestValidatorTestFixtures.java @@ -22,6 +22,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockDataGenerator; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.WithdrawalRequest; import java.util.List; @@ -36,104 +37,111 @@ public class WithdrawalRequestValidatorTestFixtures { private static final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); static WithdrawalRequestTestParameter blockWithWithdrawalRequestsAndWithdrawalRequestsRoot() { - final Optional> maybeWithdrawalRequests = - Optional.of(List.of(createWithdrawalRequest())); + final WithdrawalRequest withdrawalRequest = createWithdrawalRequest(); + final Optional> maybeWithdrawalRequests = + Optional.of(java.util.List.of(withdrawalRequest)); final BlockDataGenerator.BlockOptions blockOptions = BlockDataGenerator.BlockOptions.create() - .setWithdrawalRequestsRoot( - BodyValidation.withdrawalRequestsRoot(maybeWithdrawalRequests.get())) - .setWithdrawalRequests(maybeWithdrawalRequests); + .setRequestsRoot(BodyValidation.requestsRoot(maybeWithdrawalRequests.get())) + .setRequests(maybeWithdrawalRequests); final Block block = blockDataGenerator.block(blockOptions); return new WithdrawalRequestTestParameter( "Block with withdrawal requests and withdrawal_requests_root", block, - maybeWithdrawalRequests); + Optional.of(java.util.List.of(withdrawalRequest))); } static WithdrawalRequestTestParameter blockWithoutWithdrawalRequestsWithWithdrawalRequestsRoot() { - final Optional> maybeExits = Optional.empty(); - final BlockDataGenerator.BlockOptions blockOptions = BlockDataGenerator.BlockOptions.create() - .setWithdrawalRequestsRoot(Hash.EMPTY) - .setWithdrawalRequests(maybeExits); + .setRequestsRoot(Hash.EMPTY) + .setRequests(Optional.empty()); final Block block = blockDataGenerator.block(blockOptions); return new WithdrawalRequestTestParameter( - "Block with withdrawal_requests_root but without withdrawal requests", block, maybeExits); + "Block with withdrawal_requests_root but without withdrawal requests", + block, + Optional.empty()); } static WithdrawalRequestTestParameter blockWithWithdrawalRequestsWithoutWithdrawalRequestsRoot() { - final Optional> maybeExits = - Optional.of(List.of(createWithdrawalRequest())); + final WithdrawalRequest withdrawalRequest = createWithdrawalRequest(); + final Optional> requests = Optional.of(java.util.List.of(withdrawalRequest)); final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setWithdrawalRequests(maybeExits); + BlockDataGenerator.BlockOptions.create().setRequests(requests); final Block block = blockDataGenerator.block(blockOptions); return new WithdrawalRequestTestParameter( - "Block with withdrawal requests but without withdrawal_requests_root", block, maybeExits); + "Block with withdrawal requests but without withdrawal_requests_root", + block, + Optional.of(java.util.List.of(withdrawalRequest))); } static WithdrawalRequestTestParameter blockWithoutWithdrawalRequestsAndWithdrawalRequestsRoot() { - final Optional> maybeExits = Optional.empty(); final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create().setWithdrawalRequests(maybeExits); + BlockDataGenerator.BlockOptions.create().setRequests(Optional.empty()); final Block block = blockDataGenerator.block(blockOptions); return new WithdrawalRequestTestParameter( - "Block without withdrawal requests and withdrawal_requests_root", block, maybeExits); + "Block without withdrawal requests and withdrawal_requests_root", block, Optional.empty()); } static WithdrawalRequestTestParameter blockWithWithdrawalRequestsRootMismatch() { - final Optional> maybeExits = - Optional.of(List.of(createWithdrawalRequest())); + final WithdrawalRequest withdrawalRequest = createWithdrawalRequest(); + + final Optional> requests = Optional.of(java.util.List.of(withdrawalRequest)); final BlockDataGenerator.BlockOptions blockOptions = - BlockDataGenerator.BlockOptions.create() - .setWithdrawalRequestsRoot(Hash.EMPTY) - .setWithdrawalRequests(maybeExits); + BlockDataGenerator.BlockOptions.create().setRequestsRoot(Hash.EMPTY).setRequests(requests); final Block block = blockDataGenerator.block(blockOptions); return new WithdrawalRequestTestParameter( - "Block with withdrawal_requests_root mismatch", block, maybeExits); + "Block with withdrawal_requests_root mismatch", + block, + Optional.of(java.util.List.of(withdrawalRequest))); } static WithdrawalRequestTestParameter blockWithWithdrawalRequestsMismatch() { - final Optional> maybeExits = - Optional.of(List.of(createWithdrawalRequest(), createWithdrawalRequest())); + final WithdrawalRequest withdrawalRequest = createWithdrawalRequest(); + + final Optional> requests = + Optional.of(java.util.List.of(withdrawalRequest, withdrawalRequest)); final BlockDataGenerator.BlockOptions blockOptions = BlockDataGenerator.BlockOptions.create() - .setWithdrawalRequestsRoot(BodyValidation.withdrawalRequestsRoot(maybeExits.get())) - .setWithdrawalRequests(maybeExits); + .setRequestsRoot(BodyValidation.requestsRoot(requests.get())) + .setRequests(requests); final Block block = blockDataGenerator.block(blockOptions); return new WithdrawalRequestTestParameter( "Block with withdrawal requests mismatch", block, - maybeExits, + Optional.of(java.util.List.of(withdrawalRequest, withdrawalRequest)), List.of(createWithdrawalRequest())); } static WithdrawalRequestTestParameter blockWithMoreThanMaximumWithdrawalRequests() { - final List validatorExits = + final List withdrawalRequest = IntStream.range(0, MAX_WITHDRAWAL_REQUESTS_PER_BLOCK + 1) .mapToObj(__ -> createWithdrawalRequest()) .toList(); - final Optional> maybeExits = Optional.of(validatorExits); + + final Optional> maybeWithdrawalRequest = Optional.of(withdrawalRequest); + final Optional> maybeRequests = + Optional.of(withdrawalRequest.stream().map(r -> (Request) r).toList()); final BlockDataGenerator.BlockOptions blockOptions = BlockDataGenerator.BlockOptions.create() - .setWithdrawalRequestsRoot(BodyValidation.withdrawalRequestsRoot(maybeExits.get())) - .setWithdrawalRequests(maybeExits); + .setRequestsRoot(BodyValidation.requestsRoot(maybeRequests.get())) + .setRequests(maybeRequests); final Block block = blockDataGenerator.block(blockOptions); return new WithdrawalRequestTestParameter( - "Block with more than maximum withdrawal requests", block, maybeExits); + "Block with more than maximum withdrawal requests", block, maybeWithdrawalRequest); } static WithdrawalRequest createWithdrawalRequest() { @@ -152,7 +160,11 @@ public WithdrawalRequestTestParameter( final String description, final Block block, final Optional> maybeWithdrawalRequest) { - this(description, block, maybeWithdrawalRequest, maybeWithdrawalRequest.orElseGet(List::of)); + this( + description, + block, + maybeWithdrawalRequest, + maybeWithdrawalRequest.orElseGet(java.util.List::of)); } public WithdrawalRequestTestParameter( diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java index 17fab89676a..a8ab887a2fb 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/AbstractIsolationTests.java @@ -256,7 +256,6 @@ private TestBlockCreator( protocolContext, protocolSchedule, parentHeader, - Optional.empty(), ethScheduler); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/LogRollingTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/LogRollingTests.java index e89747d5e3e..5c0dbbf7259 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/LogRollingTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/LogRollingTests.java @@ -98,7 +98,6 @@ class LogRollingTests { null, null, null, - null, new MainnetBlockHeaderFunctions()); private static final BlockHeader headerTwo = new BlockHeader( @@ -123,7 +122,6 @@ class LogRollingTests { null, null, null, - null, new MainnetBlockHeaderFunctions()); @BeforeEach diff --git a/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague2.json b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague2.json new file mode 100644 index 00000000000..e7bccadac0b --- /dev/null +++ b/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/chain/genesis_prague2.json @@ -0,0 +1,91 @@ +{ + "config": { + "ethash": {}, + "chainID": 1, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "constantinopleFixBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "terminalTotalDifficulty": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "pragueTime": 0 + }, + "nonce": "0x0", + "timestamp": "0x0", + "extraData": "0x00", + "gasLimit": "0x16345785d8a0000", + "difficulty": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "00000000219ab540356cbb839cbe05303d7705fa": { + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + }, + "balance": "0x0", + "nonce": "0x1" + }, + "000f3df6d732807ef1319fb7b8bb8522d0beac02": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", + "balance": "0x0", + "nonce": "0x1" + }, + "00a3ca265ebcb825b45f985a16cefb49958ce017": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd", + "balance": "0x0", + "nonce": "0x1" + }, + "25a219378dad9b3503c8268c9ca836a52427a4fb": { + "code": "0x60203611603157600143035f35116029575f356120000143116029576120005f3506545f5260205ff35b5f5f5260205ff35b5f5ffd00", + "balance": "0x0", + "nonce": "0x1" + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0xad78ebc5ac62000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "baseFeePerGas": "0x7", + "excessBlobGas": "0x0", + "blobGasUsed": "0x0" +} \ No newline at end of file diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTask.java index 7c6b275a7bd..56a85b040b0 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTask.java @@ -20,10 +20,9 @@ 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.Deposit; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Withdrawal; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; import org.hyperledger.besu.ethereum.eth.manager.PendingPeerRequest; @@ -152,43 +151,33 @@ static class BodyIdentifier { private final Bytes32 transactionsRoot; private final Bytes32 ommersHash; private final Bytes32 withdrawalsRoot; - private final Bytes32 depositsRoot; - private final Bytes32 withdrawalRequestsRoot; + private final Bytes32 requestsRoot; public BodyIdentifier( final Bytes32 transactionsRoot, final Bytes32 ommersHash, final Bytes32 withdrawalsRoot, - final Bytes32 depositsRoot, - final Bytes32 withdrawalRequestsRoot) { + final Bytes32 requestsRoot) { this.transactionsRoot = transactionsRoot; this.ommersHash = ommersHash; this.withdrawalsRoot = withdrawalsRoot; - this.depositsRoot = depositsRoot; - this.withdrawalRequestsRoot = withdrawalRequestsRoot; + this.requestsRoot = requestsRoot; } public BodyIdentifier(final BlockBody body) { - this( - body.getTransactions(), - body.getOmmers(), - body.getWithdrawals(), - body.getDeposits(), - body.getWithdrawalRequests()); + this(body.getTransactions(), body.getOmmers(), body.getWithdrawals(), body.getRequests()); } public BodyIdentifier( final List transactions, final List ommers, final Optional> withdrawals, - final Optional> deposits, - final Optional> withdrawalRequests) { + final Optional> requests) { this( BodyValidation.transactionsRoot(transactions), BodyValidation.ommersHash(ommers), withdrawals.map(BodyValidation::withdrawalsRoot).orElse(null), - deposits.map(BodyValidation::depositsRoot).orElse(null), - withdrawalRequests.map(BodyValidation::withdrawalRequestsRoot).orElse(null)); + requests.map(BodyValidation::requestsRoot).orElse(null)); } public BodyIdentifier(final BlockHeader header) { @@ -196,8 +185,7 @@ public BodyIdentifier(final BlockHeader header) { header.getTransactionsRoot(), header.getOmmersHash(), header.getWithdrawalsRoot().orElse(null), - header.getDepositsRoot().orElse(null), - header.getWithdrawalRequestsRoot().orElse(null)); + header.getRequestsRoot().orElse(null)); } @Override @@ -208,14 +196,12 @@ public boolean equals(final Object o) { return Objects.equals(transactionsRoot, that.transactionsRoot) && Objects.equals(ommersHash, that.ommersHash) && Objects.equals(withdrawalsRoot, that.withdrawalsRoot) - && Objects.equals(depositsRoot, that.depositsRoot) - && Objects.equals(withdrawalRequestsRoot, that.withdrawalRequestsRoot); + && Objects.equals(requestsRoot, that.requestsRoot); } @Override public int hashCode() { - return Objects.hash( - transactionsRoot, ommersHash, withdrawalsRoot, depositsRoot, withdrawalRequestsRoot); + return Objects.hash(transactionsRoot, ommersHash, withdrawalsRoot, requestsRoot); } } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTask.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTask.java index 5be7bedf29d..bdd59260e72 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTask.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/tasks/CompleteBlocksTask.java @@ -94,7 +94,6 @@ private BlockBody createEmptyBodyBasedOnProtocolSchedule( isWithdrawalsEnabled(protocolSchedule, header) ? Optional.of(Collections.emptyList()) : Optional.empty(), - Optional.empty(), Optional.empty()); } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTaskTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTaskTest.java index 6fd6378983c..b6c635551dd 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTaskTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/task/GetBodiesFromPeerTaskTest.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.Deposit; +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.ethtaskutils.PeerMessageTaskTest; @@ -79,12 +80,7 @@ public void assertBodyIdentifierUsesWithdrawalsToGenerateBodyIdentifiers() { final BlockBody emptyBodyBlock = BlockBody.empty(); // Block with no tx, no ommers, 1 withdrawal final BlockBody bodyBlockWithWithdrawal = - new BlockBody( - emptyList(), - emptyList(), - Optional.of(List.of(withdrawal)), - Optional.empty(), - Optional.empty()); + new BlockBody(emptyList(), emptyList(), Optional.of(List.of(withdrawal)), Optional.empty()); assertThat( new GetBodiesFromPeerTask.BodyIdentifier(emptyBodyBlock) @@ -94,7 +90,7 @@ public void assertBodyIdentifierUsesWithdrawalsToGenerateBodyIdentifiers() { @Test public void assertBodyIdentifierUsesDepositsToGenerateBodyIdentifiers() { - final Deposit deposit = + final Request deposit = new Deposit( BLSPublicKey.fromHexString( "0xb10a4a15bf67b328c9b101d09e5c6ee6672978fdad9ef0d9e2ceffaee99223555d8601f0cb3bcc4ce1af9864779a416e"), @@ -109,12 +105,7 @@ public void assertBodyIdentifierUsesDepositsToGenerateBodyIdentifiers() { final BlockBody emptyBodyBlock = BlockBody.empty(); // Block with no tx, no ommers, 1 deposit final BlockBody bodyBlockWithDeposit = - new BlockBody( - emptyList(), - emptyList(), - Optional.empty(), - Optional.of(List.of(deposit)), - Optional.empty()); + new BlockBody(emptyList(), emptyList(), Optional.empty(), Optional.of(List.of(deposit))); assertThat( new GetBodiesFromPeerTask.BodyIdentifier(emptyBodyBlock) @@ -123,8 +114,8 @@ public void assertBodyIdentifierUsesDepositsToGenerateBodyIdentifiers() { } @Test - public void assertBodyIdentifierUsesExitsToGenerateBodyIdentifiers() { - final WithdrawalRequest validatorExit = + public void assertBodyIdentifierUsesWithdrawalRequestsToGenerateBodyIdentifiers() { + final WithdrawalRequest withdrawalRequest = new WithdrawalRequest( Address.fromHexString("0x763c396673F9c391DCe3361A9A71C8E161388000"), BLSPublicKey.fromHexString( @@ -136,11 +127,7 @@ public void assertBodyIdentifierUsesExitsToGenerateBodyIdentifiers() { // Block with no tx, no ommers, 1 validator exit final BlockBody bodyBlockWithValidatorExit = new BlockBody( - emptyList(), - emptyList(), - Optional.empty(), - Optional.empty(), - Optional.of(List.of(validatorExit))); + emptyList(), emptyList(), Optional.empty(), Optional.of(List.of(withdrawalRequest))); assertThat( new GetBodiesFromPeerTask.BodyIdentifier(emptyBodyBlock) diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java index b6a0babfa1e..78fcbb1c085 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java @@ -260,7 +260,6 @@ public void readFromExpectsListWrappingBodyFields() { Collections.emptyList(), Collections.emptyList(), Optional.of(Collections.emptyList()), - Optional.empty(), Optional.empty())); } @@ -286,7 +285,6 @@ public void readBodyFieldsExpectsNoListWrappingBodyFields() { Collections.emptyList(), Collections.emptyList(), Optional.of(Collections.emptyList()), - Optional.empty(), Optional.empty())); } @@ -402,7 +400,6 @@ public TestBlockHeader( null, null, null, - null, new MainnetBlockHeaderFunctions()); } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncContextTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncContextTest.java index 783d8775302..9afba66ad3a 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncContextTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/BackwardSyncContextTest.java @@ -155,7 +155,8 @@ public void setup() { // use forest-based worldstate since it does not require // blockheader stateroot to match actual worldstate root ForestReferenceTestWorldState.create(Collections.emptyMap()), - blockDataGenerator.receipts(block)))); + blockDataGenerator.receipts(block), + Optional.empty()))); }); backwardChain = inMemoryBackwardChain(); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java index 931105faa4c..82d5de4f38c 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/sync/backwardsync/ChainForTestCreator.java @@ -61,7 +61,6 @@ public static BlockHeader prepareHeader(final long number, final Optional expectedBlocks = asList(block1, block2); @@ -169,7 +167,6 @@ public void shouldCompleteBlockThatOnlyContainsWithdrawals_whenWithdrawalsAreEna Collections.emptyList(), Collections.emptyList(), Optional.of(withdrawals), - Optional.empty(), Optional.empty())); final Block block3 = new Block( @@ -178,7 +175,6 @@ public void shouldCompleteBlockThatOnlyContainsWithdrawals_whenWithdrawalsAreEna Collections.emptyList(), Collections.emptyList(), Optional.of(Collections.emptyList()), - Optional.empty(), Optional.empty())); final List expected = asList(block1, block2, block3); diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java index c8686a8881e..378637f3634 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java @@ -27,14 +27,13 @@ import org.hyperledger.besu.ethereum.core.BlockBody; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; -import org.hyperledger.besu.ethereum.core.Deposit; import org.hyperledger.besu.ethereum.core.Difficulty; import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.ParsedExtraData; +import org.hyperledger.besu.ethereum.core.Request; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Withdrawal; -import org.hyperledger.besu.ethereum.core.WithdrawalRequest; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; import org.hyperledger.besu.ethereum.rlp.RLPInput; @@ -165,8 +164,7 @@ public ReferenceTestBlockHeader( @JsonProperty("mixHash") final String mixHash, @JsonProperty("nonce") final String nonce, @JsonProperty("withdrawalsRoot") final String withdrawalsRoot, - @JsonProperty("depositsRoot") final String depositsRoot, - @JsonProperty("withdrawalRequestsRoot") final String withdrawalRequestsRoot, + @JsonProperty("requestsRoot") final String requestsRoot, @JsonProperty("dataGasUsed") final String dataGasUsed, // TODO: remove once reference tests have been updated @JsonProperty("excessDataGas") @@ -204,8 +202,7 @@ public ReferenceTestBlockHeader( ? BlobGas.fromHexString(excessDataGas) : excessBlobGas != null ? BlobGas.fromHexString(excessBlobGas) : null, parentBeaconBlockRoot != null ? Bytes32.fromHexString(parentBeaconBlockRoot) : null, - depositsRoot != null ? Hash.fromHexString(depositsRoot) : null, - withdrawalRequestsRoot != null ? Hash.fromHexString(withdrawalRequestsRoot) : null, + requestsRoot != null ? Hash.fromHexString(requestsRoot) : null, new BlockHeaderFunctions() { @Override public Hash hash(final BlockHeader header) { @@ -250,7 +247,9 @@ public CandidateBlock( @JsonProperty("blockHeader") final Object blockHeader, @JsonProperty("transactions") final Object transactions, @JsonProperty("uncleHeaders") final Object uncleHeaders, - @JsonProperty("withdrawals") final Object withdrawals) { + @JsonProperty("withdrawals") final Object withdrawals, + @JsonProperty("depositRequests") final Object depositRequests, + @JsonProperty("withdrawalRequests") final Object withdrawalRequests) { boolean blockVaid = true; // The BLOCK__WrongCharAtRLP_0 test has an invalid character in its rlp string. Bytes rlpAttempt = null; @@ -293,10 +292,7 @@ public Block getBlock() { : Optional.of(input.readList(Withdrawal::readFrom)), input.isEndOfCurrentList() ? Optional.empty() - : Optional.of(input.readList(Deposit::readFrom)), - input.isEndOfCurrentList() - ? Optional.empty() - : Optional.of(input.readList(WithdrawalRequest::readFrom))); + : Optional.of(input.readList(Request::readFrom))); return new Block(header, body); } } diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java index d8e1930a9ed..3cd248e3aef 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestEnv.java @@ -142,8 +142,7 @@ public ReferenceTestEnv( currentBlobGasUsed == null ? null : Long.decode(currentBlobGasUsed), currentExcessBlobGas == null ? null : BlobGas.of(Long.decode(currentExcessBlobGas)), beaconRoot == null ? null : Bytes32.fromHexString(beaconRoot), - null, // depositsRoot - null, // withdrawalRequestsRoot + null, // requestsRoot new MainnetBlockHeaderFunctions()); this.parentDifficulty = parentDifficulty; this.parentBaseFee = parentBaseFee; diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java index 1f56597b07d..dc32da71889 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java @@ -55,7 +55,7 @@ public class BlockchainReferenceTestTools { "test.ethereum.blockchain.eips", "FrontierToHomesteadAt5,HomesteadToEIP150At5,HomesteadToDaoAt5,EIP158ToByzantiumAt5," + "Frontier,Homestead,EIP150,EIP158,Byzantium,Constantinople,ConstantinopleFix,Istanbul,Berlin," - + "London,Merge,Paris,Shanghai,Cancun,Prague,Osaka,Bogota"); + + "London,Merge,Paris,Shanghai,Cancun,Prague,Osaka,Bogota,CancunToPragueAtTime15k"); NETWORKS_TO_RUN = Arrays.asList(networks.split(",")); } diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java index cc8d794ce89..99210f57d29 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java @@ -88,8 +88,8 @@ public ProtocolSpec getByBlockHeader(final ProcessableBlockHeader blockHeader) { Optional.empty(), original.getWithdrawalsValidator(), original.getWithdrawalsProcessor(), - original.getDepositsValidator(), - original.getWithdrawalRequestValidator(), + original.getRequestsValidatorCoordinator(), + original.getRequestProcessorCoordinator(), original.getBlockHashProcessor(), original.isPoS(), original.isReplayProtectionSupported()); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java index 453dff9ce50..ef07ea46d19 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/SelfDestructOperation.java @@ -68,7 +68,7 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { gasCalculator().selfDestructOperationGasCost(beneficiaryNullable, originatorBalance) + (beneficiaryIsWarm ? 0L : gasCalculator().getColdAccountAccessCost()); - // With the cost we can test for two early exits: static or not enough gas. + // With the cost we can test for two early WithdrawalRequests: static or not enough gas. if (frame.isStatic()) { return new OperationResult(cost, ExceptionalHaltReason.ILLEGAL_STATE_CHANGE); } else if (frame.getRemainingGas() < cost) { diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index f0135ec91d1..f61fe316bf3 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -70,7 +70,7 @@ Calculated : ${currentHash} tasks.register('checkAPIChanges', FileStateChecker) { description = "Checks that the API for the Plugin-API project does not change without deliberate thought" files = sourceSets.main.allJava.files - knownHash = 'w+IKkNGNQSO4AECcQMEeYX0TriGTdBSFSx5e7e10yuk=' + knownHash = 'xU0LMvStiFihBKBxkfNHB7oIg0PUHWkPuv2yt1GVC94=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockBody.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockBody.java index 0432fb4d77e..18a5e07ce6a 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockBody.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockBody.java @@ -49,18 +49,10 @@ public interface BlockBody { Optional> getWithdrawals(); /** - * Returns the list of deposits of the block. + * Returns the list of requests of the block. * - * @return The list of deposits of the block. + * @return The list of requests of the block. */ @Unstable - Optional> getDeposits(); - - /** - * Returns the list of withdrawal requests of the block. - * - * @return The list of withdrawal requests of the block. - */ - @Unstable - Optional> getWithdrawalRequests(); + Optional> getRequests(); } diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java index 90d6ab89443..ed8d6b87456 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java @@ -121,31 +121,20 @@ public interface BlockHeader extends ProcessableBlockHeader { Optional getWithdrawalsRoot(); /** - * The Keccak 256-bit hash of the root node of the trie structure populated with each deposit in - * the deposits list portion of the block. + * The Keccak 256-bit hash of the root node of the trie structure populated with each request in + * the request list portion of the block. * * @return The Keccak 256-bit hash of the root node of the trie structure populated with each - * deposit in the deposit list portion of the block. + * request in the request list portion of the block. */ @Unstable - Optional getDepositsRoot(); - - /** - * The Keccak 256-bit hash of the root node of the trie structure populated with each withdrawal - * request in the withdrawal request list portion of the block. - * - * @return The Keccak 256-bit hash of the root node of the trie structure populated with each - * withdrawal request in the withdrawal request list portion of the block. - */ - @Unstable - Optional getWithdrawalRequestsRoot(); + Optional getRequestsRoot(); /** * The excess_blob_gas of this header. * * @return The excess_blob_gas of this header. */ - @Unstable Optional getExcessBlobGas(); /** @@ -153,6 +142,5 @@ public interface BlockHeader extends ProcessableBlockHeader { * * @return The blob_gas_used of this header. */ - @Unstable Optional getBlobGasUsed(); } diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/Request.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/Request.java new file mode 100644 index 00000000000..2540f91098b --- /dev/null +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/Request.java @@ -0,0 +1,30 @@ +/* + * 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.plugin.data; + +import org.hyperledger.besu.datatypes.RequestType; +import org.hyperledger.besu.plugin.Unstable; + +/** A request is an operation sent to the Beacon Node */ +@Unstable +public interface Request { + + /** + * Retrieves the type of this request. + * + * @return The {@link RequestType} representing the type of this request. + */ + RequestType getType(); +}