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

[Merged by Bors] - Altair validator client and HTTP API #2404

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b477bdd
Add chainspec and genesis validators root to eth2_libp2p
pawanjay176 Apr 5, 2021
f37f267
Network altair rpc (#2301)
pawanjay176 May 11, 2021
3d42f06
Network altair gossip (#2464)
pawanjay176 Jul 16, 2021
9f9c184
Merge network-1.5 changes
pawanjay176 Jul 16, 2021
9f29788
Fix subnet service test
pawanjay176 Jul 19, 2021
2e35733
Maintain sync committee peers
pawanjay176 Jul 20, 2021
6c76853
Merge discv5 upstream changes
pawanjay176 Jul 21, 2021
bed92c9
fix incorrect method name and update test to ensure off-by-one is inv…
realbigsean Jul 13, 2021
0656056
Change libp2p dependency to sigp fork
pawanjay176 Jul 23, 2021
59a32a3
Fix minor issues
pawanjay176 Jul 23, 2021
2b04ddf
Merge branch 'unstable' into network-altair
pawanjay176 Jul 28, 2021
e63b5de
Altair validator client and API
michaelsproul Jul 22, 2021
d0e2153
Delete the fork service
michaelsproul Jul 23, 2021
a3fb7b3
Limit selection proof pre-computation
michaelsproul Jul 26, 2021
0c25e92
Prevent bootnode adding its own ENR
michaelsproul Jul 26, 2021
b9d134e
Add target-peers and spec preset to local testnet
michaelsproul Jul 26, 2021
d1bbf1a
Add /v2/ API endpoints
michaelsproul Jul 30, 2021
8d6cdf9
Merge remote-tracking branch 'origin/unstable' into altair-vc
michaelsproul Aug 2, 2021
7b3a0a1
Tweak log levels
michaelsproul Aug 2, 2021
05fe793
Fix issues from review
pawanjay176 Aug 2, 2021
940535c
Merge branch 'unstable' into network-altair
pawanjay176 Aug 2, 2021
68357f3
Remove sync_committee_subnet_count from ChainSpec
pawanjay176 Aug 2, 2021
84830a8
Implement API for sync committee indices
michaelsproul Aug 3, 2021
86b68a4
Merge remote-tracking branch 'origin/network-altair' into altair-vc
michaelsproul Aug 3, 2021
3266fcd
Fix clippy
michaelsproul Aug 3, 2021
6a6d175
Address more review comments
pawanjay176 Aug 3, 2021
8e7466a
Fix beacon chain tests
michaelsproul Aug 3, 2021
410d751
Merge remote-tracking branch 'origin/network-altair' into altair-vc
michaelsproul Aug 3, 2021
df3fab1
Fix unset SPEC_PRESET issue in doppel test
michaelsproul Aug 4, 2021
64555fd
Merge remote-tracking branch 'origin/unstable' into altair-vc
michaelsproul Aug 4, 2021
23a7839
Clean up discv5 dev dependencies
michaelsproul Aug 4, 2021
077eab6
Fix bash `set` invocation
michaelsproul Aug 5, 2021
2dd396c
Address some review comments
michaelsproul Aug 6, 2021
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 83 additions & 19 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use crate::validator_pubkey_cache::ValidatorPubkeyCache;
use crate::BeaconForkChoiceStore;
use crate::BeaconSnapshot;
use crate::{metrics, BeaconChainError};
use eth2::types::{EventKind, SseBlock, SseChainReorg, SseFinalizedCheckpoint, SseHead};
use eth2::types::{EventKind, SseBlock, SseChainReorg, SseFinalizedCheckpoint, SseHead, SyncDuty};
use fork_choice::ForkChoice;
use futures::channel::mpsc::Sender;
use itertools::process_results;
Expand Down Expand Up @@ -1081,6 +1081,29 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
Ok(pubkey_cache.get_index(pubkey))
}

/// Return the validator indices of all public keys fetched from an iterator.
///
/// If any public key doesn't belong to a known validator then an error will be returned.
/// We could consider relaxing this by returning `Vec<Option<usize>>` in future.
pub fn validator_indices<'a>(
&self,
validator_pubkeys: impl Iterator<Item = &'a PublicKeyBytes>,
) -> Result<Vec<u64>, Error> {
let pubkey_cache = self
.validator_pubkey_cache
.try_read_for(VALIDATOR_PUBKEY_CACHE_LOCK_TIMEOUT)
.ok_or(Error::ValidatorPubkeyCacheLockTimeout)?;

validator_pubkeys
.map(|pubkey| {
pubkey_cache
.get_index(pubkey)
.map(|id| id as u64)
.ok_or(Error::ValidatorPubkeyUnknown(*pubkey))
})
.collect()
}

/// Returns the validator pubkey (if any) for the given validator index.
///
/// ## Notes
Expand Down Expand Up @@ -1214,6 +1237,16 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.get_by_slot_and_root(slot, attestation_data_root)
}

/// Return an aggregated `SyncCommitteeContribution` matching the given `root`.
pub fn get_aggregated_sync_committee_contribution(
&self,
sync_contribution_data: &SyncContributionData,
) -> Option<SyncCommitteeContribution<T::EthSpec>> {
self.naive_sync_aggregation_pool
.read()
.get(sync_contribution_data)
}

/// Produce an unaggregated `Attestation` that is valid for the given `slot` and `index`.
///
/// The produced `Attestation` will not be valid until it has been signed by exactly one
Expand Down Expand Up @@ -1882,6 +1915,19 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
Ok(())
}

/// Attempt to obtain sync committee duties from the head.
pub fn sync_committee_duties_from_head(
&self,
epoch: Epoch,
validator_indices: &[u64],
) -> Result<Vec<Option<SyncDuty>>, Error> {
self.with_head(move |head| {
head.beacon_state
.get_sync_committee_duties(epoch, validator_indices, &self.spec)
.map_err(Error::SyncDutiesError)
})
}

/// Attempt to verify and import a chain of blocks to `self`.
///
/// The provided blocks _must_ each reference the previous block via `block.parent_root` (i.e.,
Expand Down Expand Up @@ -2624,6 +2670,22 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let proposer_index = state.get_beacon_proposer_index(state.slot(), &self.spec)? as u64;
let voluntary_exits = self.op_pool.get_voluntary_exits(&state, &self.spec).into();

// Closure to fetch a sync aggregate in cases where it is required.
let get_sync_aggregate = || -> Result<SyncAggregate<_>, BlockProductionError> {
Ok(self
.op_pool
.get_sync_aggregate(&state)
.map_err(BlockProductionError::OpPoolError)?
.unwrap_or_else(|| {
warn!(
self.log,
"Producing block with no sync contributions";
"slot" => state.slot(),
);
SyncAggregate::new()
}))
};

let inner_block = match state {
BeaconState::Base(_) => BeaconBlock::Base(BeaconBlockBase {
slot,
Expand All @@ -2641,24 +2703,26 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
voluntary_exits,
},
}),
BeaconState::Altair(_) => BeaconBlock::Altair(BeaconBlockAltair {
slot,
proposer_index,
parent_root,
state_root: Hash256::zero(),
body: BeaconBlockBodyAltair {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings.into(),
attestations,
deposits,
voluntary_exits,
// FIXME(altair): put a sync aggregate from the pool here (once implemented)
sync_aggregate: SyncAggregate::new(),
},
}),
BeaconState::Altair(_) => {
let sync_aggregate = get_sync_aggregate()?;
BeaconBlock::Altair(BeaconBlockAltair {
slot,
proposer_index,
parent_root,
state_root: Hash256::zero(),
body: BeaconBlockBodyAltair {
randao_reveal,
eth1_data,
graffiti,
proposer_slashings: proposer_slashings.into(),
attester_slashings: attester_slashings.into(),
attestations,
deposits,
voluntary_exits,
sync_aggregate,
},
})
}
};

let block = SignedBeaconBlock::from_block(
Expand Down
2 changes: 2 additions & 0 deletions beacon_node/beacon_chain/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pub enum BeaconChainError {
DuplicateValidatorPublicKey,
ValidatorPubkeyCacheFileError(String),
ValidatorIndexUnknown(usize),
ValidatorPubkeyUnknown(PublicKeyBytes),
OpPoolError(OpPoolError),
NaiveAggregationError(NaiveAggregationError),
ObservedAttestationsError(ObservedAttestationsError),
Expand Down Expand Up @@ -120,6 +121,7 @@ pub enum BeaconChainError {
state_epoch: Epoch,
shuffling_epoch: Epoch,
},
SyncDutiesError(BeaconStateError),
InconsistentForwardsIter {
request_slot: Slot,
slot: Slot,
Expand Down
39 changes: 31 additions & 8 deletions beacon_node/beacon_chain/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ pub fn test_spec<E: EthSpec>() -> ChainSpec {
pub struct BeaconChainHarness<T: BeaconChainTypes> {
pub validator_keypairs: Vec<Keypair>,

pub chain: BeaconChain<T>,
pub chain: Arc<BeaconChain<T>>,
pub spec: ChainSpec,
pub data_dir: TempDir,
pub shutdown_receiver: Receiver<ShutdownReason>,
Expand Down Expand Up @@ -229,6 +229,29 @@ impl<E: EthSpec> BeaconChainHarness<EphemeralHarnessType<E>> {
target_aggregators_per_committee: u64,
store_config: StoreConfig,
chain_config: ChainConfig,
) -> Self {
Self::new_with_mutator(
eth_spec_instance,
spec,
validator_keypairs,
target_aggregators_per_committee,
store_config,
chain_config,
|x| x,
)
}

/// Apply a function to beacon chain builder before building.
pub fn new_with_mutator(
eth_spec_instance: E,
spec: Option<ChainSpec>,
validator_keypairs: Vec<Keypair>,
target_aggregators_per_committee: u64,
store_config: StoreConfig,
chain_config: ChainConfig,
mutator: impl FnOnce(
BeaconChainBuilder<EphemeralHarnessType<E>>,
) -> BeaconChainBuilder<EphemeralHarnessType<E>>,
) -> Self {
let data_dir = tempdir().expect("should create temporary data_dir");
let mut spec = spec.unwrap_or_else(test_spec::<E>);
Expand All @@ -240,7 +263,7 @@ impl<E: EthSpec> BeaconChainHarness<EphemeralHarnessType<E>> {
let log = test_logger();

let store = HotColdDB::open_ephemeral(store_config, spec.clone(), log.clone()).unwrap();
let chain = BeaconChainBuilder::new(eth_spec_instance)
let builder = BeaconChainBuilder::new(eth_spec_instance)
.logger(log.clone())
.custom_spec(spec.clone())
.store(Arc::new(store))
Expand All @@ -260,13 +283,13 @@ impl<E: EthSpec> BeaconChainHarness<EphemeralHarnessType<E>> {
log.clone(),
1,
)))
.monitor_validators(true, vec![], log)
.build()
.expect("should build");
.monitor_validators(true, vec![], log);

let chain = mutator(builder).build().expect("should build");

Self {
spec: chain.spec.clone(),
chain,
chain: Arc::new(chain),
validator_keypairs,
data_dir,
shutdown_receiver,
Expand Down Expand Up @@ -311,7 +334,7 @@ impl<E: EthSpec> BeaconChainHarness<DiskHarnessType<E>> {

Self {
spec: chain.spec.clone(),
chain,
chain: Arc::new(chain),
validator_keypairs,
data_dir,
shutdown_receiver,
Expand Down Expand Up @@ -353,7 +376,7 @@ impl<E: EthSpec> BeaconChainHarness<DiskHarnessType<E>> {

Self {
spec: chain.spec.clone(),
chain,
chain: Arc::new(chain),
validator_keypairs,
data_dir,
shutdown_receiver,
Expand Down
18 changes: 13 additions & 5 deletions beacon_node/beacon_chain/tests/block_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
extern crate lazy_static;

use beacon_chain::test_utils::{
AttestationStrategy, BeaconChainHarness, BlockStrategy, EphemeralHarnessType,
test_logger, AttestationStrategy, BeaconChainHarness, BlockStrategy, EphemeralHarnessType,
};
use beacon_chain::{BeaconSnapshot, BlockError, ChainConfig, ChainSegmentResult};
use slasher::{Config as SlasherConfig, Slasher};
Expand Down Expand Up @@ -830,17 +830,25 @@ fn block_gossip_verification() {

#[test]
fn verify_block_for_gossip_slashing_detection() {
let mut harness = get_harness(VALIDATOR_COUNT);

let slasher_dir = tempdir().unwrap();
let slasher = Arc::new(
Slasher::open(
SlasherConfig::new(slasher_dir.path().into()).for_testing(),
harness.logger().clone(),
test_logger(),
)
.unwrap(),
);
harness.chain.slasher = Some(slasher.clone());

let harness = BeaconChainHarness::new_with_mutator(
MainnetEthSpec,
None,
KEYPAIRS.to_vec(),
1 << 32,
StoreConfig::default(),
ChainConfig::default(),
|builder| builder.slasher(slasher.clone()),
);
harness.advance_slot();

let state = harness.get_current_state();
let (block1, _) = harness.make_block(state.clone(), Slot::new(1));
Expand Down
5 changes: 5 additions & 0 deletions beacon_node/http_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name = "http_api"
version = "0.1.0"
authors = ["Paul Hauner <[email protected]>"]
edition = "2018"
autotests = false # using a single test binary compiles faster

[dependencies]
warp = { git = "https://github.com/paulhauner/warp ", branch = "cors-wildcard" }
Expand Down Expand Up @@ -35,3 +36,7 @@ store = { path = "../store" }
environment = { path = "../../lighthouse/environment" }
tree_hash = "0.1.1"
sensitive_url = { path = "../../common/sensitive_url" }

[[test]]
name = "bn_http_api_tests"
path = "tests/main.rs"
Loading