Skip to content

Commit

Permalink
Add more ISA tests, clippy (#2033)
Browse files Browse the repository at this point in the history
* Add more ISA tests, clippy

* fmt

---------

Co-authored-by: Thibault Martinez <[email protected]>
  • Loading branch information
Thoralf-M and thibault-martinez authored Feb 20, 2024
1 parent 901fe28 commit ad2665c
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 18 deletions.
4 changes: 2 additions & 2 deletions sdk/src/client/api/block_builder/input_selection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ impl InputSelection {
if !OUTPUT_COUNT_RANGE.contains(&(self.provided_outputs.len() as u16)) {
// If burn or mana allotments are provided, outputs will be added later, in the other cases it will just
// create remainder outputs.
if !(self.provided_outputs.is_empty()
&& (self.burn.is_some() || !self.mana_allotments.is_empty() || !self.required_inputs.is_empty()))
if !self.provided_outputs.is_empty()
|| self.burn.is_none() && self.mana_allotments.is_empty() && self.required_inputs.is_empty()
{
return Err(Error::InvalidOutputCount(self.provided_outputs.len()));
}
Expand Down
16 changes: 7 additions & 9 deletions sdk/src/client/api/block_builder/input_selection/remainder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,13 @@ impl InputSelection {
.ok_or(Error::MissingInputWithEd25519Address)?;

// If there is a mana remainder, try to fit it in an existing output
if input_mana > output_mana {
if self.output_for_added_mana_exists(&remainder_address) {
log::debug!("Allocating {mana_diff} excess input mana for output with address {remainder_address}");
self.remainders.added_mana = std::mem::take(&mut mana_diff);
// If we have no other remainders, we are done
if input_amount == output_amount && native_tokens_diff.is_none() {
log::debug!("No more remainder required");
return Ok((storage_deposit_returns, Vec::new()));
}
if input_mana > output_mana && self.output_for_added_mana_exists(&remainder_address) {
log::debug!("Allocating {mana_diff} excess input mana for output with address {remainder_address}");
self.remainders.added_mana = std::mem::take(&mut mana_diff);
// If we have no other remainders, we are done
if input_amount == output_amount && native_tokens_diff.is_none() {
log::debug!("No more remainder required");
return Ok((storage_deposit_returns, Vec::new()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,8 @@ impl InputSelection {
}

self.reduce_account_output()?;
} else {
if !self.requirements.contains(&Requirement::Mana) {
self.requirements.push(Requirement::Mana);
}
} else if !self.requirements.contains(&Requirement::Mana) {
self.requirements.push(Requirement::Mana);
}

// Remainders can only be calculated when the input mana is >= the output mana
Expand Down
61 changes: 60 additions & 1 deletion sdk/tests/client/input_selection/account_outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use iota_sdk::{
secret::types::InputSigningData,
},
types::block::{
address::Address,
address::{Address, ImplicitAccountCreationAddress},
mana::ManaAllotment,
output::{
feature::SenderFeature, unlock_condition::AddressUnlockCondition, AccountId, AccountOutputBuilder,
Expand Down Expand Up @@ -2071,3 +2071,62 @@ fn min_allot_account_mana_requirement_covered_2() {
);
assert_eq!(selected.transaction.outputs()[1].as_account().mana(), 0);
}

#[test]
fn implicit_account_transition() {
let protocol_parameters = protocol_parameters();
let account_id_1 = AccountId::from_str(ACCOUNT_ID_1).unwrap();

let inputs = [BasicOutputBuilder::new_with_amount(1_000_000)
.add_unlock_condition(AddressUnlockCondition::new(Address::ImplicitAccountCreation(
ImplicitAccountCreationAddress::new(
**Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap().as_ed25519(),
),
)))
.with_mana(961)
.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::<Vec<_>>();

let input_output_id = *inputs[0].output_id();
let account_id = AccountId::from(&input_output_id);
let outputs = vec![
AccountOutputBuilder::new_with_amount(1_000_000, account_id)
.add_unlock_condition(AddressUnlockCondition::new(
Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(),
))
.finish_output()
.unwrap(),
];

let selected = InputSelection::new(
inputs.clone(),
outputs.clone(),
[Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap()],
SLOT_INDEX,
SLOT_COMMITMENT_ID,
protocol_parameters,
)
.with_required_inputs(vec![input_output_id])
.with_min_mana_allotment(account_id_1, 2)
.select()
.unwrap();

assert!(unsorted_eq(&selected.inputs_data, &inputs));
assert_eq!(selected.transaction.outputs().len(), 1);
assert!(selected.transaction.outputs()[0].is_account());
assert_eq!(selected.transaction.allotments().len(), 1);
assert_eq!(
selected.transaction.allotments()[0],
ManaAllotment::new(account_id_1, 960).unwrap()
);
// One remainder Mana
assert_eq!(selected.transaction.outputs()[0].mana(), 1);
}
64 changes: 62 additions & 2 deletions sdk/tests/client/input_selection/basic_outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
use std::str::FromStr;

use iota_sdk::{
client::api::input_selection::{Error, InputSelection, Requirement},
client::{
api::input_selection::{Error, InputSelection, Requirement},
secret::types::InputSigningData,
},
types::block::{
address::{Address, AddressCapabilities, MultiAddress, RestrictedAddress, WeightedAddress},
output::{AccountId, NftId},
mana::ManaAllotment,
output::{unlock_condition::AddressUnlockCondition, AccountId, BasicOutputBuilder, NftId},
protocol::protocol_parameters,
rand::output::{rand_output_id_with_slot_index, rand_output_metadata_with_id},
},
};
use pretty_assertions::assert_eq;
Expand Down Expand Up @@ -2432,3 +2437,58 @@ fn ed25519_backed_available_address() {
// Provided outputs
assert_eq!(selected.transaction.outputs(), outputs);
}

#[test]
fn automatic_allotment_provided_in_and_output() {
let protocol_parameters = protocol_parameters();
let account_id_1 = AccountId::from_str(ACCOUNT_ID_1).unwrap();

let inputs = [BasicOutputBuilder::new_with_amount(1_000_000)
.add_unlock_condition(AddressUnlockCondition::new(
Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(),
))
.with_mana(881)
.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::<Vec<_>>();

let outputs = vec![
BasicOutputBuilder::new_with_amount(1_000_000)
.add_unlock_condition(AddressUnlockCondition::new(
Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(),
))
.with_mana(1)
.finish_output()
.unwrap(),
];

let selected = InputSelection::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)
.select()
.unwrap();

assert!(unsorted_eq(&selected.inputs_data, &inputs));
assert_eq!(selected.transaction.outputs().len(), 1);
assert!(selected.transaction.outputs().contains(&outputs[0]));
assert_eq!(selected.transaction.allotments().len(), 1);
let mana_cost = 880;
assert_eq!(
selected.transaction.allotments()[0],
ManaAllotment::new(account_id_1, mana_cost).unwrap()
);
assert_eq!(selected.transaction.outputs()[0].mana(), 1);
}

0 comments on commit ad2665c

Please sign in to comment.