This repository was archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Fix the broken Weight Multiplier #6328
Copy link
Copy link
Closed
Labels
I3-bugThe node fails to follow expected behavior.The node fails to follow expected behavior.U2-some_time_soonIssue is worth doing soon.Issue is worth doing soon.
Description
The current weight multiplier implementation is unfortunately wrong. From the research page we have:
ctraffic ← ctraffic ⋅ ( 1 + v(s−ss) + v^2 (s−ss)^2 / 2).
Assuming:
t1 = v(s−ss)
t2 = v^2 (s−ss)^2 / 2
This is in short:
next = prev + prev.mul(t1 + t2)
While our implementation does:
substrate/bin/node/runtime/src/impls.rs
Lines 82 to 96 in 606c56d
| if positive { | |
| // Note: this is merely bounded by how big the multiplier and the inner value can go, | |
| // not by any economical reasoning. | |
| let excess = first_term.saturating_add(second_term); | |
| multiplier.saturating_add(excess) | |
| } else { | |
| // Defensive-only: first_term > second_term. Safe subtraction. | |
| let negative = first_term.saturating_sub(second_term); | |
| multiplier.saturating_sub(negative) | |
| // despite the fact that apply_to saturates weight (final fee cannot go below 0) | |
| // it is crucially important to stop here and don't further reduce the weight fee | |
| // multiplier. While at -1, it means that the network is so un-congested that all | |
| // transactions have no weight fee. We stop here and only increase if the network | |
| // became more busy. | |
| .max(Multiplier::saturating_from_integer(-1)) |
Which in short is
next = prev + (t1 + t2)
Then the gist of the fix will be:
if positive {
// Note: this is merely bounded by how big the previous and the inner value can go,
// not by any economical reasoning.
+ let excess = first_term.saturating_add(second_term).saturating_mul(previous);
- let excess = first_term.saturating_add(second_term);
previous.saturating_add(excess)
} else {
// Defensive-only: first_term > second_term. Safe subtraction.
+ let negative = first_term.saturating_sub(second_term).saturating_mul(previous);
- let negative = first_term.saturating_sub(second_term);
previous.saturating_sub(negative)
// despite the fact that apply_to saturates weight (final fee cannot go below 0)
// it is crucially important to stop here and don't further reduce the weight fee
// previous. While at -1, it means that the network is so un-congested that all
// transactions have no weight fee. We stop here and only increase if the network
// became more busy.
.max(Multiplier::saturating_from_integer(-1))
}And fixing a number of tests. I already started with this and there's a problem: Given the default parameters here, if we let multiplier go down to 0, then it will never recover, and it is unclear how to do this.
- Moreover, the research says that the ratio should be computed only from the
normaltransaction types, with respect to the normal limit. We don't do this now and this needs fixing as well. - When applying the multiplier, we apply this
+1(multiply_accumulate) jumbo mumbo that is quite unnecessary in my opinion given the fix.
Metadata
Metadata
Assignees
Labels
I3-bugThe node fails to follow expected behavior.The node fails to follow expected behavior.U2-some_time_soonIssue is worth doing soon.Issue is worth doing soon.