Skip to content

bug(zk): Shielded unshield rejected as "Tx too large" when spending many notes #3411

@lklimek

Description

@lklimek

Summary

Unshielding the full shielded balance fails with "Tx too large" when the balance is spread across many small notes from prior shield operations. The Type 17 UnshieldCredits state transition bundles all input notes (each with an Orchard spend proof), exceeding Platform's transaction size limit.

Reproduction

  1. Shield credits in multiple small operations (e.g., 10× 0.1 DASH)
  2. Attempt to unshield the full accumulated balance (~1 DASH) to a platform address
  3. Platform rejects:
NoAvailableAddressesToRetry(Grpc(Status {
    code: Internal,
    message: "Tx too large",
    metadata: { "drive-error-data-bin": "...", "code": "-32001" }
}))

Expected Behavior

Either:

  • The SDK builder enforces the size limit pre-broadcast and returns a structured error with guidance (e.g., "Too many input notes — try a smaller amount")
  • The SDK automatically splits large unshields into multiple smaller transitions
  • The size limit is documented so client apps can pre-validate

Root Cause

The select_notes_for_amount function greedily selects all notes needed to cover the amount. When many small notes exist, the resulting state transition includes one Orchard spend proof per note, pushing the serialized size past the gRPC/Platform limit.

Questions

  1. What is the exact size limit for state transitions?
  2. Is there a maximum number of Orchard spends per transition?
  3. Should the limit be enforced in the DPP builder (with a typed error) rather than failing at the gRPC transport layer?

Related

🤖 Co-authored by Claudius the Magnificent AI Agent

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions