#State Expiration Semantics: Reads of non-existing Exclusive entries

40 messages · Page 1 of 1 (latest)

high basin
#

How do reads of non-existent Exclusive / Unique entries work? Can a contract know for certain that an Exclusive / Unique entry doesn't exist? Or do contracts need to employ their own tombstones for that purpose?

Will this function exist?

env.storage().exclusive().has(key)

Will has returning false, or get failing to find a value for a key, indicate that the Exclusive entry doesn't exist anywhere, or do contracts need to navigate the possibility that failure to read might mean it is defined somewhere else?

tribal crest
#

I think we can have has operation and contracts could do just use it naturally

#

the contract doesn't need to worry about whether unique entry has been archived or not; that's beyond the contract's scope. the only requirement is that if a contract tries to create an exclusive entry, the proof of exclusion has to be provided

#

(which also happens outside of contract scope)

high basin
#

Could you explain further? With an exclusive storage type, consistency is guaranteed to the contract. But it sounds like has is inconsistent, unless every read also requires the client to provide a proof of presence or absence in the Evicted Store when the ledger doesn't have the key.

tribal crest
#

hmm, what sort of logic can be based on the entry not present in the storage?

high basin
#

e.g. a developer might make an assumption that has is consistent, and allow certain logic to take place if a key is absent, and if that logic does not involve creating the key, then logic would be allowed that is inconsistent with the state of the overall system.

tribal crest
#

I think that's true now for any entry basically

high basin
#

Not for temporary entries.

tribal crest
#

if has is false, then entry is not in the ledger, for whatever reason

#

and the logic has to take this into account

high basin
#

Today has returning false tells you the entry is no where. Not that it is potentially evicted.

tribal crest
#

the semantics will change, I suppose

#

the same goes for get

high basin
#

Just looking at the primitives, I think it's really important we are ultra-clear about what the consistency guarantees of each function is.

tribal crest
#

it just gets the entry from ledger, if any

high basin
#

It sounds like Exclusive is consistent if the entry exists in the ledger, and inconsistent otherwise.

tribal crest
#

I'm not sure what do you mean by 'consistency' here

#

has/get consistently get entry from ledger

#

exclusive is not about consistency, it's only about the guarantee that the entry can be created just once

#

(which is important to prevent someone from re-initializing your contract or resetting your auto-increment nonce etc)

high basin
#

Got it. Thanks for helping me understand how it works. This will be relatively surprising if someone comes at exclusive storage thinking it works like storage today, or storage on any other blockchain, so we just need to be really clear about the consistency guarantees and these behaviors in the docs we produce for folks. This behavior isn't clear from the documentation I've read so far, it seems implied.

tribal crest
#

yeah, the whole expiration thing is kind of confusing

#

maybe the right way to think about it is that when entry expires, it's just deleted from ledger

high basin
#

Expiration is straight forward. It's the non-existence test that has no proof that is confusing / surprising.

tribal crest
#

but then some entries can be recovered

#

well, the right mindset is to think about expiration as about deletion

high basin
#

It's not deletion though, an external party can bring it back.

tribal crest
#

sure, the contract doesn't manage that, but I think the contract logic doesn't need to distinguish between these

#

basically if entry is deleted it might have not existed in the first place

high basin
#

That's an assumption. A contract developer needs to know they can't distinguish between them, or they might!

tribal crest
#

yeah, which is why I'm proposing to look at this as if entry has been deleted or even didn't exist in the first place

#

the only meaningful piece of logic is using exclusive/mergeable storage to make sure certain invariants hold

high basin
#

To confirm I understand correctly: all reads (.has(key), .get(key)) of exclusive/unique storage when a key doesn't exist on the ledger can tell you is that it doesn't exist on the ledger. The only way to find out for sure if it doesn't exist anywhere and can't be restored, is to create the entry with a tombstone of sorts.

tribal crest
#

yeah, I'm not sure what would be the point of having any different behavior

#

get clearly needs the value and the value probably should come from the ledger

#

having has diverge from get doesn't make much sense

#

I don't think there is any meaningful logic you can build on the fact that entry used to exist; host takes care of that when relevant

tribal crest
#

just to summarize some offline discussions, we'll probably go with proofs for all the unique storage fns (including has/get), so that it's possible to write meaningful logic contingent on these items not existing (so my previous responses can be ignored)

high basin
#

So we'll be able to say that all operations on Exclusive/Unique storage are strongly consistent 🎉