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

Remove TokenTag #1395

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
58 changes: 9 additions & 49 deletions bee-message/src/output/foundry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
feature_block::{verify_allowed_feature_blocks, FeatureBlock, FeatureBlockFlags, FeatureBlocks},
unlock_condition::{verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions},
ByteCost, ByteCostConfig, ChainId, FoundryId, NativeToken, NativeTokens, Output, OutputAmount,
OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, TokenId, TokenScheme, TokenTag,
OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, TokenId, TokenScheme,
},
semantic::{ConflictReason, ValidationContext},
unlock_block::UnlockBlock,
Expand All @@ -30,7 +30,6 @@ pub struct FoundryOutputBuilder {
amount: OutputBuilderAmount,
native_tokens: Vec<NativeToken>,
serial_number: u32,
token_tag: TokenTag,
token_scheme: TokenScheme,
unlock_conditions: Vec<UnlockCondition>,
feature_blocks: Vec<FeatureBlock>,
Expand All @@ -42,13 +41,11 @@ impl FoundryOutputBuilder {
pub fn new_with_amount(
amount: u64,
serial_number: u32,
token_tag: TokenTag,
token_scheme: TokenScheme,
) -> Result<FoundryOutputBuilder, Error> {
Self::new(
OutputBuilderAmount::Amount(amount.try_into().map_err(Error::InvalidOutputAmount)?),
serial_number,
token_tag,
token_scheme,
)
}
Expand All @@ -58,28 +55,24 @@ impl FoundryOutputBuilder {
pub fn new_with_minimum_storage_deposit(
byte_cost_config: ByteCostConfig,
serial_number: u32,
token_tag: TokenTag,
token_scheme: TokenScheme,
) -> Result<FoundryOutputBuilder, Error> {
Self::new(
OutputBuilderAmount::MinimumStorageDeposit(byte_cost_config),
serial_number,
token_tag,
token_scheme,
)
}

fn new(
amount: OutputBuilderAmount,
serial_number: u32,
token_tag: TokenTag,
token_scheme: TokenScheme,
) -> Result<FoundryOutputBuilder, Error> {
Ok(Self {
amount,
native_tokens: Vec::new(),
serial_number,
token_tag,
token_scheme,
unlock_conditions: Vec::new(),
feature_blocks: Vec::new(),
Expand Down Expand Up @@ -206,7 +199,6 @@ impl FoundryOutputBuilder {
amount: 1u64.try_into().map_err(Error::InvalidOutputAmount)?,
native_tokens: NativeTokens::new(self.native_tokens)?,
serial_number: self.serial_number,
token_tag: self.token_tag,
token_scheme: self.token_scheme,
unlock_conditions,
feature_blocks,
Expand Down Expand Up @@ -236,7 +228,6 @@ impl From<&FoundryOutput> for FoundryOutputBuilder {
amount: OutputBuilderAmount::Amount(output.amount),
native_tokens: output.native_tokens.to_vec(),
serial_number: output.serial_number,
token_tag: output.token_tag,
token_scheme: output.token_scheme.clone(),
unlock_conditions: output.unlock_conditions.to_vec(),
feature_blocks: output.feature_blocks.to_vec(),
Expand All @@ -255,8 +246,6 @@ pub struct FoundryOutput {
native_tokens: NativeTokens,
// The serial number of the foundry with respect to the controlling alias.
serial_number: u32,
// Data that is always the last 12 bytes of ID of the tokens produced by this foundry.
token_tag: TokenTag,
token_scheme: TokenScheme,
unlock_conditions: UnlockConditions,
feature_blocks: FeatureBlocks,
Expand All @@ -275,13 +264,8 @@ impl FoundryOutput {

/// Creates a new [`FoundryOutput`] with a provided amount.
#[inline(always)]
pub fn new_with_amount(
amount: u64,
serial_number: u32,
token_tag: TokenTag,
token_scheme: TokenScheme,
) -> Result<Self, Error> {
FoundryOutputBuilder::new_with_amount(amount, serial_number, token_tag, token_scheme)?.finish()
pub fn new_with_amount(amount: u64, serial_number: u32, token_scheme: TokenScheme) -> Result<Self, Error> {
FoundryOutputBuilder::new_with_amount(amount, serial_number, token_scheme)?.finish()
}

/// Creates a new [`FoundryOutput`] with a provided byte cost config.
Expand All @@ -290,27 +274,19 @@ impl FoundryOutput {
pub fn new_with_minimum_storage_deposit(
byte_cost_config: ByteCostConfig,
serial_number: u32,
token_tag: TokenTag,
token_scheme: TokenScheme,
) -> Result<Self, Error> {
FoundryOutputBuilder::new_with_minimum_storage_deposit(
byte_cost_config,
serial_number,
token_tag,
token_scheme,
)?
.finish()
FoundryOutputBuilder::new_with_minimum_storage_deposit(byte_cost_config, serial_number, token_scheme)?.finish()
}

/// Creates a new [`FoundryOutputBuilder`] with a provided amount.
#[inline(always)]
pub fn build_with_amount(
amount: u64,
serial_number: u32,
token_tag: TokenTag,
token_scheme: TokenScheme,
) -> Result<FoundryOutputBuilder, Error> {
FoundryOutputBuilder::new_with_amount(amount, serial_number, token_tag, token_scheme)
FoundryOutputBuilder::new_with_amount(amount, serial_number, token_scheme)
}

/// Creates a new [`FoundryOutputBuilder`] with a provided byte cost config.
Expand All @@ -319,10 +295,9 @@ impl FoundryOutput {
pub fn build_with_minimum_storage_deposit(
byte_cost_config: ByteCostConfig,
serial_number: u32,
token_tag: TokenTag,
token_scheme: TokenScheme,
) -> Result<FoundryOutputBuilder, Error> {
FoundryOutputBuilder::new_with_minimum_storage_deposit(byte_cost_config, serial_number, token_tag, token_scheme)
FoundryOutputBuilder::new_with_minimum_storage_deposit(byte_cost_config, serial_number, token_scheme)
}

///
Expand All @@ -343,12 +318,6 @@ impl FoundryOutput {
self.serial_number
}

///
#[inline(always)]
pub fn token_tag(&self) -> &TokenTag {
&self.token_tag
}

///
#[inline(always)]
pub fn token_scheme(&self) -> &TokenScheme {
Expand Down Expand Up @@ -390,7 +359,7 @@ impl FoundryOutput {

/// Returns the [`TokenId`] of the [`FoundryOutput`].
pub fn token_id(&self) -> TokenId {
TokenId::build(&self.id(), &self.token_tag)
TokenId::from(self.id())
}

///
Expand Down Expand Up @@ -459,7 +428,6 @@ impl StateTransitionVerifier for FoundryOutput {
) -> Result<(), StateTransitionError> {
if current_state.alias_address() != next_state.alias_address()
|| current_state.serial_number != next_state.serial_number
|| current_state.token_tag != next_state.token_tag
|| current_state.immutable_feature_blocks != next_state.immutable_feature_blocks
{
return Err(StateTransitionError::MutatedImmutableField);
Expand Down Expand Up @@ -558,7 +526,6 @@ impl Packable for FoundryOutput {
self.amount.pack(packer)?;
self.native_tokens.pack(packer)?;
self.serial_number.pack(packer)?;
self.token_tag.pack(packer)?;
self.token_scheme.pack(packer)?;
self.unlock_conditions.pack(packer)?;
self.feature_blocks.pack(packer)?;
Expand All @@ -573,7 +540,6 @@ impl Packable for FoundryOutput {
let amount = OutputAmount::unpack::<_, VERIFY>(unpacker).map_packable_err(Error::InvalidOutputAmount)?;
let native_tokens = NativeTokens::unpack::<_, VERIFY>(unpacker)?;
let serial_number = u32::unpack::<_, VERIFY>(unpacker).coerce()?;
let token_tag = TokenTag::unpack::<_, VERIFY>(unpacker).coerce()?;
let token_scheme = TokenScheme::unpack::<_, VERIFY>(unpacker)?;

let unlock_conditions = UnlockConditions::unpack::<_, VERIFY>(unpacker)?;
Expand Down Expand Up @@ -603,7 +569,6 @@ impl Packable for FoundryOutput {
amount,
native_tokens,
serial_number,
token_tag,
token_scheme,
unlock_conditions,
feature_blocks,
Expand All @@ -629,8 +594,8 @@ pub mod dto {
use crate::{
error::dto::DtoError,
output::{
feature_block::dto::FeatureBlockDto, native_token::dto::NativeTokenDto, token_id::dto::TokenTagDto,
token_scheme::dto::TokenSchemeDto, unlock_condition::dto::UnlockConditionDto,
feature_block::dto::FeatureBlockDto, native_token::dto::NativeTokenDto, token_scheme::dto::TokenSchemeDto,
unlock_condition::dto::UnlockConditionDto,
},
};

Expand All @@ -647,9 +612,6 @@ pub mod dto {
// The serial number of the foundry with respect to the controlling alias.
#[serde(rename = "serialNumber")]
pub serial_number: u32,
// Data that is always the last 12 bytes of ID of the tokens produced by this foundry.
#[serde(rename = "tokenTag")]
pub token_tag: TokenTagDto,
#[serde(rename = "tokenScheme")]
pub token_scheme: TokenSchemeDto,
#[serde(rename = "unlockConditions")]
Expand All @@ -667,7 +629,6 @@ pub mod dto {
amount: value.amount().to_string(),
native_tokens: value.native_tokens().iter().map(Into::into).collect::<_>(),
serial_number: value.serial_number(),
token_tag: TokenTagDto(value.token_tag().to_string()),
token_scheme: value.token_scheme().into(),
unlock_conditions: value.unlock_conditions().iter().map(Into::into).collect::<_>(),
feature_blocks: value.feature_blocks().iter().map(Into::into).collect::<_>(),
Expand All @@ -686,7 +647,6 @@ pub mod dto {
.parse::<u64>()
.map_err(|_| DtoError::InvalidField("amount"))?,
value.serial_number,
(&value.token_tag).try_into()?,
(&value.token_scheme).try_into()?,
)?;

Expand Down
8 changes: 7 additions & 1 deletion bee-message/src/output/foundry_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@ use packable::{packer::SlicePacker, Packable};

use crate::{
address::{Address, AliasAddress},
output::AliasId,
output::{AliasId, TokenId},
};

impl_id!(pub FoundryId, 38, "Defines the unique identifier of a foundry.");

#[cfg(feature = "serde")]
string_serde_impl!(FoundryId);

impl From<TokenId> for FoundryId {
fn from(token_id: TokenId) -> Self {
FoundryId::new(*token_id)
}
}

impl FoundryId {
/// Builds a new [`FoundryId`] from its components.
pub fn build(alias_address: &AliasAddress, serial_number: u32, token_scheme_kind: u8) -> Self {
Expand Down
2 changes: 1 addition & 1 deletion bee-message/src/output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub use self::{
nft_id::NftId,
output_id::OutputId,
state_transition::{StateTransitionError, StateTransitionVerifier},
token_id::{TokenId, TokenTag},
token_id::TokenId,
token_scheme::{SimpleTokenScheme, TokenScheme},
treasury::TreasuryOutput,
unlock_condition::{UnlockCondition, UnlockConditions},
Expand Down
55 changes: 4 additions & 51 deletions bee-message/src/output/token_id.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,16 @@
// Copyright 2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use packable::{packer::SlicePacker, Packable};

use crate::output::FoundryId;

impl_id!(pub TokenTag, 12, "TODO.");

#[cfg(feature = "serde")]
string_serde_impl!(TokenTag);

impl_id!(pub TokenId, 50, "TODO.");
impl_id!(pub TokenId, 38, "TODO.");

#[cfg(feature = "serde")]
string_serde_impl!(TokenId);

impl TokenId {
/// Builds a new [`TokenId`] from its components.
pub fn build(foundry_id: &FoundryId, token_tag: &TokenTag) -> Self {
let mut bytes = [0u8; TokenId::LENGTH];
let mut packer = SlicePacker::new(&mut bytes);

// PANIC: packing to an array of the correct length can't fail.
foundry_id.pack(&mut packer).unwrap();
token_tag.pack(&mut packer).unwrap();

TokenId::new(bytes)
}

/// Returns the [`FoundryId`] of the [`TokenId`].
pub fn foundry_id(&self) -> FoundryId {
// PANIC: the lengths are known.
FoundryId::new(self.0[0..FoundryId::LENGTH].try_into().unwrap())
}

/// Returns the [`TokenTag`] of the [`TokenId`].
pub fn token_tag(&self) -> TokenTag {
// PANIC: the lengths are known.
TokenTag::new(self.0[FoundryId::LENGTH..].try_into().unwrap())
impl From<FoundryId> for TokenId {
fn from(foundry_id: FoundryId) -> Self {
TokenId::new(*foundry_id)
}
}

Expand All @@ -49,26 +22,6 @@ pub mod dto {
use super::*;
use crate::error::dto::DtoError;

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct TokenTagDto(pub String);

impl From<&TokenTag> for TokenTagDto {
fn from(value: &TokenTag) -> Self {
Self(value.to_string())
}
}

impl TryFrom<&TokenTagDto> for TokenTag {
type Error = DtoError;

fn try_from(value: &TokenTagDto) -> Result<Self, Self::Error> {
value
.0
.parse::<TokenTag>()
.map_err(|_| DtoError::InvalidField("TokenTag"))
}
}

/// Describes a token id.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct TokenIdDto(pub String);
Expand Down
18 changes: 5 additions & 13 deletions bee-message/src/semantic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use primitive_types::U256;
use crate::{
address::Address,
error::Error,
output::{ChainId, InputsCommitment, NativeTokens, Output, OutputId, TokenId, UnlockCondition},
output::{ChainId, FoundryId, InputsCommitment, NativeTokens, Output, OutputId, TokenId, UnlockCondition},
payload::{
milestone::MilestoneIndex,
transaction::{RegularTransactionEssence, TransactionEssence, TransactionId},
Expand Down Expand Up @@ -328,15 +328,11 @@ pub fn semantic_validation(
return Ok(ConflictReason::CreatedConsumedAmountMismatch);
}

let mut native_token_ids = HashMap::new();
let mut native_token_ids = HashSet::new();

// Validation of input native tokens.
for (token_id, _input_amount) in context.input_native_tokens.iter() {
if let Some(token_tag) = native_token_ids.insert(token_id.foundry_id(), token_id.token_tag()) {
if token_tag != token_id.token_tag() {
return Ok(ConflictReason::InvalidNativeTokens);
}
}
native_token_ids.insert(token_id);
}

// Validation of output native tokens.
Expand All @@ -346,16 +342,12 @@ pub fn semantic_validation(
if output_amount > &input_amount
&& !context
.output_chains
.contains_key(&ChainId::from(token_id.foundry_id()))
.contains_key(&ChainId::from(FoundryId::from(*token_id)))
{
return Ok(ConflictReason::InvalidNativeTokens);
}

if let Some(token_tag) = native_token_ids.insert(token_id.foundry_id(), token_id.token_tag()) {
if token_tag != token_id.token_tag() {
return Ok(ConflictReason::InvalidNativeTokens);
}
}
native_token_ids.insert(token_id);
}

if native_token_ids.len() > NativeTokens::COUNT_MAX as usize {
Expand Down
Loading