Skip to content

Commit b5a25f0

Browse files
authored
Merge pull request #4644 from stacks-network/bug/update-aggregation-increase
2 parents c6ce862 + 5a9850b commit b5a25f0

File tree

4 files changed

+515
-17
lines changed

4 files changed

+515
-17
lines changed

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,6 +2185,40 @@ pub mod test {
21852185
make_tx(key, nonce, 0, payload)
21862186
}
21872187

2188+
pub fn make_pox_4_aggregation_increase(
2189+
key: &StacksPrivateKey,
2190+
nonce: u64,
2191+
pox_addr: &PoxAddress,
2192+
reward_cycle: u128,
2193+
reward_cycle_index: u128,
2194+
signature_opt: Option<Vec<u8>>,
2195+
signer_key: &Secp256k1PublicKey,
2196+
max_amount: u128,
2197+
auth_id: u128,
2198+
) -> StacksTransaction {
2199+
let addr_tuple = Value::Tuple(pox_addr.as_clarity_tuple().unwrap());
2200+
let signature = signature_opt
2201+
.map(|sig| Value::some(Value::buff_from(sig).unwrap()).unwrap())
2202+
.unwrap_or_else(|| Value::none());
2203+
let payload = TransactionPayload::new_contract_call(
2204+
boot_code_test_addr(),
2205+
POX_4_NAME,
2206+
"stack-aggregation-increase",
2207+
vec![
2208+
addr_tuple,
2209+
Value::UInt(reward_cycle),
2210+
Value::UInt(reward_cycle_index),
2211+
signature,
2212+
Value::buff_from(signer_key.to_bytes_compressed()).unwrap(),
2213+
Value::UInt(max_amount),
2214+
Value::UInt(auth_id),
2215+
],
2216+
)
2217+
.unwrap();
2218+
2219+
make_tx(key, nonce, 0, payload)
2220+
}
2221+
21882222
pub fn make_pox_4_stack_increase(
21892223
key: &StacksPrivateKey,
21902224
nonce: u64,

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

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,6 @@
316316
(some delegation-info))))
317317

318318
;; Get the size of the reward set for a reward cycle.
319-
;; Note that this does _not_ return duplicate PoX addresses.
320319
;; Note that this also _will_ return PoX addresses that are beneath
321320
;; the minimum threshold -- i.e. the threshold can increase after insertion.
322321
;; Used internally by the Stacks node, which filters out the entries
@@ -665,6 +664,12 @@
665664
(err ERR_STACKING_INVALID_POX_ADDRESS))
666665
true)
667666

667+
(match pox-addr
668+
pox-tuple
669+
(asserts! (check-pox-addr-hashbytes (get version pox-tuple) (get hashbytes pox-tuple))
670+
(err ERR_STACKING_INVALID_POX_ADDRESS))
671+
true)
672+
668673
;; tx-sender must not be delegating
669674
(asserts! (is-none (get-check-delegation tx-sender))
670675
(err ERR_STACKING_ALREADY_DELEGATED))
@@ -873,7 +878,11 @@
873878
;;
874879
(define-public (stack-aggregation-increase (pox-addr { version: (buff 1), hashbytes: (buff 32) })
875880
(reward-cycle uint)
876-
(reward-cycle-index uint))
881+
(reward-cycle-index uint)
882+
(signer-sig (optional (buff 65)))
883+
(signer-key (buff 33))
884+
(max-amount uint)
885+
(auth-id uint))
877886
(let ((partial-stacked
878887
;; fetch the partial commitments
879888
(unwrap! (map-get? partial-stacked-by-cycle { pox-addr: pox-addr, sender: tx-sender, reward-cycle: reward-cycle })
@@ -887,21 +896,22 @@
887896
(asserts! (> reward-cycle (current-pox-reward-cycle))
888897
(err ERR_STACKING_INVALID_LOCK_PERIOD))
889898

890-
(let ((amount-ustx (get stacked-amount partial-stacked))
899+
(let ((partial-amount-ustx (get stacked-amount partial-stacked))
891900
;; reward-cycle must point to an existing record in reward-cycle-total-stacked
892901
;; infallible; getting something from partial-stacked-by-cycle succeeded so this must succeed
893-
(existing-total (unwrap-panic (map-get? reward-cycle-total-stacked { reward-cycle: reward-cycle })))
902+
(existing-cycle (unwrap-panic (map-get? reward-cycle-total-stacked { reward-cycle: reward-cycle })))
894903
;; reward-cycle and reward-cycle-index must point to an existing record in reward-cycle-pox-address-list
895904
(existing-entry (unwrap! (map-get? reward-cycle-pox-address-list { reward-cycle: reward-cycle, index: reward-cycle-index })
896905
(err ERR_DELEGATION_NO_REWARD_SLOT)))
897-
(increased-ustx (+ (get total-ustx existing-entry) amount-ustx))
898-
(total-ustx (+ (get total-ustx existing-total) amount-ustx)))
906+
(increased-entry-total (+ (get total-ustx existing-entry) partial-amount-ustx))
907+
(increased-cycle-total (+ (get total-ustx existing-cycle) partial-amount-ustx))
908+
(existing-signer-key (get signer existing-entry)))
899909

900910
;; must be stackable
901-
(try! (minimal-can-stack-stx pox-addr total-ustx reward-cycle u1))
911+
(try! (minimal-can-stack-stx pox-addr increased-entry-total reward-cycle u1))
902912

903913
;; new total must exceed the stacking minimum
904-
(asserts! (<= (get-stacking-minimum) total-ustx)
914+
(asserts! (<= (get-stacking-minimum) increased-entry-total)
905915
(err ERR_STACKING_THRESHOLD_NOT_MET))
906916

907917
;; there must *not* be a stacker entry (since this is a delegator)
@@ -912,19 +922,28 @@
912922
(asserts! (is-eq pox-addr (get pox-addr existing-entry))
913923
(err ERR_DELEGATION_WRONG_REWARD_SLOT))
914924

925+
;; Validate that amount is less than or equal to `max-amount`
926+
(asserts! (>= max-amount increased-entry-total) (err ERR_SIGNER_AUTH_AMOUNT_TOO_HIGH))
927+
928+
;; Validate that signer-key matches the existing signer-key
929+
(asserts! (is-eq existing-signer-key signer-key) (err ERR_INVALID_SIGNER_KEY))
930+
931+
;; Verify signature from delegate that allows this sender for this cycle
932+
;; 'lock-period' param set to one period, same as aggregation-commit-indexed
933+
(try! (consume-signer-key-authorization pox-addr reward-cycle "agg-increase" u1 signer-sig signer-key increased-entry-total max-amount auth-id))
934+
915935
;; update the pox-address list -- bump the total-ustx
916936
(map-set reward-cycle-pox-address-list
917937
{ reward-cycle: reward-cycle, index: reward-cycle-index }
918938
{ pox-addr: pox-addr,
919-
total-ustx: increased-ustx,
939+
total-ustx: increased-entry-total,
920940
stacker: none,
921-
;; TODO: this must be authorized with a signature, or tx-sender allowance!
922-
signer: (get signer existing-entry) })
941+
signer: signer-key })
923942

924943
;; update the total ustx in this cycle
925944
(map-set reward-cycle-total-stacked
926945
{ reward-cycle: reward-cycle }
927-
{ total-ustx: total-ustx })
946+
{ total-ustx: increased-cycle-total })
928947

929948
;; don't update the stacking-state map,
930949
;; because it _already has_ this stacker's state
@@ -1161,9 +1180,6 @@
11611180
;; Verify signature from delegate that allows this sender for this cycle
11621181
(try! (consume-signer-key-authorization pox-addr cur-cycle "stack-extend" extend-count signer-sig signer-key u0 max-amount auth-id))
11631182

1164-
;; TODO: add more assertions to sanity check the `stacker-info` values with
1165-
;; the `stacker-state` values
1166-
11671183
(let ((last-extend-cycle (- (+ first-extend-cycle extend-count) u1))
11681184
(lock-period (+ u1 (- last-extend-cycle first-reward-cycle)))
11691185
(new-unlock-ht (reward-cycle-to-burn-height (+ u1 last-extend-cycle))))
@@ -1421,6 +1437,9 @@
14211437
(max-amount uint)
14221438
(auth-id uint))
14231439
(begin
1440+
;; must be called directly by the tx-sender or by an allowed contract-caller
1441+
(asserts! (check-caller-allowed)
1442+
(err ERR_NOT_ALLOWED))
14241443
;; Validate that `tx-sender` has the same pubkey hash as `signer-key`
14251444
(asserts! (is-eq
14261445
(unwrap! (principal-construct? (if is-in-mainnet STACKS_ADDR_VERSION_MAINNET STACKS_ADDR_VERSION_TESTNET) (hash160 signer-key)) (err ERR_INVALID_SIGNER_KEY))

0 commit comments

Comments
 (0)