mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-01-12 22:43:42 +08:00
fix(pox-4-tests): Refresh the model's state if the network gets to the next reward cycle
This commit is contained in:
committed by
Nikos Baxevanis
parent
e0493305c4
commit
b75cb1e93b
@@ -119,24 +119,27 @@ it("statefully interacts with PoX-4", async () => {
|
||||
|
||||
simnet.setEpoch("3.0");
|
||||
|
||||
fc.assert(
|
||||
fc.property(
|
||||
PoxCommands(model.wallets, sut.network),
|
||||
(cmds) => {
|
||||
const initialState = () => ({ model: model, real: sut });
|
||||
fc.modelRun(initialState, cmds);
|
||||
// The testing suite will run for 5000 times.
|
||||
for (let i = 0; i < 5000; i++) {
|
||||
fc.assert(
|
||||
fc.property(
|
||||
PoxCommands(model.wallets, sut.network),
|
||||
(cmds) => {
|
||||
const initialState = () => ({ model: model, real: sut });
|
||||
fc.modelRun(initialState, cmds);
|
||||
},
|
||||
),
|
||||
{
|
||||
// Defines the number of test iterations to run; default is 100.
|
||||
numRuns: 10,
|
||||
// Adjusts the level of detail in test reports. Default is 0 (minimal).
|
||||
// At level 2, reports include extensive details, helpful for deep
|
||||
// debugging. This includes not just the failing case and its seed, but
|
||||
// also a comprehensive log of all executed steps and their outcomes.
|
||||
verbose: 2,
|
||||
},
|
||||
),
|
||||
{
|
||||
// Defines the number of test iterations to run; default is 100.
|
||||
numRuns: 10,
|
||||
// Adjusts the level of detail in test reports. Default is 0 (minimal).
|
||||
// At level 2, reports include extensive details, helpful for deep
|
||||
// debugging. This includes not just the failing case and its seed, but
|
||||
// also a comprehensive log of all executed steps and their outcomes.
|
||||
verbose: 2,
|
||||
},
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
model.reportCommandRuns();
|
||||
});
|
||||
|
||||
@@ -85,6 +85,9 @@ export class AllowContractCallerCommand implements PoxCommand {
|
||||
"until",
|
||||
optionalCVToString(this.allowUntilBurnHt),
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import fc from "fast-check";
|
||||
|
||||
import { Simnet } from "@hirosystems/clarinet-sdk";
|
||||
import { StacksPrivateKey } from "@stacks/transactions";
|
||||
import {
|
||||
ClarityValue,
|
||||
cvToValue,
|
||||
StacksPrivateKey,
|
||||
} from "@stacks/transactions";
|
||||
import { StackingClient } from "@stacks/stacking";
|
||||
|
||||
export type StxAddress = string;
|
||||
@@ -12,7 +16,8 @@ export class Stub {
|
||||
readonly wallets: Map<StxAddress, Wallet>;
|
||||
readonly statistics: Map<string, number>;
|
||||
stackingMinimum: number;
|
||||
nextRewardSetIndex: number
|
||||
nextRewardSetIndex: number;
|
||||
lastRefreshedCycle: number;
|
||||
|
||||
constructor(
|
||||
wallets: Map<StxAddress, Wallet>,
|
||||
@@ -22,6 +27,7 @@ export class Stub {
|
||||
this.statistics = statistics;
|
||||
this.stackingMinimum = 0;
|
||||
this.nextRewardSetIndex = 0;
|
||||
this.lastRefreshedCycle = 0;
|
||||
}
|
||||
|
||||
trackCommandRun(commandName: string) {
|
||||
@@ -35,6 +41,53 @@ export class Stub {
|
||||
console.log(`${commandName}: ${count}`);
|
||||
});
|
||||
}
|
||||
|
||||
stateRefresh(real: Real) {
|
||||
const burnBlockHeightResult = real.network.runSnippet("burn-block-height");
|
||||
const burnBlockHeight = cvToValue(burnBlockHeightResult as ClarityValue);
|
||||
const lastRefreshedCycle = this.lastRefreshedCycle;
|
||||
const currentRewCycle = Math.floor((Number(burnBlockHeight) - 0) / 1050);
|
||||
|
||||
if (lastRefreshedCycle < currentRewCycle) {
|
||||
this.nextRewardSetIndex = 0;
|
||||
|
||||
this.wallets.forEach((wallet) => {
|
||||
const expiredDelegators = wallet.poolMembers.filter((stackerAddress) =>
|
||||
this.wallets.get(stackerAddress)!.delegatedUntilBurnHt + 1 <
|
||||
burnBlockHeight
|
||||
);
|
||||
const expiredStackers = wallet.lockedAddresses.filter(
|
||||
(stackerAddress) =>
|
||||
this.wallets.get(stackerAddress)!.unlockHeight + 1 <=
|
||||
burnBlockHeight,
|
||||
);
|
||||
|
||||
expiredDelegators.forEach((expDelegator) => {
|
||||
const expDelegatorIndex = wallet.poolMembers.indexOf(expDelegator);
|
||||
wallet.poolMembers.splice(expDelegatorIndex, 1);
|
||||
});
|
||||
|
||||
expiredStackers.forEach((expStacker) => {
|
||||
const expStackerWallet = this.wallets.get(expStacker)!;
|
||||
const expStackerIndex = wallet.lockedAddresses.indexOf(expStacker);
|
||||
wallet.lockedAddresses.splice(expStackerIndex, 1);
|
||||
wallet.amountToCommit -= expStackerWallet.amountLocked;
|
||||
});
|
||||
|
||||
if (
|
||||
wallet.unlockHeight > 0 && wallet.unlockHeight + 1 <= burnBlockHeight
|
||||
) {
|
||||
wallet.isStacking = false;
|
||||
wallet.amountUnlocked += wallet.amountLocked;
|
||||
wallet.amountLocked = 0;
|
||||
wallet.unlockHeight = 0;
|
||||
wallet.firstLockedRewardCycle = 0;
|
||||
}
|
||||
wallet.committedRewCycleIndexes = [];
|
||||
});
|
||||
}
|
||||
this.lastRefreshedCycle = currentRewCycle;
|
||||
}
|
||||
}
|
||||
|
||||
export type Real = {
|
||||
|
||||
@@ -357,7 +357,7 @@ export function PoxCommands(
|
||||
|
||||
// More on size: https://github.com/dubzzz/fast-check/discussions/2978
|
||||
// More on cmds: https://github.com/dubzzz/fast-check/discussions/3026
|
||||
return fc.commands(cmds, { size: "large" });
|
||||
return fc.commands(cmds, { size: "xsmall" });
|
||||
}
|
||||
|
||||
export const REWARD_CYCLE_LENGTH = 1050;
|
||||
|
||||
@@ -149,6 +149,9 @@ export class DelegateStackExtendCommand implements PoxCommand {
|
||||
"new unlock height",
|
||||
this.stacker.unlockHeight.toString(),
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -123,6 +123,9 @@ export class DelegateStackIncreaseCommand implements PoxCommand {
|
||||
"total locked",
|
||||
stackerWallet.amountLocked.toString(),
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -169,6 +169,9 @@ export class DelegateStackStxCommand implements PoxCommand {
|
||||
"until",
|
||||
this.stacker.unlockHeight.toString()
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -106,6 +106,9 @@ export class DelegateStxCommand implements PoxCommand {
|
||||
"until",
|
||||
this.untilBurnHt.toString()
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -87,6 +87,9 @@ export class DisallowContractCallerCommand implements PoxCommand {
|
||||
"disallow-contract-caller",
|
||||
this.callerToDisallow.label,
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -55,6 +55,9 @@ export class GetStackingMinimumCommand implements PoxCommand {
|
||||
"pox-4",
|
||||
stackingMinimum.value.toString(),
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -54,6 +54,9 @@ export class GetStxAccountCommand implements PoxCommand {
|
||||
"unlocked-height",
|
||||
actual.unlockHeight.toString(),
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -85,6 +85,9 @@ export class RevokeDelegateStxCommand implements PoxCommand {
|
||||
// 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.wallet.label}`, "revoke-delegate-stx");
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -124,12 +124,17 @@ export class StackAggregationCommitAuthCommand implements PoxCommand {
|
||||
committedAmount.toString(),
|
||||
"authorization",
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
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-commit auth-id ${this.authId} for reward cycle ${this.currentCycle}`;
|
||||
return `${this.operator.label} stack-aggregation-commit auth-id ${this.authId} for reward cycle ${
|
||||
this.currentCycle + 1
|
||||
}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,12 +128,17 @@ export class StackAggregationCommitIndexedAuthCommand implements PoxCommand {
|
||||
committedAmount.toString(),
|
||||
"authorization",
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
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-commit-indexed auth-id ${this.authId} for reward cycle ${this.currentCycle}`;
|
||||
return `${this.operator.label} stack-aggregation-commit-indexed auth-id ${this.authId} for reward cycle ${
|
||||
this.currentCycle + 1
|
||||
}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,12 +128,17 @@ export class StackAggregationCommitIndexedSigCommand implements PoxCommand {
|
||||
committedAmount.toString(),
|
||||
"signature",
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
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-commit-indexed auth-id ${this.authId} for reward cycle ${this.currentCycle}`;
|
||||
return `${this.operator.label} stack-aggregation-commit-indexed auth-id ${this.authId} for reward cycle ${
|
||||
this.currentCycle + 1
|
||||
}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,12 +124,17 @@ export class StackAggregationCommitSigCommand implements PoxCommand {
|
||||
committedAmount.toString(),
|
||||
"signature",
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
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-commit auth-id ${this.authId} for reward cycle ${this.currentCycle}`;
|
||||
return `${this.operator.label} stack-aggregation-commit auth-id ${this.authId} for reward cycle ${
|
||||
this.currentCycle + 1
|
||||
}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,9 @@ export class StackAggregationIncreaseCommand implements PoxCommand {
|
||||
"cycle index",
|
||||
this.rewardCycleIndex.toString(),
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -172,6 +172,9 @@ export class StackStxCommand implements PoxCommand {
|
||||
"lock-amount",
|
||||
amountUstx.toString(),
|
||||
);
|
||||
|
||||
// Refresh the model's state if the network gets to the next reward cycle.
|
||||
model.stateRefresh(real);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
Reference in New Issue
Block a user