Tweak signature verifier handling of proposer

This commit is contained in:
Michael Sproul
2022-09-14 17:28:49 +10:00
parent a2228d8599
commit b284f81a7d
10 changed files with 42 additions and 23 deletions

View File

@@ -548,7 +548,7 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
let mut signature_verifier = get_signature_verifier(&state, &pubkey_cache, &chain.spec);
for (block_root, block) in &chain_segment {
signature_verifier.include_all_signatures(block, Some(*block_root))?;
signature_verifier.include_all_signatures(block, Some(*block_root), true)?;
}
if signature_verifier.verify().is_err() {
@@ -938,12 +938,13 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
let mut signature_verifier = get_signature_verifier(&state, &pubkey_cache, &chain.spec);
signature_verifier.include_all_signatures(&block, Some(block_root))?;
signature_verifier.include_all_signatures(&block, Some(block_root), true)?;
if signature_verifier.verify().is_ok() {
Ok(Self {
consensus_context: ConsensusContext::new(block.slot())
.set_current_block_root(block_root),
.set_current_block_root(block_root)
.set_proposer_index(block.message().proposer_index()),
block,
block_root,
parent: Some(parent),

View File

@@ -892,11 +892,11 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
// Backtrack until we reach a state that is in the cache, or in the worst case
// the finalized state (this should only be reachable on first start-up).
let mut state_root_iter = HotStateRootIter::new(self, slot, *state_root);
let state_root_iter = HotStateRootIter::new(self, slot, *state_root);
let mut state_roots = Vec::with_capacity(32);
let mut state = None;
while let Some(res) = state_root_iter.next() {
for res in state_root_iter {
let (prior_state_root, prior_slot) = res?;
state_roots.push(Ok((prior_state_root, prior_slot)));

View File

@@ -28,7 +28,7 @@ impl<'a, E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotStateRootIter<'a,
let summary = self
.store
.load_hot_state_summary(&self.next_state_root)?
.ok_or_else(|| HotColdDBError::MissingHotStateSummary(self.next_state_root))?;
.ok_or(HotColdDBError::MissingHotStateSummary(self.next_state_root))?;
let slot = self.next_slot;
let state_root = self.next_state_root;

View File

@@ -119,6 +119,7 @@ pub fn per_block_processing<T: EthSpec, Payload: ExecPayload<T>>(
|pk_bytes| pk_bytes.decompress().ok().map(Cow::Owned),
signed_block,
block_root,
false,
spec
)
.is_ok(),
@@ -249,6 +250,7 @@ pub fn verify_block_signature<T: EthSpec, Payload: ExecPayload<T>>(
|i| get_pubkey_from_state(state, i),
block,
block_root,
false,
spec
)?
.verify(),

View File

@@ -123,10 +123,11 @@ where
decompressor: D,
block: &'a SignedBeaconBlock<T, Payload>,
block_root: Option<Hash256>,
check_proposer_index: bool,
spec: &'a ChainSpec,
) -> Result<()> {
let mut verifier = Self::new(state, get_pubkey, decompressor, spec);
verifier.include_all_signatures(block, block_root)?;
verifier.include_all_signatures(block, block_root, check_proposer_index)?;
verifier.verify()
}
@@ -135,8 +136,9 @@ where
&mut self,
block: &'a SignedBeaconBlock<T, Payload>,
block_root: Option<Hash256>,
check_proposer_index: bool,
) -> Result<()> {
self.include_block_proposal(block, block_root)?;
self.include_block_proposal(block, block_root, check_proposer_index)?;
self.include_all_signatures_except_proposal(block)?;
Ok(())
@@ -164,12 +166,14 @@ where
&mut self,
block: &'a SignedBeaconBlock<T, Payload>,
block_root: Option<Hash256>,
check_proposer_index: bool,
) -> Result<()> {
let set = block_proposal_signature_set(
self.state,
self.get_pubkey.clone(),
block,
block_root,
check_proposer_index,
self.spec,
)?;
self.sets.push(set);

View File

@@ -76,6 +76,7 @@ pub fn block_proposal_signature_set<'a, T, F, Payload: ExecPayload<T>>(
get_pubkey: F,
signed_block: &'a SignedBeaconBlock<T, Payload>,
block_root: Option<Hash256>,
check_proposer_index: bool,
spec: &'a ChainSpec,
) -> Result<SignatureSet<'a>>
where
@@ -83,14 +84,20 @@ where
F: Fn(usize) -> Option<Cow<'a, PublicKey>>,
{
let block = signed_block.message();
let proposer_index = state.get_beacon_proposer_index(block.slot(), spec)? as u64;
if proposer_index != block.proposer_index() {
return Err(Error::IncorrectBlockProposer {
block: block.proposer_index(),
local_shuffling: proposer_index,
});
}
let proposer_index = if check_proposer_index {
let proposer_index = state.get_beacon_proposer_index(block.slot(), spec)? as u64;
if proposer_index != block.proposer_index() {
return Err(Error::IncorrectBlockProposer {
block: block.proposer_index(),
local_shuffling: proposer_index,
});
}
proposer_index
} else {
block.proposer_index()
};
block_proposal_signature_set_from_parts(
signed_block,
@@ -162,7 +169,9 @@ where
T: EthSpec,
F: Fn(usize) -> Option<Cow<'a, PublicKey>>,
{
let proposer_index = state.get_beacon_proposer_index(block.slot(), spec)?;
// FIXME(sproul): ensure this is checked elsewhere
let proposer_index = block.proposer_index() as usize;
// let proposer_index = state.get_beacon_proposer_index(block.slot(), spec)?;
let domain = spec.get_domain(
block.slot().epoch(T::slots_per_epoch()),

View File

@@ -330,6 +330,7 @@ impl ParticipationCache {
}
}
#[allow(clippy::indexing_slicing)]
if is_eligible || is_active_current_epoch {
let effective_balance = val.effective_balance;
let base_reward =

View File

@@ -42,6 +42,7 @@ pub struct CommitteeCache {
/// common entries, and that new entries at the end are all `None`.
///
/// In practice this is only used in tests.
#[allow(clippy::indexing_slicing)]
fn compare_shuffling_positions(xs: &Vec<NonZeroUsizeOption>, ys: &Vec<NonZeroUsizeOption>) -> bool {
use std::cmp::Ordering;

View File

@@ -55,7 +55,7 @@ use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
use std::time::{Duration, Instant};
use types::{BeaconState, CloneConfig, EthSpec, Hash256};
use types::{BeaconState, EthSpec, Hash256};
const HTTP_TIMEOUT: Duration = Duration::from_secs(10);
@@ -121,7 +121,7 @@ pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches) -> Result<
};
for i in 0..runs {
let mut state = state.clone_with(CloneConfig::committee_caches_only());
let mut state = state.clone();
let start = Instant::now();

View File

@@ -80,7 +80,7 @@ use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::{Duration, Instant};
use store::HotColdDB;
use types::{BeaconState, ChainSpec, CloneConfig, EthSpec, Hash256, SignedBeaconBlock};
use types::{BeaconState, ChainSpec, EthSpec, Hash256, SignedBeaconBlock};
const HTTP_TIMEOUT: Duration = Duration::from_secs(10);
@@ -224,7 +224,7 @@ pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches) -> Result<
let mut output_post_state = None;
for i in 0..runs {
let pre_state = pre_state.clone_with(CloneConfig::all());
let pre_state = pre_state.clone();
let block = block.clone();
let start = Instant::now();
@@ -286,7 +286,6 @@ pub fn run<T: EthSpec>(mut env: Environment<T>, matches: &ArgMatches) -> Result<
}
drop(pre_state);
drop(post_state);
Ok(())
}
@@ -322,7 +321,6 @@ fn do_transition<T: EthSpec>(
}
state_root_opt = Some(state_root);
}
println!("Slot processing: {}ms", t.elapsed().as_millis());
let state_root = state_root_opt.ok_or("Failed to compute state root, internal error")?;
@@ -361,6 +359,7 @@ fn do_transition<T: EthSpec>(
decompressor,
&block,
Some(block_root),
false,
spec,
)
.map_err(|e| format!("Invalid block signature: {:?}", e))?;
@@ -368,10 +367,12 @@ fn do_transition<T: EthSpec>(
}
let t = Instant::now();
let mut ctxt = ConsensusContext::new(pre_state.slot())
.set_current_block_root(block_root)
.set_proposer_index(block.message().proposer_index());
per_block_processing(
&mut pre_state,
&block,
None,
BlockSignatureStrategy::NoVerification,
VerifyBlockRoot::True,
&mut ctxt,