Skip to content

Commit c179e62

Browse files
authored
Merge pull request #4670 from stacks-network/feat/stack-agg-incr-error
Feat(pox-4): return an err on improper agg-incr invocations
2 parents b7792bd + d87ff8f commit c179e62

File tree

2 files changed

+104
-3
lines changed

2 files changed

+104
-3
lines changed

stackslib/src/chainstate/stacks/boot/pox-4.clar

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -897,12 +897,12 @@
897897
(err ERR_STACKING_INVALID_LOCK_PERIOD))
898898

899899
(let ((partial-amount-ustx (get stacked-amount partial-stacked))
900-
;; reward-cycle must point to an existing record in reward-cycle-total-stacked
901-
;; infallible; getting something from partial-stacked-by-cycle succeeded so this must succeed
902-
(existing-cycle (unwrap-panic (map-get? reward-cycle-total-stacked { reward-cycle: reward-cycle })))
903900
;; reward-cycle and reward-cycle-index must point to an existing record in reward-cycle-pox-address-list
904901
(existing-entry (unwrap! (map-get? reward-cycle-pox-address-list { reward-cycle: reward-cycle, index: reward-cycle-index })
905902
(err ERR_DELEGATION_NO_REWARD_SLOT)))
903+
;; reward-cycle must point to an existing record in reward-cycle-total-stacked
904+
;; infallible; getting existing-entry succeeded so this must succeed
905+
(existing-cycle (unwrap-panic (map-get? reward-cycle-total-stacked { reward-cycle: reward-cycle })))
906906
(increased-entry-total (+ (get total-ustx existing-entry) partial-amount-ustx))
907907
(increased-cycle-total (+ (get total-ustx existing-cycle) partial-amount-ustx))
908908
(existing-signer-key (get signer existing-entry)))

stackslib/src/chainstate/stacks/boot/pox_4_tests.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6302,6 +6302,107 @@ fn delegate_stack_increase() {
63026302
assert_eq!(&reward_entry.signer.unwrap(), signer_pk_bytes.as_slice());
63036303
}
63046304

6305+
// In this test case, Alice delegates twice the stacking minimum to Bob.
6306+
// Bob stacks Alice's funds, and then immediately tries to stacks-aggregation-increase.
6307+
// This should return a clarity user error.
6308+
#[test]
6309+
fn delegate_stack_increase_err() {
6310+
let lock_period: u128 = 2;
6311+
let observer = TestEventObserver::new();
6312+
let (burnchain, mut peer, keys, latest_block, block_height, mut coinbase_nonce) =
6313+
prepare_pox4_test(function_name!(), Some(&observer));
6314+
6315+
let alice_nonce = 0;
6316+
let alice_key = &keys[0];
6317+
let alice_address = PrincipalData::from(key_to_stacks_addr(alice_key));
6318+
let mut bob_nonce = 0;
6319+
let bob_delegate_key = &keys[1];
6320+
let bob_delegate_address = PrincipalData::from(key_to_stacks_addr(bob_delegate_key));
6321+
let min_ustx = get_stacking_minimum(&mut peer, &latest_block);
6322+
let signer_sk = StacksPrivateKey::from_seed(&[1, 3, 3, 7]);
6323+
let signer_pk = StacksPublicKey::from_private(&signer_sk);
6324+
let signer_pk_bytes = signer_pk.to_bytes_compressed();
6325+
let signer_key_val = Value::buff_from(signer_pk_bytes.clone()).unwrap();
6326+
6327+
let pox_addr = PoxAddress::from_legacy(
6328+
AddressHashMode::SerializeP2PKH,
6329+
key_to_stacks_addr(bob_delegate_key).bytes,
6330+
);
6331+
6332+
let next_reward_cycle = 1 + burnchain
6333+
.block_height_to_reward_cycle(block_height)
6334+
.unwrap();
6335+
6336+
let delegate_stx = make_pox_4_delegate_stx(
6337+
alice_key,
6338+
alice_nonce,
6339+
2 * min_ustx,
6340+
bob_delegate_address.clone(),
6341+
None,
6342+
Some(pox_addr.clone()),
6343+
);
6344+
6345+
let alice_principal = PrincipalData::from(key_to_stacks_addr(alice_key));
6346+
6347+
let delegate_stack_stx = make_pox_4_delegate_stack_stx(
6348+
bob_delegate_key,
6349+
bob_nonce,
6350+
alice_principal,
6351+
min_ustx * 2,
6352+
pox_addr.clone(),
6353+
block_height as u128,
6354+
lock_period,
6355+
);
6356+
6357+
let txs = vec![delegate_stx, delegate_stack_stx];
6358+
6359+
let latest_block = peer.tenure_with_txs(&txs, &mut coinbase_nonce);
6360+
6361+
bob_nonce += 1;
6362+
6363+
let signature = make_signer_key_signature(
6364+
&pox_addr,
6365+
&signer_sk,
6366+
next_reward_cycle.into(),
6367+
&Pox4SignatureTopic::AggregationIncrease,
6368+
1_u128,
6369+
u128::MAX,
6370+
1,
6371+
);
6372+
6373+
// Bob's Aggregate Increase
6374+
let bobs_aggregate_increase = make_pox_4_aggregation_increase(
6375+
&bob_delegate_key,
6376+
bob_nonce,
6377+
&pox_addr,
6378+
next_reward_cycle.into(),
6379+
0,
6380+
Some(signature),
6381+
&signer_pk,
6382+
u128::MAX,
6383+
1,
6384+
);
6385+
6386+
let txs = vec![bobs_aggregate_increase];
6387+
6388+
let latest_block = peer.tenure_with_txs(&txs, &mut coinbase_nonce);
6389+
6390+
let delegate_transactions =
6391+
get_last_block_sender_transactions(&observer, key_to_stacks_addr(bob_delegate_key));
6392+
6393+
let actual_result = delegate_transactions.first().cloned().unwrap().result;
6394+
6395+
// Should be a DELEGATION NO REWARD SLOT error
6396+
let expected_result = Value::error(Value::Int(28)).unwrap();
6397+
6398+
assert_eq!(actual_result, expected_result);
6399+
6400+
// test that the reward set is empty
6401+
let reward_cycle_ht = burnchain.reward_cycle_to_block_height(next_reward_cycle);
6402+
let reward_set = get_reward_set_entries_at(&mut peer, &latest_block, reward_cycle_ht);
6403+
assert!(reward_set.is_empty());
6404+
}
6405+
63056406
pub fn get_stacking_state_pox_4(
63066407
peer: &mut TestPeer,
63076408
tip: &StacksBlockId,

0 commit comments

Comments
 (0)