Return error for pox3 calls in Epoch 2.5

This commit is contained in:
Jeff Bencin
2023-12-11 18:24:39 -05:00
committed by jbencin
parent 2d3fbc8425
commit 7fb7a07884
3 changed files with 72 additions and 4 deletions

View File

@@ -107,6 +107,20 @@ pub fn handle_contract_call_special_cases(
result,
);
} else if *contract_id == boot_code_id(POX_3_NAME, global_context.mainnet) {
if !pox_3::is_read_only(function_name) && global_context.epoch_id >= StacksEpochId::Epoch25
{
warn!("PoX-3 function call attempted on an account after Epoch 2.5";
"v3_unlock_ht" => global_context.database.get_v3_unlock_height(),
"current_burn_ht" => global_context.database.get_current_burnchain_block_height(),
"function_name" => function_name,
"contract_id" => %contract_id
);
return Err(ClarityError::Runtime(
RuntimeErrorType::DefunctPoxContract,
None,
));
}
return pox_3::handle_contract_call(
global_context,
sender,

View File

@@ -33,6 +33,33 @@ use crate::{LockingError, POX_3_NAME};
/////////////////////// PoX-3 /////////////////////////////////
/// is a PoX-3 function call read only?
pub(crate) fn is_read_only(func_name: &str) -> bool {
"get-pox-rejection" == func_name
|| "is-pox-active" == func_name
|| "burn-height-to-reward-cycle" == func_name
|| "reward-cycle-to-burn-height" == func_name
|| "current-pox-reward-cycle" == func_name
|| "get-stacker-info" == func_name
|| "get-check-delegation" == func_name
|| "get-reward-set-size" == func_name
|| "next-cycle-rejection-votes" == func_name
|| "get-total-ustx-stacked" == func_name
|| "get-reward-set-pox-address" == func_name
|| "get-stacking-minimum" == func_name
|| "check-pox-addr-version" == func_name
|| "check-pox-addr-hashbytes" == func_name
|| "check-pox-lock-period" == func_name
|| "can-stack-stx" == func_name
|| "minimal-can-stack-stx" == func_name
|| "get-pox-info" == func_name
|| "get-delegation-info" == func_name
|| "get-allowance-contract-callers" == func_name
|| "get-num-reward-set-pox-addresses" == func_name
|| "get-partial-stacked-by-cycle" == func_name
|| "get-total-pox-rejection" == func_name
}
/// Lock up STX for PoX for a time. Does NOT touch the account nonce.
pub fn pox_lock_v3(
db: &mut ClarityDatabase,

View File

@@ -899,8 +899,14 @@ fn pox_3_defunct() {
);
burnchain.pox_constants = pox_constants.clone();
let (mut peer, keys) =
instantiate_pox_peer_with_epoch(&burnchain, function_name!(), Some(epochs.clone()), None);
let observer = TestEventObserver::new();
let (mut peer, keys) = instantiate_pox_peer_with_epoch(
&burnchain,
function_name!(),
Some(epochs.clone()),
Some(&observer),
);
assert_eq!(burnchain.pox_constants.reward_slots(), 6);
let mut coinbase_nonce = 0;
@@ -949,6 +955,28 @@ fn pox_3_defunct() {
info!("Submitting stacking txs with pox3");
latest_block = peer.tenure_with_txs(&txs, &mut coinbase_nonce);
info!("Checking that stackers have no STX locked");
let balances = balances_from_keys(&mut peer, &latest_block, &keys);
assert_eq!(balances[0].amount_locked(), 0);
assert_eq!(balances[1].amount_locked(), 0);
info!("Checking tx receipts, all `pox3` calls should have returned `(err ...)`");
let last_observer_block = observer
.get_blocks()
.last()
.unwrap()
.clone();
let receipts = last_observer_block.receipts
.iter()
.filter(|receipt| match &receipt.result {
Value::Response(r) => !r.committed,
_ => false,
})
.collect::<Vec<_>>();
assert_eq!(receipts.len(), 4);
// Advance to start of rewards cycle stackers are participating in
let target_height = burnchain.pox_constants.pox_4_activation_height + 5;
while get_tip(peer.sortdb.as_ref()).block_height < u64::from(target_height) {
@@ -985,8 +1013,7 @@ fn pox_3_defunct() {
}
}
/// Test that we can lock STX for a couple cycles after pox4 starts,
/// and that it unlocks after the desired number of cycles
// Test that STX locked in pox3 automatically unlocks at `v3_unlock_height`
#[test]
fn pox_3_unlocks() {
// Config for this test