-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Conversation
It's not clear precisely why this is desired, but it's a pattern I've seen in several places, so I'm going this to be on the safe side. Worst case, we can revert this commit pretty easily.
We have from the problem description: > This Proposer will require an OverseerHandle to make requests via. That's next on the plate.
|
||
When a validator is selected by BABE to author a block, it becomes a block producer. The provisioner is the subsystem best suited to choosing which specific backed candidates and availability bitfields should be assembled into the block. To engage this functionality, a `ProvisionerMessage::RequestInherentData` is sent; the response is a set of non-conflicting candidates and the appropriate bitfields. Non-conflicting generally means that there are never two distinct parachain candidates included for the same parachain. | ||
|
||
One might ask: given `ProvisionerMessage::RequestInherentData`, what's the point of `ProvisionerMessage::RequestBlockAuthorshipData`? The answer is that the block authorship data includes more information than is present in the inherent data; disputes, for example. |
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.
Wouldn't any consumer of RequestInherentData
be interested in disputes as well?
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 practice our main consumer is the block authorship logic, which is clearly interested in disputes so it can report them to the chain. I am not aware of any other component which would be interested in disputes or dispute-related reports.
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 proposer consumes RequestInherentData
, and if it cares about disputes, I haven't yet seen why it does.
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.
Yeah, on further inspection we probably don't need the proposer to be aware of disputes. I was thinking about a more antiquated approach where the Proposer
constructs the dispute transactions and submits them to the block directly.
It seems that the "right way" to submit reports (based on @andresilva's work in GRANDPA/BABE) is to call a runtime API that submits a transaction to the queue. I guess that will end up being the main role of the MA subsystem - acting as an intermediary between POD reports and the Runtime API subsystem. Maybe we should rename it to Misbehavior Reporting, as most reports are "complete", and the actual dispute resolution / arbitration process will happen on-chain in the Validity
module.
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.
Then we shouldn't need the dispute records to be present in the Provisioner
then either, because the assumption is that anything that the Provisioner is responsible for everything that the Proposer will need. If the Proposer doesn't need them, then the Provisioner shouldn't either. And then I suggest removing RequestBlockAuthorshipData
, as I don't see an immediate need for it if there are no disputes and no other intended users of the Provisioner
.
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.
I think I agree with those proposals, but I also think they're out of scope for this PR.
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.
Yup, that's fair. We have a discussion on-record to reference now at least
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.
Created an issue from this so we don't lose it: #1362.
node/core/proposer/src/lib.rs
Outdated
record_proof: RecordProof, | ||
) -> Self::Proposal { | ||
let mut proposal = async move { | ||
let provisioner_inherent_data = self.provisioner_inherent_data.await.map_err(Error::ClosedChannelFromProvisioner)?; |
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 implication of returning an error here is that the validator node will not author any block. I think that it's better to author an "empty" block (at least in terms of inherent data) than no block, if the overseer or subsystems are unresponsive. Coupled with a critical warning of some kind. This would make the chain more robust.
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.
Does it actually make the chain more robust, though? If this inherent data doesn't get injected, the inclusion_inherent module panics:
polkadot/runtime/parachains/src/inclusion_inherent.rs
Lines 133 to 134 in aeb79d4
data.get_data(&Self::INHERENT_IDENTIFIER) | |
.expect("inclusion inherent data failed to decode") |
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.
I think 9bae56e takes care of this as well; do you agree?
This could use a rebase onto master to only contain the commits that are part of this PR |
I agree, but after having attempted it for a long while, I don't think its worth the effort. |
This means that we can wrap the delayed call into the same timeout check used elsewhere.
This satisfies two requirements: - only applies the timeout to actually fetching the provisioner data, not to constructing the block after - simplifies the problem of injecting default data if we could not get the real provisioner data in time.
@coriolinus the "hack" I always use when facing a bad rebase is to take these steps:
It's kind of messy, but it works |
Looks fine but I would still like the rebase if not too much trouble. |
If I understand, this These "transactions" have fairly bespoke logic however, like a fuller bitfields replacing emptier ones, and backing statements changing bits meaning from a block onwards, but older bitfields still being useful. We also have censorship concerns that become much harder to discuss, formalize, etc., probably less bad than with slashing though, but not sure.
Yes, we'd want nodes to delay issuing their first bitfield on some relay chain block until they can recieve some pieces, but neither should they get stuck between this delay, advancing the relay chain block on which they build bitfields, and the torrent of new blocks.
Yes, we should wait for bitfields before expiring candidates and accepting newly backed candidates. In my mind, we should handle the backing statements mostly off the relay chain, which sounds like only a minor optimization that an MVP can ignore. In all cases, we could politely decline to gossip backing statements until the previously backed candidate either expires or advances from availability to approvals, which I suppose fits with our gossip strategy elsewhere?
This sounds internal to the node, right? We check all the gossip signatures when receiving, and we do not have that many parachains, so I think the There are some interesting cases here, like including older availability statements for slow expired candidates. I'd skip doing that for the MVP, but maybe some such things should be collected by some "polkadot informational log parachain" eventually. We should prevent regular transactions from competing with the A&V system for block space, or else we should remove tipping entirely, which eventually might require removing user transactions form the relay chain entirely, but maybe block space reserves work fine over the short term. |
Yeah, this timeout is about handling what is essentially a node bug. However we also want a related timeout which is how long to wait for bitfields / backing before authoring the relay-chain block. Intuitively, this is going to have to be slightly longer than the timeout for signing bitfields. |
Closes #1248.
Includes #1318, #1280.
A custom proposer with an overseer handle will suit our needs better than the basic authorship one.