-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Proposal: Allow Dynamic Weights #3730
Comments
Any chain use tx fee as a security mechanism and have dispatch methods that are not |
Yeah -- now the approach is that if a particular transaction can cost more, it should handle it manually somehow.
Yeah indeed, this is exactly how the smart contract was discussed to work with the proposal of this issue. |
We have been talking quite a lot with @pepyakin off-band about this and the gist of it, at least from my PoV is: PrimitivesWhy do we have weights?: The main purpose is to prevent a block from being filled too much with transactions. weights should embody all limited resources in a block. It is easy, yet accurate, to think of it just in terms of
What does the weight system now represent?: Just execution time. For now, transactions that could potentially write to state are (to be best of our knowledge) safeguarded manually by charging more money or taking bonds or some other manual inspection form within the function definition itself. Moreover, the current system has one very important condition: weights must be known pre-dispatch from outside the runtime. This makes sense. The client (tx queue in particular) wants to know how much time it is going to spend on a transaction before starting to execute it. For this reason, the best-effort approach is to make any static weight annotation, a pure representation of the worse case scenario, if possible. I will use the term New discussion.The core fo the discussion is rooted in the fact that a typical smart contract call is consisted of
What the contract module is doing now is
Now, I never expect all runtime calls to be so restricted. We rant a lot in docs that a runtime dev should be responsible and prevent such mistakes and attack vectors. It would merely be nice to give them more flexibility for doing so, but we won't hard-code such approaches. In this sense, and so far, I don't really see substrate needing to make any effort regarding helping contracts module. But there is one problem that the current smart-contract module is causing. smart-contracts module, as of now, can not, and does not, properly update the global, per-block, accumulated weight, which is being examined by the tx-queue (indirectly) in the above example. This, as mentioned, can be a major problem as blocks could become big in terms of resource, while no one knows why. we both agree that the use cases of smart-contracts, while being unique to itself, is not the only one and even in the current substrate node runtime we are overlooking similar scenarios. Sudo, some dispatches that take a Now, @pepyakin can go on and solve everything by an ugly hack of making this accumulated weight in system public, and manually updating it. But, as mentioned, since some other modules (not to mention future modules) share the same, I see it worthwhile to create some primitives to help such scenarios. Best thing to do, that I think all modules can benefit from is to enable a general way for post-dispatch weight update. There will be a special type of weights that imply: it is still static, it should still be a worse case approximation, but you can update it after you your dispatch is done. As mentioned, this is not a holy grail to solve any attackable dispatch. That's merely the responsibility of the developer. This just makes it easier to deal with such stuff. Ideally, we can even emit this information to the transaction queue so that it can make decisions based on knowing:
(cc @tomusdrw) So that 1- queue would now the risk ahead of executing something which is
(In the rest of our discussion, we got into some more details that I will summarise here later.) |
I won't close this for now, but an update that it partially happened by adding |
Yes, this is closed. |
Regards to this conversation about weights and this part of it:
I was thinking maybe, maybe, we can allow this with a special type of weight (e.g.
#[weight = Dynamic(Foo)]
) which is allowed to be updated after the call has been dispatched. The requirement comes from what I have been discussing with @pepyakin recently about how he can use the weight system for his contract module and at least for his situation: a dispatch's operations can be separated into two parts:noop
contract.I was thinking we could make it a pattern of passing some data from the
Ok(())
of the.dispatch()
and then pass it intopost_dispatch
to make updates current block weight, charge more/less fee etc..post_dispatch
would automatically callFoo::update_weight()
with some parameterT
returned from.dispatch()
.I am not sure yet if this is general enough to be considered in substrate, or if we want to stick to the current simple approach of weight must be calculated before the dispatch, so this is to discuss this before any prototyping takes place.
The text was updated successfully, but these errors were encountered: