Reduce the inclusion inherent's actual weight if the block is already heavy#2060
Reduce the inclusion inherent's actual weight if the block is already heavy#2060
Conversation
|
So the problem I find in the outlined description is that you still don't know what extrinsics will be included. The proposer doesn't take all extrinsics from the pool. Also there is no way to tell what extrinsics will be proposed, at least not until the proposer does it job. Instead, there is a long line of extrinsics waiting to be included in the block and then the proposer adds one by one keeping an eye on the cumulative consumed weight. After it reaches a certain threshold it tries to shove some more extrinsics. So all in all this boils down to the first approach. There are two observations that may expand possibly ways to explore on how to tackle this:
As a side note, this can be also performed on the runtime side, btw. In fact, there is already this (a relevant comment) |
We can not know the weight of
How should the node know what each extrinsic is doing? If you have some important operational extrinsic, you could just schedule it, so that it is executed before the inherents in the next block. However opertional extrinsics also have more weight budget. As already said in Riot, I don't see this as anything that should be handled from the runtime. Apply the inherent and the inclusion logic will skip the data in the inherent if we already used too much weight. |
Do you mean that we should alter |
Isn't the
I was thinking about special casing this in the node, if needed.
Could you point to that discussion? |
Exactly.
Ahh yeah, good point. |
Ohh yeah you are right, somehow I thought this wasn't the case. 🤦
Special casing it in which way? Call into the runtime and get back the weights? Extrinsics are anyway negligible, because the inclusion inherent is in 99% of the cases more important. |
If we want to prevent this, we could just simply add a runtime api that returns the current and max weight and let you decide on this. While this still doesn't give you the weight that the inherent will consume. |
Perhaps, or just straight hardcoding in the node. But yeah, I agree that this perhaps is not required. |
|
Hardcode what? Sorry, I can not follow ^^ |
The waste is if we exclude the InclusionInherent due to a heuristic, when it actually would have fit, isn't it ? As far as I can see what we want ultimately is to have this inherent prioritised with other extrinsics in the transaction pool. This inherent would be of class normal or operational and priority high, thus in case of runtime upgrade and when block is full then it won't be included. But I don't know how difficult it is. So yes if we execute this inherent before all other non-inherent extrinsics then we can update check if there is enough weight available, and maybe update the used weight of the block. But then this extrinsic has more priority than operational signed/unsigned extrinsics. But considering this is probably what we want most of the time and that Operationals have some reserved weight amount (weight amount available only for operationals extrinsics), then I think it is fine. |
He means waste of block space. Because the inherent would still be part of the block extrinsics. However, the size of this probably not that much. |
|
I'm confused now, what if we just make the call If we do I'm very not familiar about how the client organize the inherent extrinsics. It doesn't use the |
|
So, if it's operational, then the weight stuff gets much easier, because the normal provisioner takes care of including it or not as space is available; we don't need to mess with it here. However, if it's not included, then we need to get appropriate defaults when we read it. ... I can't think of a reason that isn't a good idea. I'm going to try implementing it. |
This resolves a lot of the trickiness about this issue, because we no longer need to override or supplant any existing proposer logic; the existing logic should exhibit these behaviors: - the `inclusion` inherent is prioritized over standard transactions - but if it's too heavy, i.e. in case of runtime upgrade, it'll be dropped in favor of that. It is my belief that allowing the proposer to just not include this data won't have any adverse effects: it's equivalent to replacing them with empty versions of themselves, which the `ProvideInherent` impl already does.
inclusion inherent call Operational, not Mandatory
This makes some assumptions about fundamental weights, which are encapsulated as constants. From there, it lets Substrate know what the actual computed weight of the inherent is.
Co-authored-by: Guillaume Thiolliere <[email protected]>
622f267 to
8aa71bd
Compare
|
Processing availability bitfields is probably heavier than you give it credit for. It's possibly even heavier than processing backing. But we can tweak ratios later on. |
|
Needs unit tests and to be tested in practice as well. |
|
More tests on the way; I just haven't yet figured out all the details of how to implement tests that the inherent weight changes, or not, according to the block weight before execution. |
|
@bkchr Have added tests; please let me know if you would like more. |
dd38294 to
bb6a038
Compare
drahnr
left a comment
There was a problem hiding this comment.
The changes are in line with the previous comments 👍
Closes #1555.
This should give us these behaviors:
inclusioninherent is prioritized over standard transactionsIt is my belief that allowing the proposer to just not include
this data won't have any adverse effects: it's equivalent to replacing
them with empty versions of themselves, which the
ProvideInherentimpl already does.