From d4dab359a83b1513aba847a1249cc76b0eb4edce Mon Sep 17 00:00:00 2001 From: Thoralf-M <46689931+Thoralf-M@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:33:55 +0200 Subject: [PATCH] Fix mana allotment when burning something/setting a TransactionCapabilityFlag (#2231) --- bindings/nodejs/CHANGELOG.md | 6 + bindings/nodejs/package.json | 2 +- bindings/wasm/CHANGELOG.md | 4 + bindings/wasm/package.json | 2 +- .../transaction_builder/requirement/mana.rs | 1 + sdk/tests/client/transaction_builder/burn.rs | 109 +++++++++++++++++- 6 files changed, 119 insertions(+), 5 deletions(-) diff --git a/bindings/nodejs/CHANGELOG.md b/bindings/nodejs/CHANGELOG.md index 55f2b6cf25..8622494683 100644 --- a/bindings/nodejs/CHANGELOG.md +++ b/bindings/nodejs/CHANGELOG.md @@ -19,6 +19,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Security --> +## 2.0.0-alpha.7 - 2024-04-19 + +### Fixed + +- Mana allotment when burning something/setting a TransactionCapabilityFlag; + ## 2.0.0-alpha.6 - 2024-04-17 ### Fixed diff --git a/bindings/nodejs/package.json b/bindings/nodejs/package.json index 0fdaca0f3d..cb52f6f006 100644 --- a/bindings/nodejs/package.json +++ b/bindings/nodejs/package.json @@ -1,6 +1,6 @@ { "name": "@iota/sdk", - "version": "2.0.0-alpha.6", + "version": "2.0.0-alpha.7", "description": "Node.js binding to the IOTA SDK library", "main": "out/index.js", "types": "out/index.d.ts", diff --git a/bindings/wasm/CHANGELOG.md b/bindings/wasm/CHANGELOG.md index 9b8bdc0022..9bf7b71336 100644 --- a/bindings/wasm/CHANGELOG.md +++ b/bindings/wasm/CHANGELOG.md @@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Security --> +## 2.0.0-alpha.3 - 2024-04-19 + +Same changes as https://github.com/iotaledger/iota-sdk/blob/2.0/bindings/nodejs/CHANGELOG.md. + ## 2.0.0-alpha.2 - 2024-04-02 Same changes as https://github.com/iotaledger/iota-sdk/blob/2.0/bindings/nodejs/CHANGELOG.md. diff --git a/bindings/wasm/package.json b/bindings/wasm/package.json index 696f67687a..6f57fe61b7 100644 --- a/bindings/wasm/package.json +++ b/bindings/wasm/package.json @@ -1,6 +1,6 @@ { "name": "@iota/sdk-wasm", - "version": "2.0.0-alpha.2", + "version": "2.0.0-alpha.3", "description": "WebAssembly bindings for the IOTA SDK library", "repository": { "type": "git", diff --git a/sdk/src/client/api/block_builder/transaction_builder/requirement/mana.rs b/sdk/src/client/api/block_builder/transaction_builder/requirement/mana.rs index 6aec255ce6..58e75b8aeb 100644 --- a/sdk/src/client/api/block_builder/transaction_builder/requirement/mana.rs +++ b/sdk/src/client/api/block_builder/transaction_builder/requirement/mana.rs @@ -113,6 +113,7 @@ impl TransactionBuilder { .iter() .map(|(&account_id, &mana)| ManaAllotment { account_id, mana }), ) + .with_capabilities(self.transaction_capabilities.clone()) .finish_with_params(&self.protocol_parameters)?; let signed_transaction = SignedTransactionPayload::new(transaction, self.null_transaction_unlocks()?)?; diff --git a/sdk/tests/client/transaction_builder/burn.rs b/sdk/tests/client/transaction_builder/burn.rs index 56d6c47542..165cf5f141 100644 --- a/sdk/tests/client/transaction_builder/burn.rs +++ b/sdk/tests/client/transaction_builder/burn.rs @@ -6,21 +6,32 @@ use std::{ str::FromStr, }; +use crypto::keys::bip44::Bip44; use iota_sdk::{ client::{ - api::transaction_builder::{Burn, Requirement, TransactionBuilder, TransactionBuilderError}, - secret::types::InputSigningData, + api::{ + transaction_builder::{Burn, Requirement, TransactionBuilder, TransactionBuilderError}, + GetAddressesOptions, + }, + constants::SHIMMER_COIN_TYPE, + secret::{types::InputSigningData, SecretManage, SecretManager}, + Client, }, types::block::{ address::Address, + core::basic::StrongParents, output::{ unlock_condition::AddressUnlockCondition, AccountId, AccountOutputBuilder, BasicOutputBuilder, ChainId, NftId, SimpleTokenScheme, TokenId, }, - payload::signed_transaction::{TransactionCapabilities, TransactionCapabilityFlag}, + payload::{ + signed_transaction::{TransactionCapabilities, TransactionCapabilityFlag}, + Payload, SignedTransactionPayload, + }, protocol::iota_mainnet_protocol_parameters, rand::output::{rand_output_id_with_slot_index, rand_output_metadata_with_id}, slot::SlotIndex, + BlockBody, BlockId, }, }; use pretty_assertions::assert_eq; @@ -771,6 +782,98 @@ fn burn_nfts_present() { assert!(unsorted_eq(selected.transaction.outputs(), &outputs)); } +#[tokio::test] +async fn burn_nft_correct_mana_allotment() { + let secret_manager = SecretManager::try_from_mnemonic(Client::generate_mnemonic().unwrap()).unwrap(); + + let ed25519_address = secret_manager + .generate_ed25519_addresses(GetAddressesOptions::default().with_range(0..1)) + .await + .unwrap()[0] + .clone() + .into_inner(); + + let protocol_parameters = iota_mainnet_protocol_parameters(); + let account_id_1 = AccountId::from_str(ACCOUNT_ID_1).unwrap(); + let nft_id_1 = NftId::from_str(NFT_ID_1).unwrap(); + let reference_mana_cost = 1; + + let inputs = build_inputs( + [( + Nft { + amount: 1_000_000, + mana: 1_000_000, + nft_id: nft_id_1, + address: ed25519_address.clone(), + sender: None, + issuer: None, + sdruc: None, + expiration: None, + }, + Some(Bip44::new(SHIMMER_COIN_TYPE)), + )], + Some(SLOT_INDEX), + ); + + let selected = TransactionBuilder::new( + inputs.clone(), + [], + [ed25519_address], + SLOT_INDEX, + SLOT_COMMITMENT_ID, + protocol_parameters.clone(), + ) + .with_burn(Burn::new().set_nfts(HashSet::from([nft_id_1]))) + .with_min_mana_allotment(account_id_1, reference_mana_cost) + .finish() + .unwrap(); + + assert_eq!( + selected.transaction.capabilities(), + &TransactionCapabilities::from([TransactionCapabilityFlag::DestroyNftOutputs]) + ); + assert!(unsorted_eq(&selected.inputs_data, &inputs)); + + let inputs = selected + .inputs_data + .iter() + .map(|input| (input.output_id(), &input.output)) + .collect::>(); + + iota_sdk::types::block::semantic::SemanticValidationContext::new( + &selected.transaction, + &inputs, + None, + None, + &protocol_parameters, + ) + .validate() + .unwrap(); + + assert_eq!(selected.transaction.outputs().len(), 1); + + let unlocks = secret_manager + .transaction_unlocks(&selected, &protocol_parameters) + .await + .unwrap(); + + let signed_transaction_payload = SignedTransactionPayload::new(selected.transaction.clone(), unlocks).unwrap(); + + let basic_block_body = BlockBody::build_basic( + StrongParents::from_vec(vec![BlockId::new([0; 36])]).unwrap(), + (protocol_parameters.work_score_parameters(), reference_mana_cost), + ) + .with_payload(Payload::from(signed_transaction_payload)) + .finish() + .unwrap(); + + assert_eq!(selected.transaction.allotments().len(), 1); + assert_eq!( + selected.transaction.allotments().first().unwrap().mana(), + basic_block_body.max_burned_mana(), + ); +} + #[test] fn burn_nft_in_outputs() { let protocol_parameters = iota_mainnet_protocol_parameters().clone();