From 1bf3283b3ed65c242a366ecba9c390e75330fd2d Mon Sep 17 00:00:00 2001 From: Thibault Martinez Date: Wed, 21 Jun 2023 12:13:20 +0200 Subject: [PATCH] Add slot related types (#642) * Add SlotIndex * Slot module * Add SlotCommitmentId * Add SlotCommitment::id * Add RootsId * Add SlotCommitment * Add deref * Added getters * Use internal index * Update sdk/src/types/block/slot/commitment.rs Co-authored-by: Thoralf-M <46689931+Thoralf-M@users.noreply.github.com> * Update sdk/src/types/block/slot/commitment.rs Co-authored-by: Thoralf-M <46689931+Thoralf-M@users.noreply.github.com> --------- Co-authored-by: Thoralf-M <46689931+Thoralf-M@users.noreply.github.com> --- sdk/src/types/block/mod.rs | 2 + sdk/src/types/block/slot/commitment.rs | 75 +++++++++++++++++++++++ sdk/src/types/block/slot/commitment_id.rs | 7 +++ sdk/src/types/block/slot/index.rs | 18 ++++++ sdk/src/types/block/slot/mod.rs | 9 +++ sdk/src/types/block/slot/roots_id.rs | 7 +++ 6 files changed, 118 insertions(+) create mode 100644 sdk/src/types/block/slot/commitment.rs create mode 100644 sdk/src/types/block/slot/commitment_id.rs create mode 100644 sdk/src/types/block/slot/index.rs create mode 100644 sdk/src/types/block/slot/mod.rs create mode 100644 sdk/src/types/block/slot/roots_id.rs diff --git a/sdk/src/types/block/mod.rs b/sdk/src/types/block/mod.rs index 980c11be50..8489480978 100644 --- a/sdk/src/types/block/mod.rs +++ b/sdk/src/types/block/mod.rs @@ -33,6 +33,8 @@ pub mod rand; pub mod semantic; /// A module that provides types and syntactic validations of signatures. pub mod signature; +/// A module that provides types and syntactic validations of slots. +pub mod slot; /// A module that provides types and syntactic validations of unlocks. pub mod unlock; diff --git a/sdk/src/types/block/slot/commitment.rs b/sdk/src/types/block/slot/commitment.rs new file mode 100644 index 0000000000..d4d9b65f98 --- /dev/null +++ b/sdk/src/types/block/slot/commitment.rs @@ -0,0 +1,75 @@ +// Copyright 2023 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use crypto::hashes::{blake2b::Blake2b256, Digest}; +use packable::{packer::SlicePacker, Packable, PackableExt}; + +use crate::types::block::slot::{RootsId, SlotCommitmentId, SlotIndex}; + +/// Contains a summary of a slot. +/// It is linked to the commitment of the previous slot, which forms a commitment chain. +#[derive(Clone, Debug, Eq, PartialEq, Hash, derive_more::From, Packable)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SlotCommitment { + /// The slot index of this commitment. + /// It is calculated based on genesis timestamp and the duration of a slot. + index: SlotIndex, + /// The commitment ID of the previous slot. + previous_slot_commitment_id: SlotCommitmentId, + /// A BLAKE2b-256 hash of concatenating multiple sparse merkle tree roots of a slot. + roots_id: RootsId, + /// The sum of previous slot commitment cumulative weight and weight of issuers of accepted blocks within this + /// slot. It is just an indication of "committed into" this slot, and can not strictly be used for evaluating + /// the switching of a chain. + cumulative_weight: u64, +} + +impl SlotCommitment { + /// Creates a new [`SlotCommitment`]. + pub fn new( + index: SlotIndex, + previous_slot_commitment_id: SlotCommitmentId, + roots_id: RootsId, + cumulative_weight: u64, + ) -> Self { + Self { + index, + previous_slot_commitment_id, + roots_id, + cumulative_weight, + } + } + + /// Returns the index of the [`SlotCommitment`]. + pub fn index(&self) -> SlotIndex { + self.index + } + + /// Returns the previous slot commitment ID of the [`SlotCommitment`]. + pub fn previous_slot_commitment_id(&self) -> &SlotCommitmentId { + &self.previous_slot_commitment_id + } + + /// Returns the [`RootsId`] of the [`SlotCommitment`]. + pub fn roots_id(&self) -> &RootsId { + &self.roots_id + } + + /// Returns the cumulative weight of the [`SlotCommitment`]. + pub fn cumulative_weight(&self) -> u64 { + self.cumulative_weight + } + + /// Derives the [`SlotCommitmentId`] of the [`SlotCommitment`]. + pub fn id(&self) -> SlotCommitmentId { + let mut bytes = [0u8; SlotCommitmentId::LENGTH]; + let mut packer = SlicePacker::new(&mut bytes); + let hash: [u8; 32] = Blake2b256::digest(self.pack_to_vec()).into(); + + // PANIC: packing to an array of bytes can't fail. + hash.pack(&mut packer).unwrap(); + self.index.pack(&mut packer).unwrap(); + + SlotCommitmentId::from(bytes) + } +} diff --git a/sdk/src/types/block/slot/commitment_id.rs b/sdk/src/types/block/slot/commitment_id.rs new file mode 100644 index 0000000000..9c8380e2b7 --- /dev/null +++ b/sdk/src/types/block/slot/commitment_id.rs @@ -0,0 +1,7 @@ +// Copyright 2023 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +impl_id!(pub SlotCommitmentId, 40, "Identifier of a slot commitment."); + +#[cfg(feature = "serde")] +string_serde_impl!(SlotCommitmentId); diff --git a/sdk/src/types/block/slot/index.rs b/sdk/src/types/block/slot/index.rs new file mode 100644 index 0000000000..6a4b902c22 --- /dev/null +++ b/sdk/src/types/block/slot/index.rs @@ -0,0 +1,18 @@ +// Copyright 2023 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use derive_more::{Deref, From}; + +/// Timeline is divided into slots, and each slot has a corresponding slot index. +/// To calculate the slot index of a timestamp, `genesisTimestamp` and the duration of a slot are needed. +/// The slot index of timestamp `ts` is `(ts - genesisTimestamp)/duration + 1`. +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, From, Deref, packable::Packable)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SlotIndex(u64); + +impl SlotIndex { + /// Creates a new [`SlotIndex`]. + pub fn new(index: u64) -> Self { + Self::from(index) + } +} diff --git a/sdk/src/types/block/slot/mod.rs b/sdk/src/types/block/slot/mod.rs new file mode 100644 index 0000000000..d3a21fc517 --- /dev/null +++ b/sdk/src/types/block/slot/mod.rs @@ -0,0 +1,9 @@ +// Copyright 2023 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +mod commitment; +mod commitment_id; +mod index; +mod roots_id; + +pub use self::{commitment::SlotCommitment, commitment_id::SlotCommitmentId, index::SlotIndex, roots_id::RootsId}; diff --git a/sdk/src/types/block/slot/roots_id.rs b/sdk/src/types/block/slot/roots_id.rs new file mode 100644 index 0000000000..bb3e7907ae --- /dev/null +++ b/sdk/src/types/block/slot/roots_id.rs @@ -0,0 +1,7 @@ +// Copyright 2023 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +impl_id!(pub RootsId, 32, "A BLAKE2b-256 hash of concatenating multiple sparse merkle tree roots of a slot."); + +#[cfg(feature = "serde")] +string_serde_impl!(RootsId);