I've run into an issue where having a nested NEAR collection (in this case TreeMap) can give this error:
The collection is an inconsistent state. Did previous smart contract execution terminate unexpectedly?
The struct I'm using looks like this:
pub struct CollectionIssues {
nested_treemap: TreeMap<AccountId, TreeMap<u128, String>>,
}
Then we:
AccountId
)I've provided a demonstration repository here:
https://github.com/mikedotexe/near-collections-issue
To reproduce, clone and run ./test.sh
The issue is how TreeMap
is created. When initializing a collection, you need to specify the unique prefix. By default it uses global auto-increment. When the collection is saved to the state, it's prefix is also saved to the state, but global auto-increment counter is not persisted. So when you reinsert a new map, it uses auto-increment prefix value that is not unique and collides with the existing collection.
The best way to avoid it is to give a unique prefix for every TreeMap
created using TreeMap::new(unique_prefix)
. The unique prefix in your case can be env::sha256(account_id)
for the key in the first collection.
Example of this is in FungibleToken implementation: https://github.com/near/near-sdk-rs/blob/ac8c849fba6b912a5ef46d156662b3e1f6b56894/examples/fungible-token/src/lib.rs#L43
Notice how the allowances map is initialized there for a given account.