Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BEEFY] Add runtime support for reporting fork voting #4522

Merged
merged 17 commits into from
Jul 3, 2024

Conversation

serban300
Copy link
Contributor

@serban300 serban300 commented May 20, 2024

Related to #4523

Extracting part of #1903 (credits to @Lederstrumpf for the high-level strategy), but also introducing significant adjustments both to the approach and to the code. The main adjustment is the fact that the ForkVotingProof accepts only one vote, compared to the original version which accepted a vec![]. With this approach more calls are needed in order to report multiple equivocated votes on the same commit, but it simplifies a lot the checking logic. We can add support for reporting multiple signatures at once in the future.

There are 2 things that are missing in order to consider this issue done, but I would propose to do them in a separate PR since this one is already pretty big:

Co-authored-by: Robert Hambrock roberthambrock@gmail.com

@serban300 serban300 added R0-silent Changes should not be mentioned in any release notes T15-bridges This PR/Issue is related to bridges. labels May 20, 2024
@serban300 serban300 self-assigned this May 20, 2024
@serban300 serban300 marked this pull request as ready for review May 20, 2024 13:17
@serban300 serban300 requested a review from acatangiu as a code owner May 20, 2024 13:17
@serban300 serban300 requested a review from svyatonik May 20, 2024 13:17
Copy link
Contributor

@svyatonik svyatonik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

substrate/frame/beefy-mmr/src/lib.rs Outdated Show resolved Hide resolved
}

let evidence = call.to_equivocation_evidence_for().ok_or(InvalidTransaction::Call)?;
let tag = (evidence.offender_id().clone(), evidence.set_id(), *evidence.round_number());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to accept two different types of equivocation reports (double voting and fork voting) at a single slot? If so, we maybe need to add that type to the tag

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can accept 2 equivocation reports from the same offender in the same round. I think check_evidence will fail:

	fn check_evidence(
		evidence: EquivocationEvidenceFor<T>,
	) -> Result<(), TransactionValidityError> {
		let offender = evidence.checked_offender::<P>().ok_or(InvalidTransaction::BadProof)?;

		// Check if the offence has already been reported, and if so then we can discard the report.
		let time_slot = TimeSlot { set_id: evidence.set_id(), round: *evidence.round_number() };
		if R::is_known_offence(&[offender], &time_slot) {
			Err(InvalidTransaction::Stale.into())
		} else {
			Ok(())
		}
	}

Copy link
Contributor Author

@serban300 serban300 May 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, we could change check_evidence. I don't know what would be best. I would lean towards staying consistent with the current approach where we accept one equivocation per (offender, set_id, round).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see anywhere in this PR the extrinsic used to report these ForkEquivocations..

I am thinking since you only allow single offender per report does that mean that for a slashable fork equivocation we need to report all the offenders across multiple blocks?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see anywhere in this PR the extrinsic used to report these ForkEquivocations..

The extrinsic is here .

I am thinking since you only allow single offender per report does that mean that for a slashable fork equivocation we need to report all the offenders across multiple blocks?

Hmmm good point. Could be. I can try to implement the solution that was discussed here. It's good to have it anyway.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extrinsic is here .

Right, I got confused. I had noticed we don't have runtime APIs for the "unsigned" version of the call. Should we add it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, missed that. Will add it.

Copy link
Contributor Author

@serban300 serban300 May 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking since you only allow single offender per report does that mean that for a slashable fork equivocation we need to report all the offenders across multiple blocks?

Hmmm good point. Could be. I can try to implement the solution that was discussed here. It's good to have it anyway.

Done. PTAL ! Relevant commit: f709cef

Right, I got confused. I had noticed we don't have runtime APIs for the "unsigned" version of the call. Should we add it?

Yes, missed that. Will add it.

On a second thought, I think it's better to do this in a separate PR together with the logic for generating the ancestry proofs since the type of the ancestry proof will depend on that (it could either be AncestryProof or OpaqueValue, depending on how we generate it). WDYT ?

@acatangiu acatangiu removed the R0-silent Changes should not be mentioned in any release notes label May 20, 2024
@Lederstrumpf
Copy link
Contributor

The main adjustment is the fact that the ForkVotingProof accepts only one vote, compared to the original version which accepted a vec![]. With this approach more calls are needed in order to report multiple equivocated votes on the same commit, but it simplifies a lot the checking logic. We can add support for reporting multiple signatures at once in the future.

When you state "at once in the future":
Is this an immediate follow-up PR prior to integrating the client side changes from #1903, or possibly delayed beyond then - i.e. adjusting the client side changes in #1903 to work with a single vote prior to moving to a vec (eventually)?

@serban300 serban300 mentioned this pull request May 23, 2024
@serban300
Copy link
Contributor Author

The main adjustment is the fact that the ForkVotingProof accepts only one vote, compared to the original version which accepted a vec![]. With this approach more calls are needed in order to report multiple equivocated votes on the same commit, but it simplifies a lot the checking logic. We can add support for reporting multiple signatures at once in the future.

When you state "at once in the future": Is this an immediate follow-up PR prior to integrating the client side changes from #1903, or possibly delayed beyond then - i.e. adjusting the client side changes in #1903 to work with a single vote prior to moving to a vec (eventually)?

Discussed offline. I am not sure if we should support a batch of votes, since it will complicate things, but if we do, we can do any of the 2 options. They both seem ok to me.

github-merge-queue bot pushed a commit that referenced this pull request May 23, 2024
Define `OpaqueValue` and use it instead of
`grandpa::OpaqueKeyOwnershipProof` and `beefy:OpaqueKeyOwnershipProof`

Related to
#4522 (comment)

We'll need to introduce a runtime API method that calls the
`report_fork_voting_unsigned()` extrinsic. This method will need to
receive the ancestry proof as a paramater. I'm still not sure, but there
is a chance that we'll send the ancestry proof as an opaque type.

So let's introduce this `OpaqueValue`. We can already use it to replace
`grandpa::OpaqueKeyOwnershipProof` and `beefy:OpaqueKeyOwnershipProof`
and maybe we'll need it for the ancestry proof as well.

---------

Co-authored-by: Bastian Köcher <git@kchr.de>
hitchhooker pushed a commit to ibp-network/polkadot-sdk that referenced this pull request Jun 5, 2024
Define `OpaqueValue` and use it instead of
`grandpa::OpaqueKeyOwnershipProof` and `beefy:OpaqueKeyOwnershipProof`

Related to
paritytech#4522 (comment)

We'll need to introduce a runtime API method that calls the
`report_fork_voting_unsigned()` extrinsic. This method will need to
receive the ancestry proof as a paramater. I'm still not sure, but there
is a chance that we'll send the ancestry proof as an opaque type.

So let's introduce this `OpaqueValue`. We can already use it to replace
`grandpa::OpaqueKeyOwnershipProof` and `beefy:OpaqueKeyOwnershipProof`
and maybe we'll need it for the ancestry proof as well.

---------

Co-authored-by: Bastian Köcher <git@kchr.de>
substrate/frame/beefy/src/equivocation.rs Outdated Show resolved Hide resolved
prdoc/pr_4522.prdoc Outdated Show resolved Hide resolved
Co-authored-by: Adrian Catangiu <adrian@parity.io>
@acatangiu acatangiu enabled auto-merge July 3, 2024 11:28
@@ -50,6 +57,11 @@ impl crate::WeightInfo for () {
.saturating_add(DbWeight::get().reads(2))
}

// TODO: Calculate
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@serban300 what about this TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I plan to do this in a separate PR, as mentioned in the description. Also keeping track of it in the issue: #4523 to make sure we don't forget.

@acatangiu acatangiu added this pull request to the merge queue Jul 3, 2024
@serban300 serban300 removed this pull request from the merge queue due to a manual request Jul 3, 2024
doc:
- audience:
- Runtime Dev
- Runtime User
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this description relevant to runtime users?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking it might be helpful for them to know of the new extrinsics.

@serban300 serban300 enabled auto-merge July 3, 2024 12:36
@serban300 serban300 disabled auto-merge July 3, 2024 12:53
prdoc/pr_4522.prdoc Outdated Show resolved Hide resolved
@serban300 serban300 enabled auto-merge July 3, 2024 13:18
@serban300 serban300 added this pull request to the merge queue Jul 3, 2024
Merged via the queue into paritytech:master with commit b6f1823 Jul 3, 2024
156 of 159 checks passed
@serban300 serban300 deleted the beefy-equivocation-runtime branch July 3, 2024 14:12
TomaszWaszczyk pushed a commit to TomaszWaszczyk/polkadot-sdk that referenced this pull request Jul 7, 2024
Related to paritytech#4523

Extracting part of paritytech#1903
(credits to @Lederstrumpf for the high-level strategy), but also
introducing significant adjustments both to the approach and to the
code. The main adjustment is the fact that the `ForkVotingProof` accepts
only one vote, compared to the original version which accepted a
`vec![]`. With this approach more calls are needed in order to report
multiple equivocated votes on the same commit, but it simplifies a lot
the checking logic. We can add support for reporting multiple signatures
at once in the future.

There are 2 things that are missing in order to consider this issue
done, but I would propose to do them in a separate PR since this one is
already pretty big:
- benchmarks/computing a weight for the new extrinsic (this wasn't
present in paritytech#1903 either)
- exposing an API for generating the ancestry proof. I'm not sure if we
should do this in the Mmr pallet or in the Beefy pallet

Co-authored-by: Robert Hambrock <roberthambrock@gmail.com>

---------

Co-authored-by: Adrian Catangiu <adrian@parity.io>
TarekkMA pushed a commit to moonbeam-foundation/polkadot-sdk that referenced this pull request Aug 2, 2024
Define `OpaqueValue` and use it instead of
`grandpa::OpaqueKeyOwnershipProof` and `beefy:OpaqueKeyOwnershipProof`

Related to
paritytech#4522 (comment)

We'll need to introduce a runtime API method that calls the
`report_fork_voting_unsigned()` extrinsic. This method will need to
receive the ancestry proof as a paramater. I'm still not sure, but there
is a chance that we'll send the ancestry proof as an opaque type.

So let's introduce this `OpaqueValue`. We can already use it to replace
`grandpa::OpaqueKeyOwnershipProof` and `beefy:OpaqueKeyOwnershipProof`
and maybe we'll need it for the ancestry proof as well.

---------

Co-authored-by: Bastian Köcher <git@kchr.de>
TarekkMA pushed a commit to moonbeam-foundation/polkadot-sdk that referenced this pull request Aug 2, 2024
Related to paritytech#4523

Extracting part of paritytech#1903
(credits to @Lederstrumpf for the high-level strategy), but also
introducing significant adjustments both to the approach and to the
code. The main adjustment is the fact that the `ForkVotingProof` accepts
only one vote, compared to the original version which accepted a
`vec![]`. With this approach more calls are needed in order to report
multiple equivocated votes on the same commit, but it simplifies a lot
the checking logic. We can add support for reporting multiple signatures
at once in the future.

There are 2 things that are missing in order to consider this issue
done, but I would propose to do them in a separate PR since this one is
already pretty big:
- benchmarks/computing a weight for the new extrinsic (this wasn't
present in paritytech#1903 either)
- exposing an API for generating the ancestry proof. I'm not sure if we
should do this in the Mmr pallet or in the Beefy pallet

Co-authored-by: Robert Hambrock <roberthambrock@gmail.com>

---------

Co-authored-by: Adrian Catangiu <adrian@parity.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T15-bridges This PR/Issue is related to bridges.
Projects
Status: Done
Status: Audited
Development

Successfully merging this pull request may close these issues.

6 participants