Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,63 @@ pub enum TokenConfigurationChangeItem {
MainControlGroup(Option<GroupContractPosition>),
}
impl TokenConfigurationChangeItem {
pub fn payload_serialization(&self) -> Result<Option<Vec<u8>>, ProtocolError> {
Ok(match self {
TokenConfigurationChangeItem::TokenConfigurationNoChange => None,
TokenConfigurationChangeItem::Conventions(convention) => Some(
bincode::encode_to_vec(convention, bincode::config::standard())
.map_err(|e| ProtocolError::EncodingError(e.to_string()))?,
),
TokenConfigurationChangeItem::ConventionsControlGroup(a)
| TokenConfigurationChangeItem::ConventionsAdminGroup(a)
| TokenConfigurationChangeItem::MaxSupplyControlGroup(a)
| TokenConfigurationChangeItem::MaxSupplyAdminGroup(a)
| TokenConfigurationChangeItem::PerpetualDistributionControlGroup(a)
| TokenConfigurationChangeItem::PerpetualDistributionAdminGroup(a)
| TokenConfigurationChangeItem::NewTokensDestinationIdentityControlGroup(a)
| TokenConfigurationChangeItem::NewTokensDestinationIdentityAdminGroup(a)
| TokenConfigurationChangeItem::MintingAllowChoosingDestinationControlGroup(a)
| TokenConfigurationChangeItem::MintingAllowChoosingDestinationAdminGroup(a)
| TokenConfigurationChangeItem::ManualMinting(a)
| TokenConfigurationChangeItem::ManualMintingAdminGroup(a)
| TokenConfigurationChangeItem::ManualBurning(a)
| TokenConfigurationChangeItem::ManualBurningAdminGroup(a)
| TokenConfigurationChangeItem::Freeze(a)
| TokenConfigurationChangeItem::FreezeAdminGroup(a)
| TokenConfigurationChangeItem::Unfreeze(a)
| TokenConfigurationChangeItem::UnfreezeAdminGroup(a)
| TokenConfigurationChangeItem::DestroyFrozenFunds(a)
| TokenConfigurationChangeItem::DestroyFrozenFundsAdminGroup(a)
| TokenConfigurationChangeItem::EmergencyAction(a)
| TokenConfigurationChangeItem::EmergencyActionAdminGroup(a)
| TokenConfigurationChangeItem::MarketplaceTradeModeControlGroup(a)
| TokenConfigurationChangeItem::MarketplaceTradeModeAdminGroup(a) => Some(a.to_bytes()),
TokenConfigurationChangeItem::MaxSupply(max_supply) => {
max_supply.map(|amount| amount.to_be_bytes().to_vec())
}
Comment thread
QuantumExplorer marked this conversation as resolved.
TokenConfigurationChangeItem::PerpetualDistribution(distribution) => distribution
.as_ref()
.map(|dist| {
bincode::encode_to_vec(dist, bincode::config::standard())
.map_err(|e| ProtocolError::EncodingError(e.to_string()))
})
.transpose()?,
TokenConfigurationChangeItem::NewTokensDestinationIdentity(identity) => {
identity.map(|id| id.to_vec())
}
TokenConfigurationChangeItem::MintingAllowChoosingDestination(allow) => {
Some(vec![*allow as u8])
}
TokenConfigurationChangeItem::MarketplaceTradeMode(mode) => Some(
bincode::encode_to_vec(mode, bincode::config::standard())
.map_err(|e| ProtocolError::EncodingError(e.to_string()))?,
),
TokenConfigurationChangeItem::MainControlGroup(position) => match position {
Some(pos) => Some(pos.to_be_bytes().to_vec()),
None => Some(vec![]),
},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Nitpick: MainControlGroup(None) returns Some(vec![]) while other Option::None variants return None

MaxSupply(None), NewTokensDestinationIdentity(None), and PerpetualDistribution(None) all return None from payload_serialization(), but MainControlGroup(None) returns Some(vec![]). Functionally this is harmless — Some(&[]) causes extend_from_slice(&[]) which is a no-op, producing the same hash as the None path. But the inconsistency may confuse future maintainers. Consider returning None for consistency, or adding a comment explaining the intentional difference.

source: ['claude-rust-quality']

})
}
pub fn u8_item_index(&self) -> u8 {
match self {
TokenConfigurationChangeItem::TokenConfigurationNoChange => 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::data_contract::group::accessors::v0::GroupV0Getters;
use crate::data_contract::group::{Group, GroupMemberPower};
use crate::data_contract::GroupContractPosition;
use crate::group::action_taker::{ActionGoal, ActionTaker};
use crate::ProtocolError;
use bincode::{Decode, Encode};
use platform_value::Identifier;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -33,6 +34,61 @@ impl fmt::Display for AuthorizedActionTakers {
}

impl AuthorizedActionTakers {
pub fn to_bytes(&self) -> Vec<u8> {
match self {
AuthorizedActionTakers::NoOne => vec![0],
AuthorizedActionTakers::ContractOwner => vec![1],
AuthorizedActionTakers::Identity(identifier) => {
let mut bytes = vec![2];
bytes.extend_from_slice(identifier.as_bytes());
bytes
}
AuthorizedActionTakers::MainGroup => vec![3],
AuthorizedActionTakers::Group(position) => {
let mut bytes = vec![4];
bytes.extend_from_slice(&position.to_be_bytes());
bytes
}
}
}

pub fn from_bytes(bytes: &[u8]) -> Result<Self, ProtocolError> {
let Some(&tag) = bytes.first() else {
return Err(ProtocolError::DecodingError(
"empty bytes for AuthorizedActionTakers".to_string(),
));
};
match tag {
0 => Ok(AuthorizedActionTakers::NoOne),
1 => Ok(AuthorizedActionTakers::ContractOwner),
2 => {
if bytes.len() != 33 {
return Err(ProtocolError::DecodingError(format!(
"expected 33 bytes for AuthorizedActionTakers::Identity, got {}",
bytes.len()
)));
}
let identifier = Identifier::from_bytes(&bytes[1..])
.map_err(|e| ProtocolError::DecodingError(e.to_string()))?;
Ok(AuthorizedActionTakers::Identity(identifier))
}
3 => Ok(AuthorizedActionTakers::MainGroup),
4 => {
if bytes.len() != 3 {
return Err(ProtocolError::DecodingError(format!(
"expected 3 bytes for AuthorizedActionTakers::Group, got {}",
bytes.len()
)));
}
let position = u16::from_be_bytes([bytes[1], bytes[2]]);
Ok(AuthorizedActionTakers::Group(position))
}
other => Err(ProtocolError::DecodingError(format!(
"unknown AuthorizedActionTakers tag: {}",
other
))),
}
}
Comment thread
QuantumExplorer marked this conversation as resolved.
pub fn allowed_for_action_taker(
&self,
contract_owner_id: &Identifier,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use crate::ProtocolError;
use platform_value::Identifier;
use platform_version::version::PlatformVersion;

pub trait AllowedAsMultiPartyAction {
fn calculate_action_id(&self, owner_id: Identifier) -> Identifier;
fn calculate_action_id(
&self,
owner_id: Identifier,
platform_version: &PlatformVersion,
) -> Result<Identifier, ProtocolError>;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use platform_value::Identifier;
use platform_version::version::PlatformVersion;
use crate::ProtocolError;
use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction;
use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors;
use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition;
Expand Down Expand Up @@ -60,16 +62,20 @@ impl TokenBurnTransitionV0Methods for TokenBurnTransitionV0 {
}

impl AllowedAsMultiPartyAction for TokenBurnTransitionV0 {
fn calculate_action_id(&self, owner_id: Identifier) -> Identifier {
fn calculate_action_id(
&self,
owner_id: Identifier,
_platform_version: &PlatformVersion,
) -> Result<Identifier, ProtocolError> {
let TokenBurnTransitionV0 {
base, burn_amount, ..
} = self;

TokenBurnTransition::calculate_action_id_with_fields(
Ok(TokenBurnTransition::calculate_action_id_with_fields(
base.token_id().as_bytes(),
owner_id.as_bytes(),
base.identity_contract_nonce(),
*burn_amount,
)
))
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use platform_value::Identifier;
use platform_version::version::PlatformVersion;
use crate::balances::credits::TokenAmount;
use crate::prelude::IdentityNonce;
use crate::ProtocolError;
use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction;
use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors;
use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition;
Expand Down Expand Up @@ -61,9 +63,13 @@ impl TokenBurnTransitionV0Methods for TokenBurnTransition {
}

impl AllowedAsMultiPartyAction for TokenBurnTransition {
fn calculate_action_id(&self, owner_id: Identifier) -> Identifier {
fn calculate_action_id(
&self,
owner_id: Identifier,
platform_version: &PlatformVersion,
) -> Result<Identifier, ProtocolError> {
match self {
TokenBurnTransition::V0(v0) => v0.calculate_action_id(owner_id),
TokenBurnTransition::V0(v0) => v0.calculate_action_id(owner_id, platform_version),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use platform_value::Identifier;
use platform_version::version::PlatformVersion;
use crate::data_contract::associated_token::token_configuration_item::TokenConfigurationChangeItem;
use crate::ProtocolError;
use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction;
use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors;
use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition;
Expand Down Expand Up @@ -69,7 +71,12 @@ impl TokenConfigUpdateTransitionV0Methods for TokenConfigUpdateTransitionV0 {
}

impl AllowedAsMultiPartyAction for TokenConfigUpdateTransitionV0 {
fn calculate_action_id(&self, owner_id: Identifier) -> Identifier {
/// v0 action_id: uses only the u8 discriminant (kept for backward compat).
fn calculate_action_id(
&self,
owner_id: Identifier,
platform_version: &PlatformVersion,
) -> Result<Identifier, ProtocolError> {
let TokenConfigUpdateTransitionV0 {
base,
update_token_configuration_item,
Expand All @@ -80,7 +87,8 @@ impl AllowedAsMultiPartyAction for TokenConfigUpdateTransitionV0 {
base.token_id().as_bytes(),
owner_id.as_bytes(),
base.identity_contract_nonce(),
update_token_configuration_item.u8_item_index(),
update_token_configuration_item,
platform_version,
)
}
}
Loading
Loading