Răsfoiți Sursa

[crypsinous] merge crypsinousintomaster

mohab metwally 3 ani în urmă
părinte
comite
97aa221e73

BIN
db/snap.0000000000000434


+ 6 - 4
example/crypsinous.rs

@@ -20,32 +20,34 @@ async fn main()
     let n = 3;
     /// initialize n stakeholders
     let alice_settings = Settings {
-        inbound: Some(Url::parse("tls://127.0.0.1:12002").unwrap()),
+        inbound: vec!(Url::parse("tls://127.0.0.1:12002").unwrap()),
         outbound_connections: 4,
         manual_attempt_limit: 0,
         seed_query_timeout_seconds: 8,
         connect_timeout_seconds: 10,
         channel_handshake_seconds: 4,
         channel_heartbeat_seconds: 10,
-        external_addr: Some(Url::parse("tls://127.0.0.1:12002").unwrap()),
+        external_addr: vec!(Url::parse("tls://127.0.0.1:12002").unwrap()),
         peers: [Url::parse("tls://127.0.0.1:12003").unwrap()].to_vec(),
         seeds: [Url::parse("tls://irc0.dark.fi:11001").unwrap(),
                 Url::parse("tls://irc1.dark.fi:11001").unwrap()
         ].to_vec(),
+        ..Default::default()
     };
     let bob_settings = Settings {
-        inbound: Some(Url::parse("tls://127.0.0.1:12003").unwrap()),
+        inbound: vec!(Url::parse("tls://127.0.0.1:12003").unwrap()),
         outbound_connections: 4,
         manual_attempt_limit: 0,
         seed_query_timeout_seconds: 8,
         connect_timeout_seconds: 10,
         channel_handshake_seconds: 4,
         channel_heartbeat_seconds: 10,
-        external_addr: Some(Url::parse("tls://127.0.0.1:12003").unwrap()),
+        external_addr: vec!(Url::parse("tls://127.0.0.1:12003").unwrap()),
         peers: [Url::parse("tls://127.0.0.1:12002").unwrap()].to_vec(),
         seeds: [Url::parse("tls://irc0.dark.fi:11001").unwrap(),
                 Url::parse("tls://irc1.dark.fi:11001").unwrap()
         ].to_vec(),
+        ..Default::default()
     };
     let k : u32 = 13; //proof's number of rows
     let mut handles = vec!();

+ 5 - 4
example/lead.rs

@@ -27,7 +27,7 @@ use darkfi::{
         merkle_node::MerkleNode,
     },
     tx::Transaction,
-    consensus::{TransactionLeadProof, Metadata, StreamletMetadata, BlockInfo},
+    consensus::{TransactionLeadProof, StakeholderMetadata, StreamletMetadata, BlockInfo},
     net::{P2p,Settings, SettingsPtr,},
     zk::circuit::lead_contract::LeadContract,
 };
@@ -44,18 +44,19 @@ fn main() {
     };
     //
     let settings = Settings{
-        inbound: Some(Url::parse("tls://127.0.0.1:12002").unwrap()),
+        inbound: vec!(Url::parse("tls://127.0.0.1:12002").unwrap()),
         outbound_connections: 4,
         manual_attempt_limit: 0,
         seed_query_timeout_seconds: 8,
         connect_timeout_seconds: 10,
         channel_handshake_seconds: 4,
         channel_heartbeat_seconds: 10,
-        external_addr: Some(Url::parse("tls://127.0.0.1:12002").unwrap()),
+        external_addr: vec!(Url::parse("tls://127.0.0.1:12002").unwrap()),
         peers: [Url::parse("tls://127.0.0.1:12003").unwrap()].to_vec(),
         seeds: [Url::parse("tls://irc0.dark.fi:11001").unwrap(),
-                Url::parse("tls://irc1.dark.fi:11001").unwrap()
+                Url::parse("tls://irc1.dark.fi:11001").unwrap(),
         ].to_vec(),
+        ..Default::default()
     };
     let consensus = EpochConsensus::new(Some(22), Some(3), Some(22), Some(0));
 

+ 6 - 6
src/blockchain/mod.rs

@@ -4,7 +4,6 @@ use std::error;
 
 use crate::{
     consensus::{Block, BlockInfo, StreamletMetadata},
-    impl_vec,
     util::{
         serial::{Decodable, Encodable, ReadExt, VarInt, WriteExt},
         time::Timestamp,
@@ -94,14 +93,16 @@ impl Blockchain {
             ret.push(headerhash[0]);
 
             // Store block
-            let _block = Block::new(headerhash[0], tx_hashes, block.metadata.clone());
-            self.blocks.insert(&[_block])?;
+            //let _block = Block::new(headerhash[0], tx_hashes, block.m.clone());
+            //self.blocks.insert(&[_block])?;
+            let blk : Block = Block::from(block.clone());
+            self.blocks.insert(&[blk])?;
 
             // Store block order
             self.order.insert(&[block.header.slot], &[headerhash[0]])?;
 
             // Store ouroboros metadata
-            self.ouroboros_metadata.insert(&[blockhash[0]], &[block.metadata.om.clone()])?;
+            self.ouroboros_metadata.insert(&[headerhash[0]], &[block.om.clone()])?;
 
             // Store streamlet metadata
             self.streamlet_metadata.insert(&[headerhash[0]], &[block.sm.clone()])?;
@@ -139,12 +140,11 @@ impl Blockchain {
         for (i, header) in headers.iter().enumerate() {
             let header = header.clone().unwrap();
             let block = blocks[i].clone().unwrap();
-            let sm = metadata[i].clone().unwrap();
 
             let txs = self.transactions.get(&block.txs, true)?;
             let txs = txs.iter().map(|x| x.clone().unwrap()).collect();
 
-            let info = BlockInfo::new(header, txs, block.metadata.clone(), sm);
+            let info = BlockInfo::new(header, txs, block.m.clone(), block.om, block.sm);
             ret.push(info);
         }
 

+ 47 - 30
src/consensus/block.rs

@@ -3,8 +3,8 @@ use std::fmt;
 use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
 use log::debug;
 use rand::rngs::OsRng;
-
-use super::{Metadata, StreamletMetadata, OuroborosMetadata, BLOCK_INFO_MAGIC_BYTES, BLOCK_MAGIC_BYTES,BLOCK_VERSION, TransactionLeadProof};
+use pasta_curves::pallas;
+use super::{StakeholderMetadata, StreamletMetadata, OuroborosMetadata, BLOCK_INFO_MAGIC_BYTES, BLOCK_MAGIC_BYTES,BLOCK_VERSION, TransactionLeadProof};
 
 use crate::{
     crypto::{
@@ -37,17 +37,6 @@ pub struct Header {
     pub root: MerkleNode,
 }
 
-impl Default for Header {
-    fn default() -> Self {
-        Header::new(blake3::Hash(""),
-                    0,
-                    0,
-                    Timestamp::current_time(),
-                    pallas::Base::Zero())
-        )
-    }
-}
-
 impl Header {
     pub fn new(
         state: blake3::Hash,
@@ -74,6 +63,12 @@ impl Header {
     }
 }
 
+impl Default for Header {
+    fn default() -> Self {
+        Header::new(blake3::hash(b""), 0 ,0, Timestamp::current_time(), MerkleNode(pallas::Base::zero()))
+    }
+}
+
 /// This struct represents a tuple of the form (`magic`, `header`, `counter`, `txs`, `metadata`).
 /// The header and transactions are stored as hashes, serving as pointers to
 /// the actual data in the sled database.
@@ -82,9 +77,11 @@ pub struct Block {
     /// Block magic bytes
     pub magic: [u8; 4],
     /// Block header
-    header: Header,
+    pub header: blake3::Hash,
     /// Trasaction hashes
     pub txs: Vec<blake3::Hash>,
+    /// stakeholder metadata
+    pub m: StakeholderMetadata,
     /// ouroboros block information,
     pub om: OuroborosMetadata,
     /// streamlet
@@ -104,12 +101,21 @@ impl Block {
         sl: u64,
         txs: Vec<blake3::Hash>,
         root: MerkleNode,
-        ouroborosMetadata: OuroborosMetadata,
+        m: StakeholderMetadata,
+        om: OuroborosMetadata,
+        sm: StreamletMetadata,
     ) -> Self {
         let magic = *BLOCK_MAGIC_BYTES;
-        let ts = Timestamp::curent_time();
+        let ts = Timestamp::current_time();
         let header = Header::new(st, e, sl, ts, root);
-        Self { magic, header txs, ouroborosMetadata }
+        let headerhash = header.headerhash();
+        Self { magic:magic,
+               header: headerhash,
+               txs: txs,
+               m: m,
+               om: om,
+               sm: sm
+        }
     }
 
     /// Generate the genesis block.
@@ -118,9 +124,21 @@ impl Block {
         //let eta : [u8; 32] = *blake3::hash(b"let there be dark!").as_bytes();
         //let empty_lead_proof = TransactionLeadProof::default();
         let header = Header::genesis_header(genesis_ts, genesis_data);
+        let m = StakeholderMetadata::default();
         let om = OuroborosMetadata::default();
         let sm = StreamletMetadata::default();
-        Self::new(magic, header.headerhash(), vec![], om, sm)
+        Self{ magic: magic,
+              header: header.headerhash(),
+              txs: vec![],
+              m: m,
+              om: om,
+              sm: sm
+        }
+    }
+
+    /// Calculate the block hash
+    pub fn blockhash(&self) -> blake3::Hash {
+        blake3::hash(&serialize(self))
     }
 }
 
@@ -148,6 +166,8 @@ pub struct BlockInfo {
     pub header: Header,
     /// Transactions payload
     pub txs: Vec<Transaction>,
+    /// stakeholder metadata,
+    pub m: StakeholderMetadata,
     /// ouroboros metadata
     pub om: OuroborosMetadata,
     /// Proposal information used by Streamlet consensus
@@ -161,6 +181,7 @@ impl Default for BlockInfo {
             magic: magic,
             header: Header::default(),
             txs: vec![],
+            m: StakeholderMetadata::default(),
             om: OuroborosMetadata::default(),
             sm: StreamletMetadata::default(),
         }
@@ -177,11 +198,12 @@ impl BlockInfo {
     pub fn new(
         header: Header,
         txs: Vec<Transaction>,
+        m: StakeholderMetadata,
         om: OuroborosMetadata,
         sm: StreamletMetadata
     ) -> Self {
         let magic = *BLOCK_MAGIC_BYTES;
-        Self e{magic, header, txs, om, sm}
+        Self {magic, header, txs, m, om, sm}
     }
 
     /// Calculate the block hash
@@ -195,22 +217,15 @@ impl From<BlockInfo> for Block {
     fn from(b: BlockInfo) -> Self {
         let txids = b.txs.iter().map(|x| blake3::hash(&serialize(x))).collect();
         Self { magic: b.magic,
-               header: b.header,
+               header: b.header.headerhash(),
                txs: txids,
+               m: b.m,
                om: b.om,
                sm: b.sm,
         }
     }
 }
 
-
-impl net::Message for BlockInfo {
-    fn name() -> &'static str {
-        "blockinfo"
-    }
-}
-
-
 /// Auxiliary structure used for blockchain syncing
 #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
 pub struct BlockResponse {
@@ -236,10 +251,11 @@ impl BlockProposal {
     pub fn new(
         header: Header,
         txs: Vec<Transaction>,
+        m: StakeholderMetadata,
         om: OuroborosMetadata,
         sm: StreamletMetadata,
     ) -> Self {
-        let block = BlockInfo::new(header, txs, om, sm);
+        let block = BlockInfo::new(header, txs, m, om, sm);
         Self { block }
     }
 }
@@ -254,7 +270,8 @@ impl PartialEq for BlockProposal {
 impl fmt::Display for BlockProposal {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_fmt(format_args!(
-            "BlockProposal {{ hash: {}, epoch: {}, slot: {}, txs: {} }}",
+            "BlockProposal {{ leader addr: {}, hash: {}, epoch: {}, slot: {}, txs: {} }}",
+            self.block.m.address,
             self.block.header.headerhash(),
             self.block.header.epoch,
             self.block.header.slot,

+ 33 - 1
src/consensus/metadata.rs

@@ -1,4 +1,6 @@
 use super::{Participant, Vote};
+use rand::rngs::OsRng;
+
 use crate::{
     util::{
         serial::{SerialDecodable, SerialEncodable},
@@ -15,6 +17,7 @@ use crate::{
         },
         lead_proof,
         leadcoin::LeadCoin,
+        keypair::Keypair,
     },
     Result, VerifyFailed, VerifyResult,
 };
@@ -47,7 +50,36 @@ impl Metadata {
         Self { timestamp, om: OuroborosMetadata::new(eta, lead_proof) }
     }
 }
-*/
+ */
+
+#[derive(Debug, Clone, PartialEq, SerialEncodable, SerialDecodable)]
+pub struct StakeholderMetadata {
+    /// Block owner signature
+    pub signature: Signature,
+    /// Block owner address
+    pub address: Address,
+}
+
+impl Default for StakeholderMetadata {
+    fn default() -> Self {
+        let keypair = Keypair::random(&mut OsRng);
+        let address = Address::from(keypair.public);
+        let sign = Signature::dummy();
+        Self {
+            signature: sign,
+            address: address,
+        }
+    }
+}
+
+impl StakeholderMetadata {
+    pub fn new(signature: Signature, address: Address) -> Self {
+        Self {
+            signature,
+            address
+        }
+    }
+}
 
 /// wrapper over the Proof, for possiblity any metadata necessary in the future.
 #[derive(Debug, Clone, PartialEq,  SerialEncodable, SerialDecodable)]

+ 1 - 1
src/consensus/mod.rs

@@ -4,7 +4,7 @@ pub use block::{Block, BlockInfo, BlockProposal, Header, ProposalChain};
 
 /// Consensus metadata
 pub mod metadata;
-pub use metadata::{Metadata, StreamletMetadata, OuroborosMetadata, TransactionLeadProof};
+pub use metadata::{StakeholderMetadata, StreamletMetadata, OuroborosMetadata, TransactionLeadProof};
 
 /// Consensus participant
 pub mod participant;

+ 9 - 11
src/consensus/state.rs

@@ -24,6 +24,7 @@ use crate::{
         merkle_node::MerkleNode,
         schnorr::{SchnorrPublic, SchnorrSecret},
     },
+    consensus::{StakeholderMetadata},
     net,
     node::{
         state::{state_transition, ProgramState, StateUpdate},
@@ -303,14 +304,11 @@ impl ValidatorState {
         let root = tree.root(0).unwrap();
         let header = Header::new(prev_hash, self.slot_epoch(slot), slot, Timestamp::current_time(), root);
 
-
-        // are the signature, and address used?
-        //let signed_proposal = self.secret.sign(&header.headerhash().as_bytes()[..]);
-        //let metadata = Metadata::new(String::from("proof"), String::from("r"), signed_proposal, self.address);
-
-        let om = OuroborosMetadata::new(eta, lead_proof);
+        let signed_proposal = self.secret.sign(&header.headerhash().as_bytes()[..]);
+        let m = StakeholderMetadata::new(signed_proposal, self.address);
+        let om = OuroborosMetadata::default();
         let sm = StreamletMetadata::new(self.consensus.participants.values().cloned().collect());
-        Ok(Some(BlockProposal::new(header, unproposed_txs, om, sm)))
+        Ok(Some(BlockProposal::new(header, unproposed_txs, m, om, sm)))
     }
 
     /// Retrieve all unconfirmed transactions not proposed in previous blocks
@@ -380,19 +378,19 @@ impl ValidatorState {
         self.refresh_participants()?;
 
         let leader = self.slot_leader();
-        if leader.address != proposal.block.metadata.address {
+        if leader.address != proposal.block.m.address {
             warn!(
                 "Received proposal not from slot leader ({}), but from ({})",
-                leader.address, proposal.block.metadata.address
+                leader.address, proposal.block.m.address
             );
             return Ok(None)
         }
 
         if !leader.public_key.verify(
             proposal.block.header.headerhash().as_bytes(),
-            &proposal.block.metadata.signature,
+            &proposal.block.m.signature,
         ) {
-            warn!("Proposer ({}) signature could not be verified", proposal.block.metadata.address);
+            warn!("Proposer ({}) signature could not be verified", proposal.block.m.address);
             return Ok(None)
         }
 

+ 1 - 1
src/crypto/burn_proof.rs

@@ -18,7 +18,7 @@ use crate::{
             DrkCircuitField, DrkCoinBlind, DrkSerial, DrkSpendHook, DrkTokenId, DrkUserData,
             DrkUserDataBlind, DrkUserDataEnc, DrkValue, DrkValueBlind, DrkValueCommit,
         },
-        util::poseidon_hash,
+        util::{poseidon_hash},
     },
     util::serial::{SerialDecodable, SerialEncodable},
     zk::circuit::burn_contract::BurnContract,

+ 5 - 10
src/crypto/util.rs

@@ -48,17 +48,12 @@ pub fn pedersen_commitment_u64(value: u64, blind: DrkValueBlind) -> DrkValueComm
 }
 
 
-/*
-#[allow(non_snake_case)]
-pub fn pedersen_commitment_base(value: pallas::Base, blind: DrkValueBlind) -> DrkValueCommit {
-    let hasher = DrkValueCommit::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
-    let V = hasher(&VALUE_COMMITMENT_V_BYTES);
-    let R = hasher(&VALUE_COMMITMENT_R_BYTES);
-
-
-    V * mod_r_p(value) + R * blind
+/// Simplified wrapper for poseidon hash function.
+pub fn poseidon_hash<const N: usize>(messages: [pallas::Base; N]) -> pallas::Base {
+    poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<N>, 3, 2>::init()
+        .hash(messages)
 }
-*/
+
 /// Converts from pallas::Base to pallas::Scalar (aka $x \pmod{r_\mathbb{P}}$).
 ///
 /// This requires no modular reduction because Pallas' base field is smaller than its

+ 50 - 13
src/stakeholder/stakeholder.rs

@@ -4,13 +4,14 @@ use async_std::sync::Arc;
 use log::debug;
 use std::fmt;
 
+use rand::rngs::OsRng;
 use std::time::Duration;
 use std::thread;
 
 use crate::zk::circuit::LeadContract;
 
 use crate::{
-    consensus::{Block, BlockInfo,Metadata,StreamletMetadata,TransactionLeadProof},
+    consensus::{Block, BlockInfo,OuroborosMetadata, StakeholderMetadata,StreamletMetadata,TransactionLeadProof, Header},
     util::{
         time::Timestamp,
         clock::{Clock,Ticks},
@@ -20,6 +21,10 @@ use crate::{
     crypto::{
         proof::{Proof, ProvingKey, VerifyingKey,  },
         leadcoin::{LeadCoin},
+        schnorr::{Signature,SchnorrSecret, SchnorrPublic},
+        keypair::{Keypair},
+        merkle_node::MerkleNode,
+        address::Address,
     },
     blockchain::{Blockchain,Epoch,EpochConsensus},
     net::{P2p,Settings, SettingsPtr, Channel, ChannelPtr, Hosts, HostsPtr,MessageSubscription},
@@ -42,7 +47,9 @@ pub struct SlotWorkspace
     pub e: u64, // epoch index
     pub sl: u64, // absolute slot index
     pub txs: Vec<Transaction>, // unpublished block transactions
-    pub metadata: Metadata,
+    pub root: MerkleNode, /// merkle root of txs
+    pub m: StakeholderMetadata,
+    pub om: OuroborosMetadata,
     pub is_leader: bool,
     pub proof: Proof,
     pub block: BlockInfo,
@@ -54,8 +61,10 @@ impl Default for SlotWorkspace {
               e: 0,
               sl: 0,
               txs: vec![],
+              root: MerkleNode(pallas::Base::zero()),
               is_leader: false,
-              metadata: Metadata::default(),
+              m: StakeholderMetadata::default(),
+              om: OuroborosMetadata::default(),
               proof: Proof::default(),
               block: BlockInfo::default(),
         }
@@ -66,7 +75,12 @@ impl SlotWorkspace {
 
     pub fn new_block(&self) -> (BlockInfo, blake3::Hash) {
         let sm = StreamletMetadata::new(vec!());
-        let block = BlockInfo::new(self.st, self.e, self.sl, self.txs.clone(), self.metadata.clone(), sm);
+        let header = Header::new(self.st, self.e, self.sl, Timestamp::current_time(), self.root);
+        let block = BlockInfo::new(header,
+                                   self.txs.clone(),
+                                   self.m.clone(),
+                                   self.om.clone(),
+                                   sm);
         let hash = block.blockhash();
         (block, hash)
     }
@@ -75,8 +89,16 @@ impl SlotWorkspace {
         self.txs.push(tx);
     }
 
-    pub fn set_metadata(& mut self, md : Metadata) {
-        self.metadata = md;
+    pub fn set_root(&mut self, root: MerkleNode) {
+        self.root = root;
+    }
+
+    pub fn set_stakeholdermetadata(& mut self, meta : StakeholderMetadata) {
+        self.m = meta;
+    }
+
+    pub fn set_ouroborosmetadata(&mut self, meta: OuroborosMetadata) {
+        self.om = meta;
     }
 
     pub fn set_sl(&mut self, sl: u64) {
@@ -87,7 +109,6 @@ impl SlotWorkspace {
         self.st = st;
     }
 
-
     pub fn set_e(&mut self, e: u64) {
         self.e = e;
     }
@@ -101,7 +122,6 @@ impl SlotWorkspace {
     }
 }
 
-
 pub struct Stakeholder
 {
     pub blockchain: Blockchain, // stakeholder view of the blockchain
@@ -115,6 +135,7 @@ pub struct Stakeholder
     pub playing: bool,
     pub workspace : SlotWorkspace,
     pub id: u8,
+    pub keypair: Keypair,
     //pub subscription: Subscription<Result<ChannelPtr>>,
     //pub chanptr : ChannelPtr,
     //pub msgsub : MessageSubscription::<BlockInfo>,
@@ -147,6 +168,7 @@ impl Stakeholder
 
         //
         let clock = Clock::new(Some(consensus.get_epoch_len()), Some(consensus.get_slot_len()), Some(consensus.get_tick_len()), settings.peers);
+        let keypair = Keypair::random(&mut OsRng);
         debug!("stakeholder constructed...");
         Ok(Self{blockchain: bc,
                 net: p2p,
@@ -160,12 +182,23 @@ impl Stakeholder
                 playing: true,
                 workspace: workspace,
                 id: id,
+                keypair: keypair
                 //subscription: subscription,
                 //chanptr: chanptr,
                 //msgsub: msg_sub,
         })
     }
 
+    /// wrapper on Schnorr signature
+    pub fn sign(&self, message : &[u8]) -> Signature {
+        self.keypair.secret.sign(message)
+    }
+
+    /// wrapper on schnorr public verify
+    pub fn verify(&self, message: &[u8], signature: &Signature) -> bool {
+        self.keypair.public.verify(message, signature)
+    }
+
     pub fn get_provkingkey(&self) -> ProvingKey {
         self.pk.clone()
     }
@@ -300,7 +333,8 @@ impl Stakeholder
                         //add the block to the blockchain
                         self.add_block(block_info.clone());
                         let block : Block = Block::from(block_info.clone());
-                        // publish the block.
+                        // publish the block
+                        //TODO (fix) before publishing the workspace tx root need to be set.
                         self.net.broadcast(block);
                     } else {
                         //
@@ -375,10 +409,13 @@ impl Stakeholder
         self.workspace.set_proof(proof.clone());
         //
         if is_leader {
-            let metadata = Metadata::new(Timestamp::current_time(),
-                                         self.get_eta().to_repr(),
-                                         TransactionLeadProof::from(proof.clone()));
-            self.workspace.set_metadata(metadata);
+            let addr = Address::from(self.keypair.public);
+            let sign = self.sign(proof.as_ref());
+            let stakeholder_meta = StakeholderMetadata::new(sign, addr);
+            let ouroboros_meta = OuroborosMetadata::new(self.get_eta().to_repr(),
+                                                        TransactionLeadProof::from(proof.clone()));
+            self.workspace.set_stakeholdermetadata(stakeholder_meta);
+            self.workspace.set_ouroborosmetadata(ouroboros_meta);
         }
     }
 }