Add macro to simplify into_full_block implementations (#9294)

Use a macro to remove the repetitive fork variant boilerplate in `signed_beacon_block.rs` when implementing `into_full_block` for the various `SignedBeaconBlock` variants


Co-Authored-By: Mac L <mjladson@pm.me>
This commit is contained in:
Mac L
2026-05-25 05:29:34 +04:00
committed by GitHub
parent b9a68ad2c6
commit 89ee020330
2 changed files with 76 additions and 276 deletions

View File

@@ -44,6 +44,7 @@ merkle_proof = { workspace = true }
metastruct = "0.1.0" metastruct = "0.1.0"
milhouse = { workspace = true } milhouse = { workspace = true }
parking_lot = { workspace = true } parking_lot = { workspace = true }
paste = { workspace = true }
rand = { workspace = true } rand = { workspace = true }
rand_xorshift = { workspace = true } rand_xorshift = { workspace = true }
rayon = { workspace = true } rayon = { workspace = true }
@@ -67,7 +68,6 @@ yaml_serde = { workspace = true }
[dev-dependencies] [dev-dependencies]
beacon_chain = { workspace = true } beacon_chain = { workspace = true }
criterion = { workspace = true } criterion = { workspace = true }
paste = { workspace = true }
state_processing = { workspace = true } state_processing = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
types = { path = ".", features = ["arbitrary"] } types = { path = ".", features = ["arbitrary"] }

View File

@@ -433,22 +433,23 @@ impl<E: EthSpec> From<SignedBeaconBlockAltair<E, BlindedPayload<E>>>
} }
// Post-Bellatrix blocks can be "unblinded" by adding the full payload. // Post-Bellatrix blocks can be "unblinded" by adding the full payload.
// NOTE: It might be nice to come up with a `superstruct` pattern to abstract over this before macro_rules! impl_into_full_block {
// the first fork after Bellatrix. ($fork:ident, [ $($extra_field:ident),* $(,)? ]) => {
impl<E: EthSpec> SignedBeaconBlockBellatrix<E, BlindedPayload<E>> { paste::paste! {
impl<E: EthSpec> [<SignedBeaconBlock $fork>]<E, BlindedPayload<E>> {
pub fn into_full_block( pub fn into_full_block(
self, self,
execution_payload: ExecutionPayloadBellatrix<E>, execution_payload: [<ExecutionPayload $fork>]<E>,
) -> SignedBeaconBlockBellatrix<E, FullPayload<E>> { ) -> [<SignedBeaconBlock $fork>]<E, FullPayload<E>> {
let SignedBeaconBlockBellatrix { let [<SignedBeaconBlock $fork>] {
message: message:
BeaconBlockBellatrix { [<BeaconBlock $fork>] {
slot, slot,
proposer_index, proposer_index,
parent_root, parent_root,
state_root, state_root,
body: body:
BeaconBlockBodyBellatrix { [<BeaconBlockBody $fork>] {
randao_reveal, randao_reveal,
eth1_data, eth1_data,
graffiti, graffiti,
@@ -458,18 +459,19 @@ impl<E: EthSpec> SignedBeaconBlockBellatrix<E, BlindedPayload<E>> {
deposits, deposits,
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: BlindedPayloadBellatrix { .. }, execution_payload: [<BlindedPayload $fork>] { .. },
$($extra_field,)*
}, },
}, },
signature, signature,
} = self; } = self;
SignedBeaconBlockBellatrix { [<SignedBeaconBlock $fork>] {
message: BeaconBlockBellatrix { message: [<BeaconBlock $fork>] {
slot, slot,
proposer_index, proposer_index,
parent_root, parent_root,
state_root, state_root,
body: BeaconBlockBodyBellatrix { body: [<BeaconBlockBody $fork>] {
randao_reveal, randao_reveal,
eth1_data, eth1_data,
graffiti, graffiti,
@@ -479,239 +481,37 @@ impl<E: EthSpec> SignedBeaconBlockBellatrix<E, BlindedPayload<E>> {
deposits, deposits,
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadBellatrix { execution_payload }, execution_payload: [<FullPayload $fork>] { execution_payload },
$($extra_field,)*
}, },
}, },
signature, signature,
} }
} }
} }
}
};
}
impl<E: EthSpec> SignedBeaconBlockCapella<E, BlindedPayload<E>> { impl_into_full_block!(Bellatrix, []);
pub fn into_full_block( impl_into_full_block!(Capella, [bls_to_execution_changes]);
self, impl_into_full_block!(Deneb, [bls_to_execution_changes, blob_kzg_commitments]);
execution_payload: ExecutionPayloadCapella<E>, impl_into_full_block!(
) -> SignedBeaconBlockCapella<E, FullPayload<E>> { Electra,
let SignedBeaconBlockCapella { [
message:
BeaconBlockCapella {
slot,
proposer_index,
parent_root,
state_root,
body:
BeaconBlockBodyCapella {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: BlindedPayloadCapella { .. },
bls_to_execution_changes,
},
},
signature,
} = self;
SignedBeaconBlockCapella {
message: BeaconBlockCapella {
slot,
proposer_index,
parent_root,
state_root,
body: BeaconBlockBodyCapella {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: FullPayloadCapella { execution_payload },
bls_to_execution_changes,
},
},
signature,
}
}
}
impl<E: EthSpec> SignedBeaconBlockDeneb<E, BlindedPayload<E>> {
pub fn into_full_block(
self,
execution_payload: ExecutionPayloadDeneb<E>,
) -> SignedBeaconBlockDeneb<E, FullPayload<E>> {
let SignedBeaconBlockDeneb {
message:
BeaconBlockDeneb {
slot,
proposer_index,
parent_root,
state_root,
body:
BeaconBlockBodyDeneb {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: BlindedPayloadDeneb { .. },
bls_to_execution_changes, bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
}, execution_requests
}, ]
signature, );
} = self; impl_into_full_block!(
SignedBeaconBlockDeneb { Fulu,
message: BeaconBlockDeneb { [
slot,
proposer_index,
parent_root,
state_root,
body: BeaconBlockBodyDeneb {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: FullPayloadDeneb { execution_payload },
bls_to_execution_changes, bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
}, execution_requests
}, ]
signature, );
}
}
}
impl<E: EthSpec> SignedBeaconBlockElectra<E, BlindedPayload<E>> {
pub fn into_full_block(
self,
execution_payload: ExecutionPayloadElectra<E>,
) -> SignedBeaconBlockElectra<E, FullPayload<E>> {
let SignedBeaconBlockElectra {
message:
BeaconBlockElectra {
slot,
proposer_index,
parent_root,
state_root,
body:
BeaconBlockBodyElectra {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: BlindedPayloadElectra { .. },
bls_to_execution_changes,
blob_kzg_commitments,
execution_requests,
},
},
signature,
} = self;
SignedBeaconBlockElectra {
message: BeaconBlockElectra {
slot,
proposer_index,
parent_root,
state_root,
body: BeaconBlockBodyElectra {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: FullPayloadElectra { execution_payload },
bls_to_execution_changes,
blob_kzg_commitments,
execution_requests,
},
},
signature,
}
}
}
impl<E: EthSpec> SignedBeaconBlockFulu<E, BlindedPayload<E>> {
pub fn into_full_block(
self,
execution_payload: ExecutionPayloadFulu<E>,
) -> SignedBeaconBlockFulu<E, FullPayload<E>> {
let SignedBeaconBlockFulu {
message:
BeaconBlockFulu {
slot,
proposer_index,
parent_root,
state_root,
body:
BeaconBlockBodyFulu {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: BlindedPayloadFulu { .. },
bls_to_execution_changes,
blob_kzg_commitments,
execution_requests,
},
},
signature,
} = self;
SignedBeaconBlockFulu {
message: BeaconBlockFulu {
slot,
proposer_index,
parent_root,
state_root,
body: BeaconBlockBodyFulu {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings,
attester_slashings,
attestations,
deposits,
voluntary_exits,
sync_aggregate,
execution_payload: FullPayloadFulu { execution_payload },
bls_to_execution_changes,
blob_kzg_commitments,
execution_requests,
},
},
signature,
}
}
}
// We can convert gloas blocks without payloads into blocks "with" payloads. // We can convert gloas blocks without payloads into blocks "with" payloads.
// TODO(EIP-7732) Look into whether we can remove this in the future since no blinded blocks post-gloas // TODO(EIP-7732) Look into whether we can remove this in the future since no blinded blocks post-gloas