[WIP/crypsinous simulation] crypsinous simualtion still wip

This commit is contained in:
mohab metwally
2022-07-18 11:57:25 +02:00
parent 7e6c79fb4b
commit 7eee509922
8 changed files with 161 additions and 45 deletions

View File

@@ -0,0 +1,24 @@
use darkfi::{
stakeholder::Stakeholder,
blockchain::{EpochConsensus}
};
fn main()
{
let slots=3;
let reward=22;
let epoch_consensus = EpochConsensus::new(slots, reward);
/// read n from the cmd
let n = 3;
/// initialize n stakeholders
let stakeholders = vec!(n);
for i in n {
let stakeholder = Stakeholder::new();
stakeholders.push(stakeholder);
}
/// when the clock signal a new slot.
/// check for leadership.
/// if lead publish construct block metadata.
/// push the new block before the end of the slot (clock should siganl the beging, and 1/k of the way to the end).
///TODO stakeholder should signal new epoch, new slot in the background
}

View File

@@ -62,6 +62,7 @@ fn main() {
//TODO (fix) proof panics
let lead_tx = TransactionLeadProof::new(lead_pk, coin.clone());
/*
//lead_tx.verify(lead_vk, coin);
let (st_id, st_hash) = stakeholder.blockchain.last().unwrap();
let empty_txs : Vec<Transaction> = vec!();
@@ -74,7 +75,6 @@ fn main() {
// calculate public inputs
let public_inputs = coin.public_inputs();
let prover = MockProver::run(k, &contract, vec![public_inputs]).unwrap();
//
assert_eq!(prover.verify(), Ok(()));
//
*/
}

View File

@@ -27,6 +27,30 @@ pub struct EpochItem {
pub value: u64, // the stake value is static during the epoch.
}
/// epoch configuration
/// this struct need be a singleton,
/// should be populated from configuration file.
#[derive(Copy,Debug,Default,Clone)]
pub struct EpochConsensus {
pub len : u64, /// number of slots per epoch
pub reward: u64,
}
impl EpochConsensus{
fn new(len: u64, reward: u64) {
Self {len, reward}
}
/// TODO how is the reward derived?
fn get_reward(&self) {
self.reward
}
fn get_sl(&self) {
self.len
}
}
#[derive(Copy,Debug,Default,Clone)]
pub struct Epoch {
// TODO this need to emulate epoch
@@ -36,20 +60,18 @@ pub struct Epoch {
//epoch item
pub item: Option<EpochItem>,
pub eta: pallas::Base, // CRS for the leader selection.
pub coins: Vec<LeadCoin>,
}
#[derive(Debug,Default,Clone)]
pub struct LifeTime {
//lifetime metadata
//...
//lifetime epochs
pub epochs : Vec<Epoch>,
}
impl Epoch {
pub fn new(consensus: EpochConsensus, true_random:pallas::Base)
{
Self {len: consensus.len,
item: EpochItem {consensus.reward},
eta: true_random,
}
}
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);
@@ -221,6 +243,41 @@ impl Epoch {
};
coins.push(coin);
}
self.coins = coins;
coins
}
/// retrive leadership lottary coins of static stake,
/// retrived for for commitment in the genesis data
pub fn get_coins(&self) -> Vec<LeadCoin> {
return self.coins
}
/// see if the participant stakeholder of this epoch is
/// winning the lottery, in case of success return True
pub fn is_leader(&self, sl: u64) -> bool {
let coin = self.coins[i];
let y_exp = [
coin.root_sk,
coin.nonce,
];
let y_exp_hash : pallas::Base = PoseidonHash::<_, _, poseidon::P128Pow5T3, poseidon::ContractLength<2>,3,2,>::init(y_exp);
let y = pedersen_commitment_scalar(coin.y_mu, y_exp_hash);
let ord = 1024; //TODO (res)
let target = ord*coin.value;
y < target
}
pub fn get_proof(&self, sl: u64) -> Proof {
let coin = self.coins[sl];
lead_proof::create_lead_proof(pk, coin)
}
}
#[derive(Debug,Default,Clone)]
pub struct LifeTime {
//lifetime metadata
//...
//lifetime epochs
pub epochs : Vec<Epoch>,
}

View File

@@ -50,6 +50,8 @@ pub struct Blockchain {
}
impl Blockchain {
//FIXME why the blockchain taking genesis_data on the constructor as a hash?
//genesis data are supposed to be a a hash?
/// Instantiate a new `Blockchain` with the given `sled` database.
pub fn new(db: &sled::Db, genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Result<Self> {
let blocks = BlockStore::new(db, genesis_ts, genesis_data)?;

View File

@@ -24,34 +24,17 @@ use rand::{thread_rng, Rng};
#[allow(clippy::too_many_arguments)]
pub fn create_lead_proof(pk: ProvingKey, coin: LeadCoin) -> Result<Proof> {
//
let mut rng = thread_rng();
let yu64: u64 = rng.gen();
let rhou64: u64 = rng.gen();
let mau_y: pallas::Base = pallas::Base::from(yu64);
let mau_rho: pallas::Base = pallas::Base::from(rhou64);
let contract = LeadContract {
path: Value::known(coin.path.unwrap()),
coin_pk_x: Value::known(coin.pk_x.unwrap()),
coin_pk_y: Value::known(coin.pk_y.unwrap()),
root_sk: Value::known(coin.root_sk.unwrap()),
sf_root_sk: Value::known(mod_r_p(coin.root_sk.unwrap())),
path_sk: Value::known(coin.path_sk.unwrap()),
coin_timestamp: Value::known(coin.tau.unwrap()),
coin_nonce: Value::known(coin.nonce.unwrap()),
coin1_blind: Value::known(coin.c1_blind.unwrap()),
value: Value::known(coin.value.unwrap()),
coin2_blind: Value::known(coin.c2_blind.unwrap()),
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(mau_rho)),
mau_y: Value::known(mod_r_p(mau_y)),
root_cm: Value::known(coin.root_cm.unwrap()),
};
//let mut rng = thread_rng();
//let yu64: u64 = rng.gen();
//let rhou64: u64 = rng.gen();
//let mau_y: pallas::Base = pallas::Base::from(yu64);
//let mau_rho: pallas::Base = pallas::Base::from(rhou64);
let contract = coin.create_contract();
//let start = Instant::now();
let public_inputs = coin.public_inputs();
println!("creating proof");
let proof = Proof::create(&pk, &[contract], &public_inputs, &mut OsRng)?;
println!("proof created");
//debug!("Prove lead: [{:?}]", start.elapsed());
Ok(proof)
}

View File

@@ -61,7 +61,7 @@ impl Proof {
mut rng: impl RngCore,
) -> std::result::Result<Self, plonk::Error> {
let mut transcript = Blake2bWrite::<_, vesta::Affine, _>::init(vec![]);
println!("creating plonk proof");
plonk::create_proof(
&pk.params,
&pk.pk,
@@ -70,6 +70,7 @@ impl Proof {
&mut rng,
&mut transcript,
)?;
println!("created plonk proof");
Ok(Proof(transcript.finalize()))
}

View File

@@ -1,10 +1,15 @@
use crate::{
consensus::{BlockInfo},
util::time::Timestamp,
blockchain::{Blockchain},
blockchain::{Blockchain,Epoch},
Result,
};
use darkfi::crypto::proof::VerifyingKey;
use darkfi::crypto::proof::ProvingKey;
use pasta_curves::{
pallas,
};
@@ -13,28 +18,44 @@ use group::ff::PrimeField;
pub struct Stakeholder
{
pub blockchain: Blockchain // stakeholder view of the blockchain
pub blockchain: Blockchain, // stakeholder view of the blockchain
pub clock : Clock,
pub coins : Vec<LeadCoin>, // owned stakes
pub epoch : &Epoch, // current epoch
pub epoch_consensus : EpochConsensus, // configuration for the epoch
pub pk : ProvingKey,
pub vk : VerifyingKey,
}
impl Stakeholder
{
pub fn new() -> Result<Self>
/// initialize new stakeholder with sled in /tmp
pub fn new(consensus: EpochConsensus) -> Result<Self>
{
//TODO initialize the blockchain
let path = "/tmp";
let db = sled::open(path).unwrap();
let ts = Timestamp::current_time();
let genesis_hash = blake3::hash(b"data");
let genesis_hash = blake3::hash(b"");
let bc = Blockchain::new(&db, ts, genesis_hash).unwrap();
Ok(Self{blockchain: bc})
//TODO replace with const
let eta = pallas::base::one();
//let epoch = Epoch::new(consensus, eta);
let lead_pk = ProvingKey::build(k, &LeadContract::default());
let lead_vk = VerifyingKey::build(k, &LeadContract::default());
Ok(Self{blockchain: bc, epoch_consensus: consensus, pk:lead_pk, vk:lead_vk})
}
/// add new blockinfo to the blockchain
pub fn add_block(&self, block: BlockInfo)
{
let blocks = [block];
self.blockchain.add(&blocks);
}
/// extract leader selection lottery randomness \eta
/// it's the hash of the previous lead proof
/// converted to pallas base
pub fn get_eta(&self) -> pallas::Base
{
let last_proof_slot : u64 = 0;
@@ -45,4 +66,32 @@ impl Stakeholder
bytes[31] = 0;
pallas::Base::from_repr(bytes).unwrap()
}
/// on the onset of the epoch, layout the new the competing coins
/// assuming static stake during the epoch, enforced by the commitment to competing coins
/// in the epoch's gen2esis data.
pub fn new_epoch(&self)
{
let eta = self.get_eta();
let epoch = Epoch::new(self.consensus, self.get_eta());
let coins : Vec<LeadCoin> = epoch.create_coins();
self.epoch = epoch;
//TODO initialize blocks in the epoch, and add coin commitment in genesis
}
/// at the begining of the slot
/// stakeholder need to play the lottery for the slot.
/// FIXME if the stakeholder is not winning, staker can try different coins before,
/// commiting it's coins, to maximize success, thus,
/// the lottery proof need to be conditioned on the slot itself, and previous proof.
/// this will encourage each potential leader to play with honesty.
pub fn new_slot(&self) -> Result<bool, Proof>
{
let sl : u64 = self.clock.slot();
let is_leader : bool = self.epoch.is_leader(sl);
// if is leader create proof
let proof = self.epoch.get_proof(sl, self.pk);
//TODO initialize blocks in the epoch, and add proof
Ok(is_leader, proof)
}
}

View File

@@ -651,9 +651,9 @@ impl Circuit<pallas::Base> for LeadContract {
//TODO (research) this multiplication panics!
let y_commit_exp = ar_chip.mul(
layouter.namespace(|| ""),
layouter.namespace(|| ""),
//root_sk.clone(), //(fix)
&coin_nonce,
//root_sk.clone(), //(fix)
&one,
)?;