Base EIP-6110 on top of Cancun (#5752)

This is to base the existed implementation of EIP-6110 from Shanghai to Cancun. As well, it updates the implementation according to the latest Engine API specification.

Changes include:
-  Remove 6110 related changes from engine_newPayloadV2 and engine_getPayloadV2
-  Rename deposits to depositReceipts in EnginePayloadParameter
-  Introduce engine_newPayloadV6110 and engine_getPayloadV6110 that are based on engine_newPayloadV3 and engine_getPayloadV3
-  Revamp the existed 6110 acceptance test

---

Signed-off-by: Navie Chan <naviechan@gmail.com>
Signed-off-by: naviechan <adrninistrator1@protonmail.com>
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
This commit is contained in:
NC
2023-10-10 13:32:40 +08:00
committed by GitHub
parent e8a0428a27
commit 0536a18bdc
31 changed files with 975 additions and 330 deletions

View File

@@ -20,12 +20,10 @@ import java.net.URISyntaxException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
@Ignore("EIP-6110 is not yet implemented")
public class ExecutionEngineEip6110AcceptanceTest extends AbstractJsonRpcTest {
private static final String GENESIS_FILE = "/jsonrpc/engine/eip6110/genesis.json";
private static final String TEST_CASE_PATH = "/jsonrpc/engine/eip6110/test-cases/";

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,34 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_forkchoiceUpdatedV3",
"params": [
{
"headBlockHash": "0x26118cf71453320edcebbc4ebb34af5b578087a32385b80108bf691fa23efc42",
"safeBlockHash": "0x26118cf71453320edcebbc4ebb34af5b578087a32385b80108bf691fa23efc42",
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
},
{
"timestamp": "0x10",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"suggestedFeeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"withdrawals": [],
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": {
"payloadStatus": {
"status": "VALID",
"latestValidHash": "0x26118cf71453320edcebbc4ebb34af5b578087a32385b80108bf691fa23efc42",
"validationError": null
},
"payloadId": "0x282643c14de2dfef"
}
},
"statusCode" : 200
}

View File

@@ -1,46 +0,0 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_forkchoiceUpdatedV2",
"params": [
{
"headBlockHash": "0xfe950635b1bd2a416ff6283b0bbd30176e1b1125ad06fa729da9f3f4c1c61710",
"safeBlockHash": "0xfe950635b1bd2a416ff6283b0bbd30176e1b1125ad06fa729da9f3f4c1c61710",
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
},
{
"timestamp": "0x10",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"suggestedFeeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"withdrawals": [
{
"index": "0x0",
"validatorIndex": "0x0",
"address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"amount": "0x3"
},
{
"index": "0x1",
"validatorIndex": "0x1",
"address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
"amount": "0x4"
}
]
}
],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": {
"payloadStatus": {
"status": "VALID",
"latestValidHash": "0xfe950635b1bd2a416ff6283b0bbd30176e1b1125ad06fa729da9f3f4c1c61710",
"validationError": null
},
"payloadId": "0x0065bd1bbeaff359"
}
},
"statusCode" : 200
}

View File

@@ -1,9 +1,9 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_getPayloadV2",
"method": "engine_getPayloadV3",
"params": [
"0x0065bd1bbeaff359"
"0x282643c14de2dfef"
],
"id": 67
},
@@ -12,9 +12,9 @@
"id": 67,
"result": {
"executionPayload": {
"parentHash": "0xfe950635b1bd2a416ff6283b0bbd30176e1b1125ad06fa729da9f3f4c1c61710",
"parentHash": "0x26118cf71453320edcebbc4ebb34af5b578087a32385b80108bf691fa23efc42",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0xc8c8e840369eac89a610bfe2ec21fcdee4c9c43bec4876f0129fcd4b5311f6dd",
"stateRoot": "0x23e3e21a839dbba902efaad82e5c3e1ddd64ea067ce0f979a68dabcc46be4e8b",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380",
@@ -22,27 +22,22 @@
"timestamp": "0x10",
"extraData": "0x",
"baseFeePerGas": "0x7",
"excessBlobGas" : "0x0",
"parentBeaconBlockRoot" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactions": [],
"withdrawals": [
{
"index": "0x0",
"validatorIndex": "0x0",
"address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"amount": "0x3"
},
{
"index": "0x1",
"validatorIndex": "0x1",
"address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
"amount": "0x4"
}
],
"deposits": null,
"withdrawals": [],
"blockNumber": "0x1",
"blockHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"blockHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"blobGasUsed" : "0x0"
},
"blockValue": "0x0"
"blockValue": "0x0",
"blobsBundle" : {
"commitments" : [],
"proofs" : [],
"blobs" : []
},
"shouldOverrideBuilder" : false
}
},
"statusCode": 200

View File

@@ -1,12 +1,12 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_newPayloadV2",
"method": "engine_newPayloadV3",
"params": [
{
"parentHash": "0xfe950635b1bd2a416ff6283b0bbd30176e1b1125ad06fa729da9f3f4c1c61710",
"parentHash": "0x26118cf71453320edcebbc4ebb34af5b578087a32385b80108bf691fa23efc42",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0xc8c8e840369eac89a610bfe2ec21fcdee4c9c43bec4876f0129fcd4b5311f6dd",
"stateRoot": "0x23e3e21a839dbba902efaad82e5c3e1ddd64ea067ce0f979a68dabcc46be4e8b",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380",
@@ -15,24 +15,15 @@
"extraData": "0x",
"baseFeePerGas": "0x7",
"transactions": [],
"withdrawals": [
{
"index": "0x0",
"validatorIndex": "0x0",
"address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"amount": "0x3"
},
{
"index": "0x1",
"validatorIndex": "0x1",
"address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
"amount": "0x4"
}
],
"withdrawals": [],
"blockNumber": "0x1",
"blockHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
}
"blockHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"excessBlobGas" : "0x0",
"blobGasUsed" : "0x0"
},
[],
"0x0000000000000000000000000000000000000000000000000000000000000000"
],
"id": 67
},
@@ -41,7 +32,7 @@
"id": 67,
"result": {
"status": "VALID",
"latestValidHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"latestValidHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"validationError": null
}
},

View File

@@ -0,0 +1,28 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_forkchoiceUpdatedV3",
"params": [
{
"headBlockHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"safeBlockHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"finalizedBlockHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c"
},
null
],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": {
"payloadStatus": {
"status": "VALID",
"latestValidHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"validationError": null
},
"payloadId": null
}
},
"statusCode": 200
}

View File

@@ -1,28 +0,0 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_forkchoiceUpdatedV2",
"params": [
{
"headBlockHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"safeBlockHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"finalizedBlockHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13"
},
null
],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": {
"payloadStatus": {
"status": "VALID",
"latestValidHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"validationError": null
},
"payloadId": null
}
},
"statusCode": 200
}

View File

@@ -0,0 +1,34 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_forkchoiceUpdatedV3",
"params": [
{
"headBlockHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"safeBlockHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
},
{
"timestamp": "0x20",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"suggestedFeeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"withdrawals": [],
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": {
"payloadStatus": {
"status": "VALID",
"latestValidHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"validationError": null
},
"payloadId": "0x282643962616abdf"
}
},
"statusCode" : 200
}

View File

@@ -1,46 +0,0 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_forkchoiceUpdatedV2",
"params": [
{
"headBlockHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"safeBlockHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
},
{
"timestamp": "0x20",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"suggestedFeeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"withdrawals": [
{
"index": "0x0",
"validatorIndex": "0x0",
"address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"amount": "0x1"
},
{
"index": "0x1",
"validatorIndex": "0x0",
"address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
"amount": "0x2"
}
]
}
],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": {
"payloadStatus": {
"status": "VALID",
"latestValidHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"validationError": null
},
"payloadId": "0x0065bd63871ad606"
}
},
"statusCode" : 200
}

View File

@@ -1,9 +1,9 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_getPayloadV2",
"method": "engine_getPayloadV6110",
"params": [
"0x0065bd63871ad606"
"0x282643962616abdf"
],
"id": 67
},
@@ -12,9 +12,9 @@
"id": 67,
"result": {
"executionPayload": {
"parentHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"parentHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x21395692fae33414143728c9ffc0aed8dcc76eb6731dd0f5a3239977478ca969",
"stateRoot": "0x6a88816cf7e94f1f44cf82c63521bb7f2e49e99ab0ad2e4e46ef1ab8f6ccad84",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380",
@@ -22,27 +22,23 @@
"timestamp": "0x20",
"extraData": "0x",
"baseFeePerGas": "0x7",
"excessBlobGas" : "0x0",
"parentBeaconBlockRoot" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactions": [],
"withdrawals": [
{
"index": "0x0",
"validatorIndex": "0x0",
"address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"amount": "0x1"
},
{
"index": "0x1",
"validatorIndex": "0x0",
"address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
"amount": "0x2"
}
],
"deposits" : [],
"withdrawals": [],
"depositReceipts" : [],
"blockNumber": "0x2",
"blockHash": "0x4c4418c408aeadb4659d31d1c05108f26fabf713bb6f8cc487dba8424a725bf5",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
"blockHash": "0x6d4f567f7afe59226a1400fd0c11797f0bb69bec74b8eb99a066f899e0bd1d0f",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"blobGasUsed" : "0x0"
},
"blockValue": "0x0"
"blockValue": "0x0",
"blobsBundle" : {
"commitments" : [],
"proofs" : [],
"blobs" : []
},
"shouldOverrideBuilder" : false
}
},
"statusCode": 200

View File

@@ -0,0 +1,14 @@
{
"request": {
"jsonrpc": "2.0",
"method": "eth_sendRawTransaction",
"params": ["0x02f9021c8217de808459682f008459682f0e830271009442424242424242424242424242424242424242428901bc16d674ec800000b901a422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120749715de5d1226545c6b3790f515d551a5cc5bf1d49c87a696860554d2fc4f14000000000000000000000000000000000000000000000000000000000000003096a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef20000000000000000000000000000000000000000000000000000000000000060b1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9c080a09f597089338d7f44f5c59f8230bb38f243849228a8d4e9d2e2956e6050f5b2c7a076486996c7e62802b8f95eee114783e4b403fd11093ba96286ff42c595f24452"],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": "0x8ff1a50169f52f14cc1cf0300ec037c054a9b99df462e6372c7ca655bf1f00cd"
},
"statusCode": 200
}

View File

@@ -1,50 +0,0 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_newPayloadV2",
"params": [
{
"parentHash": "0xfdd94e3620a88f08927bffb318981a36b663a26e6fd62ab273eb800b90723c13",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x21395692fae33414143728c9ffc0aed8dcc76eb6731dd0f5a3239977478ca969",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380",
"gasUsed": "0x0",
"timestamp": "0x20",
"extraData": "0x",
"baseFeePerGas": "0x7",
"transactions": [],
"withdrawals": [
{
"index": "0x0",
"validatorIndex": "0x0",
"address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"amount": "0x1"
},
{
"index": "0x1",
"validatorIndex": "0x0",
"address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
"amount": "0x2"
}
],
"deposits": [],
"blockNumber": "0x2",
"blockHash": "0xdfdf57a09e352c38bb2873c5fd7d0d199481c6e13661c4a004d116417377b2e5",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
}
],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": {
"status": "VALID",
"latestValidHash": "0xdfdf57a09e352c38bb2873c5fd7d0d199481c6e13661c4a004d116417377b2e5",
"validationError": null
}
},
"statusCode": 200
}

View File

@@ -1,12 +1,12 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_newPayloadV2",
"method": "engine_newPayloadV6110",
"params": [
{
"parentHash": "0x4f88d512a0045bc6d447ba74a18eac0ed2ebb8d9faca325f5f55b2ca84be0705",
"parentHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x1a10dba514dc4faff7ec13edd9b5ef653c1cd14eb26608bfc2b37717730a55a4",
"stateRoot": "0x6a88816cf7e94f1f44cf82c63521bb7f2e49e99ab0ad2e4e46ef1ab8f6ccad84",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380",
@@ -14,26 +14,17 @@
"timestamp": "0x20",
"extraData": "0x",
"baseFeePerGas": "0x7",
"excessBlobGas" : "0x0",
"transactions": [],
"withdrawals": [
{
"index": "0x0",
"validatorIndex": "0x0",
"address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"amount": "0x1"
},
{
"index": "0x1",
"validatorIndex": "0x0",
"address": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
"amount": "0x2"
}
],
"deposits": null,
"blockNumber": "0x3",
"blockHash": "0x1475ca311179652e44b10b7e2d7b72f3708f3201f8d729880a83f3eb397910e8",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
}
"withdrawals": [],
"depositReceipts" : null,
"blockNumber": "0x2",
"blockHash": "0x6d4f567f7afe59226a1400fd0c11797f0bb69bec74b8eb99a066f899e0bd1d0f",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"blobGasUsed" : "0x0"
},
[],
"0x0000000000000000000000000000000000000000000000000000000000000000"
],
"id": 67
},
@@ -42,7 +33,8 @@
"id": 67,
"error": {
"code": -32602,
"message": "Invalid params"
"message": "Invalid params",
"data" : "Missing deposit field"
}
},
"statusCode": 200

View File

@@ -0,0 +1,45 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_newPayloadV6110",
"params": [
{
"parentHash": "0x17da7aea0f4e4ba1d905dbb7d60f6ab4133f3009ae1a1ba99e6e9cb37c15412c",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x7ffa22d9c7d856687bbec0700c17288ee6aff2bfd14e92a8921b08ed1d0c6030",
"logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380",
"gasUsed": "0x14B6E",
"timestamp": "0x20",
"extraData": "0x",
"baseFeePerGas": "0x7",
"excessBlobGas" : "0x0",
"transactions": [
"0x02f9021c8217de808459682f008459682f0e830271009442424242424242424242424242424242424242428901bc16d674ec800000b901a422895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120749715de5d1226545c6b3790f515d551a5cc5bf1d49c87a696860554d2fc4f14000000000000000000000000000000000000000000000000000000000000003096a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef20000000000000000000000000000000000000000000000000000000000000060b1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9c080a09f597089338d7f44f5c59f8230bb38f243849228a8d4e9d2e2956e6050f5b2c7a076486996c7e62802b8f95eee114783e4b403fd11093ba96286ff42c595f24452"
],
"withdrawals": [],
"depositReceipts" : [
{"amount":"0x773594000","index":"0x0","pubkey":"0x96a96086cff07df17668f35f7418ef8798079167e3f4f9b72ecde17b28226137cf454ab1dd20ef5d924786ab3483c2f9","signature":"0xb1acdb2c4d3df3f1b8d3bfd33421660df358d84d78d16c4603551935f4b67643373e7eb63dcb16ec359be0ec41fee33b03a16e80745f2374ff1d3c352508ac5d857c6476d3c3bcf7e6ca37427c9209f17be3af5264c0e2132b3dd1156c28b4e9","withdrawalCredentials":"0x003f5102dabe0a27b1746098d1dc17a5d3fbd478759fea9287e4e419b3c3cef2"}
],
"blockNumber": "0x2",
"blockHash": "0xe6763c709abac0b477073c1efd980e12728c1ea22361c03e41db6fbd6a271832",
"receiptsRoot": "0x79ee3424eb720a3ad4b1c5a372bb8160580cbe4d893778660f34213c685627a9",
"blobGasUsed" : "0x0"
},
[],
"0x0000000000000000000000000000000000000000000000000000000000000000"
],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": {
"status": "VALID",
"latestValidHash": "0xe6763c709abac0b477073c1efd980e12728c1ea22361c03e41db6fbd6a271832",
"validationError": null
}
},
"statusCode": 200
}

View File

@@ -0,0 +1,34 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_forkchoiceUpdatedV3",
"params": [
{
"headBlockHash": "0xe6763c709abac0b477073c1efd980e12728c1ea22361c03e41db6fbd6a271832",
"safeBlockHash": "0xe6763c709abac0b477073c1efd980e12728c1ea22361c03e41db6fbd6a271832",
"finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
},
{
"timestamp": "0x30",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"suggestedFeeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"withdrawals": [],
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": {
"payloadStatus": {
"status": "VALID",
"latestValidHash": "0xe6763c709abac0b477073c1efd980e12728c1ea22361c03e41db6fbd6a271832",
"validationError": null
},
"payloadId": "0x28264382a1f291cf"
}
},
"statusCode" : 200
}

View File

@@ -0,0 +1,45 @@
{
"request": {
"jsonrpc": "2.0",
"method": "engine_getPayloadV6110",
"params": [
"0x28264382a1f291cf"
],
"id": 67
},
"response": {
"jsonrpc": "2.0",
"id": 67,
"result": {
"executionPayload": {
"parentHash": "0xe6763c709abac0b477073c1efd980e12728c1ea22361c03e41db6fbd6a271832",
"feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"stateRoot": "0x2d60598bb65d4a9451c097884d1fb07e015c242e2a3475f4ef902ed23e319d3b",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x1c9c380",
"gasUsed": "0x0",
"timestamp": "0x30",
"extraData": "0x",
"baseFeePerGas": "0x7",
"excessBlobGas" : "0x0",
"parentBeaconBlockRoot" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactions": [],
"withdrawals": [],
"depositReceipts" : [],
"blockNumber": "0x3",
"blockHash": "0xa489adae4826ac6a342c382243e8841d3e3b33168e7fd6e31b2c36c17a25f702",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"blobGasUsed" : "0x0"
},
"blockValue": "0x0",
"blobsBundle" : {
"commitments" : [],
"proofs" : [],
"blobs" : []
},
"shouldOverrideBuilder" : false
}
},
"statusCode": 200
}

View File

@@ -37,7 +37,6 @@
"amount": "0x2"
}
],
"deposits": null,
"blockNumber": "0x2",
"blockHash": "0x612abd8615f544759d4aeb3dbab32f5f198a8b818e9c5436e9f7a674ef3b0f20",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"

View File

@@ -53,9 +53,11 @@ public enum RpcMethod {
ENGINE_GET_PAYLOAD_V1("engine_getPayloadV1"),
ENGINE_GET_PAYLOAD_V2("engine_getPayloadV2"),
ENGINE_GET_PAYLOAD_V3("engine_getPayloadV3"),
ENGINE_GET_PAYLOAD_V6110("engine_getPayloadV6110"),
ENGINE_NEW_PAYLOAD_V1("engine_newPayloadV1"),
ENGINE_NEW_PAYLOAD_V2("engine_newPayloadV2"),
ENGINE_NEW_PAYLOAD_V3("engine_newPayloadV3"),
ENGINE_NEW_PAYLOAD_V6110("engine_newPayloadV6110"),
ENGINE_FORKCHOICE_UPDATED_V1("engine_forkchoiceUpdatedV1"),
ENGINE_FORKCHOICE_UPDATED_V2("engine_forkchoiceUpdatedV2"),
ENGINE_FORKCHOICE_UPDATED_V3("engine_forkchoiceUpdatedV3"),

View File

@@ -63,6 +63,7 @@ public class EngineExchangeCapabilities extends ExecutionEngineJsonRpcMethod {
.filter(e -> e.getMethodName().startsWith("engine_"))
.filter(e -> !e.equals(ENGINE_EXCHANGE_CAPABILITIES))
.filter(e -> !e.equals(ENGINE_PREPARE_PAYLOAD_DEBUG))
.filter(e -> !e.getMethodName().endsWith("6110"))
.map(RpcMethod::getMethodName)
.collect(Collectors.toList());

View File

@@ -0,0 +1,87 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
import org.hyperledger.besu.consensus.merge.blockcreation.PayloadIdentifier;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory;
import org.hyperledger.besu.ethereum.core.BlockWithReceipts;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import java.util.Optional;
import io.vertx.core.Vertx;
public class EngineGetPayloadV6110 extends AbstractEngineGetPayload {
private final Optional<ScheduledProtocolSpec.Hardfork> eip6110;
public EngineGetPayloadV6110(
final Vertx vertx,
final ProtocolContext protocolContext,
final MergeMiningCoordinator mergeMiningCoordinator,
final BlockResultFactory blockResultFactory,
final EngineCallListener engineCallListener,
final ProtocolSchedule schedule) {
super(
vertx,
schedule,
protocolContext,
mergeMiningCoordinator,
blockResultFactory,
engineCallListener);
this.eip6110 = schedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("ExperimentalEips"));
}
@Override
public String getName() {
return RpcMethod.ENGINE_GET_PAYLOAD_V6110.getMethodName();
}
@Override
protected JsonRpcResponse createResponse(
final JsonRpcRequestContext request,
final PayloadIdentifier payloadId,
final BlockWithReceipts blockWithReceipts) {
return new JsonRpcSuccessResponse(
request.getRequest().getId(),
blockResultFactory.payloadTransactionCompleteV6110(blockWithReceipts));
}
@Override
protected ValidationResult<RpcErrorType> validateForkSupported(final long blockTimestamp) {
if (protocolSchedule.isPresent()) {
if (eip6110.isPresent() && blockTimestamp >= eip6110.get().milestone()) {
return ValidationResult.valid();
} else {
return ValidationResult.invalid(
RpcErrorType.UNSUPPORTED_FORK,
"EIP-6110 configured to start at timestamp: " + eip6110.get().milestone());
}
} else {
return ValidationResult.invalid(
RpcErrorType.UNSUPPORTED_FORK, "Configuration error, no schedule for EIP-6110 fork set");
}
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.EnginePayloadParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import java.util.List;
import java.util.Optional;
import io.vertx.core.Vertx;
public class EngineNewPayloadV6110 extends AbstractEngineNewPayload {
private final Optional<ScheduledProtocolSpec.Hardfork> eip6110;
public EngineNewPayloadV6110(
final Vertx vertx,
final ProtocolSchedule timestampSchedule,
final ProtocolContext protocolContext,
final MergeMiningCoordinator mergeCoordinator,
final EthPeers ethPeers,
final EngineCallListener engineCallListener) {
super(
vertx, timestampSchedule, protocolContext, mergeCoordinator, ethPeers, engineCallListener);
this.eip6110 =
timestampSchedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("ExperimentalEips"));
}
@Override
public String getName() {
return RpcMethod.ENGINE_NEW_PAYLOAD_V6110.getMethodName();
}
@Override
protected ValidationResult<RpcErrorType> validateParameters(
final EnginePayloadParameter payloadParameter,
final Optional<List<String>> maybeVersionedHashParam,
final Optional<String> maybeBeaconBlockRootParam) {
if (payloadParameter.getBlobGasUsed() == null || payloadParameter.getExcessBlobGas() == null) {
return ValidationResult.invalid(RpcErrorType.INVALID_PARAMS, "Missing blob gas fields");
} else if (maybeVersionedHashParam == null || maybeVersionedHashParam.isEmpty()) {
return ValidationResult.invalid(
RpcErrorType.INVALID_PARAMS, "Missing versioned hashes field");
} else if (maybeBeaconBlockRootParam.isEmpty()) {
return ValidationResult.invalid(
RpcErrorType.INVALID_PARAMS, "Missing parent beacon block root field");
} else if (payloadParameter.getDeposits() == null) {
return ValidationResult.invalid(RpcErrorType.INVALID_PARAMS, "Missing deposit field");
} else {
return ValidationResult.valid();
}
}
@Override
protected ValidationResult<RpcErrorType> validateForkSupported(final long blockTimestamp) {
if (protocolSchedule.isPresent()) {
if (eip6110.isPresent() && blockTimestamp >= eip6110.get().milestone()) {
return ValidationResult.valid();
} else {
return ValidationResult.invalid(
RpcErrorType.UNSUPPORTED_FORK,
"EIP-6110 configured to start at timestamp: " + eip6110.get().milestone());
}
} else {
return ValidationResult.invalid(
RpcErrorType.UNSUPPORTED_FORK, "Configuration error, no schedule for EIP-6110 fork set");
}
}
}

View File

@@ -86,7 +86,7 @@ public class EnginePayloadParameter {
@JsonProperty("withdrawals") final List<WithdrawalParameter> withdrawals,
@JsonProperty("blobGasUsed") final UnsignedLongParameter blobGasUsed,
@JsonProperty("excessBlobGas") final String excessBlobGas,
@JsonProperty("deposits") final List<DepositParameter> deposits) {
@JsonProperty("depositReceipts") final List<DepositParameter> deposits) {
this.blockHash = blockHash;
this.parentHash = parentHash;
this.feeRecipient = feeRecipient;

View File

@@ -120,7 +120,6 @@ public class BlockResultFactory {
blockWithReceipts.getHeader(),
txs,
blockWithReceipts.getBlock().getBody().getWithdrawals(),
blockWithReceipts.getBlock().getBody().getDeposits(),
Quantity.create(blockValue));
}
@@ -155,6 +154,29 @@ public class BlockResultFactory {
blobsBundleV1);
}
public EngineGetPayloadResultV6110 payloadTransactionCompleteV6110(
final BlockWithReceipts blockWithReceipts) {
final List<String> txs =
blockWithReceipts.getBlock().getBody().getTransactions().stream()
.map(
transaction ->
TransactionEncoder.encodeOpaqueBytes(transaction, EncodingContext.BLOCK_BODY))
.map(Bytes::toHexString)
.collect(Collectors.toList());
final Wei blockValue = new BlockValueCalculator().calculateBlockValue(blockWithReceipts);
final BlobsBundleV1 blobsBundleV1 =
new BlobsBundleV1(blockWithReceipts.getBlock().getBody().getTransactions());
return new EngineGetPayloadResultV6110(
blockWithReceipts.getHeader(),
txs,
blockWithReceipts.getBlock().getBody().getWithdrawals(),
blockWithReceipts.getBlock().getBody().getDeposits(),
Quantity.create(blockValue),
blobsBundleV1);
}
public BlockResult transactionHash(final BlockWithMetadata<Hash, Hash> blockWithMetadata) {
return transactionHash(blockWithMetadata, false);
}

View File

@@ -14,10 +14,8 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Deposit;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import java.util.List;
@@ -41,9 +39,8 @@ public class EngineGetPayloadResultV2 {
final BlockHeader header,
final List<String> transactions,
final Optional<List<Withdrawal>> withdrawals,
final Optional<List<Deposit>> deposits,
final String blockValue) {
this.executionPayload = new PayloadResult(header, transactions, withdrawals, deposits);
this.executionPayload = new PayloadResult(header, transactions, withdrawals);
this.blockValue = blockValue;
}
@@ -74,13 +71,11 @@ public class EngineGetPayloadResultV2 {
private final String baseFeePerGas;
protected final List<String> transactions;
private final List<WithdrawalParameter> withdrawals;
private final List<DepositParameter> deposits;
public PayloadResult(
final BlockHeader header,
final List<String> transactions,
final Optional<List<Withdrawal>> withdrawals,
final Optional<List<Deposit>> deposits) {
final Optional<List<Withdrawal>> withdrawals) {
this.blockNumber = Quantity.create(header.getNumber());
this.blockHash = header.getHash().toString();
this.parentHash = header.getParentHash().toString();
@@ -103,11 +98,6 @@ public class EngineGetPayloadResultV2 {
.map(WithdrawalParameter::fromWithdrawal)
.collect(Collectors.toList()))
.orElse(null);
this.deposits =
deposits
.map(
ds -> ds.stream().map(DepositParameter::fromDeposit).collect(Collectors.toList()))
.orElse(null);
}
@JsonGetter(value = "blockNumber")
@@ -180,11 +170,6 @@ public class EngineGetPayloadResultV2 {
return withdrawals;
}
@JsonGetter(value = "deposits")
public List<DepositParameter> getDeposits() {
return deposits;
}
@JsonGetter(value = "feeRecipient")
@JsonInclude(JsonInclude.Include.NON_NULL)
public String getFeeRecipient() {

View File

@@ -0,0 +1,230 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.DepositParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.WithdrawalParameter;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Deposit;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.apache.tuweni.bytes.Bytes32;
@JsonPropertyOrder({"executionPayload", "blockValue", "blobsBundle", "shouldOverrideBuilder"})
public class EngineGetPayloadResultV6110 {
protected final PayloadResult executionPayload;
private final String blockValue;
private final BlobsBundleV1 blobsBundle;
private final boolean shouldOverrideBuilder;
public EngineGetPayloadResultV6110(
final BlockHeader header,
final List<String> transactions,
final Optional<List<Withdrawal>> withdrawals,
final Optional<List<Deposit>> deposits,
final String blockValue,
final BlobsBundleV1 blobsBundle) {
this.executionPayload = new PayloadResult(header, transactions, withdrawals, deposits);
this.blockValue = blockValue;
this.blobsBundle = blobsBundle;
this.shouldOverrideBuilder = false;
}
@JsonGetter(value = "executionPayload")
public PayloadResult getExecutionPayload() {
return executionPayload;
}
@JsonGetter(value = "blockValue")
public String getBlockValue() {
return blockValue;
}
@JsonGetter(value = "blobsBundle")
public BlobsBundleV1 getBlobsBundle() {
return blobsBundle;
}
@JsonGetter(value = "shouldOverrideBuilder")
public boolean shouldOverrideBuilder() {
return shouldOverrideBuilder;
}
public static class PayloadResult {
protected final String blockHash;
private final String parentHash;
private final String feeRecipient;
private final String stateRoot;
private final String receiptsRoot;
private final String logsBloom;
private final String prevRandao;
private final String blockNumber;
private final String gasLimit;
private final String gasUsed;
private final String timestamp;
private final String extraData;
private final String baseFeePerGas;
private final String excessBlobGas;
private final String blobGasUsed;
private final String parentBeaconBlockRoot;
protected final List<String> transactions;
private final List<WithdrawalParameter> withdrawals;
private final List<DepositParameter> deposits;
public PayloadResult(
final BlockHeader header,
final List<String> transactions,
final Optional<List<Withdrawal>> withdrawals,
final Optional<List<Deposit>> deposits) {
this.blockNumber = Quantity.create(header.getNumber());
this.blockHash = header.getHash().toString();
this.parentHash = header.getParentHash().toString();
this.logsBloom = header.getLogsBloom().toString();
this.stateRoot = header.getStateRoot().toString();
this.receiptsRoot = header.getReceiptsRoot().toString();
this.extraData = header.getExtraData().toString();
this.baseFeePerGas = header.getBaseFee().map(Quantity::create).orElse(null);
this.gasLimit = Quantity.create(header.getGasLimit());
this.gasUsed = Quantity.create(header.getGasUsed());
this.timestamp = Quantity.create(header.getTimestamp());
this.transactions = transactions;
this.feeRecipient = header.getCoinbase().toString();
this.prevRandao = header.getPrevRandao().map(Bytes32::toHexString).orElse(null);
this.withdrawals =
withdrawals
.map(
ws ->
ws.stream()
.map(WithdrawalParameter::fromWithdrawal)
.collect(Collectors.toList()))
.orElse(null);
this.deposits =
deposits
.map(
ds -> ds.stream().map(DepositParameter::fromDeposit).collect(Collectors.toList()))
.orElse(null);
this.blobGasUsed = header.getBlobGasUsed().map(Quantity::create).orElse(Quantity.HEX_ZERO);
this.excessBlobGas =
header.getExcessBlobGas().map(Quantity::create).orElse(Quantity.HEX_ZERO);
this.parentBeaconBlockRoot =
header.getParentBeaconBlockRoot().map(Bytes32::toHexString).orElse(null);
}
@JsonGetter(value = "blockNumber")
public String getNumber() {
return blockNumber;
}
@JsonGetter(value = "blockHash")
public String getHash() {
return blockHash;
}
@JsonGetter(value = "parentHash")
public String getParentHash() {
return parentHash;
}
@JsonGetter(value = "logsBloom")
public String getLogsBloom() {
return logsBloom;
}
@JsonGetter(value = "prevRandao")
public String getPrevRandao() {
return prevRandao;
}
@JsonGetter(value = "stateRoot")
public String getStateRoot() {
return stateRoot;
}
@JsonGetter(value = "receiptsRoot")
public String getReceiptRoot() {
return receiptsRoot;
}
@JsonGetter(value = "extraData")
public String getExtraData() {
return extraData;
}
@JsonGetter(value = "baseFeePerGas")
public String getBaseFeePerGas() {
return baseFeePerGas;
}
@JsonGetter(value = "gasLimit")
public String getGasLimit() {
return gasLimit;
}
@JsonGetter(value = "gasUsed")
public String getGasUsed() {
return gasUsed;
}
@JsonGetter(value = "timestamp")
public String getTimestamp() {
return timestamp;
}
@JsonGetter(value = "transactions")
public List<String> getTransactions() {
return transactions;
}
@JsonGetter(value = "withdrawals")
public List<WithdrawalParameter> getWithdrawals() {
return withdrawals;
}
@JsonGetter(value = "depositReceipts")
public List<DepositParameter> getDeposits() {
return deposits;
}
@JsonGetter(value = "feeRecipient")
@JsonInclude(JsonInclude.Include.NON_NULL)
public String getFeeRecipient() {
return feeRecipient;
}
@JsonGetter(value = "excessBlobGas")
public String getExcessBlobGas() {
return excessBlobGas;
}
@JsonGetter(value = "blobGasUsed")
public String getBlobGasUseds() {
return blobGasUsed;
}
@JsonGetter(value = "parentBeaconBlockRoot")
public String getParentBeaconBlockRoot() {
return parentBeaconBlockRoot;
}
}
}

View File

@@ -28,9 +28,11 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineG
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV1;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV2;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV3;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineGetPayloadV6110;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineNewPayloadV1;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineNewPayloadV2;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineNewPayloadV3;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineNewPayloadV6110;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EnginePreparePayloadDebug;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.EngineQosTimer;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory;
@@ -158,6 +160,26 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {
protocolSchedule));
}
if (protocolSchedule.anyMatch(p -> p.spec().getName().equalsIgnoreCase("ExperimentalEips"))) {
executionEngineApisSupported.add(
new EngineGetPayloadV6110(
consensusEngineServer,
protocolContext,
mergeCoordinator.get(),
blockResultFactory,
engineQosTimer,
protocolSchedule));
executionEngineApisSupported.add(
new EngineNewPayloadV6110(
consensusEngineServer,
protocolSchedule,
protocolContext,
mergeCoordinator.get(),
ethPeers,
engineQosTimer));
}
return mapOf(executionEngineApisSupported);
} else {
return mapOf(

View File

@@ -40,7 +40,7 @@ public class AbstractScheduledApiTest {
protected final ScheduledProtocolSpec.Hardfork cancunHardfork =
new ScheduledProtocolSpec.Hardfork("Cancun", 30);
protected final ScheduledProtocolSpec.Hardfork experimentalHardfork =
new ScheduledProtocolSpec.Hardfork("Experimental", 40);
new ScheduledProtocolSpec.Hardfork("ExperimentalEips", 40);
@Mock protected DefaultProtocolSchedule protocolSchedule;

View File

@@ -93,30 +93,6 @@ public class EngineGetPayloadV2Test extends AbstractEngineGetPayloadTest {
verify(engineCallListener, times(1)).executionEngineCalled();
}
@Test
public void shouldReturnBlockForKnownPayloadIdPostV6110() {
// should return deposits for a post-V6110 block
when(mergeContext.retrieveBlockById(mockPid))
.thenReturn(Optional.of(mockBlockWithReceiptsAndDeposits));
final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(), mockPid);
assertThat(resp).isInstanceOf(JsonRpcSuccessResponse.class);
Optional.of(resp)
.map(JsonRpcSuccessResponse.class::cast)
.ifPresent(
r -> {
assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV2.class);
final EngineGetPayloadResultV2 res = (EngineGetPayloadResultV2) r.getResult();
assertThat(res.getExecutionPayload().getDeposits()).isNotNull();
assertThat(res.getExecutionPayload().getHash())
.isEqualTo(mockHeader.getHash().toString());
assertThat(res.getBlockValue()).isEqualTo(Quantity.create(0));
assertThat(res.getExecutionPayload().getPrevRandao())
.isEqualTo(mockHeader.getPrevRandao().map(Bytes32::toString).orElse(""));
});
verify(engineCallListener, times(1)).executionEngineCalled();
}
@Test
public void shouldReturnExecutionPayloadWithoutWithdrawals_PreShanghaiBlock() {
final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(), mockPid);
@@ -128,25 +104,6 @@ public class EngineGetPayloadV2Test extends AbstractEngineGetPayloadTest {
assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV2.class);
final EngineGetPayloadResultV2 res = (EngineGetPayloadResultV2) r.getResult();
assertThat(res.getExecutionPayload().getWithdrawals()).isNull();
assertThat(res.getExecutionPayload().getDeposits()).isNull();
});
verify(engineCallListener, times(1)).executionEngineCalled();
}
@Test
public void shouldReturnExecutionPayloadWithoutDeposits_PreV6110Block() {
when(mergeContext.retrieveBlockById(mockPid))
.thenReturn(Optional.of(mockBlockWithReceiptsAndWithdrawals));
final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V2.getMethodName(), mockPid);
assertThat(resp).isInstanceOf(JsonRpcSuccessResponse.class);
Optional.of(resp)
.map(JsonRpcSuccessResponse.class::cast)
.ifPresent(
r -> {
assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV2.class);
final EngineGetPayloadResultV2 res = (EngineGetPayloadResultV2) r.getResult();
assertThat(res.getExecutionPayload().getDeposits()).isNull();
});
verify(engineCallListener, times(1)).executionEngineCalled();
}

View File

@@ -0,0 +1,177 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.consensus.merge.blockcreation.PayloadIdentifier;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.BlobsWithCommitments;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.TransactionType;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.EngineGetPayloadResultV6110;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity;
import org.hyperledger.besu.ethereum.core.BlobTestFixture;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.BlockWithReceipts;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(
MockitoExtension.class) // mocks in parent class may not be used, throwing unnecessary stubbing
public class EngineGetPayloadV6110Test extends AbstractEngineGetPayloadTest {
public EngineGetPayloadV6110Test() {
super();
}
@BeforeEach
@Override
public void before() {
super.before();
lenient()
.when(mergeContext.retrieveBlockById(mockPid))
.thenReturn(Optional.of(mockBlockWithReceiptsAndDeposits));
when(protocolContext.safeConsensusContext(Mockito.any())).thenReturn(Optional.of(mergeContext));
this.method =
new EngineGetPayloadV6110(
vertx,
protocolContext,
mergeMiningCoordinator,
factory,
engineCallListener,
protocolSchedule);
}
@Override
@Test
public void shouldReturnExpectedMethodName() {
assertThat(method.getName()).isEqualTo("engine_getPayloadV6110");
}
@Override
@Test
public void shouldReturnBlockForKnownPayloadId() {
BlockHeader eip6110Header =
new BlockHeaderTestFixture()
.prevRandao(Bytes32.random())
.timestamp(experimentalHardfork.milestone() + 1)
.excessBlobGas(BlobGas.of(10L))
.buildHeader();
// should return withdrawals, deposits and excessGas for a post-6110 block
PayloadIdentifier postEip6110Pid =
PayloadIdentifier.forPayloadParams(
Hash.ZERO,
experimentalHardfork.milestone(),
Bytes32.random(),
Address.fromHexString("0x42"),
Optional.empty(),
Optional.empty());
BlobTestFixture blobTestFixture = new BlobTestFixture();
BlobsWithCommitments bwc = blobTestFixture.createBlobsWithCommitments(1);
Transaction blobTx =
new TransactionTestFixture()
.to(Optional.of(Address.fromHexString("0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF")))
.type(TransactionType.BLOB)
.chainId(Optional.of(BigInteger.ONE))
.maxFeePerGas(Optional.of(Wei.of(15)))
.maxFeePerBlobGas(Optional.of(Wei.of(128)))
.maxPriorityFeePerGas(Optional.of(Wei.of(1)))
.blobsWithCommitments(Optional.of(bwc))
.versionedHashes(Optional.of(bwc.getVersionedHashes()))
.createTransaction(senderKeys);
TransactionReceipt blobReceipt = mock(TransactionReceipt.class);
when(blobReceipt.getCumulativeGasUsed()).thenReturn(100L);
BlockWithReceipts postEip6110Block =
new BlockWithReceipts(
new Block(
eip6110Header,
new BlockBody(
List.of(blobTx),
Collections.emptyList(),
Optional.of(Collections.emptyList()),
Optional.of(Collections.emptyList()))),
List.of(blobReceipt));
when(mergeContext.retrieveBlockById(postEip6110Pid)).thenReturn(Optional.of(postEip6110Block));
final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V6110.getMethodName(), postEip6110Pid);
assertThat(resp).isInstanceOf(JsonRpcSuccessResponse.class);
Optional.of(resp)
.map(JsonRpcSuccessResponse.class::cast)
.ifPresent(
r -> {
assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV6110.class);
final EngineGetPayloadResultV6110 res = (EngineGetPayloadResultV6110) r.getResult();
assertThat(res.getExecutionPayload().getWithdrawals()).isNotNull();
assertThat(res.getExecutionPayload().getDeposits()).isNotNull();
assertThat(res.getExecutionPayload().getHash())
.isEqualTo(eip6110Header.getHash().toString());
assertThat(res.getBlockValue()).isEqualTo(Quantity.create(0));
assertThat(res.getExecutionPayload().getPrevRandao())
.isEqualTo(eip6110Header.getPrevRandao().map(Bytes32::toString).orElse(""));
// excessBlobGas: QUANTITY, 256 bits
String expectedQuantityOf10 = Bytes32.leftPad(Bytes.of(10)).toQuantityHexString();
assertThat(res.getExecutionPayload().getExcessBlobGas()).isNotEmpty();
assertThat(res.getExecutionPayload().getExcessBlobGas())
.isEqualTo(expectedQuantityOf10);
});
verify(engineCallListener, times(1)).executionEngineCalled();
}
@Test
public void shouldReturnUnsupportedFork() {
final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V6110.getMethodName(), mockPid);
assertThat(resp).isInstanceOf(JsonRpcErrorResponse.class);
assertThat(((JsonRpcErrorResponse) resp).getErrorType())
.isEqualTo(RpcErrorType.UNSUPPORTED_FORK);
}
@Override
protected String getMethodName() {
return RpcMethod.ENGINE_GET_PAYLOAD_V6110.getMethodName();
}
}

View File

@@ -12,7 +12,6 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
import static org.assertj.core.api.Assertions.assertThat;
@@ -55,11 +54,11 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class EngineNewPayloadEIP6110Test extends EngineNewPayloadV3Test {
public class EngineNewPayloadV6110Test extends EngineNewPayloadV3Test {
private static final Address depositContractAddress =
Address.fromHexString("0x00000000219ab540356cbb839cbe05303d7705fa");
public EngineNewPayloadEIP6110Test() {}
public EngineNewPayloadV6110Test() {}
@BeforeEach
@Override