Skip to content

Commit

Permalink
Add automatic mana allotment (#1961)
Browse files Browse the repository at this point in the history
* Add automatic mana allotment

* rework

* better loop

* set mana allotment to 1 not 0

* better error when there is insufficient mana provided

* make auto mana allotment optional

* revert some accidental changes

* missed

* rework transaction options

* improvements

* sort

* privatize

* fix mana addition on newly selected inputs

* Allow ISA to add mana to existing outputs

* better calculation

* little cleanup

* fix slot usage and detect mana remainder more accurately

* add some debug logging

* rename to required

* more renames

* make context inputs optional

* remove hard coded reward index

* another

* Allow using account mana for allotments, fix semantic validation

* Add test

* carry over previous required allotment value

* add more tests

* simplify

* more simpler

* just build the transaction in ISA

* cleanup

* increase mana bits to fix tests

* review

* Set automatically transitioned account mana to zero and order mana remainder output choices

* fix python

* unused import

* rename tests

* don't stack allotments

* track allotment debt for future selected accounts

* more unused imports

* Rework allotment

* skip allotment step if there are no inputs selected

* Loop over remainder calculations too

* fix last test

* one more creation slot usage

* only add mana to added outputs with no weird unlock conditions

* merge mana and allotments

* include provided

* fix amount sums

* remove automatically_transitioned

* unused import

* rework allotment again

* fix skipping allotment

---------

Co-authored-by: Thoralf Müller <[email protected]>
  • Loading branch information
DaughterOfMars and Thoralf-M authored Feb 15, 2024
1 parent 9db1a88 commit 7671804
Show file tree
Hide file tree
Showing 66 changed files with 2,430 additions and 1,461 deletions.
3 changes: 1 addition & 2 deletions bindings/core/src/method_handler/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,6 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM
&wallet.client().get_protocol_parameters().await?,
)?,
None,
None,
)
.await?;
Response::SentTransaction(TransactionWithMetadataDto::from(&transaction))
Expand All @@ -438,7 +437,7 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM
&wallet.client().get_protocol_parameters().await?,
)?;
let transaction = wallet
.submit_and_store_transaction(signed_transaction_data, None, None)
.submit_and_store_transaction(signed_transaction_data, None)
.await?;
Response::SentTransaction(TransactionWithMetadataDto::from(&transaction))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ async function run() {
},
];
const options = {
mandatoryInputs: [input],
requiredInputs: [input],
allowMicroAmount: false,
};
const transaction = await wallet.sendWithParams(params, options);
Expand Down
26 changes: 18 additions & 8 deletions bindings/nodejs/lib/types/wallet/transaction-options.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
// Copyright 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { AccountAddress, AccountId, Bech32Address, OutputId } from '../block';
import {
AccountAddress,
AccountId,
Bech32Address,
ContextInput,
OutputId,
} from '../block';
import { TaggedDataPayload } from '../block/payload/tagged';
import { Burn } from '../client';
import { u256, HexEncodedString, NumericString, u64 } from '../utils';
Expand All @@ -13,20 +19,24 @@ export interface TransactionOptions {
remainderValueStrategy?: RemainderValueStrategy;
/** An optional tagged data payload. */
taggedDataPayload?: TaggedDataPayload;
/**
* Custom inputs that should be used for the transaction.
* If custom inputs are provided, only those are used.
* If also other additional inputs should be used, `mandatoryInputs` should be used instead.
*/
customInputs?: OutputId[];
/** Transaction context inputs to include. */
contextInputs?: ContextInput[];
/** Inputs that must be used for the transaction. */
mandatoryInputs?: OutputId[];
requiredInputs?: OutputId[];
/** Specifies what needs to be burned during input selection. */
burn?: Burn;
/** Optional note, that is only stored locally. */
note?: string;
/** Whether to allow sending a micro amount. */
allowMicroAmount?: boolean;
/** Whether to allow the selection of additional inputs for this transaction. */
allowAdditionalInputSelection?: boolean;
/** Transaction capabilities. */
capabilities?: HexEncodedString;
/** Mana allotments for the transaction. */
manaAllotments?: { [account_id: AccountId]: u64 };
/** Optional block issuer to which the transaction will have required mana allotted. */
issuerId?: AccountId;
}

/** The possible remainder value strategies. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
amount=1000000,
)]
options = {
'mandatoryInputs': inputs,
'requiredInputs': inputs,
}
transaction = wallet.send_with_params(params, options)
wallet.wait_for_transaction_acceptance(
Expand Down
31 changes: 22 additions & 9 deletions bindings/python/iota_sdk/types/transaction_options.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Copyright 2023 IOTA Stiftung
# Copyright 2024 IOTA Stiftung
# SPDX-License-Identifier: Apache-2.0

from enum import Enum
from typing import Optional, List, Union
from dataclasses import dataclass
from iota_sdk.types.burn import Burn
from iota_sdk.types.common import json
from iota_sdk.types.common import HexStr, json
from iota_sdk.types.context_input import ContextInput
from iota_sdk.types.output_id import OutputId
from iota_sdk.types.payload import TaggedDataPayload

Expand Down Expand Up @@ -68,26 +69,38 @@ class TransactionOptions:
Attributes:
remainder_value_strategy: The strategy applied for base coin remainders.
tagged_data_payload: An optional tagged data payload.
custom_inputs: If custom inputs are provided only those are used. If also other additional inputs should be used, `mandatory_inputs` should be used instead.
mandatory_inputs: Inputs that must be used for the transaction.
context_inputs: Transaction context inputs to include.
required_inputs: Inputs that must be used for the transaction.
burn: Specifies what needs to be burned during input selection.
note: A string attached to the transaction.
allow_micro_amount: Whether to allow sending a micro amount.
allow_additional_input_selection: Whether to allow the selection of additional inputs for this transaction.
capabilities: Transaction capabilities.
mana_allotments: Mana allotments for the transaction.
issuer_id: Optional block issuer to which the transaction will have required mana allotted.
"""

def __init__(self, remainder_value_strategy: Optional[Union[RemainderValueStrategy, RemainderValueStrategyCustomAddress]] = None,
tagged_data_payload: Optional[TaggedDataPayload] = None,
custom_inputs: Optional[List[OutputId]] = None,
mandatory_inputs: Optional[List[OutputId]] = None,
context_inputs: Optional[List[ContextInput]] = None,
required_inputs: Optional[List[OutputId]] = None,
burn: Optional[Burn] = None,
note: Optional[str] = None,
allow_micro_amount: Optional[bool] = None):
allow_micro_amount: Optional[bool] = None,
allow_additional_input_selection: Optional[bool] = None,
capabilities: Optional[HexStr] = None,
mana_allotments: Optional[dict[HexStr, int]] = None,
issuer_id: Optional[HexStr] = None):
"""Initialize transaction options.
"""
self.remainder_value_strategy = remainder_value_strategy
self.tagged_data_payload = tagged_data_payload
self.custom_inputs = custom_inputs
self.mandatory_inputs = mandatory_inputs
self.context_inputs = context_inputs
self.required_inputs = required_inputs
self.burn = burn
self.note = note
self.allow_micro_amount = allow_micro_amount
self.allow_additional_input_selection = allow_additional_input_selection
self.capabilities = capabilities
self.mana_allotments = mana_allotments
self.issuer_id = issuer_id
4 changes: 2 additions & 2 deletions sdk/examples/how_tos/account_output/send_amount.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023 IOTA Stiftung
// Copyright 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

//! In this example we use an account as wallet.
Expand Down Expand Up @@ -66,7 +66,7 @@ async fn main() -> Result<()> {
1_000_000,
"rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu",
TransactionOptions {
mandatory_inputs: Some(vec![input]),
required_inputs: [input].into(),
..Default::default()
},
)
Expand Down
2 changes: 1 addition & 1 deletion sdk/examples/wallet/offline_signing/3_send_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ async fn main() -> Result<()> {

// Sends offline signed transaction online.
let transaction = wallet
.submit_and_store_transaction(signed_transaction_data, None, None)
.submit_and_store_transaction(signed_transaction_data, None)
.await?;
wait_for_inclusion(&transaction.transaction_id, &wallet).await?;

Expand Down
12 changes: 11 additions & 1 deletion sdk/src/client/api/block_builder/input_selection/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023 IOTA Stiftung
// Copyright 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

//! Error handling for input selection.
Expand All @@ -14,6 +14,8 @@ use crate::types::block::output::{ChainId, OutputId, TokenId};
#[derive(Debug, Eq, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("additional inputs required for {0:?}, but additional input selection is disabled")]
AdditionalInputsRequired(Requirement),
/// Block error.
#[error("{0}")]
Block(#[from] crate::types::block::Error),
Expand All @@ -30,6 +32,14 @@ pub enum Error {
/// The required amount.
required: u64,
},
/// Insufficient mana provided.
#[error("insufficient mana: found {found}, required {required}")]
InsufficientMana {
/// The amount found.
found: u64,
/// The required amount.
required: u64,
},
/// Insufficient native token amount provided.
#[error("insufficient native token amount: found {found}, required {required}")]
InsufficientNativeTokenAmount {
Expand Down
Loading

0 comments on commit 7671804

Please sign in to comment.