Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add burnchain advancement feature #81

Merged
merged 6 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions app.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ describe("Command-line arguments handling", () => {
[
`Using manifest path: example/Clarinet.toml`,
`Target contract: counter`,
`\nStarting invariant testing type for the counter contract...`,
`\nStarting invariant testing type for the counter contract...\n`,
],
],
[
Expand All @@ -180,7 +180,7 @@ describe("Command-line arguments handling", () => {
[
`Using manifest path: example/Clarinet.toml`,
`Target contract: counter`,
`\nStarting invariant testing type for the counter contract...`,
`\nStarting invariant testing type for the counter contract...\n`,
],
],
[
Expand All @@ -189,7 +189,7 @@ describe("Command-line arguments handling", () => {
[
`Using manifest path: example/Clarinet.toml`,
`Target contract: counter`,
`\nStarting property testing type for the counter contract...`,
`\nStarting property testing type for the counter contract...\n`,
],
],
[
Expand All @@ -198,7 +198,7 @@ describe("Command-line arguments handling", () => {
[
`Using manifest path: example/Clarinet.toml`,
`Target contract: counter`,
`\nStarting property testing type for the counter contract...`,
`\nStarting property testing type for the counter contract...\n`,
],
],
[
Expand All @@ -217,7 +217,7 @@ describe("Command-line arguments handling", () => {
`Target contract: counter`,
`Using seed: 123`,
`Using path: 84:0`,
`\nStarting invariant testing type for the counter contract...`,
`\nStarting invariant testing type for the counter contract...\n`,
],
],
[
Expand All @@ -242,7 +242,7 @@ describe("Command-line arguments handling", () => {
`Target contract: counter`,
`Using seed: 123`,
`Using path: 84:0`,
`\nStarting invariant testing type for the counter contract...`,
`\nStarting invariant testing type for the counter contract...\n`,
],
],
[
Expand All @@ -261,7 +261,7 @@ describe("Command-line arguments handling", () => {
`Target contract: counter`,
`Using seed: 123`,
`Using path: 84:0`,
`\nStarting property testing type for the counter contract...`,
`\nStarting property testing type for the counter contract...\n`,
],
],
[
Expand All @@ -280,7 +280,7 @@ describe("Command-line arguments handling", () => {
`Target contract: reverse`,
`Using seed: 123`,
`Using path: 84:0`,
`\nStarting property testing type for the reverse contract...`,
`\nStarting property testing type for the reverse contract...\n`,
],
],
[
Expand All @@ -299,7 +299,7 @@ describe("Command-line arguments handling", () => {
`Target contract: slice`,
`Using seed: 123`,
`Using path: 84:0`,
`\nStarting property testing type for the slice contract...`,
`\nStarting property testing type for the slice contract...\n`,
],
],
[
Expand All @@ -324,7 +324,7 @@ describe("Command-line arguments handling", () => {
`Target contract: counter`,
`Using seed: 123`,
`Using path: 84:0`,
`\nStarting property testing type for the counter contract...`,
`\nStarting property testing type for the counter contract...\n`,
],
],
])(
Expand Down
78 changes: 59 additions & 19 deletions invariant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const checkInvariants = (

radio.emit(
"logMessage",
`\nStarting invariant testing type for the ${sutContractName} contract...`
`\nStarting invariant testing type for the ${sutContractName} contract...\n`
moodmosaic marked this conversation as resolved.
Show resolved Hide resolved
);

const simnetAccounts = simnet.getAccounts();
Expand All @@ -64,6 +64,7 @@ export const checkInvariants = (
rendezvousContractId: fc.constantFrom(...rendezvousList),
sutCaller: fc.constantFrom(...eligibleAccounts.entries()),
invariantCaller: fc.constantFrom(...eligibleAccounts.entries()),
canMineBlocks: fc.boolean(),
})
.chain((r) => {
const functions = getFunctionsListForContract(
Expand Down Expand Up @@ -122,7 +123,25 @@ export const checkInvariants = (
invariantArgsArb: fc.tuple(...invariantArgsArb),
})
.map((args) => ({ ...r, ...args }));
}),
})
.chain((r) =>
fc
.record({
burnBlocks: r.canMineBlocks
? // This arbitrary produces integers with a maximum value
// inversely proportional to the number of runs:
// - Fewer runs result in a higher maximum burn blocks,
// allowing more blocks to be mined.
// - More runs result in a lower maximum burn blocks, as more
// blocks are mined overall.
fc.integer({
min: 1,
max: Math.ceil(100_000 / (runs || 100)),
})
: fc.constant(0),
})
.map((burnBlocks) => ({ ...r, ...burnBlocks }))
),
(r) => {
const selectedFunctionArgs = argsToCV(
r.selectedFunction,
Expand Down Expand Up @@ -174,17 +193,25 @@ export const checkInvariants = (

radio.emit(
"logMessage",
`${dim(sutCallerWallet)} ${getContractNameFromRendezvousId(
r.rendezvousContractId
)} ${underline(r.selectedFunction.name)} ${printedFunctionArgs}`
`₿ ${simnet.burnBlockHeight.toString().padStart(8)} ` +
`Ӿ ${simnet.blockHeight.toString().padStart(8)} ` +
dim(`${sutCallerWallet} `) +
`${getContractNameFromRendezvousId(r.rendezvousContractId)} ` +
`${underline(r.selectedFunction.name)} ` +
printedFunctionArgs
);
} else {
radio.emit(
"logMessage",
dim(
`${sutCallerWallet} ${getContractNameFromRendezvousId(
r.rendezvousContractId
)} ${underline(r.selectedFunction.name)} ${printedFunctionArgs}`
`₿ ${simnet.burnBlockHeight.toString().padStart(8)} ` +
`Ӿ ${simnet.blockHeight.toString().padStart(8)} ` +
`${sutCallerWallet} ` +
`${getContractNameFromRendezvousId(
r.rendezvousContractId
)} ` +
`${underline(r.selectedFunction.name)} ` +
printedFunctionArgs
)
);
}
Expand All @@ -195,9 +222,12 @@ export const checkInvariants = (
radio.emit(
"logMessage",
dim(
`${sutCallerWallet} ${getContractNameFromRendezvousId(
r.rendezvousContractId
)} ${underline(r.selectedFunction.name)} ${printedFunctionArgs}`
`₿ ${simnet.burnBlockHeight.toString().padStart(8)} ` +
`Ӿ ${simnet.blockHeight.toString().padStart(8)} ` +
`${sutCallerWallet} ` +
`${getContractNameFromRendezvousId(r.rendezvousContractId)} ` +
`${underline(r.selectedFunction.name)} ` +
printedFunctionArgs
)
);
}
Expand Down Expand Up @@ -230,11 +260,13 @@ export const checkInvariants = (
if (invariantCallResultJson.value === true) {
radio.emit(
"logMessage",
`${dim(invariantCallerWallet)} ${green(
"[PASS]"
)} ${getContractNameFromRendezvousId(
r.rendezvousContractId
)} ${underline(r.selectedInvariant.name)} ${printedInvariantArgs}`
`₿ ${simnet.burnBlockHeight.toString().padStart(8)} ` +
`Ӿ ${simnet.blockHeight.toString().padStart(8)} ` +
`${dim(invariantCallerWallet)} ` +
`${green("[PASS]")} ` +
`${getContractNameFromRendezvousId(r.rendezvousContractId)} ` +
`${underline(r.selectedInvariant.name)} ` +
printedInvariantArgs
);
}

Expand All @@ -254,15 +286,23 @@ export const checkInvariants = (
radio.emit(
"logMessage",
red(
`${invariantCallerWallet} [FAIL] ${getContractNameFromRendezvousId(
r.rendezvousContractId
)} ${underline(r.selectedInvariant.name)} ${printedInvariantArgs}`
`₿ ${simnet.burnBlockHeight.toString().padStart(8)} ` +
`Ӿ ${simnet.blockHeight.toString().padStart(8)} ` +
`${invariantCallerWallet} ` +
`[FAIL] ` +
`${getContractNameFromRendezvousId(r.rendezvousContractId)} ` +
`${underline(r.selectedInvariant.name)} ` +
printedInvariantArgs
)
);

// Re-throw the error for fast-check to catch and process.
throw error;
}

if (r.canMineBlocks) {
simnet.mineEmptyBurnBlocks(r.burnBlocks);
}
}
),
{
Expand Down
75 changes: 53 additions & 22 deletions property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const checkProperties = (

radio.emit(
"logMessage",
`\nStarting property testing type for the ${sutContractName} contract...`
`\nStarting property testing type for the ${sutContractName} contract...\n`
);

// Search for discard functions, for each test function. This map will
Expand Down Expand Up @@ -102,6 +102,7 @@ export const checkProperties = (
.record({
testContractId: fc.constantFrom(...rendezvousList),
testCaller: fc.constantFrom(...eligibleAccounts.entries()),
canMineBlocks: fc.boolean(),
})
.chain((r) => {
const testFunctionsList = getFunctionsListForContract(
Expand Down Expand Up @@ -138,7 +139,25 @@ export const checkProperties = (
functionArgsArb: fc.tuple(...functionArgsArb),
})
.map((args) => ({ ...r, ...args }));
}),
})
.chain((r) =>
fc
.record({
burnBlocks: r.canMineBlocks
? // This arbitrary produces integers with a maximum value
// inversely proportional to the number of runs:
// - Fewer runs result in a higher maximum burn blocks,
// allowing more blocks to be mined.
// - More runs result in a lower maximum burn blocks, as more
// blocks are mined overall.
fc.integer({
min: 1,
max: Math.ceil(100_000 / (runs || 100)),
})
: fc.constant(0),
})
.map((burnBlocks) => ({ ...r, ...burnBlocks }))
),
(r) => {
const selectedTestFunctionArgs = argsToCV(
r.selectedTestFunction,
Expand Down Expand Up @@ -174,11 +193,13 @@ export const checkProperties = (
if (discarded) {
radio.emit(
"logMessage",
`${dim(testCallerWallet)} ${yellow("[WARN]")} ${
r.testContractId.split(".")[1]
} ${underline(r.selectedTestFunction.name)} ${dim(
printedTestFunctionArgs
)}`
`₿ ${simnet.burnBlockHeight.toString().padStart(8)} ` +
`Ӿ ${simnet.blockHeight.toString().padStart(8)} ` +
`${dim(testCallerWallet)} ` +
`${yellow("[WARN]")} ` +
`${r.testContractId.split(".")[1]} ` +
`${underline(r.selectedTestFunction.name)} ` +
dim(printedTestFunctionArgs)
);
} else {
try {
Expand All @@ -200,11 +221,13 @@ export const checkProperties = (
if (discardedInPlace) {
radio.emit(
"logMessage",
`${dim(testCallerWallet)} ${yellow("[WARN]")} ${
r.testContractId.split(".")[1]
} ${underline(r.selectedTestFunction.name)} ${dim(
printedTestFunctionArgs
)}`
`₿ ${simnet.burnBlockHeight.toString().padStart(8)} ` +
`Ӿ ${simnet.blockHeight.toString().padStart(8)} ` +
`${dim(testCallerWallet)} ` +
`${yellow("[WARN]")} ` +
`${r.testContractId.split(".")[1]} ` +
`${underline(r.selectedTestFunction.name)} ` +
dim(printedTestFunctionArgs)
);
} else if (
!discardedInPlace &&
Expand All @@ -213,12 +236,18 @@ export const checkProperties = (
) {
radio.emit(
"logMessage",
`${dim(testCallerWallet)} ${green("[PASS]")} ${
r.testContractId.split(".")[1]
} ${underline(
r.selectedTestFunction.name
)} ${printedTestFunctionArgs}`
`₿ ${simnet.burnBlockHeight.toString().padStart(8)} ` +
`Ӿ ${simnet.blockHeight.toString().padStart(8)} ` +
`${dim(testCallerWallet)} ` +
`${green("[PASS]")} ` +
`${r.testContractId.split(".")[1]} ` +
`${underline(r.selectedTestFunction.name)} ` +
printedTestFunctionArgs
);

if (r.canMineBlocks) {
simnet.mineEmptyBurnBlocks(r.burnBlocks);
}
} else {
throw new Error(
`Test failed for ${r.testContractId.split(".")[1]} contract: "${
Expand All @@ -231,11 +260,13 @@ export const checkProperties = (
radio.emit(
"logMessage",
red(
`${testCallerWallet} [FAIL] ${
r.testContractId.split(".")[1]
} ${underline(
r.selectedTestFunction.name
)} ${printedTestFunctionArgs}`
`₿ ${simnet.burnBlockHeight.toString().padStart(8)} ` +
`Ӿ ${simnet.blockHeight.toString().padStart(8)} ` +
`${testCallerWallet} ` +
`[FAIL] ` +
`${r.testContractId.split(".")[1]} ` +
`${underline(r.selectedTestFunction.name)} ` +
printedTestFunctionArgs
)
);

Expand Down
Loading