diff --git a/example/lead.rs b/example/lead.rs index 347c2422f..e39335bc7 100644 --- a/example/lead.rs +++ b/example/lead.rs @@ -7,7 +7,12 @@ use pasta_curves::{ }; use darkfi::{ - blockchain::epoch::{Epoch,EpochItem}, + blockchain::{ + Blockchain, + epoch::{Epoch,EpochItem}, + }, + stakeholder::stakeholder::{Stakeholder}, + util::time::{Timestamp}, crypto::{ constants::MERKLE_DEPTH_ORCHARD, leadcoin::LeadCoin, @@ -25,8 +30,8 @@ fn main() { //let lead_vk = VerifyingKey::build(k, &LeadContract::default()); // const LEN: usize = 10; - let epoch_item = EpochItem{ - value: 1, //static stake value + let epoch_item = EpochItem { + value: 0, //static stake value }; //TODO to read eta you need an access to the blockchain proof transaction. @@ -34,10 +39,10 @@ fn main() { //TODO who should have view of the blockchain if not the stakeholder? // or should the blockchain be a node in itself? // but that doesn't make sense, since each stakeholder might end up with different view of it. - let genesis_data = flake3::Hash(b""); - let oc = Blockchain::new(sled_db, Timestamp::curent_time(), genesis_data); - let stakeholder = Stakeholder - { + let genesis_data = blake3::hash(b""); + let db = sled::open("/tmp/darkfi.db").unwrap(); + let oc = Blockchain::new(&db, Timestamp::current_time(), genesis_data).unwrap(); + let stakeholder = Stakeholder { blockchain: oc, }; let eta : pallas::Base = stakeholder.get_eta(); @@ -65,8 +70,8 @@ fn main() { cm_pos: Value::known(coin.idx), //sn_c1: Value::known(coin.sn.unwrap()), slot: Value::known(coin.sl.unwrap()), - mau_rho: Value::known(mod_r_p(coin.rho_mu)), - mau_y: Value::known(mod_r_p(coin.y_mu)), + mau_rho: Value::known(mod_r_p(coin.rho_mu.unwrap())), + mau_y: Value::known(mod_r_p(coin.y_mu.unwrap())), root_cm: Value::known(coin.root_cm.unwrap()), }; diff --git a/src/blockchain/blockstore.rs b/src/blockchain/blockstore.rs index 9ed149262..8a09e3322 100644 --- a/src/blockchain/blockstore.rs +++ b/src/blockchain/blockstore.rs @@ -20,7 +20,6 @@ impl BlockStore { pub fn new(db: &sled::Db, genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Result { let tree = db.open_tree(SLED_BLOCK_TREE)?; let store = Self(tree); - // In case the store is empty, initialize it with the genesis block. if store.0.is_empty() { let genesis_block = Block::genesis_block(genesis_ts, genesis_data); diff --git a/src/blockchain/epoch.rs b/src/blockchain/epoch.rs index 07ce21890..e6eae4550 100644 --- a/src/blockchain/epoch.rs +++ b/src/blockchain/epoch.rs @@ -23,14 +23,12 @@ use crate::{ const MERKLE_DEPTH: u8 = MERKLE_DEPTH_ORCHARD as u8; #[derive(Copy,Debug,Default,Clone)] -pub struct EpochItem -{ +pub struct EpochItem { pub value: u64, // the stake value is static during the epoch. } #[derive(Copy,Debug,Default,Clone)] -pub struct Epoch -{ +pub struct Epoch { // TODO this need to emulate epoch // should have ep, slot, current block, etc. //epoch metadata @@ -42,34 +40,34 @@ pub struct Epoch } #[derive(Debug,Default,Clone)] -pub struct LifeTime -{ +pub struct LifeTime { //lifetime metadata //... //lifetime epochs pub epochs : Vec, } -const ELECTION_SEED_NONCE = pallas::Base::from(3); -const ELECTION_SEED_LEAD = pallas::Base::from(22); impl Epoch { fn create_coins_election_seeds(&self, sl: pallas::Base) -> (pallas::Base, pallas::Base) { + let ELECTION_SEED_NONCE : pallas::Base = pallas::Base::from(3); + let ELECTION_SEED_LEAD : pallas::Base = pallas::Base::from(22); + // mu_rho let nonce_mu_msg = [ ELECTION_SEED_NONCE, self.eta, sl, ]; - let nonce_mu : pallas::Scalar = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init().hash(nonce_mu_msg); + let nonce_mu : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init().hash(nonce_mu_msg); // mu_y let lead_mu_msg = [ ELECTION_SEED_LEAD, self.eta, sl, ]; - let lead_mu : pallas::Scalar = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init().hash(lead_mu_msg); + let lead_mu : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init().hash(lead_mu_msg); (lead_mu, nonce_mu) } @@ -169,7 +167,7 @@ impl Epoch { //*c_seed_pt.x(), //TODO(fix) will be c_seed(base) only after calculating c_seed as hash //*c_seed_pt.y(), ]; - let lead_coin_msg_hash : pallas::Scalar = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<1>, 3, 2>::init().hash(lead_coin_msg);p + let lead_coin_msg_hash : pallas::Scalar = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<1>, 3, 2>::init().hash(lead_coin_msg); //TODO (FIX) THIS PANICS, ONLY PANICS ON LARGE VALUES! //let c_cm: pallas::Point = pedersen_commitment_scalar(lead_coin_msg_hash, c_cm1_blind); //note c_v is set to zero, should work @@ -207,7 +205,7 @@ impl Epoch { let c_path_sk = path_sks[i]; // election seeds - (y_mu, rho_mu) = self.create_coins_election_seeds(c_sl); + let (y_mu, rho_mu) = self.create_coins_election_seeds(c_sl); let coin = LeadCoin { value: Some(c_v), cm: Some(c_cm), diff --git a/src/blockchain/metadatastore.rs b/src/blockchain/metadatastore.rs index e335139a4..7b7b72e6d 100644 --- a/src/blockchain/metadatastore.rs +++ b/src/blockchain/metadatastore.rs @@ -111,13 +111,13 @@ pub struct OuroborosMetadataStore(sled::Tree); impl OuroborosMetadataStore { /// Opens a new or existing `OuroborosMetadataStore` on the given sled database. - pub fn new(db: &sled::Db, genesis_ts: Timestamp, genesis_data: blake3::Hash, eta: [u8;32]) -> Result { + pub fn new(db: &sled::Db, genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Result { let tree = db.open_tree(SLED_OUROBOROS_METADATA_TREE)?; let store = Self(tree); - + let eta : [u8;32] = *blake3::hash(b"let there be dark!").as_bytes(); // In case the store is empty, initialize it with the genesis block. if store.0.is_empty() { - let genesis_block = Block::genesis_block(genesis_ts, genesis_data, eta); + let genesis_block = Block::genesis_block(genesis_ts, genesis_data); let genesis_hash = blake3::hash(&serialize(&genesis_block)); let metadata = OuroborosMetadata { diff --git a/src/blockchain/mod.rs b/src/blockchain/mod.rs index 61c9ff7b0..0c26d3a1d 100644 --- a/src/blockchain/mod.rs +++ b/src/blockchain/mod.rs @@ -3,7 +3,7 @@ use std::io; use log::debug; use crate::{ - consensus::{Block, BlockInfo}, + consensus::{Block, BlockInfo, StreamletMetadata}, impl_vec, util::{ serial::{Decodable, Encodable, ReadExt, VarInt, WriteExt}, @@ -13,7 +13,7 @@ use crate::{ }; pub mod epoch; -pub use epoch::{Epoch,EpochItem,LifeTime}; +pub use epoch::{Epoch, EpochItem}; pub mod blockstore; pub use blockstore::{BlockOrderStore, BlockStore}; @@ -49,16 +49,15 @@ pub struct Blockchain { impl Blockchain { /// Instantiate a new `Blockchain` with the given `sled` database. - pub fn new(db: &sled::Db, genesis_ts: Timestamp, genesis_data: flake3::Hash) -> Result { + pub fn new(db: &sled::Db, genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Result { let blocks = BlockStore::new(db, genesis_ts, genesis_data)?; let order = BlockOrderStore::new(db, genesis_ts, genesis_data)?; - let eta0 = flake3::Hash(b"let there be dark").as_bytes()?; - let ouroboros_metadata = OuroborosMetadataStore::new(db, genesis_ts, genesis_data, eta0)?; + let ouroboros_metadata = OuroborosMetadataStore::new(db, genesis_ts, genesis_data)?; let transactions = TxStore::new(db)?; let nullifiers = NullifierStore::new(db)?; let merkle_roots = RootStore::new(db)?; - Ok(Self { blocks, order, transactions, ourboros_metadata, nullifiers, merkle_roots }) + Ok(Self { blocks, order, transactions, ouroboros_metadata, nullifiers, merkle_roots }) } /// Insert a given slice of [`BlockInfo`] into the blockchain database. @@ -113,8 +112,8 @@ impl Blockchain { for (i, block) in blocks.iter().enumerate() { let block = block.clone().unwrap(); - let sm = metadata[i].clone().unwrap(); - + // empty streamlet censensus. + let sm = StreamletMetadata::new(vec![]); let txs = self.transactions.get(&block.txs, true)?; let txs = txs.iter().map(|x| x.clone().unwrap()).collect(); diff --git a/src/consensus/block.rs b/src/consensus/block.rs index 2d450a172..427ebdd19 100644 --- a/src/consensus/block.rs +++ b/src/consensus/block.rs @@ -46,7 +46,8 @@ impl Block { } /// Generate the genesis block. - pub fn genesis_block(genesis_ts: Timestamp, genesis_data: blake3::Hash, eta: [u8;32]) -> Self { + pub fn genesis_block(genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Self { + let eta : [u8; 32] = *blake3::hash(b"let there be dark!").as_bytes(); let metadata = Metadata::new(genesis_ts, eta); @@ -89,7 +90,7 @@ pub struct BlockInfo { pub txs: Vec, /// Additional proposal information pub metadata: Metadata, - /// Proposal information used by Streamlet consensus + // Proposal information used by Streamlet consensus pub sm: StreamletMetadata, } @@ -100,10 +101,10 @@ impl BlockInfo { sl: u64, txs: Vec, metadata: Metadata, - sm: StreamletMetadata, + sm: StreamletMetadata ) -> Self { let v = *BLOCK_VERSION; - Self { v, st, e, sl, txs, metadata, sm } + Self { v, st, e, sl, txs, metadata, sm} } /// Calculate the block hash diff --git a/src/consensus/mod.rs b/src/consensus/mod.rs index ee5ebffaf..927ad3a10 100644 --- a/src/consensus/mod.rs +++ b/src/consensus/mod.rs @@ -4,7 +4,7 @@ pub use block::{Block, BlockInfo, BlockProposal, ProposalChain}; /// Consensus metadata pub mod metadata; -pub use metadata::{Metadata, StreamletMetadata}; +pub use metadata::{Metadata, StreamletMetadata, OuroborosMetadata}; /// Consensus participant pub mod participant; diff --git a/src/consensus/state.rs b/src/consensus/state.rs index 713b38964..5f70873c2 100644 --- a/src/consensus/state.rs +++ b/src/consensus/state.rs @@ -271,11 +271,11 @@ impl ValidatorState { let (prev_hash, index) = self.longest_notarized_chain_last_hash().unwrap(); let unproposed_txs = self.unproposed_txs(index); + let eta : [u8;32] = *blake3::hash(b"let there be dark!").as_bytes(); let metadata = Metadata::new( Timestamp::current_time(), - String::from("proof"), - String::from("r"), - String::from("s"), + // empty seed + eta, ); let sm = StreamletMetadata::new(self.consensus.participants.values().cloned().collect()); diff --git a/src/lib.rs b/src/lib.rs index 452228cf0..cd434fd19 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,9 @@ pub use error::{ClientFailed, ClientResult, Error, Result, VerifyFailed, VerifyR #[cfg(feature = "blockchain")] pub mod blockchain; +#[cfg(feature = "blockchain")] +pub mod stakeholder; + #[cfg(feature = "blockchain")] pub mod consensus; diff --git a/src/stakeholder/mod.rs b/src/stakeholder/mod.rs new file mode 100644 index 000000000..b9c9eddad --- /dev/null +++ b/src/stakeholder/mod.rs @@ -0,0 +1,2 @@ +pub mod stakeholder; +pub use stakeholder::{Stakeholder}; diff --git a/src/stakeholder/stakeholder.rs b/src/stakeholder/stakeholder.rs index 7e3bf5647..d528b63c0 100644 --- a/src/stakeholder/stakeholder.rs +++ b/src/stakeholder/stakeholder.rs @@ -1,35 +1,43 @@ -use super::blockchain::{Blockchain, Block, BlockInfo}; -use super::util::time::Timestamp; +use crate::{ + consensus::{BlockInfo}, + util::time::Timestamp, + blockchain::{Blockchain}, + Result, +}; + +use pasta_curves::{ + pallas, +}; +use group::ff::PrimeField; -#[derive(Copy,Debug,Default,Clone)] pub struct Stakeholder { - blockchain: Blockchain // stakeholder view of the blockchain + pub blockchain: Blockchain // stakeholder view of the blockchain } impl Stakeholder { - fn init() { + pub fn new() -> Result { //TODO initialize the blockchain let path = "/tmp"; - let db = sled::open(path)?; + let db = sled::open(path).unwrap(); let ts = Timestamp::current_time(); - let genesis_data = "data": - let genesis_hash = flake3::Hash(genesis_data.as_bytes()); - let eta0 = flake3::Hash("let there be dark!"); - self.blockchain = Blockchain::new(db, ts, genesis_hash, eta0.as_bytes()); + let genesis_hash = blake3::hash(b"data"); + let bc = Blockchain::new(&db, ts, genesis_hash).unwrap(); + Ok(Self{blockchain: bc}) } - fn add_block(&self, block: BlockInfo) + pub fn add_block(&self, block: BlockInfo) { let blocks = [block]; - self.blockchain.add(blocks); + self.blockchain.add(&blocks); } - fn get_eta(&self) -> pallas::Base + pub fn get_eta(&self) -> pallas::Base { let last_proof_slot : u64 = 0; - let (sl, proof_tx_hash) = self.blockchain.last()?; - pallas::Base::from_bytes(proof_tx_hash.to_bytees()) + let (sl, proof_tx_hash) = self.blockchain.last().unwrap(); + let bytes = *proof_tx_hash.as_bytes(); + pallas::Base::from_repr(bytes).unwrap() } }