Skip to content

v1 covenant transaction rejected on testnet-10: "script units exceeded" even with computeBudget set #1073

Description

@jeffsiegel1965

Environment

  • Network: kaspatest testnet-10 (rpc api-tn10.kaspa.org)
  • Tooling: Python SDK kaspa 2.0.1 (PyPI) + Rust kaspa-wasm 0.13.0
  • Date: July 2026

What I'm trying to do

Deploy a simple timelock covenant on testnet-10:

  1. Spend a v0 P2PK UTXO (40.928 KAS, Schnorr-signed)
  2. Create a version-1 transaction with computeBudget = 65535 on the input
  3. Output[0]: 1,000,000 sompi → P2SH-wrapped redeem script containing OP_CHECKLOCKTIMEVERIFY + Schnorr pubkey check, with CovenantBinding attached and covenant_id = blake2b(outpoint || authorized_outputs)
  4. Output[1]: fee; output[2]: change
  5. Sign with BIP-340 Schnorr via sign_transaction()
  6. Broadcast via /transactions

The JSON we send includes "computeBudget": 65535 on each input, version: 1, sigOpCount: 1, Schnorr signature script.

What happens

The node consistently rejects with:

RPC Server (remote error) -> Rejected transaction <txid>:
failed to verify the signature script: script units exceeded the amount committed
in the input: used=100000, limit=9999

The value 9999 matches the free-script-unit allowance on the underlying v0 UTXO. The 100,000 figure is roughly the cost of verifying one Schnorr signature. The computeBudget = 65535 that I set on the v1 input is completely ignored.

What I've tried

# Change Result
1 Default compute_budget rejected — same error
2 Smaller outputs (5 KAS total) rejected
3 Split funds into many small UTXOs rejected
4 Manually inject computeBudget: 200000 into the signed JSON rejected
5 Monkey-patch Transaction.to_dict() in the Python SDK to serialize compute_budget rejected — same error
6 sig_op_count = 0 on input (v1 covenant convention) rejected

The transaction signs successfully and produces a valid txid locally; the problem is at consensus validation.

Questions

  1. Field semantics: Is computeBudget the wrong field for raising the signature-verification limit? The error message says "the amount committed in the input" — that phrasing suggests the budget is derived from the UTXO itself (committed at spend time), not from the transaction that spends it. If so, what is the correct field to raise it?

  2. v0 → v1 bootstrap: Can a v1 covenant transaction actually spend a v0 UTXO? Or does the protocol require that covenant transactions only spend UTXOs that were themselves created by v1 (covenant-aware) transactions? If a bootstrap path exists, I'd love to see it.

  3. Signing scheme: Schnorr verification costs ~100K script units. If the input-side budget truly cannot exceed the v0 UTXO's 9999, does that mean covenant-input signature verification needs a cheaper scheme (ECDSA, or something else), or is the budget supposed to be raised via a different mechanism entirely?

  4. Reference deployment: Has anyone successfully deployed any covenant on testnet-10 (or mainnet)? A single known-good txid would let me diff the structure byte-for-byte against what I'm sending.

What I've verified locally

  • Covenant-id hash (blake2b(outpoint ‖ authorized_outputs)) matches the Rust SDK's own test vector.
  • Transaction signs; local txid computation matches node-side rejection txid.
  • Wallet side (getUtxosByAddresses, sendTransaction) is fine — the same wallet can send normal v0 payments without issue.

Repo references I checked

  • wip/covenants — no working example found
  • Consensus code under consensus/core/src/tx/ — I haven't been able to pinpoint where the 9999 limit is read without more time tracing through the script-unit accounting.

Happy to provide the signed tx hex / full JSON if that helps. Thanks for any pointer.


Posting recipe (for when user has 2 min)

# 1) install gh if not present (Ubuntu/Debian):
#    sudo mkdir -p -m 755 /etc/apt/keyrings
#    wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg \
#      | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null
#    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] \
#      https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list
#    sudo apt update && sudo apt install gh -y

# 2) auth
gh auth login   # paste token, choose HTTPS, default everything

# 3) post
cd /home/jeff-siegel/.hermes/projects/kaspa-suite
gh issue create \
  --repo kaspanet/rusty-kaspa \
  --title "v1 covenant transaction rejected on testnet-10: \"script units exceeded\" even with computeBudget set" \
  --label question \

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions