Skip to content

Commit

Permalink
Require two fishermen to veto state machine updates (#338)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wizdave97 authored Nov 8, 2024
1 parent 8df1d15 commit c12f9e4
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 21 deletions.
46 changes: 34 additions & 12 deletions modules/ismp/pallets/fishermen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ pub mod pallet {
#[pallet::getter(fn whitelist)]
pub type Fishermen<T: Config> = StorageMap<_, Twox64Concat, T::AccountId, (), OptionQuery>;

/// Set of whitelisted fishermen accounts
#[pallet::storage]
#[pallet::getter(fn pending_vetoes)]
pub type PendingVetoes<T: Config> =
StorageMap<_, Blake2_128Concat, StateMachineHeight, T::AccountId, OptionQuery>;

#[pallet::error]
pub enum Error<T> {
/// Account Already Whitelisted
Expand All @@ -61,6 +67,8 @@ pub mod pallet {
UnauthorizedAction,
/// State commitment was not found
VetoFailed,
/// Invalid veto request
InvalidVeto,
}

#[pallet::event]
Expand All @@ -72,6 +80,8 @@ pub mod pallet {
Removed { account: T::AccountId },
/// The provided state commitment was vetoed `state_machine` is by account
StateCommitmentVetoed { height: StateMachineHeight, commitment: StateCommitment },
/// The vetoe has been noted by the runtime
VetoNoted { height: StateMachineHeight, fisherman: T::AccountId },
}

#[pallet::call]
Expand Down Expand Up @@ -109,6 +119,7 @@ pub mod pallet {
/// challenge period) is infact fraudulent and misrepresentative of the state
/// changes at the provided height. This allows them to veto the state commitment.
/// They aren't required to provide any proofs for this.
/// Successful veto requires two fishermen
#[pallet::call_index(2)]
#[pallet::weight(<T as frame_system::Config>::DbWeight::get().reads_writes(2, 3))]
pub fn veto_state_commitment(
Expand All @@ -118,18 +129,29 @@ pub mod pallet {
let account = ensure_signed(origin.clone())?;
ensure!(Fishermen::<T>::contains_key(&account), Error::<T>::UnauthorizedAction);

let ismp_host = <T as Config>::IsmpHost::default();
let commitment =
ismp_host.state_machine_commitment(height).map_err(|_| Error::<T>::VetoFailed)?;
ismp_host.delete_state_commitment(height).map_err(|_| Error::<T>::VetoFailed)?;

Self::deposit_event(Event::StateCommitmentVetoed { height, commitment });
pallet_ismp::Pallet::<T>::deposit_pallet_event(
ismp::events::Event::StateCommitmentVetoed(StateCommitmentVetoed {
height,
fisherman: account.as_ref().to_vec(),
}),
);
if let Some(prev_veto) = PendingVetoes::<T>::get(height) {
if account == prev_veto {
Err(Error::<T>::InvalidVeto)?
}
let ismp_host = <T as Config>::IsmpHost::default();
let commitment = ismp_host
.state_machine_commitment(height)
.map_err(|_| Error::<T>::VetoFailed)?;
ismp_host.delete_state_commitment(height).map_err(|_| Error::<T>::VetoFailed)?;
PendingVetoes::<T>::remove(height);

Self::deposit_event(Event::StateCommitmentVetoed { height, commitment });
pallet_ismp::Pallet::<T>::deposit_pallet_event(
ismp::events::Event::StateCommitmentVetoed(StateCommitmentVetoed {
height,
fisherman: account.as_ref().to_vec(),
}),
);
} else {
PendingVetoes::<T>::insert(height, account.clone());
Self::deposit_event(Event::VetoNoted { height, fisherman: account });
}

Ok(())
}
}
Expand Down
29 changes: 29 additions & 0 deletions modules/ismp/pallets/testsuite/src/tests/pallet_fishermen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,42 @@ fn test_can_veto_state_commitments() {
}))
);

// Add another fisherman

let account_2: AccountId32 = H256::random().0.into();
pallet_fishermen::Pallet::<Test>::add(RuntimeOrigin::root(), account_2.clone()).unwrap();
assert_eq!(pallet_fishermen::Fishermen::<Test>::get(account_2.clone()), Some(()));

// actual veto
let result = pallet_fishermen::Pallet::<Test>::veto_state_commitment(
RuntimeOrigin::signed(account.clone()),
height,
);
assert_eq!(result, Ok(()));

assert_eq!(pallet_fishermen::PendingVetoes::<Test>::get(height), Some(account.clone()));

// veto with same account
let result = pallet_fishermen::Pallet::<Test>::veto_state_commitment(
RuntimeOrigin::signed(account.clone()),
height,
);

assert!(matches!(
result,
Err(sp_runtime::DispatchError::Module(ModuleError {
index: 9,
error: [4, 0, 0, 0,],
message: Some("InvalidVeto",),
}))
));

let result = pallet_fishermen::Pallet::<Test>::veto_state_commitment(
RuntimeOrigin::signed(account_2.clone()),
height,
);
assert_eq!(result, Ok(()));

// should have been deleted
let result = host.state_machine_commitment(height);
assert!(matches!(result, Err(Error::StateCommitmentNotFound { .. })));
Expand Down
19 changes: 10 additions & 9 deletions parachain/runtimes/nexus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("nexus"),
impl_name: create_runtime_str!("nexus"),
authoring_version: 1,
spec_version: 1400,
spec_version: 1600,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
Expand Down Expand Up @@ -748,19 +748,20 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
fn filter(&self, c: &RuntimeCall) -> bool {
match self {
ProxyType::Any => true,
ProxyType::NonTransfer =>
!matches!(c, RuntimeCall::Balances { .. } | RuntimeCall::Assets { .. }),
ProxyType::NonTransfer => {
!matches!(c, RuntimeCall::Balances { .. } | RuntimeCall::Assets { .. })
},
ProxyType::CancelProxy => matches!(
c,
RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) |
RuntimeCall::Utility { .. } |
RuntimeCall::Multisig { .. }
RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. })
| RuntimeCall::Utility { .. }
| RuntimeCall::Multisig { .. }
),
ProxyType::Collator => matches!(
c,
RuntimeCall::CollatorSelection { .. } |
RuntimeCall::Utility { .. } |
RuntimeCall::Multisig { .. }
RuntimeCall::CollatorSelection { .. }
| RuntimeCall::Utility { .. }
| RuntimeCall::Multisig { .. }
),
}
}
Expand Down

0 comments on commit c12f9e4

Please sign in to comment.