Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/setup-simplex
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ main() {
SIMPLEX_BIN_DIR="$SIMPLEX_DIR/bin"
BIN_PATH="$SIMPLEX_BIN_DIR/simplexup"

# Ensure bin directory exists and download simplexup into it
# Create the bin directory and download simplexup there
mkdir -p "$SIMPLEX_BIN_DIR"
say "Fetching ${FILE_PATH} from ${RAW_URL}"

Expand Down
6 changes: 3 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ In your report, please include as much information as you can, including:

* a description of the vulnerability and how it could be exploited
* its potential impact (e.g. privacy leak, denial of service, theft of funds)
* steps or code for reproducing it
* a proposed patch for remedying it
* steps or code for reproducing the vulnerability
* a proposed patch, if you have one

Also, provide us with a secure means to contact you with any follow up questions we might have.

## Considerations

Please take care not to violate the privacy of users in your report. For example, stack traces or exploit scripts sent to us should never contain private keys or personally identifiable information.

Give us at least one week to investigate the vulnerability you found and up to 90 days to fix it. Also, please give us reasonable advanced notice if at any point you intend to disclose the vulnerability to anyone else.
Give us at least one week to investigate the vulnerability you found and up to 90 days to fix the issue. Also, please give us reasonable advanced notice if at any point you intend to disclose the vulnerability to anyone else.

In general, please investigate and report bugs in a way that makes a reasonable, good faith effort not to be disruptive or harmful to us, this software's users, or the users of dependent projects.

Expand Down
2 changes: 1 addition & 1 deletion crates/build/src/config/dependency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ struct RawDependency {
rev: Option<String>,
/// The specific tag to download (only applicable if `git` is provided).
tag: Option<String>,
/// The specific branch to download (only applicable if `branch` is provided).
/// The specific branch to download (only applicable if `git` is provided).
branch: Option<String>,
/// The specific directory with contracts to download (only applicable if `git` is provided).
package: Option<String>,
Expand Down
2 changes: 1 addition & 1 deletion crates/build/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl ArtifactsGenerator {
.map_err(|e| BuildError::DependencyMap(e.to_string()))
}

/// Processes a single `.simf` source file and write it to metadata:
/// Processes a single `.simf` source file into its metadata:
/// - Writes its content to the mirrored path under `simf_out_dir`
/// - Extracts the contract name
///
Expand Down
2 changes: 1 addition & 1 deletion crates/build/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl ArtifactsResolver {
let repo_name = clean_url.split('/').next_back()?;

// Only fields that are actually set take part in the key, so adding a new
// optional field never changes the directory of dependencies that don't use it.
// optional field never changes the directory of dependencies that don't set the field.
let reference = reference.map(|reference| match reference {
GitRef::Rev(rev) => format!("rev={rev}"),
GitRef::Tag(tag) => format!("tag={tag}"),
Expand Down
4 changes: 2 additions & 2 deletions crates/cli/src/commands/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ pub enum CommandError {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),

#[error("Verbosity level should be either -v or -vv, got: -v x {0}")]
BadVersbosityMode(u8),
#[error("Verbosity must be -v or -vv, got {0} -v flags")]
BadVerbosityMode(u8),

#[error("test command failed with exit status {0}")]
TestFailed(i32),
Expand Down
6 changes: 2 additions & 4 deletions crates/cli/src/commands/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,10 @@ impl Format {
Ok(Self::normalize_status(status))
}

/// Resolves the file path to the `simfmt` binary in the same directory where `simplex` is situated.
/// Given that `simfmt` would be placed in one directory with `simplex`, this is suitable for our usecase.
/// The path to the `simfmt` binary next to the `simplex` binary, where `simplexup` installs both.
///
/// # Warning
/// Can fail to search for binary when env isn't set and `simfmt` binary lies in the other directory.
/// Even when `simfmt` is visible through PATH.
/// Doesn't find a `simfmt` in another directory, even one on `PATH`, unless the env variable is set.
#[inline]
fn simfmt_binary() -> Result<PathBuf, FmtError> {
Ok(env::current_exe()
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/commands/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ impl Install {
/// at `reference`, keeping only `package` when it is set.
///
/// 1. Clone the history without contents and any checks.
/// 2. If `package` is set, restrict the checkout to it.
/// 2. If `package` is set, restrict the checkout to that directory.
/// 3. Check out `rev` (or the cloned ref), downloading only the files it needs.
fn git_commands(url: &str, reference: Option<&GitRef>, package: Option<&str>, target_dir: &Path) -> Vec<Command> {
let mut clone = Command::new("git");
Expand Down
4 changes: 2 additions & 2 deletions crates/cli/src/commands/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use smplx_test::{TestConfig, smplx_test_marker};
use super::core::{TestArguments, TestFlags};
use super::error::CommandError;

/// Nextest dsl variable to filter and use only simplex tests
/// Nextest filter expression that selects only Simplex tests.
const SMPLX_NEXTEST_DSL_TEST_MARKER: &str = concat!("test(/", smplx_test_marker!(), "$/)");
const SMPLX_NEXTEST_FUZZ_DSL_TEST_MARKER: &str = concat!("test(/", smplx_test_marker!(fuzz), "$/)");
const DEFAULT_THREADS_NUMBER: usize = 1;
Expand All @@ -26,7 +26,7 @@ impl Test {
let cache_path = Self::get_test_config_cache_name()?;

if flags.verbose > Verbosity::MAX_VERBOSITY_LEVEL {
return Err(CommandError::BadVersbosityMode(flags.verbose));
return Err(CommandError::BadVerbosityMode(flags.verbose));
}

config.verbosity = std::cmp::max(config.verbosity, Verbosity::new(flags.verbose));
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/config/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub enum ConfigError {
#[error("Unable to get env variable: {0}")]
UnableToGetEnv(#[from] std::env::VarError),

#[error("Path doesn't a file: '{0}'")]
#[error("Path isn't a file: '{0}'")]
PathIsNotFile(PathBuf),

#[error("Path doesn't exist: '{0}'")]
Expand Down
2 changes: 1 addition & 1 deletion crates/regtest/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub(super) fn get_elementsd_bin_args(config: &RegtestConfig) -> Vec<String> {
];

if let Some(port) = config.rpc_port {
// A lib works with autoassigned rpcport, so we are required to do this woodoo
// The node library picks the RPC port itself, so a fixed port needs explicit bind settings
args.push("-rpcbind=127.0.0.1".to_string());
args.push(format!("-rpcbind=127.0.0.1:{port}"));
args.push("-rpcallowip=127.0.0.1/8".to_string());
Expand Down
44 changes: 22 additions & 22 deletions crates/sdk/src/program/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub trait ProgramTrait: DynClone + Send + Sync {
///
/// Doesn't check the witness budget; [`ProgramTrait::finalize`] does. With [`Verbosity`](crate::global::Verbosity)
/// `Debug` or `Trace`, the execution output is buffered, not printed: call
/// [`ProgramLogger::flush_logs`] to print it.
/// [`ProgramLogger::flush_logs`] to print the output.
///
/// # Errors
/// - `ProgramError::WitnessSatisfaction` if the witness doesn't fit the program's witness types.
Expand Down Expand Up @@ -136,8 +136,8 @@ pub trait ProgramFactory<P: AsRef<Program> + Sized> {
/// and the debug-symbol setting determine the CMR, and the address also depends on the internal
/// key and the storage.
///
/// Code generated by `simplex build` wraps a `Program` in one type per contract, which reaches it
/// with `as_ref()`.
/// Code generated by `simplex build` wraps a `Program` in one type per contract. Call `as_ref()`
/// on that type to get the `Program`.
#[derive(Clone)]
pub struct Program {
source: Arc<str>,
Expand Down Expand Up @@ -319,8 +319,8 @@ impl Program {
/// the tree is at most 128 layers deep.
pub const MAX_STORAGE_SLOTS: usize = 128;

/// Creates a program from `SimplicityHL` source and its `param::` arguments, without compiling
/// it.
/// Creates a program from `SimplicityHL` source and its `param::` arguments. The source
/// compiles later, on first use.
///
/// The Taproot internal key is [`tr_unspendable_key`], and there aren't any storage slots.
#[must_use]
Expand Down Expand Up @@ -433,7 +433,7 @@ impl Program {
/// The storage slot at `index`.
///
/// # Panics
/// Panics if the `index` is out of bounds for the initiated storage.
/// Panics if the `index` is out of bounds for the initialized storage.
#[must_use]
pub fn get_storage_at(&self, index: usize) -> Vec<u8> {
self.storage[index].clone()
Expand Down Expand Up @@ -485,7 +485,7 @@ impl Program {
self.cmr().unwrap_or_else(|error| panic!("{error}")).to_byte_array()
}

/// The tapleaf hash of the program's leaf. Storage doesn't change it.
/// The tapleaf hash of the program's leaf. Storage doesn't affect this hash.
///
/// # Panics
/// Panics if the `SimplicityHL` compilation fails.
Expand Down Expand Up @@ -640,7 +640,7 @@ mod tests {
}

#[test]
fn storage_slot_takes_a_full_width_value() {
fn storage_slot_accepts_32_bytes() {
let mut program = stateful(1);

program.set_storage_at(0, vec![0x11; Program::STORAGE_SLOT_BYTES]);
Expand All @@ -650,18 +650,18 @@ mod tests {

#[test]
#[should_panic(expected = "A storage slot is 32 bytes, and this one is 1")]
fn storage_slot_refuses_a_short_value() {
fn storage_slot_rejects_a_short_value() {
stateful(1).set_storage_at(0, vec![0x11]);
}

#[test]
#[should_panic(expected = "A storage slot is 32 bytes, and this one is 33")]
fn storage_slot_refuses_a_long_one() {
fn storage_slot_rejects_a_long_value() {
stateful(1).set_storage_at(0, vec![0x11; 33]);
}

#[test]
fn changing_a_slot_changes_the_address_but_not_the_program() {
fn storage_changes_the_address_but_not_the_cmr() {
let one = stateful(1);
let network = SimplicityNetwork::LiquidTestnet;
let address = one.get_tr_address(&network);
Expand Down Expand Up @@ -722,7 +722,7 @@ mod tests {
}

#[test]
fn compiles_once_and_keeps_it() {
fn program_is_compiled_once() {
let program = dummy_program();

let first = program.load().expect("the dummy program compiles");
Expand All @@ -732,7 +732,7 @@ mod tests {
}

#[test]
fn changed_build_mode_is_not_served_the_old_compilation() {
fn debug_symbols_change_the_cmr() {
let plain = dummy_program();
let plain_cmr = plain.get_cmr();

Expand All @@ -743,7 +743,7 @@ mod tests {
}

#[test]
fn test_get_env_idx() {
fn get_env_checks_the_script_pubkey() {
let program = dummy_program();
let network = dummy_network();

Expand All @@ -764,7 +764,7 @@ mod tests {
..Default::default()
});

// take a script with a wrong pubkey
// Input 0 spends a script that is not the program's
assert!(matches!(
program.get_env(&pst, 0, &network).unwrap_err(),
ProgramError::ScriptPubkeyMismatch { .. }
Expand All @@ -774,7 +774,7 @@ mod tests {
}

#[test]
fn input_without_its_utxo_is_an_error() {
fn input_without_witness_utxo_is_an_error() {
let network = SimplicityNetwork::default_regtest();
let program = stateful(0);
let mut pst = PartiallySignedTransaction::new_v2();
Expand All @@ -795,31 +795,31 @@ mod tests {
}

#[test]
fn storage_is_at_most_as_deep_as_the_taproot_tree() {
fn max_storage_slots_fit_the_taproot_tree() {
let network = SimplicityNetwork::default_regtest();

let _ = stateful(Program::MAX_STORAGE_SLOTS).get_tr_address(&network);
}

#[test]
#[should_panic(expected = "A program holds at most 128 storage slots, and this one asks for 129")]
fn storage_beyond_the_taproot_tree_is_refused() {
fn too_many_storage_slots_panic() {
let _ = stateful(Program::MAX_STORAGE_SLOTS + 1);
}

#[test]
fn left_folded_depths() {
fn taproot_leaf_depths_are_left_folded() {
assert_eq!(Program::taproot_leaf_depths(1), vec![0]);
assert_eq!(Program::taproot_leaf_depths(2), vec![1, 1]);
assert_eq!(Program::taproot_leaf_depths(3), vec![2, 2, 1]);
assert_eq!(Program::taproot_leaf_depths(4), vec![3, 3, 2, 1]);
assert_eq!(Program::taproot_leaf_depths(5), vec![4, 4, 3, 2, 1]);
}

// The measured boundary: a balanced tree agrees with a left fold up to three leaves and
// diverges from four. Four leaves balanced is [2, 2, 2, 2]; left-folded it is not.
// A balanced tree and a left fold agree up to three leaves. With four leaves, a balanced tree
// has depths [2, 2, 2, 2] and a left fold doesn't.
#[test]
fn diverges_from_a_balanced_tree_at_four_leaves() {
fn left_fold_differs_from_a_balanced_tree_at_four_leaves() {
assert_eq!(Program::taproot_leaf_depths(3), vec![2, 2, 1]);
assert_ne!(Program::taproot_leaf_depths(4), vec![2, 2, 2, 2]);
}
Expand Down
6 changes: 3 additions & 3 deletions crates/sdk/src/program/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// Errors that can occur when compiling, preparing, and executing Simplicity programs.
#[derive(Debug, thiserror::Error)]
pub enum ProgramError {
/// The serialized witness stack does not buy enough budget to cover the program's execution cost.
/// The witness budget, set by the serialized witness stack size, doesn't cover the program's execution cost.
///
/// Consensus requires `cost <= 1000 * (serialized witness stack size + 50)` milli weight units.
/// The 50 is Elements' `VALIDATION_WEIGHT_OFFSET`
Expand All @@ -15,7 +15,7 @@ pub enum ProgramError {
InsufficientBudget {
/// Static execution cost of the pruned program, rounded up to whole weight units.
cost_wu: u64,
/// Budget bought by the witness stack: its serialized size plus 50 weight units.
/// Witness budget: the serialized witness stack size plus 50 weight units.
budget_wu: u64,
/// Serialized size of the witness stack in bytes.
stack_bytes: usize,
Expand Down Expand Up @@ -51,7 +51,7 @@ pub enum ProgramError {
/// Error indicating an input that doesn't carry the output it spends.
#[error("Input {input_index} has no witness UTXO")]
MissingWitnessUtxo {
/// The index of the input without one.
/// The index of the input without a witness UTXO.
input_index: usize,
},

Expand Down
9 changes: 5 additions & 4 deletions crates/sdk/src/provider/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub const DEFAULT_ESPLORA_TIMEOUT_SECS: u64 = 10;
pub const DEFAULT_CONFIRMATION_ATTEMPTS: u32 = 9;

/// The endpoints of a provider: an Esplora URL, and for a regtest node, its RPC URL and
/// credentials. Neither the SDK nor the test framework reads it.
/// credentials. Neither the SDK nor the test framework reads these.
#[cfg(feature = "provider")]
#[derive(Debug, Clone)]
pub struct ProviderInfo {
Expand All @@ -34,16 +34,17 @@ pub struct ProviderInfo {
/// Access to a Liquid or Elements network: broadcasting, confirmation, chain queries and UTXO
/// lookups.
///
/// All methods block. `EsploraProvider` and `SimplexProvider` implement it with the `provider`
/// feature. The trait itself doesn't need the feature, so a host without it can implement it.
/// All methods block. `EsploraProvider` and `SimplexProvider` implement this trait with the
/// `provider` feature. The trait itself doesn't need the feature, so a host without the feature
/// can still implement the trait.
///
/// UTXOs come back as the chain has them: a confidential output has `secrets: None`. A
/// [`Signer`](crate::signer::Signer) unblinds its own outputs.
pub trait ProviderTrait: Send + Sync {
/// The network this provider talks to.
fn get_network(&self) -> &SimplicityNetwork;

/// Broadcasts `tx` and returns a receipt for it.
/// Broadcasts `tx` and returns the transaction's receipt.
///
/// # Errors
/// Returns `ProviderError::BroadcastRejected` if the provider answers with an error status,
Expand Down
6 changes: 3 additions & 3 deletions crates/sdk/src/provider/esplora.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ impl EsploraProvider {
}
}

/// Sends a GET to `path` under the Esplora URL, whatever the status it answers with.
/// Sends a GET to `path` under the Esplora URL, whatever the response status.
fn request(&self, path: &str) -> Result<minreq::Response, ProviderError> {
minreq::get(format!("{}{path}", self.esplora_url))
.with_timeout(self.timeout.as_secs())
.send()
.map_err(|e| ProviderError::Request(e.to_string()))
}

/// Sends a GET to `path`, failing unless it answers 200.
/// Sends a GET to `path`, failing unless the response status is 200.
fn get(&self, path: &str) -> Result<minreq::Response, ProviderError> {
let response = self.request(path)?;

Expand Down Expand Up @@ -195,7 +195,7 @@ impl ProviderTrait for EsploraProvider {
for _ in 0..self.confirmation_attempts {
let response = self.request(&path)?;

// an unknown transaction answers 404 until Esplora indexes it
// Esplora answers 404 for a transaction it hasn't indexed yet
if response.status_code == 200 {
let status: TxStatus = response.json().map_err(|e| ProviderError::Deserialize(e.to_string()))?;

Expand Down
Loading
Loading