Skip to content

Commit

Permalink
Merge branch '2.0' into issuing-time-check
Browse files Browse the repository at this point in the history
  • Loading branch information
Thoralf-M authored Jan 10, 2024
2 parents d544503 + 5620e3d commit 64430e0
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 96 deletions.
51 changes: 43 additions & 8 deletions bindings/nodejs/src/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use std::sync::Arc;
use std::{
ops::{Deref, DerefMut},
sync::Arc,
};

use iota_sdk_bindings_core::{
call_wallet_method as rust_call_wallet_method,
Expand All @@ -16,26 +19,58 @@ use crate::{
build_js_error, client::ClientMethodHandler, destroyed_err, secret_manager::SecretManagerMethodHandler, NodejsError,
};

pub type WalletMethodHandler = Arc<RwLock<Option<Wallet>>>;
pub struct WalletMethodHandlerInner(Option<Wallet>);

impl Drop for WalletMethodHandlerInner {
fn drop(&mut self) {
log::debug!("drop WalletMethodHandlerInner");
// Request to stop the background syncing silently if this wallet hasn't been destroyed yet
if let Some(wallet) = self.0.take() {
wallet.request_stop_background_syncing();
}
}
}

impl Deref for WalletMethodHandlerInner {
type Target = Option<Wallet>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl DerefMut for WalletMethodHandlerInner {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

pub type WalletMethodHandler = Arc<RwLock<WalletMethodHandlerInner>>;

#[napi(js_name = "createWallet")]
pub async fn create_wallet(options: String) -> Result<External<WalletMethodHandler>> {
let wallet_options = serde_json::from_str::<WalletOptions>(&options).map_err(NodejsError::new)?;
let wallet = wallet_options.build().await.map_err(NodejsError::new)?;

Ok(External::new(Arc::new(RwLock::new(Some(wallet)))))
Ok(External::new(Arc::new(RwLock::new(WalletMethodHandlerInner(Some(
wallet,
))))))
}

#[napi(js_name = "destroyWallet")]
pub async fn destroy_wallet(wallet: External<WalletMethodHandler>) {
*wallet.as_ref().write().await = None;
let mut wallet = wallet.as_ref().write().await;
if let Some(wallet) = &**wallet {
wallet.request_stop_background_syncing();
}
**wallet = None;
}

#[napi(js_name = "callWalletMethod")]
pub async fn call_wallet_method(wallet: External<WalletMethodHandler>, method: String) -> Result<String> {
let method = serde_json::from_str::<WalletMethod>(&method).map_err(NodejsError::new)?;

match &*wallet.as_ref().read().await {
match &**wallet.as_ref().read().await {
Some(wallet) => {
let response = rust_call_wallet_method(wallet, method).await;
match response {
Expand All @@ -58,7 +93,7 @@ pub async fn listen_wallet(
validated_event_types.push(WalletEventType::try_from(event_type).map_err(NodejsError::new)?);
}

match &*wallet.as_ref().read().await {
match &**wallet.as_ref().read().await {
Some(wallet) => {
wallet
.listen(validated_event_types, move |event_data| {
Expand All @@ -78,7 +113,7 @@ pub async fn listen_wallet(

#[napi(js_name = "getClient")]
pub async fn get_client(wallet: External<WalletMethodHandler>) -> Result<External<ClientMethodHandler>> {
if let Some(wallet) = &*wallet.as_ref().read().await {
if let Some(wallet) = &**wallet.as_ref().read().await {
Ok(External::new(Arc::new(RwLock::new(Some(wallet.client().clone())))))
} else {
Err(destroyed_err("Wallet"))
Expand All @@ -87,7 +122,7 @@ pub async fn get_client(wallet: External<WalletMethodHandler>) -> Result<Externa

#[napi(js_name = "getSecretManager")]
pub async fn get_secret_manager(wallet: External<WalletMethodHandler>) -> Result<External<SecretManagerMethodHandler>> {
if let Some(wallet) = &*wallet.as_ref().read().await {
if let Some(wallet) = &**wallet.as_ref().read().await {
Ok(External::new(wallet.get_secret_manager().clone()))
} else {
Err(destroyed_err("Wallet"))
Expand Down
4 changes: 3 additions & 1 deletion sdk/src/types/block/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use primitive_types::U256;

use super::slot::EpochIndex;
use crate::types::block::{
address::WeightedAddressCount,
address::{AddressCapabilityFlag, WeightedAddressCount},
context_input::RewardContextInputIndex,
input::UtxoInput,
mana::ManaAllotmentCount,
Expand Down Expand Up @@ -201,6 +201,7 @@ pub enum Error {
target: EpochIndex,
},
TrailingCapabilityBytes,
RestrictedAddressCapability(AddressCapabilityFlag),
}

#[cfg(feature = "std")]
Expand Down Expand Up @@ -432,6 +433,7 @@ impl fmt::Display for Error {
write!(f, "invalid epoch delta: created {created}, target {target}")
}
Self::TrailingCapabilityBytes => write!(f, "capability bytes have trailing zeroes"),
Self::RestrictedAddressCapability(cap) => write!(f, "restricted address capability: {cap:?}"),
}
}
}
Expand Down
20 changes: 13 additions & 7 deletions 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 Expand Up @@ -493,6 +502,8 @@ impl Packable for AccountOutput {
let features = Features::unpack::<_, VERIFY>(unpacker, &())?;

if VERIFY {
verify_restricted_addresses(&unlock_conditions, Self::KIND, features.native_token(), mana)
.map_err(UnpackError::Packable)?;
verify_allowed_features(&features, Self::ALLOWED_FEATURES).map_err(UnpackError::Packable)?;
}

Expand Down Expand Up @@ -611,12 +622,7 @@ mod tests {

use super::*;
use crate::types::block::{
output::account::dto::AccountOutputDto,
protocol::protocol_parameters,
rand::output::{
feature::rand_allowed_features, rand_account_id, rand_account_output,
unlock_condition::rand_address_unlock_condition_different_from_account_id,
},
output::account::dto::AccountOutputDto, protocol::protocol_parameters, rand::output::rand_account_output,
};

#[test]
Expand Down
24 changes: 13 additions & 11 deletions 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 Expand Up @@ -549,6 +558,8 @@ impl Packable for AnchorOutput {
let features = Features::unpack::<_, VERIFY>(unpacker, &())?;

if VERIFY {
verify_restricted_addresses(&unlock_conditions, Self::KIND, features.native_token(), mana)
.map_err(UnpackError::Packable)?;
verify_allowed_features(&features, Self::ALLOWED_FEATURES).map_err(UnpackError::Packable)?;
}

Expand Down Expand Up @@ -675,16 +686,7 @@ mod dto {
mod tests {
use super::*;
use crate::types::block::{
output::anchor::dto::AnchorOutputDto,
protocol::protocol_parameters,
rand::output::{
feature::rand_allowed_features,
rand_anchor_id, rand_anchor_output,
unlock_condition::{
rand_governor_address_unlock_condition_different_from,
rand_state_controller_address_unlock_condition_different_from,
},
},
output::anchor::dto::AnchorOutputDto, protocol::protocol_parameters, rand::output::rand_anchor_output,
};

#[test]
Expand Down
20 changes: 18 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 Expand Up @@ -230,6 +236,7 @@ impl From<&BasicOutput> for BasicOutputBuilder {
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Packable)]
#[packable(unpack_error = Error)]
#[packable(unpack_visitor = ProtocolParameters)]
#[packable(verify_with = verify_basic_output)]
pub struct BasicOutput {
/// Amount of IOTA coins held by the output.
amount: u64,
Expand Down Expand Up @@ -392,6 +399,15 @@ fn verify_features_packable<const VERIFY: bool>(features: &Features, _: &Protoco
verify_features::<VERIFY>(features)
}

fn verify_basic_output<const VERIFY: bool>(output: &BasicOutput, _: &ProtocolParameters) -> Result<(), Error> {
verify_restricted_addresses(
output.unlock_conditions(),
BasicOutput::KIND,
output.features.native_token(),
output.mana,
)
}

#[cfg(feature = "serde")]
mod dto {
use alloc::vec::Vec;
Expand Down
14 changes: 13 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 Expand Up @@ -215,6 +219,7 @@ impl From<&DelegationOutput> for DelegationOutputBuilder {
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Packable)]
#[packable(unpack_error = Error)]
#[packable(unpack_visitor = ProtocolParameters)]
#[packable(verify_with = verify_delegation_output)]
pub struct DelegationOutput {
/// Amount of IOTA coins held by the output.
amount: u64,
Expand Down Expand Up @@ -392,6 +397,13 @@ fn verify_unlock_conditions_packable<const VERIFY: bool>(
verify_unlock_conditions::<VERIFY>(unlock_conditions)
}

fn verify_delegation_output<const VERIFY: bool>(
output: &DelegationOutput,
_: &ProtocolParameters,
) -> Result<(), Error> {
verify_restricted_addresses(output.unlock_conditions(), DelegationOutput::KIND, None, 0)
}

#[cfg(feature = "serde")]
mod dto {
use alloc::vec::Vec;
Expand Down
7 changes: 5 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 Expand Up @@ -469,6 +470,8 @@ impl Packable for NftOutput {
let features = Features::unpack::<_, VERIFY>(unpacker, &())?;

if VERIFY {
verify_restricted_addresses(&unlock_conditions, Self::KIND, features.native_token(), mana)
.map_err(UnpackError::Packable)?;
verify_allowed_features(&features, Self::ALLOWED_FEATURES).map_err(UnpackError::Packable)?;
}

Expand Down
Loading

0 comments on commit 64430e0

Please sign in to comment.