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

Clean up wallet syncing code #2108

Merged
merged 46 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
1badfa3
const fn
Alex6323 Mar 1, 2024
bb673e2
sync options
Alex6323 Mar 1, 2024
9b77ea1
Merge branch '2.0' into cleanup-wallet-syncing
Alex6323 Mar 13, 2024
8134473
move instead of clone
Alex6323 Mar 14, 2024
264b2d9
combinators
Alex6323 Mar 14, 2024
010e276
rm unnecessary cloning 1
Alex6323 Mar 14, 2024
abe5f40
rm unnecessary cloning 2
Alex6323 Mar 14, 2024
c5e38fb
slices; impl Into<Option>
Alex6323 Mar 14, 2024
55b5a2f
refactor
Alex6323 Mar 14, 2024
8591c86
get rid of output_data
Alex6323 Mar 14, 2024
7a158a6
Merge branch '2.0' into cleanup-wallet-syncing
Alex6323 Mar 14, 2024
38afbb8
nits
Alex6323 Mar 14, 2024
1cb8c67
clippy
Alex6323 Mar 14, 2024
52e0afb
nit
Alex6323 Mar 14, 2024
99561d7
nest
Alex6323 Mar 15, 2024
afe5ada
nit
Alex6323 Mar 15, 2024
e7e592f
update python binding
Alex6323 Mar 15, 2024
0cc5e29
update nodejs binding
Alex6323 Mar 15, 2024
2f1c6e9
update core binding
Alex6323 Mar 15, 2024
dea3c64
rm output_data.py
Alex6323 Mar 15, 2024
863c7d1
nit
Alex6323 Mar 15, 2024
d035c55
suggestion
Alex6323 Mar 15, 2024
be7dcbb
rename local var
Alex6323 Mar 15, 2024
8dcb842
fix tests and clippy
Alex6323 Mar 15, 2024
62a9541
ci-doc
Alex6323 Mar 15, 2024
119fad0
rm HashSet piping of foundry output ids
Alex6323 Mar 15, 2024
ca13a6c
rm TODO
Alex6323 Mar 15, 2024
fec6cfd
fix nodejs how-to
Alex6323 Mar 15, 2024
b923a00
Merge branch '2.0' into cleanup-wallet-syncing
Alex6323 Mar 19, 2024
d12be48
Merge branch '2.0' into cleanup-wallet-syncing
Alex6323 Mar 22, 2024
0159dc9
remove todo
Alex6323 Mar 22, 2024
94de389
Merge branch '2.0' into cleanup-wallet-syncing
DaughterOfMars Mar 22, 2024
48b6661
Merge branch '2.0' into cleanup-wallet-syncing
Alex6323 Mar 27, 2024
e91b2af
undo rename
Alex6323 Apr 15, 2024
ea08631
Merge branch 'upstream/2.0' into cleanup-wallet-syncing
Alex6323 Apr 15, 2024
c3f0ae6
Merge branch '2.0' into cleanup-wallet-syncing
Alex6323 Apr 17, 2024
94419c4
Merge branch 'upstream/2.0' into cleanup-wallet-syncing
Alex6323 Apr 26, 2024
d7f4443
rust: cleanup
Alex6323 Apr 29, 2024
9e0e4e3
python: cleanup
Alex6323 Apr 29, 2024
f69965a
nodejs: cleanup
Alex6323 Apr 29, 2024
346ab5f
Merge branch '2.0' into cleanup-wallet-syncing
Alex6323 Apr 29, 2024
38b7bfc
rust: more cleanup
Alex6323 Apr 29, 2024
5de120c
Merge branch '2.0' into cleanup-wallet-syncing
Alex6323 Apr 30, 2024
a9100c3
...
Alex6323 Apr 30, 2024
b745c52
....
Alex6323 Apr 30, 2024
6412d7c
.....
Alex6323 Apr 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions bindings/core/src/method/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ pub enum WalletMethod {
/// Expected response: [`Transaction`](crate::Response::Transaction)
#[serde(rename_all = "camelCase")]
GetIncomingTransaction { transaction_id: TransactionId },
/// Get the [`OutputData`](iota_sdk::wallet::types::OutputData) of an output stored in the wallet.
/// Expected response: [`OutputData`](crate::Response::OutputData)
/// Get the [`OutputWithExtendedMetadata`](iota_sdk::wallet::types::OutputWithExtendedMetadata) of an output stored
/// in the wallet. Expected response: [`OutputData`](crate::Response::OutputData)
#[serde(rename_all = "camelCase")]
GetOutput { output_id: OutputId },
// /// Expected response: [`ParticipationEvent`](crate::Response::ParticipationEvent)
Expand Down
8 changes: 5 additions & 3 deletions bindings/core/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use iota_sdk::{
},
utils::serde::string,
wallet::{
types::{Balance, OutputData, TransactionWithMetadataDto},
types::{Balance, OutputWithExtendedMetadata, TransactionWithMetadataDto},
PreparedCreateDelegationTransaction, PreparedCreateNativeTokenTransaction,
},
};
Expand Down Expand Up @@ -300,13 +300,15 @@ pub enum Response {
/// Response for:
/// - [`ClaimableOutputs`](crate::method::WalletMethod::ClaimableOutputs)
OutputIds(Vec<OutputId>),
// TODO: update bindings in a separate PR
/// Response for:
/// - [`GetOutput`](crate::method::WalletMethod::GetOutput)
OutputData(Option<Box<OutputData>>),
OutputData(Option<Box<OutputWithExtendedMetadata>>),
// TODO: update bindings in a separate PR
Thoralf-M marked this conversation as resolved.
Show resolved Hide resolved
/// Response for:
/// - [`Outputs`](crate::method::WalletMethod::Outputs),
/// - [`UnspentOutputs`](crate::method::WalletMethod::UnspentOutputs)
OutputsData(Vec<OutputData>),
OutputsData(Vec<OutputWithExtendedMetadata>),
/// Response for:
/// - [`PrepareBurn`](crate::method::WalletMethod::PrepareBurn),
/// - [`PrepareClaimOutputs`](crate::method::WalletMethod::PrepareClaimOutputs)
Expand Down
40 changes: 22 additions & 18 deletions cli/src/wallet_cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ use iota_sdk::{
},
utils::ConvertTo,
wallet::{
types::OutputData, BeginStakingParams, ConsolidationParams, CreateDelegationParams, CreateNativeTokenParams,
MintNftParams, OutputsToClaim, ReturnStrategy, SendManaParams, SendNativeTokenParams, SendNftParams,
SendParams, SyncOptions, Wallet, WalletError,
types::OutputWithExtendedMetadata, BeginStakingParams, ConsolidationParams, CreateDelegationParams,
CreateNativeTokenParams, MintNftParams, OutputsToClaim, ReturnStrategy, SendManaParams, SendNativeTokenParams,
SendNftParams, SendParams, SyncOptions, Wallet, WalletError,
},
U256,
};
Expand Down Expand Up @@ -1289,31 +1289,31 @@ async fn print_wallet_address(wallet: &Wallet) -> Result<(), Error> {
let mut delegations = Vec::new();
let mut anchors = Vec::new();

for output_data in wallet.ledger().await.unspent_outputs().values() {
let output_id = output_data.output_id;
for output_with_ext_metadata in wallet.ledger().await.unspent_outputs().values() {
Thoralf-M marked this conversation as resolved.
Show resolved Hide resolved
let output_id = output_with_ext_metadata.output_id;
output_ids.push(output_id);

// Output might be associated with the address, but can't be unlocked by it, so we check that here.
let required_address = &output_data
let required_address = &output_with_ext_metadata
.output
.required_address(slot_index, protocol_parameters.committable_age_range())?;

if required_address
.as_ref()
.is_some_and(|required_address| required_address == address.inner())
{
if let Some(nt) = output_data.output.native_token() {
if let Some(nt) = output_with_ext_metadata.output.native_token() {
native_tokens.add_native_token(*nt)?;
}
match &output_data.output {
match &output_with_ext_metadata.output {
Output::Basic(_) => {}
Output::Account(account) => accounts.push(account.account_id_non_null(&output_id)),
Output::Foundry(foundry) => foundries.push(foundry.id()),
Output::Nft(nft) => nfts.push(nft.nft_id_non_null(&output_id)),
Output::Delegation(delegation) => delegations.push(delegation.delegation_id_non_null(&output_id)),
Output::Anchor(anchor) => anchors.push(anchor.anchor_id_non_null(&output_id)),
}
let unlock_conditions = output_data
let unlock_conditions = output_with_ext_metadata
.output
.unlock_conditions()
.expect("output must have unlock conditions");
Expand All @@ -1322,7 +1322,7 @@ async fn print_wallet_address(wallet: &Wallet) -> Result<(), Error> {
.map(|sdr| sdr.amount())
.unwrap_or(0);

amount += output_data.output.amount() - sdr_amount;
amount += output_with_ext_metadata.output.amount() - sdr_amount;
}
}

Expand Down Expand Up @@ -1650,26 +1650,30 @@ pub async fn prompt_internal(
Ok(PromptResponse::Reprompt)
}

fn print_outputs(mut outputs: Vec<OutputData>, title: &str) -> Result<(), Error> {
if outputs.is_empty() {
fn print_outputs(mut outputs_with_ext_metadata: Vec<OutputWithExtendedMetadata>, title: &str) -> Result<(), Error> {
if outputs_with_ext_metadata.is_empty() {
println_log_info!("No outputs found");
} else {
println_log_info!("{title}");
outputs.sort_unstable_by_key(|o| o.output_id);
outputs_with_ext_metadata.sort_unstable_by_key(|o| o.output_id);

for (i, output_data) in outputs.into_iter().enumerate() {
let kind_str = if output_data.output.is_implicit_account() {
for (i, output_with_ext_metadata) in outputs_with_ext_metadata.into_iter().enumerate() {
let kind_str = if output_with_ext_metadata.output.is_implicit_account() {
"ImplicitAccount"
} else {
output_data.output.kind_str()
output_with_ext_metadata.output.kind_str()
};

println_log_info!(
"{:<5}{} {:<16}{}",
i,
&output_data.output_id,
&output_with_ext_metadata.output_id,
kind_str,
if output_data.is_spent() { "Spent" } else { "Unspent" },
if output_with_ext_metadata.is_spent() {
"Spent"
} else {
"Unspent"
},
);
}
}
Expand Down
12 changes: 6 additions & 6 deletions sdk/examples/how_tos/wallet/consolidate_outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.unspent_outputs()
.values()
.enumerate()
.for_each(|(i, output_data)| {
.for_each(|(i, output_with_ext_metadata)| {
println!("OUTPUT #{i}");
println!(
"- amount: {:?}\n- native tokens: {:?}",
output_data.output.amount(),
output_data.output.native_token()
output_with_ext_metadata.output.amount(),
output_with_ext_metadata.output.native_token()
)
});

Expand Down Expand Up @@ -91,12 +91,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.unspent_outputs()
.values()
.enumerate()
.for_each(|(i, output_data)| {
.for_each(|(i, output_with_ext_metadata)| {
println!("OUTPUT #{i}");
println!(
"- amount: {:?}\n- native tokens: {:?}",
output_data.output.amount(),
output_data.output.native_token()
output_with_ext_metadata.output.amount(),
output_with_ext_metadata.output.native_token()
)
});

Expand Down
50 changes: 25 additions & 25 deletions sdk/src/wallet/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use crate::{
},
TryFromDto,
},
wallet::{operations::syncing::SyncOptions, types::OutputData, FilterOptions, WalletError},
wallet::{operations::syncing::SyncOptions, types::OutputWithExtendedMetadata, FilterOptions, WalletError},
};

/// The stateful wallet used to interact with an IOTA network.
Expand Down Expand Up @@ -111,14 +111,14 @@ pub struct WalletInner<S: SecretManage = SecretManager> {
pub struct WalletLedger {
/// Outputs
// stored separated from the wallet for performance?
pub(crate) outputs: HashMap<OutputId, OutputData>,
pub(crate) outputs: HashMap<OutputId, OutputWithExtendedMetadata>,
/// Unspent outputs that are currently used as input for transactions
// outputs used in transactions should be locked here so they don't get used again, which would result in a
// conflicting transaction
pub(crate) locked_outputs: HashSet<OutputId>,
/// Unspent outputs
// have unspent outputs in a separated hashmap so we don't need to iterate over all outputs we have
pub(crate) unspent_outputs: HashMap<OutputId, OutputData>,
pub(crate) unspent_outputs: HashMap<OutputId, OutputWithExtendedMetadata>,
/// Sent transactions
// stored separated from the wallet for performance and only the transaction id here? where to add the network id?
// transactions: HashSet<TransactionId>,
Expand All @@ -139,9 +139,9 @@ pub struct WalletLedger {

impl WalletLedger {
fn filter_outputs<'a>(
outputs: impl Iterator<Item = &'a OutputData>,
outputs: impl Iterator<Item = &'a OutputWithExtendedMetadata>,
filter: FilterOptions,
) -> impl Iterator<Item = &'a OutputData> {
) -> impl Iterator<Item = &'a OutputWithExtendedMetadata> {
outputs.filter(move |output| {
match &output.output {
Output::Account(account) => {
Expand Down Expand Up @@ -219,27 +219,27 @@ impl WalletLedger {
}

/// Returns outputs map of the wallet.
pub fn outputs(&self) -> &HashMap<OutputId, OutputData> {
pub fn outputs(&self) -> &HashMap<OutputId, OutputWithExtendedMetadata> {
&self.outputs
}

/// Returns unspent outputs map of the wallet.
pub fn unspent_outputs(&self) -> &HashMap<OutputId, OutputData> {
pub fn unspent_outputs(&self) -> &HashMap<OutputId, OutputWithExtendedMetadata> {
&self.unspent_outputs
}

/// Returns outputs of the wallet.
pub fn filtered_outputs(&self, filter: FilterOptions) -> impl Iterator<Item = &OutputData> {
pub fn filtered_outputs(&self, filter: FilterOptions) -> impl Iterator<Item = &OutputWithExtendedMetadata> {
Self::filter_outputs(self.outputs.values(), filter)
}

/// Returns unspent outputs of the wallet.
pub fn filtered_unspent_outputs(&self, filter: FilterOptions) -> impl Iterator<Item = &OutputData> {
pub fn filtered_unspent_outputs(&self, filter: FilterOptions) -> impl Iterator<Item = &OutputWithExtendedMetadata> {
Self::filter_outputs(self.unspent_outputs.values(), filter)
}

/// Gets the unspent account output matching the given ID.
pub fn unspent_account_output(&self, account_id: &AccountId) -> Option<&OutputData> {
pub fn unspent_account_output(&self, account_id: &AccountId) -> Option<&OutputWithExtendedMetadata> {
self.filtered_unspent_outputs(FilterOptions {
account_ids: Some([*account_id].into()),
..Default::default()
Expand All @@ -248,7 +248,7 @@ impl WalletLedger {
}

/// Gets the unspent anchor output matching the given ID.
pub fn unspent_anchor_output(&self, anchor_id: &AnchorId) -> Option<&OutputData> {
pub fn unspent_anchor_output(&self, anchor_id: &AnchorId) -> Option<&OutputWithExtendedMetadata> {
self.filtered_unspent_outputs(FilterOptions {
anchor_ids: Some([*anchor_id].into()),
..Default::default()
Expand All @@ -257,7 +257,7 @@ impl WalletLedger {
}

/// Gets the unspent foundry output matching the given ID.
pub fn unspent_foundry_output(&self, foundry_id: &FoundryId) -> Option<&OutputData> {
pub fn unspent_foundry_output(&self, foundry_id: &FoundryId) -> Option<&OutputWithExtendedMetadata> {
self.filtered_unspent_outputs(FilterOptions {
foundry_ids: Some([*foundry_id].into()),
..Default::default()
Expand All @@ -266,7 +266,7 @@ impl WalletLedger {
}

/// Gets the unspent nft output matching the given ID.
pub fn unspent_nft_output(&self, nft_id: &NftId) -> Option<&OutputData> {
pub fn unspent_nft_output(&self, nft_id: &NftId) -> Option<&OutputWithExtendedMetadata> {
self.filtered_unspent_outputs(FilterOptions {
nft_ids: Some([*nft_id].into()),
..Default::default()
Expand All @@ -275,7 +275,7 @@ impl WalletLedger {
}

/// Gets the unspent delegation output matching the given ID.
pub fn unspent_delegation_output(&self, delegation_id: &DelegationId) -> Option<&OutputData> {
pub fn unspent_delegation_output(&self, delegation_id: &DelegationId) -> Option<&OutputWithExtendedMetadata> {
self.filtered_unspent_outputs(FilterOptions {
delegation_ids: Some([*delegation_id].into()),
..Default::default()
Expand All @@ -284,17 +284,17 @@ impl WalletLedger {
}

/// Returns implicit accounts of the wallet.
pub fn implicit_accounts(&self) -> impl Iterator<Item = &OutputData> {
pub fn implicit_accounts(&self) -> impl Iterator<Item = &OutputWithExtendedMetadata> {
self.unspent_outputs
.values()
.filter(|output_data| output_data.output.is_implicit_account())
.filter(|output_with_ext_metadata| output_with_ext_metadata.output.is_implicit_account())
}

/// Returns accounts of the wallet.
pub fn accounts(&self) -> impl Iterator<Item = &OutputData> {
pub fn accounts(&self) -> impl Iterator<Item = &OutputWithExtendedMetadata> {
self.unspent_outputs
.values()
.filter(|output_data| output_data.output.is_account())
.filter(|output_with_ext_metadata| output_with_ext_metadata.output.is_account())
}

// Returns the first possible Account id, which can be an implicit account.
Expand All @@ -305,8 +305,8 @@ impl WalletLedger {
.or_else(|| self.implicit_accounts().next().map(|o| AccountId::from(&o.output_id)))
}

/// Get the [`OutputData`] of an output stored in the wallet.
pub fn get_output(&self, output_id: &OutputId) -> Option<&OutputData> {
/// Get the [`OutputWithExtendedMetadata`] of an output stored in the wallet.
pub fn get_output(&self, output_id: &OutputId) -> Option<&OutputWithExtendedMetadata> {
self.outputs.get(output_id)
}

Expand Down Expand Up @@ -345,10 +345,10 @@ impl<S: 'static + SecretManage> Wallet<S> {
pub async fn get_foundry_output(&self, native_token_id: TokenId) -> Result<Output, WalletError> {
let foundry_id = FoundryId::from(native_token_id);

for output_data in self.ledger.read().await.outputs.values() {
if let Output::Foundry(foundry_output) = &output_data.output {
for output_with_ext_metadata in self.ledger.read().await.outputs.values() {
if let Output::Foundry(foundry_output) = &output_with_ext_metadata.output {
if foundry_output.id() == foundry_id {
return Ok(output_data.output.clone());
return Ok(output_with_ext_metadata.output.clone());
}
}
}
Expand Down Expand Up @@ -495,9 +495,9 @@ impl<S: SecretManage> Drop for WalletInner<S> {
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WalletLedgerDto {
pub outputs: HashMap<OutputId, OutputData>,
pub outputs: HashMap<OutputId, OutputWithExtendedMetadata>,
pub locked_outputs: HashSet<OutputId>,
pub unspent_outputs: HashMap<OutputId, OutputData>,
pub unspent_outputs: HashMap<OutputId, OutputWithExtendedMetadata>,
pub transactions: HashMap<TransactionId, TransactionWithMetadataDto>,
pub pending_transactions: HashSet<TransactionId>,
pub incoming_transactions: HashMap<TransactionId, TransactionWithMetadataDto>,
Expand Down
3 changes: 2 additions & 1 deletion sdk/src/wallet/core/operations/background_syncing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ where
/// Start the background syncing process for the wallet, default interval is 7 seconds
pub async fn start_background_syncing(
&self,
options: Option<SyncOptions>,
options: impl Into<Option<SyncOptions>> + Send,
interval: Option<Duration>,
) -> Result<(), WalletError> {
log::debug!("[start_background_syncing]");

let options = options.into();
let (tx_background_sync, mut rx_background_sync) = self.background_syncing_status.clone();

// stop existing process if running
Expand Down
6 changes: 3 additions & 3 deletions sdk/src/wallet/events/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
payload::signed_transaction::{dto::SignedTransactionPayloadDto, TransactionId},
},
wallet::{
types::{InclusionState, OutputData},
types::{InclusionState, OutputWithExtendedMetadata},
WalletError,
},
};
Expand Down Expand Up @@ -167,7 +167,7 @@ impl TryFrom<u8> for WalletEventType {
#[serde(rename_all = "camelCase")]
pub struct NewOutputEvent {
/// The new output.
pub output: OutputData,
pub output: OutputWithExtendedMetadata,
/// The transaction that created the output. Might be pruned and not available.
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction: Option<SignedTransactionPayloadDto>,
Expand All @@ -179,7 +179,7 @@ pub struct NewOutputEvent {
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct SpentOutputEvent {
/// The spent output.
pub output: OutputData,
pub output: OutputWithExtendedMetadata,
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub use self::{
prepare_output::{Assets, Features, OutputParams, ReturnStrategy, StorageDeposit, Unlocks},
},
},
types::OutputData,
types::OutputWithExtendedMetadata,
};
use crate::{
types::{
Expand Down