paritytech / paritytech/contract-dependency-manager

ContractRegistry.publishLatest traps for most @org scopes on the products devnet

Open
#87 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
4
Forks
3
Avg merge
4d 13h
Merged PRs (30d)
3

Description

publishLatest returns Revive.ContractTrapped for most @org scopes and succeeds for a few, deterministically. Because cdm deploy batches deploy and register into one Utility.batch_all, this surfaces as a bare Revive.ContractTrapped on an otherwise valid contract, with nothing pointing at the registry.

Environment

Network Products devnet (Paseo Asset Hub, para 1000)
Asset Hub genesis 0xd6eec26135305a8ad257a20d003357284c8aa03d0bdb2b357ab0a22371e11ef2
Substrate RPC wss://asset-hub-paseo-rpc.n.dwellir.com
ETH RPC https://paseo-assethub-rpc.laissez-faire.trade
Registry 0x59b0245778917af55224e5f8fb55f7f8d452619f

Reproduce

Dry-run publishLatest(string,address,string) against the registry from any EOA that exists on chain. No transaction, no fees, about a second per name:

import { keccak256, toHex, encodeAbiParameters, parseAbiParameters } from "viem";

const REGISTRY = "0x59b0245778917af55224e5f8fb55f7f8d452619f";
const RPC = "https://paseo-assethub-rpc.laissez-faire.trade";
const FROM = "<any EOA that exists on chain — see the gotcha below>";
const ANY_ADDRESS = "0x0000000000000000000000000000000000000001";

const data = keccak256(toHex("publishLatest(string,address,string)")).slice(0, 10) +
  encodeAbiParameters(parseAbiParameters("string,address,string"),
    [name, ANY_ADDRESS, ""]).slice(2);

await fetch(RPC, { method: "POST", headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ id: 1, jsonrpc: "2.0", method: "eth_call",
    params: [{ to: REGISTRY, from: FROM, data }, "latest"] }) });

Results, stable across repeated calls:

@org scope result
@zz, @zzz, @mylinkdot publishes
@aa, @ab, @b, @q1, @test, @example, @linkdot ContractTrapped

What it is not

  • Not name length. Swept @zz/x through @zz/xxxxxxxxxxxxxxxxxx (5–22 chars): all publish.
  • Not new vs. existing. @zz/probe1 is unregistered and publishes; other unregistered names under trapping scopes fail. An already-owned name publishes, and a name owned by a different account correctly returns Unauthorized rather than trapping.
  • Not the package half. @linkdot/profiles, @linkdot/xxxx and @linkdot/p all trap; only the scope varies the outcome.
  • Not validate_contract_name. It is pure, returns NameError, and every failing name above is well-formed by it.
  • Not the deploying contract. ReviveApi.instantiate with the same code blob and origin returns success: true with a computed address. Only the registry half of the batch fails.

Lead: the deployed registry looks older than main

getCode(), getAdmin() and isFrozen() all revert on the deployed registry, though all three exist in src/contract/src/main.rs today. So the deployed implementation appears to predate current source, and this may already be fixed but undeployed — probably worth checking before digging into contract logic.

This could not be taken further from outside, with no source for the deployed bytecode.

Gotcha for anyone reproducing

Dry-running with a from address that has no on-chain account returns a spurious OK for names that actually trap. Use an EOA that exists on chain; one can be derived with ReviveApi.address(ss58).

Impact

cdm deploy fails with Revive.ContractTrapped on a correct contract and no way to attribute it. The natural response is to suspect the contract: a storage layout rewrite, a major-version bump of pvm-contract-sdk, and a constructor change all preceded finding the registry.

Two things would help independently of the root cause:

  1. Split deploy and register, or report which half of the batch_all failed.
  2. Return a typed error from publishLatest instead of trapping.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the deployed registry behavior and compare it with src/contract/src/main.rs, then trace cdm deploy through the Utility.batch_all path. Reproduce the failure with an on-chain EOA using the provided eth_call and inspect ReviveApi.instantiate separately. Done means the failing registry or batch step is attributed and a focused fix and regression test target is established.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, typescript
Domain
api, blockchain, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.