From 3fbd3a5fd2f73f9e1d144def50234519b6dc65e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thoralf=20M=C3=BCller?= Date: Wed, 8 May 2024 16:37:21 +0200 Subject: [PATCH] Allow custom allotment of account bound mana --- bindings/nodejs/CHANGELOG.md | 1 + bindings/python/CHANGELOG.md | 1 + cli/CHANGELOG.md | 6 + sdk/CHANGELOG.md | 1 + .../transaction_builder/requirement/mana.rs | 1 - .../transaction_builder/account_outputs.rs | 139 +++++++++++++----- 6 files changed, 108 insertions(+), 41 deletions(-) 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/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..cb7039a6ef 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 @@ -438,7 +438,6 @@ impl TransactionBuilder { mana_gained += new_required_allotment.min(output.mana()); } } - mana_gained = mana_gained.saturating_sub(output.mana()); } else if input.output.native_token().is_some() { remainder_work_score += self.protocol_parameters.work_score(self.native_token_remainder()) } else if mana_gained > missing_mana { diff --git a/sdk/tests/client/transaction_builder/account_outputs.rs b/sdk/tests/client/transaction_builder/account_outputs.rs index 67cc3aa33a..1f70984ec6 100644 --- a/sdk/tests/client/transaction_builder/account_outputs.rs +++ b/sdk/tests/client/transaction_builder/account_outputs.rs @@ -1557,28 +1557,24 @@ fn two_accounts_required() { assert!(unsorted_eq(&selected.inputs_data, &inputs)); assert_eq!(selected.transaction.outputs().len(), 3); assert!(selected.transaction.outputs().contains(&outputs[0])); - assert!( - selected - .transaction - .outputs() - .iter() - .any(|output| if let Output::Account(output) = output { - output.account_id() == &account_id_1 - } else { - false - }) - ); - assert!( - selected - .transaction - .outputs() - .iter() - .any(|output| if let Output::Account(output) = output { - output.account_id() == &account_id_2 - } else { - false - }) - ) + assert!(selected + .transaction + .outputs() + .iter() + .any(|output| if let Output::Account(output) = output { + output.account_id() == &account_id_1 + } else { + false + })); + assert!(selected + .transaction + .outputs() + .iter() + .any(|output| if let Output::Account(output) = output { + output.account_id() == &account_id_2 + } else { + false + })) } #[test] @@ -2372,9 +2368,10 @@ fn account_transition_with_required_context_inputs() { )) .with_features([BlockIssuerFeature::new( u32::MAX, - BlockIssuerKeys::from_vec(vec![ - Ed25519PublicKeyHashBlockIssuerKey::new(**ed25519_address.as_ed25519()).into(), - ]) + BlockIssuerKeys::from_vec(vec![Ed25519PublicKeyHashBlockIssuerKey::new( + **ed25519_address.as_ed25519(), + ) + .into()]) .unwrap(), ) .unwrap()]) @@ -2390,12 +2387,10 @@ fn account_transition_with_required_context_inputs() { }) .collect::>(); - let outputs = vec![ - BasicOutputBuilder::new_with_amount(1_000_000) - .add_unlock_condition(AddressUnlockCondition::new(ed25519_address.clone())) - .finish_output() - .unwrap(), - ]; + let outputs = vec![BasicOutputBuilder::new_with_amount(1_000_000) + .add_unlock_condition(AddressUnlockCondition::new(ed25519_address.clone())) + .finish_output() + .unwrap()]; let selected = TransactionBuilder::new( inputs.clone(), @@ -2435,9 +2430,10 @@ fn send_amount_from_block_issuer_account_with_generated_mana() { )) .with_features([BlockIssuerFeature::new( u32::MAX, - BlockIssuerKeys::from_vec(vec![ - Ed25519PublicKeyHashBlockIssuerKey::new(**ed25519_address.as_ed25519()).into(), - ]) + BlockIssuerKeys::from_vec(vec![Ed25519PublicKeyHashBlockIssuerKey::new( + **ed25519_address.as_ed25519(), + ) + .into()]) .unwrap(), ) .unwrap()]) @@ -2452,12 +2448,10 @@ fn send_amount_from_block_issuer_account_with_generated_mana() { }) .collect::>(); - let outputs = vec![ - BasicOutputBuilder::new_with_amount(1_000_000) - .add_unlock_condition(AddressUnlockCondition::new(ed25519_address.clone())) - .finish_output() - .unwrap(), - ]; + let outputs = vec![BasicOutputBuilder::new_with_amount(1_000_000) + .add_unlock_condition(AddressUnlockCondition::new(ed25519_address.clone())) + .finish_output() + .unwrap()]; let selected = TransactionBuilder::new( inputs.clone(), @@ -2484,3 +2478,68 @@ 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 + ); +}