-
Notifications
You must be signed in to change notification settings - Fork 2.6k
pallet-contracts: Migrate to weights mechanism #4147
Conversation
# Conflicts: # bin/node/runtime/src/lib.rs
# Conflicts: # bin/node/runtime/src/lib.rs
# Conflicts: # bin/node/runtime/src/lib.rs # frame/contracts/src/gas.rs # frame/contracts/src/lib.rs # frame/contracts/src/tests.rs # frame/contracts/src/wasm/code_cache.rs
3dae604
to
dc85fa5
Compare
# Conflicts: # bin/node/executor/src/lib.rs # bin/node/runtime/src/lib.rs # frame/contracts/src/gas.rs # frame/contracts/src/lib.rs # frame/contracts/src/wasm/code_cache.rs
@kianenigma yeah, as you say it yourself, it turns out It seems to me that we have to know the upper bound of the call at hand before execution. Otherwise, there is no way to fulfil |
# Conflicts: # bin/node/executor/src/lib.rs
Weight are surely from day 0 defined to be the upper bound. At the moment we don't have good estimates but this is an empirical issue from the substrate core, not your side. You can still assume
For calls that do use How about banning certain calls, or providing a different, more complicated ways to call them? for example if you want to call sudo from your contract, you need to put some deposit down etc. What we can do at substrate level to help a bit with this is to add a |
For posterity, we moved this discussion to the other channels. We should do a write up after we come to a conclusion though. My current thinking is that we won't be able to fix it in this PR. |
Besides that, extract it to a separate module.
# Conflicts: # bin/node/runtime/src/lib.rs # frame/contracts/src/gas.rs # frame/contracts/src/lib.rs # frame/contracts/src/tests.rs
// | ||
<GasPrice<T>>::put(gas_price); | ||
|
||
let imbalance = match T::Currency::withdraw( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You call this from SignedExtension::validate
and SignedExtension::pre_dispatch
? Aren't you charging the who
double by doing this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whatever we do in validate()
is not persistent. The state is dropped thereafter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But changes in pre_dispatch
are persisted, right?
maybe re-opened at a later time. |
To clarify: this, of course, doesn't imply that we drop this feature. We close it for clearing the PR queue. In future, we can re-open this PR or perhaps open another one. |
I am currently working on this by building on the currently merged weight refund mechanism and the unmerged weight rework (#5446). I will start a new PR for this when it is ready for review. |
This PR changes srml-contracts to tap on the weight system instead of relying on a separate gas mechanism.
In this change we treat 1 gas unit as 1 weight unit. I wasn't sure about getting rid of the notion of gas althogether since we might want to scale it relative to weight later on and because gas is familiar lingo for the existing smart-contract developers. Apart from that, it would also introduce some backward compatibility fall out.
This change also makes an assumption that the weight to price is a linear function.
The transition is not complete though, because there are basically two problems.
Dynamic Weights
It is not yet clear how to implement
ext_dispatch_call
, a contract-to-runtime call, within the weights system. The problem here is thatext_dispatch_call(T::Call)
has no information regarding how much weight the givenT::Call
would consume and thus there is no way to ensure that executing this call won't be out of given gas/weight limit budget. Related issues were filled and partially implemented (#3730, #3921), but it is still not enough. We will work this out with @kianenigma.Block weight limit
The current values for the weight budget are a bit off. To understand the issue let's take a simple example where a contract transfers some funds to another account. The situation right now is that the fees for transfers are charged with gas, trying to emulate the behavior of the balances module. The transfer fee in balances module is defined in terms of balance units. We use approximation of the gas cost (we can do that since we know the price of one unit of gas in terms of balance units) for the fees and charge that. At the moment of writing, the fee is set to 1 "cent".
The problem is that with current values set in node-runtime the whole weight limit costs 1 cent, so it is not possible to perform even one transfer.
There are different cures to that to name a few:
I opted-in to the last one, since merging of #4590 will allow us to basically use
T::Currency::transfer
directly without involving any emulation!