Cannot deserialize the contract state.: Custom { kind: InvalidData, error: "Not all bytes read"

Viewed 43

We have a smart contract that stores NFTs. There are already NFTs minted. There are view functions, namely nft_tokens, nft_supply_for_owner, nft_tokens_for_owner, get_next_buyable, get_root.

I also wanted to add a function that is able to give back data on a single NFT, I gave it the name nft_token_details. I had a few version of this function, non of them worked, I always owerwrote the contract state with the new WASM.

Here is one version of nft_token_details:

/// Query for NFT tokens on the contract regardless of the owner using pagination
pub fn nft_token_details(&self, token_id: TokenId) -> Vec<JsonToken> {
let keys = self.token_metadata_by_id.keys_as_vector();

keys.iter()
    .skip(0)
    .take(10000000)
    .filter(|id| *id == token_id)
    .map(|id| self.nft_token(id.clone()).unwrap())
    .collect()        
}

I also had version when the return type was different, but it was never a #[payable] function.

After I deployed these new versions of the contract, the old view functions does not work any more, I can't read the state of the contract.

How to fix this? How can I go back to a previous state?

I even tried going back to a previous git commit, built it and deployed it, but it didn't help.

This is the error I'm getting:

Querying [object Object] failed: wasm execution failed with error: FunctionCallError(HostError(GuestPanic { panic_msg: "panicked at 'Cannot deserialize the contract state.: Custom { kind: InvalidData, error: \"Not all bytes read\" }', /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0-pre.4/src/environment/env.rs:576:46" })).
{
  "block_hash": "DF3dChMGfUdwvYPUkFoFdiNrdRgfeyjpkAmubPq49mKm",
  "block_height": 73485017,
  "error": "wasm execution failed with error: FunctionCallError(HostError(GuestPanic { panic_msg: \"panicked at 'Cannot deserialize the contract state.: Custom { kind: InvalidData, error: \\\"Not all bytes read\\\" }', /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0-pre.4/src/environment/env.rs:576:46\" }))",
  "logs": []
}

Here is a failed transaction: https://nearblocks.io/txns/59obVeqb6skvFQU6L5Nu6ack1aMqXPxA2dyAc375sydF#

1 Answers

The problem was that I deleted a field in a much previous commit, deployed it to a new contract, it worked, and when I upgraded the old contract with a new feature, I thought that the error is not in the new feature, but that the data structure of the contract is different.

Why I also updated the new contract with the new feature, but the unused field was added back, I got very similar error:

...
 "FunctionCallError": {
        "ExecutionError": "Smart contract panicked: panicked at 'Cannot deserialize the contract state.: Custom { kind: InvalidInput, error: \"Unexpected length of input\" }', /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0-pre.4/src/environment/env.rs:576:46"
      }
...

These is basically the same error, but instead an (unused) field is missing, now an (unused) field is there.

Even an unused field can not be deleted from the Contract struct. That was the mistake I made.

Related