Skip to content

Commit

Permalink
Return Result from locked_address()
Browse files Browse the repository at this point in the history
  • Loading branch information
Thoralf-M committed Dec 6, 2023
1 parent 0526617 commit b73f82f
Show file tree
Hide file tree
Showing 13 changed files with 31 additions and 35 deletions.
1 change: 1 addition & 0 deletions sdk/src/client/api/block_builder/input_selection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ impl InputSelection {
remainder_address: None,
protocol_parameters,
// TODO may want to make this mandatory at some point
// Should be set from a commitment context input
slot_index: SlotIndex::from(0),
requirements: Vec::new(),
automatically_transitioned: HashSet::new(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ impl InputSelection {
self.slot_index,
self.protocol_parameters.committable_age_range(),
)
.expect("slot index was provided")
.expect("expiration unlockable outputs already filtered out")
.is_ed25519()
} else {
Expand All @@ -372,6 +373,7 @@ impl InputSelection {
self.slot_index,
self.protocol_parameters.committable_age_range(),
)
.expect("slot index was provided")
.expect("expiration unlockable outputs already filtered out")
.is_ed25519()
} else {
Expand Down
3 changes: 1 addition & 2 deletions sdk/src/client/secret/ledger_nano.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,7 @@ fn merge_unlocks(
.transaction
.context_inputs()
.iter()
.find_map(|c| c.as_commitment_opt().map(|c| c.slot_index()))
.unwrap_or_else(|| prepared_transaction_data.transaction.creation_slot());
.find_map(|c| c.as_commitment_opt().map(|c| c.slot_index()));
let transaction_signing_hash = prepared_transaction_data.transaction.signing_hash();

let mut merged_unlocks = Vec::new();
Expand Down
3 changes: 1 addition & 2 deletions sdk/src/client/secret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,8 +557,7 @@ where
.transaction
.context_inputs()
.iter()
.find_map(|c| c.as_commitment_opt().map(|c| c.slot_index()))
.unwrap_or_else(|| prepared_transaction_data.transaction.creation_slot());
.find_map(|c| c.as_commitment_opt().map(|c| c.slot_index()));

// Assuming inputs_data is ordered by address type
for (current_block_index, input) in prepared_transaction_data.inputs_data.iter().enumerate() {
Expand Down
2 changes: 2 additions & 0 deletions sdk/src/types/block/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ pub enum Error {
MissingAddressUnlockCondition,
MissingGovernorUnlockCondition,
MissingStateControllerUnlockCondition,
MissingSlotIndex,
NativeTokensNotUniqueSorted,
NativeTokensNullAmount,
NativeTokensOverflow,
Expand Down Expand Up @@ -367,6 +368,7 @@ impl fmt::Display for Error {
Self::MissingAddressUnlockCondition => write!(f, "missing address unlock condition"),
Self::MissingGovernorUnlockCondition => write!(f, "missing governor unlock condition"),
Self::MissingStateControllerUnlockCondition => write!(f, "missing state controller unlock condition"),
Self::MissingSlotIndex => write!(f, "missing slot index"),
Self::NativeTokensNotUniqueSorted => write!(f, "native tokens are not unique and/or sorted"),
Self::NativeTokensNullAmount => write!(f, "native tokens null amount"),
Self::NativeTokensOverflow => write!(f, "native tokens overflow"),
Expand Down
3 changes: 2 additions & 1 deletion sdk/src/types/block/output/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,12 @@ impl AccountOutput {
self.unlock_conditions()
.locked_address(
self.address(),
context.transaction.creation_slot(),
None,
context.protocol_parameters.committable_age_range(),
)
// Safe to unwrap, AccountOutput can't have an expiration unlock condition.
.unwrap()
.unwrap()
.unlock(unlock, context)?;

let account_id = if self.account_id().is_null() {
Expand Down
12 changes: 2 additions & 10 deletions sdk/src/types/block/output/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use crate::types::block::{
},
protocol::{ProtocolParameters, WorkScore, WorkScoreParameters},
semantic::{SemanticValidationContext, TransactionFailureReason},
slot::SlotIndex,
unlock::Unlock,
Error,
};
Expand Down Expand Up @@ -326,20 +325,13 @@ impl BasicOutput {
.iter()
.find_map(|c| c.as_commitment_opt().map(|c| c.slot_index()));

if slot_index.is_none()
&& (self.unlock_conditions().timelock().is_some() || self.unlock_conditions().expiration().is_some())
{
// Missing CommitmentContextInput
return Err(TransactionFailureReason::InvalidCommitmentContextInput);
}

self.unlock_conditions()
.locked_address(
self.address(),
// Safe to unwrap, we return an error before if its required but None
slot_index.unwrap_or(SlotIndex(0)),
slot_index,
context.protocol_parameters.committable_age_range(),
)
.map_err(|_| TransactionFailureReason::InvalidCommitmentContextInput)?
// because of expiration the input can't be unlocked at this time
.ok_or(TransactionFailureReason::SemanticValidationFailed)?
.unlock(unlock, context)
Expand Down
3 changes: 2 additions & 1 deletion sdk/src/types/block/output/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,11 +326,12 @@ impl DelegationOutput {
self.unlock_conditions()
.locked_address(
self.address(),
context.transaction.creation_slot(),
None,
context.protocol_parameters.committable_age_range(),
)
// Safe to unwrap, DelegationOutput can't have an expiration unlock condition.
.unwrap()
.unwrap()
.unlock(unlock, context)
}

Expand Down
6 changes: 3 additions & 3 deletions sdk/src/types/block/output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,20 +272,20 @@ impl Output {
/// Returns the address that is required to unlock this [`Output`].
pub fn required_address(
&self,
slot_index: impl Into<SlotIndex>,
slot_index: impl Into<Option<SlotIndex>>,
committable_age_range: CommittableAgeRange,
) -> Result<Option<Address>, Error> {
Ok(match self {
Self::Basic(output) => output
.unlock_conditions()
.locked_address(output.address(), slot_index, committable_age_range)
.locked_address(output.address(), slot_index, committable_age_range)?
.cloned(),
Self::Account(output) => Some(output.address().clone()),
Self::Anchor(_) => return Err(Error::UnsupportedOutputKind(AnchorOutput::KIND)),
Self::Foundry(output) => Some(Address::Account(*output.account_address())),
Self::Nft(output) => output
.unlock_conditions()
.locked_address(output.address(), slot_index, committable_age_range)
.locked_address(output.address(), slot_index, committable_age_range)?
.cloned(),
Self::Delegation(output) => Some(output.address().clone()),
})
Expand Down
12 changes: 2 additions & 10 deletions sdk/src/types/block/output/nft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use crate::types::block::{
payload::signed_transaction::TransactionCapabilityFlag,
protocol::{ProtocolParameters, WorkScore, WorkScoreParameters},
semantic::{SemanticValidationContext, TransactionFailureReason},
slot::SlotIndex,
unlock::Unlock,
Error,
};
Expand Down Expand Up @@ -421,20 +420,13 @@ impl NftOutput {
.iter()
.find_map(|c| c.as_commitment_opt().map(|c| c.slot_index()));

if slot_index.is_none()
&& (self.unlock_conditions().timelock().is_some() || self.unlock_conditions().expiration().is_some())
{
// Missing CommitmentContextInput
return Err(TransactionFailureReason::InvalidCommitmentContextInput);
}

self.unlock_conditions()
.locked_address(
self.address(),
// Safe to unwrap, we return an error before if its required but None
slot_index.unwrap_or(SlotIndex(0)),
slot_index,
context.protocol_parameters.committable_age_range(),
)
.map_err(|_| TransactionFailureReason::InvalidCommitmentContextInput)?
// because of expiration the input can't be unlocked at this time
.ok_or(TransactionFailureReason::SemanticValidationFailed)?
.unlock(unlock, context)?;
Expand Down
13 changes: 9 additions & 4 deletions sdk/src/types/block/output/unlock_condition/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,12 +302,17 @@ impl UnlockConditions {
pub fn locked_address<'a>(
&'a self,
address: &'a Address,
slot_index: impl Into<SlotIndex>,
slot_index: impl Into<Option<SlotIndex>>,
committable_age_range: CommittableAgeRange,
) -> Option<&'a Address> {
self.expiration().map_or(Some(address), |expiration| {
) -> Result<Option<&'a Address>, Error> {
let address = if let Some(expiration) = self.expiration() {
let slot_index = slot_index.into().ok_or(Error::MissingSlotIndex)?;
expiration.return_address_expired(address, slot_index, committable_age_range)
})
} else {
Some(address)
};

Ok(address)
}
}

Expand Down
4 changes: 3 additions & 1 deletion sdk/src/wallet/operations/helpers/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ pub(crate) fn can_output_be_unlocked_now(
}
}

let required_address = output_data.output.required_address(slot_index, committable_age_range)?;
let required_address = output_data
.output
.required_address(slot_index.into(), committable_age_range)?;

// In case of `None` the output can currently not be unlocked because of expiration unlock condition
required_address.map_or_else(|| Ok(false), |required_address| Ok(wallet_address == &required_address))
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/wallet/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl OutputData {
) -> crate::wallet::Result<Option<InputSigningData>> {
let required_address = self
.output
.required_address(slot_index, committable_age_range)?
.required_address(slot_index.into(), committable_age_range)?
.ok_or(crate::client::Error::ExpirationDeadzone)?;

let chain = if required_address == self.address {
Expand Down

0 comments on commit b73f82f

Please sign in to comment.