use std::{collections::BTreeMap, convert::TryInto};
use melstructs::{
BlockHeight, CoinData, CoinDataHeight, CoinID, CoinValue, Denom, NetID, StakeDoc, TxHash,
MICRO_CONVERTER,
};
use melvm::Covenant;
use novasmt::ContentAddrStore;
use serde::{Deserialize, Serialize};
use tip911_stakeset::StakeSet;
use tmelcrypt::{Ed25519PK, HashVal};
use crate::{CoinMapping, SmtMapping, UnsealedState};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GenesisConfig {
#[serde(with = "stdcode::asstr")]
pub network: NetID,
pub init_coindata: CoinData,
pub stakes: BTreeMap<TxHash, StakeDoc>,
pub init_fee_pool: CoinValue,
pub init_fee_multiplier: u128,
}
impl GenesisConfig {
pub fn std_mainnet() -> Self {
Self {
network: NetID::Mainnet,
init_coindata: CoinData {
covhash: Covenant::std_ed25519_pk_legacy(Ed25519PK(
hex::decode("7323dcb65513b84470a76339cdf0062d47d82e205e834f2d7159684a0cb3b5ba")
.unwrap()
.try_into()
.unwrap(),
))
.hash(),
value: (1000000 * MICRO_CONVERTER).into(), denom: Denom::Sym,
additional_data: Default::default(),
},
stakes: ["7323dcb65513b84470a76339cdf0062d47d82e205e834f2d7159684a0cb3b5ba"]
.iter()
.map(|v| Ed25519PK(hex::decode(v).unwrap().try_into().unwrap()))
.map(|pubkey| {
(
tmelcrypt::hash_single(pubkey.0).into(), StakeDoc {
pubkey,
e_start: 0,
e_post_end: 3, syms_staked: 1.into(),
},
)
})
.collect(),
init_fee_pool: CoinValue::from_millions(6553600u64), init_fee_multiplier: MICRO_CONVERTER,
}
}
pub fn std_testnet() -> Self {
serde_yaml::from_slice(include_bytes!("genesis-testnet.yaml")).unwrap()
}
pub fn realize<C: ContentAddrStore>(self, db: &novasmt::Database<C>) -> UnsealedState<C> {
let empty_tree = db.get_tree(HashVal::default().0).unwrap();
let mut new_state = UnsealedState {
network: self.network,
height: 0.into(),
history: SmtMapping::new(empty_tree.clone()),
coins: CoinMapping::new(empty_tree.clone()),
transactions: Default::default(),
fee_pool: self.init_fee_pool,
fee_multiplier: self.init_fee_multiplier,
tips: 0.into(),
dosc_speed: MICRO_CONVERTER,
pools: SmtMapping::new(empty_tree),
stakes: StakeSet::new(self.stakes.into_iter()),
};
new_state.coins.insert_coin(
CoinID::zero_zero(),
CoinDataHeight {
height: BlockHeight(0),
coin_data: self.init_coindata,
},
new_state.tip_906(),
);
new_state
}
}