|
|
@@ -11,6 +11,8 @@ use crate::{
|
|
|
};
|
|
|
|
|
|
/// This struct represents a tuple of the form (`st`, `sl`, txs`, `metadata`).
|
|
|
+/// The transactions here are stored as hashes, which serve as pointers to
|
|
|
+/// the actual transaction data in the blockchain database.
|
|
|
#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
|
|
|
pub struct Block {
|
|
|
/// Previous block hash
|
|
|
@@ -37,18 +39,27 @@ impl Block {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/// This struct represents a block proposal, used for consensus.
|
|
|
+/// Auxiliary structure used for blockchain syncing.
|
|
|
+#[derive(Debug, SerialEncodable, SerialDecodable)]
|
|
|
+pub struct BlockOrder {
|
|
|
+ /// Slot UID
|
|
|
+ pub sl: u64,
|
|
|
+ /// Blockhash of that slot
|
|
|
+ pub block: blake3::Hash,
|
|
|
+}
|
|
|
+
|
|
|
+impl net::Message for BlockOrder {
|
|
|
+ fn name() -> &'static str {
|
|
|
+ "blockorder"
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// Structure representing full block data.
|
|
|
#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
|
|
|
-pub struct BlockProposal {
|
|
|
- /// Leader public key
|
|
|
- pub public_key: PublicKey,
|
|
|
- /// Block signature
|
|
|
- pub signature: Signature,
|
|
|
- /// Leader ID
|
|
|
- pub id: u64,
|
|
|
+pub struct BlockInfo {
|
|
|
/// Previous block hash
|
|
|
pub st: blake3::Hash,
|
|
|
- /// Slot uid, generated by the beacon
|
|
|
+ /// Slot UID, generated by the beacon
|
|
|
pub sl: u64,
|
|
|
/// Transactions payload
|
|
|
pub txs: Vec<Tx>,
|
|
|
@@ -58,6 +69,52 @@ pub struct BlockProposal {
|
|
|
pub sm: StreamletMetadata,
|
|
|
}
|
|
|
|
|
|
+impl BlockInfo {
|
|
|
+ pub fn new(
|
|
|
+ st: blake3::Hash,
|
|
|
+ sl: u64,
|
|
|
+ txs: Vec<Tx>,
|
|
|
+ metadata: Metadata,
|
|
|
+ sm: StreamletMetadata,
|
|
|
+ ) -> Self {
|
|
|
+ Self { st, sl, txs, metadata, sm }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl net::Message for BlockInfo {
|
|
|
+ fn name() -> &'static str {
|
|
|
+ "blockinfo"
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl_vec!(BlockInfo);
|
|
|
+
|
|
|
+/// Auxiliary structure used for blockchain syncing
|
|
|
+#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
|
|
|
+pub struct BlockResponse {
|
|
|
+ /// Response blocks.
|
|
|
+ pub blocks: Vec<BlockInfo>,
|
|
|
+}
|
|
|
+
|
|
|
+impl net::Message for BlockResponse {
|
|
|
+ fn name() -> &'static str {
|
|
|
+ "blockresponse"
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// This struct represents a block proposal, used for consensus.
|
|
|
+#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
|
|
|
+pub struct BlockProposal {
|
|
|
+ /// Leader public key
|
|
|
+ pub public_key: PublicKey,
|
|
|
+ /// Block signature
|
|
|
+ pub signature: Signature,
|
|
|
+ /// Leader ID
|
|
|
+ pub id: u64,
|
|
|
+ /// Block data
|
|
|
+ pub block: BlockInfo,
|
|
|
+}
|
|
|
+
|
|
|
impl BlockProposal {
|
|
|
#[allow(clippy::too_many_arguments)]
|
|
|
pub fn new(
|
|
|
@@ -70,12 +127,13 @@ impl BlockProposal {
|
|
|
metadata: Metadata,
|
|
|
sm: StreamletMetadata,
|
|
|
) -> Self {
|
|
|
- Self { public_key, signature, id, st, sl, txs, metadata, sm }
|
|
|
+ let block = BlockInfo::new(st, sl, txs, metadata, sm);
|
|
|
+ Self { public_key, signature, id, block }
|
|
|
}
|
|
|
|
|
|
/// Produce proposal hash using `st`, `sl`, `txs`, and `metadata`.
|
|
|
pub fn hash(&self) -> blake3::Hash {
|
|
|
- Self::to_proposal_hash(self.st, self.sl, &self.txs, &self.metadata)
|
|
|
+ Self::to_proposal_hash(self.block.st, self.block.sl, &self.block.txs, &self.block.metadata)
|
|
|
}
|
|
|
|
|
|
/// Generate a proposal hash using provided `st`, `sl`, `txs`, and `metadata`.
|
|
|
@@ -99,10 +157,10 @@ impl PartialEq for BlockProposal {
|
|
|
self.public_key == other.public_key &&
|
|
|
self.signature == other.signature &&
|
|
|
self.id == other.id &&
|
|
|
- self.st == other.st &&
|
|
|
- self.sl == other.sl &&
|
|
|
- self.txs == other.txs &&
|
|
|
- self.metadata == other.metadata
|
|
|
+ self.block.st == other.block.st &&
|
|
|
+ self.block.sl == other.block.sl &&
|
|
|
+ self.block.txs == other.block.txs &&
|
|
|
+ self.block.metadata == other.block.metadata
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -114,6 +172,12 @@ impl net::Message for BlockProposal {
|
|
|
|
|
|
impl_vec!(BlockProposal);
|
|
|
|
|
|
+impl From<BlockProposal> for BlockInfo {
|
|
|
+ fn from(block: BlockProposal) -> BlockInfo {
|
|
|
+ block.block
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/// This struct represents a sequence of block proposals.
|
|
|
#[derive(Debug, Clone, PartialEq, SerialEncodable, SerialDecodable)]
|
|
|
pub struct ProposalChain {
|
|
|
@@ -131,13 +195,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.st == self.genesis_block {
|
|
|
+ if proposal.block.st == self.genesis_block {
|
|
|
debug!("check_proposal(): Genesis block proposal provided.");
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
let prev_hash = previous.hash();
|
|
|
- if proposal.st != prev_hash || proposal.sl <= previous.sl {
|
|
|
+ if proposal.block.st != prev_hash || proposal.block.sl <= previous.block.sl {
|
|
|
debug!("check_proposal(): Provided proposal is invalid.");
|
|
|
return false
|
|
|
}
|
|
|
@@ -167,7 +231,7 @@ impl ProposalChain {
|
|
|
/// Proposals chain notarization check.
|
|
|
pub fn notarized(&self) -> bool {
|
|
|
for proposal in &self.proposals {
|
|
|
- if !proposal.sm.notarized {
|
|
|
+ if !proposal.block.sm.notarized {
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
@@ -177,3 +241,29 @@ impl ProposalChain {
|
|
|
}
|
|
|
|
|
|
impl_vec!(ProposalChain);
|
|
|
+
|
|
|
+/// Auxiliary structure used for forks syncing.
|
|
|
+#[derive(Debug, SerialEncodable, SerialDecodable)]
|
|
|
+pub struct ForkOrder {
|
|
|
+ /// Validator ID
|
|
|
+ pub id: u64,
|
|
|
+}
|
|
|
+
|
|
|
+impl net::Message for ForkOrder {
|
|
|
+ fn name() -> &'static str {
|
|
|
+ "forkorder"
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// Auxiliary structure used for forks syncing.
|
|
|
+#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
|
|
|
+pub struct ForkResponse {
|
|
|
+ /// Fork chains containing block proposals
|
|
|
+ pub proposals: Vec<ProposalChain>,
|
|
|
+}
|
|
|
+
|
|
|
+impl net::Message for ForkResponse {
|
|
|
+ fn name() -> &'static str {
|
|
|
+ "forkresponse"
|
|
|
+ }
|
|
|
+}
|