mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
consensus: introduce staking coins initial distribution logic
This commit is contained in:
@@ -30,7 +30,8 @@ use darkfi::{
|
||||
consensus::{
|
||||
constants::{
|
||||
MAINNET_BOOTSTRAP_TIMESTAMP, MAINNET_GENESIS_HASH_BYTES, MAINNET_GENESIS_TIMESTAMP,
|
||||
TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP,
|
||||
MAINNET_INITIAL_DISTRIBUTION, TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES,
|
||||
TESTNET_GENESIS_TIMESTAMP, TESTNET_INITIAL_DISTRIBUTION,
|
||||
},
|
||||
proto::{ProtocolProposal, ProtocolSync, ProtocolSyncConsensus, ProtocolTx},
|
||||
task::{block_sync_task, proposal_task},
|
||||
@@ -298,13 +299,19 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
|
||||
let sled_db = sled::open(&db_path)?;
|
||||
|
||||
// Initialize validator state
|
||||
let (bootstrap_ts, genesis_ts, genesis_data) = match args.chain.as_str() {
|
||||
"mainnet" => {
|
||||
(*MAINNET_BOOTSTRAP_TIMESTAMP, *MAINNET_GENESIS_TIMESTAMP, *MAINNET_GENESIS_HASH_BYTES)
|
||||
}
|
||||
"testnet" => {
|
||||
(*TESTNET_BOOTSTRAP_TIMESTAMP, *TESTNET_GENESIS_TIMESTAMP, *TESTNET_GENESIS_HASH_BYTES)
|
||||
}
|
||||
let (bootstrap_ts, genesis_ts, genesis_data, initial_distribution) = match args.chain.as_str() {
|
||||
"mainnet" => (
|
||||
*MAINNET_BOOTSTRAP_TIMESTAMP,
|
||||
*MAINNET_GENESIS_TIMESTAMP,
|
||||
*MAINNET_GENESIS_HASH_BYTES,
|
||||
*MAINNET_INITIAL_DISTRIBUTION,
|
||||
),
|
||||
"testnet" => (
|
||||
*TESTNET_BOOTSTRAP_TIMESTAMP,
|
||||
*TESTNET_GENESIS_TIMESTAMP,
|
||||
*TESTNET_GENESIS_HASH_BYTES,
|
||||
*TESTNET_INITIAL_DISTRIBUTION,
|
||||
),
|
||||
x => {
|
||||
error!("Unsupported chain `{}`", x);
|
||||
return Err(Error::UnsupportedChain)
|
||||
@@ -330,6 +337,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
|
||||
bootstrap_ts,
|
||||
genesis_ts,
|
||||
genesis_data,
|
||||
initial_distribution,
|
||||
wallet.clone(),
|
||||
faucet_pubkeys,
|
||||
args.consensus,
|
||||
|
||||
@@ -56,7 +56,8 @@ use darkfi::{
|
||||
consensus::{
|
||||
constants::{
|
||||
MAINNET_BOOTSTRAP_TIMESTAMP, MAINNET_GENESIS_HASH_BYTES, MAINNET_GENESIS_TIMESTAMP,
|
||||
TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP,
|
||||
MAINNET_INITIAL_DISTRIBUTION, TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES,
|
||||
TESTNET_GENESIS_TIMESTAMP, TESTNET_INITIAL_DISTRIBUTION,
|
||||
},
|
||||
proto::{ProtocolSync, ProtocolTx},
|
||||
task::block_sync_task,
|
||||
@@ -528,13 +529,19 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
|
||||
let sled_db = sled::open(&db_path)?;
|
||||
|
||||
// Initialize validator state
|
||||
let (bootstrap_ts, genesis_ts, genesis_data) = match args.chain.as_str() {
|
||||
"mainnet" => {
|
||||
(*MAINNET_BOOTSTRAP_TIMESTAMP, *MAINNET_GENESIS_TIMESTAMP, *MAINNET_GENESIS_HASH_BYTES)
|
||||
}
|
||||
"testnet" => {
|
||||
(*TESTNET_BOOTSTRAP_TIMESTAMP, *TESTNET_GENESIS_TIMESTAMP, *TESTNET_GENESIS_HASH_BYTES)
|
||||
}
|
||||
let (bootstrap_ts, genesis_ts, genesis_data, initial_distribution) = match args.chain.as_str() {
|
||||
"mainnet" => (
|
||||
*MAINNET_BOOTSTRAP_TIMESTAMP,
|
||||
*MAINNET_GENESIS_TIMESTAMP,
|
||||
*MAINNET_GENESIS_HASH_BYTES,
|
||||
*MAINNET_INITIAL_DISTRIBUTION,
|
||||
),
|
||||
"testnet" => (
|
||||
*TESTNET_BOOTSTRAP_TIMESTAMP,
|
||||
*TESTNET_GENESIS_TIMESTAMP,
|
||||
*TESTNET_GENESIS_HASH_BYTES,
|
||||
*TESTNET_INITIAL_DISTRIBUTION,
|
||||
),
|
||||
x => {
|
||||
error!("Unsupported chain `{}`", x);
|
||||
return Err(Error::UnsupportedChain)
|
||||
@@ -560,6 +567,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
|
||||
bootstrap_ts,
|
||||
genesis_ts,
|
||||
genesis_data,
|
||||
initial_distribution,
|
||||
wallet.clone(),
|
||||
faucet_pubkeys,
|
||||
false,
|
||||
|
||||
@@ -32,6 +32,9 @@ lazy_static! {
|
||||
/// Bootstrap timestamp for the mainnet chain
|
||||
pub static ref MAINNET_BOOTSTRAP_TIMESTAMP: Timestamp = Timestamp(1650887115);
|
||||
|
||||
/// Total sum of initial staking coins for the mainnet chain
|
||||
pub static ref MAINNET_INITIAL_DISTRIBUTION: u64 = 1000;
|
||||
|
||||
/// Genesis hash for the testnet chain
|
||||
pub static ref TESTNET_GENESIS_HASH_BYTES: blake3::Hash = blake3::hash(b"darkfi_testnet");
|
||||
|
||||
@@ -41,22 +44,25 @@ lazy_static! {
|
||||
/// Bootstrap timestamp for the testnet chain
|
||||
pub static ref TESTNET_BOOTSTRAP_TIMESTAMP: Timestamp = Timestamp(1671546600);
|
||||
|
||||
/// Total sum of initial staking coins for the testnet chain
|
||||
pub static ref TESTNET_INITIAL_DISTRIBUTION: u64 = 1000;
|
||||
|
||||
// Commonly used Float10
|
||||
pub static ref FLOAT10_ZERO: Float10 = Float10::from_str_native("0").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_ONE: Float10 = Float10::from_str_native("1").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_TWO: Float10 = Float10::from_str_native("2").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_THREE: Float10 = Float10::from_str_native("3").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_FIVE: Float10 = Float10::from_str_native("5").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_NINE: Float10 = Float10::from_str_native("9").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_TEN: Float10 = Float10::from_str_native("10").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_ZERO: Float10 = Float10::from_str_native("0").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_ONE: Float10 = Float10::from_str_native("1").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_TWO: Float10 = Float10::from_str_native("2").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_THREE: Float10 = Float10::from_str_native("3").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_FIVE: Float10 = Float10::from_str_native("5").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_NINE: Float10 = Float10::from_str_native("9").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref FLOAT10_TEN: Float10 = Float10::from_str_native("10").unwrap().with_precision(RADIX_BITS).value();
|
||||
|
||||
// Consensus parameters
|
||||
pub static ref DT: Float10 = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref TI: Float10 = FLOAT10_ONE.clone();
|
||||
pub static ref TD: Float10 = FLOAT10_ONE.clone();
|
||||
pub static ref KP: Float10 = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref KI: Float10 = Float10::from_str_native("0.03").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref KD: Float10 = FLOAT10_ONE.clone();
|
||||
pub static ref DT: Float10 = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref TI: Float10 = FLOAT10_ONE.clone();
|
||||
pub static ref TD: Float10 = FLOAT10_ONE.clone();
|
||||
pub static ref KP: Float10 = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref KI: Float10 = Float10::from_str_native("0.03").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref KD: Float10 = FLOAT10_ONE.clone();
|
||||
pub static ref PID_OUT_STEP: Float10 = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref MAX_DER: Float10 = Float10::from_str_native("0.1").unwrap().with_precision(RADIX_BITS).value();
|
||||
pub static ref MIN_DER: Float10 = Float10::from_str_native("-0.1").unwrap().with_precision(RADIX_BITS).value();
|
||||
@@ -113,4 +119,4 @@ pub const PI_MU_Y_INDEX: usize = 8;
|
||||
pub const PI_MU_RHO_INDEX: usize = 10;
|
||||
pub const PI_SIGMA1_INDEX: usize = 12;
|
||||
pub const PI_SIGMA2_INDEX: usize = 13;
|
||||
pub const GENESIS_TOTAL_STAKE: i64 = 1;
|
||||
pub const GENESIS_TOTAL_STAKE: u64 = 1;
|
||||
|
||||
@@ -48,6 +48,8 @@ pub struct ConsensusState {
|
||||
pub genesis_ts: Timestamp,
|
||||
/// Genesis block hash
|
||||
pub genesis_block: blake3::Hash,
|
||||
/// Total sum of initial staking coins
|
||||
pub initial_distribution: u64,
|
||||
/// Slot the network was bootstrapped
|
||||
pub bootstrap_slot: u64,
|
||||
/// Participating start slot
|
||||
@@ -83,6 +85,7 @@ impl ConsensusState {
|
||||
bootstrap_ts: Timestamp,
|
||||
genesis_ts: Timestamp,
|
||||
genesis_data: blake3::Hash,
|
||||
initial_distribution: u64,
|
||||
) -> Result<Self> {
|
||||
let genesis_block = Block::genesis_block(genesis_ts, genesis_data).blockhash();
|
||||
Ok(Self {
|
||||
@@ -90,6 +93,7 @@ impl ConsensusState {
|
||||
bootstrap_ts,
|
||||
genesis_ts,
|
||||
genesis_block,
|
||||
initial_distribution,
|
||||
bootstrap_slot: 0,
|
||||
participating: None,
|
||||
proposing: false,
|
||||
@@ -229,18 +233,10 @@ impl ConsensusState {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
/// return 2-term target approximation sigma coefficients.
|
||||
/// Return 2-term target approximation sigma coefficients.
|
||||
pub fn sigmas(&mut self) -> (pallas::Base, pallas::Base) {
|
||||
let f = self.win_inv_prob_with_full_stake();
|
||||
|
||||
// Generate sigmas
|
||||
let mut total_stake = self.total_stake(); // Only used for fine-tuning
|
||||
// at genesis epoch first slot, of absolute index 0,
|
||||
// the total stake would be 0, to avoid division by zero,
|
||||
// we asume total stake at first division is GENESIS_TOTAL_STAKE.
|
||||
if total_stake == 0 {
|
||||
total_stake = constants::GENESIS_TOTAL_STAKE;
|
||||
}
|
||||
let total_stake = self.total_stake();
|
||||
info!("sigmas(): f: {}", f);
|
||||
info!("sigmas(): stake: {}", total_stake);
|
||||
let one = constants::FLOAT10_ONE.clone();
|
||||
@@ -284,10 +280,13 @@ impl ConsensusState {
|
||||
// The wallet has specific tables for consensus coins.
|
||||
// TODO: TESTNET: Token ID still has to be enforced properly in the consensus.
|
||||
|
||||
// Temporarily, we compete with zero stake
|
||||
// Temporarily, we compete with fixed stake.
|
||||
// This stake should be based on how many nodes we want to run, and they all
|
||||
// must sum to initial distribution total coins.
|
||||
let stake = self.initial_distribution;
|
||||
let coin = LeadCoin::new(
|
||||
eta,
|
||||
rand::thread_rng().gen_range(0..1000),
|
||||
stake,
|
||||
slot,
|
||||
epoch_secrets.secret_keys[0].inner(),
|
||||
epoch_secrets.merkle_roots[0],
|
||||
@@ -301,9 +300,9 @@ impl ConsensusState {
|
||||
Ok(coins)
|
||||
}
|
||||
|
||||
/// leadership reward, assuming constant reward
|
||||
/// Leadership reward, assuming constant reward
|
||||
/// TODO (res) implement reward mechanism with accord to DRK,DARK token-economics
|
||||
fn reward() -> u64 {
|
||||
fn reward(&self) -> u64 {
|
||||
constants::REWARD
|
||||
}
|
||||
|
||||
@@ -341,11 +340,19 @@ impl ConsensusState {
|
||||
current_slot - blocks - self.get_current_offset(current_slot) - max_fork_length
|
||||
}
|
||||
|
||||
/// total stake
|
||||
/// assuming constant Reward.
|
||||
fn total_stake(&mut self) -> i64 {
|
||||
/// Network total stake, assuming constant reward.
|
||||
/// Only used for fine-tuning. At genesis epoch first slot, of absolute index 0,
|
||||
/// if no stake was distributed, the total stake would be 0.
|
||||
/// To avoid division by zero, we asume total stake at first division is GENESIS_TOTAL_STAKE(1).
|
||||
fn total_stake(&mut self) -> u64 {
|
||||
let current_slot = self.current_slot();
|
||||
((current_slot - self.overall_empty_slots(current_slot)) * Self::reward()) as i64
|
||||
let rewarded_slots = current_slot - self.overall_empty_slots(current_slot);
|
||||
let rewards = rewarded_slots * self.reward();
|
||||
let total_stake = rewards + self.initial_distribution;
|
||||
if total_stake == 0 {
|
||||
return constants::GENESIS_TOTAL_STAKE
|
||||
}
|
||||
total_stake
|
||||
}
|
||||
|
||||
/// Calculate how many leaders existed in previous slot and appends
|
||||
|
||||
@@ -93,6 +93,7 @@ impl ValidatorState {
|
||||
bootstrap_ts: Timestamp,
|
||||
genesis_ts: Timestamp,
|
||||
genesis_data: blake3::Hash,
|
||||
initial_distribution: u64,
|
||||
wallet: WalletPtr,
|
||||
faucet_pubkeys: Vec<PublicKey>,
|
||||
enable_participation: bool,
|
||||
@@ -122,8 +123,13 @@ impl ValidatorState {
|
||||
};
|
||||
|
||||
let blockchain = Blockchain::new(db, genesis_ts, genesis_data)?;
|
||||
let consensus =
|
||||
ConsensusState::new(blockchain.clone(), bootstrap_ts, genesis_ts, genesis_data)?;
|
||||
let consensus = ConsensusState::new(
|
||||
blockchain.clone(),
|
||||
bootstrap_ts,
|
||||
genesis_ts,
|
||||
genesis_data,
|
||||
initial_distribution,
|
||||
)?;
|
||||
|
||||
let unconfirmed_txs = vec![];
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ use darkfi::{
|
||||
consensus::{
|
||||
constants::{
|
||||
TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP,
|
||||
TESTNET_INITIAL_DISTRIBUTION,
|
||||
},
|
||||
ValidatorState, ValidatorStatePtr,
|
||||
},
|
||||
@@ -86,6 +87,7 @@ impl DaoTestHarness {
|
||||
*TESTNET_BOOTSTRAP_TIMESTAMP,
|
||||
*TESTNET_GENESIS_TIMESTAMP,
|
||||
*TESTNET_GENESIS_HASH_BYTES,
|
||||
*TESTNET_INITIAL_DISTRIBUTION,
|
||||
alice_wallet,
|
||||
vec![],
|
||||
false,
|
||||
|
||||
@@ -21,6 +21,7 @@ use darkfi::{
|
||||
consensus::{
|
||||
constants::{
|
||||
TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP,
|
||||
TESTNET_INITIAL_DISTRIBUTION,
|
||||
},
|
||||
ValidatorState, ValidatorStatePtr,
|
||||
},
|
||||
@@ -105,6 +106,7 @@ impl MoneyTestHarness {
|
||||
*TESTNET_BOOTSTRAP_TIMESTAMP,
|
||||
*TESTNET_GENESIS_TIMESTAMP,
|
||||
*TESTNET_GENESIS_HASH_BYTES,
|
||||
*TESTNET_INITIAL_DISTRIBUTION,
|
||||
faucet_wallet,
|
||||
faucet_pubkeys.clone(),
|
||||
false,
|
||||
@@ -116,6 +118,7 @@ impl MoneyTestHarness {
|
||||
*TESTNET_BOOTSTRAP_TIMESTAMP,
|
||||
*TESTNET_GENESIS_TIMESTAMP,
|
||||
*TESTNET_GENESIS_HASH_BYTES,
|
||||
*TESTNET_INITIAL_DISTRIBUTION,
|
||||
alice_wallet,
|
||||
faucet_pubkeys.clone(),
|
||||
false,
|
||||
@@ -127,6 +130,7 @@ impl MoneyTestHarness {
|
||||
*TESTNET_BOOTSTRAP_TIMESTAMP,
|
||||
*TESTNET_GENESIS_TIMESTAMP,
|
||||
*TESTNET_GENESIS_HASH_BYTES,
|
||||
*TESTNET_INITIAL_DISTRIBUTION,
|
||||
bob_wallet,
|
||||
faucet_pubkeys.clone(),
|
||||
false,
|
||||
|
||||
Reference in New Issue
Block a user