2019-03-06 05:24:56 +00:00
|
|
|
use types::*;
|
2019-03-05 23:22:19 +00:00
|
|
|
|
2019-03-06 04:22:45 +00:00
|
|
|
macro_rules! impl_from_beacon_state_error {
|
|
|
|
($type: ident) => {
|
|
|
|
impl From<BeaconStateError> for $type {
|
|
|
|
fn from(e: BeaconStateError) -> $type {
|
|
|
|
$type::BeaconStateError(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! impl_into_with_index_with_beacon_error {
|
|
|
|
($error_type: ident, $invalid_type: ident) => {
|
|
|
|
impl IntoWithIndex<BlockProcessingError> for $error_type {
|
|
|
|
fn into_with_index(self, i: usize) -> BlockProcessingError {
|
|
|
|
match self {
|
|
|
|
$error_type::Invalid(e) => {
|
|
|
|
BlockProcessingError::Invalid(BlockInvalid::$invalid_type(i, e))
|
|
|
|
}
|
|
|
|
$error_type::BeaconStateError(e) => BlockProcessingError::BeaconStateError(e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! impl_into_with_index_without_beacon_error {
|
|
|
|
($error_type: ident, $invalid_type: ident) => {
|
|
|
|
impl IntoWithIndex<BlockProcessingError> for $error_type {
|
|
|
|
fn into_with_index(self, i: usize) -> BlockProcessingError {
|
|
|
|
match self {
|
|
|
|
$error_type::Invalid(e) => {
|
|
|
|
BlockProcessingError::Invalid(BlockInvalid::$invalid_type(i, e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// A conversion that consumes `self` and adds an `index` variable to resulting struct.
|
|
|
|
///
|
|
|
|
/// Used here to allow converting an error into an upstream error that points to the object that
|
|
|
|
/// caused the error. For example, pointing to the index of an attestation that caused the
|
|
|
|
/// `AttestationInvalid` error.
|
2019-03-06 04:22:45 +00:00
|
|
|
pub trait IntoWithIndex<T>: Sized {
|
2019-03-06 05:24:56 +00:00
|
|
|
fn into_with_index(self, index: usize) -> T;
|
2019-03-06 04:22:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Block Validation
|
|
|
|
*/
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The object is invalid or validation failed.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum BlockProcessingError {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Validation completed successfully and the object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
Invalid(BlockInvalid),
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Encountered a `BeaconStateError` whilst attempting to determine validity.
|
2019-03-06 04:22:45 +00:00
|
|
|
BeaconStateError(BeaconStateError),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_from_beacon_state_error!(BlockProcessingError);
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Describes why an object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum BlockInvalid {
|
|
|
|
StateSlotMismatch,
|
2019-04-17 03:59:40 +00:00
|
|
|
ParentBlockRootMismatch {
|
|
|
|
state: Hash256,
|
|
|
|
block: Hash256,
|
|
|
|
},
|
2019-05-20 02:42:02 +00:00
|
|
|
ProposerSlashed(usize),
|
2019-03-06 04:22:45 +00:00
|
|
|
BadSignature,
|
|
|
|
BadRandaoSignature,
|
|
|
|
MaxAttestationsExceeded,
|
|
|
|
MaxAttesterSlashingsExceed,
|
|
|
|
MaxProposerSlashingsExceeded,
|
2019-05-21 08:02:31 +00:00
|
|
|
DepositCountInvalid,
|
2019-03-06 04:22:45 +00:00
|
|
|
MaxExitsExceeded,
|
|
|
|
MaxTransfersExceed,
|
|
|
|
AttestationInvalid(usize, AttestationInvalid),
|
2019-05-13 07:28:04 +00:00
|
|
|
/// A `IndexedAttestation` inside an `AttesterSlashing` was invalid.
|
2019-03-09 21:55:45 +00:00
|
|
|
///
|
|
|
|
/// To determine the offending `AttesterSlashing` index, divide the error message `usize` by two.
|
2019-05-13 07:28:04 +00:00
|
|
|
IndexedAttestationInvalid(usize, IndexedAttestationInvalid),
|
2019-03-06 04:22:45 +00:00
|
|
|
AttesterSlashingInvalid(usize, AttesterSlashingInvalid),
|
|
|
|
ProposerSlashingInvalid(usize, ProposerSlashingInvalid),
|
|
|
|
DepositInvalid(usize, DepositInvalid),
|
|
|
|
// TODO: merge this into the `DepositInvalid` error.
|
|
|
|
DepositProcessingFailed(usize),
|
|
|
|
ExitInvalid(usize, ExitInvalid),
|
|
|
|
TransferInvalid(usize, TransferInvalid),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Into<BlockProcessingError> for BlockInvalid {
|
|
|
|
fn into(self) -> BlockProcessingError {
|
|
|
|
BlockProcessingError::Invalid(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Attestation Validation
|
|
|
|
*/
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The object is invalid or validation failed.
|
2019-03-05 23:22:19 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum AttestationValidationError {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Validation completed successfully and the object is invalid.
|
2019-03-05 23:22:19 +00:00
|
|
|
Invalid(AttestationInvalid),
|
2019-03-06 04:22:45 +00:00
|
|
|
/// Encountered a `BeaconStateError` whilst attempting to determine validity.
|
|
|
|
BeaconStateError(BeaconStateError),
|
2019-03-05 23:22:19 +00:00
|
|
|
}
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Describes why an object is invalid.
|
2019-03-05 23:22:19 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum AttestationInvalid {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Attestation references a pre-genesis slot.
|
2019-03-17 01:25:37 +00:00
|
|
|
PreGenesis { genesis: Slot, attestation: Slot },
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Attestation included before the inclusion delay.
|
2019-03-17 01:25:37 +00:00
|
|
|
IncludedTooEarly {
|
|
|
|
state: Slot,
|
|
|
|
delay: u64,
|
|
|
|
attestation: Slot,
|
|
|
|
},
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Attestation slot is too far in the past to be included in a block.
|
2019-03-17 01:25:37 +00:00
|
|
|
IncludedTooLate { state: Slot, attestation: Slot },
|
2019-05-21 06:38:16 +00:00
|
|
|
/// Attestation target epoch does not match the current or previous epoch.
|
|
|
|
BadTargetEpoch,
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Attestation justified epoch does not match the states current or previous justified epoch.
|
|
|
|
///
|
2019-03-17 01:25:37 +00:00
|
|
|
/// `is_current` is `true` if the attestation was compared to the
|
|
|
|
/// `state.current_justified_epoch`, `false` if compared to `state.previous_justified_epoch`.
|
|
|
|
WrongJustifiedEpoch {
|
|
|
|
state: Epoch,
|
|
|
|
attestation: Epoch,
|
|
|
|
is_current: bool,
|
|
|
|
},
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Attestation justified epoch root does not match root known to the state.
|
|
|
|
///
|
2019-03-17 01:25:37 +00:00
|
|
|
/// `is_current` is `true` if the attestation was compared to the
|
|
|
|
/// `state.current_justified_epoch`, `false` if compared to `state.previous_justified_epoch`.
|
|
|
|
WrongJustifiedRoot {
|
|
|
|
state: Hash256,
|
|
|
|
attestation: Hash256,
|
|
|
|
is_current: bool,
|
|
|
|
},
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Attestation crosslink root does not match the state crosslink root for the attestations
|
|
|
|
/// slot.
|
2019-03-17 01:25:37 +00:00
|
|
|
BadPreviousCrosslink,
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The custody bitfield has some bits set `true`. This is not allowed in phase 0.
|
2019-03-05 23:22:19 +00:00
|
|
|
CustodyBitfieldHasSetBits,
|
2019-03-06 05:24:56 +00:00
|
|
|
/// There are no set bits on the attestation -- an attestation must be signed by at least one
|
|
|
|
/// validator.
|
2019-03-05 23:22:19 +00:00
|
|
|
AggregationBitfieldIsEmpty,
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The custody bitfield length is not the smallest possible size to represent the committee.
|
2019-03-17 01:25:37 +00:00
|
|
|
BadCustodyBitfieldLength {
|
|
|
|
committee_len: usize,
|
|
|
|
bitfield_len: usize,
|
|
|
|
},
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The aggregation bitfield length is not the smallest possible size to represent the committee.
|
2019-03-17 01:25:37 +00:00
|
|
|
BadAggregationBitfieldLength {
|
|
|
|
committee_len: usize,
|
|
|
|
bitfield_len: usize,
|
|
|
|
},
|
|
|
|
/// There was no known committee in this `epoch` for the given shard and slot.
|
|
|
|
NoCommitteeForShard { shard: u64, slot: Slot },
|
2019-03-09 09:09:17 +00:00
|
|
|
/// The validator index was unknown.
|
|
|
|
UnknownValidator(u64),
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The attestation signature verification failed.
|
2019-03-05 23:22:19 +00:00
|
|
|
BadSignature,
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The shard block root was not set to zero. This is a phase 0 requirement.
|
2019-03-05 23:22:19 +00:00
|
|
|
ShardBlockRootNotZero,
|
2019-05-21 06:38:16 +00:00
|
|
|
/// The indexed attestation created from this attestation was found to be invalid.
|
|
|
|
BadIndexedAttestation(IndexedAttestationInvalid),
|
2019-03-05 23:22:19 +00:00
|
|
|
}
|
|
|
|
|
2019-03-06 04:22:45 +00:00
|
|
|
impl_from_beacon_state_error!(AttestationValidationError);
|
|
|
|
impl_into_with_index_with_beacon_error!(AttestationValidationError, AttestationInvalid);
|
|
|
|
|
2019-05-21 06:38:16 +00:00
|
|
|
impl From<IndexedAttestationValidationError> for AttestationValidationError {
|
|
|
|
fn from(err: IndexedAttestationValidationError) -> Self {
|
|
|
|
let IndexedAttestationValidationError::Invalid(e) = err;
|
|
|
|
AttestationValidationError::Invalid(AttestationInvalid::BadIndexedAttestation(e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-06 04:22:45 +00:00
|
|
|
/*
|
|
|
|
* `AttesterSlashing` Validation
|
|
|
|
*/
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The object is invalid or validation failed.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum AttesterSlashingValidationError {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Validation completed successfully and the object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
Invalid(AttesterSlashingInvalid),
|
|
|
|
/// Encountered a `BeaconStateError` whilst attempting to determine validity.
|
|
|
|
BeaconStateError(BeaconStateError),
|
|
|
|
}
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Describes why an object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum AttesterSlashingInvalid {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The attestation data is identical, an attestation cannot conflict with itself.
|
2019-03-06 04:22:45 +00:00
|
|
|
AttestationDataIdentical,
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The attestations were not in conflict.
|
2019-03-06 04:22:45 +00:00
|
|
|
NotSlashable,
|
2019-05-13 07:28:04 +00:00
|
|
|
/// The first `IndexedAttestation` was invalid.
|
|
|
|
IndexedAttestation1Invalid(IndexedAttestationInvalid),
|
|
|
|
/// The second `IndexedAttestation` was invalid.
|
|
|
|
IndexedAttestation2Invalid(IndexedAttestationInvalid),
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The validator index is unknown. One cannot slash one who does not exist.
|
|
|
|
UnknownValidator(u64),
|
2019-03-17 01:25:37 +00:00
|
|
|
/// The specified validator has already been withdrawn.
|
|
|
|
ValidatorAlreadyWithdrawn(u64),
|
2019-03-06 05:24:56 +00:00
|
|
|
/// There were no indices able to be slashed.
|
2019-03-06 04:22:45 +00:00
|
|
|
NoSlashableIndices,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_from_beacon_state_error!(AttesterSlashingValidationError);
|
|
|
|
impl_into_with_index_with_beacon_error!(AttesterSlashingValidationError, AttesterSlashingInvalid);
|
|
|
|
|
|
|
|
/*
|
2019-05-13 07:28:04 +00:00
|
|
|
* `IndexedAttestation` Validation
|
2019-03-06 04:22:45 +00:00
|
|
|
*/
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The object is invalid or validation failed.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
2019-05-13 07:28:04 +00:00
|
|
|
pub enum IndexedAttestationValidationError {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Validation completed successfully and the object is invalid.
|
2019-05-13 07:28:04 +00:00
|
|
|
Invalid(IndexedAttestationInvalid),
|
2019-03-06 04:22:45 +00:00
|
|
|
}
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Describes why an object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
2019-05-13 07:28:04 +00:00
|
|
|
pub enum IndexedAttestationInvalid {
|
2019-05-21 06:38:16 +00:00
|
|
|
/// The custody bit 0 validators intersect with the bit 1 validators.
|
|
|
|
CustodyBitValidatorsIntersect,
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The custody bitfield has some bits set `true`. This is not allowed in phase 0.
|
2019-03-06 04:22:45 +00:00
|
|
|
CustodyBitfieldHasSetBits,
|
2019-03-06 05:24:56 +00:00
|
|
|
/// No validator indices were specified.
|
2019-03-06 04:22:45 +00:00
|
|
|
NoValidatorIndices,
|
2019-05-21 06:38:16 +00:00
|
|
|
/// The number of indices exceeds the global maximum.
|
|
|
|
///
|
|
|
|
/// (max_indices, indices_given)
|
|
|
|
MaxIndicesExceed(u64, usize),
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The validator indices were not in increasing order.
|
|
|
|
///
|
|
|
|
/// The error occured between the given `index` and `index + 1`
|
|
|
|
BadValidatorIndicesOrdering(usize),
|
|
|
|
/// The validator index is unknown. One cannot slash one who does not exist.
|
|
|
|
UnknownValidator(u64),
|
2019-05-21 06:38:16 +00:00
|
|
|
/// The indexed attestation aggregate signature was not valid.
|
2019-03-06 04:22:45 +00:00
|
|
|
BadSignature,
|
|
|
|
}
|
|
|
|
|
2019-05-13 07:28:04 +00:00
|
|
|
impl Into<IndexedAttestationInvalid> for IndexedAttestationValidationError {
|
|
|
|
fn into(self) -> IndexedAttestationInvalid {
|
2019-03-06 04:22:45 +00:00
|
|
|
match self {
|
2019-05-13 07:28:04 +00:00
|
|
|
IndexedAttestationValidationError::Invalid(e) => e,
|
2019-03-06 04:22:45 +00:00
|
|
|
}
|
2019-03-05 23:22:19 +00:00
|
|
|
}
|
|
|
|
}
|
2019-03-06 04:22:45 +00:00
|
|
|
|
2019-03-09 21:55:45 +00:00
|
|
|
impl_into_with_index_without_beacon_error!(
|
2019-05-13 07:28:04 +00:00
|
|
|
IndexedAttestationValidationError,
|
|
|
|
IndexedAttestationInvalid
|
2019-03-09 21:55:45 +00:00
|
|
|
);
|
|
|
|
|
2019-03-06 04:22:45 +00:00
|
|
|
/*
|
|
|
|
* `ProposerSlashing` Validation
|
|
|
|
*/
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The object is invalid or validation failed.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum ProposerSlashingValidationError {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Validation completed successfully and the object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
Invalid(ProposerSlashingInvalid),
|
|
|
|
}
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Describes why an object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum ProposerSlashingInvalid {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The proposer index is not a known validator.
|
|
|
|
ProposerUnknown(u64),
|
2019-04-01 23:22:19 +00:00
|
|
|
/// The two proposal have different epochs.
|
2019-03-06 05:24:56 +00:00
|
|
|
///
|
|
|
|
/// (proposal_1_slot, proposal_2_slot)
|
2019-04-01 23:22:19 +00:00
|
|
|
ProposalEpochMismatch(Slot, Slot),
|
2019-03-17 01:25:37 +00:00
|
|
|
/// The proposals are identical and therefore not slashable.
|
|
|
|
ProposalsIdentical,
|
2019-05-20 05:04:55 +00:00
|
|
|
/// The specified proposer cannot be slashed because they are already slashed, or not active.
|
|
|
|
ProposerNotSlashable(u64),
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The first proposal signature was invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
BadProposal1Signature,
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The second proposal signature was invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
BadProposal2Signature,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_into_with_index_without_beacon_error!(
|
|
|
|
ProposerSlashingValidationError,
|
|
|
|
ProposerSlashingInvalid
|
|
|
|
);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* `Deposit` Validation
|
|
|
|
*/
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The object is invalid or validation failed.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum DepositValidationError {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Validation completed successfully and the object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
Invalid(DepositInvalid),
|
2019-03-13 05:40:28 +00:00
|
|
|
/// Encountered a `BeaconStateError` whilst attempting to determine validity.
|
|
|
|
BeaconStateError(BeaconStateError),
|
2019-03-06 04:22:45 +00:00
|
|
|
}
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Describes why an object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum DepositInvalid {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The deposit index does not match the state index.
|
2019-03-17 01:25:37 +00:00
|
|
|
BadIndex { state: u64, deposit: u64 },
|
2019-03-09 21:33:17 +00:00
|
|
|
/// The proof-of-possession does not match the given pubkey.
|
|
|
|
BadProofOfPossession,
|
|
|
|
/// The withdrawal credentials for the depositing validator did not match the withdrawal
|
|
|
|
/// credentials of an existing validator with the same public key.
|
|
|
|
BadWithdrawalCredentials,
|
2019-03-07 22:26:03 +00:00
|
|
|
/// The specified `branch` and `index` did not form a valid proof that the deposit is included
|
|
|
|
/// in the eth1 deposit root.
|
|
|
|
BadMerkleProof,
|
2019-03-06 04:22:45 +00:00
|
|
|
}
|
|
|
|
|
2019-03-13 05:40:28 +00:00
|
|
|
impl_from_beacon_state_error!(DepositValidationError);
|
|
|
|
impl_into_with_index_with_beacon_error!(DepositValidationError, DepositInvalid);
|
2019-03-06 04:22:45 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* `Exit` Validation
|
|
|
|
*/
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The object is invalid or validation failed.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum ExitValidationError {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Validation completed successfully and the object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
Invalid(ExitInvalid),
|
|
|
|
}
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Describes why an object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum ExitInvalid {
|
2019-05-22 01:41:15 +00:00
|
|
|
/// The specified validator is not active.
|
|
|
|
NotActive(u64),
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The specified validator is not in the state's validator registry.
|
|
|
|
ValidatorUnknown(u64),
|
2019-03-17 01:25:37 +00:00
|
|
|
/// The specified validator has a non-maximum exit epoch.
|
|
|
|
AlreadyExited(u64),
|
|
|
|
/// The specified validator has already initiated exit.
|
|
|
|
AlreadyInitiatedExited(u64),
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The exit is for a future epoch.
|
2019-03-17 01:25:37 +00:00
|
|
|
FutureEpoch { state: Epoch, exit: Epoch },
|
|
|
|
/// The validator has not been active for long enough.
|
|
|
|
TooYoungToLeave { lifespan: Epoch, expected: u64 },
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The exit signature was not signed by the validator.
|
2019-03-06 04:22:45 +00:00
|
|
|
BadSignature,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_into_with_index_without_beacon_error!(ExitValidationError, ExitInvalid);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* `Transfer` Validation
|
|
|
|
*/
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// The object is invalid or validation failed.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum TransferValidationError {
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Validation completed successfully and the object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
Invalid(TransferInvalid),
|
2019-03-07 05:15:38 +00:00
|
|
|
/// Encountered a `BeaconStateError` whilst attempting to determine validity.
|
|
|
|
BeaconStateError(BeaconStateError),
|
2019-03-06 04:22:45 +00:00
|
|
|
}
|
|
|
|
|
2019-03-06 05:24:56 +00:00
|
|
|
/// Describes why an object is invalid.
|
2019-03-06 04:22:45 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
2019-03-07 05:15:38 +00:00
|
|
|
pub enum TransferInvalid {
|
|
|
|
/// The validator indicated by `transfer.from` is unknown.
|
|
|
|
FromValidatorUnknown(u64),
|
|
|
|
/// The validator indicated by `transfer.to` is unknown.
|
|
|
|
ToValidatorUnknown(u64),
|
|
|
|
/// The balance of `transfer.from` is insufficient.
|
|
|
|
///
|
|
|
|
/// (required, available)
|
|
|
|
FromBalanceInsufficient(u64, u64),
|
|
|
|
/// Adding `transfer.fee` to `transfer.amount` causes an overflow.
|
|
|
|
///
|
|
|
|
/// (transfer_fee, transfer_amount)
|
|
|
|
FeeOverflow(u64, u64),
|
|
|
|
/// This transfer would result in the `transfer.from` account to have `0 < balance <
|
|
|
|
/// min_deposit_amount`
|
|
|
|
///
|
|
|
|
/// (resulting_amount, min_deposit_amount)
|
|
|
|
InvalidResultingFromBalance(u64, u64),
|
|
|
|
/// The state slot does not match `transfer.slot`.
|
|
|
|
///
|
|
|
|
/// (state_slot, transfer_slot)
|
|
|
|
StateSlotMismatch(Slot, Slot),
|
2019-03-06 03:46:12 +00:00
|
|
|
/// The `transfer.slot` is in the past relative to the state slot.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// (state_slot, transfer_slot)
|
|
|
|
TransferSlotInPast(Slot, Slot),
|
2019-03-07 05:15:38 +00:00
|
|
|
/// The `transfer.from` validator has been activated and is not withdrawable.
|
|
|
|
///
|
|
|
|
/// (from_validator)
|
|
|
|
FromValidatorIneligableForTransfer(u64),
|
|
|
|
/// The validators withdrawal credentials do not match `transfer.pubkey`.
|
2019-03-07 06:23:11 +00:00
|
|
|
///
|
|
|
|
/// (state_credentials, transfer_pubkey_credentials)
|
|
|
|
WithdrawalCredentialsMismatch(Hash256, Hash256),
|
2019-03-07 05:15:38 +00:00
|
|
|
/// The deposit was not signed by `deposit.pubkey`.
|
|
|
|
BadSignature,
|
|
|
|
/// Overflow when adding to `transfer.to` balance.
|
|
|
|
///
|
|
|
|
/// (to_balance, transfer_amount)
|
|
|
|
ToBalanceOverflow(u64, u64),
|
|
|
|
/// Overflow when adding to beacon proposer balance.
|
|
|
|
///
|
|
|
|
/// (proposer_balance, transfer_fee)
|
|
|
|
ProposerBalanceOverflow(u64, u64),
|
|
|
|
}
|
2019-03-06 04:22:45 +00:00
|
|
|
|
2019-03-07 05:15:38 +00:00
|
|
|
impl_from_beacon_state_error!(TransferValidationError);
|
|
|
|
impl_into_with_index_with_beacon_error!(TransferValidationError, TransferInvalid);
|