Block limit exceeded (1010) when deploying contracts with many circuits

A developer in #dev-chat is hitting “1010: Transaction would exhaust the block limits” when deploying a contract with many circuits on undeployed.

What’s happening:

The node computes transaction cost across 5 dimensions (readTime, computeTime, blockUsage, bytesWritten, bytesChurned), normalizes each against the block limits, then maps the maximum to a Substrate weight. If the weight exceeds the block capacity, Substrate rejects with InvalidTransaction::ExhaustsResources (error 1010).

Source path: pallets/midnight/src/lib.rs:590 (get_tx_weight) → ledger/…/mod.rs:582
(get_transaction_cost) → cost.normalize(limits) in base-crypto/src/cost_model.rs:261 → Substrate frame_executive weight check.

Questions for the Compact team:

  1. Is there a recommended way to split a contract with many circuits into multiple smaller deployments?
  2. Are the current bytesWritten limits expected to increase, or are they intentionally tight?
  3. Is there tooling or a Compact-level diagnostic that can estimate transaction size before deployment, so devs can catch this earlier than the 1010 at submission time?
  4. Any guidance on what “many circuits” realistically means in terms of hitting these limits? (e.g., rough circuit count or contract complexity thresholds)
2 Likes

1. Splitting a large contract into multiple smaller deployments

The recommended pattern is to decompose the contract into multiple Compact source files, each deployed independently. Circuits that share state pass the contract address around as a reference. A coordinator contract can hold the addresses of sibling contracts in its ledger as Bytes<32> values and route calls between them. This gives you one logical dApp backed by several on-chain contracts, each small enough to fit within the bytesWritten limit.

2. Whether bytesWritten limits will increase

The block limits are intentionally conservative for the current network phase. They are expected to increase as the network matures and throughput is validated at scale. Following the upstream node release notes and the midnight-docs support matrix is the best way to track when limits change.

3. Pre-deployment size estimation

There is no first-class compact CLI flag today that prints the estimated transaction weight before deployment. The closest approach is to watch the output directory after compilation: the .zkir and .wasm artifacts give you a rough sense of circuit size. A practical workaround is to deploy against a local devnet (via the testkit Docker Compose) where rejection is free and fast, and iterate there before submitting to preprod or mainnet.

4. Rough circuit count threshold

There is no published number. Based on community reports, the limit tends to surface on contracts with 10 or more non-trivial circuits, or contracts whose compiled bytecode exceeds roughly 500 KB. Splitting at 5–7 circuits per contract appears to be a safe heuristic for now.

2 Likes