diff --git a/dan_layer/engine/src/runtime/address_allocation.rs b/dan_layer/engine/src/runtime/address_allocation.rs index 87e69da06..f7d16f8af 100644 --- a/dan_layer/engine/src/runtime/address_allocation.rs +++ b/dan_layer/engine/src/runtime/address_allocation.rs @@ -1,7 +1,10 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use tari_engine_types::{substate::SubstateId, TemplateAddress}; +use tari_engine_types::{ + substate::{InvalidSubstateIdVariant, SubstateId}, + TemplateAddress, +}; use tari_template_lib::models::ComponentAddress; #[derive(Debug, Clone)] @@ -28,7 +31,7 @@ impl AllocatedAddress { } impl TryFrom for ComponentAddress { - type Error = SubstateId; + type Error = InvalidSubstateIdVariant; fn try_from(value: AllocatedAddress) -> Result { value.address.try_into() diff --git a/dan_layer/engine/src/runtime/tracker.rs b/dan_layer/engine/src/runtime/tracker.rs index 96933d0a8..21338ab15 100644 --- a/dan_layer/engine/src/runtime/tracker.rs +++ b/dan_layer/engine/src/runtime/tracker.rs @@ -37,7 +37,7 @@ use tari_engine_types::{ indexed_value::{IndexedValue, IndexedWellKnownTypes}, lock::LockFlag, logs::LogEntry, - substate::{SubstateId, SubstateValue}, + substate::{InvalidSubstateIdVariant, SubstateId, SubstateValue}, virtual_substate::VirtualSubstates, TemplateAddress, }; @@ -163,8 +163,11 @@ impl StateTracker { let component_address = match address_allocation { Some(address_allocation) => { let addr = state.take_allocated_address(address_allocation.id())?; - addr.try_into() - .map_err(|address| RuntimeError::AddressAllocationTypeMismatch { address })? + addr.try_into().map_err(|error: InvalidSubstateIdVariant| { + RuntimeError::AddressAllocationTypeMismatch { + address: error.substate_id, + } + })? }, None => state.id_provider()?.new_component_address(template_address, None)?, }; diff --git a/dan_layer/engine_types/src/substate.rs b/dan_layer/engine_types/src/substate.rs index 17d9d917b..c5b759922 100644 --- a/dan_layer/engine_types/src/substate.rs +++ b/dan_layer/engine_types/src/substate.rs @@ -21,6 +21,7 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use std::{ + any, fmt::{Display, Formatter}, str::FromStr, }; @@ -31,13 +32,8 @@ use tari_bor::{decode, decode_exact, encode, BorError}; use tari_common_types::types::FixedHash; use tari_template_lib::{ models::{ - ComponentAddress, - NonFungibleAddress, - NonFungibleIndexAddress, - ObjectKey, - ResourceAddress, - UnclaimedConfidentialOutputAddress, - VaultId, + ComponentAddress, NonFungibleAddress, NonFungibleIndexAddress, ObjectKey, ResourceAddress, + UnclaimedConfidentialOutputAddress, VaultId, }, prelude::PUBLIC_IDENTITY_RESOURCE_ADDRESS, Hash, @@ -167,15 +163,15 @@ impl SubstateId { /// Returns true for any substate that has is "versionable" i.e. can have a version > 0, otherwise false. pub fn is_versioned(&self) -> bool { match self { - SubstateId::Component(_) | - SubstateId::Resource(_) | - SubstateId::Vault(_) | - SubstateId::NonFungibleIndex(_) | - SubstateId::Template(_) | - SubstateId::NonFungible(_) => true, - SubstateId::UnclaimedConfidentialOutput(_) | - SubstateId::TransactionReceipt(_) | - SubstateId::FeeClaim(_) => false, + SubstateId::Component(_) + | SubstateId::Resource(_) + | SubstateId::Vault(_) + | SubstateId::NonFungibleIndex(_) + | SubstateId::Template(_) + | SubstateId::NonFungible(_) => true, + SubstateId::UnclaimedConfidentialOutput(_) + | SubstateId::TransactionReceipt(_) + | SubstateId::FeeClaim(_) => false, } } @@ -346,13 +342,135 @@ impl From for SubstateId { } } +#[derive(Debug, thiserror::Error)] +#[error("Could not convert substate ID variant '{substate_id}' to {expected}")] +pub struct InvalidSubstateIdVariant { + pub substate_id: SubstateId, + pub expected: &'static str, +} + impl TryFrom for ComponentAddress { - type Error = SubstateId; + type Error = InvalidSubstateIdVariant; fn try_from(value: SubstateId) -> Result { match value { SubstateId::Component(addr) => Ok(addr), - _ => Err(value), + _ => Err(InvalidSubstateIdVariant { + substate_id: value, + expected: any::type_name::(), + }), + } + } +} + +impl TryFrom for ResourceAddress { + type Error = InvalidSubstateIdVariant; + + fn try_from(value: SubstateId) -> Result { + match value { + SubstateId::Resource(addr) => Ok(addr), + _ => Err(InvalidSubstateIdVariant { + substate_id: value, + expected: any::type_name::(), + }), + } + } +} + +impl TryFrom for VaultId { + type Error = InvalidSubstateIdVariant; + + fn try_from(value: SubstateId) -> Result { + match value { + SubstateId::Vault(addr) => Ok(addr), + _ => Err(InvalidSubstateIdVariant { + substate_id: value, + expected: any::type_name::(), + }), + } + } +} + +impl TryFrom for NonFungibleAddress { + type Error = InvalidSubstateIdVariant; + + fn try_from(value: SubstateId) -> Result { + match value { + SubstateId::NonFungible(addr) => Ok(addr), + _ => Err(InvalidSubstateIdVariant { + substate_id: value, + expected: any::type_name::(), + }), + } + } +} + +impl TryFrom for NonFungibleIndexAddress { + type Error = InvalidSubstateIdVariant; + + fn try_from(value: SubstateId) -> Result { + match value { + SubstateId::NonFungibleIndex(addr) => Ok(addr), + _ => Err(InvalidSubstateIdVariant { + substate_id: value, + expected: any::type_name::(), + }), + } + } +} + +impl TryFrom for UnclaimedConfidentialOutputAddress { + type Error = InvalidSubstateIdVariant; + + fn try_from(value: SubstateId) -> Result { + match value { + SubstateId::UnclaimedConfidentialOutput(addr) => Ok(addr), + _ => Err(InvalidSubstateIdVariant { + substate_id: value, + expected: any::type_name::(), + }), + } + } +} + +impl TryFrom for FeeClaimAddress { + type Error = InvalidSubstateIdVariant; + + fn try_from(value: SubstateId) -> Result { + match value { + SubstateId::FeeClaim(addr) => Ok(addr), + _ => Err(InvalidSubstateIdVariant { + substate_id: value, + expected: any::type_name::(), + }), + } + } +} + +impl TryFrom for TransactionReceiptAddress { + type Error = InvalidSubstateIdVariant; + + fn try_from(value: SubstateId) -> Result { + match value { + SubstateId::TransactionReceipt(addr) => Ok(addr), + _ => Err(InvalidSubstateIdVariant { + substate_id: value, + expected: any::type_name::(), + }), + } + } +} + +impl TryFrom for PublishedTemplateAddress { + type Error = InvalidSubstateIdVariant; + + fn try_from(value: SubstateId) -> Result { + match value { + SubstateId::Template(addr) => Ok(addr), + _ => Err(InvalidSubstateIdVariant { + substate_id: value, + expected: any::type_name::(), + }), } } }