Skip to content

Commit 878e17d

Browse files
committed
Merge branch 'develop' into test/pox-4-unit
2 parents 90a6e74 + e534515 commit 878e17d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+3749
-505
lines changed

.github/workflows/bitcoin-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ jobs:
8181
- tests::nakamoto_integrations::correct_burn_outs
8282
- tests::nakamoto_integrations::vote_for_aggregate_key_burn_op
8383
- tests::nakamoto_integrations::follower_bootup
84+
- tests::nakamoto_integrations::forked_tenure_is_ignored
8485
- tests::signer::stackerdb_dkg
8586
- tests::signer::stackerdb_sign
8687
- tests::signer::stackerdb_block_proposal

clarity/src/vm/contexts.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,11 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> {
973973
let contract = self
974974
.global_context
975975
.database
976-
.get_contract(contract_identifier)?;
976+
.get_contract(contract_identifier)
977+
.or_else(|e| {
978+
self.global_context.roll_back()?;
979+
Err(e)
980+
})?;
977981

978982
let result = {
979983
let mut nested_env = Environment::new(

clarity/src/vm/tests/contracts.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,3 +1147,38 @@ fn test_cc_trait_stack_depth(
11471147
RuntimeErrorType::MaxStackDepthReached.into()
11481148
);
11491149
}
1150+
1151+
#[apply(test_epochs)]
1152+
fn test_eval_with_non_existing_contract(
1153+
epoch: StacksEpochId,
1154+
mut env_factory: MemoryEnvironmentGenerator,
1155+
) {
1156+
let mut owned_env = env_factory.get_env(epoch);
1157+
1158+
let mut placeholder_context = ContractContext::new(
1159+
QualifiedContractIdentifier::transient(),
1160+
ClarityVersion::Clarity2,
1161+
);
1162+
1163+
let mut env = owned_env.get_exec_environment(
1164+
Some(get_principal().expect_principal().unwrap()),
1165+
None,
1166+
&mut placeholder_context,
1167+
);
1168+
1169+
let result = env.eval_read_only(
1170+
&QualifiedContractIdentifier::local("absent").unwrap(),
1171+
"(ok 0)",
1172+
);
1173+
assert_eq!(
1174+
result.as_ref().unwrap_err(),
1175+
&Error::Unchecked(CheckErrors::NoSuchContract(
1176+
QualifiedContractIdentifier::local("absent")
1177+
.unwrap()
1178+
.to_string()
1179+
))
1180+
);
1181+
drop(env);
1182+
owned_env.commit().unwrap();
1183+
assert!(owned_env.destruct().is_some());
1184+
}

contrib/core-contract-tests/package-lock.json

Lines changed: 36 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contrib/core-contract-tests/package.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@
1212
"author": "",
1313
"license": "ISC",
1414
"dependencies": {
15-
"@hirosystems/clarinet-sdk": "^2.5.0",
16-
"@stacks/clarunit": "^0.0.2",
17-
"@stacks/encryption": "^6.13.0",
18-
"@stacks/network": "^6.13.0",
19-
"@stacks/stacking": "^6.13.0",
15+
"@hirosystems/clarinet-sdk": "^2.4.1",
16+
"@stacks/clarunit": "0.0.1",
17+
"@stacks/stacking": "^6.13.2",
2018
"@stacks/transactions": "^6.13.0",
2119
"chokidar-cli": "^3.0.0",
2220
"fast-check": "^3.15.1",
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
import { it } from "vitest";
2+
import { initSimnet } from "@hirosystems/clarinet-sdk";
3+
import { Real, Stub } from "./pox_CommandModel.ts";
4+
5+
import {
6+
getPublicKeyFromPrivate,
7+
publicKeyToBtcAddress,
8+
} from "@stacks/encryption";
9+
import { StacksDevnet } from "@stacks/network";
10+
import {
11+
createStacksPrivateKey,
12+
getAddressFromPrivateKey,
13+
TransactionVersion,
14+
} from "@stacks/transactions";
15+
import { StackingClient } from "@stacks/stacking";
16+
17+
import fc from "fast-check";
18+
import { PoxCommands } from "./pox_Commands.ts";
19+
20+
import fs from "fs";
21+
import path from "path";
22+
23+
it("statefully interacts with PoX-4", async () => {
24+
// SUT stands for "System Under Test".
25+
const sut: Real = {
26+
network: await initSimnet(),
27+
};
28+
29+
const wallets = [
30+
[
31+
"wallet_1",
32+
"7287ba251d44a4d3fd9276c88ce34c5c52a038955511cccaf77e61068649c17801",
33+
],
34+
[
35+
"wallet_2",
36+
"530d9f61984c888536871c6573073bdfc0058896dc1adfe9a6a10dfacadc209101",
37+
],
38+
[
39+
"wallet_3",
40+
"d655b2523bcd65e34889725c73064feb17ceb796831c0e111ba1a552b0f31b3901",
41+
],
42+
[
43+
"wallet_4",
44+
"f9d7206a47f14d2870c163ebab4bf3e70d18f5d14ce1031f3902fbbc894fe4c701",
45+
],
46+
[
47+
"wallet_5",
48+
"3eccc5dac8056590432db6a35d52b9896876a3d5cbdea53b72400bc9c2099fe801",
49+
],
50+
[
51+
"wallet_6",
52+
"7036b29cb5e235e5fd9b09ae3e8eec4404e44906814d5d01cbca968a60ed4bfb01",
53+
],
54+
[
55+
"wallet_7",
56+
"b463f0df6c05d2f156393eee73f8016c5372caa0e9e29a901bb7171d90dc4f1401",
57+
],
58+
[
59+
"wallet_8",
60+
"6a1a754ba863d7bab14adbbc3f8ebb090af9e871ace621d3e5ab634e1422885e01",
61+
],
62+
[
63+
"wallet_9",
64+
"de433bdfa14ec43aa1098d5be594c8ffb20a31485ff9de2923b2689471c401b801",
65+
],
66+
].map((wallet) => {
67+
const label = wallet[0];
68+
const prvKey = wallet[1];
69+
const pubKey = getPublicKeyFromPrivate(prvKey);
70+
const devnet = new StacksDevnet();
71+
const initialUstxBalance = 100_000_000_000_000;
72+
const signerPrvKey = createStacksPrivateKey(prvKey);
73+
const signerPubKey = getPublicKeyFromPrivate(signerPrvKey.data);
74+
const btcAddress = publicKeyToBtcAddress(pubKey);
75+
const stxAddress = getAddressFromPrivateKey(
76+
prvKey,
77+
TransactionVersion.Testnet,
78+
);
79+
80+
return {
81+
label,
82+
stxAddress,
83+
btcAddress,
84+
signerPrvKey,
85+
signerPubKey,
86+
stackingClient: new StackingClient(stxAddress, devnet),
87+
ustxBalance: initialUstxBalance,
88+
isStacking: false,
89+
hasDelegated: false,
90+
lockedAddresses: [],
91+
amountToCommit: 0,
92+
poolMembers: [],
93+
delegatedTo: "",
94+
delegatedMaxAmount: 0,
95+
delegatedUntilBurnHt: 0,
96+
delegatedPoxAddress: "",
97+
amountLocked: 0,
98+
amountUnlocked: initialUstxBalance,
99+
unlockHeight: 0,
100+
firstLockedRewardCycle: 0,
101+
allowedContractCaller: "",
102+
callerAllowedBy: [],
103+
committedRewCycleIndexes: [],
104+
};
105+
});
106+
107+
// Track the number of times each command is run, so we can see if all the
108+
// commands are run at least once.
109+
const statistics = fs.readdirSync(path.join(__dirname)).filter((file) =>
110+
file.startsWith("pox_") && file.endsWith(".ts") &&
111+
file !== "pox_CommandModel.ts" && file !== "pox_Commands.ts"
112+
).map((file) => file.slice(4, -3)); // Remove "pox_" prefix and ".ts" suffix.
113+
114+
// This is the initial state of the model.
115+
const model = new Stub(
116+
new Map(wallets.map((wallet) => [wallet.stxAddress, wallet])),
117+
new Map(wallets.map((wallet) => [wallet.stxAddress, {
118+
ustxBalance: 100_000_000_000_000,
119+
isStacking: false,
120+
isStackingSolo: false,
121+
hasDelegated: false,
122+
lockedAddresses: [],
123+
amountToCommit: 0,
124+
poolMembers: [],
125+
delegatedTo: "",
126+
delegatedMaxAmount: 0,
127+
delegatedUntilBurnHt: 0,
128+
delegatedPoxAddress: "",
129+
amountLocked: 0,
130+
amountUnlocked: 100_000_000_000_000,
131+
unlockHeight: 0,
132+
firstLockedRewardCycle: 0,
133+
allowedContractCaller: "",
134+
callerAllowedBy: [],
135+
committedRewCycleIndexes: [],
136+
}])),
137+
new Map(statistics.map((commandName) => [commandName, 0])),
138+
);
139+
140+
simnet.setEpoch("3.0");
141+
142+
fc.assert(
143+
fc.property(
144+
PoxCommands(model.wallets, model.stackers, sut.network),
145+
(cmds) => {
146+
const initialState = () => ({ model: model, real: sut });
147+
fc.modelRun(initialState, cmds);
148+
},
149+
),
150+
{
151+
// Defines the number of test iterations to run; default is 100.
152+
numRuns: 1000,
153+
// Adjusts the level of detail in test reports. Default is 0 (minimal).
154+
// At level 2, reports include extensive details, helpful for deep
155+
// debugging. This includes not just the failing case and its seed, but
156+
// also a comprehensive log of all executed steps and their outcomes.
157+
verbose: 2,
158+
},
159+
);
160+
161+
model.reportCommandRuns();
162+
});

0 commit comments

Comments
 (0)