|
|
|
|
@ -1,253 +0,0 @@
|
|
|
|
|
//! Standalone Conversion Functions for Handling Different Versions of Execution Payloads in
|
|
|
|
|
//! Ethereum's Engine
|
|
|
|
|
|
|
|
|
|
use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals};
|
|
|
|
|
use alloy_rpc_types_engine::payload::ExecutionPayloadBodyV1;
|
|
|
|
|
use reth_primitives_traits::BlockBody as _;
|
|
|
|
|
|
|
|
|
|
/// Converts a [`reth_primitives_traits::Block`] to [`ExecutionPayloadBodyV1`]
|
|
|
|
|
pub fn convert_to_payload_body_v1(
|
|
|
|
|
value: impl reth_primitives_traits::Block,
|
|
|
|
|
) -> ExecutionPayloadBodyV1 {
|
|
|
|
|
let transactions = value.body().transactions_iter().map(|tx| tx.encoded_2718().into());
|
|
|
|
|
ExecutionPayloadBodyV1 {
|
|
|
|
|
transactions: transactions.collect(),
|
|
|
|
|
withdrawals: value.body().withdrawals().cloned().map(Withdrawals::into_inner),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use alloy_primitives::{b256, hex, Bytes, U256};
|
|
|
|
|
use alloy_rpc_types_engine::{
|
|
|
|
|
CancunPayloadFields, ExecutionPayload, ExecutionPayloadSidecar, ExecutionPayloadV1,
|
|
|
|
|
ExecutionPayloadV2, ExecutionPayloadV3,
|
|
|
|
|
};
|
|
|
|
|
use reth_primitives::{Block, TransactionSigned};
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn roundtrip_payload_to_block() {
|
|
|
|
|
let first_transaction_raw = Bytes::from_static(&hex!("02f9017a8501a1f0ff438211cc85012a05f2008512a05f2000830249f094d5409474fd5a725eab2ac9a8b26ca6fb51af37ef80b901040cc7326300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000001bdd2ed4b616c800000000000000000000000000001e9ee781dd4b97bdef92e5d1785f73a1f931daa20000000000000000000000007a40026a3b9a41754a95eec8c92c6b99886f440c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000009ae80eb647dd09968488fa1d7e412bf8558a0b7a0000000000000000000000000f9815537d361cb02befd9918c95c97d4d8a4a2bc001a0ba8f1928bb0efc3fcd01524a2039a9a2588fa567cd9a7cc18217e05c615e9d69a0544bfd11425ac7748e76b3795b57a5563e2b0eff47b5428744c62ff19ccfc305")[..]);
|
|
|
|
|
let second_transaction_raw = Bytes::from_static(&hex!("03f901388501a1f0ff430c843b9aca00843b9aca0082520894e7249813d8ccf6fa95a2203f46a64166073d58878080c005f8c6a00195f6dff17753fc89b60eac6477026a805116962c9e412de8015c0484e661c1a001aae314061d4f5bbf158f15d9417a238f9589783f58762cd39d05966b3ba2fba0013f5be9b12e7da06f0dd11a7bdc4e0db8ef33832acc23b183bd0a2c1408a757a0019d9ac55ea1a615d92965e04d960cb3be7bff121a381424f1f22865bd582e09a001def04412e76df26fefe7b0ed5e10580918ae4f355b074c0cfe5d0259157869a0011c11a415db57e43db07aef0de9280b591d65ca0cce36c7002507f8191e5d4a80a0c89b59970b119187d97ad70539f1624bbede92648e2dc007890f9658a88756c5a06fb2e3d4ce2c438c0856c2de34948b7032b1aadc4642a9666228ea8cdc7786b7")[..]);
|
|
|
|
|
|
|
|
|
|
let new_payload = ExecutionPayloadV3 {
|
|
|
|
|
payload_inner: ExecutionPayloadV2 {
|
|
|
|
|
payload_inner: ExecutionPayloadV1 {
|
|
|
|
|
base_fee_per_gas: U256::from(7u64),
|
|
|
|
|
block_number: 0xa946u64,
|
|
|
|
|
block_hash: hex!("a5ddd3f286f429458a39cafc13ffe89295a7efa8eb363cf89a1a4887dbcf272b").into(),
|
|
|
|
|
logs_bloom: hex!("00200004000000000000000080000000000200000000000000000000000000000000200000000000000000000000000000000000800000000200000000000000000000000000000000000008000000200000000000000000000001000000000000000000000000000000800000000000000000000100000000000030000000000000000040000000000000000000000000000000000800080080404000000000000008000000000008200000000000200000000000000000000000000000000000000002000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000100000000000000000000").into(),
|
|
|
|
|
extra_data: hex!("d883010d03846765746888676f312e32312e31856c696e7578").into(),
|
|
|
|
|
gas_limit: 0x1c9c380,
|
|
|
|
|
gas_used: 0x1f4a9,
|
|
|
|
|
timestamp: 0x651f35b8,
|
|
|
|
|
fee_recipient: hex!("f97e180c050e5ab072211ad2c213eb5aee4df134").into(),
|
|
|
|
|
parent_hash: hex!("d829192799c73ef28a7332313b3c03af1f2d5da2c36f8ecfafe7a83a3bfb8d1e").into(),
|
|
|
|
|
prev_randao: hex!("753888cc4adfbeb9e24e01c84233f9d204f4a9e1273f0e29b43c4c148b2b8b7e").into(),
|
|
|
|
|
receipts_root: hex!("4cbc48e87389399a0ea0b382b1c46962c4b8e398014bf0cc610f9c672bee3155").into(),
|
|
|
|
|
state_root: hex!("017d7fa2b5adb480f5e05b2c95cb4186e12062eed893fc8822798eed134329d1").into(),
|
|
|
|
|
transactions: vec![first_transaction_raw, second_transaction_raw],
|
|
|
|
|
},
|
|
|
|
|
withdrawals: vec![],
|
|
|
|
|
},
|
|
|
|
|
blob_gas_used: 0xc0000,
|
|
|
|
|
excess_blob_gas: 0x580000,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut block: Block = new_payload.clone().try_into_block().unwrap();
|
|
|
|
|
|
|
|
|
|
// this newPayload came with a parent beacon block root, we need to manually insert it
|
|
|
|
|
// before hashing
|
|
|
|
|
let parent_beacon_block_root =
|
|
|
|
|
b256!("531cd53b8e68deef0ea65edfa3cda927a846c307b0907657af34bc3f313b5871");
|
|
|
|
|
block.header.parent_beacon_block_root = Some(parent_beacon_block_root);
|
|
|
|
|
|
|
|
|
|
let converted_payload = ExecutionPayloadV3::from_block_unchecked(block.hash_slow(), &block);
|
|
|
|
|
|
|
|
|
|
// ensure the payloads are the same
|
|
|
|
|
assert_eq!(new_payload, converted_payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn payload_to_block_rejects_network_encoded_tx() {
|
|
|
|
|
let first_transaction_raw = Bytes::from_static(&hex!("b9017e02f9017a8501a1f0ff438211cc85012a05f2008512a05f2000830249f094d5409474fd5a725eab2ac9a8b26ca6fb51af37ef80b901040cc7326300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000001bdd2ed4b616c800000000000000000000000000001e9ee781dd4b97bdef92e5d1785f73a1f931daa20000000000000000000000007a40026a3b9a41754a95eec8c92c6b99886f440c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000009ae80eb647dd09968488fa1d7e412bf8558a0b7a0000000000000000000000000f9815537d361cb02befd9918c95c97d4d8a4a2bc001a0ba8f1928bb0efc3fcd01524a2039a9a2588fa567cd9a7cc18217e05c615e9d69a0544bfd11425ac7748e76b3795b57a5563e2b0eff47b5428744c62ff19ccfc305")[..]);
|
|
|
|
|
let second_transaction_raw = Bytes::from_static(&hex!("b9013c03f901388501a1f0ff430c843b9aca00843b9aca0082520894e7249813d8ccf6fa95a2203f46a64166073d58878080c005f8c6a00195f6dff17753fc89b60eac6477026a805116962c9e412de8015c0484e661c1a001aae314061d4f5bbf158f15d9417a238f9589783f58762cd39d05966b3ba2fba0013f5be9b12e7da06f0dd11a7bdc4e0db8ef33832acc23b183bd0a2c1408a757a0019d9ac55ea1a615d92965e04d960cb3be7bff121a381424f1f22865bd582e09a001def04412e76df26fefe7b0ed5e10580918ae4f355b074c0cfe5d0259157869a0011c11a415db57e43db07aef0de9280b591d65ca0cce36c7002507f8191e5d4a80a0c89b59970b119187d97ad70539f1624bbede92648e2dc007890f9658a88756c5a06fb2e3d4ce2c438c0856c2de34948b7032b1aadc4642a9666228ea8cdc7786b7")[..]);
|
|
|
|
|
|
|
|
|
|
let new_payload = ExecutionPayloadV3 {
|
|
|
|
|
payload_inner: ExecutionPayloadV2 {
|
|
|
|
|
payload_inner: ExecutionPayloadV1 {
|
|
|
|
|
base_fee_per_gas: U256::from(7u64),
|
|
|
|
|
block_number: 0xa946u64,
|
|
|
|
|
block_hash: hex!("a5ddd3f286f429458a39cafc13ffe89295a7efa8eb363cf89a1a4887dbcf272b").into(),
|
|
|
|
|
logs_bloom: hex!("00200004000000000000000080000000000200000000000000000000000000000000200000000000000000000000000000000000800000000200000000000000000000000000000000000008000000200000000000000000000001000000000000000000000000000000800000000000000000000100000000000030000000000000000040000000000000000000000000000000000800080080404000000000000008000000000008200000000000200000000000000000000000000000000000000002000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000100000000000000000000").into(),
|
|
|
|
|
extra_data: hex!("d883010d03846765746888676f312e32312e31856c696e7578").into(),
|
|
|
|
|
gas_limit: 0x1c9c380,
|
|
|
|
|
gas_used: 0x1f4a9,
|
|
|
|
|
timestamp: 0x651f35b8,
|
|
|
|
|
fee_recipient: hex!("f97e180c050e5ab072211ad2c213eb5aee4df134").into(),
|
|
|
|
|
parent_hash: hex!("d829192799c73ef28a7332313b3c03af1f2d5da2c36f8ecfafe7a83a3bfb8d1e").into(),
|
|
|
|
|
prev_randao: hex!("753888cc4adfbeb9e24e01c84233f9d204f4a9e1273f0e29b43c4c148b2b8b7e").into(),
|
|
|
|
|
receipts_root: hex!("4cbc48e87389399a0ea0b382b1c46962c4b8e398014bf0cc610f9c672bee3155").into(),
|
|
|
|
|
state_root: hex!("017d7fa2b5adb480f5e05b2c95cb4186e12062eed893fc8822798eed134329d1").into(),
|
|
|
|
|
transactions: vec![first_transaction_raw, second_transaction_raw],
|
|
|
|
|
},
|
|
|
|
|
withdrawals: vec![],
|
|
|
|
|
},
|
|
|
|
|
blob_gas_used: 0xc0000,
|
|
|
|
|
excess_blob_gas: 0x580000,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let _block = new_payload
|
|
|
|
|
.try_into_block::<TransactionSigned>()
|
|
|
|
|
.expect_err("execution payload conversion requires typed txs without a rlp header");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn devnet_invalid_block_hash_repro() {
|
|
|
|
|
let deser_block = r#"
|
|
|
|
|
{
|
|
|
|
|
"parentHash": "0xae8315ee86002e6269a17dd1e9516a6cf13223e9d4544d0c32daff826fb31acc",
|
|
|
|
|
"feeRecipient": "0xf97e180c050e5ab072211ad2c213eb5aee4df134",
|
|
|
|
|
"stateRoot": "0x03787f1579efbaa4a8234e72465eb4e29ef7e62f61242d6454661932e1a282a1",
|
|
|
|
|
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
|
|
|
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
|
|
|
"prevRandao": "0x918e86b497dc15de7d606457c36ca583e24d9b0a110a814de46e33d5bb824a66",
|
|
|
|
|
"blockNumber": "0x6a784",
|
|
|
|
|
"gasLimit": "0x1c9c380",
|
|
|
|
|
"gasUsed": "0x0",
|
|
|
|
|
"timestamp": "0x65bc1d60",
|
|
|
|
|
"extraData": "0x9a726574682f76302e312e302d616c7068612e31362f6c696e7578",
|
|
|
|
|
"baseFeePerGas": "0x8",
|
|
|
|
|
"blobGasUsed": "0x0",
|
|
|
|
|
"excessBlobGas": "0x0",
|
|
|
|
|
"blockHash": "0x340c157eca9fd206b87c17f0ecbe8d411219de7188a0a240b635c88a96fe91c5",
|
|
|
|
|
"transactions": [],
|
|
|
|
|
"withdrawals": [
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab202",
|
|
|
|
|
"validatorIndex": "0xb1b",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x19b3d"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab203",
|
|
|
|
|
"validatorIndex": "0xb1c",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x15892"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab204",
|
|
|
|
|
"validatorIndex": "0xb1d",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x19b3d"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab205",
|
|
|
|
|
"validatorIndex": "0xb1e",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x19b3d"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab206",
|
|
|
|
|
"validatorIndex": "0xb1f",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x19b3d"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab207",
|
|
|
|
|
"validatorIndex": "0xb20",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x19b3d"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab208",
|
|
|
|
|
"validatorIndex": "0xb21",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x15892"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab209",
|
|
|
|
|
"validatorIndex": "0xb22",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x19b3d"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab20a",
|
|
|
|
|
"validatorIndex": "0xb23",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x19b3d"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab20b",
|
|
|
|
|
"validatorIndex": "0xb24",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x17db2"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab20c",
|
|
|
|
|
"validatorIndex": "0xb25",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x19b3d"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab20d",
|
|
|
|
|
"validatorIndex": "0xb26",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x19b3d"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab20e",
|
|
|
|
|
"validatorIndex": "0xa91",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x15892"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab20f",
|
|
|
|
|
"validatorIndex": "0xa92",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x1c05d"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab210",
|
|
|
|
|
"validatorIndex": "0xa93",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x15892"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": "0x5ab211",
|
|
|
|
|
"validatorIndex": "0xa94",
|
|
|
|
|
"address": "0x388ea662ef2c223ec0b047d41bf3c0f362142ad5",
|
|
|
|
|
"amount": "0x19b3d"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
// deserialize payload
|
|
|
|
|
let payload: ExecutionPayload =
|
|
|
|
|
serde_json::from_str::<ExecutionPayloadV3>(deser_block).unwrap().into();
|
|
|
|
|
|
|
|
|
|
// NOTE: the actual block hash here is incorrect, it is a result of a bug, this was the
|
|
|
|
|
// fix:
|
|
|
|
|
// <https://github.com/paradigmxyz/reth/pull/6328>
|
|
|
|
|
let block_hash_with_blob_fee_fields =
|
|
|
|
|
b256!("a7cdd5f9e54147b53a15833a8c45dffccbaed534d7fdc23458f45102a4bf71b0");
|
|
|
|
|
|
|
|
|
|
let versioned_hashes = vec![];
|
|
|
|
|
let parent_beacon_block_root =
|
|
|
|
|
b256!("1162de8a0f4d20d86b9ad6e0a2575ab60f00a433dc70d9318c8abc9041fddf54");
|
|
|
|
|
|
|
|
|
|
// set up cancun payload fields
|
|
|
|
|
let cancun_fields = CancunPayloadFields { parent_beacon_block_root, versioned_hashes };
|
|
|
|
|
|
|
|
|
|
// convert into block
|
|
|
|
|
let block = payload
|
|
|
|
|
.try_into_block_with_sidecar::<TransactionSigned>(&ExecutionPayloadSidecar::v3(
|
|
|
|
|
cancun_fields,
|
|
|
|
|
))
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
// Ensure the actual hash is calculated if we set the fields to what they should be
|
|
|
|
|
assert_eq!(block_hash_with_blob_fee_fields, block.header.hash_slow());
|
|
|
|
|
}
|
|
|
|
|
}
|