Tree hash caching and optimisations for Altair (#2459)

## Proposed Changes

Remove the remaining Altair `FIXME`s from consensus land.

1. Implement tree hash caching for the participation lists. This required some light type manipulation, including removing the `TreeHash` bound from `CachedTreeHash` which was purely descriptive.
2. Plumb the proposer index through Altair attestation processing, to avoid calculating it for _every_ attestation (potentially 128ms on large networks). This duplicates some work from #2431, but with the aim of getting it in sooner, particularly for the Altair devnets.
3. Removes two FIXMEs related to `superstruct` and cloning, which are unlikely to be particularly detrimental and will be tracked here instead: https://github.com/sigp/superstruct/issues/5
This commit is contained in:
Michael Sproul
2021-07-23 00:23:53 +00:00
parent 74aa99c409
commit 84e6d71950
11 changed files with 206 additions and 39 deletions

View File

@@ -127,7 +127,7 @@ pub fn per_block_processing<T: EthSpec>(
process_randao(state, block, verify_signatures, spec)?;
process_eth1_data(state, block.body().eth1_data())?;
process_operations(state, block.body(), verify_signatures, spec)?;
process_operations(state, block.body(), proposer_index, verify_signatures, spec)?;
if let BeaconBlockRef::Altair(inner) = block {
process_sync_aggregate(state, &inner.body.sync_aggregate, proposer_index, spec)?;

View File

@@ -11,6 +11,7 @@ use types::consts::altair::{PARTICIPATION_FLAG_WEIGHTS, PROPOSER_WEIGHT, WEIGHT_
pub fn process_operations<'a, T: EthSpec>(
state: &mut BeaconState<T>,
block_body: BeaconBlockBodyRef<'a, T>,
proposer_index: u64,
verify_signatures: VerifySignatures,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
@@ -26,7 +27,7 @@ pub fn process_operations<'a, T: EthSpec>(
verify_signatures,
spec,
)?;
process_attestations(state, block_body, verify_signatures, spec)?;
process_attestations(state, block_body, proposer_index, verify_signatures, spec)?;
process_deposits(state, block_body.deposits(), spec)?;
process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?;
Ok(())
@@ -85,6 +86,7 @@ pub mod altair {
pub fn process_attestations<T: EthSpec>(
state: &mut BeaconState<T>,
attestations: &[Attestation<T>],
proposer_index: u64,
verify_signatures: VerifySignatures,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
@@ -92,7 +94,14 @@ pub mod altair {
.iter()
.enumerate()
.try_for_each(|(i, attestation)| {
process_attestation(state, attestation, i, verify_signatures, spec)
process_attestation(
state,
attestation,
i,
proposer_index,
verify_signatures,
spec,
)
})
}
@@ -100,6 +109,7 @@ pub mod altair {
state: &mut BeaconState<T>,
attestation: &Attestation<T>,
att_index: usize,
proposer_index: u64,
verify_signatures: VerifySignatures,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
@@ -145,9 +155,7 @@ pub mod altair {
.safe_mul(WEIGHT_DENOMINATOR)?
.safe_div(PROPOSER_WEIGHT)?;
let proposer_reward = proposer_reward_numerator.safe_div(proposer_reward_denominator)?;
// FIXME(altair): optimise by passing in proposer_index
let proposer_index = state.get_beacon_proposer_index(state.slot(), spec)?;
increase_balance(state, proposer_index, proposer_reward)?;
increase_balance(state, proposer_index as usize, proposer_reward)?;
Ok(())
}
}
@@ -212,6 +220,7 @@ pub fn process_attester_slashings<T: EthSpec>(
pub fn process_attestations<'a, T: EthSpec>(
state: &mut BeaconState<T>,
block_body: BeaconBlockBodyRef<'a, T>,
proposer_index: u64,
verify_signatures: VerifySignatures,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
@@ -223,6 +232,7 @@ pub fn process_attestations<'a, T: EthSpec>(
altair::process_attestations(
state,
block_body.attestations(),
proposer_index,
verify_signatures,
spec,
)?;

View File

@@ -337,6 +337,7 @@ fn invalid_attestation_no_committee_for_index() {
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&spec,
);
@@ -368,6 +369,7 @@ fn invalid_attestation_wrong_justified_checkpoint() {
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&spec,
);
@@ -400,6 +402,7 @@ fn invalid_attestation_bad_aggregation_bitfield_len() {
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&spec,
);
@@ -425,6 +428,7 @@ fn invalid_attestation_bad_signature() {
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&spec,
);
@@ -456,6 +460,7 @@ fn invalid_attestation_included_too_early() {
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&spec,
);
@@ -491,6 +496,7 @@ fn invalid_attestation_included_too_late() {
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&spec,
);
@@ -522,6 +528,7 @@ fn invalid_attestation_target_epoch_slot_mismatch() {
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&spec,
);