Skip to content

feat: implemented multiple signer count#751

Open
muhahahmad68 wants to merge 1 commit intodotandev:mainfrom
muhahahmad68:feat/signer-count
Open

feat: implemented multiple signer count#751
muhahahmad68 wants to merge 1 commit intodotandev:mainfrom
muhahahmad68:feat/signer-count

Conversation

@muhahahmad68
Copy link
Contributor

Summary

Fixes #586 . When a contract deployment requires multiple signers, the simulate endpoint now mocks the presence of those signatures so the Soroban host charges realistic ed25519 verification budget and produces an accurate gas estimate.

Without this change, a dry-run on an unsigned or partially-signed multisig transaction shows the host zero signature verification work, systematically underestimating the fee. The on-chain transaction is then submitted with an insufficient fee and fails.


Root Cause

At dry-run time the DecoratedSignature list in the transaction envelope is empty or partially filled — the transaction has not yet been fully signed by all required parties. The Soroban host meters ed25519 verification cost per signature present in the envelope, so an empty list means zero metered cost and an underestimated budget.


Changes

internal/cmd/dry_run.go

  • extractSignerCountFromEnvelope — auto-detects the right signer count in priority order: (1) use existing DecoratedSignatures if present, (2) count InvokeHostFunction operations as a proxy, (3) fall back to 1
  • --mock-signers flag — explicit override when the caller knows the exact auth policy (e.g. --mock-signers 3 for a 3-of-5 multisig)
  • Passes MockSigners through to SimulationRequest
  • Prints Mock signers used for gas estimation: N in the output so the estimate is auditable
  • RPC preflight path is unchanged — the Soroban node handles signature mocking internally

Auto-Detection Logic

For the common case where --mock-signers is not supplied:

  1. Envelope already has signatures → use that count (partial signing in progress)
  2. No signatures, has InvokeHostFunction ops → use op count (each invoke needs ≥1 signer)
  3. Fallback → 1 (minimum for any transaction)

Callers with a known multisig policy should always pass --mock-signers explicitly for a precise estimate.


Testing

# Rust unit tests
cargo test -p simulator inject_mock_signers

# Full simulator test suite
cargo test -p simulator

# Go
go test ./internal/cmd/... -run TestDryRun -v
go test ./internal/simulator/... -v

Type of Change

  • New feature
  • Bug fix
  • Breaking change
  • Documentation update

Checklist

  • Rust types and Go schema kept in sync (matching JSON field names)
  • Zero-value mock signatures cannot be mistaken for real signatures by the host
  • Envelope padding stops at XDR VecM cap (20) without panicking
  • Existing envelopes with sufficient signatures are left unchanged
  • RPC preflight path unaffected
  • Auto-detection is a safe lower bound; --mock-signers overrides when needed
  • Tests added — 2 Rust unit tests, schema compile-tested
  • Backward compatible — mock_signers is Option<u32> / omitempty; existing callers that don't send the field get the old behaviour

@dotandev
Copy link
Owner

fix the newest conflicts, please.

@dotandev
Copy link
Owner

dotandev commented Mar 4, 2026

fix these conflicts, when you can, please.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement dry-run mode for multi-sig deployments

2 participants