Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
Halting & resuming bridge pallets (paritytech#883)
Browse files Browse the repository at this point in the history
* Halting & resuming bridge pallets

* Ignore .env

* Remove .env

* Some polish

* Set owner of bridge pallets

* Update cumulus

* Relax RANDAO_COMMIT_DELAY for local setup

* Update cumulus

* Update cumulus

* Fix test
  • Loading branch information
yrong authored Jul 19, 2023
1 parent 5e25cd0 commit 4950e80
Show file tree
Hide file tree
Showing 18 changed files with 252 additions and 38 deletions.
1 change: 1 addition & 0 deletions core/packages/test/.envrc-example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ source_up_if_exists
# export BEEFY_START_BLOCK= # Start block to configure beefy client, default value: 1
# export RELAYCHAIN_ENDPOINT= # Relaychain endpoint, default value: ws://localhost:9944
# export PARACHAIN_RUNTIME= # Runtime type of parachain should be one of snowbase|snowblink|snowbridge
# export BRIDGEHUB_PALLETS_OWNER= # Pubkey of bridge owner which can be used to halt/resume the bridge pallets


## Eth config for production
Expand Down
1 change: 1 addition & 0 deletions core/packages/test/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ rococo-local.json
.pnp.*
ethereum-goerli
testdata
.env
27 changes: 26 additions & 1 deletion core/packages/test/scripts/configure-bridgehub.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,31 @@ config_inbound_queue()
local pallet="30"
local callindex="01"
local payload="0x$pallet$callindex$(address_for OutboundQueue | cut -c3-)"
send_governance_transact_from_relaychain $bridgehub_para_id "$payload" 180000000000 900000
send_governance_transact_from_relaychain $bridgehub_para_id "$payload"
}

config_pallet_owner()
{
local owner=$(echo $bridgehub_pallets_owner | cut -c3-)
local option="01"

# config owner of inbound queue
local pallet="30"
local callindex="03"
local payload="0x$pallet$callindex$option$owner"
send_governance_transact_from_relaychain $bridgehub_para_id "$payload"

# config owner of outbound queue
local pallet="31"
local callindex="00"
local payload="0x$pallet$callindex$option$owner"
send_governance_transact_from_relaychain $bridgehub_para_id "$payload"

# config owner of beacon client owner
local pallet="32"
local callindex="03"
local payload="0x$pallet$callindex$option$owner"
send_governance_transact_from_relaychain $bridgehub_para_id "$payload"
}

wait_beacon_chain_ready()
Expand Down Expand Up @@ -45,6 +69,7 @@ configure_bridgehub()
{
fund_accounts
config_inbound_queue
config_pallet_owner
wait_beacon_chain_ready
config_beacon_checkpoint
}
Expand Down
3 changes: 2 additions & 1 deletion core/packages/test/scripts/set-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ beacon_endpoint_http="${BEACON_HTTP_ENDPOINT:-http://127.0.0.1:9596}"
bridgehub_ws_url="${BRIDGEHUB_WS_URL:-ws://127.0.0.1:11144}"
bridgehub_para_id="${BRIDGEHUB_PARA_ID:-1013}"
bridgehub_seed="${BRIDGEHUB_SEED:-//Alice}"
bridgehub_pallets_owner="${BRIDGEHUB_PALLETS_OWNER:-0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d}"

statemine_ws_url="${STATEMINE_WS_URL:-ws://127.0.0.1:12144}"
statemine_para_id="${STATEMINE_PARA_ID:-1000}"
Expand Down Expand Up @@ -77,7 +78,7 @@ export PRIVATE_KEY="${DEPLOYER_ETH_KEY:-0x4e9444a6efd6d42725a250b650a781da2737ea
# but for rococo-local each session is only 20 slots=120s
# so relax somehow here just for quick test
# for production deployment ETH_RANDAO_DELAY should be configured in a more reasonable sense
export RANDAO_COMMIT_DELAY="${ETH_RANDAO_DELAY:-6}"
export RANDAO_COMMIT_DELAY="${ETH_RANDAO_DELAY:-3}"
export RANDAO_COMMIT_EXP="${ETH_RANDAO_EXP:-3}"

## ParachainClient
Expand Down
10 changes: 8 additions & 2 deletions core/packages/test/scripts/xcm-helper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ source scripts/set-env.sh
send_governance_transact_from_relaychain() {
local para_id=$1
local hex_encoded_data=$2
local require_weight_at_most_ref_time=$3
local require_weight_at_most_proof_size=$4
local require_weight_at_most_ref_time=$(echo "$3")
local require_weight_at_most_proof_size=$(echo "$4")
if [ -z "${require_weight_at_most_ref_time}" ]; then
require_weight_at_most_ref_time=200000000
fi
if [ -z "${require_weight_at_most_proof_size}" ]; then
require_weight_at_most_proof_size=12000
fi
echo " calling send_governance_transact:"
echo " relay_url: ${relaychain_ws_url}"
echo " relay_chain_seed: ${relaychain_sudo_seed}"
Expand Down
25 changes: 25 additions & 0 deletions parachain/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions parachain/pallets/control/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ mod benchmarks {

#[benchmark]
fn upgrade() -> Result<(), BenchmarkError> {
let caller: T::AccountId = whitelisted_caller();
let upgrade_task = H160::repeat_byte(3);

#[extrinsic_call]
_(RawOrigin::Signed(caller), upgrade_task);
_(RawOrigin::Root, upgrade_task);

Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion parachain/pallets/control/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub mod pallet {
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::upgrade())]
pub fn upgrade(origin: OriginFor<T>, upgrade_task: H160) -> DispatchResult {
let _ = ensure_signed(origin)?;
ensure_root(origin)?;

let message = OutboundMessage {
id: T::MessageHasher::hash(upgrade_task.as_ref()),
Expand Down
2 changes: 2 additions & 0 deletions parachain/pallets/ethereum-beacon-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ snowbridge-core = { path = "../../primitives/core", default-features = false }
snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false }
primitives = { package = "snowbridge-beacon-primitives", path = "../../primitives/beacon", default-features = false }
static_assertions = { version = "1.1.0" }
bp-runtime = { git = "https://github.com/Snowfork/cumulus.git", branch = "snowbridge", default-features = false }

[dev-dependencies]
rand = "0.8.5"
Expand Down Expand Up @@ -58,6 +59,7 @@ std = [
"primitives/std",
"ssz_rs/std",
"byte-slice-cast/std",
"bp-runtime/std",
]
runtime-benchmarks = [
"beacon-spec-mainnet",
Expand Down
55 changes: 51 additions & 4 deletions parachain/pallets/ethereum-beacon-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,17 @@ pub use pallet::*;

pub use config::SLOTS_PER_HISTORICAL_ROOT;

pub const LOG_TARGET: &str = "ethereum-beacon-client";

#[frame_support::pallet]
pub mod pallet {
use super::*;

use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;

use bp_runtime::{BasicOperatingMode, OwnedBridgeModule};

#[derive(scale_info::TypeInfo, codec::Encode, codec::Decode, codec::MaxEncodedLen)]
#[codec(mel_bound(T: Config))]
#[scale_info(skip_type_params(T))]
Expand Down Expand Up @@ -90,7 +94,6 @@ pub mod pallet {
}

#[pallet::error]
#[cfg_attr(test, derive(PartialEq))]
pub enum Error<T> {
SkippedSyncCommitteePeriod,
/// Attested header is older than latest finalized header.
Expand Down Expand Up @@ -119,6 +122,7 @@ pub mod pallet {
InvalidSyncCommitteeUpdate,
ExecutionHeaderTooFarBehind,
ExecutionHeaderSkippedSlot,
BridgeModule(bp_runtime::OwnedBridgeModuleError),
}

/// Latest imported checkpoint root
Expand Down Expand Up @@ -179,6 +183,28 @@ pub mod pallet {
#[pallet::storage]
pub type ExecutionHeaderMapping<T: Config> = StorageMap<_, Identity, u32, H256, ValueQuery>;

/// Optional pallet owner.
///
/// Pallet owner has a right to halt all pallet operations and then resume them. If it is
/// `None`, then there are no direct ways to halt/resume pallet operations, but other
/// runtime methods may still be used to do that (i.e. democracy::referendum to update halt
/// flag directly or call the `halt_operations`).
#[pallet::storage]
pub type PalletOwner<T: Config> = StorageValue<_, T::AccountId, OptionQuery>;

/// The current operating mode of the pallet.
///
/// Depending on the mode either all, or no transactions will be allowed.
#[pallet::storage]
pub type PalletOperatingMode<T: Config> = StorageValue<_, BasicOperatingMode, ValueQuery>;

impl<T: Config> OwnedBridgeModule<T> for Pallet<T> {
const LOG_TARGET: &'static str = LOG_TARGET;
type OwnerStorage = PalletOwner<T>;
type OperatingMode = BasicOperatingMode;
type OperatingModeStorage = PalletOperatingMode<T>;
}

#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
Expand All @@ -203,6 +229,7 @@ pub mod pallet {
/// Submits a new finalized beacon header update. The update may contain the next
/// sync committee.
pub fn submit(origin: OriginFor<T>, update: Update) -> DispatchResult {
Self::ensure_not_halted().map_err(Error::<T>::BridgeModule)?;
ensure_signed(origin)?;
Self::process_update(&update)?;
Ok(())
Expand All @@ -217,10 +244,30 @@ pub mod pallet {
origin: OriginFor<T>,
update: ExecutionHeaderUpdate,
) -> DispatchResult {
Self::ensure_not_halted().map_err(Error::<T>::BridgeModule)?;
ensure_signed(origin)?;
Self::process_execution_header_update(&update)?;
Ok(())
}

/// Change `PalletOwner`.
/// May only be called either by root, or by `PalletOwner`.
#[pallet::call_index(3)]
#[pallet::weight((T::DbWeight::get().reads_writes(1, 1), DispatchClass::Operational))]
pub fn set_owner(origin: OriginFor<T>, new_owner: Option<T::AccountId>) -> DispatchResult {
<Self as OwnedBridgeModule<_>>::set_owner(origin, new_owner)
}

/// Halt or resume all pallet operations.
/// May only be called either by root, or by `PalletOwner`.
#[pallet::call_index(4)]
#[pallet::weight((T::DbWeight::get().reads_writes(1, 1), DispatchClass::Operational))]
pub fn set_operating_mode(
origin: OriginFor<T>,
operating_mode: BasicOperatingMode,
) -> DispatchResult {
<Self as OwnedBridgeModule<_>>::set_operating_mode(origin, operating_mode)
}
}

impl<T: Config> Pallet<T> {
Expand Down Expand Up @@ -459,7 +506,7 @@ pub mod pallet {
<NextSyncCommittee<T>>::set(sync_committee_prepared);
}
log::info!(
target: "ethereum-beacon-client",
target: LOG_TARGET,
"💫 SyncCommitteeUpdated at period {}.",
update_finalized_period
);
Expand Down Expand Up @@ -628,7 +675,7 @@ pub mod pallet {
<LatestFinalizedBlockRoot<T>>::set(header_root);

log::info!(
target: "ethereum-beacon-client",
target: LOG_TARGET,
"💫 Updated latest finalized block root {} at slot {}.",
header_root,
slot
Expand All @@ -653,7 +700,7 @@ pub mod pallet {
<ExecutionHeaderBuffer<T>>::insert(block_hash, header);

log::trace!(
target: "ethereum-beacon-client",
target: LOG_TARGET,
"💫 Updated latest execution block at {} to number {}.",
block_hash,
block_number
Expand Down
2 changes: 2 additions & 0 deletions parachain/pallets/inbound-queue/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "master"
sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "master", default-features = false }

xcm = { git = "https://github.com/paritytech/polkadot.git", branch = "master", default-features = false }
bp-runtime = { git = "https://github.com/Snowfork/cumulus.git", branch = "snowbridge", default-features = false }

snowbridge-core = { path = "../../primitives/core", default-features = false }
snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false }
Expand Down Expand Up @@ -60,6 +61,7 @@ std = [
"snowbridge-router-primitives/std",
"ethabi/std",
"xcm/std",
"bp-runtime/std",
"snowbridge-beacon-primitives/std",
"snowbridge-ethereum-beacon-client/std",
]
Expand Down
2 changes: 1 addition & 1 deletion parachain/pallets/inbound-queue/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ mod benchmarks {

impl_benchmark_test_suite!(
InboundQueue,
crate::test::new_tester(crate::H160::default()),
crate::test::new_tester::<crate::test::Test>(crate::H160::default()),
crate::test::Test
);

Expand Down
Loading

0 comments on commit 4950e80

Please sign in to comment.