-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Disputes which are unknown for the Runtime are sent with priority by the Provisioner when preparing inherent data #5336
Disputes which are unknown for the Runtime are sent with priority by the Provisioner when preparing inherent data #5336
Conversation
ff2efae
to
92515d6
Compare
92515d6
to
c1f587e
Compare
node/core/provisioner/src/lib.rs
Outdated
@@ -712,7 +714,20 @@ async fn select_disputes( | |||
// In case of an overload condition, we limit ourselves to active disputes, and fill up to the | |||
// upper bound of disputes to pass to wasm `fn create_inherent_data`. | |||
// If the active ones are already exceeding the bounds, randomly select a subset. | |||
let recent = request_disputes(sender, RequestType::Recent).await; | |||
let mut recent = request_disputes(sender, RequestType::Recent).await; |
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.
Doesn't the dispute coordinator subsystem also scrape onchain votes? I imagine we can move this there and then we could have a RequestType::RecentOffChain
(not sure if this is the best naming) request type that we can use here.
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.
If I'm not mistaken what's scraped in the disputes-coordinator are the resolved disputes while here we are fetching the ongoing disputes so one way or another - we'll have to make the runtime API call.
In which module to do it - you have a point. It can also be done in the disputes-coordinator but for me it felt more natural to keep this logic in the provisioner because the inherent data is prepared there. I don't insist on this approach though. Keeping it in the disputes-coordinator is very reasonable too.
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.
The on chain votes are the votes that are imported in that very block, not the overall disputes. Put another way, the votes the provisioner provides can later be found in the on chain votes of the created block. This is a backup mechanism, in case a validator misses disputes off-chain, it will still know about current disputes via those onchain vote scraping.
e4f4e0f
to
dccb17e
Compare
What's happening here? Seems stagnant for a week? |
I'm finishing the tests today and this will be ready for review. |
e487906
to
4826cdb
Compare
49b2049
to
6d41b0a
Compare
3571e8e
to
a435768
Compare
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.
In summary, I don't think that #4573 is resolved by this PR. In particular we don't take into account votes the chain knows about disputes at all. Also we still don't seem to care whether the dispute already concluded on chain. (Votes for such disputes can be imported with lower priority.)
With #4573, I don't think that we need random selection of votes/disputes at all anymore:
- We limit to only information the chain does not know about
- If that is still too much (by some metric), we just truncate the data. There is no need for random selection, as the remaining data will get imported on the next blocks, as the next block producers will again only include data the chain does not know about.
I agree, this is actually half of the work and I forgot to remove 'Closes $4573' from the description. I edited it now. About the rest, especially the votes - what I understood was that I should focus on the votes in separate PR. Is this correct or I should extend the PR to address the votes too? P.S. After rereading the PR description I realise that I don't mention anywhere that the votes should be handled separately. My bad. |
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.
nice work, @tdimitrov ! It certainly is an improvement a full #4573 can be a follow up.
Co-authored-by: Andrei Sandu <54316454+sandreim@users.noreply.github.com>
Co-authored-by: Andronik <write@reusable.software>
Co-authored-by: Bernhard Schuster <bernhard@ahoi.io>
- Logging - Separate error module - Add additional fields for GetOnchainDisputesErr - logging and impl MallocSizeOf - fix impl MallocSizeOf for DisputeState - fix tests
Co-authored-by: Andronik <write@reusable.software>
Co-authored-by: Andronik <write@reusable.software>
Co-authored-by: Andronik <write@reusable.software>
dummy metrics instance Co-authored-by: Bernhard Schuster <bernhard@ahoi.io>
bot merge |
Waiting for commit status. |
This PR adds logic which improves the efficiency of the on-chain disputes importing in provisioner subsystem. First step for resolving #4573
Motivation
When the provisioner prepares inherent data (on message
RequestInherentData
) it requests all disputes the current node knows about from the disputes-coordinator (viaDisputeCoordinatorMessage::RecentDisputes
message). These disputes are sent to the Runtime no matter if they are already on-chain or not. Furthermore if the disputes count is too large - it is trimmed by randomly dropping disputes. This approach works but is not effective.What's changed in the PR
Before preparing the disputes list the provisioner fetches all on-chain disputes by issuing a staging API call to the Runtime -RuntimeApiRequest::Disputes
. Then the provisioner filters out the result fromDisputeCoordinatorMessage::RecentDisputes
by removing the disputes already imported on-chain. The rest of the logic remains the same.The description above is not correct. A dispute occurring and concluding within the time a single block is created is a quite happy case. So it is not acceptable to import a dispute once and consider it done, because the node might receive new votes for ongoing disputes and they will never be sent on chain.
For this reason the PR implements the following logic:
Case 1: All RECENT disputes can be sent to the Runtime
Provisioner
gets all RECENT disputes. They are sent to the runtime.Case 2: RECENT disputes are too much (more than
MAX_DISPUTES_FORWARDED_TO_RUNTIME
). ACTIVE disputes fit in the limit.Provisioner
queries the Runtime about the disputes it knows about (withRuntimeApiRequest::Disputes
).MAX_DISPUTES_FORWARDED_TO_RUNTIME
limit. Disputes unknown to the Runtime are added with priority during the extension.Case 3: Both RECENT and ACTIVE disputes are more than
MAX_DISPUTES_FORWARDED_TO_RUNTIME
limit.Provisioner
queries the Runtime about the disputes it knows about (withRuntimeApiRequest::Disputes
).Provisioner
adds creates a set of ACTIVE disputes with sizeMAX_DISPUTES_FORWARDED_TO_RUNTIME
. Disputes unknown to the Runtime are added with priority in this set.Benefits
Feature flag
Due to the usage of a staging API call the whole functionality is put behind a feature flag -
staging-client
. All features using staging Runtime calls will be behind this feature flag.