diff --git a/Cargo.lock b/Cargo.lock index ba88aef84..887059470 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6579,6 +6579,7 @@ dependencies = [ "pallet-asset-manager", "pallet-assets", "pallet-balances", + "pallet-tx-pause", "parity-scale-codec", "rand_chacha 0.3.1", "scale-info", diff --git a/pallets/manta-pay/Cargo.toml b/pallets/manta-pay/Cargo.toml index d5f74cfef..f12fd3548 100644 --- a/pallets/manta-pay/Cargo.toml +++ b/pallets/manta-pay/Cargo.toml @@ -116,10 +116,11 @@ manta-util = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0. [dev-dependencies] lazy_static = "1.4.0" manta-crypto = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.9", features = ["getrandom"] } -manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.9", default-features = false, features = ["groth16", "parameters", "scale", "download", "test"] } +manta-pay = { git = "https://github.com/manta-network/manta-rs.git", tag = "v0.5.9", features = ["groth16", "parameters", "scale", "download", "test"] } pallet-asset-manager = { path = "../asset-manager" } pallet-assets = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.28" } pallet-balances = { git = 'https://github.com/paritytech/substrate.git', branch = "polkadot-v0.9.28" } +pallet-tx-pause = { path = '../tx-pause' } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } tempfile = "3.3.0" diff --git a/pallets/manta-pay/src/lib.rs b/pallets/manta-pay/src/lib.rs index 4a4c0ce75..b71e29e87 100644 --- a/pallets/manta-pay/src/lib.rs +++ b/pallets/manta-pay/src/lib.rs @@ -126,6 +126,17 @@ pub mod pallet { const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + /// Suspend execution of MantaPay extrinsics (via tx-pause) due to unexpected internal ledger error. + /// Currently the following errors, which are only controlled by our own code, not user input: + /// ChecksumError, MerkleTreeCapacityError, VerifyingContextDecodeError + pub trait SuspendMantaPay { + fn suspend_manta_pay_execution(); + } + + impl SuspendMantaPay for () { + fn suspend_manta_pay_execution() {} + } + /// Pallet #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] @@ -146,6 +157,9 @@ pub mod pallet { /// Pallet ID type PalletId: Get; + + /// Suspends execution of all extrinsics via TxPause + type Suspender: SuspendMantaPay; } /// Fungible Ledger Implementation for [`Config`] @@ -474,7 +488,10 @@ pub mod pallet { } } - impl From> for Error { + impl From> for Error + where + T: Config, + { #[inline] fn from(err: SenderPostError) -> Self { match err { @@ -485,12 +502,24 @@ pub mod pallet { } } - impl From> for Error { + impl From>> for Error + where + T: Config, + { #[inline] - fn from(err: ReceiverPostError) -> Self { + fn from(err: ReceiverPostError>) -> Self { match err { ReceiverPostError::AssetRegistered => Self::AssetRegistered, - ReceiverPostError::UnexpectedError(_) => Self::InternalLedgerError, + ReceiverPostError::UnexpectedError(e) => { + match e { + ReceiverLedgerError::ChecksumError + | ReceiverLedgerError::MerkleTreeCapacityError => { + T::Suspender::suspend_manta_pay_execution(); + } + _ => {} + }; + Self::InternalLedgerError + } } } } @@ -505,12 +534,19 @@ pub mod pallet { } } - impl From for TransferLedgerError + impl From> for TransferLedgerError where T: Config, { #[inline] - fn from(err: ReceiverLedgerError) -> Self { + fn from(err: ReceiverLedgerError) -> Self { + match err { + ReceiverLedgerError::ChecksumError + | ReceiverLedgerError::MerkleTreeCapacityError => { + T::Suspender::suspend_manta_pay_execution(); + } + _ => {} + }; TransferLedgerError::ReceiverLedgerError(err) } } @@ -541,7 +577,7 @@ pub mod pallet { config::Config, ::AccountId, SenderLedgerError, - ReceiverLedgerError, + ReceiverLedgerError, TransferLedgerError, >; @@ -561,7 +597,16 @@ pub mod pallet { TransferPostError::::DuplicateMint => Self::DuplicateRegister, TransferPostError::::DuplicateSpend => Self::DuplicateSpend, TransferPostError::::InvalidProof => Self::InvalidProof, - TransferPostError::::UnexpectedError(_) => Self::InternalLedgerError, + TransferPostError::::UnexpectedError(e) => { + match e { + TransferLedgerError::ChecksumError + | TransferLedgerError::VerifyingContextDecodeError(_) => { + T::Suspender::suspend_manta_pay_execution(); + } + _ => {} + }; + Self::InternalLedgerError + } } } } @@ -921,7 +966,10 @@ pub type UtxoItemHashError = codec::DecodeError< >; /// Receiver Ledger Error -pub enum ReceiverLedgerError { +pub enum ReceiverLedgerError +where + T: Config, +{ /// Utxo Decoding Error UtxoDecodeError(scale_codec::Error), @@ -953,14 +1001,27 @@ pub enum ReceiverLedgerError { /// /// The asset has already been registered with the ledger. AssetRegistered, + + /// Type Marker Parameter + Marker(PhantomData), } -impl From for ReceiverPostError { +impl From> for ReceiverPostError> +where + T: Config, +{ #[inline] - fn from(value: ReceiverLedgerError) -> Self { + fn from(value: ReceiverLedgerError) -> Self { if let ReceiverLedgerError::AssetRegistered = value { Self::AssetRegistered } else { + match value { + ReceiverLedgerError::ChecksumError + | ReceiverLedgerError::MerkleTreeCapacityError => { + T::Suspender::suspend_manta_pay_execution(); + } + _ => {} + }; Self::UnexpectedError(value) } } @@ -972,7 +1033,7 @@ where { type SuperPostingKey = (Wrap<()>, ()); type ValidUtxo = Wrap; - type Error = ReceiverLedgerError; + type Error = ReceiverLedgerError; #[inline] fn is_not_registered(&self, utxo: config::Utxo) -> Result { @@ -1093,7 +1154,7 @@ where ChecksumError, /// Verifying Context Decoding Error - VerifiyingContextDecodeError(VerifyingContextError), + VerifyingContextDecodeError(VerifyingContextError), /// Field Element Encoding Error FpEncodeError(scale_codec::Error), @@ -1108,7 +1169,7 @@ where SenderLedgerError(SenderLedgerError), /// Receiver Ledger Error - ReceiverLedgerError(ReceiverLedgerError), + ReceiverLedgerError(ReceiverLedgerError), /// Invalid Transfer Shape InvalidTransferShape, @@ -1137,7 +1198,16 @@ where TransferLedgerError::SenderLedgerError(err) => Self::Sender(err.into()), TransferLedgerError::ReceiverLedgerError(err) => Self::Receiver(err.into()), TransferLedgerError::UnknownAsset => Self::InvalidProof, - err => Self::UnexpectedError(err), + err => { + match err { + TransferLedgerError::ChecksumError + | TransferLedgerError::VerifyingContextDecodeError(_) => { + T::Suspender::suspend_manta_pay_execution(); + } + _ => {} + }; + Self::UnexpectedError(err) + } } } } @@ -1285,7 +1355,7 @@ where let verification = posting_key .has_valid_proof( &config::VerifyingContext::decode(&mut verifying_context) - .map_err(TransferLedgerError::VerifiyingContextDecodeError)?, + .map_err(TransferLedgerError::VerifyingContextDecodeError)?, ) .map_err(TransferLedgerError::ProofSystemError)?; if verification { diff --git a/pallets/manta-pay/src/mock.rs b/pallets/manta-pay/src/mock.rs index c7d3715df..3ac413d3d 100644 --- a/pallets/manta-pay/src/mock.rs +++ b/pallets/manta-pay/src/mock.rs @@ -17,10 +17,10 @@ use frame_support::{ pallet_prelude::DispatchResult, parameter_types, - traits::{ConstU32, Everything}, + traits::{ConstU32, IsInVec}, PalletId, }; -use frame_system::EnsureRoot; +use frame_system::{EnsureRoot, RawOrigin}; use manta_primitives::{ assets::{ AssetConfig, AssetIdType, AssetLocation, AssetRegistry, AssetRegistryMetadata, @@ -52,10 +52,11 @@ frame_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Config, Storage, Event}, - MantaPayPallet: crate::{Pallet, Call, Storage, Event}, + MantaPay: crate::{Pallet, Call, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Assets: pallet_assets::{Pallet, Storage, Event}, AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event}, + TransactionPause: pallet_tx_pause::{Pallet, Storage, Call, Event}, } ); @@ -65,7 +66,7 @@ parameter_types! { } impl frame_system::Config for Test { - type BaseCallFilter = Everything; + type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); type DbWeight = (); @@ -251,6 +252,23 @@ impl pallet_asset_manager::Config for Test { type WeightInfo = (); } +pub struct MantaPaySuspensionManager; +impl crate::SuspendMantaPay for MantaPaySuspensionManager { + fn suspend_manta_pay_execution() { + let _ = TransactionPause::pause_transactions( + RawOrigin::Root.into(), + vec![( + b"MantaPay".to_vec(), + vec![ + b"to_private".to_vec(), + b"private_transfer".to_vec(), + b"to_public".to_vec(), + ], + )], + ); + } +} + parameter_types! { pub const MantaPayPalletId: PalletId = MANTA_PAY_PALLET_ID; } @@ -260,11 +278,27 @@ impl crate::Config for Test { type WeightInfo = crate::weights::SubstrateWeight; type PalletId = MantaPayPalletId; type AssetConfig = MantaAssetConfig; + type Suspender = MantaPaySuspensionManager; +} + +parameter_types! { + pub NonPausablePallets: Vec> = vec![b"Democracy".to_vec(), b"Balances".to_vec(), b"Council".to_vec(), b"CouncilCollective".to_vec(), b"TechnicalCommittee".to_vec(), b"TechnicalCollective".to_vec()]; +} + +impl pallet_tx_pause::Config for Test { + type Event = Event; + type Call = Call; + type MaxCallNames = ConstU32<25>; + type PauseOrigin = EnsureRoot; + type UnpauseOrigin = EnsureRoot; + type NonPausablePallets = IsInVec; + type WeightInfo = (); } pub fn new_test_ext() -> sp_io::TestExternalities { - frame_system::GenesisConfig::default() + let t = frame_system::GenesisConfig::default() .build_storage::() - .unwrap() - .into() + .unwrap(); + + t.into() } diff --git a/pallets/manta-pay/src/test/payment.rs b/pallets/manta-pay/src/test/payment.rs index affd2d42e..b54380543 100644 --- a/pallets/manta-pay/src/test/payment.rs +++ b/pallets/manta-pay/src/test/payment.rs @@ -17,16 +17,18 @@ use crate::{ fp_decode, mock::{ - new_test_ext, MantaAssetConfig, MantaAssetRegistry, MantaPayPallet, Origin as MockOrigin, - Test, + new_test_ext, MantaAssetConfig, MantaAssetRegistry, MantaPay, Origin as MockOrigin, Test, + TransactionPause, }, types::{fp_encode, AssetId, AssetValue, TransferPost as PalletTransferPost}, - Error, FungibleLedger, StandardAssetId, + Error, FungibleLedger, ReceiverLedgerError, StandardAssetId, TransferLedgerError, + TransferPostError, VerifyingContextError, }; use frame_support::{assert_noop, assert_ok}; +use frame_system::RawOrigin; use manta_accounting::transfer::test::value_distribution; use manta_crypto::{ - arkworks::constraint::fp::Fp, + arkworks::{constraint::fp::Fp, serialize::SerializationError}, merkle_tree::{forest::TreeArrayMerkleForest, full::Full}, rand::{CryptoRng, OsRng, Rand, RngCore}, }; @@ -35,9 +37,11 @@ use manta_pay::{ utxo::MerkleTreeConfiguration, ConstraintField, MultiProvingContext, Parameters, UtxoAccumulatorModel, }, + manta_accounting::transfer::receiver::ReceiverPostError, parameters::{self, load_transfer_parameters, load_utxo_accumulator_model}, test, }; + use manta_primitives::{ assets::{ AssetConfig, AssetRegistry, AssetRegistryMetadata, AssetStorageMetadata, @@ -90,7 +94,7 @@ where &PROVING_CONTEXT.to_private, &PARAMETERS, &mut utxo_accumulator, - MantaPayPallet::id_from_field(asset_id).unwrap().into(), + MantaPay::id_from_field(asset_id).unwrap().into(), value, rng, )) @@ -123,9 +127,9 @@ where R: CryptoRng + RngCore + ?Sized, { for value in values { - assert_ok!(MantaPayPallet::to_private( + assert_ok!(MantaPay::to_private( MockOrigin::signed(ALICE), - sample_to_private(MantaPayPallet::field_from_id(id), *value, rng) + sample_to_private(MantaPay::field_from_id(id), *value, rng) )); } } @@ -160,15 +164,15 @@ where [balance / 2, balance / 2], rng, ); - assert_ok!(MantaPayPallet::to_private( + assert_ok!(MantaPay::to_private( MockOrigin::signed(ALICE), PalletTransferPost::try_from(to_private_0).unwrap() )); - assert_ok!(MantaPayPallet::to_private( + assert_ok!(MantaPay::to_private( MockOrigin::signed(ALICE), PalletTransferPost::try_from(to_private_1).unwrap() )); - assert_ok!(MantaPayPallet::private_transfer( + assert_ok!(MantaPay::private_transfer( MockOrigin::signed(ALICE), PalletTransferPost::try_from(private_transfer.clone()).unwrap(), )); @@ -224,30 +228,30 @@ where rng, ); - assert_ok!(MantaPayPallet::to_private(MockOrigin::signed(ALICE), mint0)); + assert_ok!(MantaPay::to_private(MockOrigin::signed(ALICE), mint0)); - assert_ok!(MantaPayPallet::to_private( + assert_ok!(MantaPay::to_private( MockOrigin::signed(ALICE), PalletTransferPost::try_from(transfer_input_0).unwrap() )); - assert_ok!(MantaPayPallet::to_private( + assert_ok!(MantaPay::to_private( MockOrigin::signed(ALICE), PalletTransferPost::try_from(transfer_input_1).unwrap() )); - assert_ok!(MantaPayPallet::private_transfer( + assert_ok!(MantaPay::private_transfer( MockOrigin::signed(ALICE), PalletTransferPost::try_from(private_transfer.clone()).unwrap(), )); - assert_ok!(MantaPayPallet::to_private( + assert_ok!(MantaPay::to_private( MockOrigin::signed(ALICE), PalletTransferPost::try_from(to_public_input_0).unwrap() )); - assert_ok!(MantaPayPallet::to_private( + assert_ok!(MantaPay::to_private( MockOrigin::signed(ALICE), PalletTransferPost::try_from(to_public_input_1).unwrap() )); - assert_ok!(MantaPayPallet::to_public( + assert_ok!(MantaPay::to_public( MockOrigin::signed(ALICE), PalletTransferPost::try_from(to_public.clone()).unwrap() )); @@ -287,15 +291,15 @@ where [balance / 2, balance / 2], rng, ); - assert_ok!(MantaPayPallet::to_private( + assert_ok!(MantaPay::to_private( MockOrigin::signed(ALICE), PalletTransferPost::try_from(to_private_0).unwrap() )); - assert_ok!(MantaPayPallet::to_private( + assert_ok!(MantaPay::to_private( MockOrigin::signed(ALICE), PalletTransferPost::try_from(to_private_1).unwrap() )); - assert_ok!(MantaPayPallet::to_public( + assert_ok!(MantaPay::to_public( MockOrigin::signed(ALICE), PalletTransferPost::try_from(to_public.clone()).unwrap() )); @@ -326,7 +330,7 @@ fn initialize_test(id: StandardAssetId, value: AssetValue) { assert_ok!(FungibleLedger::::deposit_minting(id, &ALICE, value)); assert_ok!(FungibleLedger::::deposit_minting( id, - &MantaPayPallet::account_id(), + &MantaPay::account_id(), TEST_DEFAULT_ASSET_ED )); } @@ -358,9 +362,9 @@ fn to_private_with_zero_should_not_work() { let total_free_supply: AssetValue = rng.gen(); initialize_test(asset_id, total_free_supply + TEST_DEFAULT_ASSET_ED); assert_noop!( - MantaPayPallet::to_private( + MantaPay::to_private( MockOrigin::signed(ALICE), - sample_to_private(MantaPayPallet::field_from_id(asset_id), 0, &mut rng) + sample_to_private(MantaPay::field_from_id(asset_id), 0, &mut rng) ), Error::::ZeroTransfer ); @@ -376,7 +380,7 @@ fn to_public_with_zero_should_not_work() { let total_free_supply: AssetValue = rng.gen(); initialize_test(asset_id, total_free_supply + TEST_DEFAULT_ASSET_ED); assert_noop!( - MantaPayPallet::to_public( + MantaPay::to_public( MockOrigin::signed(ALICE), sample_to_public(asset_id, [0, 0], &mut rng) ), @@ -412,10 +416,10 @@ fn overdrawn_mint_should_not_work() { let total_supply: u128 = rng.gen(); initialize_test(asset_id, total_supply + TEST_DEFAULT_ASSET_ED); assert_noop!( - MantaPayPallet::to_private( + MantaPay::to_private( MockOrigin::signed(ALICE), sample_to_private( - MantaPayPallet::field_from_id(asset_id), + MantaPay::field_from_id(asset_id), total_supply + TEST_DEFAULT_ASSET_ED + 1, &mut rng ) @@ -433,9 +437,9 @@ fn to_private_without_init_should_not_work() { for _ in 0..RANDOMIZED_TESTS_ITERATIONS { new_test_ext().execute_with(|| { assert_noop!( - MantaPayPallet::to_private( + MantaPay::to_private( MockOrigin::signed(ALICE), - sample_to_private(MantaPayPallet::field_from_id(rng.gen()), 100, &mut rng) + sample_to_private(MantaPay::field_from_id(rng.gen()), 100, &mut rng) ), Error::::InvalidSourceAccount, ); @@ -451,14 +455,13 @@ fn mint_existing_coin_should_not_work() { new_test_ext().execute_with(|| { let asset_id = rng.gen(); initialize_test(asset_id, 32579u128); - let mint_post = - sample_to_private(MantaPayPallet::field_from_id(asset_id), 100, &mut rng); - assert_ok!(MantaPayPallet::to_private( + let mint_post = sample_to_private(MantaPay::field_from_id(asset_id), 100, &mut rng); + assert_ok!(MantaPay::to_private( MockOrigin::signed(ALICE), mint_post.clone() )); assert_noop!( - MantaPayPallet::to_private(MockOrigin::signed(ALICE), mint_post), + MantaPay::to_private(MockOrigin::signed(ALICE), mint_post), Error::::AssetRegistered ); }); @@ -498,7 +501,7 @@ fn double_spend_in_private_transfer_should_not_work() { new_test_ext().execute_with(|| { for private_transfer in private_transfer_test(10, None, &mut OsRng) { assert_noop!( - MantaPayPallet::private_transfer(MockOrigin::signed(ALICE), private_transfer), + MantaPay::private_transfer(MockOrigin::signed(ALICE), private_transfer), Error::::AssetSpent, ); } @@ -550,7 +553,7 @@ fn double_spend_in_reclaim_should_not_work() { let total_supply: u128 = rng.gen(); for reclaim in reclaim_test(10, total_supply / 2, None, &mut rng) { assert_noop!( - MantaPayPallet::to_public(MockOrigin::signed(ALICE), reclaim), + MantaPay::to_public(MockOrigin::signed(ALICE), reclaim), Error::::AssetSpent, ); } @@ -563,14 +566,14 @@ fn check_number_conversions() { let mut rng = OsRng; let start = rng.gen(); - let expected = MantaPayPallet::field_from_id(start); + let expected = MantaPay::field_from_id(start); let fp = Fp::::from(start); let encoded = fp_encode(fp).unwrap(); assert_eq!(expected, encoded); - let id_from_field = MantaPayPallet::id_from_field(encoded).unwrap(); + let id_from_field = MantaPay::id_from_field(encoded).unwrap(); let decoded: Fp = fp_decode(expected.to_vec()).unwrap(); assert_eq!(start, id_from_field); assert_eq!(fp, decoded); @@ -596,7 +599,7 @@ fn pull_ledger_diff_should_work() { let (max_receivers, max_senders) = (128, 128); let check_point = crate::Checkpoint::default(); let runtime_pull_response = - MantaPayPallet::pull_ledger_diff(check_point, max_receivers, max_senders); + MantaPay::pull_ledger_diff(check_point, max_receivers, max_senders); // ensure all Utxos have been returned. assert!(!runtime_pull_response.should_continue); @@ -616,3 +619,79 @@ fn pull_ledger_diff_should_work() { assert_eq!(runtime_pull_response.senders, decoded_senders); }); } + +fn assert_manta_pay_suspension() { + assert_eq!( + TransactionPause::paused_transactions((b"MantaPay".to_vec(), b"to_private".to_vec())), + Some(()) + ); + + assert_eq!( + TransactionPause::paused_transactions((b"MantaPay".to_vec(), b"private_transfer".to_vec())), + Some(()) + ); + + assert_eq!( + TransactionPause::paused_transactions((b"MantaPay".to_vec(), b"to_public".to_vec())), + Some(()) + ); + + let _ = TransactionPause::unpause_pallets(RawOrigin::Root.into(), vec![b"MantaPay".to_vec()]); +} + +#[test] +fn receiver_ledger_errors_should_shut_down() { + new_test_ext().execute_with(|| { + let _e = ReceiverPostError::from(ReceiverLedgerError::::ChecksumError); + assert_manta_pay_suspension(); + + let _e = ReceiverPostError::from(ReceiverLedgerError::::MerkleTreeCapacityError); + assert_manta_pay_suspension(); + + let _e = Error::::from(ReceiverPostError::UnexpectedError( + ReceiverLedgerError::::ChecksumError, + )); + assert_manta_pay_suspension(); + + let _e = Error::::from(ReceiverPostError::UnexpectedError( + ReceiverLedgerError::::MerkleTreeCapacityError, + )); + assert_manta_pay_suspension(); + }); +} +#[test] +fn transfer_ledger_errors_should_shut_down() { + new_test_ext().execute_with(|| { + let _e = TransferPostError::from(TransferLedgerError::::ChecksumError); + assert_manta_pay_suspension(); + + let _e = TransferPostError::from(TransferLedgerError::::VerifyingContextDecodeError( + VerifyingContextError::Decode(SerializationError::NotEnoughSpace), + )); + assert_manta_pay_suspension(); + + let _e = Error::::from(TransferPostError::::UnexpectedError( + TransferLedgerError::ChecksumError, + )); + assert_manta_pay_suspension(); + + let _e = Error::::from(TransferPostError::::UnexpectedError( + TransferLedgerError::::VerifyingContextDecodeError( + VerifyingContextError::Decode(SerializationError::NotEnoughSpace), + ), + )); + assert_manta_pay_suspension(); + + let _e = Error::::from(TransferPostError::::Receiver( + ReceiverPostError::UnexpectedError( + ReceiverLedgerError::::MerkleTreeCapacityError, + ), + )); + assert_manta_pay_suspension(); + + let _e = Error::::from(TransferPostError::::Receiver( + ReceiverPostError::UnexpectedError(ReceiverLedgerError::::ChecksumError), + )); + assert_manta_pay_suspension(); + }); +} diff --git a/runtime/calamari/src/assets_config.rs b/runtime/calamari/src/assets_config.rs index ce431a695..42cfce8e3 100644 --- a/runtime/calamari/src/assets_config.rs +++ b/runtime/calamari/src/assets_config.rs @@ -16,7 +16,7 @@ use super::{ weights, xcm_config::SelfReserve, AssetManager, Assets, Balances, Event, - NativeTokenExistentialDeposit, Origin, Runtime, + MantaPaySuspensionManager, NativeTokenExistentialDeposit, Origin, Runtime, }; use manta_primitives::{ @@ -174,4 +174,5 @@ impl pallet_manta_pay::Config for Runtime { type WeightInfo = weights::pallet_manta_pay::SubstrateWeight; type AssetConfig = CalamariAssetConfig; type PalletId = MantaPayPalletId; + type Suspender = MantaPaySuspensionManager; } diff --git a/runtime/calamari/src/lib.rs b/runtime/calamari/src/lib.rs index 26d996011..7c2a30bd9 100644 --- a/runtime/calamari/src/lib.rs +++ b/runtime/calamari/src/lib.rs @@ -24,7 +24,6 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -pub use frame_support::traits::Get; use manta_collator_selection::IdentityCollator; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; @@ -43,7 +42,7 @@ use sp_version::RuntimeVersion; use frame_support::{ construct_runtime, parameter_types, traits::{ - ConstU128, ConstU16, ConstU32, ConstU8, Contains, Currency, EitherOfDiverse, IsInVec, + ConstU128, ConstU16, ConstU32, ConstU8, Contains, Currency, EitherOfDiverse, Get, IsInVec, NeverEnsureOrigin, PrivilegeCmp, }, weights::{ConstantMultiplier, DispatchClass, Weight}, @@ -51,7 +50,7 @@ use frame_support::{ }; use frame_system::{ limits::{BlockLength, BlockWeights}, - EnsureRoot, + EnsureRoot, RawOrigin, }; use manta_primitives::{ constants::{time::*, RocksDbWeight, STAKING_PALLET_ID, TREASURY_PALLET_ID, WEIGHT_PER_SECOND}, @@ -1282,3 +1281,23 @@ cumulus_pallet_parachain_system::register_validate_block! { BlockExecutor = pallet_author_inherent::BlockExecutor::, CheckInherents = CheckInherents, } + +pub struct MantaPaySuspensionManager; +impl pallet_manta_pay::SuspendMantaPay for MantaPaySuspensionManager { + fn suspend_manta_pay_execution() { + match TransactionPause::pause_transactions( + RawOrigin::Root.into(), + vec![( + b"MantaPay".to_vec(), + vec![ + b"to_private".to_vec(), + b"private_transfer".to_vec(), + b"to_public".to_vec(), + ], + )], + ) { + Ok(_) => log::error!("MantaPay has been suspended due to an unexpected internal ledger error!"), + Err(tx_pause_error) => log::error!("MantaPay encountered an unexpected internal ledger error, but failed to be suspended with the following tx-pause error: {:?}!", tx_pause_error) + } + } +} diff --git a/runtime/calamari/tests/integrations_mock/integration_tests.rs b/runtime/calamari/tests/integrations_mock/integration_tests.rs index 0a6b7b3a9..d9fdeb85e 100644 --- a/runtime/calamari/tests/integrations_mock/integration_tests.rs +++ b/runtime/calamari/tests/integrations_mock/integration_tests.rs @@ -27,7 +27,7 @@ pub use calamari_runtime::{ fee::{FEES_PERCENTAGE_TO_AUTHOR, FEES_PERCENTAGE_TO_TREASURY}, xcm_config::{XcmExecutorConfig, XcmFeesAccount}, AssetManager, Assets, Authorship, Balances, CalamariVesting, Council, DefaultBlocksPerRound, - Democracy, EnactmentPeriod, Event, Get, LaunchPeriod, LeaveDelayRounds, + Democracy, EnactmentPeriod, Event, LaunchPeriod, LeaveDelayRounds, NativeTokenExistentialDeposit, Origin, ParachainStaking, Period, PolkadotXcm, Runtime, TechnicalCommittee, Timestamp, TransactionPause, Treasury, Utility, VotingPeriod, }; @@ -37,9 +37,10 @@ use frame_support::{ assert_err, assert_noop, assert_ok, codec::Encode, dispatch::Dispatchable, - traits::{tokens::ExistenceRequirement, PalletInfo, StorageInfo, StorageInfoTrait}, + traits::{tokens::ExistenceRequirement, Get, PalletInfo, StorageInfo, StorageInfoTrait}, StorageHasher, Twox128, }; + use manta_primitives::{ assets::{ AssetConfig, AssetLocation, AssetRegistryMetadata, AssetStorageMetadata, FungibleLedger, diff --git a/runtime/dolphin/src/assets_config.rs b/runtime/dolphin/src/assets_config.rs index ed8bcff57..6c3db96a6 100644 --- a/runtime/dolphin/src/assets_config.rs +++ b/runtime/dolphin/src/assets_config.rs @@ -184,4 +184,5 @@ impl pallet_manta_pay::Config for Runtime { type WeightInfo = weights::pallet_manta_pay::SubstrateWeight; type AssetConfig = DolphinAssetConfig; type PalletId = MantaPayPalletId; + type Suspender = (); }