Просмотр исходного кода

src/consensus: updated structures

aggstam 4 лет назад
Родитель
Сommit
f6d19df216
4 измененных файлов с 60 добавлено и 53 удалено
  1. 21 10
      doc/src/architecture/blockchain.md
  2. 11 13
      src/consensus/block.rs
  3. 9 4
      src/consensus/metadata.rs
  4. 19 26
      src/consensus/state.rs

+ 21 - 10
doc/src/architecture/blockchain.md

@@ -228,11 +228,11 @@ without the need of forking the blockchain.
 
 |   Field     |        Type        |            Description                     |
 |-------------|--------------------|--------------------------------------------|
-| `v`         | `u8`               | Version                                    |
-| `st`        | `blake3Hash`       | Previous block hash                        |
-| `e`         | `u64`              | Epoch                                      |
-| `sl`        | `u64`              | Slot UID                                   |
-| `time`      | `Timestamp`        | Block creation timestamp                   |
+| `version`   | `u8`               | Version                                    |
+| `state`     | `blake3Hash`       | Previous block hash                        |
+| `epoch`     | `u64`              | Epoch                                      |
+| `slot`      | `u64`              | Slot UID                                   |
+| `timestamp` | `Timestamp`        | Block creation timestamp                   |
 | `root`      | `MerkleRoot`       | Root of the transaction hashes merkle tree |
 
 
@@ -259,11 +259,12 @@ without the need of forking the blockchain.
 
 ## Metadata
 
-|    Field    |         Type        |                  Description                  |
-|-------------|---------------------|-----------------------------------------------|
-| `proof`     | `VRFOutput`         | Proof the stakeholder is the block owner      |
-| `r`         | `Seed`              | Random seed for the VRF                       |
-| `s`         | `Signature`         | Block owner signature                         |
+|    Field       |         Type        |                  Description                 |
+|----------------|---------------------|----------------------------------------------|
+| `proof`        | `VRFOutput`         | Proof the stakeholder is the block owner     |
+| `rand_seed`    | `Seed`              | Random seed for the VRF                      |
+| `signature`    | `Signature`         | Block owner signature                        |
+| `address`      | `Address`           | Block owner address                          |
 
 
 ## Streamlet Metadata
@@ -273,3 +274,13 @@ without the need of forking the blockchain.
 | `votes`     | `Vec<Vote>`         | Epoch votes for the block                     |
 | `notarized` | `bool`              | Block notarization flag                       |
 | `finalized` | `bool`              | Block finalization flag                       |
+
+## Participant
+
+|    Field      |         Type        |                  Description                  |
+|---------------|---------------------|-----------------------------------------------|
+| `public_key`  | `PublicKey`         | Node public key                               |
+| `address`     | `Address`           | Node wallet address                           |
+| `joined`      | `u64`               | Slot node joined the network                  |
+| `voted`       | `Option<u64>`       | Last slot node voted                          |
+| `quarantined` | `Option<u64>`       | Slot participant was quarantined by the node  |

+ 11 - 13
src/consensus/block.rs

@@ -2,13 +2,15 @@ use std::{fmt, io};
 
 use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
 use log::debug;
+use rand::rngs::OsRng;
 
 use super::{
     Metadata, StreamletMetadata, BLOCK_INFO_MAGIC_BYTES, BLOCK_MAGIC_BYTES, BLOCK_VERSION,
 };
 use crate::{
     crypto::{
-        address::Address, constants::MERKLE_DEPTH, merkle_node::MerkleNode, schnorr::Signature,
+        address::Address, constants::MERKLE_DEPTH, keypair::Keypair, merkle_node::MerkleNode,
+        schnorr::SchnorrSecret,
     },
     impl_vec, net,
     tx::Transaction,
@@ -86,7 +88,11 @@ impl Block {
     /// Generate the genesis block.
     pub fn genesis_block(genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Self {
         let header = Header::genesis_header(genesis_ts, genesis_data);
-        let metadata = Metadata::new(String::from("proof"), String::from("r"), String::from("s"));
+        // Signing the genesis data using a random keypair
+        let keypair = Keypair::random(&mut OsRng);
+        let signature = keypair.secret.sign(&genesis_data.as_bytes()[..]);
+        let address = Address::from(keypair.public);
+        let metadata = Metadata::new(String::from("proof"), String::from("r"), signature, address);
 
         Self::new(header.headerhash(), vec![], metadata)
     }
@@ -158,10 +164,6 @@ impl net::Message for BlockResponse {
 /// This struct represents a block proposal, used for consensus.
 #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
 pub struct BlockProposal {
-    /// Block signature
-    pub signature: Signature,
-    /// Leader address
-    pub address: Address,
     /// Block data
     pub block: BlockInfo,
 }
@@ -169,23 +171,19 @@ pub struct BlockProposal {
 impl BlockProposal {
     #[allow(clippy::too_many_arguments)]
     pub fn new(
-        signature: Signature,
-        address: Address,
         header: Header,
         txs: Vec<Transaction>,
         metadata: Metadata,
         sm: StreamletMetadata,
     ) -> Self {
         let block = BlockInfo::new(header, txs, metadata, sm);
-        Self { signature, address, block }
+        Self { block }
     }
 }
 
 impl PartialEq for BlockProposal {
     fn eq(&self, other: &Self) -> bool {
-        self.signature == other.signature &&
-            self.address == other.address &&
-            self.block.header == other.block.header &&
+        self.block.header == other.block.header &&
             self.block.txs == other.block.txs &&
             self.block.metadata == other.block.metadata
     }
@@ -195,7 +193,7 @@ impl fmt::Display for BlockProposal {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_fmt(format_args!(
             "BlockProposal {{ leader: {}, hash: {}, epoch: {}, slot: {}, txs: {} }}",
-            self.address,
+            self.block.metadata.address,
             self.block.header.headerhash(),
             self.block.header.epoch,
             self.block.header.slot,

+ 9 - 4
src/consensus/metadata.rs

@@ -1,5 +1,8 @@
 use super::{Participant, Vote};
-use crate::util::serial::{SerialDecodable, SerialEncodable};
+use crate::{
+    crypto::{address::Address, schnorr::Signature},
+    util::serial::{SerialDecodable, SerialEncodable},
+};
 
 /// This struct represents [`Block`](super::Block) information used by the Ouroboros
 /// Praos consensus protocol.
@@ -10,12 +13,14 @@ pub struct Metadata {
     /// Random seed for VRF
     pub rand_seed: String,
     /// Block owner signature
-    pub signature: String,
+    pub signature: Signature,
+    /// Block owner address
+    pub address: Address,
 }
 
 impl Metadata {
-    pub fn new(proof: String, rand_seed: String, signature: String) -> Self {
-        Self { proof, rand_seed, signature }
+    pub fn new(proof: String, rand_seed: String, signature: Signature, address: Address) -> Self {
+        Self { proof, rand_seed, signature, address }
     }
 }
 

+ 19 - 26
src/consensus/state.rs

@@ -287,20 +287,14 @@ impl ValidatorState {
         let header =
             Header::new(prev_hash, self.slot_epoch(slot), slot, Timestamp::current_time(), root);
 
-        let metadata = Metadata::new(String::from("proof"), String::from("r"), String::from("s"));
+        let signed_proposal = self.secret.sign(&header.headerhash().as_bytes()[..]);
 
-        let sm = StreamletMetadata::new(self.consensus.participants.values().cloned().collect());
+        let metadata =
+            Metadata::new(String::from("proof"), String::from("r"), signed_proposal, self.address);
 
-        let signed_proposal = self.secret.sign(&header.headerhash().as_bytes()[..]);
+        let sm = StreamletMetadata::new(self.consensus.participants.values().cloned().collect());
 
-        Ok(Some(BlockProposal::new(
-            signed_proposal,
-            self.address,
-            header,
-            unproposed_txs,
-            metadata,
-            sm,
-        )))
+        Ok(Some(BlockProposal::new(header, unproposed_txs, metadata, sm)))
     }
 
     /// Retrieve all unconfirmed transactions not proposed in previous blocks
@@ -370,20 +364,19 @@ impl ValidatorState {
         self.refresh_participants()?;
 
         let leader = self.slot_leader();
-        if leader.address != proposal.address {
+        if leader.address != proposal.block.metadata.address {
             warn!(
                 "Received proposal not from slot leader ({}), but from ({})",
-                leader.address.to_string(),
-                proposal.address.to_string()
+                leader.address, proposal.block.metadata.address
             );
             return Ok(None)
         }
 
-        if !leader
-            .public_key
-            .verify(proposal.block.header.headerhash().as_bytes(), &proposal.signature)
-        {
-            warn!("Proposer ({}) signature could not be verified", proposal.address.to_string());
+        if !leader.public_key.verify(
+            proposal.block.header.headerhash().as_bytes(),
+            &proposal.block.metadata.signature,
+        ) {
+            warn!("Proposer ({}) signature could not be verified", proposal.block.metadata.address);
             return Ok(None)
         }
 
@@ -529,7 +522,7 @@ impl ValidatorState {
         match self.consensus.participants.get(&vote.address) {
             Some(participant) => {
                 let mut participant = participant.clone();
-                let va = vote.address.to_string();
+                let va = vote.address;
                 if current_slot <= participant.joined {
                     warn!("consensus: Voter ({}) joined after current slot.", va);
                     return Ok((false, None))
@@ -563,7 +556,7 @@ impl ValidatorState {
                 self.consensus.participants.insert(participant.address, participant);
             }
             None => {
-                warn!("consensus: Voter ({}) is not a participant!", vote.address.to_string());
+                warn!("consensus: Voter ({}) is not a participant!", vote.address);
                 return Ok((false, None))
             }
         }
@@ -792,7 +785,7 @@ impl ValidatorState {
 
         debug!(
             "refresh_participants(): Node {:?} checking slots: previous - {:?}, last - {:?}, previous from last - {:?}",
-            self.address.to_string(), previous_slot, last_slot, previous_from_last_slot
+            self.address, previous_slot, last_slot, previous_from_last_slot
         );
 
         let leader = self.slot_leader();
@@ -802,7 +795,7 @@ impl ValidatorState {
                     if (current - slot) > QUARANTINE_DURATION {
                         warn!(
                             "refresh_participants(): Removing participant: {:?} (joined {:?}, voted {:?})",
-                            participant.address.to_string(),
+                            participant.address,
                             participant.joined,
                             participant.voted
                         );
@@ -815,7 +808,7 @@ impl ValidatorState {
                     if participant.address == leader.address {
                         debug!(
                             "refresh_participants(): Quaranteening leader: {:?} (joined {:?}, voted {:?})",
-                            participant.address.to_string(),
+                            participant.address,
                             participant.joined,
                             participant.voted
                         );
@@ -827,7 +820,7 @@ impl ValidatorState {
                             if slot < last_slot {
                                 warn!(
                                     "refresh_participants(): Quaranteening participant: {:?} (joined {:?}, voted {:?})",
-                                    participant.address.to_string(),
+                                    participant.address,
                                     participant.joined,
                                     participant.voted
                                 );
@@ -841,7 +834,7 @@ impl ValidatorState {
                             {
                                 warn!(
                                     "refresh_participants(): Quaranteening participant: {:?} (joined {:?}, voted {:?})",
-                                    participant.address.to_string(),
+                                    participant.address,
                                     participant.joined,
                                     participant.voted
                                 );