Skip to content

Include contract and function names in VK-size mismatch errors #25107

Description

@Kubudak90

What happens

Registering a contract in PXE fails with:

verification key has wrong size: expected 5216, got 4576

Two byte counts, and nothing else. No contract, no function, and no hint that the artifact is what's wrong rather than the contract source.

Still the case on v5.1.0, the latest release at the time of writing (line references below are pinned to that tag).

Why it can't be fixed where it's thrown

The throw is in barretenberg, bbapi_shared.hpp#L41-L48:

template <typename VK> inline void validate_vk_size(const std::vector<uint8_t>& vk_bytes)
{
    const size_t expected_size = VK::calc_num_data_types() * sizeof(bb::fr);
    if (vk_bytes.size() != expected_size) {
        throw_or_abort("verification key has wrong size: expected " + std::to_string(expected_size) + ", got " +
                       std::to_string(vk_bytes.size()));
    }
}

(duplicated at chonk/chonk_step_processor.cpp.)

That function only receives bytes, so it genuinely cannot name a contract — this is not a bb bug.

Worth noting you already appear to be moving this way: master (post-v5.1.0) adds a labelled sibling, has_expected_vk_size, which does print an identifier. But its labels are bb-level operations ("ChonkVerify", "ChonkVerifyFromFields", "ChonkBatchVerify") — bb has no way to know an application-level name, and the unlabelled validate_vk_size is still the path that fires for contract registration.

Where the names do exist

The artifact-conversion layer already has the missing context — contract_artifact.ts#L237:

...(fn.verification_key ? { verificationKey: fn.verification_key } : undefined),

Both contract.name and fn.name are in scope there. The same file already formats exactly the identifier that would help, at #L192:

const pathToFind = `${contract.name}::${fn.name}_abi`;

and already gives a stale-artifact error with a remedy, at #L175:

`No custom attributes found for contract function ${fn.name}. Try rebuilding the contract with the latest nargo …`

The convention, the context and the tone all exist in this file. The VK-size case just doesn't get the same treatment.

Proposed change

Either validate the VK while converting the named artifact, or preserve the contract/function context around the downstream validation, so the resulting error includes:

  • the contract name
  • the function name
  • the original expected/actual byte counts
  • a suggestion to rebuild artifacts with the current toolchain

So instead of two bare numbers:

LiquidityPool::deposit — verification key has wrong size (expected 5216, got 4576).
This artifact may be stale or compiled with an incompatible toolchain version; rebuild it with the current toolchain.

The contract and function name alone do most of the work, because they reframe the problem from "something is wrong with my contract" to "this artifact is stale".

What it cost us

We run a DEX on testnet (5.0.0, Nargo deps pinned to tag v5.0.0). During our 4.3.1 → 5.0.0 migration the v5 toolchain produced 5216-byte private-function keys, while two of our five committed artifacts still carried 4576-byte ones.

Those artifacts were already tracked in git; a local nargo compile modified them and the modification was never committed. So the developer's working tree was correct while every build from a clean checkout remained broken. Because the other three contracts were fine, it looked like a per-contract logic problem rather than a build-hygiene issue. Our deployed testnet stack was unavailable for 13 days.

The diagnosis, once we thought to look, was mechanical: base64-decode functions[].verification_key and compare byte lengths against git show HEAD:<path>. But nothing in the error pointed at build outputs, so that is not where we looked.

Environment

  • Hit on aztec / @aztec/* 5.0.0, Nargo deps at tag v5.0.0; contracts compiled via the aztecprotocol/aztec:5.0.0 Docker image
  • Re-checked against v5.1.0 before filing — the throw site and the TS conversion are both unchanged there
  • Reproduced at PXE contract registration in both an aggregator daemon and a faucet service
  • Affected: 3 private functions across 2 contracts, all 4576 bytes where 5216 was expected

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