Skip to content

Commit

Permalink
External block verifier (#916)
Browse files Browse the repository at this point in the history
Refs: #883

It is the implementation of the block verifier. Right now it provides
only one function to verify the block's fields. But in the future, we
can add verification of the seals(it is why it holds a relayer) and
reuse this verifier in the `fuel-core-sync`.

Along with the verifier, I changed the `fuel_core_poa::Config` and
`ChainConfig` to have rules for the block's time of the network and
separate rules for block production.

- Added `NodeRole::Producer` and `NodeRole::Validator`. Based on the
role, we will create a `fuel_core_poa::Config`.
- Removed `Never` from `BlockProduction` from `ChainConfig` because it
is the block production information of the `PoA`.

No unit tests right now.

Co-authored-by: Tom <tomrgowan@gmail.com>
Co-authored-by: Voxelot <brandonkite92@gmail.com>
  • Loading branch information
3 people authored Jan 23, 2023
1 parent 1d2c75f commit 4c65bd2
Show file tree
Hide file tree
Showing 37 changed files with 712 additions and 170 deletions.
44 changes: 23 additions & 21 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"crates/fuel-core",
"crates/metrics",
"crates/services",
"crates/services/consensus_module",
"crates/services/consensus_module/bft",
"crates/services/consensus_module/poa",
"crates/services/executor",
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ $ ./target/debug/fuel-core run --db-type in-memory
Jul 12 23:28:47.238 INFO fuel_core: Binding GraphQL provider to 127.0.0.1:4000
```

To disable block production on your local node, set `--poa-instant=false`

#### Example

```console
$ ./target/debug/fuel-core run --poa-instant=false
2023-01-23T02:25:18.787401Z INFO fuel_core::cli::run: 173: Block production disabled.
```

#### Troubleshooting

##### Outdated database
Expand Down
7 changes: 5 additions & 2 deletions bin/fuel-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ path = "src/main.rs"

[dependencies]
anyhow = "1.0"
clap = { version = "3.2", features = ["derive", "env"] }
clap = { version = "4.1", features = ["derive", "env"] }
dirs = "4.0"
fuel-core = { path = "../../crates/fuel-core", version = "0.15.1" }
humantime = "2.1"
lazy_static = "1.4"
serde_json = { version = "1.0", features = ["raw_value"], optional = true }
strum = "0.24"
tokio = { version = "1.21", features = ["macros", "rt-multi-thread"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = [
Expand All @@ -32,6 +32,9 @@ tracing-subscriber = { version = "0.3", features = [
] }
url = { version = "2.2", optional = true }

[dev-dependencies]
test-case = "2.2"

[features]
debug = ["fuel-core/debug"]
default = ["debug", "metrics", "relayer", "rocksdb"]
Expand Down
73 changes: 52 additions & 21 deletions bin/fuel-core/src/cli/run.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#![allow(unused_variables)]
use crate::{
cli::DEFAULT_DB_PATH,
cli::{
run::consensus::PoATriggerArgs,
DEFAULT_DB_PATH,
},
FuelService,
};
use anyhow::{
Expand All @@ -12,7 +15,10 @@ use fuel_core::{
chain_config::ChainConfig,
producer::Config as ProducerConfig,
service::{
config::default_consensus_dev_key,
config::{
default_consensus_dev_key,
Trigger,
},
Config,
DbType,
ServiceTrait,
Expand All @@ -36,7 +42,6 @@ use std::{
path::PathBuf,
str::FromStr,
};
use strum::VariantNames;
use tracing::{
info,
log::warn,
Expand All @@ -48,13 +53,14 @@ pub const CONSENSUS_KEY_ENV: &str = "CONSENSUS_KEY_SECRET";
#[cfg(feature = "p2p")]
mod p2p;

mod consensus;
#[cfg(feature = "relayer")]
mod relayer;

/// Run the Fuel client node locally.
#[derive(Debug, Clone, Parser)]
pub struct Command {
#[clap(long = "ip", default_value = "127.0.0.1", parse(try_from_str))]
#[clap(long = "ip", default_value = "127.0.0.1", value_parser)]
pub ip: net::IpAddr,

#[clap(long = "port", default_value = "4000")]
Expand All @@ -63,49 +69,58 @@ pub struct Command {
#[clap(
name = "DB_PATH",
long = "db-path",
parse(from_os_str),
value_parser,
default_value = (*DEFAULT_DB_PATH).to_str().unwrap()
)]
pub database_path: PathBuf,

#[clap(long = "db-type", default_value = "rocks-db", possible_values = &*DbType::VARIANTS, ignore_case = true)]
#[clap(
long = "db-type",
default_value = "rocks-db",
value_enum,
ignore_case = true
)]
pub database_type: DbType,

/// Specify either an alias to a built-in configuration or filepath to a JSON file.
#[clap(name = "CHAIN_CONFIG", long = "chain", default_value = "local_testnet")]
#[arg(name = "CHAIN_CONFIG", long = "chain", default_value = "local_testnet")]
pub chain_config: String,

/// Allows GraphQL Endpoints to arbitrarily advanced blocks. Should be used for local development only
#[clap(long = "manual_blocks_enabled")]
#[arg(long = "manual_blocks_enabled")]
pub manual_blocks_enabled: bool,

/// Enable logging of backtraces from vm errors
#[clap(long = "vm-backtrace")]
#[arg(long = "vm-backtrace")]
pub vm_backtrace: bool,

/// Enable full utxo stateful validation
/// disabled by default until downstream consumers stabilize
#[clap(long = "utxo-validation")]
#[arg(long = "utxo-validation")]
pub utxo_validation: bool,

/// The minimum allowed gas price
#[clap(long = "min-gas-price", default_value = "0")]
#[arg(long = "min-gas-price", default_value = "0")]
pub min_gas_price: u64,

/// The signing key used when producing blocks.
/// Setting via the `CONSENSUS_KEY_SECRET` ENV var is preferred.
#[clap(long = "consensus-key")]
#[arg(long = "consensus-key")]
pub consensus_key: Option<String>,

/// A new block is produced instantly when transactions are available.
#[clap(flatten)]
pub poa_trigger: PoATriggerArgs,

/// Use a default insecure consensus key for testing purposes.
/// This will not be enabled by default in the future.
#[clap(long = "dev-keys", default_value = "true")]
#[arg(long = "dev-keys", default_value = "true")]
pub consensus_dev_key: bool,

/// The block's fee recipient public key.
///
/// If not set, `consensus_key` is used as the provider of the `Address`.
#[clap(long = "coinbase-recipient")]
#[arg(long = "coinbase-recipient")]
pub coinbase_recipient: Option<String>,

#[cfg(feature = "relayer")]
Expand All @@ -116,7 +131,7 @@ pub struct Command {
#[cfg(feature = "p2p")]
pub p2p_args: p2p::P2PArgs,

#[clap(long = "metrics")]
#[arg(long = "metrics")]
pub metrics: bool,
}

Expand All @@ -133,6 +148,7 @@ impl Command {
utxo_validation,
min_gas_price,
consensus_key,
poa_trigger,
consensus_dev_key,
coinbase_recipient,
#[cfg(feature = "relayer")]
Expand All @@ -149,9 +165,17 @@ impl Command {
#[cfg(feature = "p2p")]
let p2p_cfg = p2p_args.into_config(metrics)?;

let trigger: Trigger = poa_trigger.into();

if trigger != Trigger::Never {
info!("Block production mode: {:?}", &trigger);
} else {
info!("Block production disabled");
}

// if consensus key is not configured, fallback to dev consensus key
let consensus_key = load_consensus_key(consensus_key)?.or_else(|| {
if consensus_dev_key {
if consensus_dev_key && trigger != Trigger::Never {
let key = default_consensus_dev_key();
warn!(
"Fuel Core is using an insecure test key for consensus. Public key: {}",
Expand All @@ -164,16 +188,21 @@ impl Command {
}
});

if consensus_key.is_some() && trigger == Trigger::Never {
warn!("Consensus key configured but block production is disabled!")
}

let coinbase_recipient = if let Some(coinbase_recipient) = coinbase_recipient {
Address::from_str(coinbase_recipient.as_str()).map_err(|err| anyhow!(err))?
} else {
let consensus_key = consensus_key
consensus_key
.as_ref()
.cloned()
.unwrap_or_else(|| Secret::new(SecretKeyWrapper::default()));

let sk = consensus_key.expose_secret().deref();
Address::from(*sk.public_key().hash())
.map(|key| {
let sk = key.expose_secret().deref();
Address::from(*sk.public_key().hash())
})
.unwrap_or_default()
};

Ok(Config {
Expand All @@ -183,6 +212,7 @@ impl Command {
chain_conf: chain_conf.clone(),
utxo_validation,
manual_blocks_enabled,
block_production: trigger,
vm: VMConfig {
backtrace: vm_backtrace,
},
Expand All @@ -193,6 +223,7 @@ impl Command {
metrics,
},
block_executor: Default::default(),
block_importer: Default::default(),
#[cfg(feature = "relayer")]
relayer: relayer_args.into(),
#[cfg(feature = "p2p")]
Expand Down
Loading

0 comments on commit 4c65bd2

Please sign in to comment.