Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion polkadot/node/service/src/fake_runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ sp_api::impl_runtime_apis! {
unimplemented!()
}

fn submit_report_equivocation_unsigned_extrinsic(
fn submit_report_double_voting_unsigned_extrinsic(
_: beefy_primitives::DoubleVotingProof<
BlockNumber,
BeefyId,
Expand Down
7 changes: 4 additions & 3 deletions polkadot/runtime/rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,7 @@ impl pallet_beefy::Config for Runtime {
type MaxNominators = ConstU32<0>;
type MaxSetIdSessionEntries = BeefySetIdSessionEntries;
type OnNewValidatorSet = MmrLeaf;
type AncestryHelper = MmrLeaf;
type WeightInfo = ();
type KeyOwnerProof = <Historical as KeyOwnerProofSystem<(KeyTypeId, BeefyId)>>::Proof;
type EquivocationReportSystem =
Expand Down Expand Up @@ -2086,7 +2087,7 @@ sp_api::impl_runtime_apis! {
}
}

#[api_version(3)]
#[api_version(4)]
impl beefy_primitives::BeefyApi<Block, BeefyId> for Runtime {
fn beefy_genesis() -> Option<BlockNumber> {
pallet_beefy::GenesisBlock::<Runtime>::get()
Expand All @@ -2096,7 +2097,7 @@ sp_api::impl_runtime_apis! {
Beefy::validator_set()
}

fn submit_report_equivocation_unsigned_extrinsic(
fn submit_report_double_voting_unsigned_extrinsic(
equivocation_proof: beefy_primitives::DoubleVotingProof<
BlockNumber,
BeefyId,
Expand All @@ -2106,7 +2107,7 @@ sp_api::impl_runtime_apis! {
) -> Option<()> {
let key_owner_proof = key_owner_proof.decode()?;

Beefy::submit_unsigned_equivocation_report(
Beefy::submit_unsigned_double_voting_report(
equivocation_proof,
key_owner_proof,
)
Expand Down
2 changes: 1 addition & 1 deletion polkadot/runtime/test-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,7 @@ sp_api::impl_runtime_apis! {
None
}

fn submit_report_equivocation_unsigned_extrinsic(
fn submit_report_double_voting_unsigned_extrinsic(
_equivocation_proof: beefy_primitives::DoubleVotingProof<
BlockNumber,
BeefyId,
Expand Down
6 changes: 4 additions & 2 deletions polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ impl pallet_beefy::Config for Runtime {
type MaxNominators = MaxNominators;
type MaxSetIdSessionEntries = BeefySetIdSessionEntries;
type OnNewValidatorSet = BeefyMmrLeaf;
type AncestryHelper = BeefyMmrLeaf;
type WeightInfo = ();
type KeyOwnerProof = sp_session::MembershipProof;
type EquivocationReportSystem =
Expand Down Expand Up @@ -1995,6 +1996,7 @@ sp_api::impl_runtime_apis! {
}
}

#[api_version(4)]
impl beefy_primitives::BeefyApi<Block, BeefyId> for Runtime {
fn beefy_genesis() -> Option<BlockNumber> {
pallet_beefy::GenesisBlock::<Runtime>::get()
Expand All @@ -2004,7 +2006,7 @@ sp_api::impl_runtime_apis! {
Beefy::validator_set()
}

fn submit_report_equivocation_unsigned_extrinsic(
fn submit_report_double_voting_unsigned_extrinsic(
equivocation_proof: beefy_primitives::DoubleVotingProof<
BlockNumber,
BeefyId,
Expand All @@ -2014,7 +2016,7 @@ sp_api::impl_runtime_apis! {
) -> Option<()> {
let key_owner_proof = key_owner_proof.decode()?;

Beefy::submit_unsigned_equivocation_report(
Beefy::submit_unsigned_double_voting_report(
equivocation_proof,
key_owner_proof,
)
Expand Down
7 changes: 4 additions & 3 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2563,6 +2563,7 @@ impl pallet_beefy::Config for Runtime {
type MaxNominators = ConstU32<0>;
type MaxSetIdSessionEntries = BeefySetIdSessionEntries;
type OnNewValidatorSet = MmrLeaf;
type AncestryHelper = MmrLeaf;
type WeightInfo = ();
type KeyOwnerProof = <Historical as KeyOwnerProofSystem<(KeyTypeId, BeefyId)>>::Proof;
type EquivocationReportSystem =
Expand Down Expand Up @@ -3031,7 +3032,7 @@ impl_runtime_apis! {
}
}

#[api_version(3)]
#[api_version(4)]
impl sp_consensus_beefy::BeefyApi<Block, BeefyId> for Runtime {
fn beefy_genesis() -> Option<BlockNumber> {
pallet_beefy::GenesisBlock::<Runtime>::get()
Expand All @@ -3041,7 +3042,7 @@ impl_runtime_apis! {
Beefy::validator_set()
}

fn submit_report_equivocation_unsigned_extrinsic(
fn submit_report_double_voting_unsigned_extrinsic(
equivocation_proof: sp_consensus_beefy::DoubleVotingProof<
BlockNumber,
BeefyId,
Expand All @@ -3051,7 +3052,7 @@ impl_runtime_apis! {
) -> Option<()> {
let key_owner_proof = key_owner_proof.decode()?;

Beefy::submit_unsigned_equivocation_report(
Beefy::submit_unsigned_double_voting_report(
equivocation_proof,
key_owner_proof,
)
Expand Down
2 changes: 1 addition & 1 deletion substrate/client/consensus/beefy/src/fisherman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ where
for ProvedValidator { key_owner_proof, .. } in key_owner_proofs {
self.runtime
.runtime_api()
.submit_report_equivocation_unsigned_extrinsic(
.submit_report_double_voting_unsigned_extrinsic(
best_block_hash,
proof.clone(),
key_owner_proof,
Expand Down
2 changes: 1 addition & 1 deletion substrate/client/consensus/beefy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ sp_api::mock_impl_runtime_apis! {
self.inner.validator_set.clone()
}

fn submit_report_equivocation_unsigned_extrinsic(
fn submit_report_double_voting_unsigned_extrinsic(
proof: DoubleVotingProof<NumberFor<Block>, AuthorityId, Signature>,
_dummy: OpaqueKeyOwnershipProof,
) -> Option<()> {
Expand Down
6 changes: 3 additions & 3 deletions substrate/client/consensus/beefy/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,7 @@ pub(crate) mod tests {
known_payloads,
known_payloads::MMR_ROOT_ID,
mmr::MmrRootProvider,
test_utils::{generate_equivocation_proof, Keyring},
test_utils::{generate_double_voting_proof, Keyring},
ConsensusLog, Payload, SignedCommitment,
};
use sp_runtime::traits::{Header as HeaderT, One};
Expand Down Expand Up @@ -1555,7 +1555,7 @@ pub(crate) mod tests {
let payload2 = Payload::from_single_entry(MMR_ROOT_ID, vec![128]);

// generate an equivocation proof, with Bob as perpetrator
let good_proof = generate_equivocation_proof(
let good_proof = generate_double_voting_proof(
(block_num, payload1.clone(), set_id, &Keyring::Bob),
(block_num, payload2.clone(), set_id, &Keyring::Bob),
);
Expand Down Expand Up @@ -1587,7 +1587,7 @@ pub(crate) mod tests {
assert!(api_alice.reported_equivocations.as_ref().unwrap().lock().is_empty());

// now let's try reporting a self-equivocation
let self_proof = generate_equivocation_proof(
let self_proof = generate_double_voting_proof(
(block_num, payload1.clone(), set_id, &Keyring::Alice),
(block_num, payload2.clone(), set_id, &Keyring::Alice),
);
Expand Down
79 changes: 75 additions & 4 deletions substrate/frame/beefy-mmr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,22 @@
//!
//! and thanks to versioning can be easily updated in the future.

use sp_runtime::traits::{Convert, Member};
use sp_runtime::traits::{Convert, Header, Member};
use sp_std::prelude::*;

use codec::Decode;
use pallet_mmr::{LeafDataProvider, ParentNumberAndHash};
use pallet_mmr::{primitives::AncestryProof, LeafDataProvider, ParentNumberAndHash};
use sp_consensus_beefy::{
known_payloads,
mmr::{BeefyAuthoritySet, BeefyDataProvider, BeefyNextAuthoritySet, MmrLeaf, MmrLeafVersion},
ValidatorSet as BeefyValidatorSet,
AncestryHelper, Commitment, ConsensusLog, ValidatorSet as BeefyValidatorSet,
};

use frame_support::{crypto::ecdsa::ECDSAExt, traits::Get};
use frame_system::pallet_prelude::BlockNumberFor;
use frame_system::pallet_prelude::{BlockNumberFor, HeaderFor};

pub use pallet::*;
use sp_runtime::generic::OpaqueDigestItemId;

#[cfg(test)]
mod mock;
Expand Down Expand Up @@ -172,6 +174,75 @@ where
}
}

impl<T: Config> AncestryHelper<HeaderFor<T>> for Pallet<T>
where
T: pallet_mmr::Config<Hashing = sp_consensus_beefy::MmrHashing>,
{
type Proof = AncestryProof<MerkleRootOf<T>>;
type ValidationContext = MerkleRootOf<T>;

fn extract_validation_context(header: HeaderFor<T>) -> Option<Self::ValidationContext> {
// Check if the provided header is canonical.
let expected_hash = frame_system::Pallet::<T>::block_hash(header.number());
if expected_hash != header.hash() {
return None;
}

// Extract the MMR root from the header digest
header.digest().convert_first(|l| {
l.try_to(OpaqueDigestItemId::Consensus(&sp_consensus_beefy::BEEFY_ENGINE_ID))
.and_then(|log: ConsensusLog<<T as pallet_beefy::Config>::BeefyId>| match log {
ConsensusLog::MmrRoot(mmr_root) => Some(mmr_root),
_ => None,
})
})
}

fn is_non_canonical(
commitment: &Commitment<BlockNumberFor<T>>,
proof: Self::Proof,
context: Self::ValidationContext,
) -> bool {
let commitment_leaf_count =
match pallet_mmr::Pallet::<T>::block_num_to_leaf_count(commitment.block_number) {
Ok(commitment_leaf_count) => commitment_leaf_count,
Err(_) => {
// We can't prove that the commitment is non-canonical if the
// `commitment.block_number` is invalid.
return false
},
};
if commitment_leaf_count != proof.prev_leaf_count {
// Can't prove that the commitment is non-canonical if the `commitment.block_number`
// doesn't match the ancestry proof.
return false;
}

let canonical_mmr_root = context;
let canonical_prev_root =
match pallet_mmr::Pallet::<T>::verify_ancestry_proof(canonical_mmr_root, proof) {
Ok(canonical_prev_root) => canonical_prev_root,
Err(_) => {
// Can't prove that the commitment is non-canonical if the proof
// is invalid.
return false
},
};

let commitment_root =
match commitment.payload.get_decoded::<MerkleRootOf<T>>(&known_payloads::MMR_ROOT_ID) {
Some(commitment_root) => commitment_root,
None => {
// If the commitment doesn't contain any MMR root, while the proof is valid,
// the commitment is invalid
return true
},
};

canonical_prev_root != commitment_root
}
}

impl<T: Config> Pallet<T> {
/// Return the currently active BEEFY authority set proof.
pub fn authority_set_proof() -> BeefyAuthoritySet<MerkleRootOf<T>> {
Expand Down
1 change: 1 addition & 0 deletions substrate/frame/beefy-mmr/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ impl pallet_beefy::Config for Test {
type MaxNominators = ConstU32<1000>;
type MaxSetIdSessionEntries = ConstU64<100>;
type OnNewValidatorSet = BeefyMmr;
type AncestryHelper = BeefyMmr;
type WeightInfo = ();
type KeyOwnerProof = sp_core::Void;
type EquivocationReportSystem = ();
Expand Down
Loading