Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add automatic mana allotment #1961

Merged
merged 74 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
865cf5a
Add automatic mana allotment
Feb 6, 2024
13a55e1
rework
Feb 6, 2024
e3bfbf7
better loop
Feb 6, 2024
d15d9ef
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 6, 2024
2108a8c
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 6, 2024
38e7734
set mana allotment to 1 not 0
Feb 6, 2024
69b628d
Merge branch 'feat/automatic-mana-allotment' of https://github.com/io…
Feb 6, 2024
5b8988d
better error when there is insufficient mana provided
Feb 6, 2024
b0d6ae6
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 6, 2024
be1a40f
make auto mana allotment optional
Feb 7, 2024
773448b
revert some accidental changes
Feb 7, 2024
f9560a9
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 7, 2024
a5596a6
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 7, 2024
b5173e1
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 8, 2024
5a467c9
missed
Feb 8, 2024
5273d2a
rework transaction options
Feb 8, 2024
0872e4d
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 8, 2024
83fc511
improvements
Feb 8, 2024
5a88376
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 8, 2024
4fb1135
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 9, 2024
0a40797
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 9, 2024
474efa3
sort
Feb 9, 2024
d40b984
privatize
Feb 12, 2024
1f93565
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 12, 2024
a54519f
fix mana addition on newly selected inputs
Feb 12, 2024
f62195d
Merge branch 'feat/automatic-mana-allotment' of https://github.com/io…
Feb 12, 2024
5a4ff71
Allow ISA to add mana to existing outputs
Feb 12, 2024
bd49c60
better calculation
Feb 12, 2024
b8454fa
little cleanup
Feb 12, 2024
98c4308
fix slot usage and detect mana remainder more accurately
Feb 12, 2024
063d88a
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 12, 2024
5f9c4a4
add some debug logging
Feb 12, 2024
56827a8
Merge branch 'feat/automatic-mana-allotment' of https://github.com/io…
Feb 12, 2024
b8abe20
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 13, 2024
5bceb5d
rename to required
Feb 13, 2024
65a42dd
more renames
Feb 13, 2024
6a82da7
make context inputs optional
Feb 13, 2024
f19558c
remove hard coded reward index
Feb 13, 2024
4d786a5
another
Feb 13, 2024
7e8add3
Allow using account mana for allotments, fix semantic validation
Thoralf-M Feb 13, 2024
f91bf99
Add test
Thoralf-M Feb 13, 2024
97684d0
carry over previous required allotment value
Feb 13, 2024
e1d3ea1
add more tests
Feb 13, 2024
dc57b4f
simplify
Feb 13, 2024
568dc59
more simpler
Feb 13, 2024
769c55f
just build the transaction in ISA
Feb 13, 2024
b15d64c
cleanup
Feb 13, 2024
544b534
increase mana bits to fix tests
Feb 13, 2024
589b7a7
review
Feb 14, 2024
544ffb4
Set automatically transitioned account mana to zero and order mana re…
Feb 14, 2024
72dbfc0
fix python
Feb 14, 2024
5ff83da
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 14, 2024
1c84083
unused import
Feb 14, 2024
e01fad2
rename tests
Feb 14, 2024
9fdafd2
don't stack allotments
Feb 14, 2024
8529512
track allotment debt for future selected accounts
Feb 14, 2024
6ac3751
more unused imports
Feb 14, 2024
3825a41
Rework allotment
Feb 14, 2024
42d0933
skip allotment step if there are no inputs selected
Feb 14, 2024
5666e30
Loop over remainder calculations too
Feb 15, 2024
8ea3f42
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 15, 2024
6569ccf
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 15, 2024
7127d81
fix last test
Feb 15, 2024
fe02563
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 15, 2024
9fcecaa
one more creation slot usage
Feb 15, 2024
bc2a7af
only add mana to added outputs with no weird unlock conditions
Feb 15, 2024
d155b8b
merge mana and allotments
Feb 15, 2024
6e20820
include provided
Feb 15, 2024
4ba7497
fix amount sums
Feb 15, 2024
d8c9ac4
remove automatically_transitioned
Feb 15, 2024
e3b9bda
unused import
Feb 15, 2024
c24587a
rework allotment again
Feb 15, 2024
2a0efbf
fix skipping allotment
Feb 15, 2024
f193e12
Merge branch '2.0' into feat/automatic-mana-allotment
Feb 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions sdk/src/client/api/block_builder/input_selection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ impl InputSelection {
.0;
let added_mana = self.remainders.added_mana;
if let Some(output) = self.get_output_for_added_mana(&remainder_address) {
log::debug!("Adding {added_mana} excess input mana to output with address {remainder_address}");
println!("Adding {added_mana} excess input mana to output with address {remainder_address}");
Thoralf-M marked this conversation as resolved.
Show resolved Hide resolved
let new_mana = output.mana() + added_mana;
*output = match output {
Output::Basic(b) => BasicOutputBuilder::from(&*b).with_mana(new_mana).finish_output()?,
Expand Down Expand Up @@ -325,7 +325,7 @@ impl InputSelection {
}

fn select_input(&mut self, input: InputSigningData) -> Result<(), Error> {
log::debug!("Selecting input {:?}", input.output_id());
println!("Selecting input {:?}", input.output_id());

if let Some(output) = self.transition_input(&input)? {
// No need to check for `outputs_requirements` because
Expand All @@ -337,7 +337,7 @@ impl InputSelection {
}

if let Some(requirement) = self.required_account_nft_addresses(&input)? {
log::debug!("Adding {requirement:?} from input {:?}", input.output_id());
println!("Adding {requirement:?} from input {:?}", input.output_id());
self.requirements.push(requirement);
}

Expand Down Expand Up @@ -682,7 +682,7 @@ impl InputSelection {
&input_chains_foundries,
outputs,
) {
log::debug!("validate_transitions error {err:?}");
println!("validate_transitions error {err:?}");
return Err(Error::UnfulfillableRequirement(Requirement::Account(
*account_output.account_id(),
)));
Expand Down Expand Up @@ -715,7 +715,7 @@ impl InputSelection {
// native tokens, and validation will fail without the capability.
&TransactionCapabilities::all(),
) {
log::debug!("validate_transitions error {err:?}");
println!("validate_transitions error {err:?}");
return Err(Error::UnfulfillableRequirement(Requirement::Foundry(
foundry_output.id(),
)));
Expand All @@ -740,7 +740,7 @@ impl InputSelection {
.expect("ISA is broken because there is no nft input");

if let Err(err) = NftOutput::transition_inner(nft_input.output.as_nft(), nft_output) {
log::debug!("validate_transitions error {err:?}");
println!("validate_transitions error {err:?}");
return Err(Error::UnfulfillableRequirement(Requirement::Nft(*nft_output.nft_id())));
}
}
Expand Down
12 changes: 6 additions & 6 deletions sdk/src/client/api/block_builder/input_selection/remainder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl InputSelection {

// TODO verify_storage_deposit ?

log::debug!("Created storage deposit return output of {diff} for {address:?}");
println!("Created storage deposit return output of {diff} for {address:?}");

storage_deposit_returns.push(srd_output);
}
Expand All @@ -126,7 +126,7 @@ impl InputSelection {
let (input_mana, output_mana) = self.mana_sums(false)?;

if input_amount == output_amount && input_mana == output_mana && native_tokens_diff.is_none() {
log::debug!("No remainder required");
println!("No remainder required");
return Ok((storage_deposit_returns, Vec::new()));
}

Expand All @@ -144,11 +144,11 @@ impl InputSelection {
// 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}");
println!("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");
println!("No more remainder required");
return Ok((storage_deposit_returns, Vec::new()));
}
}
Expand Down Expand Up @@ -269,7 +269,7 @@ fn create_remainder_outputs(
.add_unlock_condition(AddressUnlockCondition::new(remainder_address.clone()))
.with_native_token(*native_token)
.finish_output()?;
log::debug!(
println!(
"Created remainder output of amount {}, mana {} and native token {native_token:?} for {remainder_address:?}",
output.amount(),
output.mana()
Expand All @@ -287,7 +287,7 @@ fn create_remainder_outputs(
}
let catchall = catchall.finish_output()?;
catchall.verify_storage_deposit(storage_score_parameters)?;
log::debug!(
println!(
"Created remainder output of amount {}, mana {} and native token {:?} for {remainder_address:?}",
catchall.amount(),
catchall.mana(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,6 @@ impl InputSelection {
};

if !self.selected_inputs.is_empty() {
// Remainders can only be calculated when the input mana is >= the output mana
let (input_mana, output_mana) = self.mana_sums(false)?;
if input_mana >= output_mana {
// Update remainders so the transaction is valid
self.update_remainders()?;
}

self.selected_inputs = Self::sort_input_signing_data(
std::mem::take(&mut self.selected_inputs),
self.creation_slot,
Expand All @@ -67,46 +60,48 @@ impl InputSelection {
// Add the empty allotment so the work score includes it
self.mana_allotments.entry(issuer_id).or_default();

let transaction = builder
// If the transaction fails to build, just keep going in case another requirement helps
if let Ok(transaction) = builder
.with_context_inputs(self.context_inputs.clone())
.with_mana_allotments(
self.mana_allotments
.iter()
.map(|(&account_id, &mana)| ManaAllotment { account_id, mana }),
)
.finish_with_params(&self.protocol_parameters)?;

let signed_transaction = SignedTransactionPayload::new(transaction, self.null_transaction_unlocks()?)?;

let block_work_score = self.protocol_parameters.work_score(&signed_transaction)
+ self.protocol_parameters.work_score_parameters().block();

let required_allotment_mana = block_work_score as u64 * reference_mana_cost;

let MinManaAllotment {
issuer_id,
allotment_debt,
..
} = self
.min_mana_allotment
.as_mut()
.ok_or(Error::UnfulfillableRequirement(Requirement::Mana))?;

// Add the required allotment to the issuing allotment
if required_allotment_mana > self.mana_allotments[issuer_id] {
log::debug!("Allotting at least {required_allotment_mana} mana to account ID {issuer_id}");
let additional_allotment = required_allotment_mana - self.mana_allotments[&issuer_id];
log::debug!("{additional_allotment} additional mana required to meet minimum allotment");
// Unwrap: safe because we always add the record above
*self.mana_allotments.get_mut(issuer_id).unwrap() = required_allotment_mana;
log::debug!("Adding {additional_allotment} to allotment debt {allotment_debt}");
*allotment_debt += additional_allotment;
} else {
log::debug!("Setting allotment debt to {}", self.mana_allotments[issuer_id]);
*allotment_debt = self.mana_allotments[issuer_id];
}
.finish_with_params(&self.protocol_parameters)
{
let signed_transaction = SignedTransactionPayload::new(transaction, self.null_transaction_unlocks()?)?;

let block_work_score = self.protocol_parameters.work_score(&signed_transaction)
+ self.protocol_parameters.work_score_parameters().block();

let required_allotment_mana = block_work_score as u64 * reference_mana_cost;

let MinManaAllotment {
issuer_id,
allotment_debt,
..
} = self
.min_mana_allotment
.as_mut()
.ok_or(Error::UnfulfillableRequirement(Requirement::Mana))?;

// Add the required allotment to the issuing allotment
if required_allotment_mana > self.mana_allotments[issuer_id] {
println!("Allotting at least {required_allotment_mana} mana to account ID {issuer_id}");
let additional_allotment = required_allotment_mana - self.mana_allotments[&issuer_id];
println!("{additional_allotment} additional mana required to meet minimum allotment");
// Unwrap: safe because we always add the record above
*self.mana_allotments.get_mut(issuer_id).unwrap() = required_allotment_mana;
println!("Adding {additional_allotment} to allotment debt {allotment_debt}");
*allotment_debt += additional_allotment;
} else {
println!("Setting allotment debt to {}", self.mana_allotments[issuer_id]);
*allotment_debt = self.mana_allotments[issuer_id];
}

self.reduce_account_output()?;
self.reduce_account_output()?;
}
}

// Remainders can only be calculated when the input mana is >= the output mana
Expand Down Expand Up @@ -142,7 +137,7 @@ impl InputSelection {
.filter(|o| o.is_account() && o.mana() != 0)
.find(|o| o.as_account().account_id() == issuer_id)
{
log::debug!(
println!(
"Reducing account mana of {} by {} for allotment",
output.as_account().account_id(),
allotment_debt
Expand All @@ -152,7 +147,7 @@ impl InputSelection {
.with_mana(output_mana.saturating_sub(*allotment_debt))
.finish_output()?;
*allotment_debt = allotment_debt.saturating_sub(output_mana);
log::debug!("Allotment debt after reduction: {}", allotment_debt);
println!("Allotment debt after reduction: {}", allotment_debt);
}
Ok(())
}
Expand Down Expand Up @@ -238,10 +233,10 @@ impl InputSelection {
pub(crate) fn get_inputs_for_mana_balance(&mut self) -> Result<Vec<InputSigningData>, Error> {
let (mut selected_mana, required_mana) = self.mana_sums(true)?;

log::debug!("Mana requirement selected mana: {selected_mana}, required mana: {required_mana}");
println!("Mana requirement selected mana: {selected_mana}, required mana: {required_mana}");

if selected_mana >= required_mana {
log::debug!("Mana requirement already fulfilled");
println!("Mana requirement already fulfilled");
Ok(Vec::new())
} else {
let mut inputs = Vec::new();
Expand Down
Loading