diff --git a/Cargo.lock b/Cargo.lock index bb2a9b7dab..17e7574623 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -503,7 +503,7 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "cli-wallet" -version = "2.0.0-alpha.1" +version = "2.0.0-beta.1" dependencies = [ "chrono", "clap", diff --git a/bindings/nodejs/CHANGELOG.md b/bindings/nodejs/CHANGELOG.md index 4bba29f19d..8cd960b4f3 100644 --- a/bindings/nodejs/CHANGELOG.md +++ b/bindings/nodejs/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - `Client::getOutputManaRewards()` slot query parameter; +- Allow custom allotment of account bound mana; ## 2.0.0-alpha.9 - 2024-05-02 diff --git a/bindings/python/CHANGELOG.md b/bindings/python/CHANGELOG.md index 4efd795e6e..dc3c52e6a1 100644 --- a/bindings/python/CHANGELOG.md +++ b/bindings/python/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - `Client::get_output_mana_rewards()` slot query parameter; +- Allow custom allotment of account bound mana; ## 2.0.0-alpha.1 - 2024-05-07 diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 9d5a77c56b..1e0ab558c4 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -19,6 +19,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Security --> +## 2.0.0-beta.1 - 2024-05-08 + +### Fixed + +- Allow custom allotment of account bound mana; + ## 2.0.0-alpha.1 - 2024-05-08 Initial alpha release of the 2.0 `cli-wallet`. diff --git a/cli/Cargo.toml b/cli/Cargo.toml index ed31d065e7..45ea1fa631 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cli-wallet" -version = "2.0.0-alpha.1" +version = "2.0.0-beta.1" authors = ["IOTA Stiftung"] edition = "2021" homepage = "https://iota.org" diff --git a/sdk/CHANGELOG.md b/sdk/CHANGELOG.md index 1a7819c149..8879c450cb 100644 --- a/sdk/CHANGELOG.md +++ b/sdk/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - `Client::get_output_mana_rewards()` slot query parameter; +- Allow custom allotment of account bound mana; ## 2.0.0-alpha.1 - 2024-04-29 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 58e75b8aeb..bdece56298 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 @@ -427,10 +427,9 @@ impl TransactionBuilder { work_score += self.protocol_parameters.work_score(&output); if let Some(allotment) = self.min_mana_allotment { // If we're allotting to this output account, we will have more mana from the reduction. - if output - .as_account_opt() - .is_some_and(|account| account.account_id() == &allotment.issuer_id) - { + if output.as_account_opt().is_some_and(|account| { + account.is_block_issuer() && account.account_id() == &allotment.issuer_id + }) { // We can regain as much as the full account mana value // by reducing the mana on the account. let new_required_allotment = allotment.required_allotment.unwrap_or_default() @@ -451,7 +450,14 @@ impl TransactionBuilder { mana_gained = mana_gained.saturating_sub(work_score as u64 * allotment.reference_mana_cost); } - if mana_gained == 0 { + if mana_gained == 0 + && !(input.output.as_account_opt().is_some_and(|account| { + account.is_block_issuer() + && self + .min_mana_allotment + .is_some_and(|allotment| *account.account_id() == allotment.issuer_id) + })) + { return None; } diff --git a/sdk/tests/client/transaction_builder/account_outputs.rs b/sdk/tests/client/transaction_builder/account_outputs.rs index 67cc3aa33a..817ded804d 100644 --- a/sdk/tests/client/transaction_builder/account_outputs.rs +++ b/sdk/tests/client/transaction_builder/account_outputs.rs @@ -2484,3 +2484,67 @@ fn send_amount_from_block_issuer_account_with_generated_mana() { 1 ); } + +#[test] +fn custom_allot_account_bound_mana() { + let protocol_parameters = iota_mainnet_protocol_parameters().clone(); + let account_id_1 = AccountId::from_str(ACCOUNT_ID_1).unwrap(); + let ed25519_address = Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(); + + let provided_allotment = 500_000; + let account_mana = 2_000_000; + + let inputs = [AccountOutputBuilder::new_with_amount(2_000_000, account_id_1) + .with_mana(account_mana) + .add_unlock_condition(AddressUnlockCondition::new( + Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), + )) + .add_feature( + BlockIssuerFeature::new( + u32::MAX, + BlockIssuerKeys::from_vec(vec![ + Ed25519PublicKeyHashBlockIssuerKey::new(**ed25519_address.as_ed25519()).into(), + ]) + .unwrap(), + ) + .unwrap(), + ) + .finish_output() + .unwrap()]; + let inputs = inputs + .into_iter() + .map(|input| InputSigningData { + output: input, + output_metadata: rand_output_metadata_with_id(rand_output_id_with_slot_index(SLOT_INDEX)), + chain: None, + }) + .collect::>(); + + let outputs = []; + + let selected = TransactionBuilder::new( + inputs.clone(), + outputs.clone(), + [Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap()], + SLOT_INDEX, + SLOT_COMMITMENT_ID, + protocol_parameters, + ) + .with_min_mana_allotment(account_id_1, 2) + .with_mana_allotments(Some((account_id_1, provided_allotment))) + .finish() + .unwrap(); + + assert!(unsorted_eq(&selected.inputs_data, &inputs)); + assert_eq!(selected.transaction.outputs().len(), 1); + + assert_eq!(selected.transaction.allotments().len(), 1); + assert_eq!( + selected.transaction.allotments()[0], + ManaAllotment::new(account_id_1, provided_allotment).unwrap() + ); + assert_eq!( + selected.transaction.outputs().iter().map(|o| o.mana()).sum::(), + account_mana - provided_allotment + ); +}