darkfid2: enchanched args configuration

This commit is contained in:
aggstam
2023-10-26 21:20:31 +03:00
parent 202b6d99f2
commit 44482105c8
16 changed files with 573 additions and 111 deletions

View File

@@ -10,7 +10,7 @@ edition = "2021"
[dependencies]
# Darkfi
darkfi = {path = "../../", features = ["async-daemonize"]}
darkfi = {path = "../../", features = ["async-daemonize", "bs58"]}
darkfi-consensus-contract = {path = "../../src/contract/consensus"}
darkfi-money-contract = {path = "../../src/contract/money"}
darkfi-contract-test-harness = {path = "../../src/contract/test-harness"}

View File

@@ -7,7 +7,174 @@
## uncommenting, or by using the command-line.
# JSON-RPC listen URL
rpc_listen = "tcp://127.0.0.1:18340"
rpc_listen = "tcp://127.0.0.1:8340"
# Blockchain network to use
network = "testnet"
# Localnet blockchain network configuration
[localnet]
# Path to the blockchain database directory
database = "~/.local/darkfi/darkfid_blockchain_localnet"
# Finalization threshold, denominated by number of blocks
threshold = 3
# PoW miner number of threads to use
pow_threads = 4
# PoW block production target, in seconds
pow_target = 10
# Epoch duration, denominated by number of blocks/slots
epoch_length = 10
# PoS slot duration, in seconds
slot_time = 10
# Whitelisted faucet addresses
faucet_pub = []
# Participate in the consensus protocol
consensus = true
# Wallet address to receive consensus rewards.
# This is a dummy one so the miner can start,
# replace with your own one.
recipient = "5ZHfYpt4mpJcwBNxfEyxLzeFJUEeoePs5NQ5jVEgHrMf"
# Skip syncing process and start node right away
skip_sync = true
# Enable testing mode for local testing
testing_mode = true
## Localnet sync P2P network settings
[localnet.sync_net]
# P2P accept addresses the instance listens on for inbound connections
inbound = ["tcp+tls://0.0.0.0:8242"]
# P2P external addresses the instance advertises so other peers can
# reach us and connect to us, as long as inbound addrs are configured.
#external_addrs = []
# Peer nodes to manually connect to
#peers = []
# Seed nodes to connect to for peer discovery and/or adversising our
# own external addresses
#seeds = []
# Whitelisted network transports for outbound connections
#allowed_transports = []
# Allow transport mixing (e.g. Tor would be allowed to connect to `tcp://`)
#transport_mixing = true
# Outbound connection slots number, this many connections will be
# attempted. (This does not include manual connections)
#outbound_connections = 8
# Inbound connections slots number, this many active inbound connections
# will be allowed. (This does not include manual or outbound connections)
#inbound_connections = 0
# Manual connections retry limit, 0 for forever looping
#manual_attempt_limit = 0
# Outbound connection timeout (in seconds)
#outbound_connect_timeout = 10
# Exchange versions (handshake) timeout (in seconds)
#channel_handshake_timeout = 4
# Ping-pong exchange execution interval (in seconds)
#channel_heartbeat_interval = 10
# Allow localnet hosts
localnet = true
# Delete a peer from hosts if they've been quarantined N times
#hosts_quarantine_limit = 50
# Cooling off time for peer discovery when unsuccessful
#outbound_peer_discovery_cooloff_time = 30
# Time between peer discovery attempts
#outbound_peer_discovery_attempt_time = 5
## Localnet consensus P2P network settings
[localnet.consensus_net]
# P2P accept addresses the instance listens on for inbound connections
#inbound = ["tcp+tls://0.0.0.0:8241"]
# P2P external addresses the instance advertises so other peers can
# reach us and connect to us, as long as inbound addrs are configured.
#external_addrs = []
# Peer nodes to manually connect to
#peers = []
# Seed nodes to connect to for peer discovery and/or adversising our
# own external addresses
#seeds = []
# Whitelisted network transports for outbound connections
#allowed_transports = []
# Allow transport mixing (e.g. Tor would be allowed to connect to `tcp://`)
#transport_mixing = true
# Outbound connection slots number, this many connections will be
# attempted. (This does not include manual connections)
#outbound_connections = 8
# Manual connections retry limit, 0 for forever looping
#manual_attempt_limit = 0
# Outbound connection timeout (in seconds)
#outbound_connect_timeout = 10
# Exchange versions (handshake) timeout (in seconds)
#channel_handshake_timeout = 4
# Ping-pong exchange execution interval (in seconds)
#channel_heartbeat_interval = 10
# Allow localnet hosts
localnet = true
# Delete a peer from hosts if they've been quarantined N times
#hosts_quarantine_limit = 50
# Cooling off time for peer discovery when unsuccessful
#outbound_peer_discovery_cooloff_time = 30
# Time between peer discovery attempts
#outbound_peer_discovery_attempt_time = 5
# Testnet blockchain network configuration
[testnet]
# Path to the blockchain database directory
database = "~/.local/darkfi/darkfid_blockchain_testnet"
# Finalization threshold, denominated by number of blocks
threshold = 6
# PoW miner number of threads to use
pow_threads = 6
# PoW block production target, in seconds
pow_target = 90
# Epoch duration, denominated by number of blocks/slots
epoch_length = 10
# PoS slot duration, in seconds
slot_time = 90
# Whitelisted faucet addresses
faucet_pub = ["3ce5xa3PjuQGFtTaF7AvMJp7fGxqeGRJx7zj3LCwNCkP"]
# Participate in the consensus protocol
consensus = false
@@ -21,34 +188,34 @@ skip_sync = false
# Enable testing mode for local testing
testing_mode = false
## Sync P2P network settings
[sync_net]
## Testnet sync P2P network settings
[testnet.sync_net]
# P2P accept addresses the instance listens on for inbound connections
# You can also use an IPv6 address
inbound = ["tcp+tls://0.0.0.0:18342"]
inbound = ["tls://0.0.0.0:8342"]
# IPv6 version:
#inbound = ["tcp+tls://[::]:8342"]
#inbound = ["tls://[::]:8342"]
# Combined:
#inbound = ["tcp+tls://0.0.0.0:8342", "tcp+tls://[::]:8342"]
#inbound = ["tls://0.0.0.0:8342", "tls://[::]:8342"]
# P2P external addresses the instance advertises so other peers can
# reach us and connect to us, as long as inbound addrs are configured.
# You can also use an IPv6 address
#external_addrs = ["tcp+tls://XXX.XXX.XXX.XXX:8342"]
#external_addrs = ["tls://XXX.XXX.XXX.XXX:8342"]
# IPv6 version:
#external_addrs = ["tcp+tls://[ipv6 address here]:8342"]
#external_addrs = ["tls://[ipv6 address here]:8342"]
# Combined:
#external_addrs = ["tcp+tls://XXX.XXX.XXX.XXX:8342", "tcp+tls://[ipv6 address here]:8342"]
#external_addrs = ["tls://XXX.XXX.XXX.XXX:8342", "tls://[ipv6 address here]:8342"]
# Peer nodes to manually connect to
#peers = []
# Seed nodes to connect to for peer discovery and/or adversising our
# own external addresses
#seeds = ["tcp+tls://lilith0.dark.fi:8342", "tcp+tls://lilith1.dark.fi:8342"]
seeds = ["tls://lilith0.dark.fi:8342", "tls://lilith1.dark.fi:8342"]
# Whitelisted network transports for outbound connections
allowed_transports = ["tcp+tls"]
allowed_transports = ["tls"]
# Allow transport mixing (e.g. Tor would be allowed to connect to `tcp://`)
#transport_mixing = true
@@ -74,36 +241,45 @@ outbound_connections = 8
#channel_heartbeat_interval = 10
# Allow localnet hosts
#localnet = false
localnet = false
## Sync P2P network settings
[consensus_net]
# Delete a peer from hosts if they've been quarantined N times
#hosts_quarantine_limit = 50
# Cooling off time for peer discovery when unsuccessful
#outbound_peer_discovery_cooloff_time = 30
# Time between peer discovery attempts
#outbound_peer_discovery_attempt_time = 5
## Testnet consensus P2P network settings
[testnet.consensus_net]
# P2P accept addresses the instance listens on for inbound connections
# You can also use an IPv6 address
#inbound = ["tcp+tls://0.0.0.0:8341"]
inbound = ["tls://0.0.0.0:8341"]
# IPv6 version:
#inbound = ["tcp+tls://[::]:8341"]
#inbound = ["tls://[::]:8341"]
# Combined:
#inbound = ["tcp+tls://0.0.0.0:8341", "tcp+tls://[::]:8341"]
#inbound = ["tls://0.0.0.0:8341", "tls://[::]:8341"]
# P2P external addresses the instance advertises so other peers can
# reach us and connect to us, as long as inbound addrs are configured.
# You can also use an IPv6 address
#external_addrs = ["tcp+tls://XXX.XXX.XXX.XXX:8341"]
#external_addrs = ["tls://XXX.XXX.XXX.XXX:8341"]
# IPv6 version:
#external_addrs = ["tcp+tls://[ipv6 address here]:8341"]
#external_addrs = ["tls://[ipv6 address here]:8341"]
# Combined:
#external_addrs = ["tcp+tls://XXX.XXX.XXX.XXX:8341", "tcp+tls://[ipv6 address here]:8341"]
#external_addrs = ["tls://XXX.XXX.XXX.XXX:8341", "tls://[ipv6 address here]:8341"]
# Peer nodes to manually connect to
#peers = []
# Seed nodes to connect to for peer discovery and/or adversising our
# own external addresses
#seeds = ["tcp+tls://lilith0.dark.fi:8341", "tcp+tls://lilith1.dark.fi:8341"]
seeds = ["tls://lilith0.dark.fi:8341", "tls://lilith1.dark.fi:8341"]
# Whitelisted network transports for outbound connections
#allowed_transports = ["tcp+tls"]
allowed_transports = ["tls"]
# Allow transport mixing (e.g. Tor would be allowed to connect to `tcp://`)
#transport_mixing = true
@@ -125,4 +301,172 @@ outbound_connections = 8
#channel_heartbeat_interval = 10
# Allow localnet hosts
#localnet = false
localnet = false
# Delete a peer from hosts if they've been quarantined N times
#hosts_quarantine_limit = 50
# Cooling off time for peer discovery when unsuccessful
#outbound_peer_discovery_cooloff_time = 30
# Time between peer discovery attempts
#outbound_peer_discovery_attempt_time = 5
# Mainnet blockchain network configuration
[mainnet]
# Path to the blockchain database directory
database = "~/.local/darkfi/darkfid_blockchain_mainnet"
# Finalization threshold, denominated by number of blocks
threshold = 11
# PoW miner number of threads to use
pow_threads = 8
# PoW block production target, in seconds
pow_target = 90
# Epoch duration, denominated by number of blocks/slots
epoch_length = 10
# PoS slot duration, in seconds
slot_time = 90
# Whitelisted faucet addresses
faucet_pub = []
# Participate in the consensus protocol
consensus = false
# Wallet address to receive consensus rewards
#recipient = "YOUR_WALLET_ADDRESS_HERE"
# Skip syncing process and start node right away
skip_sync = false
# Enable testing mode for local testing
testing_mode = false
## Mainnet sync P2P network settings
[mainnet.sync_net]
# P2P accept addresses the instance listens on for inbound connections
# You can also use an IPv6 address
inbound = ["tls://0.0.0.0:8442"]
# IPv6 version:
#inbound = ["tls://[::]:8442"]
# Combined:
#inbound = ["tls://0.0.0.0:8442", "tls://[::]:8442"]
# P2P external addresses the instance advertises so other peers can
# reach us and connect to us, as long as inbound addrs are configured.
# You can also use an IPv6 address
#external_addrs = ["tls://XXX.XXX.XXX.XXX:8442"]
# IPv6 version:
#external_addrs = ["tls://[ipv6 address here]:8442"]
# Combined:
#external_addrs = ["tls://XXX.XXX.XXX.XXX:8442", "tls://[ipv6 address here]:8442"]
# Peer nodes to manually connect to
#peers = []
# Seed nodes to connect to for peer discovery and/or adversising our
# own external addresses
seeds = ["tls://lilith0.dark.fi:8442", "tls://lilith1.dark.fi:8442"]
# Whitelisted network transports for outbound connections
allowed_transports = ["tls"]
# Allow transport mixing (e.g. Tor would be allowed to connect to `tcp://`)
#transport_mixing = true
# Outbound connection slots number, this many connections will be
# attempted. (This does not include manual connections)
outbound_connections = 8
# Inbound connections slots number, this many active inbound connections
# will be allowed. (This does not include manual or outbound connections)
#inbound_connections = 0
# Manual connections retry limit, 0 for forever looping
#manual_attempt_limit = 0
# Outbound connection timeout (in seconds)
#outbound_connect_timeout = 10
# Exchange versions (handshake) timeout (in seconds)
#channel_handshake_timeout = 4
# Ping-pong exchange execution interval (in seconds)
#channel_heartbeat_interval = 10
# Allow localnet hosts
localnet = false
# Delete a peer from hosts if they've been quarantined N times
#hosts_quarantine_limit = 50
# Cooling off time for peer discovery when unsuccessful
#outbound_peer_discovery_cooloff_time = 30
# Time between peer discovery attempts
#outbound_peer_discovery_attempt_time = 5
## Mainnet consensus P2P network settings
[mainnet.consensus_net]
# P2P accept addresses the instance listens on for inbound connections
# You can also use an IPv6 address
inbound = ["tls://0.0.0.0:8441"]
# IPv6 version:
#inbound = ["tls://[::]:8441"]
# Combined:
#inbound = ["tls://0.0.0.0:8441", "tls://[::]:8441"]
# P2P external addresses the instance advertises so other peers can
# reach us and connect to us, as long as inbound addrs are configured.
# You can also use an IPv6 address
#external_addrs = ["tls://XXX.XXX.XXX.XXX:8441"]
# IPv6 version:
#external_addrs = ["tls://[ipv6 address here]:8441"]
# Combined:
#external_addrs = ["tls://XXX.XXX.XXX.XXX:8441", "tls://[ipv6 address here]:8441"]
# Peer nodes to manually connect to
#peers = []
# Seed nodes to connect to for peer discovery and/or adversising our
# own external addresses
seeds = ["tls://lilith0.dark.fi:8441", "tls://lilith1.dark.fi:8441"]
# Whitelisted network transports for outbound connections
allowed_transports = ["tls"]
# Allow transport mixing (e.g. Tor would be allowed to connect to `tcp://`)
#transport_mixing = true
# Outbound connection slots number, this many connections will be
# attempted. (This does not include manual connections)
#outbound_connections = 8
# Manual connections retry limit, 0 for forever looping
#manual_attempt_limit = 0
# Outbound connection timeout (in seconds)
#outbound_connect_timeout = 10
# Exchange versions (handshake) timeout (in seconds)
#channel_handshake_timeout = 4
# Ping-pong exchange execution interval (in seconds)
#channel_heartbeat_interval = 10
# Allow localnet hosts
localnet = false
# Delete a peer from hosts if they've been quarantined N times
#hosts_quarantine_limit = 50
# Cooling off time for peer discovery when unsuccessful
#outbound_peer_discovery_cooloff_time = 30
# Time between peer discovery attempts
#outbound_peer_discovery_attempt_time = 5

View File

@@ -0,0 +1 @@
3N337zZEeEFfZFBPotybXsdtKNjrAUx56QLqcr4izXLvyTVCY6E4MgUvUpEj57f6RNbkqMtZ4vqxFzWKGEnhvoMuaj1QK1fs7nRA4bY3JNrbvfzvP5UBCL9F7uTT3vpDbUiNEWwwr1UnvrzFkj7jryLLGkFDo7VMYXgovrnxMfQQczSiPVSQWGm8yXXMp9SaWeDW96r6GLbJWVc5roofVyGYYw4Cdd4vrbRMGnP7n78xWRGcmmHRebBHru2TqDSFnxYRKN3vtu1s42TkyxbbWVLrJft8ta1sq6PPPvk4idJsboEaxX9gj1DCMdvkq5gKFp5WohfhfMz7jXJod6do4xdPfutedLK3fUVYvTkRRqoSVogbzr2jdjiRPzf9WuvJyULZY7KT6Knby6aenGLdPPd3TcndiqXyWscU1LcWFX59Z7Nkp63no6rmps

View File

@@ -0,0 +1 @@
3N337zZEeEFfZFBPotybXsdtKNjrAUx56QLqcr4izXLvyTVCY6E4MgUvUpEj57f6RNbkqMtZ4vqxFzWKGEnhvoMuaj1QK1fs7nRA4bY3JNrbvfzvP5UBCL9F7uTT3vpDbUiNEWwwr1UnvrzFkj7jryLLGkFDo7VMYXgovrnxMfQQczSiPVSQWGm8yXXMp9SaWeDW96r6GLbJWVc5roofVyGYYw4Cdd4vrbRMGnP7n78xWRGcmmHRebBHru2TqDSFnxYRKN3vtu1s42TkyxbbWVLrJft8ta1sq6PPPvk4idJsboEaxX9gj1DCMdvkq5gKFp5WohfhfMz7jXJod6do4xdPfutedLK3fUVYvTkRRqoSVogbzr2jdjiRPzf9WuvJyULZY7KT6Knby6aenGLdPPd3TcndiqXyWscU1LcWFX59Z7Nkp63no6rmps

View File

@@ -0,0 +1 @@
3N337zZEeEFfZFBPotybXsdtKNjrAUx56QLqcr4izXLvyTVCY6E4MgUvUpEj57f6RNbkqMtZ4vqxFzWKGEnhvoMuaj1QK1fs7nRA4bY3JNrbvfzvP5UBCL9F7uTT3vpDbUiNEWwwr1UnvrzFkj7jryLLGkFDo7VMYXgovrnxMfQQczSiPVSQWGm8yXXMp9SaWeDW96r6GLbJWVc5roofVyGYYw4Cdd4vrbRMGnP7n78xWRGcmmHRebBHru2TqDSFnxYRKN3vtu1s42TkyxbbWVLrJft8ta1sq6PPPvk4idJsboEaxX9gj1DCMdvkq5gKFp5WohfhfMz7jXJod6do4xdPfutedLK3fUVYvTkRRqoSVogbzr2jdjiRPzf9WuvJyULZY7KT6Knby6aenGLdPPd3TcndiqXyWscU1LcWFX59Z7Nkp63no6rmps

View File

@@ -37,12 +37,12 @@ use darkfi::{
server::{listen_and_serve, RequestHandler},
},
system::{StoppableTask, StoppableTaskPtr},
util::time::TimeKeeper,
util::{path::expand_path, time::TimeKeeper},
validator::{utils::genesis_txs_total, Validator, ValidatorConfig, ValidatorPtr},
Error, Result,
};
use darkfi_contract_test_harness::vks;
use darkfi_sdk::crypto::PublicKey;
use darkfi_serial::deserialize;
#[cfg(test)]
mod tests;
@@ -68,6 +68,12 @@ use utils::{spawn_consensus_p2p, spawn_sync_p2p};
const CONFIG_FILE: &str = "darkfid_config.toml";
const CONFIG_FILE_CONTENTS: &str = include_str!("../darkfid_config.toml");
/// Note:
/// If you change these don't forget to remove their corresponding database folder,
/// since if it already has a genesis block, provided one is ignored.
const GENESIS_BLOCK_LOCALNET: &str = include_str!("../genesis_block_localnet");
const GENESIS_BLOCK_TESTNET: &str = include_str!("../genesis_block_testnet");
const GENESIS_BLOCK_MAINNET: &str = include_str!("../genesis_block_mainnet");
#[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)]
#[serde(default)]
@@ -81,29 +87,21 @@ struct Args {
/// JSON-RPC listen URL
rpc_listen: Url,
#[structopt(long)]
/// Participate in the consensus protocol
consensus: bool,
#[structopt(long, default_value = "testnet")]
/// Blockchain network to use
network: String,
#[structopt(long)]
/// Wallet address to receive consensus rewards
recipient: Option<String>,
#[structopt(long)]
/// Skip syncing process and start node right away
skip_sync: bool,
/// Syncing network settings
#[structopt(flatten)]
sync_net: SettingsOpt,
/// Localnet blockchain network configuration
localnet: BlockchainNetwork,
/// Consensus network settings
#[structopt(flatten)]
consensus_net: SettingsOpt,
/// Testnet blockchain network configuration
testnet: BlockchainNetwork,
#[structopt(long)]
/// Enable testing mode for local testing
testing_mode: bool,
#[structopt(flatten)]
/// Mainnet blockchain network configuration
mainnet: BlockchainNetwork,
#[structopt(short, long)]
/// Set log file to ouput into
@@ -114,6 +112,64 @@ struct Args {
verbose: u8,
}
/// Defines a blockchain network configuration.
/// Default values correspond to a local network.
#[derive(Clone, Debug, serde::Deserialize, structopt::StructOpt, structopt_toml::StructOptToml)]
#[structopt()]
pub struct BlockchainNetwork {
#[structopt(long, default_value = "~/.local/darkfi/darkfid_blockchain_localnet")]
/// Path to blockchain database
pub database: String,
#[structopt(long, default_value = "3")]
/// Finalization threshold, denominated by number of blocks
pub threshold: usize,
#[structopt(long, default_value = "4")]
/// PoW miner number of threads to use
pub pow_threads: usize,
#[structopt(long, default_value = "10")]
/// PoW block production target, in seconds
pub pow_target: usize,
#[structopt(long, default_value = "10")]
/// Epoch duration, denominated by number of blocks/slots
pub epoch_length: u64,
#[structopt(long, default_value = "10")]
/// PoS slot duration, in seconds
pub slot_time: u64,
#[structopt(long)]
/// Whitelisted faucet public key (repeatable flag)
pub faucet_pub: Vec<String>,
#[structopt(long)]
/// Participate in the consensus protocol
pub consensus: bool,
#[structopt(long)]
/// Wallet address to receive consensus rewards
pub recipient: Option<String>,
#[structopt(long)]
/// Skip syncing process and start node right away
pub skip_sync: bool,
#[structopt(long)]
/// Enable testing mode for local testing
pub testing_mode: bool,
/// Syncing network settings
#[structopt(flatten)]
pub sync_net: SettingsOpt,
/// Consensus network settings
#[structopt(flatten)]
pub consensus_net: SettingsOpt,
}
/// Daemon structure
pub struct Darkfid {
/// Syncing P2P network pointer
@@ -149,30 +205,46 @@ async_daemonize!(realmain);
async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
info!(target: "darkfid", "Initializing DarkFi node...");
if args.testing_mode {
// Grab blockchain network configuration
let (blockchain_config, genesis_block) = match args.network.as_str() {
"localnet" => (args.localnet, GENESIS_BLOCK_LOCALNET),
"testnet" => (args.testnet, GENESIS_BLOCK_TESTNET),
"mainnet" => (args.mainnet, GENESIS_BLOCK_MAINNET),
_ => {
error!("Unsupported chain `{}`", args.network);
return Err(Error::UnsupportedChain)
}
};
if blockchain_config.testing_mode {
info!(target: "darkfid", "Node is configured to run in testing mode!");
}
// NOTE: everything is dummy for now
// FIXME: The VKS should only ever have to be generated on initial run.
// Do not use the precompiles for actual production code.
// Parse the genesis block
let bytes = bs58::decode(&genesis_block.trim()).into_vec()?;
let genesis_block: BlockInfo = deserialize(&bytes)?;
// Initialize or open sled database
let sled_db = sled::Config::new().temporary(true).open()?;
let (_, vks) = vks::read_or_gen_vks_and_pks()?;
vks::inject(&sled_db, &vks)?;
let db_path = expand_path(&blockchain_config.database)?;
let sled_db = sled::open(&db_path)?;
// Initialize validator configuration
let genesis_block = BlockInfo::default();
let genesis_txs_total = genesis_txs_total(&genesis_block.txs)?;
let time_keeper = TimeKeeper::new(genesis_block.header.timestamp, 10, 90, 0);
// TODO: add miner threads arg
let time_keeper = TimeKeeper::new(
genesis_block.header.timestamp,
blockchain_config.epoch_length,
blockchain_config.slot_time,
0,
);
let config = ValidatorConfig::new(
time_keeper,
Some(40),
blockchain_config.threshold,
blockchain_config.pow_threads,
blockchain_config.pow_target,
genesis_block,
genesis_txs_total,
vec![],
args.testing_mode,
blockchain_config.testing_mode,
);
// Initialize validator
@@ -182,19 +254,25 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
let mut subscribers = HashMap::new();
subscribers.insert("blocks", JsonSubscriber::new("blockchain.subscribe_blocks"));
subscribers.insert("txs", JsonSubscriber::new("blockchain.subscribe_txs"));
if args.consensus {
if blockchain_config.consensus {
subscribers.insert("proposals", JsonSubscriber::new("blockchain.subscribe_proposals"));
}
// Initialize syncing P2P network
let sync_p2p =
spawn_sync_p2p(&args.sync_net.into(), &validator, &subscribers, ex.clone()).await;
spawn_sync_p2p(&blockchain_config.sync_net.into(), &validator, &subscribers, ex.clone())
.await;
// Initialize consensus P2P network
let consensus_p2p = if args.consensus {
let consensus_p2p = if blockchain_config.consensus {
Some(
spawn_consensus_p2p(&args.consensus_net.into(), &validator, &subscribers, ex.clone())
.await,
spawn_consensus_p2p(
&blockchain_config.consensus_net.into(),
&validator,
&subscribers,
ex.clone(),
)
.await,
)
} else {
None
@@ -230,7 +308,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
sync_p2p.clone().start().await?;
// Consensus protocol
if args.consensus {
if blockchain_config.consensus {
info!(target: "darkfid", "Starting consensus P2P network");
let consensus_p2p = consensus_p2p.clone().unwrap();
consensus_p2p.clone().start().await?;
@@ -239,7 +317,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
}
// Sync blockchain
if !args.skip_sync {
if !blockchain_config.skip_sync {
sync_task(&darkfid).await?;
} else {
darkfid.validator.write().await.synced = true;
@@ -249,13 +327,13 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
darkfid.validator.write().await.purge_pending_txs().await?;
// Consensus protocol
let (consensus_task, consensus_sender) = if args.consensus {
let (consensus_task, consensus_sender) = if blockchain_config.consensus {
info!(target: "darkfid", "Starting consensus protocol task");
// Grab rewards recipient public key(address)
if args.recipient.is_none() {
if blockchain_config.recipient.is_none() {
return Err(Error::ParseFailed("Recipient address missing"))
}
let recipient = match PublicKey::from_str(&args.recipient.unwrap()) {
let recipient = match PublicKey::from_str(&blockchain_config.recipient.unwrap()) {
Ok(address) => address,
Err(_) => return Err(Error::InvalidAddress),
};
@@ -291,7 +369,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
info!(target: "darkfid", "Stopping syncing P2P network...");
sync_p2p.stop().await;
if args.consensus {
if blockchain_config.consensus {
info!(target: "darkfid", "Stopping consensus P2P network...");
consensus_p2p.unwrap().stop().await;

View File

@@ -30,7 +30,7 @@ fn forks() -> Result<()> {
// Create a temporary blockchain and a PoW module
let blockchain = Blockchain::new(&sled::Config::new().temporary(true).open()?)?;
let module = PoWModule::new(blockchain.clone(), None, Some(90))?;
let module = PoWModule::new(blockchain.clone(), 2, 90)?;
// Create a fork
let fork = Fork::new(&blockchain, module)?;

View File

@@ -42,7 +42,8 @@ use crate::{
};
pub struct HarnessConfig {
pub pow_target: Option<usize>,
pub pow_threads: usize,
pub pow_target: usize,
pub testing_node: bool,
pub alice_initial: u64,
pub bob_initial: u64,
@@ -82,6 +83,8 @@ impl Harness {
let time_keeper = TimeKeeper::new(genesis_block.header.timestamp, 10, 90, 0);
let validator_config = ValidatorConfig::new(
time_keeper,
3,
config.pow_threads,
config.pow_target,
genesis_block,
genesis_txs_total,
@@ -136,8 +139,21 @@ impl Harness {
let alice = &self.alice.validator.read().await;
let bob = &self.bob.validator.read().await;
alice.validate_blockchain(genesis_txs_total, vec![], self.config.pow_target).await?;
bob.validate_blockchain(genesis_txs_total, vec![], self.config.pow_target).await?;
alice
.validate_blockchain(
genesis_txs_total,
vec![],
self.config.pow_threads,
self.config.pow_target,
)
.await?;
bob.validate_blockchain(
genesis_txs_total,
vec![],
self.config.pow_threads,
self.config.pow_target,
)
.await?;
let alice_blockchain_len = alice.blockchain.len();
assert_eq!(alice_blockchain_len, bob.blockchain.len());

View File

@@ -32,9 +32,15 @@ async fn sync_pos_blocks_real(ex: Arc<Executor<'static>>) -> Result<()> {
init_logger();
// Initialize harness in testing mode
let pow_target = Some(90);
let config =
HarnessConfig { testing_node: true, pow_target, alice_initial: 1000, bob_initial: 500 };
let pow_threads = 2;
let pow_target = 90;
let config = HarnessConfig {
pow_threads,
pow_target,
testing_node: true,
alice_initial: 1000,
bob_initial: 500,
};
let th = Harness::new(config, &ex).await?;
// Retrieve genesis block
@@ -67,7 +73,7 @@ async fn sync_pos_blocks_real(ex: Arc<Executor<'static>>) -> Result<()> {
let genesis_txs_total = th.config.alice_initial + th.config.bob_initial;
let alice = &th.alice.validator.read().await;
let charlie = &charlie.validator.read().await;
charlie.validate_blockchain(genesis_txs_total, vec![], pow_target).await?;
charlie.validate_blockchain(genesis_txs_total, vec![], pow_threads, pow_target).await?;
assert_eq!(alice.blockchain.len(), charlie.blockchain.len());
assert_eq!(alice.blockchain.slots.len(), charlie.blockchain.slots.len());

View File

@@ -157,7 +157,9 @@ impl Wallet {
let time_keeper = TimeKeeper::new(genesis_block.header.timestamp, 10, 90, 0);
let config = ValidatorConfig::new(
time_keeper,
Some(90),
3,
1,
90,
genesis_block.clone(),
0,
faucet_pubkeys.to_vec(),

View File

@@ -162,6 +162,7 @@ pub struct SettingsOpt {
#[structopt(long = "transports")]
pub allowed_transports: Vec<String>,
/// Allow transport mixing (e.g. Tor would be allowed to connect to `tcp://`)
#[structopt(long)]
pub transport_mixing: Option<bool>,
@@ -170,12 +171,15 @@ pub struct SettingsOpt {
#[structopt(long)]
pub localnet: bool,
/// Delete a peer from hosts if they've been quarantined N times
#[structopt(skip)]
pub hosts_quarantine_limit: Option<usize>,
/// Cooling off time for peer discovery when unsuccessful
#[structopt(skip)]
pub outbound_peer_discovery_cooloff_time: Option<u64>,
/// Time between peer discovery attempts
#[structopt(skip)]
pub outbound_peer_discovery_attempt_time: Option<u64>,
}

View File

@@ -38,8 +38,6 @@ use crate::{
// Consensus configuration
/// Block/proposal maximum transactions
pub const TXS_CAP: usize = 50;
/// Fork size(length) after which it can be finalized
const FINALIZATION_SECURITY_THRESSHOLD: usize = 3;
/// This struct represents the information required by the consensus algorithm
pub struct Consensus {
@@ -47,6 +45,8 @@ pub struct Consensus {
pub blockchain: Blockchain,
/// Helper structure to calculate time related operations
pub time_keeper: TimeKeeper,
/// Fork size(length) after which it can be finalized
pub finalization_threshold: usize,
/// Node is participating to consensus
pub participating: bool,
/// Last slot node check for finalization
@@ -64,13 +64,16 @@ impl Consensus {
pub fn new(
blockchain: Blockchain,
time_keeper: TimeKeeper,
pow_target: Option<usize>,
finalization_threshold: usize,
pow_threads: usize,
pow_target: usize,
testing_mode: bool,
) -> Result<Self> {
let module = PoWModule::new(blockchain.clone(), None, pow_target)?;
let module = PoWModule::new(blockchain.clone(), pow_threads, pow_target)?;
Ok(Self {
blockchain,
time_keeper,
finalization_threshold,
participating: false,
checked_finalization: 0,
forks: vec![],
@@ -393,7 +396,7 @@ impl Consensus {
}
/// Consensus finalization logic:
/// - If the current best fork has reached greater length than the security thresshold, and
/// - If the current best fork has reached greater length than the security threshold, and
/// no other fork exist with same rank, all proposals excluding the last one in that fork
// can be finalized (append to canonical blockchain).
/// When best fork can be finalized, blocks(proposals) should be appended to canonical, excluding the
@@ -417,7 +420,7 @@ impl Consensus {
// Check its length
let length = fork.proposals.len();
if length < FINALIZATION_SECURITY_THRESSHOLD {
if length < self.finalization_threshold {
debug!(target: "validator::consensus::finalization", "Nothing to finalize yet, best fork size: {}", length);
return Ok(vec![])
}

View File

@@ -70,8 +70,12 @@ pub mod float_10;
pub struct ValidatorConfig {
/// Helper structure to calculate time related operations
pub time_keeper: TimeKeeper,
/// Currently configured finalization security threshold
pub finalization_threshold: usize,
/// Currently configured PoW miner number of threads to use
pub pow_threads: usize,
/// Currently configured PoW target
pub pow_target: Option<usize>,
pub pow_target: usize,
/// Genesis block
pub genesis_block: BlockInfo,
/// Total amount of minted tokens in genesis block
@@ -83,9 +87,12 @@ pub struct ValidatorConfig {
}
impl ValidatorConfig {
#[allow(clippy::too_many_arguments)]
pub fn new(
time_keeper: TimeKeeper,
pow_target: Option<usize>,
finalization_threshold: usize,
pow_threads: usize,
pow_target: usize,
genesis_block: BlockInfo,
genesis_txs_total: u64,
faucet_pubkeys: Vec<PublicKey>,
@@ -93,6 +100,8 @@ impl ValidatorConfig {
) -> Self {
Self {
time_keeper,
finalization_threshold,
pow_threads,
pow_target,
genesis_block,
genesis_txs_total,
@@ -150,6 +159,8 @@ impl Validator {
let consensus = Consensus::new(
blockchain.clone(),
config.time_keeper,
config.finalization_threshold,
config.pow_threads,
config.pow_target,
testing_mode,
)?;
@@ -527,7 +538,8 @@ impl Validator {
&self,
genesis_txs_total: u64,
faucet_pubkeys: Vec<PublicKey>,
pow_target: Option<usize>,
pow_threads: usize,
pow_target: usize,
) -> Result<()> {
let blocks = self.blockchain.get_all()?;
@@ -546,7 +558,7 @@ impl Validator {
// Create a time keeper and a PoW module to validate each block
let mut time_keeper = self.consensus.time_keeper.clone();
let mut module = PoWModule::new(blockchain.clone(), None, pow_target)?;
let mut module = PoWModule::new(blockchain.clone(), pow_threads, pow_target)?;
// Deploy native wasm contracts
deploy_native_contracts(&overlay, &time_keeper, &faucet_pubkeys)?;

View File

@@ -45,8 +45,6 @@ use crate::{
};
// Note: We have combined some constants for better performance.
/// Default number of threads to use for hashing
const N_THREADS: usize = 4;
/// Amount of max items(blocks) to use for next difficulty calculation.
/// Must be >= 2 and == BUF_SIZE - DIFFICULTY_LAG.
const DIFFICULTY_WINDOW: usize = 720;
@@ -71,9 +69,6 @@ const RETAINED: usize = 600;
const CUT_BEGIN: usize = 60;
/// Already known cutoff end index for this config
const CUT_END: usize = 660;
/// Default target block time, in seconds
const DIFFICULTY_TARGET: usize = 20;
// TODO: maybe add more difficulty targets (testnet, mainnet, etc)
/// How many most recent blocks to use to verify new blocks' timestamp
const BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW: usize = 60;
/// Time limit in the future of what blocks can be
@@ -82,11 +77,9 @@ const BLOCK_FUTURE_TIME_LIMIT: u64 = 60 * 60 * 2;
/// This struct represents the information required by the PoW algorithm
#[derive(Clone)]
pub struct PoWModule {
/// Number of threads to use for hashing,
/// if None provided will use N_THREADS
/// Number of threads to use for hashing
pub threads: usize,
/// Target block time, in seconds,
/// if None provided will use DIFFICULTY_TARGET
/// Target block time, in seconds
pub target: usize,
/// Latest block timestamps ringbuffer
pub timestamps: RingBuffer<u64, BUF_SIZE>,
@@ -100,14 +93,7 @@ pub struct PoWModule {
}
impl PoWModule {
pub fn new(
blockchain: Blockchain,
threads: Option<usize>,
target: Option<usize>,
) -> Result<Self> {
let threads = if let Some(t) = threads { t } else { N_THREADS };
let target = if let Some(t) = target { t } else { DIFFICULTY_TARGET };
pub fn new(blockchain: Blockchain, threads: usize, target: usize) -> Result<Self> {
// Retrieving last BUF_ZISE difficulties from blockchain to build the buffers
let mut timestamps = RingBuffer::<u64, BUF_SIZE>::new();
let mut difficulties = RingBuffer::<BigUint, BUF_SIZE>::new();
@@ -390,13 +376,15 @@ mod tests {
use super::PoWModule;
const DEFAULT_TEST_THREADS: usize = 2;
const DEFAULT_TEST_DIFFICULTY_TARGET: usize = 120;
#[test]
fn test_wide_difficulty() -> Result<()> {
let sled_db = sled::Config::new().temporary(true).open()?;
let blockchain = Blockchain::new(&sled_db)?;
let mut module = PoWModule::new(blockchain, None, Some(DEFAULT_TEST_DIFFICULTY_TARGET))?;
let mut module =
PoWModule::new(blockchain, DEFAULT_TEST_THREADS, DEFAULT_TEST_DIFFICULTY_TARGET)?;
let output = Command::new("./script/research/pow/gen_wide_data.py").output().unwrap();
let reader = Cursor::new(output.stdout);
@@ -429,7 +417,8 @@ mod tests {
// Default setup
let sled_db = sled::Config::new().temporary(true).open()?;
let blockchain = Blockchain::new(&sled_db)?;
let module = PoWModule::new(blockchain, None, Some(DEFAULT_TEST_DIFFICULTY_TARGET))?;
let module =
PoWModule::new(blockchain, DEFAULT_TEST_THREADS, DEFAULT_TEST_DIFFICULTY_TARGET)?;
let (_, recvr) = smol::channel::bounded(1);
let genesis_block = BlockInfo::default();

View File

@@ -333,9 +333,13 @@ pub fn validate_pos_slot(
/// A blockchain is considered valid, when every block is valid,
/// based on validate_block checks.
/// Be careful as this will try to load everything in memory.
pub fn validate_blockchain(blockchain: &Blockchain, pow_target: Option<usize>) -> Result<()> {
pub fn validate_blockchain(
blockchain: &Blockchain,
pow_threads: usize,
pow_target: usize,
) -> Result<()> {
// Generate a PoW module
let mut module = PoWModule::new(blockchain.clone(), None, pow_target)?;
let mut module = PoWModule::new(blockchain.clone(), pow_threads, pow_target)?;
// We use block order store here so we have all blocks in order
let blocks = blockchain.order.get_all()?;
for (index, block) in blocks[1..].iter().enumerate() {

View File

@@ -30,7 +30,8 @@ use darkfi_sdk::{
pasta::{group::ff::Field, pallas},
};
const POW_TARGET: Option<usize> = Some(10);
const POW_THREADS: usize = 1;
const POW_TARGET: usize = 10;
struct Node {
blockchain: Blockchain,
@@ -40,7 +41,7 @@ struct Node {
impl Node {
fn new() -> Result<Self> {
let blockchain = Blockchain::new(&sled::Config::new().temporary(true).open()?)?;
let module = PoWModule::new(blockchain.clone(), None, POW_TARGET)?;
let module = PoWModule::new(blockchain.clone(), POW_THREADS, POW_TARGET)?;
Ok(Self { blockchain, module })
}
}
@@ -63,8 +64,8 @@ impl Harness {
}
fn validate_chains(&self) -> Result<()> {
validate_blockchain(&self.alice.blockchain, POW_TARGET)?;
validate_blockchain(&self.bob.blockchain, POW_TARGET)?;
validate_blockchain(&self.alice.blockchain, POW_THREADS, POW_TARGET)?;
validate_blockchain(&self.bob.blockchain, POW_THREADS, POW_TARGET)?;
assert_eq!(self.alice.blockchain.len(), self.bob.blockchain.len());