Skip to content

Commit

Permalink
Testing the upgrade process (#910)
Browse files Browse the repository at this point in the history
* upgrade tests

* updated weights

* Mock upgrade contract

* add smoketest for upgrade

* remove verbose print

* added smoketest

* updated error logging

* fixes

* better messages

* typos

* update readme

* moved file

* ws

* update paths

* update cumulus
  • Loading branch information
alistair-singh authored Jul 30, 2023
1 parent be0ff69 commit 0cef959
Show file tree
Hide file tree
Showing 14 changed files with 597 additions and 528 deletions.
3 changes: 3 additions & 0 deletions contracts/src/DeployScript.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {BeefyClient} from "./BeefyClient.sol";
import {IGateway} from "./interfaces/IGateway.sol";
import {GatewayProxy} from "./GatewayProxy.sol";
import {Gateway} from "./Gateway.sol";
import {GatewayUpgradeMock} from "../test/mocks/GatewayUpgradeMock.sol";
import {Agent} from "./Agent.sol";
import {AgentExecutor} from "./AgentExecutor.sol";
import {ParaID, Config} from "./Types.sol";
Expand Down Expand Up @@ -79,6 +80,8 @@ contract DeployScript is Script {
payable(bridgeHubAgent).safeNativeTransfer(initialDeposit);
payable(assetHubAgent).safeNativeTransfer(initialDeposit);

new GatewayUpgradeMock();

vm.stopBroadcast();
}
}
2 changes: 1 addition & 1 deletion contracts/src/Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ contract Gateway is IGateway, IInitializable {
}

// Increment nonce for origin.
// This also prevents the re-entrancy case in which a malicous party tries to re-enter by calling `submitInbound`
// This also prevents the re-entrancy case in which a malicious party tries to re-enter by calling `submitInbound`
// again with the same (message, leafProof, headerProof) arguments.
channel.inboundNonce++;

Expand Down
52 changes: 52 additions & 0 deletions contracts/test/mocks/GatewayUpgradeMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 Snowfork <[email protected]>
pragma solidity 0.8.20;

import {Channel, InboundMessage, OperatingMode, ParaID, Config, Command} from "../../src/Types.sol";
import {IGateway} from "../../src/interfaces/IGateway.sol";
import {IInitializable} from "../../src/interfaces/IInitializable.sol";
import {Verification} from "../../src/Verification.sol";

contract GatewayUpgradeMock is IGateway, IInitializable {
/**
* Getters
*/

function operatingMode() external pure returns (OperatingMode) {
return OperatingMode.Normal;
}

function channelOperatingModeOf(ParaID) external pure returns (OperatingMode) {
return OperatingMode.Normal;
}

function channelFeeRewardOf(ParaID) external pure returns (uint256, uint256) {
return (0, 0);
}

function channelNoncesOf(ParaID) external pure returns (uint64, uint64) {
return (0, 0);
}

function agentOf(bytes32) external pure returns (address) {
return address(0);
}

function implementation() external pure returns (address) {
return address(0);
}

function submitInbound(InboundMessage calldata, bytes32[] calldata, Verification.Proof calldata) external {}

function registerToken(address) external payable {}
function sendToken(address, ParaID, bytes32, uint128) external payable {}
function sendToken(address, ParaID, address, uint128) external payable {}

event Initialized(uint256 d0, uint256 d1);

function initialize(bytes memory data) external {
// Just decode and exit
(uint256 d0, uint256 d1) = abi.decode(data, (uint256, uint256));
emit Initialized(d0, d1);
}
}
71 changes: 71 additions & 0 deletions parachain/pallets/control/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,74 @@ fn create_agent_with_sibling_chain_account20_origin_yields_success() {
}));
});
}

#[test]
fn create_agent_without_root_yields_bad_origin() {
new_test_ext().execute_with(|| {
let origin = RuntimeOrigin::signed(AccountId32::new([0; 32]));
let address: H160 = Default::default();
let code_hash: H256 = Default::default();
let params: Option<Vec<u8>> = None;

frame_support::assert_noop!(
EthereumControl::upgrade(origin, address, code_hash, params),
BadOrigin
);
});
}

#[test]
fn create_agent_with_root_yields_success() {
new_test_ext().execute_with(|| {
let origin = RuntimeOrigin::root();
let address: H160 = Default::default();
let code_hash: H256 = Default::default();
let params: Option<Vec<u8>> = None;
let expected_hash = None;

frame_support::assert_ok!(EthereumControl::upgrade(origin, address, code_hash, params));

System::assert_last_event(RuntimeEvent::EthereumControl(crate::Event::Upgrade {
impl_address: address,
impl_code_hash: code_hash,
params_hash: expected_hash,
}));
});
}

#[test]
fn create_agent_with_large_params_yields_upgrade_too_large() {
new_test_ext().execute_with(|| {
const MAX_SIZE: usize = MaxUpgradeDataSize::get() as usize;
let origin = RuntimeOrigin::root();
let address: H160 = Default::default();
let code_hash: H256 = Default::default();
let params: Option<Vec<u8>> = Some([0; MAX_SIZE].into());

frame_support::assert_noop!(
EthereumControl::upgrade(origin, address, code_hash, params),
Error::<Test>::UpgradeDataTooLarge
);
});
}

#[test]
fn create_agent_with_small_params_yields_success() {
new_test_ext().execute_with(|| {
const MAX_SIZE_LESS_ONE: usize = (MaxUpgradeDataSize::get() - 1) as usize;
let origin = RuntimeOrigin::root();
let address: H160 = Default::default();
let code_hash: H256 = Default::default();
let params: Option<Vec<u8>> = Some([0; MAX_SIZE_LESS_ONE].into());
let expected_hash =
Some(H256(hex!("c95ef6b0bf891c06e1318f07b86977998674a0ae996999915c1f5d93359e72a9")));

frame_support::assert_ok!(EthereumControl::upgrade(origin, address, code_hash, params));

System::assert_last_event(RuntimeEvent::EthereumControl(crate::Event::Upgrade {
impl_address: address,
impl_code_hash: code_hash,
params_hash: expected_hash,
}));
});
}
30 changes: 20 additions & 10 deletions parachain/pallets/control/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,34 @@ pub trait WeightInfo {
/// Weights for pallet_template using the Substrate node and recommended hardware.
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
fn upgrade(_data_size: u32) -> Weight {
Weight::from_parts(9_000_000, 0)
.saturating_add(T::DbWeight::get().writes(1_u64))
fn upgrade(data_size: u32) -> Weight {
Weight::from_parts(30_740_411, 0)
.saturating_add(Weight::from_parts(0, 3517))
.saturating_add(Weight::from_parts(8_805, 0).saturating_mul(data_size.into()))
.saturating_add(T::DbWeight::get().reads(4))
.saturating_add(T::DbWeight::get().writes(3))
}
fn create_agent() -> Weight {
Weight::from_parts(9_000_000, 0)
.saturating_add(T::DbWeight::get().writes(1_u64))
Weight::from_parts(35_000_000, 0)
.saturating_add(Weight::from_parts(0, 3517))
.saturating_add(T::DbWeight::get().reads(5))
.saturating_add(T::DbWeight::get().writes(4))
}
}

// For backwards compatibility and tests
impl WeightInfo for () {
fn upgrade(_data_size: u32) -> Weight {
Weight::from_parts(9_000_000, 0)
.saturating_add(RocksDbWeight::get().writes(1_u64))
fn upgrade(data_size: u32) -> Weight {
Weight::from_parts(30_740_411, 0)
.saturating_add(Weight::from_parts(0, 3517))
.saturating_add(Weight::from_parts(8_805, 0).saturating_mul(data_size.into()))
.saturating_add(RocksDbWeight::get().reads(4))
.saturating_add(RocksDbWeight::get().writes(3))
}
fn create_agent() -> Weight {
Weight::from_parts(9_000_000, 0)
.saturating_add(RocksDbWeight::get().writes(1_u64))
Weight::from_parts(35_000_000, 0)
.saturating_add(Weight::from_parts(0, 3517))
.saturating_add(RocksDbWeight::get().reads(5))
.saturating_add(RocksDbWeight::get().writes(4))
}
}
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 @@ -39,7 +39,7 @@ mod benchmarks {

// Make sure the sovereign balance is enough. This is a funny number, because
// in some cases the minimum balance is really high, in other cases very low.
// e.g. on bridgehub the minium balance is 33333, on test it is 1. So this equation makes
// e.g. on bridgehub the minimum balance is 33333, on test it is 1. So this equation makes
// it is at least twice the minimum balance (so as to satisfy the minimum balance
// requirement, and then some (in case the minimum balance is very low, even lower
// than the relayer reward fee).
Expand Down
2 changes: 2 additions & 0 deletions smoketest/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@
.local

src/parachains/bridgehub.rs
src/parachains/assethub.rs
src/parachains/relaychain.rs
src/contracts
Loading

0 comments on commit 0cef959

Please sign in to comment.