Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pause Contract and Resume Contract #779

Merged
merged 14 commits into from
Jul 11, 2023
1 change: 1 addition & 0 deletions engine-standalone-storage/src/relayer_db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ mod test {
chain_id: aurora_engine_types::types::u256_to_arr(&1_313_161_555.into()),
owner_id: "aurora".parse().unwrap(),
upgrade_delay_blocks: 0,
is_paused: false,
};

// Initialize engine and connector states in storage.
Expand Down
16 changes: 16 additions & 0 deletions engine-standalone-storage/src/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,22 @@ fn non_submit_execute<'db, M: ModExpAlgorithm + 'static>(
prev.upgrade_delay_blocks = args.upgrade_delay_blocks;
state::set_state(&mut io, &prev)?;

None
}
TransactionKind::PauseContract => {
let mut prev = state::get_state(&io)?;

prev.is_paused = true;
state::set_state(&mut io, &prev)?;

None
}
TransactionKind::ResumeContract => {
let mut prev = state::get_state(&io)?;

prev.is_paused = false;
state::set_state(&mut io, &prev)?;

None
}
};
Expand Down
12 changes: 12 additions & 0 deletions engine-standalone-storage/src/sync/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ pub enum TransactionKind {
FactoryUpdateAddressVersion(AddressVersionUpdateArgs),
FactorySetWNearAddress(Address),
FundXccSubAccound(FundXccArgs),
/// Pause the contract
PauseContract,
/// Resume the contract
ResumeContract,
/// Sentinel kind for cases where a NEAR receipt caused a
/// change in Aurora state, but we failed to parse the Action.
Unknown,
Expand Down Expand Up @@ -354,6 +358,8 @@ impl TransactionKind {
Self::SetOwner(_) => Self::no_evm_execution("set_owner"),
Self::SetUpgradeDelayBlocks(_) => Self::no_evm_execution("set_upgrade_delay_blocks"),
Self::FundXccSubAccound(_) => Self::no_evm_execution("fund_xcc_sub_account"),
Self::PauseContract => Self::no_evm_execution("pause_contract"),
Self::ResumeContract => Self::no_evm_execution("resume_contract"),
}
}

Expand Down Expand Up @@ -523,6 +529,8 @@ enum BorshableTransactionKind<'a> {
SubmitWithArgs(Cow<'a, parameters::SubmitArgs>),
FundXccSubAccound(Cow<'a, FundXccArgs>),
SetUpgradeDelayBlocks(Cow<'a, parameters::SetUpgradeDelayBlocksArgs>),
PauseContract,
ResumeContract,
}

impl<'a> From<&'a TransactionKind> for BorshableTransactionKind<'a> {
Expand Down Expand Up @@ -569,6 +577,8 @@ impl<'a> From<&'a TransactionKind> for BorshableTransactionKind<'a> {
TransactionKind::SetUpgradeDelayBlocks(x) => {
Self::SetUpgradeDelayBlocks(Cow::Borrowed(x))
}
TransactionKind::PauseContract => Self::PauseContract,
TransactionKind::ResumeContract => Self::ResumeContract,
}
}
}
Expand Down Expand Up @@ -634,6 +644,8 @@ impl<'a> TryFrom<BorshableTransactionKind<'a>> for TransactionKind {
BorshableTransactionKind::SetUpgradeDelayBlocks(x) => {
Ok(Self::SetUpgradeDelayBlocks(x.into_owned()))
}
BorshableTransactionKind::PauseContract => Ok(Self::PauseContract),
BorshableTransactionKind::ResumeContract => Ok(Self::ResumeContract),
}
}
}
4 changes: 4 additions & 0 deletions engine-tests/src/test_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub const PAUSED_PRECOMPILES: &str = "paused_precompiles";
pub const RESUME_PRECOMPILES: &str = "resume_precompiles";
pub const SET_OWNER: &str = "set_owner";
pub const SET_UPGRADE_DELAY_BLOCKS: &str = "set_upgrade_delay_blocks";
pub const PAUSE_CONTRACT: &str = "pause_contract";
pub const RESUME_CONTRACT: &str = "resume_contract";

const CALLER_ACCOUNT_ID: &str = "some-account.near";

Expand Down Expand Up @@ -245,6 +247,8 @@ impl AuroraRunner {
|| method_name == RESUME_PRECOMPILES
|| method_name == SET_OWNER
|| method_name == SET_UPGRADE_DELAY_BLOCKS
|| method_name == PAUSE_CONTRACT
|| method_name == RESUME_CONTRACT
{
standalone_runner.submit_raw(method_name, &self.context, &self.promise_results)?;
self.validate_standalone();
Expand Down
32 changes: 32 additions & 0 deletions engine-tests/src/test_utils/standalone/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,38 @@ impl StandaloneRunner {
self.cumulative_diff.append(outcome.diff.clone());
storage::commit(storage, &outcome);

Ok(SubmitResult::new(
TransactionStatus::Succeed(Vec::new()),
0,
Vec::new(),
))
} else if method_name == test_utils::PAUSE_CONTRACT {
let transaction_hash = aurora_engine_sdk::keccak(&ctx.input);
let mut tx_msg =
Self::template_tx_msg(storage, &env, 0, transaction_hash, promise_results);
tx_msg.transaction = TransactionKind::PauseContract;

let outcome =
sync::execute_transaction_message::<AuroraModExp>(storage, tx_msg).unwrap();
self.cumulative_diff.append(outcome.diff.clone());
storage::commit(storage, &outcome);

Ok(SubmitResult::new(
TransactionStatus::Succeed(Vec::new()),
0,
Vec::new(),
))
} else if method_name == test_utils::RESUME_CONTRACT {
let transaction_hash = aurora_engine_sdk::keccak(&ctx.input);
let mut tx_msg =
Self::template_tx_msg(storage, &env, 0, transaction_hash, promise_results);
tx_msg.transaction = TransactionKind::ResumeContract;

let outcome =
sync::execute_transaction_message::<AuroraModExp>(storage, tx_msg).unwrap();
self.cumulative_diff.append(outcome.diff.clone());
storage::commit(storage, &outcome);

Ok(SubmitResult::new(
TransactionStatus::Succeed(Vec::new()),
0,
Expand Down
1 change: 1 addition & 0 deletions engine-tests/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod modexp;
mod multisender;
mod one_inch;
mod pausable_precompiles;
mod pause_contract;
mod prepaid_gas_precompile;
mod promise_results_precompile;
mod random;
Expand Down
118 changes: 118 additions & 0 deletions engine-tests/src/tests/pause_contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
use crate::test_utils;
use aurora_engine::parameters::SetUpgradeDelayBlocksArgs;
use borsh::BorshSerialize;

#[test]
fn test_pause_contract_require_owner() {
let mut runner = test_utils::deploy_evm();
let aurora_account_id = runner.aurora_account_id.clone();
aleksuss marked this conversation as resolved.
Show resolved Hide resolved

let result = runner.call("pause_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());

let result = runner.call("resume_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());

let result = runner.call("pause_contract", "new_owner.near", vec![]);
assert!(result.is_err());
}

#[test]
fn test_resume_contract_require_owner() {
let mut runner = test_utils::deploy_evm();
let aurora_account_id = runner.aurora_account_id.clone();

let result = runner.call("pause_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());

let result = runner.call("resume_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());

let result = runner.call("pause_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());

let result = runner.call("resume_contract", "new_owner.near", vec![]);
assert!(result.is_err());
}
Casuso marked this conversation as resolved.
Show resolved Hide resolved

#[test]
fn test_pause_contract_require_running() {
let mut runner = test_utils::deploy_evm();
let aurora_account_id = runner.aurora_account_id.clone();

let result = runner.call("pause_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());

let result = runner.call("pause_contract", &aurora_account_id, vec![]);
assert!(result.is_err());
}

#[test]
fn test_resume_contract_require_paused() {
let mut runner = test_utils::deploy_evm();
let aurora_account_id = runner.aurora_account_id.clone();

let result = runner.call("resume_contract", &aurora_account_id, vec![]);
assert!(result.is_err());

let result = runner.call("pause_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());

let result = runner.call("resume_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());
}

#[test]
fn test_pause_contract() {
let mut runner = test_utils::deploy_evm();
let aurora_account_id = runner.aurora_account_id.clone();
let set = SetUpgradeDelayBlocksArgs {
upgrade_delay_blocks: 2,
}
.try_to_vec()
.unwrap();

// contract is running by default, gets and sets should work
let result = runner.call("get_upgrade_delay_blocks", &aurora_account_id, vec![]);
assert!(result.is_ok());

let result = runner.call("set_upgrade_delay_blocks", &aurora_account_id, set.clone());
assert!(result.is_ok());

// pause contract
let result = runner.call("pause_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());

// contract is paused, gets should still work but sets should fail
let result = runner.call("get_upgrade_delay_blocks", &aurora_account_id, vec![]);
assert!(result.is_ok());

let result = runner.call("set_upgrade_delay_blocks", &aurora_account_id, set);
assert!(result.is_err());
}

#[test]
fn test_resume_contract() {
let mut runner = test_utils::deploy_evm();
let aurora_account_id = runner.aurora_account_id.clone();
let set = SetUpgradeDelayBlocksArgs {
upgrade_delay_blocks: 2,
}
.try_to_vec()
.unwrap();

// pause contract
let result = runner.call("pause_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());

// resume contract
let result = runner.call("resume_contract", &aurora_account_id, vec![]);
assert!(result.is_ok());

// contract is running again, gets and sets should work
let result = runner.call("get_upgrade_delay_blocks", &aurora_account_id, vec![]);
assert!(result.is_ok());

let result = runner.call("set_upgrade_delay_blocks", &aurora_account_id, set);
assert!(result.is_ok());
}
4 changes: 2 additions & 2 deletions engine-tests/src/tests/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ fn test_state_format() {
};
let state: aurora_engine::state::EngineState = args.into();
let expected_hex: String = [
"01000000000000000000000000000000000000000000000000000000000000029a",
"02000000000000000000000000000000000000000000000000000000000000029a",
"04000000626f7373",
"0300000000000000",
"030000000000000000",
]
.concat();
assert_eq!(hex::encode(state.borsh_serialize().unwrap()), expected_hex);
Expand Down
1 change: 1 addition & 0 deletions engine-tests/src/tests/standalone/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ fn test_deploy_code() {
chain_id,
owner_id: owner_id.clone(),
upgrade_delay_blocks: 0,
is_paused: false,
};
let origin = Address::new(H160([0u8; 20]));
let storage = RefCell::new(Storage::default());
Expand Down
2 changes: 2 additions & 0 deletions engine/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub const ERR_VERIFY_PROOF: &[u8; 16] = b"ERR_VERIFY_PROOF";
pub const ERR_INVALID_UPGRADE: &[u8; 19] = b"ERR_INVALID_UPGRADE";
pub const ERR_NO_UPGRADE: &[u8; 14] = b"ERR_NO_UPGRADE";
pub const ERR_NOT_ALLOWED: &[u8; 15] = b"ERR_NOT_ALLOWED";
pub const ERR_PAUSED: &[u8; 10] = b"ERR_PAUSED";
pub const ERR_RUNNING: &[u8; 11] = b"ERR_RUNNING";

pub const ERR_SERIALIZE: &str = "ERR_SERIALIZE";
pub const ERR_PROMISE_ENCODING: &str = "ERR_PROMISE_ENCODING";
Expand Down
Loading
Loading