Skip to content

Commit

Permalink
reenable unsigned validation for ethy and prevent EthCallNotarization…
Browse files Browse the repository at this point in the history
… resubmissions
  • Loading branch information
JCSanPedro committed Oct 9, 2024
1 parent 2f8e148 commit 52574a7
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 45 deletions.
46 changes: 1 addition & 45 deletions pallet/ethy/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ impl<T: Config> Pallet<T> {
}

/// Send a notarization for the given claim
fn offchain_send_notarization(
pub(crate) fn offchain_send_notarization(
key: &T::EthyId,
payload: NotarizationPayload,
) -> Result<(), Error<T>> {
Expand Down Expand Up @@ -986,50 +986,6 @@ impl<T: Config> Pallet<T> {
}
}

impl<T: Config> frame_support::unsigned::ValidateUnsigned for Pallet<T> {
type Call = Call<T>;

fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
if let Call::submit_notarization { ref payload, ref signature } = call {
// notarization must be from an active notary
let notary_keys = NotaryKeys::<T>::get();
let notary_public_key = match notary_keys.get(payload.authority_index() as usize) {
Some(id) => id,
None => return InvalidTransaction::BadProof.into(),
};
// notarization must not be a duplicate/equivocation
if <EventNotarizations<T>>::contains_key(payload.payload_id(), &notary_public_key) {
log!(
error,
"💎 received equivocation from: {:?} on {:?}",
notary_public_key,
payload.payload_id()
);
return InvalidTransaction::BadProof.into();
}
// notarization is signed correctly
if !(notary_public_key.verify(&payload.encode(), signature)) {
return InvalidTransaction::BadProof.into();
}
ValidTransaction::with_tag_prefix("eth-bridge")
.priority(UNSIGNED_TXS_PRIORITY)
// 'provides' must be unique for each submission on the network (i.e. unique for
// each claim id and validator)
.and_provides([
b"notarize",
&payload.type_id().to_be_bytes(),
&payload.payload_id().to_be_bytes(),
&(payload.authority_index() as u64).to_be_bytes(),
])
.longevity(3)
.propagate(true)
.build()
} else {
InvalidTransaction::Call.into()
}
}
}

impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Pallet<T> {
type Public = T::EthyId;
}
Expand Down
71 changes: 71 additions & 0 deletions pallet/ethy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,77 @@ pub mod pallet {
}
}

#[pallet::validate_unsigned]
impl<T: Config> frame_support::unsigned::ValidateUnsigned for Pallet<T> {
type Call = Call<T>;

fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
if let Call::submit_notarization { ref payload, ref signature } = call {
// notarization must be from an active notary
let notary_keys = NotaryKeys::<T>::get();
let notary_public_key = match notary_keys.get(payload.authority_index() as usize) {
Some(id) => id,
None => return InvalidTransaction::BadProof.into(),
};

let st = notary_public_key.as_ref();

// notarization must not be a duplicate/equivocation
match payload {
NotarizationPayload::Call { .. } => {
if <EthCallNotarizations<T>>::contains_key(
payload.payload_id(),
&notary_public_key,
) {
log!(
error,
"💎 received equivocation from: {:?} on {:?}",
notary_public_key,
payload.payload_id()
);
return InvalidTransaction::BadProof.into();
}
},
NotarizationPayload::Event { .. } => {
if <EventNotarizations<T>>::contains_key(
payload.payload_id(),
&notary_public_key,
) {
log!(
error,
"💎 received equivocation from: {:?} on {:?}",
notary_public_key,
payload.payload_id()
);
return InvalidTransaction::BadProof.into();
}
},
}

// notarization is signed correctly
if !(notary_public_key.verify(&payload.encode(), signature)) {
return InvalidTransaction::BadProof.into();
}

ValidTransaction::with_tag_prefix("eth-bridge")
.priority(UNSIGNED_TXS_PRIORITY)
// 'provides' must be unique for each submission on the network (i.e. unique for
// each claim id and validator)
.and_provides([
b"notarize",
&payload.type_id().to_be_bytes(),
&payload.payload_id().to_be_bytes(),
&(payload.authority_index() as u64).to_be_bytes(),
])
.longevity(3)
.propagate(true)
.build()
} else {
InvalidTransaction::Call.into()
}
}
}

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Set new XRPL door signers
Expand Down

0 comments on commit 52574a7

Please sign in to comment.