Skip to content

pallet-revive: expensive reverse lookup needed since ReviveApi.call requires SS58 origin but contracts use H160 msg.sender #11597

@BigTava

Description

@BigTava

Problem

When performing a read-only dry-run via ReviveApi.call, the origin parameter must be an SS58 account address. Inside the contract, msg.sender resolves to the corresponding H160 (EVM) address. This means that to read data stored under a specific user's msg.sender, the caller must first reverse-lookup the H160 → SS58 mapping via Revive.OriginalAccount storage.

This is a significant bottleneck for apps that need to enumerate data across many contracts.

Concrete example

The DotNS Store contract stores values per-user:

mapping(address user => string[] userValues) private values;

function getValues() external view returns (string[] memory) {
    return values[msg.sender]; // keyed by caller's H160
}

A StoreFactory deploys one Store per user. To enumerate all values across all stores, an app must:

  1. Call StoreFactory.getAllDeployedStores() → 363 store addresses
  2. For each store, call Store.owner() → get the owner's H160
  3. For each H160, query Revive.OriginalAccount → get the SS58 address
  4. Call Store.getValues() with the SS58 as origin, so msg.sender matches

Step 3 is the bottleneck: 363 individual substrate storage queries, each requiring a state proof through the light client.

Steps 1, 2, and 4 can all be batched via Multicall3 (a single ReviveApi.call per batch). Step 3 cannot — it's a pallet storage query, not a contract call.

Possible solutions

  1. Accept H160 directly as origin in ReviveApi.call — if the caller passes a 20-byte address, skip the SS58→H160 mapping and use it as msg.sender directly. This would eliminate the reverse lookup entirely for read-only dry-runs.

  2. Provide a batch/multi-key query for Revive.OriginalAccount — allow querying multiple H160→SS58 mappings in a single RPC call (e.g. state_queryStorageAt with multiple keys, or a dedicated runtime API).

  3. Add a ReviveApi.call_as(h160, contract, data) variant — explicit API for "call this contract as if msg.sender were this H160 address", for dry-run/simulation purposes only.

  4. Expose OriginalAccount as a contract-callable precompile — so the reverse lookup can be batched through Multicall3 alongside other contract calls.

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