mod auth;
pub use auth::{AuthParams, AuthorizationScope};
mod r#impl;
pub use r#impl::RuntimeInterfaceImpl;
mod engine_args;
pub use crate::runtime::engine_args::EngineArgs;
mod error;
pub use error::*;
mod actions;
pub use actions::*;
mod module;
pub use module::{RuntimeEvent, RuntimeModule, RuntimeModuleError};
mod fee_state;
mod tracker;
mod locking;
pub mod scope;
pub use locking::{LockError, LockState};
mod address_allocation;
mod pay_fee;
mod state_store;
mod tracker_auth;
mod validation;
mod working_state;
mod workspace;
use std::{fmt::Debug, ptr::NonNull};
pub use pay_fee::PayFee;
use tari_engine_types::{
commit_result::{FinalizeResult, RejectReason},
component::ComponentHeader,
confidential::{ClaimBurnOutputData, MinotariBurnClaimProof},
indexed_value::IndexedValue,
lock::LockFlag,
published_template::TemplateBlob,
};
use tari_ootle_template_metadata::MetadataHash;
use tari_ootle_transaction::{
AllocatableAddressType,
ComponentReference,
ResourceAddressRef,
args::{InstructionArg, WorkspaceId, WorkspaceOffsetId},
};
use tari_template_abi::TemplateDef;
use tari_template_lib::{
args::{
AddressAllocationInvokeArg,
AllocateAddressResult,
BucketAction,
BucketRef,
BuiltinTemplateAction,
CallAction,
CallerContextAction,
ComponentAction,
ComponentRef,
ConsensusAction,
GenerateRandomAction,
InvokeResult,
NonFungibleAction,
ProofAction,
ProofRef,
ResourceAction,
ResourceRef,
VaultAction,
WorkspaceAction,
},
models::{BucketId, VaultRef},
types::{
ComponentAddress,
EntityId,
LogLevel,
Metadata,
NonFungibleAddress,
TemplateAddress,
ValidatorFeePoolAddress,
engine_args::SignatureAction,
stealth::StealthTransferStatement,
},
};
pub use tracker::StateTracker;
use crate::runtime::{locking::LockedSubstate, scope::PushCallFrame};
pub trait RuntimeInterface {
fn next_entity_id(&self) -> Result<EntityId, RuntimeError>;
fn emit_event(&mut self, topic: String, payload: Metadata) -> Result<(), RuntimeError>;
fn emit_log(&mut self, level: LogLevel, message: String) -> Result<(), RuntimeError>;
fn load_component(&mut self, call: ComponentReference)
-> Result<(ComponentAddress, ComponentHeader), RuntimeError>;
fn lock_component(
&mut self,
address: ComponentAddress,
lock_flag: LockFlag,
) -> Result<LockedSubstate, RuntimeError>;
fn component_invoke(
&mut self,
component_ref: ComponentRef,
action: ComponentAction,
args: EngineArgs,
) -> Result<InvokeResult, RuntimeError>;
fn resource_invoke(
&mut self,
resource_ref: ResourceRef,
action: ResourceAction,
args: EngineArgs,
) -> Result<InvokeResult, RuntimeError>;
fn vault_invoke(
&mut self,
vault_ref: VaultRef,
action: VaultAction,
args: EngineArgs,
) -> Result<InvokeResult, RuntimeError>;
fn bucket_invoke(
&mut self,
bucket_ref: BucketRef,
action: BucketAction,
args: EngineArgs,
) -> Result<InvokeResult, RuntimeError>;
fn proof_invoke(
&mut self,
proof_ref: ProofRef,
action: ProofAction,
args: EngineArgs,
) -> Result<InvokeResult, RuntimeError>;
fn workspace_invoke(&mut self, action: WorkspaceAction, args: EngineArgs) -> Result<InvokeResult, RuntimeError>;
fn non_fungible_invoke(
&mut self,
nf_addr: NonFungibleAddress,
action: NonFungibleAction,
args: EngineArgs,
) -> Result<InvokeResult, RuntimeError>;
fn consensus_invoke(&mut self, action: ConsensusAction) -> Result<InvokeResult, RuntimeError>;
fn generate_random_invoke(&mut self, action: GenerateRandomAction) -> Result<InvokeResult, RuntimeError>;
fn generate_uuid(&mut self) -> Result<[u8; 32], RuntimeError>;
fn set_last_instruction_output(&mut self, value: IndexedValue) -> Result<(), RuntimeError>;
fn claim_burn(
&mut self,
claim: MinotariBurnClaimProof,
output_data: ClaimBurnOutputData,
) -> Result<(), RuntimeError>;
fn claim_validator_fees(&mut self, address: ValidatorFeePoolAddress) -> Result<(), RuntimeError>;
fn checkpoint_fee_intent(&mut self) -> Result<(), RuntimeError>;
fn finalize(&mut self) -> Result<FinalizeResult, RuntimeError>;
fn finalize_failure(&mut self, reason: RejectReason) -> Result<FinalizeResult, RuntimeError>;
fn validate_finalized(&self) -> Result<(), RuntimeError>;
fn caller_context_invoke(
&mut self,
action: CallerContextAction,
args: EngineArgs,
) -> Result<InvokeResult, RuntimeError>;
fn allocate_address_invoke(&mut self, action: AddressAllocationInvokeArg) -> Result<InvokeResult, RuntimeError>;
fn call_invoke(&mut self, action: CallAction, args: EngineArgs) -> Result<InvokeResult, RuntimeError>;
fn builtin_template_invoke(&mut self, action: BuiltinTemplateAction) -> Result<InvokeResult, RuntimeError>;
fn check_component_access_rules(&self, method: &str) -> Result<(), RuntimeError>;
fn check_component_ownership(&self, action: ActionIdent) -> Result<(), RuntimeError>;
fn update_component_template(&mut self, new_template: TemplateAddress) -> Result<(), RuntimeError>;
fn validate_return_value(&self, value: &IndexedValue) -> Result<(), RuntimeError>;
fn push_call_frame(&mut self, frame: PushCallFrame) -> Result<(), RuntimeError>;
fn pop_call_frame(&mut self) -> Result<(), RuntimeError>;
fn publish_template(
&mut self,
template: TemplateBlob,
metadata_hash: Option<MetadataHash>,
template_def: TemplateDef,
) -> Result<(), RuntimeError>;
fn put_on_workspace(&mut self, id: WorkspaceId, value: IndexedValue) -> Result<(), RuntimeError>;
fn signature_invoke(&mut self, action: SignatureAction, args: EngineArgs) -> Result<InvokeResult, RuntimeError>;
fn allocate_address(
&mut self,
substate_type: AllocatableAddressType,
entity_id: EntityId,
workspace_id: WorkspaceId,
) -> Result<AllocateAddressResult, RuntimeError>;
fn stealth_transfer(
&mut self,
resource_address: ResourceAddressRef,
statement: StealthTransferStatement,
revealed_funds_bucket: Option<BucketId>,
) -> Result<Option<BucketId>, RuntimeError>;
fn pay_fee(&mut self, pay_fee: PayFee) -> Result<(), RuntimeError>;
fn track_template_loaded(
&mut self,
template_address: &TemplateAddress,
bytes_loaded: usize,
) -> Result<(), RuntimeError>;
fn resolve_args(
&self,
prepend: Option<InstructionArg>,
args: &[InstructionArg],
) -> Result<Vec<tari_bor::Value>, RuntimeError>;
fn resolve_workspace_id(&self, workspace_id: &WorkspaceOffsetId) -> Result<tari_bor::Value, RuntimeError>;
fn set_runtime_pointer(&mut self, pointer: *mut Box<dyn RuntimeInterface>);
}
#[derive(Clone)]
pub struct Runtime {
interface: NonNull<Box<dyn RuntimeInterface>>,
}
unsafe impl Sync for Runtime {}
unsafe impl Send for Runtime {}
impl Runtime {
pub const fn from_mut(interface: &mut Box<dyn RuntimeInterface>) -> Self {
Self {
interface: NonNull::from_mut(interface),
}
}
pub fn from_pointer(interface: *mut Box<dyn RuntimeInterface>) -> Option<Self> {
Some(Self {
interface: NonNull::new(interface)?,
})
}
pub fn as_pointer(&self) -> *mut Box<dyn RuntimeInterface> {
self.interface.as_ptr()
}
pub fn interface(&self) -> &dyn RuntimeInterface {
unsafe { self.interface.as_ref() }.as_ref()
}
pub fn interface_mut(&mut self) -> &mut dyn RuntimeInterface {
unsafe { self.interface.as_mut() }.as_mut()
}
}
impl Debug for Runtime {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Runtime")
.field("interface", &"dyn RuntimeInterface")
.finish()
}
}