@@ -20,9 +20,12 @@ use super::error::ProgramError;
2020use crate :: provider:: SimplicityNetwork ;
2121use crate :: utils:: { check_budget, hash_script, tap_data_hash, tr_unspendable_key} ;
2222
23- /// Executes `simplicity` programs at runtime.
23+ /// What the [`Signer`](crate::signer::Signer) needs from a program to sign for and finalize a
24+ /// program input.
2425///
25- /// This trait defines a core behavior related to testing and execution.
26+ /// [`Program`] implements it, as does `&T` for any `T: ProgramTrait`.
27+ /// [`ProgramInput`](crate::transaction::ProgramInput) holds a `Box<dyn ProgramTrait>`, which is
28+ /// `Clone`.
2629pub trait ProgramTrait : DynClone + Send + Sync {
2730 /// Retrieves the types of arguments required by a `simplicity` program.
2831 ///
@@ -36,25 +39,36 @@ pub trait ProgramTrait: DynClone + Send + Sync {
3639 /// Returns a `ProgramError` if parsing or generating ABI metadata fails.
3740 fn get_witness_types ( & self ) -> Result < WitnessTypes , ProgramError > ;
3841
39- /// Constructs the Elements environment for a specified input index, PST, and network for further program execution.
42+ /// The Simplicity transaction environment for input `input_index` of `pst`: what the
43+ /// program's transaction jets, such as `jet::sig_all_hash()`, read.
4044 ///
4145 /// # Errors
42- /// Returns a `ProgramError` if the input index is out of bounds or if the script pubkey of the UTXO mismatches the expected program script.
46+ /// Returns `ProgramError::MissingWitnessUtxo` if an input of `pst` doesn't carry the output it
47+ /// spends, `ProgramError::UtxoIndexOutOfBounds` if `input_index` is past the inputs, and
48+ /// `ProgramError::ScriptPubkeyMismatch` if the input doesn't spend this program's address.
4349 fn get_env (
4450 & self ,
4551 pst : & PartiallySignedTransaction ,
4652 input_index : usize ,
4753 network : & SimplicityNetwork ,
4854 ) -> Result < ElementsEnv < Arc < Transaction > > , ProgramError > ;
4955
50- /// Executes a Simplicity program for the given input index of a partially signed transaction.
56+ /// Runs the program locally on input `input_index` of `pst` with `witness`: satisfies it,
57+ /// prunes it, and runs the pruned program on the Bit Machine. Returns the pruned program and
58+ /// its output.
5159 ///
52- /// This function evaluates a Simplicity script associated with a specific transaction input
53- /// in a given network, producing the result of the computation along with the redeem node
54- /// used during execution .
60+ /// Doesn't check the witness budget; [`ProgramTrait::finalize`] does. With [`Verbosity`](crate::global::Verbosity)
61+ /// `Debug` or `Trace`, the execution output is buffered, not printed: call
62+ /// [`ProgramLogger::flush_logs`] to print it .
5563 ///
5664 /// # Errors
57- /// Returns a `ProgramError` if loading the program, satisfying the witness, retrieving the environment, or executing the `BitMachine` fails.
65+ /// - `ProgramError::WitnessSatisfaction` if the witness doesn't fit the program's witness types.
66+ /// - `ProgramError::Pruning` if the program fails. A failed `assert!` or jet is
67+ /// `ExecutionError::JetFailed`. Reaching a pruned branch, for example with `unwrap(None)`, is
68+ /// `ExecutionError::ReachedPrunedBranch`. [`Program`] reports a failure in the Bit Machine run
69+ /// after pruning with this variant too.
70+ /// - `ProgramError::BitMachineCreation` if the program exceeds the Bit Machine's limits.
71+ /// - The errors of [`ProgramTrait::get_env`] and of compiling the program.
5872 fn execute (
5973 & self ,
6074 pst : & PartiallySignedTransaction ,
@@ -63,14 +77,16 @@ pub trait ProgramTrait: DynClone + Send + Sync {
6377 network : & SimplicityNetwork ,
6478 ) -> Result < ( Arc < RedeemNode > , Value ) , ProgramError > ;
6579
66- /// Finalizes and returns `pruned_witness` as output after executing the program on certain parameters.
80+ /// Runs the program as [`ProgramTrait::execute`] does and returns the input's witness stack:
81+ /// `[witness, program, cmr, control_block]`.
6782 ///
6883 /// Implementations must compare the pruned program's static cost with the budget from the
6984 /// exact serialized witness stack they return. Use [`check_budget`] for this check,
7085 /// as the built-in `Program` does.
7186 ///
7287 /// # Errors
73- /// Returns a `ProgramError` if execution, control block construction or budget validation fails.
88+ /// Returns the errors of [`ProgramTrait::execute`], and `ProgramError::InsufficientBudget` if the
89+ /// witness stack doesn't pay for the program's execution cost.
7490 fn finalize (
7591 & self ,
7692 pst : & PartiallySignedTransaction ,
@@ -81,6 +97,9 @@ pub trait ProgramTrait: DynClone + Send + Sync {
8197}
8298
8399/// Static description of a program's inputs and integer literals. Implemented by `include_simf!()`.
100+ ///
101+ /// The fuzz engine uses it to generate arguments and witnesses for a program it knows only by
102+ /// type.
84103pub trait ProgramSchema {
85104 /// Generated arguments struct.
86105 type Arguments ;
@@ -94,22 +113,31 @@ pub trait ProgramSchema {
94113 /// Witness names and types.
95114 fn witness_types ( ) -> Vec < ( TemplateProgramWitness , ResolvedType ) > ;
96115
97- /// Integer literals in the source.
116+ /// The integer literals in the source, sorted and without duplicates .
98117 fn literals ( ) -> Vec < U256 > ;
99118}
100119
101- /// A trait for creating instances of a program. The `ProgramFactory` trait defines a mechanism
102- /// for constructing and returning a program instance of a type that implements `AsRef<Program>`.
103- /// Only by generic struct name we have a possibility to create an instance of a program.
120+ /// Creates a program of type `P` from arguments, for code that knows the program only by type,
121+ /// such as the fuzz engine. Implemented by `include_simf!()`.
104122pub trait ProgramFactory < P : AsRef < Program > + Sized > {
105123 /// Instantiates a program with the given arguments.
106124 fn instantiate_program ( args : impl Into < Arguments > ) -> Box < P > ;
107125}
108126
109- /// Represents a program structure containing its public key, compiled program, and associated storage.
110- /// The compiled program with its CMR and the taproot spend info act as caches, filled on first use.
127+ /// A SimplicityHL program with its arguments, its Taproot internal key, and its storage slots.
128+ ///
129+ /// The program compiles on first use, and the result is cached and shared between clones. The
130+ /// getters that need the compiled program panic if it doesn't compile. Call [`Program::load`]
131+ /// to get the compile error instead.
132+ ///
133+ /// The program's address is a Taproot output. Its script tree holds the program as one leaf and
134+ /// one hidden leaf per storage slot, `tagged_hash("TapData", slot)`. The tree is left-folded:
135+ /// `tapbranch(tapbranch(tapbranch(program, slot0), slot1), slot2)`. So the source, the arguments
136+ /// and the debug-symbol setting determine the CMR, and the address also depends on the internal
137+ /// key and the storage.
111138///
112- /// Abstraction giving the power to execute Simplicity contracts without specifying any additional parameters.
139+ /// Code generated by `simplex build` wraps a `Program` in one type per contract, which reaches it
140+ /// with `as_ref()`.
113141#[ derive( Clone ) ]
114142pub struct Program {
115143 source : Arc < str > ,
@@ -287,10 +315,14 @@ impl Program {
287315 /// The width of a storage slot.
288316 pub const STORAGE_SLOT_BYTES : usize = 32 ;
289317
290- /// Each slot deepens the taproot tree by one and the tree is at most 128 layers deep.
318+ /// The most storage slots a program can have. Each slot deepens the Taproot tree by one, and
319+ /// the tree is at most 128 layers deep.
291320 pub const MAX_STORAGE_SLOTS : usize = 128 ;
292321
293- /// Creates a new instance of the struct with the provided source string and arguments.
322+ /// Creates a program from SimplicityHL source and its `param::` arguments, without compiling
323+ /// it.
324+ ///
325+ /// The Taproot internal key is [`tr_unspendable_key`], and there aren't any storage slots.
294326 #[ must_use]
295327 pub fn new ( source : impl Into < Arc < str > > , arguments : impl Into < Arguments > ) -> Self {
296328 Self {
@@ -304,8 +336,7 @@ impl Program {
304336 }
305337 }
306338
307- /// Sets the `pub_key` field of the struct to the provided `XOnlyPublicKey` value and returns the updated builder instance.
308- /// This is used to set the taproot public key for the program.
339+ /// Sets the Taproot internal key, which changes the address.
309340 #[ must_use]
310341 pub fn with_taproot_pubkey ( mut self , pub_key : XOnlyPublicKey ) -> Self {
311342 self . pub_key = pub_key;
@@ -314,7 +345,11 @@ impl Program {
314345 self
315346 }
316347
317- /// Builds this program in the mode the protocol declares.
348+ /// Compiles the program with or without debug symbols, overriding [`GlobalConfig`].
349+ ///
350+ /// Debug symbols change the CMR and so the address. A program whose address must match one
351+ /// computed elsewhere, such as a deployed contract, should set this explicitly, because
352+ /// verbosity `Debug` or `Trace` turns debug symbols on by default.
318353 #[ must_use]
319354 pub fn with_debug_symbols ( mut self , include : bool ) -> Self {
320355 self . include_debug_symbols = Some ( include) ;
@@ -325,7 +360,7 @@ impl Program {
325360 self
326361 }
327362
328- /// Sets storage capacity for further usage .
363+ /// Replaces the storage with ` capacity` zeroed slots .
329364 ///
330365 /// # Panics
331366 /// Panics if `capacity` exceeds `MAX_STORAGE_SLOTS`.
@@ -383,19 +418,19 @@ impl Program {
383418 & self . arguments
384419 }
385420
386- /// Returns the number of storage chunks for a program .
421+ /// The number of storage slots .
387422 #[ must_use]
388423 pub fn get_storage_len ( & self ) -> usize {
389424 self . storage . len ( )
390425 }
391426
392- /// Returns storage as a whole array of 32-byte chunks .
427+ /// The storage slots, each [`Program::STORAGE_SLOT_BYTES`] long .
393428 #[ must_use]
394429 pub fn get_storage ( & self ) -> & [ Vec < u8 > ] {
395430 & self . storage
396431 }
397432
398- /// Returns storage value at a certain index.
433+ /// The storage slot at ` index` .
399434 ///
400435 /// # Panics
401436 /// Panics if the `index` is out of bounds for the initiated storage.
@@ -404,10 +439,10 @@ impl Program {
404439 self . storage [ index] . clone ( )
405440 }
406441
407- /// Returns a taproot address for a defined `SimplicityNetwork `.
442+ /// The program's unconfidential Taproot address on `network `.
408443 ///
409444 /// # Panics
410- /// Panics if generating the taproot spending information fails .
445+ /// Panics if the program doesn't compile .
411446 #[ must_use]
412447 pub fn get_tr_address ( & self , network : & SimplicityNetwork ) -> Address {
413448 let spend_info = self . taproot_spending_info ( ) . unwrap_or_else ( |error| panic ! ( "{error}" ) ) ;
@@ -421,19 +456,27 @@ impl Program {
421456 )
422457 }
423458
424- /// Retrieves the `ScriptPubKey` associated with the Simplicity address for the specified network.
459+ /// The script of the program's address on `network`, which locks the outputs the program
460+ /// controls.
461+ ///
462+ /// # Panics
463+ /// Panics if the program doesn't compile.
425464 #[ must_use]
426465 pub fn get_script_pubkey ( & self , network : & SimplicityNetwork ) -> Script {
427466 self . get_tr_address ( network) . script_pubkey ( )
428467 }
429468
430- /// Retrieves the 32-byte `ScriptPubKey` hash associated with the Simplicity address for the specified network.
469+ /// The SHA-256 hash of [`Program::get_script_pubkey`], as Esplora's `scripthash` endpoints
470+ /// and the `jet::output_script_hash` family use.
471+ ///
472+ /// # Panics
473+ /// Panics if the program doesn't compile.
431474 #[ must_use]
432475 pub fn get_script_hash ( & self , network : & SimplicityNetwork ) -> [ u8 ; 32 ] {
433476 hash_script ( & self . get_script_pubkey ( network) )
434477 }
435478
436- /// Compiles the program and returns its Commitment Merkle Root.
479+ /// The program's Commitment Merkle Root.
437480 ///
438481 /// # Panics
439482 /// Panics if the `SimplicityHL` compilation fails.
@@ -442,7 +485,7 @@ impl Program {
442485 self . cmr ( ) . unwrap_or_else ( |error| panic ! ( "{error}" ) ) . to_byte_array ( )
443486 }
444487
445- /// Returns the 32-byte tapleaf hash of the program's Simplicity script .
488+ /// The tapleaf hash of the program's leaf. Storage doesn't change it .
446489 ///
447490 /// # Panics
448491 /// Panics if the `SimplicityHL` compilation fails.
@@ -453,7 +496,7 @@ impl Program {
453496 taproot:: TapLeafHash :: from_script ( & script, version) . to_byte_array ( )
454497 }
455498
456- /// Retrieves program ABI metadata for argument types .
499+ /// The names and types of the program's `param::` arguments .
457500 ///
458501 /// # Errors
459502 /// Returns a `ProgramError` if compilation fails or generating ABI metadata fails.
@@ -466,18 +509,18 @@ impl Program {
466509 Ok ( abi_meta. param_types )
467510 }
468511
469- /// Retrieves the witness types of the compiled program.
512+ /// The names and types of the program's `witness::` fields .
470513 ///
471514 /// # Errors
472515 /// Returns a `ProgramError` if compilation fails.
473516 pub fn get_witness_types ( & self ) -> Result < WitnessTypes , ProgramError > {
474517 Ok ( self . load ( ) ?. witness_types ( ) . shallow_clone ( ) )
475518 }
476519
477- /// Compiles program by providing saved `Arguments` .
520+ /// Compiles the program, or returns the cached result of an earlier compilation .
478521 ///
479522 /// # Errors
480- /// Retruns an error we have problems in a program compilation .
523+ /// Returns `ProgramError::Compilation` if the source doesn't compile with these arguments .
481524 pub fn load ( & self ) -> Result < & CompiledProgram , ProgramError > {
482525 Ok ( & self . load_with_cmr ( ) ?. 0 )
483526 }
0 commit comments