polkadot-js / api

Promise and RxJS APIs around Polkadot and Substrate based chains via RPC calls. It is dynamically generated based on what the Substrate runtime provides in terms of metadata.
Apache License 2.0
1.07k stars 350 forks source link

Unable to create Enum via index 128, in Alive, Tombstone #4151

Closed forgetso closed 2 years ago

forgetso commented 2 years ago

Steps to reproduce

  1. Deploy a contract with a salt
  2. Retrieve the contract deployedAddress
  3. Use contractInfoOf

const contractInfo = await this.api.query.contracts.contractInfoOf(deployedAddress);

2021-11-02 15:06:07 RPC-CORE: getStorage(key: StorageKey, at?: BlockHash): StorageData:: Unable to decode storage contracts.contractInfoOf:: createType(ContractInfo):: Unable to create Enum via index 128, in Alive, Tombstone Error: Unable to decode storage contracts.contractInfoOf:: createType(ContractInfo):: Unable to create Enum via index 128, in Alive, Tombstone at RpcCore._newType (/home/user/dev/project/provider/node_modules/@polkadot/rpc-core/bundle.cjs:455:13) at RpcCore._formatStorageData (/home/user/dev/project/provider/node_modules/@polkadot/rpc-core/bundle.cjs:403:17) at RpcCore._formatOutput (/home/user/dev/project/provider/node_modules/@polkadot/rpc-core/bundle.cjs:380:19) at RpcCore._formatResult (/home/user/dev/project/provider/node_modules/@polkadot/rpc-core/bundle.cjs:238:27) at callWithRegistry (/home/user/dev/project/provider/node_modules/@polkadot/rpc-core/bundle.cjs:259:19)

Using versions:

    "@polkadot/api": "^6.6.1",
    "@polkadot/api-contract": "^6.6.1",
    "@polkadot/types": "^6.6.1",
    "@polkadot/util": "^7.7.1"

This error has also been encountered in ink waterfall tests: https://gitlab.parity.io/parity/ink-waterfall/-/jobs/1189814

I'm running the substrate contracts node, which tracks master. I most recently compiled this today (https://github.com/paritytech/substrate#b391b829).

jacogr commented 2 years ago

Ummm… has there been changes to -

Before it started breaking?

forgetso commented 2 years ago

I'm afraid I don't know when this was last working as I have only just started using contractInfoOf in my code. I see the same error in the polkadot apps UI in the contracts section however.

From the console on contract page after having instantiated a contract using command line.

Error: Unable to decode storage contracts.contractInfoOf: entry 0:: createType(ContractInfo):: Unable to create Enum via index 128, in Alive, Tombstone
    at Ji._newType (polkadot.01.68fdc50b.js:1)
    at Ji._formatStorageSetEntry (polkadot.01.68fdc50b.js:1)
    at polkadot.01.68fdc50b.js:1
    at Array.reduce (<anonymous>)
    at Ji._formatStorageSet (polkadot.01.68fdc50b.js:1)
    at Ji._formatOutput (polkadot.01.68fdc50b.js:1)
    at Ji._formatResult (polkadot.01.68fdc50b.js:1)
    at Object.d [as callback] (polkadot.01.68fdc50b.js:1)
    at W.value (polkadot.01.68fdc50b.js:1)
    at WebSocket.value (polkadot.01.68fdc50b.js:1)

One thing I noticed was the definitions for AliveContractInfo are differently named in substrate compared to polkadotjs

polkadot-js

    AliveContractInfo: {
      trieId: 'TrieId',
      storageSize: 'u32',
      pairCount: 'u32',
      codeHash: 'CodeHash',
      rentAllowance: 'Balance',
      rentPaid: 'Balance',
      deductBlock: 'BlockNumber',
      lastWrite: 'Option<BlockNumber>',
      _reserved: 'Option<Null>'
    },

Substrate - many more underscored variables

    #[derive(Decode)]
    struct RawAliveContractInfo<CodeHash, Balance, BlockNumber> {
        trie_id: TrieId,
        _storage_size: u32,
        _pair_count: u32,
        code_hash: CodeHash,
        _rent_allowance: Balance,
        _rent_paid: Balance,
        _deduct_block: BlockNumber,
        _last_write: Option<BlockNumber>,
        _reserved: Option<()>,
    }

I have also seen it mentioned that Tombstones are no longer a thing due to changes in the way rent works.

jacogr commented 2 years ago

Any reason why nose contracts are not on metadata v14. Trying to keep up with the contracts dev but a a nightmare.

We have stopped adding types since v14 was added (since it defies all) I hate to go back and add more for recent contract changes.

Where it is an issue even with v14 is when it comes via RPC (ie. Not storage) - that is still hanging.

forgetso commented 2 years ago

I'm not sure I follow. The contracts were compiled using cargo +nightly contract build --release and the latest version of ink 3.0.0-rc6 and rustc 1.57.0-nightly. How would I know if the contracts were using metadata v14 or not?

I know you're referring to metadata versions in node_modules/@polkadot/types/metadata/ but I don't know how they relate to my contract wasm and abi.

forgetso commented 2 years ago

I see I have V1 specified in my .contract file. Should this be set to V14?

{
  "source": {
    "hash": "0x0954598fe5597774d05212f8e78d09234fe481da6ee3e4c0e8cb0a0ced4c9346",
    "language": "ink! 3.0.0-rc6",
    "compiler": "rustc 1.57.0-nightly",
    "wasm": "0x00..."
  },
  "contract": {
    "name": "prosopo",
    "version": "3.0.0-rc6",
  },
  "V1": {  <---------------------------- here
forgetso commented 2 years ago

Having looked into it, I see that this key is something to do with ink versioning their metadata as either V0 or V1.

https://github.com/paritytech/ink/blob/ee42309d830b1b4b4f3874c2f53c3f5d6ae9b47f/crates/metadata/src/lib.rs#L68

pub enum MetadataVersioned {
    /// Version 0 placeholder. Represents the original non-versioned metadata format.
    V0(MetadataVersionDeprecated),
    /// Version 1 of the contract metadata.
    V1(InkProject),
}
jacogr commented 2 years ago

There are 2 metadata areas that come into play -

  1. The ABI, indeed, as above that is using the latest version
  2. The runtime - for <= v13 runtimes, types needed to be manually kept in sync in the API, with >= v14 these types (like ContractInfo) is actually exposed by the metadata from the runtime, i.e. the API definitions doesn't come into play, hence it not being maintained anymore after the v14 went into Substrate

If it is a metadata v14 node, the api-contracts module does something funky where it doesn't use a specific type from metadata (but rather the old-style-huge-PITA-to-sync types). Which would be a bug.

forgetso commented 2 years ago

Thanks @jacogr. The node is the substrate contracts node.

How do I tell if its <=13 or >=14? jsonrpc-core = "18.0.0" in the .toml?

https://github.com/paritytech/substrate-contracts-node/blob/acbf103f4305e8eb685aa8589704436b7fc327f4/node/Cargo.toml#L43

jacogr commented 2 years ago

Still v13, the merge was reverted - https://github.com/paritytech/substrate-contracts-node/pull/8

If a crisis, would accept PRs to update the types.

(As suggested it is not something I can dedicate time to myself since it is not needed anymore in Substrate, so luckily all those hours that were needed to keep in sync is now available for other efforts)

forgetso commented 2 years ago

Really appreciate the info. I checked out the repo before it was reverted (8d91b8e) and built it locally. This has allowed me to successfully use contractsInfoOf in polkadot-js both in code and in the contracts page. More importantly, it means I can keep developing my contract! Thanks.

polkadot-js-bot commented 2 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue if you think you have a related problem or query.