Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no-std implementation #167

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
779a1e7
started no-std support
dharjeezy Dec 27, 2022
3e66ff7
invalid operation error
dharjeezy Dec 27, 2022
0b79485
introduce prelude which contains the no_std imports
dharjeezy Dec 28, 2022
7492dde
transform all state_transition errors to no_std
dharjeezy Dec 28, 2022
8221123
introduce BTreeSet and BTreeMap in prelude
dharjeezy Dec 28, 2022
ac1b571
further no_std imports in prelude
dharjeezy Dec 28, 2022
cd52ded
introduce hashbrown crate
dharjeezy Dec 29, 2022
0d05be0
serde features on structs
dharjeezy Jan 3, 2023
54f8133
make use of milagro_bls for no_std support
dharjeezy Jan 4, 2023
eeb1d5e
make ssz-rs default feature
dharjeezy Jan 4, 2023
8849fcb
fix on comments
dharjeezy Jan 4, 2023
2c0d3dd
use signature for aggregate verify
dharjeezy Jan 4, 2023
32883ab
use signature for aggregate verify
dharjeezy Jan 4, 2023
04f9bcc
introduce key validation failed
dharjeezy Jan 4, 2023
a6c3687
build successful in std and no_std context
dharjeezy Jan 5, 2023
1f0e6e2
all test passes
dharjeezy Jan 5, 2023
71710e9
remove duplication
dharjeezy Jan 8, 2023
df115f5
implement Eq and PartialEq traits for DomainType enum
dharjeezy Jan 13, 2023
7875009
remove saturating_div
dharjeezy Jan 19, 2023
33f236a
Merge branch 'main' of https://github.com/polytope-labs/ethereum-cons…
dharjeezy Jan 19, 2023
8c50522
merge changes
dharjeezy Jan 19, 2023
e5c0d21
fix warnings
dharjeezy Jan 19, 2023
2f46baf
remove prelude.rs
dharjeezy Jan 21, 2023
248b5d1
remove excess clones
Wizdave97 Jan 24, 2023
63b847d
introduce default macro for execution payload
dharjeezy Jan 26, 2023
9177be3
remove default
dharjeezy Jan 26, 2023
6b971e2
include default and alias
dharjeezy Jan 30, 2023
918fda3
use rev
dharjeezy Feb 1, 2023
a850739
Merge branch 'main' of https://github.com/polytope-labs/ethereum-cons…
dharjeezy Feb 1, 2023
8be43ea
no-std for capella fork
dharjeezy Feb 1, 2023
9862cab
change ssz-rs repo temporarily
dharjeezy Feb 1, 2023
e334085
Merge branch 'main' of https://github.com/polytope-labs/ethereum-cons…
dharjeezy Feb 25, 2023
6b7f33d
merge conflict fixed
dharjeezy Feb 25, 2023
b6ced43
fix std and no std builds
Wizdave97 Feb 27, 2023
23cd342
extra fixes
Wizdave97 Feb 27, 2023
bd19d7c
point ssz-rs to original crate
Wizdave97 Feb 27, 2023
34bb57f
point ssz-rs to polytope labs
Wizdave97 Mar 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,44 @@ license = "MIT OR Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = ["serde", "async"]
serde = ["dep:serde", "hex", "serde_json"]
async = ["tokio", "tokio-stream", "async-stream"]
spec-tests = ["serde", "serde_yaml"]
gen-spec = ["syn", "prettyplease", "quote"]
gen-tests = ["walkdir", "convert_case"]

std = [
"rand/std",
"sha2/std",
"multihash/std",
"bs58/std",
"getrandom/std",
"serde/std",
"ssz-rs/std"
]

serde = ["dep:hex", "serde_json"]

[dependencies]
ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f1" }
blst = "0.3.6"
rand = "0.8.4"
thiserror = "1.0.30"
sha2 = "0.9.8"
integer-sqrt = "0.1.5"
enr = "0.6.2"
getrandom = { version = "0.2.8", default-features=false, features = ["js"] }
ssz-rs = { git = "https://github.com/Snowfork/ssz_rs", branch="feat/contribution", default-features=false }
rand = {version = "0.8.4", default-features = false}
thiserror = {version = "1.0.30", optional=true}
error-chain={version = "0.12.4", default-features=false}
sha2 = { version ="0.9.8", default-features = false }
integer-sqrt = {version = "0.1.5", default-features = false }
enr = {version = "0.6.2" }
multihash = { version = "0.16", default-features = false, features = ["std", "multihash-impl", "identity", "sha2"] }
multiaddr = "0.14.0"
multiaddr = {version="0.14.0" }
hashbrown = {version="0.13.1"}

serde = { version = "1.0", features = ["derive"], optional = true }
serde = { version = "1.0", default-features = false, features = ["derive"] }
dharjeezy marked this conversation as resolved.
Show resolved Hide resolved
serde_json = { version = "1.0.81", optional = true }
serde_yaml = { version = "0.8", optional = true }
hex = {version = "0.4.3", optional = true }

blst = {version = "0.3.6", optional=true}
milagro_bls = { git = "https://github.com/webb-tools/milagro_bls", default-features = false }
dharjeezy marked this conversation as resolved.
Show resolved Hide resolved

tokio = { version = "1.18.2", features = ["full"], optional = true }
tokio-stream = { version = "0.1.8", optional = true }
async-stream = { version = "0.3.3", optional = true }
Expand All @@ -39,7 +55,7 @@ quote = { version = "1.0.18", optional = true }

walkdir = { version = "2.3.2", optional = true }
convert_case = { version = "0.5.0", optional = true }
bs58 = "0.4.0"
bs58 = {version="0.4.0", default-features = false }

[dev-dependencies]
serde_with = "1.13.0"
Expand Down
5 changes: 3 additions & 2 deletions src/altair/beacon_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::altair::SyncAggregate;
use crate::phase0::{
Attestation, AttesterSlashing, Deposit, Eth1Data, ProposerSlashing, SignedVoluntaryExit,
};
use crate::prelude::*;
use crate::primitives::{BlsSignature, Bytes32, Root, Slot, ValidatorIndex};
use ssz_rs::prelude::*;

Expand Down Expand Up @@ -39,9 +40,9 @@ pub struct BeaconBlock<
const MAX_VOLUNTARY_EXITS: usize,
const SYNC_COMMITTEE_SIZE: usize,
> {
#[serde(with = "crate::serde::as_string")]
#[cfg_attr(feature = "serde", serde(with = "crate::serde::as_string"))]
pub slot: Slot,
#[serde(with = "crate::serde::as_string")]
#[cfg_attr(feature = "serde", serde(with = "crate::serde::as_string"))]
pub proposer_index: ValidatorIndex,
pub parent_root: Root,
pub state_root: Root,
Expand Down
32 changes: 24 additions & 8 deletions src/altair/beacon_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::altair::{
BeaconBlockHeader, Checkpoint, Eth1Data, Fork, SyncCommittee, Validator,
JUSTIFICATION_BITS_LENGTH,
};
use crate::prelude::*;
use crate::primitives::{Bytes32, Gwei, ParticipationFlags, Root, Slot};
use ssz_rs::prelude::*;

Expand All @@ -17,10 +18,10 @@ pub struct BeaconState<
const MAX_VALIDATORS_PER_COMMITTEE: usize,
const SYNC_COMMITTEE_SIZE: usize,
> {
#[serde(with = "crate::serde::as_string")]
#[cfg_attr(feature = "serde", serde(with = "crate::serde::as_string"))]
pub genesis_time: u64,
pub genesis_validators_root: Root,
#[serde(with = "crate::serde::as_string")]
#[cfg_attr(feature = "serde", serde(with = "crate::serde::as_string"))]
pub slot: Slot,
pub fork: Fork,
pub latest_block_header: BeaconBlockHeader,
Expand All @@ -29,23 +30,38 @@ pub struct BeaconState<
pub historical_roots: List<Root, HISTORICAL_ROOTS_LIMIT>,
pub eth1_data: Eth1Data,
pub eth1_data_votes: List<Eth1Data, ETH1_DATA_VOTES_BOUND>,
#[serde(with = "crate::serde::as_string")]
#[cfg_attr(feature = "serde", serde(with = "crate::serde::as_string"))]
pub eth1_deposit_index: u64,
pub validators: List<Validator, VALIDATOR_REGISTRY_LIMIT>,
#[serde(with = "crate::serde::collection_over_string")]
#[cfg_attr(
feature = "serde",
serde(with = "crate::serde::collection_over_string")
)]
pub balances: List<Gwei, VALIDATOR_REGISTRY_LIMIT>,
pub randao_mixes: Vector<Bytes32, EPOCHS_PER_HISTORICAL_VECTOR>,
#[serde(with = "crate::serde::collection_over_string")]
#[cfg_attr(
feature = "serde",
serde(with = "crate::serde::collection_over_string")
)]
pub slashings: Vector<Gwei, EPOCHS_PER_SLASHINGS_VECTOR>,
#[serde(with = "crate::serde::collection_over_string")]
#[cfg_attr(
feature = "serde",
serde(with = "crate::serde::collection_over_string")
)]
pub previous_epoch_participation: List<ParticipationFlags, VALIDATOR_REGISTRY_LIMIT>,
#[serde(with = "crate::serde::collection_over_string")]
#[cfg_attr(
feature = "serde",
serde(with = "crate::serde::collection_over_string")
)]
pub current_epoch_participation: List<ParticipationFlags, VALIDATOR_REGISTRY_LIMIT>,
pub justification_bits: Bitvector<JUSTIFICATION_BITS_LENGTH>,
pub previous_justified_checkpoint: Checkpoint,
pub current_justified_checkpoint: Checkpoint,
pub finalized_checkpoint: Checkpoint,
#[serde(with = "crate::serde::collection_over_string")]
#[cfg_attr(
feature = "serde",
serde(with = "crate::serde::collection_over_string")
)]
pub inactivity_scores: List<u64, VALIDATOR_REGISTRY_LIMIT>,
pub current_sync_committee: SyncCommittee<SYNC_COMMITTEE_SIZE>,
pub next_sync_committee: SyncCommittee<SYNC_COMMITTEE_SIZE>,
Expand Down
11 changes: 6 additions & 5 deletions src/altair/block_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use crate::altair as spec;

use crate::crypto::{eth_fast_aggregate_verify, verify_signature};
use crate::domains::DomainType;
use crate::prelude::*;
use crate::prelude::*;
dharjeezy marked this conversation as resolved.
Show resolved Hide resolved
use crate::primitives::{BlsPublicKey, ParticipationFlags, ValidatorIndex};
use crate::signing::compute_signing_root;
use crate::state_transition::{
Expand All @@ -20,8 +22,6 @@ use spec::{
PARTICIPATION_FLAG_WEIGHTS, PROPOSER_WEIGHT, SYNC_REWARD_WEIGHT, WEIGHT_DENOMINATOR,
};
use ssz_rs::prelude::*;
use std::collections::{HashMap, HashSet};
use std::iter::zip;

pub fn process_attestation<
const SLOTS_PER_HISTORICAL_ROOT: usize,
Expand Down Expand Up @@ -202,8 +202,9 @@ pub fn process_deposit<

let public_key = &deposit.data.public_key;
let amount = deposit.data.amount;
let cloned_validators = state.validators.clone();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we avoid a full clone here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this, if i don't clone, mutable borrow occurs when i try to iterate over the validators and put them into a HashSet

let validator_public_keys: HashSet<&BlsPublicKey> =
HashSet::from_iter(state.validators.iter().map(|v| &v.public_key));
cloned_validators.iter().map(|v| &v.public_key).collect();
if !validator_public_keys.contains(public_key) {
let mut deposit_message = DepositMessage {
public_key: public_key.clone(),
Expand Down Expand Up @@ -315,9 +316,9 @@ pub fn process_sync_aggregate<
let proposer_reward =
participant_reward * PROPOSER_WEIGHT / (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT);

let cloned_validators = state.validators.clone();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same -- why do we need to change this in the first place?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is due to the iteration and collecting into the Hashbrown's Hashset crate

// Apply participant and proposer rewards
let all_public_keys = state
.validators
let all_public_keys = cloned_validators
.iter()
.enumerate()
.map(|(i, v)| (&v.public_key, i))
Expand Down
2 changes: 1 addition & 1 deletion src/altair/epoch_processing.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::altair as spec;

use crate::prelude::*;
use crate::primitives::{Gwei, ParticipationFlags, ValidatorIndex, GENESIS_EPOCH};
use crate::state_transition::{Context, Result};
use spec::{
Expand All @@ -12,7 +13,6 @@ use spec::{
weigh_justification_and_finalization, BeaconState, PARTICIPATION_FLAG_WEIGHTS,
TIMELY_TARGET_FLAG_INDEX,
};
use std::mem;

// Return the base reward for the validator defined by `index` with respect to the current `state`
pub fn get_base_reward<
Expand Down
1 change: 1 addition & 0 deletions src/altair/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::altair::{
get_next_sync_committee, BeaconState, Fork,
};
use crate::phase0;
use crate::prelude::*;
use crate::state_transition::{Context, Result};
use ssz_rs::prelude::*;

Expand Down
3 changes: 2 additions & 1 deletion src/altair/genesis.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::altair as spec;

use crate::phase0::DEPOSIT_DATA_LIST_BOUND;
use crate::prelude::*;
use crate::primitives::{Gwei, Hash32, GENESIS_EPOCH};
use crate::state_transition::{Context, Result};
use spec::{
Expand Down Expand Up @@ -65,7 +66,7 @@ pub fn initialize_beacon_state_from_eth1<
..Default::default()
};
let randao_mixes = Vector::from_iter(
std::iter::repeat(eth1_block_hash).take(context.epochs_per_historical_vector as usize),
repeat(eth1_block_hash).take(context.epochs_per_historical_vector as usize),
);
let mut state = BeaconState {
genesis_time: eth1_timestamp + context.genesis_delay,
Expand Down
2 changes: 1 addition & 1 deletion src/altair/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::altair as spec;

use crate::crypto::{eth_aggregate_public_keys, hash};
use crate::domains::DomainType;
use crate::prelude::*;
use crate::primitives::{Epoch, Gwei, ParticipationFlags, ValidatorIndex};
use crate::state_transition::{
invalid_operation_error, Context, Error, InvalidAttestation, InvalidOperation, Result,
Expand All @@ -16,7 +17,6 @@ use spec::{
TIMELY_HEAD_FLAG_INDEX, TIMELY_SOURCE_FLAG_INDEX, TIMELY_TARGET_FLAG_INDEX, WEIGHT_DENOMINATOR,
};
use ssz_rs::Vector;
use std::collections::HashSet;

// Return a new ``ParticipationFlags`` adding ``flag_index`` to ``flags``
pub fn add_flag(flags: ParticipationFlags, flag_index: usize) -> ParticipationFlags {
Expand Down
1 change: 1 addition & 0 deletions src/altair/light_client.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::altair::{SyncAggregate, SyncCommittee};
use crate::phase0::BeaconBlockHeader;
use crate::prelude::*;
use crate::primitives::{Bytes32, Version};
use ssz_rs::prelude::*;

Expand Down
1 change: 1 addition & 0 deletions src/altair/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub use state_transition::{
block_processing::*, epoch_processing::*, helpers::*, slot_processing::*, *,
};

use crate::prelude::*;
pub use beacon_block::*;
pub use beacon_state::*;
pub use fork::*;
Expand Down
4 changes: 2 additions & 2 deletions src/altair/state_transition/block_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub use crate::altair::block_processing::process_attestation;
pub use crate::altair::block_processing::process_block;
pub use crate::altair::block_processing::process_deposit;
pub use crate::altair::block_processing::process_sync_aggregate;
use crate::prelude::*;
use crate::primitives::{Bytes32, DomainType, Gwei, ValidatorIndex, FAR_FUTURE_EPOCH};
use crate::signing::compute_signing_root;
use ssz_rs::prelude::*;
Expand All @@ -22,7 +23,6 @@ use spec::{
BeaconBlock, BeaconBlockBody, BeaconBlockHeader, BeaconState, Deposit, ProposerSlashing,
SignedVoluntaryExit, Validator,
};
use std::collections::HashSet;
pub fn get_validator_from_deposit(deposit: &Deposit, context: &Context) -> Validator {
let amount = deposit.data.amount;
let effective_balance = Gwei::min(
Expand Down Expand Up @@ -489,7 +489,7 @@ pub fn process_voluntary_exit<
validator.activation_eligibility_epoch + context.shard_committee_period;
if current_epoch < minimum_time_active {
return Err(invalid_operation_error(InvalidOperation::VoluntaryExit(
InvalidVoluntaryExit::ValidatoIsNotActiveForLongEnough {
InvalidVoluntaryExit::ValidatorIsNotActiveForLongEnough {
ralexstokes marked this conversation as resolved.
Show resolved Hide resolved
current_epoch,
minimum_time_active,
},
Expand Down
1 change: 1 addition & 0 deletions src/altair/state_transition/epoch_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub use crate::altair::epoch_processing::process_rewards_and_penalties;
pub use crate::altair::epoch_processing::process_slashings;
pub use crate::altair::epoch_processing::process_sync_committee_updates;

use crate::prelude::*;
use crate::primitives::{Epoch, Gwei, ValidatorIndex};
use spec::{
compute_activation_exit_epoch, get_block_root, get_current_epoch, get_previous_epoch,
Expand Down
8 changes: 4 additions & 4 deletions src/altair/state_transition/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub use crate::altair::helpers::get_unslashed_participating_indices;
pub use crate::altair::helpers::has_flag;
pub use crate::altair::helpers::slash_validator;
use crate::crypto::{fast_aggregate_verify, hash, verify_signature};
use crate::prelude::*;
use crate::primitives::{
Bytes32, CommitteeIndex, Domain, DomainType, Epoch, ForkDigest, Gwei, Root, Slot,
ValidatorIndex, Version, FAR_FUTURE_EPOCH, GENESIS_EPOCH,
Expand All @@ -25,8 +26,7 @@ use spec::{
Validator,
};
use ssz_rs::prelude::*;
use std::cmp;
use std::collections::HashSet;

pub fn compute_activation_exit_epoch(epoch: Epoch, context: &Context) -> Epoch {
epoch + 1 + context.max_seed_lookahead
}
Expand Down Expand Up @@ -117,7 +117,7 @@ pub fn compute_proposer_index<
loop {
let shuffled_index = compute_shuffled_index((i % total) as usize, total, seed, context)?;
let candidate_index = indices[shuffled_index];
let i_bytes: [u8; 8] = (i / 32).to_le_bytes();
let i_bytes: [u8; 4] = (i.saturating_div(32)).to_le_bytes();
hash_input[32..].copy_from_slice(&i_bytes);
let random_byte = hash(hash_input).as_ref()[(i % 32)] as u64;
let effective_balance = state.validators[candidate_index].effective_balance;
Expand Down Expand Up @@ -254,7 +254,7 @@ pub fn get_attesting_indices<
},
)));
}
let mut indices = HashSet::with_capacity(bits.capacity());
let mut indices = HashSet::new();
for (i, validator_index) in committee.iter().enumerate() {
if bits[i] {
indices.insert(*validator_index);
Expand Down
5 changes: 3 additions & 2 deletions src/altair/sync.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::prelude::*;
use crate::primitives::{BlsPublicKey, BlsSignature};
use ssz_rs::prelude::*;

Expand All @@ -11,8 +12,8 @@ pub struct SyncAggregate<const SYNC_COMMITTEE_SIZE: usize> {
#[derive(Default, Debug, SimpleSerialize, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SyncCommittee<const SYNC_COMMITTEE_SIZE: usize> {
#[serde(rename = "pubkeys")]
#[cfg_attr(feature = "serde", serde(rename = "pubkeys"))]
pub public_keys: Vector<BlsPublicKey, SYNC_COMMITTEE_SIZE>,
#[serde(rename = "aggregate_pubkey")]
#[cfg_attr(feature = "serde", serde(rename = "aggregate_pubkey"))]
pub aggregate_public_key: BlsPublicKey,
}
11 changes: 6 additions & 5 deletions src/altair/validator.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::prelude::*;
use crate::primitives::{BlsSignature, Root, Slot, ValidatorIndex};
use ssz_rs::prelude::*;

Expand All @@ -6,10 +7,10 @@ pub const SYNC_COMMITTEE_SUBNET_COUNT: usize = 4;
#[derive(Debug, Default, Clone, SimpleSerialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SyncCommitteeMessage {
#[serde(with = "crate::serde::as_string")]
#[cfg_attr(feature = "serde", serde(with = "crate::serde::as_string"))]
pub slot: Slot,
pub beacon_block_root: Root,
#[serde(with = "crate::serde::as_string")]
#[cfg_attr(feature = "serde", serde(with = "crate::serde::as_string"))]
pub validator_index: ValidatorIndex,
pub signature: BlsSignature,
}
Expand All @@ -21,10 +22,10 @@ pub(super) const fn get_sync_subcommittee_size(sync_committee_size: usize) -> us
#[derive(Debug, Default, Clone, SimpleSerialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SyncCommitteeContribution<const SYNC_SUBCOMMITTEE_SIZE: usize> {
#[serde(with = "crate::serde::as_string")]
#[cfg_attr(feature = "serde", serde(with = "crate::serde::as_string"))]
pub slot: Slot,
pub beacon_block_root: Root,
#[serde(with = "crate::serde::as_string")]
#[cfg_attr(feature = "serde", serde(with = "crate::serde::as_string"))]
pub subcommittee_index: u64,
pub aggregation_bits: Bitvector<SYNC_SUBCOMMITTEE_SIZE>,
pub signature: BlsSignature,
Expand All @@ -33,7 +34,7 @@ pub struct SyncCommitteeContribution<const SYNC_SUBCOMMITTEE_SIZE: usize> {
#[derive(Debug, Default, Clone, SimpleSerialize)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ContributionAndProof<const SYNC_SUBCOMMITTEE_SIZE: usize> {
#[serde(with = "crate::serde::as_string")]
#[cfg_attr(feature = "serde", serde(with = "crate::serde::as_string"))]
pub aggregator_index: ValidatorIndex,
pub contribution: SyncCommitteeContribution<SYNC_SUBCOMMITTEE_SIZE>,
pub selection_proof: BlsSignature,
Expand Down
Loading