iuna

iuna

iuna - experimental mainnet-candidate protocol
git clone https://getiuna.org/git/iuna.git
Log | Files | Refs | README | LICENSE

node_lifecycle.rs (6798B)


      1 use std::collections::{BTreeMap, BTreeSet};
      2 
      3 use anyhow::Result;
      4 
      5 use crate::{
      6     adapters::config_store::{DEFAULT_POW_MINING_WORKERS, clamp_pow_mining_workers},
      7     domain::{
      8         AddressNetwork, Amount, BurnBundle, DEFAULT_FEE_PER_BYTE, Ledger, VersionedAddress, Wallet,
      9         decode_address, decode_versioned_address, encode_address, transaction_v2_is_active,
     10     },
     11 };
     12 
     13 use super::{GossipEnvelope, NodeConfig, NodeCore, NodeWallet};
     14 
     15 impl NodeCore {
     16     pub fn new(config: NodeConfig) -> Self {
     17         let ledger = Ledger::new(config.genesis_allocations, config.vdf_rounds);
     18         let mut node = Self::from_ledger_with_burn_fee(
     19             config.wallet,
     20             ledger,
     21             config.burn_per_block,
     22             config.burn_fee,
     23         );
     24         node.set_pow_mining_workers(config.pow_mining_workers);
     25         node.set_recovery_vdf_top_rank_percent(config.recovery_vdf_top_rank_percent);
     26         node
     27     }
     28 
     29     pub fn from_ledger(wallet: Wallet, ledger: Ledger, burn_per_block: Amount) -> Self {
     30         Self::from_ledger_with_burn_fee(wallet, ledger, burn_per_block, DEFAULT_FEE_PER_BYTE)
     31     }
     32 
     33     pub fn from_locked_wallet_address(
     34         address: impl Into<String>,
     35         ledger: Ledger,
     36         automatic_mining_enabled: bool,
     37         burn_per_block: Amount,
     38         burn_fee: Amount,
     39     ) -> Self {
     40         Self::from_node_wallet_with_burn_fee_and_enabled(
     41             NodeWallet::Locked {
     42                 address: address.into(),
     43             },
     44             ledger,
     45             automatic_mining_enabled,
     46             burn_per_block,
     47             burn_fee,
     48             DEFAULT_POW_MINING_WORKERS,
     49             100,
     50         )
     51     }
     52 
     53     pub fn from_ledger_with_burn_fee(
     54         wallet: Wallet,
     55         ledger: Ledger,
     56         burn_per_block: Amount,
     57         burn_fee: Amount,
     58     ) -> Self {
     59         Self::from_ledger_with_burn_fee_and_enabled(
     60             wallet,
     61             ledger,
     62             burn_per_block > 0,
     63             burn_per_block,
     64             burn_fee,
     65         )
     66     }
     67 
     68     pub fn from_ledger_with_burn_fee_and_enabled(
     69         wallet: Wallet,
     70         ledger: Ledger,
     71         automatic_mining_enabled: bool,
     72         burn_per_block: Amount,
     73         burn_fee: Amount,
     74     ) -> Self {
     75         Self::from_node_wallet_with_burn_fee_and_enabled(
     76             NodeWallet::Unlocked(wallet),
     77             ledger,
     78             automatic_mining_enabled,
     79             burn_per_block,
     80             burn_fee,
     81             DEFAULT_POW_MINING_WORKERS,
     82             100,
     83         )
     84     }
     85 
     86     fn from_node_wallet_with_burn_fee_and_enabled(
     87         wallet: NodeWallet,
     88         ledger: Ledger,
     89         automatic_mining_enabled: bool,
     90         burn_per_block: Amount,
     91         burn_fee: Amount,
     92         pow_mining_workers: u8,
     93         recovery_vdf_top_rank_percent: u8,
     94     ) -> Self {
     95         Self {
     96             wallet,
     97             ledger,
     98             automatic_mining_enabled,
     99             pow_mining_enabled: false,
    100             pow_mining_workers: clamp_pow_mining_workers(pow_mining_workers),
    101             burn_per_block,
    102             burn_fee,
    103             recovery_vdf_top_rank_percent: recovery_vdf_top_rank_percent.min(100),
    104             last_auto_burn_height: None,
    105             last_auto_anchor_burn_height: None,
    106             last_auto_finalization_status: None,
    107             last_auto_pow_mine_anchor: None,
    108             last_auto_pow_mine_status: None,
    109             auto_pow_mine_cursor: None,
    110             burn_bundles: BTreeMap::<(u64, u8, String), BurnBundle>::new(),
    111             equivocated_burn_bundle_slots: BTreeSet::new(),
    112             burn_bundle_collection_started: None,
    113             local_block_anchor_burn: None,
    114             outbox: Vec::<GossipEnvelope>::new(),
    115             network_migration_from: None,
    116         }
    117     }
    118 
    119     pub fn require_network_migration(&mut self, from_network: impl Into<String>) {
    120         self.network_migration_from = Some(from_network.into());
    121     }
    122 
    123     pub fn network_migration_from(&self) -> Option<&str> {
    124         self.network_migration_from.as_deref()
    125     }
    126 
    127     pub fn complete_network_migration(&mut self) {
    128         self.network_migration_from = None;
    129     }
    130 
    131     pub fn wallet_address(&self) -> &str {
    132         self.wallet.address()
    133     }
    134 
    135     pub fn wallet_receive_address(&self) -> Result<String> {
    136         if transaction_v2_is_active(self.ledger.height()) {
    137             if let Ok(wallet) = self.wallet.unlocked() {
    138                 return self.ledger.wallet_receive_address(wallet);
    139             }
    140         }
    141         encode_address(self.wallet.address(), self.address_network())
    142     }
    143 
    144     pub fn wallet_owned_addresses(&self) -> Result<Vec<String>> {
    145         let mut addresses = vec![self.wallet.address().to_string()];
    146         if let Ok(wallet) = self.wallet.unlocked() {
    147             addresses.extend(self.ledger.wallet_owned_hybrid_encoded_addresses(wallet)?);
    148         }
    149         addresses.sort();
    150         addresses.dedup();
    151         Ok(addresses)
    152     }
    153 
    154     pub fn normalize_user_address(&self, address: &str) -> Result<String> {
    155         decode_address(address, self.address_network())
    156     }
    157 
    158     pub fn decode_user_address(&self, address: &str) -> Result<VersionedAddress> {
    159         decode_versioned_address(address, self.address_network())
    160     }
    161 
    162     fn address_network(&self) -> AddressNetwork {
    163         AddressNetwork::from_profile_id(&self.ledger.launch_profile().profile_id)
    164     }
    165 
    166     pub fn wallet_is_locked(&self) -> bool {
    167         self.wallet.is_locked()
    168     }
    169 
    170     pub fn replace_wallet(&mut self, wallet: Wallet) {
    171         self.wallet = NodeWallet::Unlocked(wallet);
    172         self.reset_automatic_mining_progress();
    173         self.burn_bundles.clear();
    174         self.equivocated_burn_bundle_slots.clear();
    175         self.burn_bundle_collection_started = None;
    176         self.local_block_anchor_burn = None;
    177     }
    178 
    179     pub fn reset_chain_to_setup_placeholder(&mut self) {
    180         let launch_profile = self.ledger.launch_profile().clone();
    181         self.ledger = Ledger::new_with_genesis_burns_and_profile(
    182             BTreeMap::new(),
    183             Vec::new(),
    184             1,
    185             launch_profile,
    186         )
    187         .expect("empty setup ledger is valid");
    188         self.reset_automatic_mining_progress();
    189         self.burn_bundles.clear();
    190         self.equivocated_burn_bundle_slots.clear();
    191         self.burn_bundle_collection_started = None;
    192         self.local_block_anchor_burn = None;
    193         self.outbox.clear();
    194     }
    195 
    196     pub(super) fn reset_automatic_mining_progress(&mut self) {
    197         self.last_auto_burn_height = None;
    198         self.last_auto_anchor_burn_height = None;
    199         self.last_auto_finalization_status = None;
    200         self.last_auto_pow_mine_anchor = None;
    201         self.last_auto_pow_mine_status = None;
    202         self.auto_pow_mine_cursor = None;
    203         self.burn_bundle_collection_started = None;
    204     }
    205 }