Skip to content

Commit

Permalink
chore(pox-4): Track command execution in PoxCommand implementations
Browse files Browse the repository at this point in the history
Each `run` method now calls `model.trackCommandRun(this.constructor.name)`,
enhancing observability and aiding in debugging by systematically tracking
command executions.

Example output:

    Command run method execution counts:
    AllowContractCallerCommand: 491
    DelegateStackStxCommand: 1
    DelegateStxCommand: 285
    GetStackingMinimumCommand: 536
    GetStxAccountCommand: 503
    RevokeDelegateStxCommand: 281
    StackStxCommand: 8
  • Loading branch information
moodmosaic committed Mar 29, 2024
1 parent 3c080bb commit 5450bc8
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 14 deletions.
29 changes: 18 additions & 11 deletions contrib/core-contract-tests/tests/pox-4/pox-4.stateful-prop.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { it } from "vitest";
import { initSimnet } from "@hirosystems/clarinet-sdk";
import { Real, Stub, StxAddress, Wallet } from "./pox_CommandModel.ts";
import { Real, Stub } from "./pox_CommandModel.ts";

import {
getPublicKeyFromPrivate,
Expand All @@ -17,18 +17,15 @@ import { StackingClient } from "@stacks/stacking";
import fc from "fast-check";
import { PoxCommands } from "./pox_Commands.ts";

import fs from "fs";
import path from "path";

it("statefully interacts with PoX-4", async () => {
// SUT stands for "System Under Test".
const sut: Real = {
network: await initSimnet(),
};

// This is the initial state of the model.
const model: Stub = {
stackingMinimum: 0,
wallets: new Map<StxAddress, Wallet>(),
};

const wallets = [
[
"wallet_1",
Expand Down Expand Up @@ -103,10 +100,18 @@ it("statefully interacts with PoX-4", async () => {
};
});

// Add the wallets to the model.
wallets.forEach((wallet) => {
model.wallets.set(wallet.stxAddress, wallet);
});
// Track the number of times each command is run, so we can see if all the
// commands are run at least once.
const statistics = fs.readdirSync(path.join(__dirname)).filter((file) =>
file.startsWith("pox_") && file.endsWith(".ts") &&
file !== "pox_CommandModel.ts" && file !== "pox_Commands.ts"
).map((file) => file.slice(4, -3)); // Remove "pox_" prefix and ".ts" suffix.

// This is the initial state of the model.
const model = new Stub(
new Map(wallets.map((wallet) => [wallet.stxAddress, wallet])),
new Map(statistics.map((commandName) => [commandName, 0])),
);

simnet.setEpoch("3.0");

Expand All @@ -128,4 +133,6 @@ it("statefully interacts with PoX-4", async () => {
verbose: 2,
},
);

model.reportCommandRuns();
});
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export class AllowContractCallerCommand implements PoxCommand {
}

run(model: Stub, real: Real): void {
model.trackCommandRun(this.constructor.name);
// Act
const allowContractCaller = real.network.callPublicFn(
"ST000000000000000000002AMW42H.pox-4",
Expand Down
29 changes: 26 additions & 3 deletions contrib/core-contract-tests/tests/pox-4/pox_CommandModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,34 @@ import { StackingClient } from "@stacks/stacking";

export type StxAddress = string;
export type BtcAddress = string;
export type CommandTag = string;

export type Stub = {
export class Stub {
readonly wallets: Map<StxAddress, Wallet>;
readonly statistics: Map<string, number>;
stackingMinimum: number;
wallets: Map<StxAddress, Wallet>;
};

constructor(
wallets: Map<StxAddress, Wallet>,
statistics: Map<CommandTag, number>,
) {
this.wallets = wallets;
this.statistics = statistics;
this.stackingMinimum = 0;
}

trackCommandRun(commandName: string) {
const count = this.statistics.get(commandName) || 0;
this.statistics.set(commandName, count + 1);
}

reportCommandRuns() {
process.stdout.write("Command run method execution counts:");
this.statistics.forEach((count, commandName) => {
process.stdout.write(`\n${commandName}: ${count}`);
});
}
}

export type Real = {
network: Simnet;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export class DelegateStackStxCommand implements PoxCommand {
}

run(model: Stub, real: Real): void {
model.trackCommandRun(this.constructor.name);
// Act
const delegateStackStx = real.network.callPublicFn(
"ST000000000000000000002AMW42H.pox-4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class DelegateStxCommand implements PoxCommand {
}

run(model: Stub, real: Real): void {
model.trackCommandRun(this.constructor.name);
// The amount of uSTX delegated by the Stacker to the Delegatee.
// Even if there are no constraints about the delegated amount,
// it will be checked in the future, when calling delegate-stack-stx.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class GetStackingMinimumCommand implements PoxCommand {
}

run(model: Stub, real: Real): void {
model.trackCommandRun(this.constructor.name);
// Act
const { result: stackingMinimum } = real.network.callReadOnlyFn(
"ST000000000000000000002AMW42H.pox-4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class GetStxAccountCommand implements PoxCommand {
}

run(model: Stub, real: Real): void {
model.trackCommandRun(this.constructor.name);
const actual = model.wallets.get(this.wallet.stxAddress)!;
expect(real.network.runSnippet(`(stx-account '${actual.stxAddress})`))
.toBeTuple({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class RevokeDelegateStxCommand implements PoxCommand {
}

run(model: Stub, real: Real): void {
model.trackCommandRun(this.constructor.name);
// Get the Operator's wallet
const operatorWallet = model.wallets.get(this.wallet.delegatedTo)!;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class StackStxCommand implements PoxCommand {
}

run(model: Stub, real: Real): void {
model.trackCommandRun(this.constructor.name);
// The maximum amount of uSTX that can be used (per tx) with this signer
// key. For our tests, we will use the minimum amount of uSTX to be stacked
// in the given reward cycle multiplied by the margin, which is a randomly
Expand Down

0 comments on commit 5450bc8

Please sign in to comment.