diff --git a/crates/rpc/rpc-types-compat/src/engine/payload.rs b/crates/rpc/rpc-types-compat/src/engine/payload.rs index 61b07fe099b7..1dad91f651a8 100644 --- a/crates/rpc/rpc-types-compat/src/engine/payload.rs +++ b/crates/rpc/rpc-types-compat/src/engine/payload.rs @@ -391,9 +391,14 @@ pub fn execution_payload_from_sealed_block(value: SealedBlock) -> ExecutionPaylo #[cfg(test)] mod tests { - use super::{block_to_payload_v3, try_payload_v3_to_block}; - use reth_primitives::{hex, Bytes, U256}; - use reth_rpc_types::{engine::ExecutionPayloadV3, ExecutionPayloadV1, ExecutionPayloadV2}; + use super::{ + block_to_payload_v3, try_into_block, try_payload_v3_to_block, validate_block_hash, + }; + use reth_primitives::{b256, hex, Bytes, U256}; + use reth_rpc_types::{ + engine::{CancunPayloadFields, ExecutionPayloadV3}, + ExecutionPayload, ExecutionPayloadV1, ExecutionPayloadV2, + }; #[test] fn roundtrip_payload_to_block() { @@ -470,4 +475,149 @@ mod tests { let _block = try_payload_v3_to_block(new_payload.clone()) .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::(deser_block).unwrap().into(); + + // NOTE: the actual block hash here is incorrect, it is a result of a bug, this was the + // fix: + // + 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 = try_into_block(payload, Some(cancun_fields.parent_beacon_block_root)).unwrap(); + + // Ensure the actual hash is calculated if we set the fields to what they should be + validate_block_hash(block_hash_with_blob_fee_fields, block).unwrap(); + } }