Browse Source

stakeholder: conflict resolved

aggstam 3 years ago
parent
commit
c4227d9e03

+ 3 - 2
bin/darkfid/src/main.rs

@@ -10,7 +10,8 @@ use darkfi::{
     async_daemonize, cli_desc,
     consensus::{
         proto::{
-            ProtocolKeepAlive, ProtocolParticipant, ProtocolProposal, ProtocolSync, ProtocolSyncConsensus, ProtocolTx,
+            ProtocolKeepAlive, ProtocolParticipant, ProtocolProposal, ProtocolSync,
+            ProtocolSyncConsensus, ProtocolTx,
         },
         state::ValidatorStatePtr,
         task::{block_sync_task, proposal_task},
@@ -375,7 +376,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'_>>) -> Result<()> {
     let consensus_p2p = {
         if !args.consensus {
             None
-        } else {            
+        } else {
             info!("Registering consensus P2P protocols...");
             let consensus_network_settings = net::Settings {
                 inbound: args.consensus_p2p_accept,

+ 15 - 113
src/blockchain/metadatastore.rs

@@ -1,124 +1,30 @@
 use crate::{
-    consensus::{Block, OuroborosMetadata, StreamletMetadata, TransactionLeadProof},
+    consensus::{Block, Metadata},
     serial::{deserialize, serialize},
     util::time::Timestamp,
     Error, Result,
 };
 
-const SLED_STREAMLET_METADATA_TREE: &[u8] = b"_streamlet_metadata";
-const SLED_OUROBOROS_METADATA_TREE: &[u8] = b"_ouroboros_metadata";
+const SLED_METADATA_TREE: &[u8] = b"_metadata";
 
-/// The `StreamletMetadataStore` is a `sled` tree storing all the blockchain's
+/// The `MetadataStore` is a `sled` tree storing all the blockchain's
 /// blocks' metadata used by the Streamlet consensus protocol, where the key
 /// is the block's headers' hash, and the value is the serialized metadata.
 #[derive(Clone)]
-pub struct StreamletMetadataStore(sled::Tree);
+pub struct MetadataStore(sled::Tree);
 
-impl StreamletMetadataStore {
-    /// Opens a new or existing `StreamletMetadataStore` on the given sled database.
-    pub fn new(db: &sled::Db, genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Result<Self> {
-        let tree = db.open_tree(SLED_STREAMLET_METADATA_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);
-
-            let metadata = StreamletMetadata {
-                notarized: true,
-                finalized: true,
-                participants: vec![],
-            };
-
-            store.insert(&[genesis_block.header], &[metadata])?;
-        }
-
-        Ok(store)
-    }
-
-    /// Insert a slice of blockhashes and respective metadata into the store.
-    /// With sled, the operation is done as a batch.
-    /// The block hash is used as the key, and the metadata is used as value.
-    pub fn insert(&self, hashes: &[blake3::Hash], metadatas: &[StreamletMetadata]) -> Result<()> {
-        assert_eq!(hashes.len(), metadatas.len());
-        let mut batch = sled::Batch::default();
-
-        for (i, hash) in hashes.iter().enumerate() {
-            batch.insert(hash.as_bytes(), serialize(&metadatas[i]));
-        }
-
-        self.0.apply_batch(batch)?;
-        Ok(())
-    }
-
-    /// Check if the metadata store contains a given block hash
-    pub fn contains(&self, hash: &blake3::Hash) -> Result<bool> {
-        Ok(self.0.contains_key(hash.as_bytes())?)
-    }
-
-    /// Fetch given blockhashes from the store. The resulting vector contains
-    /// `Option`, which is `Some` if the slot was found in the blockstore, and
-    /// otherwise it is `None`, if it has not. The second parameter is a boolean
-    /// which tells the function to fail in case at least one blockhash was not
-    /// found.
-    pub fn get(
-        &self,
-        hashes: &[blake3::Hash],
-        strict: bool,
-    ) -> Result<Vec<Option<StreamletMetadata>>> {
-        let mut ret = Vec::with_capacity(hashes.len());
-
-        for hash in hashes {
-            if let Some(found) = self.0.get(hash.as_bytes())? {
-                let sm = deserialize(&found)?;
-                ret.push(Some(sm));
-            } else {
-                if strict {
-                    let s = hash.to_hex().as_str().to_string();
-                    return Err(Error::BlockMetadataNotFound(s))
-                }
-                ret.push(None);
-            }
-        }
-
-        Ok(ret)
-    }
-
-    /// Retrieve all metadata from the store in the form of a tuple
-    /// (`hash`, `metadata`).
-    /// Be careful as this will try to load everything in memory.
-    pub fn get_all(&self) -> Result<Vec<(blake3::Hash, StreamletMetadata)>> {
-        let mut hashes = vec![];
-
-        for hash in self.0.iter() {
-            let (key, value) = hash.unwrap();
-            let hash_bytes: [u8; 32] = key.as_ref().try_into().unwrap();
-            let m = deserialize(&value)?;
-            hashes.push((hash_bytes.into(), m));
-        }
-
-        Ok(hashes)
-    }
-}
-
-#[derive(Clone)]
-pub struct OuroborosMetadataStore(sled::Tree);
-
-impl OuroborosMetadataStore {
+impl MetadataStore {
     /// Opens a new or existing `OuroborosMetadataStore` on the given sled database.
     pub fn new(db: &sled::Db, genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Result<Self> {
-        let tree = db.open_tree(SLED_OUROBOROS_METADATA_TREE)?;
+        let tree = db.open_tree(SLED_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);
             let genesis_hash = blake3::hash(&serialize(&genesis_block));
 
-            let empty_lead_proof = TransactionLeadProof::default();
-            let metadata = OuroborosMetadata { eta, lead_proof: empty_lead_proof };
-
-            store.insert(&[genesis_hash], &[metadata])?;
+            store.insert(&[genesis_hash], &[genesis_block.metadata])?;
         }
 
         Ok(store)
@@ -127,7 +33,7 @@ impl OuroborosMetadataStore {
     /// Insert a slice of blockhashes and respective metadata into the store.
     /// With sled, the operation is done as a batch.
     /// The block hash is used as the key, and the metadata is used as value.
-    pub fn insert(&self, hashes: &[blake3::Hash], metadatas: &[OuroborosMetadata]) -> Result<()> {
+    pub fn insert(&self, hashes: &[blake3::Hash], metadatas: &[Metadata]) -> Result<()> {
         assert_eq!(hashes.len(), metadatas.len());
         let mut batch = sled::Batch::default();
 
@@ -144,16 +50,12 @@ impl OuroborosMetadataStore {
         Ok(self.0.contains_key(hash.as_bytes())?)
     }
 
-    /// Fetch given blockhashes from the store. The resulting vector contains
-    /// `Option`, which is `Some` if the slot was found in the blockstore, and
+    /// Fetch given blockhashes metadata from the store. The resulting vector contains
+    /// `Option`, which is `Some` if the metadata was found in the metadatastore, and
     /// otherwise it is `None`, if it has not. The second parameter is a boolean
-    /// which tells the function to fail in case at least one blockhash was not
+    /// which tells the function to fail in case at least one blocks' metadata was not
     /// found.
-    pub fn get(
-        &self,
-        hashes: &[blake3::Hash],
-        strict: bool,
-    ) -> Result<Vec<Option<OuroborosMetadata>>> {
+    pub fn get(&self, hashes: &[blake3::Hash], strict: bool) -> Result<Vec<Option<Metadata>>> {
         let mut ret = Vec::with_capacity(hashes.len());
 
         for hash in hashes {
@@ -175,7 +77,7 @@ impl OuroborosMetadataStore {
     /// Retrieve all metadata from the store in the form of a tuple
     /// (`hash`, `metadata`).
     /// Be careful as this will try to load everything in memory.
-    pub fn get_all(&self) -> Result<Vec<(blake3::Hash, OuroborosMetadata)>> {
+    pub fn get_all(&self) -> Result<Vec<(blake3::Hash, Metadata)>> {
         let mut hashes = vec![];
 
         for hash in self.0.iter() {
@@ -189,7 +91,7 @@ impl OuroborosMetadataStore {
     }
 
     /// Retrive last key/val
-    pub fn get_last(&self) -> Result<(blake3::Hash, OuroborosMetadata)> {
+    pub fn get_last(&self) -> Result<(blake3::Hash, Metadata)> {
         let all = self.get_all().unwrap();
         Ok(all[all.len() - 1].clone())
     }

+ 8 - 23
src/blockchain/mod.rs

@@ -13,7 +13,7 @@ pub mod blockstore;
 pub use blockstore::{BlockOrderStore, BlockStore, HeaderStore};
 
 pub mod metadatastore;
-pub use metadatastore::{OuroborosMetadataStore, StreamletMetadataStore};
+pub use metadatastore::MetadataStore;
 
 pub mod nfstore;
 pub use nfstore::NullifierStore;
@@ -37,10 +37,8 @@ pub struct Blockchain {
     pub order: BlockOrderStore,
     /// Transactions sled tree
     pub transactions: TxStore,
-    /// Streamlet metadata sled tree
-    pub streamlet_metadata: StreamletMetadataStore,
-    /// Ourobors metadata sled tree
-    pub ouroboros_metadata: OuroborosMetadataStore,
+    /// Metadata sled tree
+    pub metadata: MetadataStore,
     /// Nullifiers sled tree
     pub nullifiers: NullifierStore,
     /// Merkle roots sled tree
@@ -55,22 +53,12 @@ impl Blockchain {
         let headers = HeaderStore::new(db, genesis_ts, genesis_data)?;
         let blocks = BlockStore::new(db, genesis_ts, genesis_data)?;
         let order = BlockOrderStore::new(db, genesis_ts, genesis_data)?;
-        let streamlet_metadata = StreamletMetadataStore::new(db, genesis_ts, genesis_data)?;
-        let ouroboros_metadata = OuroborosMetadataStore::new(db, genesis_ts, genesis_data)?;
+        let metadata = MetadataStore::new(db, genesis_ts, genesis_data)?;
         let transactions = TxStore::new(db)?;
         let nullifiers = NullifierStore::new(db)?;
         let merkle_roots = RootStore::new(db)?;
 
-        Ok(Self {
-            headers,
-            blocks,
-            order,
-            transactions,
-            streamlet_metadata,
-            ouroboros_metadata,
-            nullifiers,
-            merkle_roots,
-        })
+        Ok(Self { headers, blocks, order, transactions, metadata, nullifiers, merkle_roots })
     }
 
     /// Insert a given slice of [`BlockInfo`] into the blockchain database.
@@ -99,10 +87,7 @@ impl Blockchain {
             self.order.insert(&[block.header.slot], &[headerhash[0]])?;
 
             // Store ouroboros metadata
-            self.ouroboros_metadata.insert(&[headerhash[0]], &[block.om.clone()])?;
-
-            // Store streamlet metadata
-            self.streamlet_metadata.insert(&[headerhash[0]], &[block.sm.clone()])?;
+            self.metadata.insert(&[headerhash[0]], &[block.metadata.clone()])?;
 
             // NOTE: The nullifiers and Merkle roots are applied in the state
             // transition apply function.
@@ -138,7 +123,7 @@ impl Blockchain {
             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.m.clone(), block.om, block.sm);
+            let info = BlockInfo::new(header, txs, block.metadata.clone());
             ret.push(info);
         }
 
@@ -171,7 +156,7 @@ impl Blockchain {
     }
 
     pub fn get_last_proof_hash(&self) -> Result<blake3::Hash> {
-        let (hash, _) = self.ouroboros_metadata.get_last().unwrap();
+        let (hash, _) = self.metadata.get_last().unwrap();
         Ok(hash)
     }
 }

+ 34 - 81
src/consensus/block.rs

@@ -1,8 +1,6 @@
 use std::fmt;
 
-use super::{
-    OuroborosMetadata, StakeholderMetadata, StreamletMetadata, BLOCK_MAGIC_BYTES, BLOCK_VERSION,
-};
+use super::{Metadata, BLOCK_MAGIC_BYTES, BLOCK_VERSION};
 use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
 use log::debug;
 use pasta_curves::pallas;
@@ -15,13 +13,13 @@ use crate::{
     util::time::Timestamp,
 };
 
-/// This struct represents a tuple of the form (version, state, epoch, slot, timestamp, merkle_root).
+/// This struct represents a tuple of the form (version, previous, epoch, slot, timestamp, merkle_root).
 #[derive(Debug, Clone, PartialEq, Eq, SerialEncodable, SerialDecodable)]
 pub struct Header {
     /// Block version
     pub version: u8,
     /// Previous block hash
-    pub state: blake3::Hash,
+    pub previous: blake3::Hash,
     /// Epoch
     pub epoch: u64,
     /// Slot UID
@@ -34,14 +32,14 @@ pub struct Header {
 
 impl Header {
     pub fn new(
-        state: blake3::Hash,
+        previous: blake3::Hash,
         epoch: u64,
         slot: u64,
         timestamp: Timestamp,
         root: MerkleNode,
     ) -> Self {
         let version = *BLOCK_VERSION;
-        Self { version, state, epoch, slot, timestamp, root }
+        Self { version, previous, epoch, slot, timestamp, root }
     }
 
     /// Generate the genesis block.
@@ -81,12 +79,8 @@ pub struct Block {
     pub header: blake3::Hash,
     /// Trasaction hashes
     pub txs: Vec<blake3::Hash>,
-    /// stakeholder metadata
-    pub m: StakeholderMetadata,
-    /// ouroboros block information,
-    pub om: OuroborosMetadata,
-    /// streamlet
-    pub sm: StreamletMetadata,
+    /// Metadata
+    pub metadata: Metadata,
 }
 
 impl net::Message for Block {
@@ -97,32 +91,27 @@ impl net::Message for Block {
 
 impl Block {
     pub fn new(
-        st: blake3::Hash,
-        e: u64,
-        sl: u64,
+        previous: blake3::Hash,
+        epoch: u64,
+        slot: u64,
         txs: Vec<blake3::Hash>,
         root: MerkleNode,
-        m: StakeholderMetadata,
-        om: OuroborosMetadata,
-        sm: StreamletMetadata,
+        metadata: Metadata,
     ) -> Self {
         let magic = *BLOCK_MAGIC_BYTES;
-        let ts = Timestamp::current_time();
-        let header = Header::new(st, e, sl, ts, root);
-        let headerhash = header.headerhash();
-        Self { magic, header: headerhash, txs, m, om, sm }
+        let timestamp = Timestamp::current_time();
+        let header = Header::new(previous, epoch, slot, timestamp, root);
+        let header = header.headerhash();
+        Self { magic, header, txs, metadata }
     }
 
     /// Generate the genesis block.
     pub fn genesis_block(genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Self {
         let magic = *BLOCK_MAGIC_BYTES;
-        //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 { magic, header: header.headerhash(), txs: vec![], m, om, sm }
+        let header = header.headerhash();
+        let metadata = Metadata::default();
+        Self { magic, header, txs: vec![], metadata }
     }
 
     /// Calculate the block hash
@@ -155,25 +144,14 @@ 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
-    pub sm: StreamletMetadata,
+    /// Metadata,
+    pub metadata: Metadata,
 }
 
 impl Default for BlockInfo {
     fn default() -> Self {
         let magic = *BLOCK_MAGIC_BYTES;
-        Self {
-            magic,
-            header: Header::default(),
-            txs: vec![],
-            m: StakeholderMetadata::default(),
-            om: OuroborosMetadata::default(),
-            sm: StreamletMetadata::default(),
-        }
+        Self { magic, header: Header::default(), txs: vec![], metadata: Metadata::default() }
     }
 }
 
@@ -184,15 +162,9 @@ impl net::Message for BlockInfo {
 }
 
 impl BlockInfo {
-    pub fn new(
-        header: Header,
-        txs: Vec<Transaction>,
-        m: StakeholderMetadata,
-        om: OuroborosMetadata,
-        sm: StreamletMetadata,
-    ) -> Self {
+    pub fn new(header: Header, txs: Vec<Transaction>, metadata: Metadata) -> Self {
         let magic = *BLOCK_MAGIC_BYTES;
-        Self { magic, header, txs, m, om, sm }
+        Self { magic, header, txs, metadata }
     }
 
     /// Calculate the block hash
@@ -203,15 +175,13 @@ impl BlockInfo {
 }
 
 impl From<BlockInfo> for Block {
-    fn from(b: BlockInfo) -> Self {
-        let txids = b.txs.iter().map(|x| blake3::hash(&serialize(x))).collect();
+    fn from(block_info: BlockInfo) -> Self {
+        let txs = block_info.txs.iter().map(|x| blake3::hash(&serialize(x))).collect();
         Self {
-            magic: b.magic,
-            header: b.header.headerhash(),
-            txs: txids,
-            m: b.m,
-            om: b.om,
-            sm: b.sm,
+            magic: block_info.magic,
+            header: block_info.header.headerhash(),
+            txs,
+            metadata: block_info.metadata,
         }
     }
 }
@@ -238,14 +208,8 @@ pub struct BlockProposal {
 
 impl BlockProposal {
     #[allow(clippy::too_many_arguments)]
-    pub fn new(
-        header: Header,
-        txs: Vec<Transaction>,
-        m: StakeholderMetadata,
-        om: OuroborosMetadata,
-        sm: StreamletMetadata,
-    ) -> Self {
-        let block = BlockInfo::new(header, txs, m, om, sm);
+    pub fn new(header: Header, txs: Vec<Transaction>, metadata: Metadata) -> Self {
+        let block = BlockInfo::new(header, txs, metadata);
         Self { block }
     }
 }
@@ -260,7 +224,7 @@ impl fmt::Display for BlockProposal {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_fmt(format_args!(
             "BlockProposal {{ leader addr: {}, hash: {}, epoch: {}, slot: {}, txs: {} }}",
-            self.block.m.address,
+            self.block.metadata.address,
             self.block.header.headerhash(),
             self.block.header.epoch,
             self.block.header.slot,
@@ -298,13 +262,13 @@ impl ProposalChain {
     /// excluding the genesis block proposal.
     /// Additional validity rules can be applied.
     pub fn check_proposal(&self, proposal: &BlockProposal, previous: &BlockProposal) -> bool {
-        if proposal.block.header.state == self.genesis_block {
+        if proposal.block.header.previous == self.genesis_block {
             debug!("check_proposal(): Genesis block proposal provided.");
             return false
         }
 
         let prev_hash = previous.block.header.headerhash();
-        if proposal.block.header.state != prev_hash ||
+        if proposal.block.header.previous != prev_hash ||
             proposal.block.header.slot <= previous.block.header.slot
         {
             debug!("check_proposal(): Provided proposal is invalid.");
@@ -332,15 +296,4 @@ impl ProposalChain {
             self.proposals.push(proposal.clone());
         }
     }
-
-    /// Proposals chain notarization check.
-    pub fn notarized(&self) -> bool {
-        for proposal in &self.proposals {
-            if !proposal.block.sm.notarized {
-                return false
-            }
-        }
-
-        true
-    }
 }

+ 32 - 50
src/consensus/metadata.rs

@@ -15,83 +15,65 @@ use crate::{
     VerifyResult,
 };
 
+/// This struct represents [`Block`](super::Block) information used by the consensus protocol.
 #[derive(Debug, Clone, PartialEq, Eq, SerialEncodable, SerialDecodable)]
-pub struct StakeholderMetadata {
+pub struct Metadata {
     /// Block owner signature
     pub signature: Signature,
     /// Block owner address
     pub address: Address,
+    /// Response of global random oracle, or it's emulation.
+    pub eta: [u8; 32],
+    /// Leader NIZK proof
+    pub proof: LeadProof,
+    /// Nodes participating in the consensus process
+    pub participants: Vec<Participant>,
 }
 
-impl Default for StakeholderMetadata {
+impl Default for Metadata {
     fn default() -> Self {
         let keypair = Keypair::random(&mut OsRng);
         let address = Address::from(keypair.public);
-        let sign = Signature::dummy();
-        Self { signature: sign, address }
+        let signature = Signature::dummy();
+        let eta: [u8; 32] = *blake3::hash(b"let there be dark!").as_bytes();
+        let proof = LeadProof::default();
+        let participants = vec![];
+        Self { signature, address, eta, proof, participants }
     }
 }
 
-impl StakeholderMetadata {
-    pub fn new(signature: Signature, address: Address) -> Self {
-        Self { signature, address }
+impl Metadata {
+    pub fn new(
+        signature: Signature,
+        address: Address,
+        eta: [u8; 32],
+        proof: LeadProof,
+        participants: Vec<Participant>,
+    ) -> Self {
+        Self { signature, address, eta, proof, participants }
     }
 }
 
-/// wrapper over the Proof, for possiblity any metadata necessary in the future.
+/// Wrapper over the Proof, for future additions.
 #[derive(Default, Debug, Clone, PartialEq, Eq, SerialEncodable, SerialDecodable)]
-pub struct TransactionLeadProof {
-    /// leadership proof
-    pub lead_proof: Proof,
+pub struct LeadProof {
+    /// Leadership proof
+    pub proof: Proof,
 }
 
-impl TransactionLeadProof {
+impl LeadProof {
     pub fn new(pk: &ProvingKey, coin: LeadCoin) -> Self {
         let proof = lead_proof::create_lead_proof(pk, coin).unwrap();
-        Self { lead_proof: proof }
+        Self { proof }
     }
 
     pub fn verify(&self, vk: VerifyingKey, public_inputs: &[DrkCircuitField]) -> VerifyResult<()> {
-        lead_proof::verify_lead_proof(&vk, &self.lead_proof, public_inputs)
+        lead_proof::verify_lead_proof(&vk, &self.proof, public_inputs)
     }
 }
 
-impl From<Proof> for TransactionLeadProof {
+impl From<Proof> for LeadProof {
     fn from(proof: Proof) -> Self {
-        Self { lead_proof: proof }
-    }
-}
-
-/// This struct represents [`Block`](super::Block) information used by the Ouroboros
-/// Praos consensus protocol.
-#[derive(Default, Debug, Clone, PartialEq, Eq, SerialEncodable, SerialDecodable)]
-pub struct OuroborosMetadata {
-    /// response of global random oracle, or it's emulation.
-    pub eta: [u8; 32],
-    /// stakeholder lead NIZK lead proof
-    pub lead_proof: TransactionLeadProof,
-}
-
-impl OuroborosMetadata {
-    pub fn new(eta: [u8; 32], lead_proof: TransactionLeadProof) -> Self {
-        Self { eta, lead_proof }
-    }
-}
-
-/// This struct represents [`Block`](super::Block) information used by the Streamlet
-/// consensus protocol.
-#[derive(Debug, Clone, Default, SerialEncodable, SerialDecodable)]
-pub struct StreamletMetadata {
-    /// Block notarization flag
-    pub notarized: bool,
-    /// Block finalization flag
-    pub finalized: bool,
-    /// Nodes participated in the voting process
-    pub participants: Vec<Participant>,
-}
-
-impl StreamletMetadata {
-    pub fn new(participants: Vec<Participant>) -> Self {
-        Self { notarized: false, finalized: false, participants }
+        Self { proof }
     }
 }

+ 1 - 3
src/consensus/mod.rs

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

+ 22 - 22
src/consensus/state.rs

@@ -13,13 +13,12 @@ use log::{debug, error, info, warn};
 use rand::rngs::OsRng;
 
 use super::{
-    Block, BlockInfo, BlockProposal, Header, KeepAlive, OuroborosMetadata, Participant, ProposalChain,
-    StreamletMetadata,
+    Block, BlockInfo, BlockProposal, Header, KeepAlive, LeadProof, Metadata, Participant,
+    ProposalChain,
 };
 
 use crate::{
     blockchain::Blockchain,
-    consensus::StakeholderMetadata,
     crypto::{
         address::Address,
         constants::MERKLE_DEPTH,
@@ -302,15 +301,17 @@ impl ValidatorState {
             Header::new(prev_hash, self.slot_epoch(slot), slot, Timestamp::current_time(), root);
 
         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());
-        
+        // TODO: Replace with correct proof
+        let eta: [u8; 32] = *blake3::hash(b"let there be dark!").as_bytes();
+        let proof = LeadProof::default();
+        let participants = self.consensus.participants.values().cloned().collect();
+        let metadata = Metadata::new(signed_proposal, self.address, eta, proof, participants);
+
         // TODO: [PLACEHOLDER] Add balance proof creation
         // TODO: [PLACEHOLDER] Add crypsinous leader proof creation (to replace balance proof)
         // TODO: [PLACEHOLDER] Add rewards calculation (proof?)
         // TODO: [PLACEHOLDER] Create and add rewards transaction
-        Ok(Some(BlockProposal::new(header, unproposed_txs, m, om, sm)))
+        Ok(Some(BlockProposal::new(header, unproposed_txs, metadata)))
     }
 
     /// Retrieve all unconfirmed transactions not proposed in previous blocks
@@ -385,19 +386,19 @@ impl ValidatorState {
         self.refresh_participants()?;
 
         let mut leader = self.slot_leader();
-        if leader.address != proposal.block.m.address {
+        if leader.address != proposal.block.metadata.address {
             warn!(
                 "Received proposal not from slot leader ({}), but from ({})",
-                leader.address, proposal.block.m.address
+                leader.address, proposal.block.metadata.address
             );
             return Ok(None)
         }
 
         if !leader.public_key.verify(
             proposal.block.header.headerhash().as_bytes(),
-            &proposal.block.m.signature,
+            &proposal.block.metadata.signature,
         ) {
-            warn!("Proposer ({}) signature could not be verified", proposal.block.m.address);
+            warn!("Proposer ({}) signature could not be verified", proposal.block.metadata.address);
             return Ok(None)
         }
 
@@ -418,7 +419,7 @@ impl ValidatorState {
         // TODO: [PLACEHOLDER] Add balance proof validation
         // TODO: [PLACEHOLDER] Add crypsinous proof validation (to replace balance proof)
         // TODO: [PLACEHOLDER] Add rewards validation
-        
+
         if current > leader.seen {
             leader.seen = current;
         }
@@ -463,20 +464,20 @@ impl ValidatorState {
         for (index, chain) in self.consensus.proposals.iter().enumerate() {
             let last = chain.proposals.last().unwrap();
             let hash = last.block.header.headerhash();
-            if proposal.block.header.state == hash &&
+            if proposal.block.header.previous == hash &&
                 proposal.block.header.slot > last.block.header.slot
             {
                 return Ok(index as i64)
             }
 
-            if proposal.block.header.state == last.block.header.state &&
+            if proposal.block.header.previous == last.block.header.previous &&
                 proposal.block.header.slot == last.block.header.slot
             {
                 debug!("find_extended_chain_index(): Proposal already received");
                 return Ok(-2)
             }
 
-            if proposal.block.header.state == last.block.header.state &&
+            if proposal.block.header.previous == last.block.header.previous &&
                 proposal.block.header.slot > last.block.header.slot
             {
                 fork = Some(chain.clone());
@@ -494,7 +495,7 @@ impl ValidatorState {
         }
 
         let (last_slot, last_block) = self.blockchain.last()?;
-        if proposal.block.header.state != last_block || proposal.block.header.slot <= last_slot {
+        if proposal.block.header.previous != last_block || proposal.block.header.slot <= last_slot {
             debug!("find_extended_chain_index(): Proposal doesn't extend any known chain");
             return Ok(-2)
         }
@@ -581,7 +582,7 @@ impl ValidatorState {
         let mut dropped = vec![];
         for chain in self.consensus.proposals.iter() {
             let first = chain.proposals.first().unwrap();
-            if first.block.header.state != last_block || first.block.header.slot <= last_slot {
+            if first.block.header.previous != last_block || first.block.header.slot <= last_slot {
                 dropped.push(chain.clone());
             }
         }
@@ -598,13 +599,13 @@ impl ValidatorState {
         if self.consensus.pending_participants.contains(&participant) {
             return false
         }
-        
-    // TODO: [PLACEHOLDER] Add balance proof validation
+
+        // TODO: [PLACEHOLDER] Add balance proof validation
 
         self.consensus.pending_participants.push(participant);
         true
     }
-    
+
     /// Update participant seen.
     pub fn participant_keep_alive(&mut self, keep_alive: KeepAlive) -> bool {
         match self.consensus.participants.get(&keep_alive.address) {
@@ -647,7 +648,6 @@ impl ValidatorState {
         }
     }
 
-
     /// Refresh the participants map, to retain only the active ones.
     /// Active nodes are considered those that their last seen slot is
     /// in range: [current_slot - QUARANTINE_DURATION, current_slot]

+ 1 - 1
src/consensus/task/proposal.rs

@@ -58,7 +58,7 @@ pub async fn proposal_task(
         Ok(()) => info!("consensus: Participation message broadcasted successfully."),
         Err(e) => error!("Failed broadcasting consensus participation: {}", e),
     }
-    
+
     // Node initiates the background task to send keep alive messages
     match keep_alive_task(consensus_p2p.clone(), state.clone(), ex).await {
         Ok(()) => info!("consensus: Keep alive background task initiated successfully."),

+ 1 - 1
src/error.rs

@@ -235,7 +235,7 @@ pub enum Error {
 
     #[error("Merkle tree already exists in wallet")]
     WalletTreeExists,
-    
+
     #[error("Wallet insufficient balance")]
     WalletInsufficientBalance,
 

+ 1 - 1
src/node/client.rs

@@ -217,7 +217,7 @@ impl Client {
         let kp = self.wallet.keygen().await?;
         Ok(Address::from(kp.public))
     }
-    
+
     pub async fn get_balance(&self, token_id: DrkTokenId) -> Result<Option<Balance>> {
         self.wallet.get_balance(token_id).await
     }

+ 8 - 18
src/stakeholder/mod.rs

@@ -14,8 +14,7 @@ use crate::{
     blockchain::{Blockchain, Epoch, EpochConsensus},
     consensus::{
         clock::{Clock, Ticks},
-        Block, BlockInfo, Header, OuroborosMetadata, StakeholderMetadata, StreamletMetadata,
-        TransactionLeadProof,
+        Block, BlockInfo, Header, LeadProof, Metadata,
     },
     crypto::{
         address::Address,
@@ -54,8 +53,7 @@ pub struct SlotWorkspace {
     pub txs: Vec<Transaction>, // unpublished block transactions
     pub root: MerkleNode,
     /// merkle root of txs
-    pub m: StakeholderMetadata,
-    pub om: OuroborosMetadata,
+    pub m: Metadata,
     pub is_leader: bool,
     pub proof: Proof,
     pub block: BlockInfo,
@@ -70,8 +68,7 @@ impl Default for SlotWorkspace {
             txs: vec![],
             root: MerkleNode(pallas::Base::zero()),
             is_leader: false,
-            m: StakeholderMetadata::default(),
-            om: OuroborosMetadata::default(),
+            m: Metadata::default(),
             proof: Proof::default(),
             block: BlockInfo::default(),
         }
@@ -80,9 +77,8 @@ impl Default for SlotWorkspace {
 
 impl SlotWorkspace {
     pub fn new_block(&self) -> (BlockInfo, blake3::Hash) {
-        let sm = StreamletMetadata::new(vec![]);
         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 block = BlockInfo::new(header, self.txs.clone(), self.m.clone());
         let hash = block.blockhash();
         (block, hash)
     }
@@ -95,14 +91,10 @@ impl SlotWorkspace {
         self.root = root;
     }
 
-    pub fn set_stakeholdermetadata(&mut self, meta: StakeholderMetadata) {
+    pub fn set_metadata(&mut self, meta: Metadata) {
         self.m = meta;
     }
 
-    pub fn set_ouroborosmetadata(&mut self, meta: OuroborosMetadata) {
-        self.om = meta;
-    }
-
     pub fn set_sl(&mut self, sl: u64) {
         self.sl = sl;
     }
@@ -548,11 +540,9 @@ impl Stakeholder {
         let keypair = coin.keypair.unwrap();
         let addr = Address::from(keypair.public);
         let sign = keypair.secret.sign(proof.as_ref());
-        let stakeholder_meta = StakeholderMetadata::new(sign, addr);
-        let ouroboros_meta =
-            OuroborosMetadata::new(self.get_eta().to_repr(), TransactionLeadProof::from(proof));
-        self.workspace.set_stakeholdermetadata(stakeholder_meta);
-        self.workspace.set_ouroborosmetadata(ouroboros_meta);
+        let meta =
+            Metadata::new(sign, addr, self.get_eta().to_repr(), LeadProof::from(proof), vec![]);
+        self.workspace.set_metadata(meta);
         //
         if won {
             //TODO (res) verify the coin is finalized

+ 9 - 8
src/wallet/walletdb.rs

@@ -420,7 +420,7 @@ impl WalletDb {
 
         Ok(())
     }
-    
+
     pub async fn get_balance(&self, token_id: DrkTokenId) -> Result<Option<Balance>> {
         debug!("Getting balance of token ID");
 
@@ -428,12 +428,13 @@ impl WalletDb {
         let id = serialize(&token_id);
 
         let mut conn = self.conn.acquire().await?;
-        let row =
-            sqlx::query("SELECT value, token_id, nullifier FROM coins WHERE token_id = ?1 AND is_spent = ?2;")
-                .bind(id)
-                .bind(is_spent)
-                .fetch_optional(&mut conn)
-                .await?;
+        let row = sqlx::query(
+            "SELECT value, token_id, nullifier FROM coins WHERE token_id = ?1 AND is_spent = ?2;",
+        )
+        .bind(id)
+        .bind(is_spent)
+        .fetch_optional(&mut conn)
+        .await?;
 
         let balance = match row {
             Some(b) => {
@@ -600,7 +601,7 @@ mod tests {
             assert_eq!(i, token_id);
             assert!(wallet.token_id_exists(i).await?);
         }
-        
+
         // get_balance()
         let balance = wallet.get_balance(token_id).await?;
         assert_eq!(balance.unwrap().value, 69);