-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
consensus: Expose ephemerality of elements in Apply/RevertUpdate #174
Conversation
Since it seems like |
I wondered about that. You do need it when constructing v2 transaction chains, but since we already have the |
Ok, tried that. The results are pretty good, but there are a few places where the caller definitely needs to know whether an element is ephemeral or not. Namely, when deciding which elements to call |
I pushed a workaround to SiaFoundation/coreutils#65, lmk what you think |
var ephemeralLeafIndex = consensus.UnassignedStateElement(types.Hash256{}).LeafIndex Hmm.. That's kind of nasty.. I'd probably lean towards making |
Another option: just ban ephemeral outputs :P I think it's probably best to mostly return to the status quo, with an exported const in |
This adds a
created bool
argument to the(Update).ForEach
methods, allowing callers to identify ephemeral elements by checking forcreated && spent
(or, in the case of file contracts,created && resolved
.This is very useful for any callers who care about persistently tracking unspent outputs. Normally, the code for doing so looks like this:
but this is subtly buggy: if the element was ephemeral,
spent
will be true, so we'll try to delete it; but since it's ephemeral, it's not in the set, so there's nothing to delete! Whether or not this causes problems depends on howdeleteUTXO
is implemented. Specifically, if you assert that an element must exist in order to be deleted, that assert will fail.To avoid this, we need a way to detect whether an element is ephemeral.
chain.DBStore
attempted to do this by checkingsce.LeafIndex == types.EphemeralLeafIndex
. However, this doesn't work: ephemeral elements are assigned leaf indices just like regular outputs, so that condition is never satisfied! This eventually lead to a panic: ephemeral outputs within a reverted block would be added to the UTXO set (instead of being ignored), and if a future block references that same output, the DB gets confused and crashes.Adding a
created
flag seemed like the most direct of doing this. Another option would be to always skip the ephemeral elements in theForEach
methods, and add a new method (or methods) for accessing only the ephemeral elements. This is attractive, since it doesn't break any existing code, and most callers want to skip ephemeral elements anyway. Ultimately, though, I decided against it; it pollutes the namespace, and it's one more thing you "just need to know" in order to use the API properly. Plus it makes the name "ForEach" a lie. Better to keep everything in one place.