style: tighten comments and apply nightly rustfmt

Condense the explanatory comments on the new account-accounting check and the
dropped_account test guest, and fix imprecise wording (the account is dropped
from both pre_state and post_states together, not just pre_state). Also
applies cargo +nightly fmt's wrapping of the new error message.
This commit is contained in:
Marvin Jones 2026-07-15 15:20:04 -04:00
parent fb84915935
commit 09af47b862
3 changed files with 6 additions and 12 deletions

View File

@ -132,7 +132,9 @@ pub enum InvalidProgramBehaviorError {
#[error("Called program {program_id:?} which is not listed in dependencies")]
UndeclaredProgramDependency { program_id: ProgramId },
#[error("Account {account_id} was declared in the transaction but is missing from the program output")]
#[error(
"Account {account_id} was declared in the transaction but is missing from the program output"
)]
DeclaredAccountMissingFromOutput { account_id: AccountId },
}

View File

@ -294,11 +294,7 @@ impl ValidatedStateDiff {
}
// Every account the caller declared as part of the transaction must appear in the final
// diff. A well-behaved program's output always echoes back every account it was handed
// (unchanged if it only reads it) — this catches a program (or a macro-generated
// dispatcher wrapping one) that silently drops an account from its own output instead.
// Chained calls may still introduce accounts beyond this original list; this only checks
// the reverse direction.
// diff.
for account_id in &message.account_ids {
ensure!(
state_diff.contains_key(account_id),

View File

@ -5,12 +5,8 @@ type Instruction = ();
/// Silently drops the second account entirely from its own output: given two `pre_states`, it
/// returns only one `(pre, post)` pair, echoing the first account back unchanged.
///
/// Unlike `missing_output` (whose own `pre_states.len() != post_states.len()`, tripping
/// `validate_execution`'s internal length check directly), this program's own output is
/// internally consistent — one `pre_state` and one matching `post_state` — it just reports fewer
/// accounts than it was handed. This mirrors a well-behaved-looking dispatcher that filters an
/// account out of both sides of its output together (e.g. a stale-signer-nonce workaround that's
/// too broad), rather than an obviously malformed program.
/// Differs from `missing_output` because the `pre_state` and `post_states` lengths match. We
/// simply drop the account from both before returning them as part of the program's output.
fn main() {
let (
ProgramInput {