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

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

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>
TomaszWaszczyk pushed a commit to TomaszWaszczyk/polkadot-sdk that referenced this pull request May 27, 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>
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>
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: Audited
Development

Successfully merging this pull request may close these issues.

None yet

4 participants