Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Milestone changes (TIP-29) #1347

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ coverage/
*.key

# bee-node
bee-node/config.toml
bee-node/config.json
bee-node/snapshots/
bee-node/storage/
bee-node/*.log
bee-node/bee-node/config.toml
bee-node/bee-node/config.json
bee-node/bee-node/snapshots/
bee-node/bee-node/storage/
bee-node/bee-node/*.log

# mdBook
book
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ pub(crate) async fn white_flag<B: StorageBackend>(
}
}

// TODO
let mut metadata = WhiteFlagMetadata::new(index, 0);
// TODO Actually pass the previous milestone id ?
let mut metadata = WhiteFlagMetadata::new(index, 0, None);

// Wait for either all parents to get solid or the timeout to expire.
let response = match timeout(
Expand All @@ -176,7 +176,7 @@ pub(crate) async fn white_flag<B: StorageBackend>(
.map_err(|e| reject::custom(CustomRejection::BadRequest(e.to_string())))?;

Ok(warp::reply::json(&WhiteFlagResponse {
merkle_tree_hash: prefix_hex::encode(metadata.merkle_proof()),
merkle_tree_hash: prefix_hex::encode(metadata.applied_merkle_proof()),
}))
}
Err(_) => {
Expand Down
2 changes: 1 addition & 1 deletion bee-api/bee-rest-api/src/endpoints/routes/health.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub async fn is_healthy<B: StorageBackend>(tangle: &Tangle<B>, peer_manager: &Pe
.duration_since(UNIX_EPOCH)
.expect("Clock may have gone backwards")
.as_secs() as u64)
.saturating_sub(milestone.timestamp())
.saturating_sub(milestone.timestamp().into())
<= HEALTH_MILESTONE_AGE_MAX
}
None => false,
Expand Down
4 changes: 2 additions & 2 deletions bee-api/bee-rest-api/src/types/dtos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

use bee_ledger::types::Receipt;
use bee_message::payload::dto::ReceiptPayloadDto;
use bee_message::payload::milestone::option::dto::ReceiptMilestoneOptionDto;
#[cfg(feature = "peer")]
use bee_protocol::types::peer::Peer;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -127,7 +127,7 @@ pub struct MetricsDto {
/// Describes a receipt.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ReceiptDto {
pub receipt: ReceiptPayloadDto,
pub receipt: ReceiptMilestoneOptionDto,
#[serde(rename = "milestoneIndex")]
pub milestone_index: u32,
}
Expand Down
2 changes: 1 addition & 1 deletion bee-api/bee-rest-api/src/types/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub struct StatusResponse {
#[serde(rename = "isHealthy")]
pub is_healthy: bool,
#[serde(rename = "latestMilestoneTimestamp")]
pub latest_milestone_timestamp: u64,
pub latest_milestone_timestamp: u32,
#[serde(rename = "latestMilestoneIndex")]
pub latest_milestone_index: u32,
#[serde(rename = "confirmedMilestoneIndex")]
Expand Down
8 changes: 4 additions & 4 deletions bee-ledger/src/types/receipt.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
// Copyright 2020-2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use bee_message::{constant::IOTA_SUPPLY, milestone::MilestoneIndex, payload::receipt::ReceiptPayload};
use bee_message::{constant::IOTA_SUPPLY, milestone::MilestoneIndex, payload::milestone::ReceiptMilestoneOption};

use crate::types::{error::Error, TreasuryOutput};

/// A type that wraps a receipt and the index of the milestone in which it was included.
#[derive(Clone, Debug, Eq, PartialEq, packable::Packable)]
pub struct Receipt {
inner: ReceiptPayload,
inner: ReceiptMilestoneOption,
included_in: MilestoneIndex,
}

impl Receipt {
/// Creates a new `Receipt`.
pub fn new(inner: ReceiptPayload, included_in: MilestoneIndex) -> Self {
pub fn new(inner: ReceiptMilestoneOption, included_in: MilestoneIndex) -> Self {
Self { inner, included_in }
}

/// Returns the inner receipt of the `Receipt`.
pub fn inner(&self) -> &ReceiptPayload {
pub fn inner(&self) -> &ReceiptMilestoneOption {
&self.inner
}

Expand Down
6 changes: 3 additions & 3 deletions bee-ledger/src/types/snapshot/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const SNAPSHOT_VERSION: u8 = 2;
#[derive(Clone)]
pub struct SnapshotHeader {
kind: SnapshotKind,
timestamp: u64,
timestamp: u32,
network_id: u64,
sep_index: MilestoneIndex,
ledger_index: MilestoneIndex,
Expand All @@ -33,7 +33,7 @@ impl SnapshotHeader {
}

/// Returns the timestamp of a `SnapshotHeader`.
pub fn timestamp(&self) -> u64 {
pub fn timestamp(&self) -> u32 {
self.timestamp
}

Expand Down Expand Up @@ -80,7 +80,7 @@ impl Packable for SnapshotHeader {
}

let kind = SnapshotKind::unpack::<_, VERIFY>(unpacker)?;
let timestamp = u64::unpack::<_, VERIFY>(unpacker).coerce()?;
let timestamp = u32::unpack::<_, VERIFY>(unpacker).coerce()?;
let network_id = u64::unpack::<_, VERIFY>(unpacker).coerce()?;
let sep_index = MilestoneIndex::unpack::<_, VERIFY>(unpacker).coerce()?;
let ledger_index = MilestoneIndex::unpack::<_, VERIFY>(unpacker).coerce()?;
Expand Down
8 changes: 4 additions & 4 deletions bee-ledger/src/types/snapshot/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct SnapshotInfo {
snapshot_index: MilestoneIndex,
entry_point_index: MilestoneIndex,
pruning_index: MilestoneIndex,
timestamp: u64,
timestamp: u32,
}

impl SnapshotInfo {
Expand All @@ -20,7 +20,7 @@ impl SnapshotInfo {
snapshot_index: MilestoneIndex,
entry_point_index: MilestoneIndex,
pruning_index: MilestoneIndex,
timestamp: u64,
timestamp: u32,
) -> Self {
Self {
network_id,
Expand Down Expand Up @@ -67,12 +67,12 @@ impl SnapshotInfo {
}

/// Returns the timestamp of a `SnapshotInfo`.
pub fn timestamp(&self) -> u64 {
pub fn timestamp(&self) -> u32 {
self.timestamp
}

/// Updates the timestamp of a `SnapshotInfo`.
pub fn update_timestamp(&mut self, timestamp: u64) {
pub fn update_timestamp(&mut self, timestamp: u32) {
self.timestamp = timestamp;
}
}
4 changes: 2 additions & 2 deletions bee-ledger/src/types/snapshot/milestone_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl Packable for MilestoneDiff {
MilestonePayload::KIND.pack(packer)?;
self.milestone.pack(packer)?;

if self.milestone.essence().receipt().is_some() {
if self.milestone.essence().options().receipt().is_some() {
if let Some((treasury_output, milestone_id)) = self.consumed_treasury.as_ref() {
milestone_id.pack(packer)?;
treasury_output.pack(packer)?;
Expand Down Expand Up @@ -106,7 +106,7 @@ impl Packable for MilestoneDiff {
)));
}

let consumed_treasury = if milestone.essence().receipt().is_some() {
let consumed_treasury = if milestone.essence().options().receipt().is_some() {
let milestone_id = MilestoneId::unpack::<_, VERIFY>(unpacker).coerce()?;
let amount = u64::unpack::<_, VERIFY>(unpacker).coerce()?;

Expand Down
44 changes: 32 additions & 12 deletions bee-ledger/src/workers/consensus/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

use std::collections::HashMap;

use bee_message::{milestone::MilestoneIndex, output::OutputId, semantic::ConflictReason, MessageId};
use bee_message::{
milestone::MilestoneIndex, output::OutputId, payload::milestone::MilestoneId, semantic::ConflictReason, MessageId,
};

use crate::types::{ConsumedOutput, CreatedOutput};

Expand All @@ -12,9 +14,13 @@ pub struct WhiteFlagMetadata {
/// Index of the confirmed milestone.
pub(crate) milestone_index: MilestoneIndex,
/// Timestamp of the confirmed milestone.
pub(crate) milestone_timestamp: u64,
/// The number of messages which were referenced by the confirmed milestone.
pub(crate) referenced_messages: usize,
pub(crate) milestone_timestamp: u32,
/// The id of the previous milestone.
pub(crate) previous_milestone_id: Option<MilestoneId>,
/// Whether the previous milestone has been found in the past cone of the current milestone.
pub(crate) found_previous_milestone: bool,
/// The messages which were referenced by the confirmed milestone.
pub(crate) referenced_messages: Vec<MessageId>,
/// The messages which were excluded because they did not include a transaction.
pub(crate) excluded_no_transaction_messages: Vec<MessageId>,
/// The messages which were excluded because they were conflicting with the ledger state.
Expand All @@ -25,28 +31,42 @@ pub struct WhiteFlagMetadata {
pub(crate) created_outputs: HashMap<OutputId, CreatedOutput>,
/// The outputs consumed within the confirmed milestone.
pub(crate) consumed_outputs: HashMap<OutputId, (CreatedOutput, ConsumedOutput)>,
/// The merkle proof of the milestone.
pub(crate) merkle_proof: Vec<u8>,
/// The confirmed merkle proof of the milestone.
pub(crate) confirmed_merkle_proof: Vec<u8>,
/// The applied merkle proof of the milestone.
pub(crate) applied_merkle_proof: Vec<u8>,
}

impl WhiteFlagMetadata {
/// Creates a new [`WhiteFlagMetadata`].
pub fn new(milestone_index: MilestoneIndex, milestone_timestamp: u64) -> WhiteFlagMetadata {
pub fn new(
milestone_index: MilestoneIndex,
milestone_timestamp: u32,
previous_milestone_id: Option<MilestoneId>,
) -> WhiteFlagMetadata {
WhiteFlagMetadata {
milestone_index,
milestone_timestamp,
referenced_messages: 0,
previous_milestone_id,
found_previous_milestone: false,
referenced_messages: Vec::new(),
excluded_no_transaction_messages: Vec::new(),
excluded_conflicting_messages: Vec::new(),
included_messages: Vec::new(),
created_outputs: HashMap::new(),
consumed_outputs: HashMap::new(),
merkle_proof: Vec::new(),
confirmed_merkle_proof: Vec::new(),
applied_merkle_proof: Vec::new(),
}
}

/// Returns the merkle proof of a [`WhiteFlagMetadata`].
pub fn merkle_proof(&self) -> &[u8] {
&self.merkle_proof
/// Returns the confirmed merkle proof of a [`WhiteFlagMetadata`].
pub fn confirmed_merkle_proof(&self) -> &[u8] {
&self.confirmed_merkle_proof
}

/// Returns the applied merkle proof of a [`WhiteFlagMetadata`].
pub fn applied_merkle_proof(&self) -> &[u8] {
&self.applied_merkle_proof
}
}
27 changes: 21 additions & 6 deletions bee-ledger/src/workers/consensus/white_flag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ fn apply_message<B: StorageBackend>(
message: &Message,
metadata: &mut WhiteFlagMetadata,
) -> Result<(), Error> {
metadata.referenced_messages += 1;
metadata.referenced_messages.push(*message_id);

match message.payload() {
Some(Payload::Transaction(transaction)) => {
Expand All @@ -147,6 +147,14 @@ fn apply_message<B: StorageBackend>(
conflict => metadata.excluded_conflicting_messages.push((*message_id, conflict)),
}
}
Some(Payload::Milestone(milestone)) => {
if let Some(previous_milestone_id) = metadata.previous_milestone_id {
if previous_milestone_id == milestone.id() {
metadata.found_previous_milestone = true;
}
}
metadata.excluded_no_transaction_messages.push(*message_id);
}
_ => metadata.excluded_no_transaction_messages.push(*message_id),
}

Expand Down Expand Up @@ -177,8 +185,10 @@ async fn traverse_past_cone<B: StorageBackend>(
if let Some(unvisited) = message.parents().iter().find(|p| !visited.contains(p)) {
message_ids.push(*unvisited);
} else {
apply_message(storage, message_id, &message, metadata)?;
visited.insert(*message_id);
if !visited.contains(message_id) {
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
apply_message(storage, message_id, &message, metadata)?;
visited.insert(*message_id);
}
message_ids.pop();
}
} else if !tangle.is_solid_entry_point(message_id).await {
Expand All @@ -202,15 +212,20 @@ pub async fn white_flag<B: StorageBackend>(
) -> Result<(), Error> {
traverse_past_cone(tangle, storage, message_ids.iter().rev().copied().collect(), metadata).await?;

metadata.merkle_proof = MerkleHasher::<Blake2b256>::new().digest(&metadata.included_messages);
metadata.confirmed_merkle_proof = MerkleHasher::<Blake2b256>::new().digest(&metadata.referenced_messages);
metadata.applied_merkle_proof = MerkleHasher::<Blake2b256>::new().digest(&metadata.included_messages);

if metadata.previous_milestone_id.is_some() && !metadata.found_previous_milestone {
return Err(Error::PreviousMilestoneNotFound);
}

if metadata.referenced_messages
if metadata.referenced_messages.len()
!= metadata.excluded_no_transaction_messages.len()
+ metadata.excluded_conflicting_messages.len()
+ metadata.included_messages.len()
{
return Err(Error::InvalidMessagesCount(
metadata.referenced_messages,
metadata.referenced_messages.len(),
metadata.excluded_no_transaction_messages.len(),
metadata.excluded_conflicting_messages.len(),
metadata.included_messages.len(),
Expand Down
Loading