Skip to content

Commit

Permalink
Use verify_restricted_addresses in builders
Browse files Browse the repository at this point in the history
  • Loading branch information
thibault-martinez committed Jan 10, 2024
1 parent bfae6ff commit 964642d
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 51 deletions.
11 changes: 10 additions & 1 deletion sdk/src/types/block/output/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use crate::types::block::{
address::{AccountAddress, Address},
output::{
feature::{verify_allowed_features, Feature, FeatureFlags, Features},
unlock_condition::{verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions},
unlock_condition::{
verify_allowed_unlock_conditions, verify_restricted_addresses, UnlockCondition, UnlockConditionFlags,
UnlockConditions,
},
ChainId, MinimumOutputAmount, Output, OutputBuilderAmount, OutputId, StorageScore, StorageScoreParameters,
},
protocol::{ProtocolParameters, WorkScore, WorkScoreParameters},
Expand Down Expand Up @@ -217,6 +220,12 @@ impl AccountOutputBuilder {

let features = Features::from_set(self.features)?;

verify_restricted_addresses(
&unlock_conditions,
AccountOutput::KIND,
features.native_token(),
self.mana,
)?;
verify_allowed_features(&features, AccountOutput::ALLOWED_FEATURES)?;

let immutable_features = Features::from_set(self.immutable_features)?;
Expand Down
11 changes: 10 additions & 1 deletion sdk/src/types/block/output/anchor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use crate::types::block::{
address::{Address, AnchorAddress},
output::{
feature::{verify_allowed_features, Feature, FeatureFlags, Features},
unlock_condition::{verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions},
unlock_condition::{
verify_allowed_unlock_conditions, verify_restricted_addresses, UnlockCondition, UnlockConditionFlags,
UnlockConditions,
},
ChainId, MinimumOutputAmount, Output, OutputBuilderAmount, OutputId, StorageScore, StorageScoreParameters,
},
protocol::{ProtocolParameters, WorkScore, WorkScoreParameters},
Expand Down Expand Up @@ -248,6 +251,12 @@ impl AnchorOutputBuilder {

let features = Features::from_set(self.features)?;

verify_restricted_addresses(
&unlock_conditions,
AnchorOutput::KIND,
features.native_token(),
self.mana,
)?;
verify_allowed_features(&features, AnchorOutput::ALLOWED_FEATURES)?;

let immutable_features = Features::from_set(self.immutable_features)?;
Expand Down
10 changes: 8 additions & 2 deletions sdk/src/types/block/output/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::types::block::{
output::{
feature::{verify_allowed_features, Feature, FeatureFlags, Features, NativeTokenFeature},
unlock_condition::{
verify_allowed_unlock_conditions, AddressUnlockCondition, StorageDepositReturnUnlockCondition,
UnlockCondition, UnlockConditionFlags, UnlockConditions,
verify_allowed_unlock_conditions, verify_restricted_addresses, AddressUnlockCondition,
StorageDepositReturnUnlockCondition, UnlockCondition, UnlockConditionFlags, UnlockConditions,
},
MinimumOutputAmount, NativeToken, Output, OutputBuilderAmount, StorageScore, StorageScoreParameters,
},
Expand Down Expand Up @@ -192,6 +192,12 @@ impl BasicOutputBuilder {

let features = Features::from_set(self.features)?;

verify_restricted_addresses(
&unlock_conditions,
BasicOutput::KIND,
features.native_token(),
self.mana,
)?;
verify_features::<true>(&features)?;

let mut output = BasicOutput {
Expand Down
6 changes: 5 additions & 1 deletion sdk/src/types/block/output/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use crate::types::block::{
address::{AccountAddress, Address},
output::{
chain_id::ChainId,
unlock_condition::{verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions},
unlock_condition::{
verify_allowed_unlock_conditions, verify_restricted_addresses, UnlockCondition, UnlockConditionFlags,
UnlockConditions,
},
MinimumOutputAmount, Output, OutputBuilderAmount, OutputId, StorageScore, StorageScoreParameters,
},
protocol::{ProtocolParameters, WorkScore, WorkScoreParameters},
Expand Down Expand Up @@ -172,6 +175,7 @@ impl DelegationOutputBuilder {
let unlock_conditions = UnlockConditions::from_set(self.unlock_conditions)?;

verify_unlock_conditions::<true>(&unlock_conditions)?;
verify_restricted_addresses(&unlock_conditions, DelegationOutput::KIND, None, 0)?;

let mut output = DelegationOutput {
amount: 0,
Expand Down
5 changes: 3 additions & 2 deletions sdk/src/types/block/output/nft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use crate::types::block::{
output::{
feature::{verify_allowed_features, Feature, FeatureFlags, Features},
unlock_condition::{
verify_allowed_unlock_conditions, AddressUnlockCondition, StorageDepositReturnUnlockCondition,
UnlockCondition, UnlockConditionFlags, UnlockConditions,
verify_allowed_unlock_conditions, verify_restricted_addresses, AddressUnlockCondition,
StorageDepositReturnUnlockCondition, UnlockCondition, UnlockConditionFlags, UnlockConditions,
},
BasicOutputBuilder, ChainId, MinimumOutputAmount, Output, OutputBuilderAmount, OutputId, StorageScore,
StorageScoreParameters,
Expand Down Expand Up @@ -256,6 +256,7 @@ impl NftOutputBuilder {

let features = Features::from_set(self.features)?;

verify_restricted_addresses(&unlock_conditions, NftOutput::KIND, features.native_token(), self.mana)?;
verify_allowed_features(&features, NftOutput::ALLOWED_FEATURES)?;

let immutable_features = Features::from_set(self.immutable_features)?;
Expand Down
91 changes: 47 additions & 44 deletions sdk/src/types/block/output/unlock_condition/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,50 +333,6 @@ impl UnlockConditions {
pub fn restricted_addresses(&self) -> impl Iterator<Item = &RestrictedAddress> {
self.addresses().filter_map(Address::as_restricted_opt)
}

pub(crate) fn verify_restricted_addresses(
&self,
output_kind: u8,
native_token: Option<&NativeTokenFeature>,
mana: u64,
) -> Result<(), Error> {
let addresses = self.restricted_addresses();

for address in addresses {
if native_token.is_some() && !address.has_capability(AddressCapabilityFlag::OutputsWithNativeTokens) {
return Err(Error::RestrictedAddressCapability);
}

if mana > 0 && !address.has_capability(AddressCapabilityFlag::OutputsWithMana) {
return Err(Error::RestrictedAddressCapability);
}

if self.timelock().is_some() && !address.has_capability(AddressCapabilityFlag::OutputsWithTimelock) {
return Err(Error::RestrictedAddressCapability);
}

if self.expiration().is_some() && !address.has_capability(AddressCapabilityFlag::OutputsWithExpiration) {
return Err(Error::RestrictedAddressCapability);
}

if self.storage_deposit_return().is_some()
&& !address.has_capability(AddressCapabilityFlag::OutputsWithStorageDepositReturn)
{
return Err(Error::RestrictedAddressCapability);
}

if match output_kind {
AccountOutput::KIND => !address.has_capability(AddressCapabilityFlag::AccountOutputs),
AnchorOutput::KIND => !address.has_capability(AddressCapabilityFlag::AnchorOutputs),
NftOutput::KIND => !address.has_capability(AddressCapabilityFlag::NftOutputs),
DelegationOutput::KIND => !address.has_capability(AddressCapabilityFlag::DelegationOutputs),
_ => return Err(Error::UnsupportedOutputKind(output_kind)),
} {
return Err(Error::RestrictedAddressCapability);
}
}
Ok(())
}
}

impl StorageScore for UnlockConditions {
Expand Down Expand Up @@ -418,6 +374,53 @@ pub(crate) fn verify_allowed_unlock_conditions(
Ok(())
}

pub(crate) fn verify_restricted_addresses(
unlock_conditions: &UnlockConditions,
output_kind: u8,
native_token: Option<&NativeTokenFeature>,
mana: u64,
) -> Result<(), Error> {
let addresses = unlock_conditions.restricted_addresses();

for address in addresses {
if native_token.is_some() && !address.has_capability(AddressCapabilityFlag::OutputsWithNativeTokens) {
return Err(Error::RestrictedAddressCapability);
}

if mana > 0 && !address.has_capability(AddressCapabilityFlag::OutputsWithMana) {
return Err(Error::RestrictedAddressCapability);
}

if unlock_conditions.timelock().is_some() && !address.has_capability(AddressCapabilityFlag::OutputsWithTimelock)
{
return Err(Error::RestrictedAddressCapability);
}

if unlock_conditions.expiration().is_some()
&& !address.has_capability(AddressCapabilityFlag::OutputsWithExpiration)
{
return Err(Error::RestrictedAddressCapability);
}

if unlock_conditions.storage_deposit_return().is_some()
&& !address.has_capability(AddressCapabilityFlag::OutputsWithStorageDepositReturn)
{
return Err(Error::RestrictedAddressCapability);
}

if match output_kind {
AccountOutput::KIND => !address.has_capability(AddressCapabilityFlag::AccountOutputs),
AnchorOutput::KIND => !address.has_capability(AddressCapabilityFlag::AnchorOutputs),
NftOutput::KIND => !address.has_capability(AddressCapabilityFlag::NftOutputs),
DelegationOutput::KIND => !address.has_capability(AddressCapabilityFlag::DelegationOutputs),
_ => return Err(Error::UnsupportedOutputKind(output_kind)),
} {
return Err(Error::RestrictedAddressCapability);
}
}
Ok(())
}

#[cfg(test)]
mod test {
use pretty_assertions::assert_eq;
Expand Down

0 comments on commit 964642d

Please sign in to comment.