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

Runtime network selection #1482

Merged
merged 83 commits into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
15b5856
Refactor code for dynamic network selection (wip)
elmattic Mar 9, 2022
8bee099
Fix some params for testing calibnet sync
elmattic Mar 9, 2022
cc524f0
Fix typo
elmattic Mar 9, 2022
53bc86c
add chain flag to forest daemon
connormullett Mar 9, 2022
4e99b2d
Merge branch 'elmattic/network_selection' of github.com:ChainSafe/for…
connormullett Mar 9, 2022
e730bfb
scaffold CustomConfig
connormullett Mar 9, 2022
6120390
implement some members of custom config
connormullett Mar 9, 2022
e2ee9c0
Merge branch 'main' into elmattic/network_selection
elmattic Mar 10, 2022
d994fbd
Use mainnet network config
elmattic Mar 10, 2022
e60c0c0
Remove cfg attributes
elmattic Mar 10, 2022
73225d5
Add block delay method
elmattic Mar 10, 2022
0b35972
Change newest network version to be the same for all
elmattic Mar 10, 2022
7ab0c3f
hook up CustomConfig struct to build_config
connormullett Mar 10, 2022
031f4f0
Merge branch 'elmattic/network_selection' of github.com:ChainSafe/for…
connormullett Mar 10, 2022
b2b61fb
Add trait function to get an Height's epoch
elmattic Mar 11, 2022
90bd3db
Change const upgrade heights to runtime ones
elmattic Mar 14, 2022
58c30b6
Refactor Config not to use trait and remove public consts
elmattic Mar 14, 2022
2cc7aae
Add calibnet ctor
elmattic Mar 14, 2022
d094e1d
Fix cli args
elmattic Mar 15, 2022
5a7aef7
Move back to network name
elmattic Mar 15, 2022
99e99df
Initial work for file-based chain configuration
elmattic Mar 16, 2022
5518737
Change rpc_port to be a u16 instead of a string
elmattic Mar 16, 2022
22b79c3
Fix calibnet heights epoch
elmattic Mar 16, 2022
293b7bc
Fix typo
elmattic Mar 16, 2022
af46b0f
Fix incomplete config parsing error
elmattic Mar 17, 2022
44267cb
Fix missing default directives
elmattic Mar 17, 2022
b237841
Add genesis builtin bytes
elmattic Mar 17, 2022
77002d7
Merge branch 'main' into elmattic/network_selection
elmattic Mar 17, 2022
f31af33
Remove useless methods
elmattic Mar 17, 2022
8d7d681
Fix compilation errors
elmattic Mar 18, 2022
95dbd95
Fix more tests
elmattic Mar 18, 2022
8930d6c
Merge branch 'main' into elmattic/network_selection
elmattic Mar 18, 2022
f886f2b
Fix previous commit
elmattic Mar 18, 2022
afe5812
cargo fmt
elmattic Mar 18, 2022
f57790b
Make clippy happy
elmattic Mar 18, 2022
435c15c
Merge branch 'main' into elmattic/network_selection
elmattic Mar 18, 2022
e336bed
Fix conformance tests compilation
elmattic Mar 18, 2022
5d1a668
Refactor Heights creation with ctor
elmattic Mar 21, 2022
8c489a2
Merge branch 'main' into elmattic/network_selection
elmattic Mar 21, 2022
5b9d035
Fix panic when using config dump subcommand
elmattic Mar 21, 2022
b09703d
Fix cargo fmt
elmattic Mar 21, 2022
2371721
Remove network from version
elmattic Mar 21, 2022
6dc7944
Add proper error handling for unsupported network
elmattic Mar 21, 2022
83b15d9
Revert code to original
elmattic Mar 21, 2022
d94ac3a
Fix address network prefix
elmattic Mar 21, 2022
9e3331d
Fix conformance tests
elmattic Mar 21, 2022
65150b5
Fix cargo fmt
elmattic Mar 21, 2022
8218e88
Fix use of wrong submodule version
elmattic Mar 22, 2022
becf58c
Fix conformance tests
elmattic Mar 22, 2022
6b57ac7
Make clippy happy
elmattic Mar 22, 2022
0b2e332
Refactor chain config construction
elmattic Mar 23, 2022
091bbf7
Fix cargo fmt
elmattic Mar 23, 2022
a3fcf9f
Remove the conformance feature
elmattic Mar 23, 2022
3edf135
Refactor infos inside associated module
elmattic Mar 23, 2022
2965cf2
Remove old networks
elmattic Mar 23, 2022
63d4adf
Update the README
elmattic Mar 23, 2022
843ad33
Remove useless closure
elmattic Mar 23, 2022
38553a9
Fix chain parameter to use possible_values
elmattic Mar 24, 2022
9acef01
Fix overriding logic
elmattic Mar 24, 2022
1e443e2
Remove dead code
elmattic Mar 24, 2022
c1f5105
Refactor ctor to use chain config
elmattic Mar 24, 2022
9ead3a9
Fix lint
elmattic Mar 24, 2022
b100aa9
Fix duplicated code
elmattic Mar 24, 2022
fab7026
Refactor MessagePool to take ChainConfig as parameter
elmattic Mar 24, 2022
f041d63
Merge branch 'main' into elmattic/network_selection
elmattic Mar 25, 2022
009286a
Remove genesis field in ChainConfig struct
elmattic Mar 29, 2022
6468e0e
Move out the bootstrap peers override
elmattic Mar 29, 2022
aa18d77
Separate Chain DBs (#1523)
connormullett Apr 4, 2022
73c2d3b
Deserialize Typesafe NetworkVersion (#1533)
connormullett Jun 8, 2022
364ac97
Merge branch 'main' into elmattic/network_selection
elmattic Jun 20, 2022
7f5808d
Fix missing calico height
elmattic Jun 20, 2022
42e8864
Merge branch 'main' into elmattic/network_selection
elmattic Jun 21, 2022
a2a20e9
Fix previous merge error
elmattic Jun 21, 2022
5a5e3b4
Remove toml file
elmattic Jun 21, 2022
226162f
Add some comment (seen in Lotus codebase)
elmattic Jun 21, 2022
a5194d6
Refactor code to use parse method
elmattic Jun 21, 2022
73ae06d
Merge branch 'main' into elmattic/network_selection
lemmih Jun 22, 2022
5545ef0
Fail with informative error message.
lemmih Jun 22, 2022
21720e8
Hide BeaconSchedule internals.
lemmih Jun 22, 2022
ef0decb
Stricter parsing of network names.
lemmih Jun 22, 2022
e8e3f5c
Also support calibnet.
lemmih Jun 22, 2022
d4edb24
Remove the conformance network.
lemmih Jun 22, 2022
4d0f709
Remove conformance chain heights.
lemmih Jun 22, 2022
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
3 changes: 3 additions & 0 deletions Cargo.lock

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

13 changes: 2 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,6 @@ build:
release:
cargo build --release --bin forest

interopnet:
cargo build --release --manifest-path=forest/Cargo.toml --no-default-features --features "rocksdb, interopnet"

devnet:
cargo build --manifest-path=forest/Cargo.toml --no-default-features --features "devnet, rocksdb"

calibnet:
cargo build --release --manifest-path=forest/Cargo.toml --no-default-features --features "calibnet, rocksdb"

docker-run:
docker build -t forest:latest -f ./Dockerfile . && docker run forest

Expand All @@ -81,7 +72,7 @@ pull-serialization-tests:
run-serialization-vectors:
cargo test --release --manifest-path=$(SER_TESTS)/Cargo.toml --features "submodule_tests" -- --test-threads=$(RUST_TEST_THREADS)

run-vectors: run-serialization-vectors run-conformance-vectors
run-vectors: run-serialization-vectors

test-vectors: pull-serialization-tests run-vectors

Expand Down Expand Up @@ -122,4 +113,4 @@ mdbook:
mdbook-build:
mdbook build ./documentation

.PHONY: clean clean-all lint build release test test-all test-release license test-vectors run-vectors pull-serialization-tests install docs run-serialization-vectors run-conformance-vectors
.PHONY: clean clean-all lint build release test test-all test-release license test-vectors run-vectors pull-serialization-tests install docs run-serialization-vectors
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,17 @@ make test-all

### Joining the testnet

Build with the `interopnet` config with:
Select the builtin calibnet configuration with the `--chain` option:

```bash
make interopnet

# Run and import past the state migrations to latest network version
./target/release/forest --import-snapshot ./types/networks/src/interopnet/snapshot.car
./target/release/forest --chain calibnet --import-snapshot snapshot.car
```

Importing the snapshot only needs to happen during the first run. Following this, to restart the daemon run:

```bash
./target/release/forest
./target/release/forest --chain calibnet
```

### Interacting with Forest via CLI
Expand Down
5 changes: 5 additions & 0 deletions blockchain/beacon/src/drand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ impl<T> BeaconSchedule<T>
where
T: Beacon,
{
/// Constructs a new, empty BeaconSchedule<T> with the specified capacity.
pub fn with_capacity(capacity: usize) -> Self {
BeaconSchedule(Vec::with_capacity(capacity))
}

/// Returns the beacon entries for a given epoch.
/// When the beacon for the given epoch is on a new beacon, randomness entries are taken
/// from the last two rounds.
Expand Down
31 changes: 24 additions & 7 deletions blockchain/chain/src/store/base_fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use clock::ChainEpoch;
use encoding::Cbor;
use ipld_blockstore::BlockStore;
use message::Message;
use networks::UPGRADE_SMOKE_HEIGHT;
use num_bigint::{BigInt, Integer};
use std::collections::HashSet;
use types::BLOCK_GAS_LIMIT;
Expand Down Expand Up @@ -36,8 +35,9 @@ fn compute_next_base_fee(
gas_limit_used: i64,
no_of_blocks: usize,
epoch: ChainEpoch,
smoke_height: ChainEpoch,
) -> BigInt {
let mut delta: i64 = if epoch > UPGRADE_SMOKE_HEIGHT {
let mut delta: i64 = if epoch > smoke_height {
(gas_limit_used / no_of_blocks as i64) - BLOCK_GAS_TARGET
} else {
// Yes the denominator and numerator are intentionally flipped here. We are matching go.
Expand Down Expand Up @@ -65,7 +65,11 @@ fn compute_next_base_fee(
next_base_fee
}

pub fn compute_base_fee<DB>(db: &DB, ts: &Tipset) -> Result<BigInt, crate::Error>
pub fn compute_base_fee<DB>(
db: &DB,
ts: &Tipset,
smoke_height: ChainEpoch,
) -> Result<BigInt, crate::Error>
where
DB: BlockStore,
{
Expand Down Expand Up @@ -98,12 +102,14 @@ where
total_limit,
ts.blocks().len(),
ts.epoch(),
smoke_height,
))
}

#[cfg(test)]
mod tests {
use super::*;
use networks::{ChainConfig, Height};

fn construct_tests() -> Vec<(i64, i64, usize, i64, i64)> {
// (base_fee, limit_used, no_of_blocks, output)
Expand Down Expand Up @@ -137,17 +143,28 @@ mod tests {

#[test]
fn run_base_fee_tests() {
let smoke_height = ChainConfig::default().epoch(Height::Smoke);
let cases = construct_tests();

for case in cases {
// Pre smoke
let output =
compute_next_base_fee(&case.0.into(), case.1, case.2, UPGRADE_SMOKE_HEIGHT - 1);
let output = compute_next_base_fee(
&case.0.into(),
case.1,
case.2,
smoke_height - 1,
smoke_height,
);
assert_eq!(BigInt::from(case.3), output);

// Post smoke
let output =
compute_next_base_fee(&case.0.into(), case.1, case.2, UPGRADE_SMOKE_HEIGHT + 1);
let output = compute_next_base_fee(
&case.0.into(),
case.1,
case.2,
smoke_height + 1,
smoke_height,
);
assert_eq!(BigInt::from(case.4), output);
}
}
Expand Down
8 changes: 8 additions & 0 deletions blockchain/chain_sync/src/chain_muxer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ where
mem_pool: Arc<MessagePool<M>>,
genesis: Arc<Tipset>,
message_processing_strategy: PubsubMessageProcessingStrategy,
block_delay: u64,
) -> Result<Option<(FullTipset, PeerId)>, ChainMuxerError> {
let (tipset, source) = match event {
NetworkEvent::HelloRequest { request, source } => {
Expand Down Expand Up @@ -454,6 +455,7 @@ where
chain_store.clone(),
bad_block_cache.clone(),
genesis.clone(),
block_delay,
)
.await
{
Expand Down Expand Up @@ -490,6 +492,7 @@ where
let bad_block_cache = self.bad_blocks.clone();
let mem_pool = self.mpool.clone();
let tipset_sample_size = self.sync_config.tipset_sample_size;
let block_delay = self.state_manager.chain_config.block_delay_secs;

let evaluator = async move {
let mut tipsets = vec![];
Expand All @@ -510,6 +513,7 @@ where
mem_pool.clone(),
genesis.clone(),
PubsubMessageProcessingStrategy::Process,
block_delay,
)
.await
{
Expand Down Expand Up @@ -607,6 +611,7 @@ where
let genesis = self.genesis.clone();
let bad_block_cache = self.bad_blocks.clone();
let mem_pool = self.mpool.clone();
let block_delay = self.state_manager.chain_config.block_delay_secs;
let stream_processor: ChainMuxerFuture<(), ChainMuxerError> = Box::pin(async move {
loop {
let event = match p2p_messages.recv().await {
Expand All @@ -625,6 +630,7 @@ where
mem_pool.clone(),
genesis.clone(),
PubsubMessageProcessingStrategy::DoNotProcess,
block_delay,
)
.await
{
Expand Down Expand Up @@ -697,6 +703,7 @@ where
let bad_block_cache = self.bad_blocks.clone();
let mem_pool = self.mpool.clone();
let tipset_sender = self.tipset_sender.clone();
let block_delay = self.state_manager.chain_config.block_delay_secs;
let stream_processor: ChainMuxerFuture<UnexpectedReturnKind, ChainMuxerError> = Box::pin(
async move {
// If a tipset has been provided, pass it to the tipset processor
Expand All @@ -723,6 +730,7 @@ where
mem_pool.clone(),
genesis.clone(),
PubsubMessageProcessingStrategy::Process,
block_delay,
)
.await
{
Expand Down
4 changes: 3 additions & 1 deletion blockchain/chain_sync/src/sync/peer_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use fil_types::verifier::MockVerifier;
use forest_libp2p::hello::HelloRequest;
use libp2p::core::PeerId;
use message_pool::{test_provider::TestApi, MessagePool};
use networks::ChainConfig;
use state_manager::StateManager;
use std::time::Duration;

Expand All @@ -26,6 +27,7 @@ fn peer_manager_update() {
"test".to_string(),
tx,
Default::default(),
&ChainConfig::default(),
))
.unwrap();
let mpool = Arc::new(mpool);
Expand All @@ -49,7 +51,7 @@ fn peer_manager_update() {
height: 0,
beacon: Arc::new(MockBeacon::new(Duration::from_secs(1))),
}]));
let state_manager = Arc::new(StateManager::new(chain_store));
let state_manager = Arc::new(StateManager::new(chain_store, config.chain));
let cs = ChainSyncer::<_, _, MockVerifier, TestApi>::new(
state_manager,
beacon,
Expand Down
23 changes: 15 additions & 8 deletions blockchain/chain_sync/src/tipset_syncer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use forest_libp2p::chain_exchange::TipsetBundle;
use interpreter::price_list_by_epoch;
use ipld_blockstore::BlockStore;
use message::{Message, UnsignedMessage};
use networks::{get_network_version_default, BLOCK_DELAY_SECS, UPGRADE_SMOKE_HEIGHT};
use networks::Height;
use state_manager::Error as StateManagerError;
use state_manager::StateManager;
use state_tree::StateTree;
Expand Down Expand Up @@ -1242,8 +1242,10 @@ async fn validate_block<
.map_err(|e| (*block_cid, e.into()))?;

// Timestamp checks
let block_delay = state_manager.chain_config.block_delay_secs;
let smoke_height = state_manager.chain_config.epoch(Height::Smoke);
let nulls = (header.epoch() - (base_tipset.epoch() + 1)) as u64;
let target_timestamp = base_tipset.min_timestamp() + BLOCK_DELAY_SECS * (nulls + 1);
let target_timestamp = base_tipset.min_timestamp() + block_delay * (nulls + 1);
if target_timestamp != header.timestamp() {
return Err((
*block_cid,
Expand Down Expand Up @@ -1303,9 +1305,11 @@ async fn validate_block<
let v_block = Arc::clone(&block);
validations.push(task::spawn_blocking(move || {
let base_fee =
chain::compute_base_fee(v_block_store.as_ref(), &v_base_tipset).map_err(|e| {
TipsetRangeSyncerError::Validation(format!("Could not compute base fee: {}", e))
})?;
chain::compute_base_fee(v_block_store.as_ref(), &v_base_tipset, smoke_height).map_err(
|e| {
TipsetRangeSyncerError::Validation(format!("Could not compute base fee: {}", e))
},
)?;
let parent_base_fee = v_block.header.parent_base_fee();
if &base_fee != parent_base_fee {
return Err(TipsetRangeSyncerError::Validation(format!(
Expand Down Expand Up @@ -1459,7 +1463,7 @@ async fn validate_block<
let header = v_block.header();
let mut miner_address_buf = header.miner_address().marshal_cbor()?;

if header.epoch() > UPGRADE_SMOKE_HEIGHT {
if header.epoch() > smoke_height {
let vrf_proof = base_tipset
.min_ticket()
.ok_or(TipsetRangeSyncerError::TipsetWithoutTicket)?
Expand Down Expand Up @@ -1626,7 +1630,10 @@ fn check_block_messages<
block: &Block,
base_tipset: &Arc<Tipset>,
) -> Result<(), TipsetRangeSyncerError> {
let network_version = get_network_version_default(block.header.epoch());
let network_version = state_manager
.chain_config
.network_version(block.header.epoch());
let calico_height = state_manager.chain_config.epoch(Height::Calico);

// Do the initial loop here
// check block message and signatures in them
Expand Down Expand Up @@ -1663,7 +1670,7 @@ fn check_block_messages<
} else {
return Err(TipsetRangeSyncerError::BlockWithoutBlsAggregate);
}
let price_list = price_list_by_epoch(base_tipset.epoch());
let price_list = price_list_by_epoch(base_tipset.epoch(), calico_height);
let mut sum_gas_limit = 0;

// Check messages for validity
Expand Down
13 changes: 8 additions & 5 deletions blockchain/chain_sync/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use cid::{Cid, Code::Blake2b256};
use encoding::{Cbor, Error as EncodingError};
use ipld_blockstore::BlockStore;
use message::{SignedMessage, UnsignedMessage};
use networks::BLOCK_DELAY_SECS;

use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
Expand Down Expand Up @@ -59,14 +58,15 @@ impl<'a> TipsetValidator<'a> {
chainstore: Arc<ChainStore<DB>>,
bad_block_cache: Arc<BadBlockCache>,
genesis_tipset: Arc<Tipset>,
block_delay: u64,
) -> Result<(), TipsetValidationError> {
// No empty blocks
if self.0.blocks().is_empty() {
return Err(TipsetValidationError::NoBlocks);
}

// Tipset epoch must not be behind current max
self.validate_epoch(genesis_tipset)?;
self.validate_epoch(genesis_tipset, block_delay)?;

// Validate each block in the tipset by:
// 1. Calculating the message root using all of the messages to ensure it matches the mst root in the block header
Expand All @@ -81,13 +81,16 @@ impl<'a> TipsetValidator<'a> {
Ok(())
}

pub fn validate_epoch(&self, genesis_tipset: Arc<Tipset>) -> Result<(), TipsetValidationError> {
pub fn validate_epoch(
&self,
genesis_tipset: Arc<Tipset>,
block_delay: u64,
) -> Result<(), TipsetValidationError> {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
let max_epoch =
((now - genesis_tipset.min_timestamp()) / BLOCK_DELAY_SECS) + MAX_HEIGHT_DRIFT;
let max_epoch = ((now - genesis_tipset.min_timestamp()) / block_delay) + MAX_HEIGHT_DRIFT;
let too_far_ahead_in_time = self.0.epoch() as u64 > max_epoch;
if too_far_ahead_in_time {
Err(TipsetValidationError::EpochTooLarge)
Expand Down
1 change: 1 addition & 0 deletions blockchain/message_pool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ blocks = { package = "forest_blocks", path = "../blocks" }
message = { package = "forest_message", version = "0.7", features = ["proofs", "json", "blst"] }
thiserror = "1.0"
cid = { package = "forest_cid", version = "0.3" }
clock = { package = "fil_clock", path = "../../node/clock" }
encoding = { package = "forest_encoding", version = "0.2.1" }
blockstore = { package = "ipld_blockstore", version = "0.1" }
num-bigint = { path = "../../utils/bigint", package = "forest_bigint" }
Expand Down
4 changes: 3 additions & 1 deletion blockchain/message_pool/src/msg_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::utils::{get_gas_perf, get_gas_reward};
use address::Address;
use async_std::sync::RwLock;
use blocks::Tipset;
use clock::ChainEpoch;
use encoding::Cbor;
use log::warn;
use message::{Message, SignedMessage};
Expand Down Expand Up @@ -344,6 +345,7 @@ pub(crate) async fn create_message_chains<T>(
base_fee: &BigInt,
ts: &Tipset,
chains: &mut Chains,
calico_height: ChainEpoch,
) -> Result<(), Error>
where
T: Provider,
Expand Down Expand Up @@ -387,7 +389,7 @@ where
}
cur_seq += 1;

let min_gas = interpreter::price_list_by_epoch(ts.epoch())
let min_gas = interpreter::price_list_by_epoch(ts.epoch(), calico_height)
.on_chain_message(m.marshal_cbor()?.len())
.total();

Expand Down
Loading