Skip to content

Commit

Permalink
Add StackAggregationIncreaseCommand
Browse files Browse the repository at this point in the history
Adding the `StackAggregationIncreaseCommand` is currently causing the tests to fail.
To investigate:
- this may be a PoX-4 bug
- this may be a command implementation issue
  • Loading branch information
BowTiedRadone authored and moodmosaic committed Apr 8, 2024
1 parent fe2777b commit ee51196
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ it("statefully interacts with PoX-4", async () => {
firstLockedRewardCycle: 0,
allowedContractCaller: "",
callerAllowedBy: [],
committedRewCycleIndexes: [],
};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export type Wallet = {
firstLockedRewardCycle: number;
allowedContractCaller: StxAddress;
callerAllowedBy: StxAddress[];
committedRewCycleIndexes: number[];
};

export type PoxCommand = fc.Command<Stub, Real>;
Expand Down
28 changes: 28 additions & 0 deletions contrib/core-contract-tests/tests/pox-4/pox_Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { StackAggregationCommitAuthCommand } from "./pox_StackAggregationCommitA
import { StackAggregationCommitSigCommand } from "./pox_StackAggregationCommitSigCommand";
import { StackAggregationCommitIndexedSigCommand } from "./pox_StackAggregationCommitIndexedSigCommand";
import { StackAggregationCommitIndexedAuthCommand } from "./pox_StackAggregationCommitIndexedAuthCommand";
import { StackAggregationIncreaseCommand } from "./pox_StackAggregationIncreaseCommand";

export function PoxCommands(
wallets: Map<StxAddress, Wallet>,
Expand Down Expand Up @@ -150,6 +151,33 @@ export function PoxCommands(
r.currentCycle,
)
),
// StackAggregationIncreaseCommand
fc.record({
wallet: fc.constantFrom(...wallets.values()),
currentCycle: fc.constant(currentCycle(network)),
}).chain((r) => {
const committedRewCycleIndexesOrFallback =
r.wallet.committedRewCycleIndexes.length > 0
? r.wallet.committedRewCycleIndexes
: [-1];
return fc.record({
rewardCycleIndex: fc.constantFrom(
...committedRewCycleIndexesOrFallback,
),
}).map((cycleIndex) => ({ ...r, ...cycleIndex }));
}).map((
r: {
wallet: Wallet;
currentCycle: number;
rewardCycleIndex: number;
},
) =>
new StackAggregationIncreaseCommand(
r.wallet,
r.currentCycle,
r.rewardCycleIndex,
)
),
// RevokeDelegateStxCommand
fc.record({
wallet: fc.constantFrom(...wallets.values()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export class StackAggregationCommitAuthCommand implements PoxCommand {

const operatorWallet = model.wallets.get(this.operator.stxAddress)!;
operatorWallet.amountToCommit -= committedAmount;
operatorWallet.committedRewCycleIndexes.push(model.nextRewardSetIndex);
model.nextRewardSetIndex++;

// Log to console for debugging purposes. This is not necessary for the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export class StackAggregationCommitIndexedAuthCommand implements PoxCommand {
// Update the model
const operatorWallet = model.wallets.get(this.operator.stxAddress)!;
operatorWallet.amountToCommit -= committedAmount;
operatorWallet.committedRewCycleIndexes.push(model.nextRewardSetIndex);
model.nextRewardSetIndex++;

// Log to console for debugging purposes. This is not necessary for the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export class StackAggregationCommitIndexedSigCommand implements PoxCommand {
// Update the model
const operatorWallet = model.wallets.get(this.operator.stxAddress)!;
operatorWallet.amountToCommit -= committedAmount;
operatorWallet.committedRewCycleIndexes.push(model.nextRewardSetIndex);
model.nextRewardSetIndex++;

// Log to console for debugging purposes. This is not necessary for the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export class StackAggregationCommitSigCommand implements PoxCommand {

const operatorWallet = model.wallets.get(this.operator.stxAddress)!;
operatorWallet.amountToCommit -= committedAmount;
operatorWallet.committedRewCycleIndexes.push(model.nextRewardSetIndex);
model.nextRewardSetIndex++;

// Log to console for debugging purposes. This is not necessary for the
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import {
logCommand,
PoxCommand,
Real,
Stub,
Wallet,
} from "./pox_CommandModel.ts";
import { poxAddressToTuple } from "@stacks/stacking";
import { expect } from "vitest";
import { Cl } from "@stacks/transactions";

/**
* The `StackAggregationIncreaseCommand` allows an operator to commit
* partially stacked STX to a PoX address which has already received
* some STX (more than the `stacking minimum`).
* This allows a delegator to lock up marginally more STX from new
* delegates, even if they collectively do not exceed the Stacking
* minimum, so long as the target PoX address already represents at
* least as many STX as the `stacking minimum`.
* This command calls stack-aggregation-increase.
*
* Constraints for running this command include:
* - The Operator must have locked STX on behalf of at least one stacker.
* - The PoX address must have partial committed STX.
* - The Reward Cycle Index must be positive.
*/
export class StackAggregationIncreaseCommand implements PoxCommand {
readonly operator: Wallet;
readonly currentCycle: number;
readonly rewardCycleIndex: number;

/**
* Constructs a `StackAggregationIncreaseCommand` to commit partially
* stacked STX to a PoX address which has already received some STX.
*
* @param operator - Represents the `Operator`'s wallet.
* @param currentCycle - The current reward cycle.
* @param rewardCycleIndex - The cycle index to increase the commit for.
*/
constructor(
operator: Wallet,
currentCycle: number,
rewardCycleIndex: number,
) {
this.operator = operator;
this.currentCycle = currentCycle;
this.rewardCycleIndex = rewardCycleIndex;
}

check(_model: Readonly<Stub>): boolean {
// Constraints for running this command include:
// - The Operator must have locked STX on behalf of at least one stacker.
// - The PoX address must have partial committed STX.
// - The Reward Cycle Index must be positive.

return (
this.operator.lockedAddresses.length > 0 &&
this.rewardCycleIndex >= 0 &&
this.operator.amountToCommit > 0
);
}

run(model: Stub, real: Real): void {
model.trackCommandRun(this.constructor.name);

const committedAmount = this.operator.amountToCommit;

// Act
const stackAggregationIncrease = real.network.callPublicFn(
"ST000000000000000000002AMW42H.pox-4",
"stack-aggregation-increase",
[
// (pox-addr { version: (buff 1), hashbytes: (buff 32) })
poxAddressToTuple(this.operator.btcAddress),
// (reward-cycle uint)
Cl.uint(this.currentCycle + 1),
// (reward-cycle-index uint))
Cl.uint(this.rewardCycleIndex),
],
this.operator.stxAddress,
);

// Assert
expect(stackAggregationIncrease.result).toBeOk(Cl.bool(true));

const operatorWallet = model.wallets.get(this.operator.stxAddress)!;
operatorWallet.amountToCommit -= committedAmount;

// Log to console for debugging purposes. This is not necessary for the
// test to pass but it is useful for debugging and eyeballing the test.
logCommand(
`✓ ${this.operator.label}`,
"stack-agg-increase",
"amount committed",
committedAmount.toString(),
"cycle index",
this.rewardCycleIndex.toString(),
);
}

toString() {
// fast-check will call toString() in case of errors, e.g. property failed.
// It will then make a minimal counterexample, a process called 'shrinking'
// https://github.com/dubzzz/fast-check/issues/2864#issuecomment-1098002642
return `${this.operator.label} stack-aggregation-increase for reward cycle ${
this.currentCycle + 1
} index ${this.rewardCycleIndex}`;
}
}

0 comments on commit ee51196

Please sign in to comment.