diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 784edf564dc..6569131921c 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -1257,7 +1257,7 @@ impl<'a, 'b, 'hooks> ExecutionState<'a, 'b, 'hooks> { /// `allow_private` should always be set to `false` for user transactions: /// this ensures that only `define-public` and `define-read-only` methods can /// be invoked. The `allow_private` mode should only be used by - /// `Environment::execute_contract_allow_private`. + /// `ExecutionState::execute_contract_allow_private`. fn inner_execute_contract( &mut self, invoke_ctx: &InvocationContext, diff --git a/clarity/src/vm/database/clarity_db.rs b/clarity/src/vm/database/clarity_db.rs index 30728694fad..6aa27b5326c 100644 --- a/clarity/src/vm/database/clarity_db.rs +++ b/clarity/src/vm/database/clarity_db.rs @@ -501,7 +501,7 @@ impl<'a> ClarityDatabase<'a> { self.store.put_data(key, &value.serialize()) } - /// Like `put()`, but returns the serialized byte size of the stored value + /// Like `put_data()`, but returns the serialized byte size of the stored value pub fn put_data_with_size( &mut self, key: &str, @@ -1102,10 +1102,14 @@ impl ClarityDatabase<'_> { } /// Get the last-known burnchain block height. - /// Note that this is _not_ the burnchain height in which this block was mined! - /// This is the burnchain block height of the parent of the Stacks block at the current Stacks - /// block height (i.e. that returned by `get_index_block_header_hash` for - /// `get_current_block_height`). + /// + /// Behavior depends on the active Clarity epoch: + /// * Before epoch 3.0, this is the burnchain block height of the parent of the Stacks block + /// at the current Stacks block height (i.e. that returned by `get_index_block_header_hash` + /// for `get_current_block_height`) — note this is _not_ the burnchain height in which this + /// block was mined. + /// * In epoch 3.0+, this is the current burnchain tip height (queried directly via + /// `BurnStateDB::get_tip_burn_block_height`). pub fn get_current_burnchain_block_height(&mut self) -> Result { let cur_stacks_height = self.store.get_current_block_height(); diff --git a/clarity/src/vm/database/structures.rs b/clarity/src/vm/database/structures.rs index 9741f3fb4ff..ef833f75d07 100644 --- a/clarity/src/vm/database/structures.rs +++ b/clarity/src/vm/database/structures.rs @@ -544,7 +544,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { } /// Increase the account's current lock to `new_total_locked`. - /// Panics if `self` was not locked by V2 PoX. + /// Returns Err(VmInternalError::Expect) if `self` was not locked by V2 PoX. pub fn increase_lock_v2(&mut self, new_total_locked: u128) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { @@ -763,7 +763,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { } /// Increase the account's current lock to `new_total_locked`. - /// Panics if `self` was not locked by V3 PoX. + /// Returns Err(VmInternalError::Expect) if `self` was not locked by V3 PoX. pub fn increase_lock_v3(&mut self, new_total_locked: u128) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { @@ -863,7 +863,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { /// Extend this account's current lock to `unlock_burn_height`. /// After calling, this method will set the balance to a "LockedPoxFour" balance, - /// because this method is only invoked as a result of PoX3 interactions + /// because this method is only invoked as a result of PoX4 interactions pub fn extend_lock_v4(&mut self, unlock_burn_height: u64) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { @@ -889,7 +889,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { } /// Increase the account's current lock to `new_total_locked`. - /// Panics if `self` was not locked by V3 PoX. + /// Panics if `self` was not locked by V4 PoX. pub fn increase_lock_v4(&mut self, new_total_locked: u128) -> Result<(), VmExecutionError> { let unlocked = self.unlock_available_tokens_if_any()?; if unlocked > 0 { @@ -929,7 +929,7 @@ impl<'db, 'conn> STXBalanceSnapshot<'db, 'conn> { } /// Return true iff `self` represents a snapshot that has a lock - /// created by PoX v3. + /// created by PoX v4. pub fn is_v4_locked(&mut self) -> Result { match self.canonical_balance_repr()? { STXBalance::LockedPoxFour { .. } => Ok(true), @@ -1036,7 +1036,8 @@ impl STXBalance { } /// This method returns the datastructure's lazy view of the unlock_height - /// *while* factoring in the PoX 2 early unlock for PoX 1 and PoX 3 early unlock for PoX 2. + /// *while* factoring in the PoX 2 early unlock for PoX 1, the PoX 3 early + /// unlock for PoX 2, and the PoX 4 early unlock for PoX 3. /// This value is still lazy: this unlock height may be less than the current /// burn block height, if so it will be updated in a canonicalized view. pub fn effective_unlock_height( @@ -1159,9 +1160,9 @@ impl STXBalance { } /// Returns a canonicalized STXBalance at a given burn_block_height - /// (i.e., if burn_block_height >= unlock_height, then return struct where - /// amount_unlocked = 0, unlock_height = 0), and the amount of tokens which - /// are "unlocked" by the canonicalization + /// (i.e., if burn_block_height >= unlock_height, then return + /// STXBalance::Unlocked { amount: total_balance }), and the amount of + /// tokens which are "unlocked" by the canonicalization. pub fn canonical_repr_at_block( &self, burn_block_height: u64, diff --git a/clarity/src/vm/errors.rs b/clarity/src/vm/errors.rs index 8f6fa863494..00a486a1475 100644 --- a/clarity/src/vm/errors.rs +++ b/clarity/src/vm/errors.rs @@ -173,8 +173,8 @@ pub enum RuntimeError { /// These errors halt evaluation and fail the transaction. pub enum EarlyReturnError { /// Failed to unwrap an `Optional` (`none`) or `Response` (`err` or `ok`) Clarity value. - /// The `Box` holds the original or thrown value. Triggered by `try!`, `unwrap-or`, or - /// `unwrap-err-or`. + /// The `Box` holds the original or thrown value. Triggered by `try!`, `unwrap!`, or + /// `unwrap-err!`. UnwrapFailed(Box), /// An 'asserts!' expression evaluated to false. /// The `Box` holds the value provided as the second argument to `asserts!`. diff --git a/clarity/src/vm/functions/database.rs b/clarity/src/vm/functions/database.rs index 7167c6d5358..2390703c705 100644 --- a/clarity/src/vm/functions/database.rs +++ b/clarity/src/vm/functions/database.rs @@ -934,7 +934,7 @@ pub fn special_delete_entry_v205( /// # Errors: /// - [`RuntimeCheckErrorKind`] cost errors (e.g., `CostOverflow`, `CostBalanceExceeded`) from [`runtime_cost`]. /// - [`RuntimeCheckErrorKind::IncorrectArgumentCount`] if there aren't 2 arguments. -/// - [`RuntimeCheckErrorKind::GetBlockInfoExpectPropertyName`] if `args[0]` isn't a ClarityName or isn't a valid [`BlockInfoProperty`]. +/// - [`RuntimeCheckErrorKind::Unreachable`] if `args[0]` isn't a ClarityName or isn't a valid [`BlockInfoProperty`] (the static analyzer normally rejects this with [`StaticCheckErrorKind::GetBlockInfoExpectPropertyName`] before reaching runtime). /// - [`RuntimeCheckErrorKind::TypeValueError`] if `args[1]` doesn't evaluate to a `uint`. /// - [`VmExecutionError`] propagated from [`eval`] when evaluating `args[1]`. /// - [`VmInternalError`] from database operations when retrieving block information. @@ -1091,15 +1091,15 @@ pub fn special_get_block_info( } /// Handles the `get-burn-block-info?` special function. -/// Interprets `args` as variables `[property_name, burn_block_height]`, and returns -/// a property value determined by `property_name`: -/// - `header_hash` returns the burn block header hash at `burn_block_height` -/// - `pox_addrs` returns the list of PoX addresses paid out at `burn_block_height` +/// Interprets `args` as variables `[property-name, burn-block-height]`, and returns +/// a property value determined by `property-name`: +/// - `header-hash` returns the burn block header hash at `burn-block-height` +/// - `pox-addrs` returns the list of PoX addresses paid out at `burn-block-height` /// /// # Errors: /// - [`RuntimeCheckErrorKind::IncorrectArgumentCount`] if there aren't 2 arguments. -/// - [`RuntimeCheckErrorKind::GetBlockInfoExpectPropertyName`] if `args[0]` isn't a ClarityName. -/// - [`RuntimeCheckErrorKind::NoSuchBurnBlockInfoProperty`] if `args[0]` isn't a [`BurnBlockInfoProperty`]. +/// - [`RuntimeCheckErrorKind::Unreachable`] if `args[0]` isn't a ClarityName (the static analyzer normally rejects this). +/// - [`RuntimeCheckErrorKind::Unreachable`] if `args[0]` isn't a [`BurnBlockInfoProperty`] (the static analyzer normally rejects this with [`StaticCheckErrorKind::NoSuchBurnBlockInfoProperty`]). /// - [`RuntimeCheckErrorKind::TypeValueError`] if `args[1]` doesn't evaluate to a `uint`. /// - [`RuntimeCheckErrorKind`] cost errors (e.g., `CostOverflow`, `CostBalanceExceeded`) from [`runtime_cost`]. /// - [`VmExecutionError`] propagated from [`eval`] when evaluating `args[1]`. @@ -1302,7 +1302,7 @@ pub fn special_get_stacks_block_info( /// /// # Errors: /// - [`RuntimeCheckErrorKind::IncorrectArgumentCount`] if there aren't 2 arguments. -/// - [`RuntimeCheckErrorKind::GetTenureInfoExpectPropertyName`] if `args[0]` isn't a ClarityName or isn't a valid [`TenureInfoProperty`]. +/// - [`RuntimeCheckErrorKind::Unreachable`] if `args[0]` isn't a ClarityName or isn't a valid [`TenureInfoProperty`] (the static analyzer normally rejects this with [`StaticCheckErrorKind::GetTenureInfoExpectPropertyName`] before reaching runtime). /// - [`RuntimeCheckErrorKind::TypeValueError`] if `args[1]` doesn't evaluate to a `uint`. /// - [`RuntimeCheckErrorKind`] cost errors (e.g., `CostOverflow`, `CostBalanceExceeded`) from [`runtime_cost`]. /// - [`VmExecutionError`] propagated from [`eval`] when evaluating `args[1]`. diff --git a/libsigner/src/events.rs b/libsigner/src/events.rs index 44775497249..d2d47f581c9 100644 --- a/libsigner/src/events.rs +++ b/libsigner/src/events.rs @@ -111,7 +111,7 @@ pub struct BlockProposalData { } impl BlockProposalData { - /// Create a new BlockProposalData for the provided server version and unknown bytes + /// Create a new BlockProposalData for the provided server version and miner diagnostic data. pub fn new(server_version: String, miner_diagnostic_data: MinerDiagnosticData) -> Self { Self { version: BLOCK_PROPOSAL_DATA_VERSION, @@ -400,7 +400,7 @@ impl EventReceiver for SignerEventReceiver { /// Start listening on the given socket address. /// Returns the address that was bound. - /// Errors out if bind(2) fails + /// Panics if `HttpServer::http()` fails to bind to the listener address. fn bind(&mut self, listener: SocketAddr) -> Result { self.http_server = Some(HttpServer::http(listener).expect("failed to start HttpServer")); self.local_addr = Some(listener); diff --git a/libsigner/src/http.rs b/libsigner/src/http.rs index ba135b69f63..304360ffa87 100644 --- a/libsigner/src/http.rs +++ b/libsigner/src/http.rs @@ -58,7 +58,7 @@ impl SignerHttpRequest { } /// Decode the HTTP request payload into its headers and body. -/// Returns (verb, path, table of headers, body_offset) on success +/// Returns a `SignerHttpRequest` (verb, path, table of headers, body_offset) on success. pub fn decode_http_request(payload: &[u8]) -> Result { // realistically, there won't be more than 32 headers let mut headers_buf = [httparse::EMPTY_HEADER; MAX_HTTP_HEADERS]; @@ -123,7 +123,7 @@ pub fn decode_http_request(payload: &[u8]) -> Result { /// This is the main loop body for the signer. It continuously receives events from /// `event_recv`, polling for up to `self.get_event_timeout()` units of time. Once it has /// polled for events, they are fed into `run_one_pass()`. This continues until either - /// `run_one_pass()` returns `false`, or the event receiver hangs up. At this point, this + /// `run_one_pass()` returns `Some(R)`, or the event receiver hangs up. At this point, this /// method calls the `event_stop_signaler.send()` to terminate the receiver. /// /// This would run in a separate thread from the event receiver. diff --git a/libsigner/src/signer_set.rs b/libsigner/src/signer_set.rs index 75c25bacbfd..ab337dfd7fe 100644 --- a/libsigner/src/signer_set.rs +++ b/libsigner/src/signer_set.rs @@ -48,7 +48,7 @@ pub enum Error { } impl SignerEntries { - /// Try to parse the reward set defined by `NakamotoSignEntry` into the SignerEntries struct + /// Try to parse the reward set defined by `NakamotoSignerEntry` into the SignerEntries struct pub fn parse(is_mainnet: bool, reward_set: &[NakamotoSignerEntry]) -> Result { let mut signer_pk_to_id = HashMap::with_capacity(reward_set.len()); let mut signer_id_to_pk = HashMap::with_capacity(reward_set.len()); diff --git a/libsigner/src/v0/messages.rs b/libsigner/src/v0/messages.rs index 8220a3e99f4..2256a8d82de 100644 --- a/libsigner/src/v0/messages.rs +++ b/libsigner/src/v0/messages.rs @@ -354,7 +354,7 @@ pub struct MockProposal { } impl MockProposal { - /// Create a new mock proposal data struct from the provided peer info, chain id, and private key. + /// Create a new mock proposal data struct from the provided peer info and private key. pub fn new(peer_info: PeerInfo, stacks_private_key: &StacksPrivateKey) -> Self { let mut sig = Self { signature: MessageSignature::empty(), @@ -1412,7 +1412,7 @@ impl BlockResponse { } } - /// Get the block accept data from the block response + /// Get the block rejection data from the block response pub fn as_block_rejection(&self) -> Option<&BlockRejection> { match self { BlockResponse::Rejected(rejection) => Some(rejection), @@ -1530,7 +1530,8 @@ pub struct BlockResponseData { } impl BlockResponseData { - /// Create a new BlockResponseData for the provided tenure extend timestamp and unknown bytes + /// Create a new BlockResponseData from the provided tenure-extend timestamp, reject reason, + /// tenure-extend read-count timestamp, and failed-tx id. `unknown_bytes` is initialised empty. pub fn new( tenure_extend_timestamp: u64, reject_reason: RejectReason, @@ -1625,7 +1626,7 @@ impl StacksMessageCodec for BlockResponseData { } } -/// A rejection response from a signer for a proposed block +/// An acceptance response from a signer for a proposed block #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct BlockAccepted { /// The signer signature hash of the block that was accepted diff --git a/pox-locking/src/lib.rs b/pox-locking/src/lib.rs index ee67990caab..6e65c73d8e7 100644 --- a/pox-locking/src/lib.rs +++ b/pox-locking/src/lib.rs @@ -20,7 +20,7 @@ //! This library provides a contract-call special case handler //! `crate::handle_contract_call_special_cases()` which matches a //! contract-call result against zero-address published contracts -//! `pox`, `pox-2`, and `pox-3`. For each of those contracts, it +//! `pox`, `pox-2`, `pox-3`, and `pox-4`. For each of those contracts, it //! checks if the function called requires applying or updating the //! `STXBalance` struct's locks, and if the function was successfully //! invoked. If so, it updates the PoX lock. diff --git a/pox-locking/src/pox_2.rs b/pox-locking/src/pox_2.rs index e2b605786eb..0e488a60ed0 100644 --- a/pox-locking/src/pox_2.rs +++ b/pox-locking/src/pox_2.rs @@ -56,7 +56,7 @@ pub fn is_read_only(func_name: &str) -> bool { } /// Parse the returned value from PoX `stack-stx` and `delegate-stack-stx` functions -/// from pox-2.clar or pox-3.clar into a format more readily digestible in rust. +/// from pox-2.clar, pox-3.clar, or pox-4.clar into a format more readily digestible in rust. /// Panics if the supplied value doesn't match the expected tuple structure pub fn parse_pox_stacking_result( result: &Value, @@ -98,7 +98,7 @@ pub fn parse_pox_stacking_result( } } -/// Parse the returned value from PoX2 or PoX3 `stack-extend` and `delegate-stack-extend` functions +/// Parse the returned value from PoX2, PoX3, or PoX4 `stack-extend` and `delegate-stack-extend` functions /// into a format more readily digestible in rust. /// Panics if the supplied value doesn't match the expected tuple structure pub fn parse_pox_extend_result(result: &Value) -> std::result::Result<(PrincipalData, u64), i128> { @@ -133,7 +133,7 @@ pub fn parse_pox_extend_result(result: &Value) -> std::result::Result<(Principal } } -/// Parse the returned value from PoX2 or PoX3 `stack-increase` function +/// Parse the returned value from PoX2, PoX3, or PoX4 `stack-increase` function /// into a format more readily digestible in rust. /// Panics if the supplied value doesn't match the expected tuple structure pub fn parse_pox_increase(result: &Value) -> std::result::Result<(PrincipalData, u128), i128> { @@ -172,7 +172,7 @@ pub fn parse_pox_increase(result: &Value) -> std::result::Result<(PrincipalData, /// Returns Ok( account snapshot ) when successful /// /// # Errors -/// - Returns Error::PoxExtendNotLocked if this function was called on an account +/// - Returns LockingError::PoxExtendNotLocked if this function was called on an account /// which isn't locked. This *should* have been checked by the PoX v2 contract, /// so this should surface in a panic. pub fn pox_lock_increase_v2( @@ -225,7 +225,7 @@ pub fn pox_lock_increase_v2( /// Returns Ok(lock_amount) when successful /// /// # Errors -/// - Returns Error::PoxExtendNotLocked if this function was called on an account +/// - Returns LockingError::PoxExtendNotLocked if this function was called on an account /// which isn't locked. This *should* have been checked by the PoX v2 contract, /// so this should surface in a panic. pub fn pox_lock_extend_v2( diff --git a/pox-locking/src/pox_3.rs b/pox-locking/src/pox_3.rs index 1aefe8ec05d..58108ef92ee 100644 --- a/pox-locking/src/pox_3.rs +++ b/pox-locking/src/pox_3.rs @@ -95,7 +95,7 @@ pub fn pox_lock_v3( /// Returns Ok(lock_amount) when successful /// /// # Errors -/// - Returns Error::PoxExtendNotLocked if this function was called on an account +/// - Returns LockingError::PoxExtendNotLocked if this function was called on an account /// which isn't locked. This *should* have been checked by the PoX v3 contract, /// so this should surface in a panic. pub fn pox_lock_extend_v3( @@ -131,7 +131,7 @@ pub fn pox_lock_extend_v3( /// Returns Ok( account snapshot ) when successful /// /// # Errors -/// - Returns Error::PoxExtendNotLocked if this function was called on an account +/// - Returns LockingError::PoxExtendNotLocked if this function was called on an account /// which isn't locked. This *should* have been checked by the PoX v3 contract, /// so this should surface in a panic. pub fn pox_lock_increase_v3( diff --git a/pox-locking/src/pox_4.rs b/pox-locking/src/pox_4.rs index de8eeea38bc..413c00e4efa 100644 --- a/pox-locking/src/pox_4.rs +++ b/pox-locking/src/pox_4.rs @@ -68,7 +68,7 @@ pub fn pox_lock_v4( /// Returns Ok(lock_amount) when successful /// /// # Errors -/// - Returns Error::PoxExtendNotLocked if this function was called on an account +/// - Returns LockingError::PoxExtendNotLocked if this function was called on an account /// which isn't locked. This *should* have been checked by the PoX v4 contract, /// so this should surface in a panic. pub fn pox_lock_extend_v4( @@ -104,7 +104,7 @@ pub fn pox_lock_extend_v4( /// Returns Ok( account snapshot ) when successful /// /// # Errors -/// - Returns Error::PoxExtendNotLocked if this function was called on an account +/// - Returns LockingError::PoxExtendNotLocked if this function was called on an account /// which isn't locked. This *should* have been checked by the PoX v4 contract, /// so this should surface in a panic. pub fn pox_lock_increase_v4( diff --git a/stacks-codec/src/lib.rs b/stacks-codec/src/lib.rs index dbdf88400da..d8cf9c37d79 100644 --- a/stacks-codec/src/lib.rs +++ b/stacks-codec/src/lib.rs @@ -242,7 +242,7 @@ pub const MAX_PAYLOAD_LEN: u32 = 1 + 16 * 1024 * 1024; pub const MAX_MESSAGE_LEN: u32 = MAX_PAYLOAD_LEN + (PREAMBLE_ENCODED_SIZE + MAX_RELAYERS_LEN * RELAY_DATA_ENCODED_SIZE); -/// P2P preamble length (addands correspond to fields above) +/// P2P preamble length (addends correspond to the fields of `blockstack_lib::net::Preamble`, in order). pub const PREAMBLE_ENCODED_SIZE: u32 = 4 + 4 + 4 diff --git a/stacks-common/src/util/db.rs b/stacks-common/src/util/db.rs index da629dfde25..e5ae3a75b69 100644 --- a/stacks-common/src/util/db.rs +++ b/stacks-common/src/util/db.rs @@ -48,8 +48,10 @@ pub fn update_lock_table(conn: &Connection) { LOCK_TABLE.lock().unwrap().insert(k, v); } -/// Called by `rusqlite` if we are waiting too long on a database lock -/// If called too many times, will assume a deadlock and panic +/// Called by `rusqlite` if we are waiting too long on a database lock. +/// Logs an error with a backtrace and the current `LOCK_TABLE` every +/// ~5 minutes of accumulated waiting, then keeps sleeping and returning +/// `true` so `rusqlite` retries the lock indefinitely. pub fn tx_busy_handler(run_count: i32) -> bool { const AVG_SLEEP_TIME_MS: u64 = 100; diff --git a/stacks-common/src/util/hash.rs b/stacks-common/src/util/hash.rs index e33483d18ca..29248c804c8 100644 --- a/stacks-common/src/util/hash.rs +++ b/stacks-common/src/util/hash.rs @@ -519,7 +519,9 @@ where } /// Get the path from the given data's leaf up to the root. - /// will be None if the data isn't a leaf. + /// Will be `None` if the data isn't a leaf and the tree is non-empty. + /// **Panics** if `self` is empty (built via `MerkleTree::empty()` or + /// `MerkleTree::new(&[])`) — there is no row to index into. pub fn path(&self, data: &[u8]) -> Option> { let leaf_hash = MerkleTree::get_leaf_hash(data); let mut hash_index = self.find_hash_index(&leaf_hash, 0)?; diff --git a/stacks-common/src/util/lru_cache.rs b/stacks-common/src/util/lru_cache.rs index 91233d9ec4e..83005a88bcb 100644 --- a/stacks-common/src/util/lru_cache.rs +++ b/stacks-common/src/util/lru_cache.rs @@ -204,8 +204,7 @@ impl LruCache { /// Flush all dirty values in the cache, calling the given function, `f`, /// for each dirty value. - /// Outer result is an error iff the cache is corrupted and should be discarded. - /// Inner result is an error iff the function, `f`, returns an error. + /// Returns an error iff the function, `f`, returns an error. pub fn flush( &mut self, mut f: impl FnMut(&K, V) -> Result<(), E>, diff --git a/stacks-node/src/nakamoto_node/relayer.rs b/stacks-node/src/nakamoto_node/relayer.rs index 6b0bdea184e..ebfc6e89021 100644 --- a/stacks-node/src/nakamoto_node/relayer.rs +++ b/stacks-node/src/nakamoto_node/relayer.rs @@ -1022,7 +1022,8 @@ impl RelayerThread { } /// Create and broadcast a VRF public key registration transaction. - /// Returns true if we succeed in doing so; false if not. + /// No-ops (without indicating failure) if a registration is already in-flight or if the + /// underlying bitcoin submission fails — callers cannot observe success from this method. pub fn rotate_vrf_and_register(&mut self, burn_block: &BlockSnapshot) { if self.last_vrf_key_burn_height.is_some() { // already in-flight @@ -1062,8 +1063,9 @@ impl RelayerThread { /// /// Takes the Nakamoto chain tip (consensus hash, block header hash). /// - /// Returns the (the most recent burn snapshot, the most recent stakcs tip, the commit-op) on success - /// Returns None if we fail somehow. + /// Returns Ok(LastCommit) on success — its block_commit/burn_tip/stacks_tip + /// fields are the most recent commit-op, burn snapshot, and stacks tip. + /// Returns Err(NakamotoNodeError) if we fail somehow. /// /// TODO: unit test pub(crate) fn make_block_commit( @@ -2282,8 +2284,10 @@ impl RelayerThread { continue_running } - /// Reload config.burnchain to see if burn_fee_cap has changed. - /// If it has, update the miner spend amount and return true. + /// Reload `config.burnchain` and check whether it has changed from the last observed value. + /// Unconditionally update the miner's recorded spend amount and last-seen burnchain config. + /// Returns `(changed, current_burnchain_config)` where `changed` is true iff the burnchain + /// config differs from the last one observed (false on the first call). pub fn check_burnchain_config_changed(&self) -> (bool, BurnchainConfig) { let burnchain_config = self.config.get_burnchain_config(); let last_burnchain_config_opt = self.globals.get_last_burnchain_config(); diff --git a/stacks-node/src/nakamoto_node/stackerdb_listener.rs b/stacks-node/src/nakamoto_node/stackerdb_listener.rs index 6045a5e3bd6..5d4bdf3d6b4 100644 --- a/stacks-node/src/nakamoto_node/stackerdb_listener.rs +++ b/stacks-node/src/nakamoto_node/stackerdb_listener.rs @@ -749,7 +749,7 @@ impl StackerDBListenerComms { } /// Get the timestamp at which at least 70% of the signing power should be - /// willing to accept a time-based tenure extension. + /// willing to accept a time-based read-count extension. pub fn get_read_count_extend_timestamp(&self, weight_threshold: u32) -> u64 { let signer_read_count_timestamps = self .signer_read_count_timestamps diff --git a/stacks-signer/src/client/stacks_client.rs b/stacks-signer/src/client/stacks_client.rs index 0739fd72bab..4cf7ecc696d 100644 --- a/stacks-signer/src/client/stacks_client.rs +++ b/stacks-signer/src/client/stacks_client.rs @@ -476,7 +476,7 @@ impl StacksClient { Ok(self.get_reward_set(reward_cycle)?.stacker_set.signers) } - /// Get the reward set signers from the stacks node for the given reward cycle + /// Get the reward set from the stacks node for the given reward cycle pub fn get_reward_set(&self, reward_cycle: u64) -> Result { debug!("StacksClient: Getting reward set signers"; "reward_cycle" => reward_cycle, diff --git a/stacks-signer/src/signerdb.rs b/stacks-signer/src/signerdb.rs index d811510f9a4..7b276ecc062 100644 --- a/stacks-signer/src/signerdb.rs +++ b/stacks-signer/src/signerdb.rs @@ -1219,7 +1219,7 @@ impl SignerDb { /// The current schema version used in this build of the signer binary. pub const SCHEMA_VERSION: u32 = SchemaVersion::V19.as_u32(); - /// Create a new `SignerState` instance. + /// Create a new `SignerDb` instance. /// This will create a new SQLite database at the given path /// or an in-memory database if the path is ":memory:" pub fn new(db_path: impl AsRef) -> Result { @@ -1624,7 +1624,7 @@ impl SignerDb { } /// Insert or replace a block into the database. - /// Preserves the `broadcast` column if replacing an existing block. + /// Preserves the `broadcasted` column if replacing an existing block. pub fn insert_block(&mut self, block_info: &BlockInfo) -> Result<(), DBError> { let block_json = serde_json::to_string(&block_info).expect("Unable to serialize block info"); @@ -1738,7 +1738,9 @@ impl SignerDb { .collect() } - /// Record an observed block rejection_signature + /// Record an observed block rejection from a signer, identified by the signer's address and + /// the `RejectReasonPrefix` reject code. Does not record a signature; signatures are recorded + /// by `add_block_signature`. pub fn add_block_rejection_signer_addr( &self, block_sighash: &Sha512Trunc256Sum, diff --git a/stacks-signer/src/v0/signer.rs b/stacks-signer/src/v0/signer.rs index 53f0806c48d..375d545f602 100644 --- a/stacks-signer/src/v0/signer.rs +++ b/stacks-signer/src/v0/signer.rs @@ -2265,7 +2265,9 @@ impl Signer { } } - /// Helper for logging insert_block error + /// Helper for logging an `insert_block` error and then aborting the signer process. + /// This function does not return — it `panic!`s after logging. Callers wired up via + /// `.unwrap_or_else(|e| self.handle_insert_block_error(e))` are signalling intent to halt. pub fn handle_insert_block_error(&self, e: DBError) { error!("{self}: Failed to insert block into signer-db: {e:?}"); panic!("{self} Failed to write block to signerdb: {e}"); diff --git a/stacks-signer/src/v0/signer_state.rs b/stacks-signer/src/v0/signer_state.rs index 6a17bbef38b..14981da4881 100644 --- a/stacks-signer/src/v0/signer_state.rs +++ b/stacks-signer/src/v0/signer_state.rs @@ -98,7 +98,7 @@ pub struct ReplayScope { pub past_tip: NewBurnBlock, } -/// Optional `TxReplayScope`, representing the potential absence of a replay scope. +/// Optional `ReplayScope`, representing the potential absence of a replay scope. pub type ReplayScopeOpt = Option; /// Represents the Tx Replay state @@ -963,7 +963,7 @@ impl LocalStateMachine { } } - /// Determines whether a signer with the `local_address` and `local_update` should capitulate + /// Determines whether a signer with the given `local_update` should capitulate /// its current miner view to a new state. This is not necessarily the same as the current global /// view of the miner as it is up to signers to capitulate before this becomes the finalized view. pub fn capitulate_miner_view( diff --git a/stackslib/src/burnchains/db.rs b/stackslib/src/burnchains/db.rs index 99e835855ce..68b6d22b046 100644 --- a/stackslib/src/burnchains/db.rs +++ b/stackslib/src/burnchains/db.rs @@ -341,7 +341,7 @@ pub static SCHEMA_3: &[&str] = &[ impl BurnchainDBTransaction<'_> { /// Store a burnchain block header into the burnchain database. - /// Returns the row ID on success. + /// Uses `INSERT OR IGNORE`, so a duplicate header is silently dropped. pub(crate) fn store_burnchain_db_entry( &self, header: &BurnchainBlockHeader, diff --git a/stackslib/src/chainstate/burn/atc.rs b/stackslib/src/chainstate/burn/atc.rs index 4d44adf6672..ffa3f0e782f 100644 --- a/stackslib/src/chainstate/burn/atc.rs +++ b/stackslib/src/chainstate/burn/atc.rs @@ -145,7 +145,7 @@ impl AtcRational { /// that the miner underpaid relative to their past performance, and the closer to 0.0 this ratio /// is, the more likely the null miner wins and this miner loses. /// -/// This table is generated with `make_null_miner_lookup_table()` above. +/// This table is generated with the `make_null_miner_lookup_table()` test below. pub(crate) const ATC_LOOKUP: [AtcRational; 1024] = [ AtcRational(Uint256([14665006693661589504, 0, 0, 0])), AtcRational(Uint256([14663943061084833792, 0, 0, 0])), diff --git a/stackslib/src/chainstate/burn/db/processing.rs b/stackslib/src/chainstate/burn/db/processing.rs index 58fea322125..4d94263ab90 100644 --- a/stackslib/src/chainstate/burn/db/processing.rs +++ b/stackslib/src/chainstate/burn/db/processing.rs @@ -228,7 +228,8 @@ impl SortitionHandleTx<'_> { /// * do a cryptographic sortition to select the next Stacks block /// * commit all valid transactions /// * commit the results of the sortition - /// Returns the BlockSnapshot created from this block. + /// Returns `(BlockSnapshot created from this block, BurnchainStateTransition for the + /// committed ops)` on success. pub fn process_block_ops( &mut self, mainnet: bool, diff --git a/stackslib/src/chainstate/burn/db/sortdb.rs b/stackslib/src/chainstate/burn/db/sortdb.rs index 3125db5630b..394014c8b6e 100644 --- a/stackslib/src/chainstate/burn/db/sortdb.rs +++ b/stackslib/src/chainstate/burn/db/sortdb.rs @@ -2169,8 +2169,7 @@ impl<'a> SortitionHandleConn<'a> { } /// Get consensus hash from a particular chain tip's history - /// Returns None if the block height or block hash does not correspond to a - /// known snapshot. + /// Returns None if the block height does not correspond to a known snapshot. pub fn get_consensus_at(&self, block_height: u64) -> Result, db_error> { if block_height >= BLOCK_HEIGHT_MAX { return Err(db_error::BlockHeightOutOfRange); @@ -3126,7 +3125,7 @@ impl SortitionDB { } /// Get the schema version of a sortition DB, given the path to it. - /// Returns the version string, if it exists. + /// Returns the version number as a `u32`, if it exists. /// /// Does **not** migrate the database (like `open()` or `connect()` would) pub fn get_db_version_from_path(path: &str) -> Result, db_error> { diff --git a/stackslib/src/chainstate/burn/distribution.rs b/stackslib/src/chainstate/burn/distribution.rs index f3abb66a06e..a14d59d242d 100644 --- a/stackslib/src/chainstate/burn/distribution.rs +++ b/stackslib/src/chainstate/burn/distribution.rs @@ -131,7 +131,7 @@ impl BurnSamplePoint { } /// Make a burn distribution -- a list of (burn total, block candidate) pairs -- from a block's - /// block commits and user support burns. + /// block commits. /// /// All operations need to be supplied in an ordered Vec of Vecs containing /// the ops at each block height in a mining commit window. Normally, this window @@ -140,9 +140,6 @@ impl BurnSamplePoint { /// consider which window is active; it merely deduces it by inspecting the length of the /// given `block_commits` argument. /// - /// If a burn refers to more than one commitment, its burn amount is *split* between those - /// commitments - /// /// Burns are evaluated over the mining commitment window, where the effective burn for /// a commitment is := min(last_burn_amount, median over the window) /// diff --git a/stackslib/src/chainstate/burn/mod.rs b/stackslib/src/chainstate/burn/mod.rs index 6a12d68dd9a..437a6ff8173 100644 --- a/stackslib/src/chainstate/burn/mod.rs +++ b/stackslib/src/chainstate/burn/mod.rs @@ -113,7 +113,7 @@ pub struct BlockSnapshot { } impl SortitionHash { - /// Calculate a new sortition hash from the given burn header hash + /// Initial sortition hash, used before any burn header is mixed in. It's all 0's. pub fn initial() -> SortitionHash { SortitionHash([0u8; 32]) } diff --git a/stackslib/src/chainstate/burn/operations/leader_block_commit.rs b/stackslib/src/chainstate/burn/operations/leader_block_commit.rs index 26641d5c11b..d229ad1acb6 100644 --- a/stackslib/src/chainstate/burn/operations/leader_block_commit.rs +++ b/stackslib/src/chainstate/burn/operations/leader_block_commit.rs @@ -1042,7 +1042,9 @@ impl LeaderBlockCommitOp { Ok(()) } - /// Returns Ok() and a vector of PoxAddresses which were punished by this op + /// Validates this block-commit. On success, records how each PoX address in the reward set + /// was treated by this op (reward or punishment) in `self.treatment` — but only when + /// `reward_set_info.allow_nakamoto_punishment` is true. pub fn check( &mut self, burnchain: &Burnchain, diff --git a/stackslib/src/chainstate/coordinator/mod.rs b/stackslib/src/chainstate/coordinator/mod.rs index e78303dbc6a..c0d7ce7b470 100644 --- a/stackslib/src/chainstate/coordinator/mod.rs +++ b/stackslib/src/chainstate/coordinator/mod.rs @@ -558,8 +558,7 @@ impl< } /// This is the Stacks 2.x coordinator loop body, which handles communications - /// from the given `comms`. It returns `true` if the coordinator is still running, and `false` - /// if not. + /// dispatched by the given event `bits`. Returns `true` if the coordinator is still running, and `false` otherwise. pub fn handle_comms_epoch2(&mut self, bits: u8, miner_status: Arc>) -> bool { // timeout so that we handle Ctrl-C a little gracefully if (bits & (CoordinatorEvents::NEW_STACKS_BLOCK as u8)) != 0 { diff --git a/stackslib/src/chainstate/nakamoto/coordinator/mod.rs b/stackslib/src/chainstate/nakamoto/coordinator/mod.rs index 0e17267361f..f19a471a4f9 100644 --- a/stackslib/src/chainstate/nakamoto/coordinator/mod.rs +++ b/stackslib/src/chainstate/nakamoto/coordinator/mod.rs @@ -293,7 +293,6 @@ fn find_prepare_phase_sortitions( /// /// Returns Ok(Some(reward-cycle-info)) if we found the first sortition in the prepare phase. /// Returns Ok(None) if we're still waiting for the PoX anchor block sortition -/// Returns Err(Error::NotInPreparePhase) if `burn_height` is not in the prepare phase pub fn get_nakamoto_reward_cycle_info( sortition_tip: &SortitionId, reward_cycle: u64, @@ -766,10 +765,10 @@ impl< fn fault_injection_pause_nakamoto_block_processing() {} /// Handle one or more new Nakamoto Stacks blocks. - /// If we process a PoX anchor block, then return its block hash. This unblocks processing the - /// next reward cycle's burnchain blocks. Subsequent calls to this function will terminate - /// with Some(pox-anchor-block-hash) until the reward cycle info is processed in the sortition - /// DB. + /// When this function reaches the first Stacks block in the prepare phase for the next reward + /// cycle, it pauses to process burnchain sortitions for that cycle (via an inline call to + /// `handle_new_nakamoto_burnchain_block`) before continuing. The successful return is always + /// `Ok(None)`; the `Option` in the return type is reserved for future use. pub fn handle_new_nakamoto_stacks_block(&mut self) -> Result, Error> { debug!("Handle new Nakamoto block"); let canonical_sortition_tip = self.canonical_sortition_tip.clone().ok_or_else(|| { diff --git a/stackslib/src/chainstate/nakamoto/keys.rs b/stackslib/src/chainstate/nakamoto/keys.rs index 5883917ec55..e3e0d0263eb 100644 --- a/stackslib/src/chainstate/nakamoto/keys.rs +++ b/stackslib/src/chainstate/nakamoto/keys.rs @@ -57,7 +57,9 @@ pub fn tenure_start_block_id(ch: &ConsensusHash) -> String { format!("nakamoto::headers::tenure_start_block_id::{}", ch) } -/// MARF key to map a tenure to its final block's block ID +/// MARF key marking a tenure as finished. The stored value is the boolean +/// `true` (see `make_bool_value`); presence of this key indicates the tenure +/// has ended, absence indicates it is still in progress. pub fn finished_tenure_consensus_hash(ch: &ConsensusHash) -> String { format!("nakamoto::tenures::finished_tenure_consensus_hash::{}", ch) } diff --git a/stackslib/src/chainstate/nakamoto/miner.rs b/stackslib/src/chainstate/nakamoto/miner.rs index 497c967f4a2..11bf8b6d493 100644 --- a/stackslib/src/chainstate/nakamoto/miner.rs +++ b/stackslib/src/chainstate/nakamoto/miner.rs @@ -245,7 +245,8 @@ pub struct BlockMetadata { pub tenure_consumed: ExecutionCost, /// The cost budget for the current tenure pub tenure_budget: ExecutionCost, - /// The size of the blocks in the current tenure in bytes + /// The size, in bytes, of the single block just built (i.e. `builder.bytes_so_far`). + /// Tenure-wide accumulation lives on `StacksHeaderInfo::total_tenure_size`. pub tenure_size: u64, /// The events emitted by the transactions included in this block pub tx_events: Vec, @@ -274,7 +275,7 @@ impl NakamotoBlockBuilder { /// Make a Nakamoto block builder appropriate for building atop the given block header /// - /// * `parent_stacker_header` - the stacks header this builder's block will build off + /// * `parent_stacks_header` - the stacks header this builder's block will build off /// /// * `tenure_id_consensus_hash` - consensus hash of this tenure's burnchain block. /// This is the consensus hash that goes into the block header. @@ -290,6 +291,13 @@ impl NakamotoBlockBuilder { /// /// * `soft_limit` - an optional soft limit for the block's clarity cost for this block /// + /// * `contract_limit_percentage` - an optional cap (as a percentage of the block budget) for + /// contract-call cost in this block + /// + /// * `timestamp` - an optional override for the block-header timestamp + /// + /// * `max_tenure_bytes` - the maximum total byte budget for the tenure + /// pub fn new( parent_stacks_header: &StacksHeaderInfo, tenure_id_consensus_hash: &ConsensusHash, diff --git a/stackslib/src/chainstate/nakamoto/mod.rs b/stackslib/src/chainstate/nakamoto/mod.rs index a0112f49feb..c39366d4652 100644 --- a/stackslib/src/chainstate/nakamoto/mod.rs +++ b/stackslib/src/chainstate/nakamoto/mod.rs @@ -841,7 +841,8 @@ impl NakamotoBlockHeader { /// - Order of signatures is maintained vs signer set /// /// Returns the signing weight on success. - /// Returns ChainstateError::InvalidStacksBlock on error + /// Returns ChainstateError::InvalidStacksBlock when the signatures fail validation, + /// or ChainstateError::NoRegisteredSigners if the reward set has no signers. #[cfg_attr(test, mutants::skip)] pub fn verify_signer_signatures(&self, reward_set: &RewardSet) -> Result { let message = self.signer_signature_hash(); @@ -2544,7 +2545,9 @@ impl NakamotoChainState { .map_err(ChainstateError::from) } - /// Return the ExecutionCost of `block` + /// Return the total tenure ExecutionCost up to and including `block`. + /// This queries the `total_tenure_cost` column (cumulative); use the `cost` column for the + /// per-block ExecutionCost. pub fn get_block_cost( chainstate_conn: &Connection, block: &StacksBlockId, @@ -3116,7 +3119,7 @@ impl NakamotoChainState { } /// Get the status of a Nakamoto block. - /// Returns Some(accepted?, orphaned?) on success + /// Returns Some(processed?, orphaned?) on success /// Returns None if there's no such block /// Returns Err on DBError pub fn get_nakamoto_block_status( @@ -3718,7 +3721,8 @@ impl NakamotoChainState { } } - /// Get index_block_hash and transaction payload hex by txid from the transactions table + /// Get the index_block_hash, transaction payload hex, and execution result string for a txid + /// from the transactions table. pub fn get_tx_info_from_txid( conn: &Connection, txid: &Txid, @@ -4397,7 +4401,7 @@ impl NakamotoChainState { /// `mine_anchored_block` in miner.rs. /// Processes matured miner rewards, alters liquid supply of ustx, processes /// stx lock events, and marks the microblock public key as used - /// Returns stx lockup events. + /// Returns the stx lockup events and (on a new tenure) the SIP-031 mint/transfer event. pub fn finish_block( clarity_tx: &mut ClarityTx, miner_payouts: Option<&MaturedMinerRewards>, @@ -5234,7 +5238,6 @@ impl NakamotoChainState { /// Returns Some(Range) if the miner is in the StackerDB config, where the range of slots for the miner is [start, end). /// i.e., inclusive of `start`, exclusive of `end`. /// Returns None if the miner is not in the StackerDB config. - /// Returns an error if the miner is in the StackerDB config but the slot number is invalid. pub fn get_miner_slot( sortdb: &SortitionDB, tip: &BlockSnapshot, diff --git a/stackslib/src/chainstate/nakamoto/shadow.rs b/stackslib/src/chainstate/nakamoto/shadow.rs index 58133588a29..e46209a2c43 100644 --- a/stackslib/src/chainstate/nakamoto/shadow.rs +++ b/stackslib/src/chainstate/nakamoto/shadow.rs @@ -114,8 +114,9 @@ impl NakamotoBlock { self.header.is_shadow_block() } - /// Verify that if this shadow block has a coinbase, that its VRF proof is consistent with the leader - /// public key's VRF key. If there is no coinbase tx, then this is a no-op. + /// Verify that if this shadow block has a coinbase, then it carries a VRF proof and pays to the + /// burn address for the configured network. The VRF proof itself is not checked against any key + /// (shadow blocks are not produced by a miner). If there is no coinbase tx, then this is a no-op. pub(crate) fn check_shadow_coinbase_tx(&self, mainnet: bool) -> Result<(), ChainstateError> { if !self.is_shadow_block() { error!( @@ -170,7 +171,7 @@ impl NakamotoBlock { /// /// Verifies the following: /// -- (self.header.consensus_hash) that this block falls into this block-commit's tenure - /// -- (self.header.burn_spent) that this block's burn total matches `burn_tip`'s total burn + /// -- (self.header.burn_spent) that this block's burn total matches `tenure_burn_chain_tip`'s total burn /// -- if this block has a tenure change, then it's consistent with the miner's public key and /// self.header.consensus_hash /// @@ -313,7 +314,7 @@ impl NakamotoChainState { /// Load the stored VRF proof for the given shadow block's tenure. /// /// Returns Ok(Some(vrf proof)) on success - /// Returns Ok(None) if the parent tenure isn't a shadow tenure + /// Returns Ok(None) if `tip_block_id` is not present or is not a shadow block pub(crate) fn get_shadow_vrf_proof( chainstate_conn: &mut SDBI, tip_block_id: &StacksBlockId, @@ -421,7 +422,7 @@ impl NakamotoChainState { } impl NakamotoBlockBuilder { - /// This function should be called before `tenure_begin`. + /// This function should be called before `shadow_tenure_begin`. /// It creates a MinerTenureInfo struct which owns connections to the chainstate and sortition /// DBs, so that block-processing is guaranteed to terminate before the lives of these handles /// expire. diff --git a/stackslib/src/chainstate/nakamoto/signer_set.rs b/stackslib/src/chainstate/nakamoto/signer_set.rs index 737ae834b4b..e28b7a77a34 100644 --- a/stackslib/src/chainstate/nakamoto/signer_set.rs +++ b/stackslib/src/chainstate/nakamoto/signer_set.rs @@ -197,7 +197,8 @@ impl NakamotoSigners { } /// Compute the reward set for the next reward cycle, store it, and write it to the .signers - /// contract. `reward_cycle` is the _current_ reward cycle. + /// contract. `reward_cycle` is the upcoming cycle the reward set is being computed *for* + /// (i.e. the cycle the prepare phase is preparing). pub fn handle_signer_stackerdb_update( clarity: &mut ClarityTransactionConnection, pox_constants: &PoxConstants, diff --git a/stackslib/src/chainstate/nakamoto/staging_blocks.rs b/stackslib/src/chainstate/nakamoto/staging_blocks.rs index 1a08778d14b..4cd689ca079 100644 --- a/stackslib/src/chainstate/nakamoto/staging_blocks.rs +++ b/stackslib/src/chainstate/nakamoto/staging_blocks.rs @@ -279,9 +279,10 @@ impl<'a> NakamotoStagingBlocksConnRef<'a> { Ok(res.is_some()) } - /// Get the block ID, processed-status, orphan-status, and signing weight of the non-orphaned + /// Get the block ID, processed-status, orphan-status, and signing weight of the /// block with the given consensus hash and sighash with the most amount of signatures. - /// There will be at most one such block. + /// There will be at most one such block. The returned `orphaned` flag lets the caller + /// decide how to handle an orphaned match — the query does not filter on it. /// /// NOTE: for Nakamoto blocks, the sighash is the same as the block hash. pub fn get_block_processed_and_signed_weight( @@ -434,7 +435,7 @@ impl<'a> NakamotoStagingBlocksConnRef<'a> { .collect()) } - /// Get all nakamoto blocks in a tenure + /// Get all processed nakamoto blocks in a tenure. pub fn get_nakamoto_blocks_in_tenure( &self, consensus_hash: &ConsensusHash, @@ -543,8 +544,7 @@ impl<'a> NakamotoStagingBlocksConnRef<'a> { impl NakamotoStagingBlocksTx<'_> { /// Notify the staging database that a given stacks block has been processed. - /// This will update the attachable status for children blocks, as well as marking the stacks - /// block itself as processed. + /// This marks the staging row for `block` as processed. pub fn set_block_processed(&self, block: &StacksBlockId) -> Result<(), ChainstateError> { let clear_staged_block = "UPDATE nakamoto_staging_blocks SET processed = 1, processed_time = ?2 @@ -558,8 +558,8 @@ impl NakamotoStagingBlocksTx<'_> { } /// Modify the staging database that a given stacks block can never be processed. - /// This will update the attachable status for children blocks, as well as marking the stacks - /// block itself as orphaned. + /// This marks any staging row whose `parent_block_id` is `block` as orphaned, and marks + /// the staging row for `block` itself as both processed and orphaned. pub fn set_block_orphaned(&self, block: &StacksBlockId) -> Result<(), ChainstateError> { let update_dependents = "UPDATE nakamoto_staging_blocks SET orphaned = 1 WHERE parent_block_id = ?"; diff --git a/stackslib/src/chainstate/nakamoto/tenure.rs b/stackslib/src/chainstate/nakamoto/tenure.rs index 99c85bf366e..1469da99789 100644 --- a/stackslib/src/chainstate/nakamoto/tenure.rs +++ b/stackslib/src/chainstate/nakamoto/tenure.rs @@ -333,7 +333,8 @@ impl NakamotoChainState { } /// Get scheduled miner rewards that have matured when this tenure starts. - /// Returns (list of miners to pay, any residual payments to the parent miner) on success. + /// Returns `Ok(Some(MaturedMinerPaymentSchedules { latest_miners, parent_miner }))` on success. + /// Returns `Err(ChainstateError)` if a required header/reward lookup fails. pub(crate) fn get_matured_miner_reward_schedules( chainstate_tx: &mut ChainstateTx, tip_index_hash: &StacksBlockId, @@ -483,9 +484,11 @@ impl NakamotoChainState { Ok(chainstate_conn.get_parent_tenure_consensus_hash(tip_block_id, consensus_hash)?) } - /// Get the number of blocks in a tenure, given a block ID. + /// Get `height_in_tenure` for the Nakamoto block identified by `block_id` + /// (i.e. its 1-indexed position within its tenure). When called with the + /// last block of a tenure, this equals the number of blocks in that tenure. /// Only works for Nakamoto blocks, not Stacks epoch2 blocks. - /// Returns 0 if there are no blocks in this tenure + /// Returns 0 if no row exists for `block_id`. pub fn get_nakamoto_tenure_length( chainstate_conn: &Connection, block_id: &StacksBlockId, @@ -548,8 +551,9 @@ impl NakamotoChainState { /// Verify that a tenure change tx is a valid first-ever tenure change. It must connect to an /// epoch2 block, and it must be sortition-induced. /// - /// Returns Some(mocked-epoch2-tenure) on success - /// Returns None on error + /// Returns Ok(Some(mocked-epoch2-tenure)) on success + /// Returns Ok(None) if the tenure change is invalid + /// Returns Err(..) on DB error pub(crate) fn check_first_nakamoto_tenure_change( headers_conn: &Connection, tenure_payload: &TenureChangePayload, @@ -612,8 +616,9 @@ impl NakamotoChainState { } /// Check that a consensus hash is on the canonical burnchain fork - /// Returns Some(corresponding snapshot) if so - /// Returns None if it's not on the canonical fork + /// Returns Ok(Some(corresponding snapshot)) if so + /// Returns Ok(None) if the consensus hash has no snapshot, or its snapshot is not on the canonical fork + /// Returns Err(..) on DB error pub(crate) fn check_valid_consensus_hash( sort_handle: &mut SH, ch: &ConsensusHash, diff --git a/stackslib/src/chainstate/stacks/auth.rs b/stackslib/src/chainstate/stacks/auth.rs index 9bac5dfaf89..aec3d85fe15 100644 --- a/stackslib/src/chainstate/stacks/auth.rs +++ b/stackslib/src/chainstate/stacks/auth.rs @@ -930,7 +930,7 @@ impl TransactionSpendingCondition { } } - /// Get the mainnet account address of the spending condition + /// Get the testnet account address of the spending condition pub fn address_testnet(&self) -> StacksAddress { match *self { TransactionSpendingCondition::Singlesig(ref data) => data.address_testnet(), diff --git a/stackslib/src/chainstate/stacks/block.rs b/stackslib/src/chainstate/stacks/block.rs index d8093e155df..67d97ac631f 100644 --- a/stackslib/src/chainstate/stacks/block.rs +++ b/stackslib/src/chainstate/stacks/block.rs @@ -423,7 +423,7 @@ impl StacksBlock { } /// Find and return the coinbase transaction. It's always the first transaction. - /// If there are 0 coinbase txs, or more than 1, then return None + /// If the first transaction is not a coinbase (including the empty-block case), return None. pub fn get_coinbase_tx(&self) -> Option { let tx = self.txs.first()?; match tx.payload { @@ -811,8 +811,8 @@ impl StacksMicroblockHeader { StacksMicroblockHeader::first_unsigned(parent_block_hash, &Sha512Trunc256Sum([0u8; 32])) } - /// Create an unsigned microblock header from its parent - /// Return an error on overflow + /// Create an unsigned microblock header from its parent. + /// Returns `None` if `parent_header.sequence + 1` overflows. pub fn from_parent_unsigned( parent_header: &StacksMicroblockHeader, tx_merkle_root: &Sha512Trunc256Sum, diff --git a/stackslib/src/chainstate/stacks/boot/mod.rs b/stackslib/src/chainstate/stacks/boot/mod.rs index 9aa20c9220f..3e6749ce95d 100644 --- a/stackslib/src/chainstate/stacks/boot/mod.rs +++ b/stackslib/src/chainstate/stacks/boot/mod.rs @@ -318,7 +318,7 @@ impl RewardSet { } /// Return the total `weight` of all signers in the reward set. - /// If there are no reward set signers, a ChainstateError is returned. + /// If there are no reward set signers, returns `Err(String)` describing the failure. pub fn total_signing_weight(&self) -> Result { let Some(ref reward_set_signers) = self.signers else { return Err("Unable to calculate total weight - No signers in reward set".to_string()); @@ -507,10 +507,9 @@ impl StacksChainState { // TODO: add tests from mutation testing results #4854 #[cfg_attr(test, mutants::skip)] - /// Do all the necessary Clarity operations at the start of a PoX reward cycle. - /// Currently, this just means applying any auto-unlocks to Stackers who qualified. - /// - /// This should only be called for PoX v4 cycles. + /// No-op start-of-cycle hook for PoX v4. PoX v4 has no Rust-side start-of-cycle + /// operations (unlike v2/v3, which apply missed auto-unlocks here); kept for symmetry + /// with the v2 and v3 helpers. Returns an empty event vector. pub fn handle_pox_cycle_start_pox_4( _clarity: &mut ClarityTransactionConnection, _cycle_number: u64, diff --git a/stackslib/src/chainstate/stacks/db/accounts.rs b/stackslib/src/chainstate/stacks/db/accounts.rs index d09063fdb66..413d414acc8 100644 --- a/stackslib/src/chainstate/stacks/db/accounts.rs +++ b/stackslib/src/chainstate/stacks/db/accounts.rs @@ -981,8 +981,9 @@ impl StacksChainState { } /// Find the latest miner reward to mature, assuming that there are mature rewards. - /// Returns a list of payments to make to each address -- miners and user-support burners -- as - /// well as an info struct about where the rewards took place on the chain. + /// Returns `Some((miner_reward, user_support_payments, parent_miner_reward, info))` where + /// `user_support_payments` is the list of user-support-burner payments and `info` describes + /// where the rewards took place on the chain. Returns `None` if no mature rewards exist. pub fn find_mature_miner_rewards( clarity_tx: &mut ClarityTx, sortdb_conn: &Connection, diff --git a/stackslib/src/chainstate/stacks/db/blocks.rs b/stackslib/src/chainstate/stacks/db/blocks.rs index 8f15deb9289..e2df77445bf 100644 --- a/stackslib/src/chainstate/stacks/db/blocks.rs +++ b/stackslib/src/chainstate/stacks/db/blocks.rs @@ -3265,9 +3265,9 @@ impl StacksChainState { /// Pre-process and store an anchored block to staging, queuing it up for /// subsequent processing once all of its ancestors have been processed. /// - /// Caller must have called SortitionDB::expects_stacks_block() to determine if this block belongs - /// to the blockchain. The consensus_hash is the hash of the burnchain block whose sortition - /// elected the given Stacks block. + /// Caller must have called SortitionHandleTx::expects_stacks_block_in_fork() to determine if + /// this block belongs to the blockchain. The consensus_hash is the hash of the burnchain block + /// whose sortition elected the given Stacks block. /// /// If we find the same Stacks block in two or more burnchain forks, insert it there too. /// @@ -3918,8 +3918,8 @@ impl StacksChainState { Ok(None) } - /// Process a stream of microblocks - /// Return the fees and burns. + /// Process a stream of microblocks. + /// Returns `(fees, burns, receipts)` on success. pub fn process_microblocks_transactions( clarity_tx: &mut ClarityTx, microblocks: &[StacksMicroblock], @@ -4491,7 +4491,7 @@ impl StacksChainState { } /// Process a single anchored block. - /// Return the fees and burns. + /// Returns `(fees, burns, receipts)` on success. pub fn process_block_transactions( clarity_tx: &mut ClarityTx, block_txs: &[StacksTransaction], @@ -4593,7 +4593,9 @@ impl StacksChainState { } /// Process all STX that unlock at this block height. - /// Return the total number of uSTX unlocked in this block + /// Returns `(total_unlocked_ustx, lockup_events)`, where `total_unlocked_ustx` is the total + /// number of uSTX unlocked in this block and `lockup_events` is the list of `STXMintEvent`s + /// emitted for each unlocked recipient. pub fn process_stx_unlocks( clarity_tx: &mut ClarityTx<'_, '_>, ) -> Result<(u128, Vec), Error> { @@ -4983,10 +4985,13 @@ impl StacksChainState { /// Called in both follower and miner block assembly paths. /// - /// Returns clarity_tx, list of receipts, microblock execution cost, - /// microblock fees, microblock burns, list of microblock tx receipts, - /// miner rewards tuples, the stacks epoch id, and a boolean that - /// represents whether the epoch transition has been applied. + /// Returns a `SetupBlockResult`, which contains: clarity_tx, list of receipts, + /// microblock execution cost, microblock fees, microblock burns, list of + /// microblock tx receipts, miner rewards tuples, the stacks epoch id, a boolean + /// that represents whether the epoch transition has been applied, the + /// burnchain-originated stack-stx / transfer-stx / delegate-stx / vote-for-agg-key + /// operations applied in this block, the auto-unlock events emitted by reward-cycle + /// processing, and an optional signer-set calculation result. /// /// The `burn_dbconn`, `sortition_dbconn`, and `conn` arguments /// all reference the same sortition database through different @@ -5328,7 +5333,8 @@ impl StacksChainState { /// processed yet. /// /// Returns a `StacksEpochReceipt` containing receipts and events from the transactions executed - /// in the block, and a `PreCommitClarityBlock` struct. + /// in the block, a `PreCommitClarityBlock` struct, and an `Option` describing + /// the reward set just computed at this block (if any). /// /// The `StacksEpochReceipts` contains the list of transaction /// receipts for the preceeding microblock stream that the diff --git a/stackslib/src/chainstate/stacks/index/marf.rs b/stackslib/src/chainstate/stacks/index/marf.rs index 4d9b71325ff..ea665bd2aac 100644 --- a/stackslib/src/chainstate/stacks/index/marf.rs +++ b/stackslib/src/chainstate/stacks/index/marf.rs @@ -690,7 +690,7 @@ impl<'a, T: MarfTrieId> MarfTransaction<'a, T> { /// Seal the in-RAM MARF state so that no subsequent writes will be permitted. /// Returns the new root hash of the MARF. - /// Runtime-panics if the MARF was already sealed. + /// Returns `Err(Error::ReadOnlyError)` if the MARF was already sealed (i.e. readonly). pub fn seal(&mut self) -> Result { if self.storage.readonly() { return Err(Error::ReadOnlyError); @@ -862,9 +862,7 @@ impl MARF { /// create or open a particular Trie. /// If the trie doesn't exist, then extend it from the current Trie and create a root node that /// has back pointers to its immediate children in the current trie. - /// On Ok, s will point to new_bhh and will be open for reading. - /// Returns true/false, based on whether or not the trie will be created (this can return false - /// if we're resuming work on an unconfirmed trie) + /// On Ok(()), `storage` will point to `new_bhh` and will be open for reading. pub fn extend_trie(storage: &mut TrieStorageTransaction, new_bhh: &T) -> Result<(), Error> { if storage.readonly() { unreachable!("CORRUPTION: constructed read-only TrieStorageTransaction instance"); diff --git a/stackslib/src/chainstate/stacks/miner.rs b/stackslib/src/chainstate/stacks/miner.rs index 5b8a9fe5670..6107cc7cd12 100644 --- a/stackslib/src/chainstate/stacks/miner.rs +++ b/stackslib/src/chainstate/stacks/miner.rs @@ -1856,9 +1856,9 @@ impl StacksBlockBuilder { /// This function should be called before `epoch_begin`. /// It loads the parent microblock stream, sets the parent microblock, and returns /// data necessary for `epoch_begin`. - /// Returns chainstate transaction, clarity instance, burnchain header hash - /// of the burn tip, burn tip height + 1, the parent microblock stream, - /// the parent consensus hash, the parent header hash, and a bool + /// Returns a `MinerEpochInfo` with chainstate transaction, clarity instance, + /// burnchain header hash of the burn tip, burn tip height + 1, the parent + /// microblock stream, and a bool /// representing whether the network is mainnet or not. pub fn pre_epoch_begin<'a>( &mut self, @@ -2285,7 +2285,7 @@ impl StacksBlockBuilder { // Or keep the skip and remove the comment #[cfg_attr(test, mutants::skip)] /// Given access to the mempool, mine an anchored block with no more than the given execution cost. - /// returns the assembled block, and the consumed execution budget. + /// returns the assembled block, the consumed execution budget, and the block size in bytes. pub fn build_anchored_block( chainstate_handle: &StacksChainState, // not directly used; used as a handle to open other chainstates burn_dbconn: &SortitionHandleConn, diff --git a/stackslib/src/chainstate/stacks/transaction.rs b/stackslib/src/chainstate/stacks/transaction.rs index 93c59c1124f..fa48e840a69 100644 --- a/stackslib/src/chainstate/stacks/transaction.rs +++ b/stackslib/src/chainstate/stacks/transaction.rs @@ -838,7 +838,10 @@ impl StacksTransaction { } /// Sign a sighash and append the signature and public key to the given spending condition. - /// Returns the next sighash + /// Returns the sighash that the *next* signer should use. + /// For `Singlesig` and `Multisig`, this is the advanced sighash after this signature. + /// For `OrderIndependentMultisig`, this is `cur_sighash` unchanged, since every signer in an + /// order-independent multisig signs the same sighash. fn sign_and_append( condition: &mut TransactionSpendingCondition, cur_sighash: &Txid, @@ -916,7 +919,9 @@ impl StacksTransaction { } /// Append the next signature from the origin account authorization. - /// Return the next sighash. + /// Return the sighash that the next origin signer should use. + /// For Singlesig / Multisig this is the advanced sighash; for OrderIndependentMultisig + /// it is `cur_sighash` unchanged. pub fn sign_next_origin( &mut self, cur_sighash: &Txid, @@ -949,7 +954,9 @@ impl StacksTransaction { } /// Append the next signature from the sponsoring account. - /// Return the next sighash + /// Return the sighash that the next sponsor signer should use. + /// For Singlesig / Multisig this is the advanced sighash; for OrderIndependentMultisig + /// it is `cur_sighash` unchanged. pub fn sign_next_sponsor( &mut self, cur_sighash: &Txid, diff --git a/stackslib/src/clarity_vm/clarity.rs b/stackslib/src/clarity_vm/clarity.rs index 21d0e07a44b..e1c267e014e 100644 --- a/stackslib/src/clarity_vm/clarity.rs +++ b/stackslib/src/clarity_vm/clarity.rs @@ -191,7 +191,7 @@ pub trait WritableMarfStore: /// These needs are each captured in distinct methods for committing this transaction. pub trait ClarityMarfStoreTransaction { /// Commit all inserted metadata and associate it with the block trie identified by `target`. - /// It can later be deleted via `drop_metadata_for()` if given the same taret. + /// It can later be deleted via `drop_metadata_for_trie()` if given the same target. /// Returns Ok(()) on success /// Returns Err(..) on error fn commit_metadata_for_trie(&mut self, target: &StacksBlockId) -> Result<(), VmExecutionError>; diff --git a/stackslib/src/net/api/getpoxinfo.rs b/stackslib/src/net/api/getpoxinfo.rs index 7dac63c2ea0..696aae83a32 100644 --- a/stackslib/src/net/api/getpoxinfo.rs +++ b/stackslib/src/net/api/getpoxinfo.rs @@ -634,7 +634,7 @@ impl HttpResponse for RPCPoxInfoRequestHandler { } impl StacksHttpRequest { - /// Make a new getinfo request to this endpoint + /// Make a new getpoxinfo request to this endpoint pub fn new_getpoxinfo(host: PeerHost, tip_req: TipRequest) -> StacksHttpRequest { StacksHttpRequest::new_for_peer( host, diff --git a/stackslib/src/net/api/getsigner.rs b/stackslib/src/net/api/getsigner.rs index e80923ba363..ae2e6ee7d40 100644 --- a/stackslib/src/net/api/getsigner.rs +++ b/stackslib/src/net/api/getsigner.rs @@ -164,7 +164,7 @@ impl HttpResponse for GetSignerRequestHandler { } impl StacksHttpRequest { - /// Make a new getinfo request to this endpoint + /// Make a new getsigner request to this endpoint pub fn new_getsigner( host: PeerHost, signer_pubkey: &Secp256k1PublicKey, diff --git a/stackslib/src/net/api/getstackers.rs b/stackslib/src/net/api/getstackers.rs index 31bafa2734f..3c37833148d 100644 --- a/stackslib/src/net/api/getstackers.rs +++ b/stackslib/src/net/api/getstackers.rs @@ -218,7 +218,7 @@ impl HttpResponse for GetStackersRequestHandler { } impl StacksHttpRequest { - /// Make a new getinfo request to this endpoint + /// Make a new getstackers request to this endpoint pub fn new_getstackers( host: PeerHost, cycle_num: u64, diff --git a/stackslib/src/net/api/gettenureinfo.rs b/stackslib/src/net/api/gettenureinfo.rs index 307c7cc6cbb..1e848b78025 100644 --- a/stackslib/src/net/api/gettenureinfo.rs +++ b/stackslib/src/net/api/gettenureinfo.rs @@ -139,7 +139,7 @@ impl HttpResponse for RPCNakamotoTenureInfoRequestHandler { } impl StacksHttpRequest { - /// Make a new getinfo request to this endpoint + /// Make a new get-tenure-info request to this endpoint pub fn new_get_nakamoto_tenure_info(host: PeerHost) -> StacksHttpRequest { StacksHttpRequest::new_for_peer( host, diff --git a/stackslib/src/net/api/gettenuretip.rs b/stackslib/src/net/api/gettenuretip.rs index 595491c40fe..202de83dde6 100644 --- a/stackslib/src/net/api/gettenuretip.rs +++ b/stackslib/src/net/api/gettenuretip.rs @@ -150,7 +150,7 @@ impl HttpResponse for RPCNakamotoTenureTipRequestHandler { } impl StacksHttpRequest { - /// Make a new getinfo request to this endpoint + /// Make a new get-tenure-tip request to this endpoint pub fn new_get_tenure_tip(host: PeerHost, consensus_hash: &ConsensusHash) -> StacksHttpRequest { StacksHttpRequest::new_for_peer( host, diff --git a/stackslib/src/net/chat.rs b/stackslib/src/net/chat.rs index a5d1d673306..c3c4a277e56 100644 --- a/stackslib/src/net/chat.rs +++ b/stackslib/src/net/chat.rs @@ -799,9 +799,9 @@ impl ConversationP2P { } /// Validate an inbound message's preamble against our knowledge of the burn chain. - /// Return Ok(true) if we can proceed - /// Return Ok(false) if we can't proceed, but the remote peer is not in violation of the protocol - /// Return Err(net_error::InvalidMessage) if the remote peer returns an invalid message in + /// Returns Ok(true) if we can proceed. A `debug!` log is emitted (but `Ok(true)` is still + /// returned) when the peer is too far ahead for neighbor walks. + /// Returns Err(net_error::InvalidMessage) if the remote peer returns an invalid message in /// violation of the protocol pub fn is_preamble_valid( &self, @@ -1125,7 +1125,9 @@ impl ConversationP2P { } /// Update connection state from handshake data. - /// Returns true if we learned a new public key; false if not + /// Returns Ok(true) if the peer's public key was *replaced* (a prior key existed and differs + /// from the new one). Returns Ok(false) when the peer is supplying its public key for the + /// first time, or when the new key matches the prior one. pub fn update_from_handshake_data( &mut self, preamble: &Preamble, diff --git a/stackslib/src/net/download/nakamoto/tenure_downloader.rs b/stackslib/src/net/download/nakamoto/tenure_downloader.rs index 5637424795d..80ae17c4662 100644 --- a/stackslib/src/net/download/nakamoto/tenure_downloader.rs +++ b/stackslib/src/net/download/nakamoto/tenure_downloader.rs @@ -479,12 +479,9 @@ impl NakamotoTenureDownloader { /// Produce the next HTTP request that, when successfully executed, will fetch the data needed /// to advance this state machine. - /// Not all states require an HTTP request for advanceement. /// - /// Returns Ok(Some(request)) if a request is needed - /// Returns Ok(None) if a request is not needed (i.e. we're waiting for some other machine's - /// state) - /// Returns Err(()) if we're done. + /// Returns Ok(Some(request)) if a request is needed (any non-`Done` state). + /// Returns Err(()) if we're done (the `Done` state). pub fn make_next_download_request( &self, peerhost: PeerHost, @@ -697,7 +694,7 @@ impl NakamotoTenureDownloader { /// data URL corresponding to self.naddr. /// Returns Ok(true) if we sent the request, or there's already an in-flight request. The /// caller should try this again until it gets one of the other possible return values. - /// Returns Ok(false) if not (e.g. neighbor is known to be dead or broken) + /// Returns Ok(false) if `make_next_download_request` failed to build a request. /// Returns Err(..) if self.naddr is known to be a dead or broken peer, or if we were unable to /// resolve its data URL to a socket address. pub fn send_next_download_request( diff --git a/stackslib/src/net/inv/nakamoto.rs b/stackslib/src/net/inv/nakamoto.rs index fae6eea8a7c..ef0e82c1743 100644 --- a/stackslib/src/net/inv/nakamoto.rs +++ b/stackslib/src/net/inv/nakamoto.rs @@ -524,7 +524,7 @@ impl NakamotoTenureInv { rc_tenures.get(rc_height).unwrap_or(false) } - /// How many reward cycles of data do we have for this peer? + /// Highest reward cycle for which we have any inv data from this peer (zero if none). pub fn highest_reward_cycle(&self) -> u64 { self.tenures_inv .last_key_value() @@ -963,8 +963,8 @@ impl NakamotoInvStateMachine { /// Finish asking for inventories, and update inventory state. /// Returns Ok(num-messages, true) if an inv state machine learned something. - /// Returns Ok(num-messages, false) if not - /// Returns Err(..) on I/O errors + /// Returns Ok(num-messages, false) if not. Per-peer I/O errors are logged and the + /// corresponding neighbor is marked broken via `add_broken`; they are not propagated. pub fn process_getnakamotoinv_finishes( &mut self, network: &mut PeerNetwork, diff --git a/stackslib/src/net/neighbors/mod.rs b/stackslib/src/net/neighbors/mod.rs index 2a49bad96f2..2347a48419b 100644 --- a/stackslib/src/net/neighbors/mod.rs +++ b/stackslib/src/net/neighbors/mod.rs @@ -392,8 +392,11 @@ impl PeerNetwork { /// Update the state of our peer graph walk. /// If we complete a walk, give back a walk result. /// Mask errors by restarting the graph walk. - /// Returns the walk result, and a true/false flag to indicate whether or not the work for the - /// walk was finished (i.e. we either completed the walk, or we reset the walk) + /// Returns a tuple `(done, walk_result_opt)`: + /// * `done` — `true` if the work for the walk was finished (i.e. we either completed the walk, + /// or we reset the walk), `false` if there is more progress still to make. + /// * `walk_result_opt` — `Some(result)` if the walk ran to completion this call, `None` + /// otherwise. pub fn walk_peer_graph(&mut self, ibd: bool) -> (bool, Option) { if !self.setup_walk(ibd) { // nothing to do diff --git a/stackslib/src/net/relay.rs b/stackslib/src/net/relay.rs index 9ba52461138..913f0e3d7da 100644 --- a/stackslib/src/net/relay.rs +++ b/stackslib/src/net/relay.rs @@ -778,7 +778,10 @@ impl Relayer { /// Insert a staging block that got relayed to us somehow -- e.g. uploaded via http, downloaded /// by us, or pushed via p2p. - /// Return Ok(true) if we stored it, Ok(false) if we didn't + /// Returns `Ok(BlockAcceptResponse::Accepted)` if the block was newly stored, + /// `Ok(BlockAcceptResponse::AlreadyStored)` if we already had it, + /// `Ok(BlockAcceptResponse::Rejected(reason))` if it was rejected, and + /// `Err(..)` on DB or chainstate errors. pub fn process_new_anchored_block( sort_ic: &SortitionDBConn, chainstate: &mut StacksChainState, @@ -851,7 +854,7 @@ impl Relayer { } } - /// Wrapper around inner_process_new_nakamoto_block + /// Wrapper around `process_new_nakamoto_block_ext` that pins `force_broadcast` to `false`. pub fn process_new_nakamoto_block( burnchain: &Burnchain, sortdb: &SortitionDB, @@ -877,10 +880,12 @@ impl Relayer { /// Insert a staging Nakamoto block that got relayed to us somehow -- e.g. uploaded via http, /// downloaded by us, or pushed via p2p. - /// Return Ok(true) if we should broadcast the block. If force_broadcast is true, then this - /// function will return Ok(true) even if we already have the block. - /// Return Ok(false) if we should not broadcast it (e.g. we already have it, it was invalid, - /// etc.) + /// Returns `Ok(BlockAcceptResponse::Accepted)` if the block was newly stored (or if + /// `force_broadcast` is true and we already have it). + /// Returns `Ok(BlockAcceptResponse::AlreadyStored)` if we already have the block (and + /// `force_broadcast` is false), or if `accept_block` returned `false`. + /// Returns `Ok(BlockAcceptResponse::Rejected(reason))` if the block was rejected + /// (fault-injected, problematic AST, etc.). /// Return Err(..) in the following cases, beyond DB errors: /// * If the block is from a tenure we don't recognize /// * If we're not in the Nakamoto epoch @@ -1761,8 +1766,8 @@ impl Relayer { /// Verify that a relayed transaction is not problematic. This is a static check -- we only /// look at the tx contents. /// - /// Return true if the check passes -- i.e. it's not problematic - /// Return false if the check fails -- i.e. it is problematic + /// Return `Ok(())` if the check passes -- i.e. it's not problematic + /// Return `Err(..)` if the check fails -- i.e. it is problematic pub fn static_check_problematic_relayed_tx( mainnet: bool, epoch_id: StacksEpochId, @@ -2640,8 +2645,10 @@ impl Relayer { #[cfg_attr(test, mutants::skip)] /// Relay Nakamoto blocks. - /// By default, only sends them if we don't have them yet. - /// This can be overridden by setting `force_send` to true. + /// Each block is skipped if it was already relayed within + /// `connection_opts.nakamoto_push_interval_ms` (tracked via + /// `self.recently_sent_nakamoto_blocks`), or if its tenure is not in the + /// last `connection_opts.max_nakamoto_block_relay_age` sortitions. pub fn relay_epoch3_blocks( &mut self, _local_peer: &LocalPeer, diff --git a/stackslib/src/net/stackerdb/db.rs b/stackslib/src/net/stackerdb/db.rs index da5129da371..50f20fc6267 100644 --- a/stackslib/src/net/stackerdb/db.rs +++ b/stackslib/src/net/stackerdb/db.rs @@ -395,8 +395,15 @@ impl StackerDBTx<'_> { Ok(()) } - /// Add or replace a chunk for a given reward cycle, if it is valid - /// Otherwise, this errors out with Error::StaleChunk + /// Add or replace a chunk for a given reward cycle, if it is valid. + /// Otherwise, returns one of: + /// * `net_error::StackerDBChunkTooBig` if `chunk` exceeds the configured maximum size, + /// * `net_error::NoSuchSlot` if the slot does not exist for this DB, + /// * `net_error::BadSlotSigner` if `slot_desc`'s signature does not verify under the slot's + /// configured signer, + /// * `net_error::StaleChunk` if `slot_desc.slot_version` is not strictly greater than the + /// stored slot's version, or + /// * `net_error::TooManySlotWrites` if `slot_desc.slot_version` exceeds `config.max_writes`. pub fn try_replace_chunk( &self, smart_contract: &QualifiedContractIdentifier, diff --git a/stackslib/src/net/stackerdb/sync.rs b/stackslib/src/net/stackerdb/sync.rs index e7a5bb9571c..0923beb440a 100644 --- a/stackslib/src/net/stackerdb/sync.rs +++ b/stackslib/src/net/stackerdb/sync.rs @@ -298,9 +298,11 @@ impl StackerDBSync { /// Given the downloaded set of chunk inventories, identify: /// * which chunks we need to fetch, because they're newer than ours. - /// * what order to fetch chunks in, in rarest-first order - /// Returns a list of (chunk requests, list of neighbors that can service them), which is - /// ordered from rarest chunk to most-common chunk. + /// * what order to fetch chunks in. + /// Returns a list of (chunk requests, list of neighbors that can service them), currently + /// ordered from most-common chunk (highest neighbor count) to rarest. NOTE: this is opposite + /// to the inline comment's stated intent and to `make_chunk_push_schedule` — see the + /// `schedule.reverse()` call below. May represent a stale doc or an intentional inversion. pub fn make_chunk_request_schedule( &self, network: &PeerNetwork,