Make HRMP advancement rule more restrictive#9086
Make HRMP advancement rule more restrictive#9086serban300 merged 6 commits intoparitytech:masterfrom
Conversation
077f83f to
69609db
Compare
|
/cmd prdoc --bump patch |
5a51d66 to
eeb9161
Compare
77f14a0 to
0ca86b6
Compare
0ca86b6 to
408a035
Compare
| min_size | ||
| ); | ||
| }, | ||
| None => { |
There was a problem hiding this comment.
If this is None, it means there are no hashed messages and we left the function already.
There was a problem hiding this comment.
I don't know if I understand. This should mean that no size constraints were provided in which case we should apply the most basic constraint. Which is the case now for DMP. There might be hashed messages.
There was a problem hiding this comment.
The if in line 203. We can never end up here, because the if should resolve to true if the hashed messages are empty, which also means that the message_info is not set.
Maybe the entire function should only be called when we have message_size_info.
There was a problem hiding this comment.
Done, but for DMP we need the logic in the None branch. So I split this in 2 functions.
| size = size.saturating_add(msg.data().len()); | ||
| } | ||
|
|
||
| // Let's take a margin of safety. |
There was a problem hiding this comment.
I can remove it, but I think it's safer to have it. It can save us from a parachain stall in very ugly corner cases while it doesn't impact the min size very much normally. I don't know.
For example if there have been some miscalculations in other places and we end up with a message that is off by a couple of bytes for example. Off by 1 errors are very common in my experience (there was one in this PR as well :D ).
| let first_hashed_msg_channel = hashed_messages | ||
| .first() | ||
| .map(|(sender, _msg)| *sender) | ||
| .map(|sender| Self::get_ingress_channel_or_panic(ingress_channels, sender)); |
There was a problem hiding this comment.
We should take the maximum from all the max_message_size. Otherwise you may take 100bytes while some other channel has a max size of 1MIB.
There was a problem hiding this comment.
Yes, but I think only the max size of the first hashed message should be important. For example:
Let's say that we are connected to parachains:
- 1000 -> max_message_size = 1
- 2000 -> max_message_size = 50
And:
- XCMP full messages total size limit = 100
full_messages: [{len: 50, sender: 2000}, {len: 1, sender: 1000}] => total length = 51
If we have:
hashed_messages: [{sender: 2000}, ...]
It's ok, because in the worst case scenario we had a maximal message from parachain 2000 and this would have exceeded the max full messages limit: 51 + 50 = 101 > 100
If we have:
hashed_messages: [{sender: 1000}, ...]
We should panic because the first message could have been added as a full message: 51 + 1 = 52 < 100 . Regardless of the fact that sender 2000 has a max size of 50.
Am I missing something ?
There was a problem hiding this comment.
I see where my confusion is coming from. I assumed we took messages from the hrmp messages until we hit the maximum. But this is not correct, as we directly stop when one message doesn't fit anymore. Maybe another improvement 🙈
There was a problem hiding this comment.
Yes, would be nice. We can consider doing this in the future. But I think it would require changing the MQC head logic ? which wouldn't be trivial
There was a problem hiding this comment.
We would need to keep the order per parachain. That is fine. But we should be able to skip parachain A and continue with B etc.
| min_size | ||
| ); | ||
| }, | ||
| None => { |
There was a problem hiding this comment.
The if in line 203. We can never end up here, because the if should resolve to true if the hashed messages are empty, which also means that the message_info is not set.
Maybe the entire function should only be called when we have message_size_info.
| let first_hashed_msg_channel = hashed_messages | ||
| .first() | ||
| .map(|(sender, _msg)| *sender) | ||
| .map(|sender| Self::get_ingress_channel_or_panic(ingress_channels, sender)); |
There was a problem hiding this comment.
I see where my confusion is coming from. I assumed we took messages from the hrmp messages until we hit the maximum. But this is not correct, as we directly stop when one message doesn't fit anymore. Maybe another improvement 🙈
| assert!( | ||
| full_messages_size > min_full_messages_size, |
There was a problem hiding this comment.
Just doing full_message_size + first_hashed_msg_max_size > max_full_messages_size should be easier? Then we don't need to do leave any extra room or whatever?
There was a problem hiding this comment.
We would still have no margin of safety in the worst case scenario. Anyway, normally it's more correct like this. Done.
| ingress_channels | ||
| .get(channel_idx) | ||
| .map(|(_, channel)| channel) | ||
| .expect("Channel index was just calculated and is correct; qed") |
There was a problem hiding this comment.
You can probably use some and, map or then functions on the option to directly check both in the if above.
Two possible pancis for the same thing is a bit odd.
ggwpez
left a comment
There was a problem hiding this comment.
Okay so you make the HRMP rule greedy now? So that it forces the collator to include all possible messages and not just one? good
|
|
||
| // Here we just check that there is at least 1 full message. | ||
| assert!( | ||
| self.full_messages.len() >= 1, |
There was a problem hiding this comment.
So the case that already the first message is too big can never happen, right?
There was a problem hiding this comment.
Very good point !
With the current Polkadot and Kusama configs it won't happen. But with a misconfiguration it probably could. Anyway this check is only used for DMP and the problem there is that we don't know the max message size in order to do a proper check. This will be fixed when we migrate DMP to check_enough_messages_included_advanced as well. But in order to do this we need to also forward the max dmp message size to the parachain in the metadata. It would be great if we could do that in a separate PR and merge this one as it is. WDYT ?
There was a problem hiding this comment.
So the case that already the first message is too big can never happen, right?
If this would happen, we could never move forward. I see this not as an issue. Yes, could be a misconfiguration, but then you can not receive messages anymore.
e30ff0d
Related to: #9021
Followup for #8860
Looked some more into this and from what I understand the HRMP max message size can't be changed dynamically. In order to change it we would need to close the channel and than open it again which would lead to clearing all the pending messages. So it's safe to use the current hrmp max message size in the advancement rule check.