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

feat: add block issuer feature #984

Merged
merged 42 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a2b493e
init
qrayven Jul 28, 2023
bf9801c
init
qrayven Jul 28, 2023
101a95f
Merge branch '2.0' into pr/qrayven/889
qrayven Aug 1, 2023
98f0719
feat: block issuer feature
qrayven Aug 1, 2023
ab28953
add rand
qrayven Aug 1, 2023
5419ba2
some fixes
qrayven Aug 1, 2023
d5cb04c
fix more issues
qrayven Aug 1, 2023
ba84964
change order in rand
qrayven Aug 1, 2023
6818f91
fix no_std for box
qrayven Aug 1, 2023
e289900
fix no_std for macro
qrayven Aug 1, 2023
11b9c0d
remove unnecessary imports
qrayven Aug 1, 2023
cbba160
too much
qrayven Aug 1, 2023
6f81054
Merge branch '2.0' into pr/qrayven/889
qrayven Aug 1, 2023
1717a61
fix error order
qrayven Aug 1, 2023
d591eaa
addressing comments
qrayven Aug 2, 2023
7f35d52
Update sdk/src/types/block/rand/public_key.rs
qrayven Aug 2, 2023
dc41f9a
Update sdk/src/types/block/output/feature/block_issuer.rs
qrayven Aug 2, 2023
e1af229
Update sdk/src/types/block/output/feature/block_issuer.rs
qrayven Aug 2, 2023
bae2972
Update sdk/src/types/block/output/feature/block_issuer.rs
qrayven Aug 2, 2023
0d8df8a
fixing issues
qrayven Aug 3, 2023
7464531
unused imports
qrayven Aug 3, 2023
ef3fb47
Merge branch '2.0' into pr/qrayven/889
qrayven Aug 3, 2023
e86edda
remove alloc
qrayven Aug 3, 2023
8d525e6
add string ser-de for slot index
qrayven Aug 3, 2023
0ec5cfa
fmt
qrayven Aug 3, 2023
4d6be36
clippyt
qrayven Aug 3, 2023
802bc2b
Update sdk/src/types/block/rand/output/feature.rs
qrayven Aug 3, 2023
4d365ce
Update sdk/src/types/block/output/feature/block_issuer.rs
qrayven Aug 3, 2023
b77339d
Update sdk/src/types/block/output/feature/block_issuer.rs
qrayven Aug 3, 2023
d347906
address issues
qrayven Aug 3, 2023
68fdc0e
use btreeset
qrayven Aug 3, 2023
b3c23b9
fix
qrayven Aug 3, 2023
ec16552
Merge branch '2.0' into pr/qrayven/889
Aug 3, 2023
2e1e887
Merge branch '2.0' into pr/qrayven/889
qrayven Aug 4, 2023
eb096b5
add uniq and sorted public keys
qrayven Aug 4, 2023
99690b1
fmt
qrayven Aug 4, 2023
ccc91e7
fmt
qrayven Aug 4, 2023
8d2b52b
clippy
qrayven Aug 4, 2023
e7125ec
Merge branch '2.0' into pr/qrayven/889
qrayven Aug 4, 2023
c21406a
fix non-std
qrayven Aug 4, 2023
0c83442
fmt
qrayven Aug 4, 2023
a54d406
remove default
qrayven Aug 4, 2023
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
2 changes: 0 additions & 2 deletions sdk/src/types/block/address/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ impl core::fmt::Debug for AccountAddress {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/address/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ impl core::fmt::Debug for Ed25519Address {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/address/nft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ impl core::fmt::Debug for NftAddress {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/context_input/block_issuance_credit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ impl BlockIssuanceCreditContextInput {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/context_input/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ impl CommitmentContextInput {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/context_input/reward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ impl RewardContextInput {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
8 changes: 6 additions & 2 deletions sdk/src/types/block/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ use super::mana::AllotmentCount;
use crate::types::block::{
input::UtxoInput,
output::{
feature::FeatureCount, unlock_condition::UnlockConditionCount, AccountId, ChainId, MetadataFeatureLength,
NativeTokenCount, NftId, OutputIndex, StateMetadataLength, TagFeatureLength,
feature::{FeatureCount, PublicKeyCount},
unlock_condition::UnlockConditionCount,
AccountId, ChainId, MetadataFeatureLength, NativeTokenCount, NftId, OutputIndex, StateMetadataLength,
TagFeatureLength,
},
payload::{InputCount, OutputCount, TagLength, TaggedDataLength},
unlock::{UnlockCount, UnlockIndex},
Expand Down Expand Up @@ -70,6 +72,7 @@ pub enum Error {
InvalidParentCount,
InvalidPayloadKind(u32),
InvalidPayloadLength { expected: usize, actual: usize },
InvalidPublicKeyCount(<PublicKeyCount as TryFrom<usize>>::Error),
InvalidReferenceIndex(<UnlockIndex as TryFrom<u16>>::Error),
InvalidSignature,
InvalidSignatureKind(u8),
Expand Down Expand Up @@ -203,6 +206,7 @@ impl fmt::Display for Error {
Self::InvalidPayloadLength { expected, actual } => {
write!(f, "invalid payload length: expected {expected} but got {actual}")
}
Self::InvalidPublicKeyCount(count) => write!(f, "invalid public key count: {count}"),
Self::InvalidReferenceIndex(index) => write!(f, "invalid reference index: {index}"),
Self::InvalidSignature => write!(f, "invalid signature provided"),
Self::InvalidSignatureKind(k) => write!(f, "invalid signature kind: {k}"),
Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/input/utxo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ impl core::fmt::Debug for UtxoInput {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/types/block/macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ macro_rules! impl_serde_typed_dto {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let dto = <$dto>::deserialize(d)?;
if dto.kind != Self::KIND {
return Err(serde::de::Error::custom(format!(
return Err(serde::de::Error::custom(alloc::format!(
"invalid {} type: expected {}, found {}",
$type_str,
Self::KIND,
Expand Down
105 changes: 105 additions & 0 deletions sdk/src/types/block/output/feature/block_issuer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use alloc::boxed::Box;

use packable::{bounded::BoundedU8, prefix::BoxedSlicePrefix};

use crate::types::block::{public_key::PublicKey, slot::SlotIndex, Error};

pub(crate) type PublicKeyCount =
BoundedU8<{ BlockIssuerFeature::KEY_COUNT_MIN }, { BlockIssuerFeature::KEY_COUNT_MAX }>;

/// This feature defines the public keys with which a signature from the containing
/// account's Block Issuance Credit can be verified in order to burn Mana.
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, packable::Packable)]
#[packable(unpack_error = Error)]
pub struct BlockIssuerFeature {
/// The slot index at which the Block Issuer Feature expires and can be removed.
expiry_slot: SlotIndex,
/// The Block Issuer Keys.
#[packable(unpack_error_with = |e| e.unwrap_item_err_or_else(|p| Error::InvalidPublicKeyCount(p.into())))]
keys: BoxedSlicePrefix<PublicKey, PublicKeyCount>,
}

impl BlockIssuerFeature {
/// The [`Feature`](crate::types::block::output::Feature) kind of a [`BlockIssuerFeature`].
pub const KIND: u8 = 4;
/// Minimum number of [`PublicKey`]s in a [`BlockIssuerFeature`].
pub const KEY_COUNT_MIN: u8 = 1;
/// Maximum number of [`PublicKey`]s in a [`BlockIssuerFeature`].
pub const KEY_COUNT_MAX: u8 = 128;

/// Creates a new [`BlockIssuerFeature`].
#[inline(always)]
pub fn new(expiry_slot: impl Into<SlotIndex>, keys: impl Into<Box<[PublicKey]>>) -> Result<Self, Error> {
let keys: Box<[PublicKey]> = keys.into();

Ok(Self {
expiry_slot: expiry_slot.into(),
keys: keys.try_into().map_err(Error::InvalidPublicKeyCount)?,
})
}

/// Returns the Slot Index at which the Block Issuer Feature expires and can be removed.
pub fn expiry_slot(&self) -> SlotIndex {
self.expiry_slot
}

/// Returns the Block Issuer Keys.
pub fn keys(&self) -> &[PublicKey] {
&self.keys
}
}

mod dto {
use alloc::vec::Vec;

use serde::{Deserialize, Serialize};

use super::BlockIssuerFeature;
use crate::{
types::block::{
public_key::{dto::PublicKeyDto, PublicKey},
Error,
},
utils::serde::string,
};

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct BlockIssuerFeatureDto {
#[serde(rename = "type")]
kind: u8,
#[serde(with = "string")]
expiry_slot: u64,
DaughterOfMars marked this conversation as resolved.
Show resolved Hide resolved
#[serde(skip_serializing_if = "Vec::is_empty", default)]
Thoralf-M marked this conversation as resolved.
Show resolved Hide resolved
keys: Vec<PublicKeyDto>,
}

impl From<&BlockIssuerFeature> for BlockIssuerFeatureDto {
fn from(value: &BlockIssuerFeature) -> Self {
Self {
kind: BlockIssuerFeature::KIND,
expiry_slot: value.expiry_slot.into(),
keys: value.keys.iter().map(|key| key.into()).collect(),
}
}
}

impl TryFrom<BlockIssuerFeatureDto> for BlockIssuerFeature {
type Error = Error;

fn try_from(value: BlockIssuerFeatureDto) -> Result<Self, Self::Error> {
let keys = value
.keys
.into_iter()
.map(PublicKey::try_from)
.collect::<Result<Vec<PublicKey>, Error>>()?;

Self::new(value.expiry_slot, keys)
}
}

impl_serde_typed_dto!(BlockIssuerFeature, BlockIssuerFeatureDto, "block issuer feature");
}
2 changes: 0 additions & 2 deletions sdk/src/types/block/output/feature/issuer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ impl IssuerFeature {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/types/block/output/feature/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl core::fmt::Debug for MetadataFeature {
}

mod dto {
use alloc::{borrow::Cow, format};
use alloc::borrow::Cow;

use serde::{Deserialize, Serialize};

Expand Down
34 changes: 32 additions & 2 deletions sdk/src/types/block/output/feature/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2021-2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

mod block_issuer;
mod issuer;
mod metadata;
mod sender;
Expand All @@ -15,9 +16,10 @@ use iterator_sorted::is_unique_sorted;
use packable::{bounded::BoundedU8, prefix::BoxedSlicePrefix, Packable};

pub use self::{
issuer::IssuerFeature, metadata::MetadataFeature, sender::SenderFeature, staking::StakingFeature, tag::TagFeature,
block_issuer::BlockIssuerFeature, issuer::IssuerFeature, metadata::MetadataFeature, sender::SenderFeature,
staking::StakingFeature, tag::TagFeature,
};
pub(crate) use self::{metadata::MetadataFeatureLength, tag::TagFeatureLength};
pub(crate) use self::{block_issuer::PublicKeyCount, metadata::MetadataFeatureLength, tag::TagFeatureLength};
use crate::types::block::{create_bitflags, Error};

///
Expand All @@ -38,6 +40,9 @@ pub enum Feature {
/// A tag feature.
#[packable(tag = TagFeature::KIND)]
Tag(TagFeature),
/// A block issuer feature.
#[packable(tag = BlockIssuerFeature::KIND)]
BlockIssuer(BlockIssuerFeature),
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
/// A staking feature.
#[packable(tag = StakingFeature::KIND)]
Staking(StakingFeature),
Expand All @@ -62,6 +67,7 @@ impl core::fmt::Debug for Feature {
Self::Issuer(feature) => feature.fmt(f),
Self::Metadata(feature) => feature.fmt(f),
Self::Tag(feature) => feature.fmt(f),
Self::BlockIssuer(feature) => feature.fmt(f),
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
Self::Staking(feature) => feature.fmt(f),
}
}
Expand All @@ -75,6 +81,7 @@ impl Feature {
Self::Issuer(_) => IssuerFeature::KIND,
Self::Metadata(_) => MetadataFeature::KIND,
Self::Tag(_) => TagFeature::KIND,
Self::BlockIssuer(_) => BlockIssuerFeature::KIND,
Self::Staking(_) => StakingFeature::KIND,
}
}
Expand All @@ -86,6 +93,7 @@ impl Feature {
Self::Issuer(_) => FeatureFlags::ISSUER,
Self::Metadata(_) => FeatureFlags::METADATA,
Self::Tag(_) => FeatureFlags::TAG,
Self::BlockIssuer(_) => FeatureFlags::BLOCK_ISSUER,
Self::Staking(_) => FeatureFlags::STAKING,
}
}
Expand Down Expand Up @@ -150,6 +158,21 @@ impl Feature {
}
}

/// Checks whether the feature is a [`BlockIssuerFeature`].
pub fn is_block_issuer(&self) -> bool {
matches!(self, Self::BlockIssuer(_))
}

/// Gets the feature as an actual [`BlockIssuerFeature`].
/// NOTE: Will panic if the feature is not a [`BlockIssuerFeature`].
pub fn as_block_issuer(&self) -> &BlockIssuerFeature {
if let Self::BlockIssuer(feature) = self {
feature
} else {
panic!("invalid downcast of non-BlockIssuerFeature");
}
}

/// Checks whether the feature is a [`StakingFeature`].
pub fn is_staking(&self) -> bool {
matches!(self, Self::Staking(_))
Expand All @@ -175,6 +198,7 @@ create_bitflags!(
(ISSUER, IssuerFeature),
(METADATA, MetadataFeature),
(TAG, TagFeature),
(BLOCK_ISSUER, BlockIssuerFeature),
(STAKING, StakingFeature),
]
);
Expand Down Expand Up @@ -270,6 +294,11 @@ impl Features {
self.get(TagFeature::KIND).map(Feature::as_tag)
}

/// Gets a reference to a [`BlockIssuerFeature`], if any.
pub fn block_issuer(&self) -> Option<&BlockIssuerFeature> {
self.get(BlockIssuerFeature::KIND).map(Feature::as_block_issuer)
}

/// Gets a reference to a [`StakingFeature`], if any.
pub fn staking(&self) -> Option<&StakingFeature> {
self.get(StakingFeature::KIND).map(Feature::as_staking)
Expand Down Expand Up @@ -311,6 +340,7 @@ mod test {
FeatureFlags::ISSUER,
FeatureFlags::METADATA,
FeatureFlags::TAG,
FeatureFlags::BLOCK_ISSUER,
FeatureFlags::STAKING
]
);
Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/output/feature/sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ impl SenderFeature {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/output/feature/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ impl StakingFeature {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/types/block/output/feature/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl core::fmt::Debug for TagFeature {
}

mod dto {
use alloc::{borrow::Cow, format};
use alloc::borrow::Cow;

use serde::{Deserialize, Serialize};

Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/output/token_scheme/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ fn verify_supply(minted_tokens: &U256, melted_tokens: &U256, maximum_supply: &U2
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/output/unlock_condition/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ impl AddressUnlockCondition {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
2 changes: 0 additions & 2 deletions sdk/src/types/block/output/unlock_condition/expiration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ fn verify_timestamp<const VERIFY: bool>(timestamp: &u32, _: &()) -> Result<(), E
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ impl GovernorAddressUnlockCondition {
}

mod dto {
use alloc::format;

use serde::{Deserialize, Serialize};

use super::*;
Expand Down
Loading
Loading