commit b25639af59541215beb21c4065ce2233c2798b84
parent e336832e1b30ad7e9aaf16be67bea0a12313ed14
Author: Joris Hartog <jorishartog@hotmail.com>
Date: Fri, 24 Jul 2026 14:05:19 +0200
Revert "Use mine action for genesis issuance"
This reverts commit 2c1dcedf8fd9f7e3e9f8923ebadcf4f542b7e7f2.
Diffstat:
| M | src/domain.rs | | | 64 | ++-------------------------------------------------------------- |
| M | src/main.rs | | | 57 | ++++++++++++++++++++------------------------------------- |
2 files changed, 22 insertions(+), 99 deletions(-)
diff --git a/src/domain.rs b/src/domain.rs
@@ -110,28 +110,6 @@ pub enum Transaction {
}
impl Transaction {
- pub fn genesis_mine(to: impl Into<String>) -> Result<Self> {
- let output = TxOutput {
- address: to.into(),
- amount: MINE_REWARD,
- };
- let anchor = genesis_mine_anchor();
- let difficulty_bits = MINE_DIFFICULTY_BITS;
- for nonce in 0..u64::MAX {
- let signature = mine_signature(&output, &anchor, nonce, difficulty_bits);
- if hash_meets_difficulty(&signature, difficulty_bits) {
- return Ok(Self::Mine {
- output,
- anchor,
- nonce,
- difficulty_bits,
- signature,
- });
- }
- }
- bail!("could not find valid genesis mine proof");
- }
-
pub fn genesis_burn(from: impl Into<String>, amount: Amount) -> Self {
let from = from.into();
Self::genesis_burn_with_change(from, amount, Vec::new())
@@ -475,10 +453,6 @@ fn mine_signature(output: &TxOutput, anchor: &str, nonce: u64, difficulty_bits:
hex_hash(mine_payload(output, anchor, nonce, difficulty_bits))
}
-fn genesis_mine_anchor() -> String {
- "0".repeat(64)
-}
-
fn hash_meets_difficulty(hash: &str, difficulty_bits: u32) -> bool {
let full_zero_nibbles = (difficulty_bits / 4) as usize;
let remaining_bits = difficulty_bits % 4;
@@ -910,14 +884,6 @@ impl Ledger {
Self::new_with_genesis_transactions(genesis_allocations, transactions, vdf_rounds)
}
- pub fn new_with_genesis_mine(recipient: impl Into<String>, vdf_rounds: u32) -> Result<Self> {
- Self::new_with_genesis_transactions(
- BTreeMap::new(),
- vec![Transaction::genesis_mine(recipient)?],
- vdf_rounds,
- )
- }
-
fn new_with_genesis_transactions(
genesis_allocations: BTreeMap<String, Amount>,
genesis_transactions: Vec<Transaction>,
@@ -2277,12 +2243,8 @@ fn utxos_after_genesis(
for transaction in &genesis.transactions {
match transaction {
Transaction::Burn { .. } => apply_transaction(transaction, &mut utxos)?,
- Transaction::Mine { .. } => {
- validate_genesis_mine_transaction(transaction)?;
- apply_transaction(transaction, &mut utxos)?;
- }
- Transaction::Transfer { .. } => {
- bail!("genesis only supports burn and mine transactions")
+ Transaction::Transfer { .. } | Transaction::Mine { .. } => {
+ bail!("genesis only supports burn transactions")
}
}
}
@@ -2359,28 +2321,6 @@ fn validate_genesis_block(block: &Block) -> Result<()> {
Ok(())
}
-fn validate_genesis_mine_transaction(transaction: &Transaction) -> Result<()> {
- let Transaction::Mine {
- output,
- anchor,
- difficulty_bits,
- ..
- } = transaction
- else {
- bail!("genesis transaction is not a mine transaction");
- };
- if output.amount != MINE_REWARD {
- bail!("genesis mine reward is invalid");
- }
- if anchor != &genesis_mine_anchor() {
- bail!("genesis mine anchor is invalid");
- }
- if *difficulty_bits != MINE_DIFFICULTY_BITS {
- bail!("genesis mine difficulty is invalid");
- }
- transaction.verify_signature()
-}
-
fn genesis_miner(
genesis_allocations: &BTreeMap<String, Amount>,
transactions: &[Transaction],
diff --git a/src/main.rs b/src/main.rs
@@ -11,12 +11,12 @@ use anyhow::{Context, Result, bail};
use luun::{
adapters::{chain_store::SqliteChainStore, config_store, http, p2p, wallet_store},
app::{NodeCore, PeerBook, SharedNode, SharedPeerBook, now_ms},
- domain::{Amount, ChainSnapshot, Ledger, MICRO_LUUN, MINE_REWARD, run_vdf},
+ domain::{Amount, BLOCK_REWARD, ChainSnapshot, GenesisBurn, Ledger, MICRO_LUUN, run_vdf},
};
use tokio::sync::Mutex;
-const GENESIS_INITIAL_BURN_PER_BLOCK: Amount = MINE_REWARD;
-const GENESIS_INITIAL_BURN_FEE: Amount = 0;
+const GENESIS_BOOTSTRAP_BURN_AMOUNT: Amount = MICRO_LUUN;
+const GENESIS_INITIAL_BURN_PER_BLOCK: Amount = BLOCK_REWARD;
const VDF_MEASUREMENT_INITIAL_ROUNDS: u32 = 1_000_000;
const VDF_MEASUREMENT_MAX_ROUNDS: u32 = 100_000_000;
const VDF_MEASUREMENT_MIN_ELAPSED: Duration = Duration::from_millis(150);
@@ -47,7 +47,7 @@ async fn main() -> Result<()> {
let ledger = initialize_ledger(&opts, wallet.address(), &chain_store).await?;
let has_chain = opts.has_chain() || persisted_chain_exists;
let initial_burn_per_block = initial_burn_per_block(&opts, &ui_config);
- let initial_burn_fee = initial_burn_fee(&opts, &ui_config);
+ let initial_burn_fee = ui_config.burn_fee;
let node: SharedNode = Arc::new(Mutex::new(NodeCore::from_ledger_with_burn_fee(
wallet,
@@ -299,13 +299,6 @@ fn initial_burn_per_block(opts: &CliOptions, ui_config: &config_store::UiConfig)
}
}
-fn initial_burn_fee(opts: &CliOptions, ui_config: &config_store::UiConfig) -> Amount {
- match opts.chain_mode {
- ChainMode::Genesis => GENESIS_INITIAL_BURN_FEE,
- ChainMode::Setup | ChainMode::Join => ui_config.burn_fee,
- }
-}
-
fn print_help() {
println!("{}", help_text());
}
@@ -342,7 +335,16 @@ fn setup_ledger() -> Ledger {
fn start_genesis_ledger(wallet_address: &str) -> Result<Ledger> {
let vdf_rounds = measure_initial_vdf_rounds();
- Ledger::new_with_genesis_mine(wallet_address, vdf_rounds)
+ let mut genesis = BTreeMap::new();
+ genesis.insert(wallet_address.to_string(), GENESIS_BOOTSTRAP_BURN_AMOUNT);
+ Ledger::new_with_genesis_burns(
+ genesis,
+ vec![GenesisBurn::new(
+ wallet_address,
+ GENESIS_BOOTSTRAP_BURN_AMOUNT,
+ )],
+ vdf_rounds,
+ )
}
fn measure_initial_vdf_rounds() -> u32 {
@@ -545,16 +547,16 @@ mod tests {
use luun::{
adapters::{chain_store::SqliteChainStore, config_store::UiConfig},
app::{DEFAULT_BURN_PER_BLOCK, NodeCore},
- domain::{GenesisBurn, Ledger, MINE_REWARD, Transaction, Wallet},
+ domain::{BLOCK_REWARD, GenesisBurn, Ledger, Wallet},
};
use rusqlite::Connection;
use tempfile::tempdir;
use tokio::sync::Mutex;
use super::{
- ChainMode, CliOptions, extrapolate_vdf_rounds, help_text, initial_burn_fee,
- initial_burn_per_block, initialize_ledger, measure_vdf_rounds, persist_chain_snapshot,
- run_chain_persistence_with_interval, start_genesis_ledger, validate_wallet_for_mode,
+ ChainMode, CliOptions, extrapolate_vdf_rounds, help_text, initial_burn_per_block,
+ initialize_ledger, measure_vdf_rounds, persist_chain_snapshot,
+ run_chain_persistence_with_interval, validate_wallet_for_mode,
};
fn parse(args: &[&str]) -> anyhow::Result<Option<CliOptions>> {
@@ -629,31 +631,14 @@ mod tests {
}
#[test]
- fn genesis_mode_starts_with_mine_reward_burn_rate_and_zero_fee() {
+ fn genesis_mode_starts_with_full_reward_burn_rate() {
let genesis = parse(&["--genesis"]).unwrap().unwrap();
let configured = UiConfig {
burn_per_block: 50,
burn_fee: 3,
..UiConfig::default()
};
- assert_eq!(initial_burn_per_block(&genesis, &configured), MINE_REWARD);
- assert_eq!(initial_burn_fee(&genesis, &configured), 0);
- }
-
- #[test]
- fn genesis_ledger_starts_with_single_mine_action() {
- let wallet = Wallet::from_seed("genesis-mine-wallet");
- let ledger = start_genesis_ledger(wallet.address()).unwrap();
- let genesis = &ledger.chain()[0];
-
- assert_eq!(genesis.height, 0);
- assert_eq!(genesis.miner, "genesis");
- assert_eq!(genesis.reward, 0);
- assert_eq!(genesis.transactions.len(), 1);
- assert!(matches!(genesis.transactions[0], Transaction::Mine { .. }));
- assert_eq!(genesis.transactions[0].amount(), MINE_REWARD);
- assert_eq!(ledger.balance_of(wallet.address()), MINE_REWARD);
- assert_eq!(ledger.expected_leader_for_next_block(), None);
+ assert_eq!(initial_burn_per_block(&genesis, &configured), BLOCK_REWARD);
}
#[test]
@@ -666,11 +651,9 @@ mod tests {
let setup = parse(&[]).unwrap().unwrap();
assert_eq!(initial_burn_per_block(&setup, &configured), 50);
- assert_eq!(initial_burn_fee(&setup, &configured), 3);
let join = parse(&["--join", "127.0.0.1:9444"]).unwrap().unwrap();
assert_eq!(initial_burn_per_block(&join, &configured), 50);
- assert_eq!(initial_burn_fee(&join, &configured), 3);
assert_eq!(
initial_burn_per_block(&setup, &UiConfig::default()),