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
claim_reward_balance_operation has no extension field #1859
Comments
Actually we have another option:
This option is the "cleanest" IMHO. If a user wants to claim more than one reward, they may simply include multiple instances of the operation in a transaction. Re-purposing the existing operation gives 90% of the benefit for 10% of the work, and we don't have two different operations around, one of which we then have to worry about how to deprecate. So my preferences are (2), (3), (1) in that order. |
The merits of this operation depends on how many tokens we expect a user to claim, on average. I will define option (1) a bit more precisely. It has an extensions field and accepts a vector of tokens to claim. Option (1), claiming a single token consumes a 16 byte account name, a 4 byte vector length, a 12 byte asset, and a 4 byte extension vector length. Option (2), claiming a single token consumes a 16 byte account name, and 3x12 byte assets. Option (3), claiming a single token consumes 16 bytes of an account name, a 12 byte asset, and a 4 byte extension vector length. We can see the growth of overhead of these options as we increase the number of assets claimed.
Option (1) wins at scale. Option (2) is better only when we are claiming 3 assets. Option (3) is better only when claiming one asset. However, because SBD and SP are guaranteed assets, it looses already. I think option (1) is the best choice. |
I am leaning heavily towards efficiency. Creating and maintaining a new operation is not ideal, but I also think (1) is the best choice. |
So what's different about this operation that we don't apply the same logic to, say, the
we instead have
In fact there's nothing special about Why don't we do that? What's special about this operation that we only "vectorize" this operation, and don't vectorize any other operation? Option (3) has a clear answer to this question: Nothing's special about this operation, so for consistency with our other operations, we won't vectorize it. Option (2) also has a clear answer: Vectorizing with a fixed length of 3 elements allows the new semantics to be backward compatible with the existing Option (1) doesn't really have a clear answer. Also, there's a related issue. How long does it take an operation to execute? For most ops, it is [1] Amortized in some cases, for example a market order that consumes multiple orders from the books could force arbitrarily many database lookups, but we could consider "accounting" the database lookups for the consumed orders as being "charged" to the transaction that created them, not the transaction that consumes them. |
TLDR, I agree option (1) is more efficient on the wire, and that's an important consideration. But it subtly changes / breaks the blockchain's ontology [1], which makes me reflexively want to reject it -- I might be willing to accept it, but we should at least think carefully about it for a while. [1] What is the meaning of an operation? How do you perform iteration? These are fundamental design decisions about how the "Steem VM" is designed. Maybe the decisions that were made when Steem was created aren't optimal, but they're what we have to work with. I'm concerned that throwing out the existing answers to those questions and making up different answers on a case-by-case basis is going to result in a Frankenstein hodgepodge of weird exceptions and special cases, so we have to explain to developers "well usually you do things THIS way, but for THIS operation you do things THAT way." |
The difference is probabilistic. How many transfers would we expect to occur in the dynamic length transfer op? If the value is 2, then I would be all in favor of creating a batch transfer operation that supports one to many transfers. (If it is not one to many then you cannot amortize the savings from repeated account names in the I cannot say that with absolute certainty that I paid close enough attention to reward balances as I should have when implementing them. However, we likely would not have gone with option (1) because SMTs were not being considered at the time. After having done this analysis I wish that we would have done something similar on other operations during design. |
I agree with basing the decision on probabilistic efficiency, and the first paragraph of the above post by @mvandeberg definitely puts words to my feelings on the matter. Another thing that strikes me is that the existing |
We will go with option (1), creating a new operation with an extensions field, and a vector of tokens. |
claim_reward_balance
will have to carry balances in multiple tokens, but there is no way to extend it as it is defined since it doesn't have an extensions field.Possibilities I see:
Both are messy in their own way. 1) is probably the more "correct" way, but it's going to be more work. 2) limits us to only 3 assets, and seems very unclean to me.
I am leaning towards 1), but are there other possibilities I am missing?
The text was updated successfully, but these errors were encountered: