Fix Eth1 data underflow (#977)
* Fix Eth1 data underflow #540 * Refactor: smart transformation from Option to Result * Add tests for BeaconState::get_outstanding_deposit_len()
This commit is contained in:
parent
54782d896c
commit
c188227cc2
@ -417,7 +417,7 @@ pub fn process_deposits<T: EthSpec>(
|
|||||||
) -> Result<(), BlockProcessingError> {
|
) -> Result<(), BlockProcessingError> {
|
||||||
let expected_deposit_len = std::cmp::min(
|
let expected_deposit_len = std::cmp::min(
|
||||||
T::MaxDeposits::to_u64(),
|
T::MaxDeposits::to_u64(),
|
||||||
state.eth1_data.deposit_count - state.eth1_deposit_index,
|
state.get_outstanding_deposit_len()?,
|
||||||
);
|
);
|
||||||
block_verify!(
|
block_verify!(
|
||||||
deposits.len() as u64 == expected_deposit_len,
|
deposits.len() as u64 == expected_deposit_len,
|
||||||
|
@ -71,6 +71,10 @@ pub enum Error {
|
|||||||
InvalidValidatorPubkey(ssz::DecodeError),
|
InvalidValidatorPubkey(ssz::DecodeError),
|
||||||
ValidatorRegistryShrunk,
|
ValidatorRegistryShrunk,
|
||||||
TreeHashCacheInconsistent,
|
TreeHashCacheInconsistent,
|
||||||
|
InvalidDepositState {
|
||||||
|
deposit_count: u64,
|
||||||
|
deposit_index: u64,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Control whether an epoch-indexed field can be indexed at the next epoch or not.
|
/// Control whether an epoch-indexed field can be indexed at the next epoch or not.
|
||||||
@ -766,6 +770,19 @@ impl<T: EthSpec> BeaconState<T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the number of outstanding deposits.
|
||||||
|
///
|
||||||
|
/// Returns `Err` if the state is invalid.
|
||||||
|
pub fn get_outstanding_deposit_len(&self) -> Result<u64, Error> {
|
||||||
|
self.eth1_data
|
||||||
|
.deposit_count
|
||||||
|
.checked_sub(self.eth1_deposit_index)
|
||||||
|
.ok_or_else(|| Error::InvalidDepositState {
|
||||||
|
deposit_count: self.eth1_data.deposit_count,
|
||||||
|
deposit_index: self.eth1_deposit_index,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Build all the caches, if they need to be built.
|
/// Build all the caches, if they need to be built.
|
||||||
pub fn build_all_caches(&mut self, spec: &ChainSpec) -> Result<(), Error> {
|
pub fn build_all_caches(&mut self, spec: &ChainSpec) -> Result<(), Error> {
|
||||||
self.build_all_committee_caches(spec)?;
|
self.build_all_committee_caches(spec)?;
|
||||||
|
@ -365,3 +365,44 @@ mod committees {
|
|||||||
committee_consistency_test_suite::<MinimalEthSpec>(RelativeEpoch::Next);
|
committee_consistency_test_suite::<MinimalEthSpec>(RelativeEpoch::Next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod get_outstanding_deposit_len {
|
||||||
|
use super::*;
|
||||||
|
use crate::MinimalEthSpec;
|
||||||
|
use crate::test_utils::TestingBeaconStateBuilder;
|
||||||
|
|
||||||
|
fn state() -> BeaconState<MinimalEthSpec> {
|
||||||
|
let spec = MinimalEthSpec::default_spec();
|
||||||
|
let builder: TestingBeaconStateBuilder<MinimalEthSpec> =
|
||||||
|
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec);
|
||||||
|
let (state, _keypairs) = builder.build();
|
||||||
|
|
||||||
|
state
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn returns_ok() {
|
||||||
|
let mut state = state();
|
||||||
|
assert_eq!(state.get_outstanding_deposit_len(), Ok(0));
|
||||||
|
|
||||||
|
state.eth1_data.deposit_count = 17;
|
||||||
|
state.eth1_deposit_index = 16;
|
||||||
|
assert_eq!(state.get_outstanding_deposit_len(), Ok(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn returns_err_if_the_state_is_invalid() {
|
||||||
|
let mut state = state();
|
||||||
|
// The state is invalid, deposit count is lower than deposit index.
|
||||||
|
state.eth1_data.deposit_count = 16;
|
||||||
|
state.eth1_deposit_index = 17;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
state.get_outstanding_deposit_len(),
|
||||||
|
Err(BeaconStateError::InvalidDepositState {
|
||||||
|
deposit_count: 16,
|
||||||
|
deposit_index: 17,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user