Skip to content

Commit 205986c

Browse files
committed
Merge remote-tracking branch 'core/release/3.2.0.0.0-rc1' into feat/sip31-boot-contract-tests
2 parents dcf19f5 + 2ecc90d commit 205986c

File tree

3 files changed

+128
-12
lines changed

3 files changed

+128
-12
lines changed

stacks-node/src/tests/nakamoto_integrations.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use std::time::{Duration, Instant};
2424
use std::{env, thread};
2525

2626
use clarity::vm::ast::ASTRules;
27-
use clarity::vm::costs::ExecutionCost;
28-
use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier};
27+
use clarity::vm::costs::{ExecutionCost, LimitedCostTracker};
28+
use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier, StandardPrincipalData};
2929
use clarity::vm::{ClarityName, ClarityVersion, Value};
3030
use http_types::headers::AUTHORIZATION;
3131
use lazy_static::lazy_static;
@@ -51,7 +51,7 @@ use stacks::chainstate::nakamoto::test_signers::TestSigners;
5151
use stacks::chainstate::nakamoto::{NakamotoBlock, NakamotoBlockHeader, NakamotoChainState};
5252
use stacks::chainstate::stacks::address::{PoxAddress, StacksAddressExtensions};
5353
use stacks::chainstate::stacks::boot::{
54-
MINERS_NAME, SIGNERS_VOTING_FUNCTION_NAME, SIGNERS_VOTING_NAME,
54+
MINERS_NAME, SIGNERS_VOTING_FUNCTION_NAME, SIGNERS_VOTING_NAME, SIP_031_TESTNET_ADDR,
5555
};
5656
use stacks::chainstate::stacks::db::{StacksChainState, StacksHeaderInfo};
5757
use stacks::chainstate::stacks::miner::{
@@ -12910,6 +12910,40 @@ fn test_sip_031_activation() {
1291012910
coinbase_txid.unwrap()
1291112911
);
1291212912

12913+
// Check that the boot contract has the right recipient
12914+
let sip_031_recipient = chainstate
12915+
.with_read_only_clarity_tx(
12916+
&sortdb
12917+
.index_handle_at_block(&chainstate, &latest_stacks_block_id)
12918+
.unwrap(),
12919+
&latest_stacks_block_id,
12920+
|conn| {
12921+
conn.with_readonly_clarity_env(
12922+
naka_conf.is_mainnet(),
12923+
naka_conf.burnchain.chain_id,
12924+
ClarityVersion::Clarity3,
12925+
PrincipalData::Standard(StandardPrincipalData::transient()),
12926+
None,
12927+
LimitedCostTracker::new_free(),
12928+
|tx| {
12929+
tx.eval_read_only(
12930+
&boot_code_id(SIP_031_NAME, naka_conf.is_mainnet()),
12931+
"(get-recipient)",
12932+
)
12933+
},
12934+
)
12935+
.unwrap()
12936+
},
12937+
)
12938+
.unwrap()
12939+
.expect_principal()
12940+
.unwrap();
12941+
12942+
assert_eq!(
12943+
sip_031_recipient,
12944+
PrincipalData::Standard(StandardPrincipalData::from(SIP_031_TESTNET_ADDR.clone()))
12945+
);
12946+
1291312947
coord_channel
1291412948
.lock()
1291512949
.expect("Mutex poisoned")

stackslib/src/chainstate/stacks/boot/mod.rs

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
use std::cmp;
1818
use std::collections::BTreeMap;
19+
use std::sync::LazyLock;
1920

21+
use clarity::types::Address;
2022
use clarity::vm::analysis::CheckErrors;
2123
use clarity::vm::ast::ASTRules;
2224
use clarity::vm::clarity::{Error as ClarityError, TransactionConnection};
@@ -34,6 +36,8 @@ use serde::Deserialize;
3436
use stacks_common::codec::StacksMessageCodec;
3537
use stacks_common::types::chainstate::{StacksAddress, StacksBlockId};
3638
use stacks_common::util::hash::{hex_bytes, to_hex};
39+
#[cfg(test)]
40+
use stacks_common::util::tests::TestFlag;
3741

3842
use crate::burnchains::{Burnchain, PoxConstants};
3943
use crate::chainstate::burn::db::sortdb::SortitionDB;
@@ -77,7 +81,8 @@ pub const SIGNERS_BODY: &str = std::include_str!("signers.clar");
7781
pub const SIGNERS_DB_0_BODY: &str = std::include_str!("signers-0-xxx.clar");
7882
pub const SIGNERS_DB_1_BODY: &str = std::include_str!("signers-1-xxx.clar");
7983
pub const SIGNERS_VOTING_BODY: &str = std::include_str!("signers-voting.clar");
80-
pub const SIP_031_BODY: &str = std::include_str!("sip-031.clar");
84+
/// Not public - be sure to use [make_sip_031_body]
85+
const SIP_031_BODY: &str = std::include_str!("sip-031.clar");
8186

8287
pub const COSTS_1_NAME: &str = "costs";
8388
pub const COSTS_2_NAME: &str = "costs-2";
@@ -90,6 +95,20 @@ pub const BOOT_TEST_POX_4_AGG_KEY_FNAME: &str = "aggregate-key";
9095

9196
pub const MINERS_NAME: &str = "miners";
9297

98+
/// The initial recipient address for SIP-031 on mainnet.
99+
pub const SIP_031_MAINNET_ADDR: LazyLock<StacksAddress> = LazyLock::new(|| {
100+
StacksAddress::from_string("SM1Z6BP8PDKYKXTZXXSKXFEY6NQ7RAM7DAEAYR045").unwrap()
101+
});
102+
103+
/// The initial recipient address for SIP-031 on testnet.
104+
pub const SIP_031_TESTNET_ADDR: LazyLock<StacksAddress> = LazyLock::new(|| {
105+
StacksAddress::from_string("ST1QCN9YMXMJPJ0Y5EMR627FCWDXQWT1CRK9CWN23").unwrap()
106+
});
107+
108+
#[cfg(test)]
109+
pub static TEST_SIP_031_ADDR: LazyLock<TestFlag<Option<StacksAddress>>> =
110+
LazyLock::new(TestFlag::default);
111+
93112
pub mod docs;
94113

95114
lazy_static! {
@@ -139,6 +158,40 @@ fn make_testnet_cost_voting() -> String {
139158
)
140159
}
141160

161+
#[cfg(test)]
162+
pub fn get_sip_031_recipient_addr(is_mainnet: bool) -> StacksAddress {
163+
if is_mainnet {
164+
SIP_031_MAINNET_ADDR.clone()
165+
} else {
166+
TEST_SIP_031_ADDR
167+
.get()
168+
.unwrap_or(SIP_031_TESTNET_ADDR.clone())
169+
}
170+
}
171+
172+
#[cfg(not(test))]
173+
pub fn get_sip_031_recipient_addr(is_mainnet: bool) -> StacksAddress {
174+
if is_mainnet {
175+
SIP_031_MAINNET_ADDR.clone()
176+
} else {
177+
SIP_031_TESTNET_ADDR.clone()
178+
}
179+
}
180+
181+
/// Generate the contract body for the SIP-031 contract.
182+
///
183+
/// When on mainnet, only the constant [SIP_031_MAINNET_ADDR] is used.
184+
/// Otherwise, on testnet, you can provide a configurable address.
185+
pub fn make_sip_031_body(is_mainnet: bool) -> String {
186+
let addr = get_sip_031_recipient_addr(is_mainnet).to_string();
187+
188+
SIP_031_BODY.replacen(
189+
"(define-data-var recipient principal tx-sender)",
190+
&format!("(define-data-var recipient principal '{addr})"),
191+
1,
192+
)
193+
}
194+
142195
pub fn make_contract_id(addr: &StacksAddress, name: &str) -> QualifiedContractIdentifier {
143196
QualifiedContractIdentifier::new(
144197
StandardPrincipalData::from(addr.clone()),
@@ -2631,7 +2684,7 @@ pub mod test {
26312684
)
26322685
(begin
26332686
;; take the stx from the tx-sender
2634-
2687+
26352688
(unwrap-panic (stx-transfer? amount-ustx tx-sender this-contract))
26362689
26372690
;; this contract stacks the stx given to it
@@ -5847,5 +5900,34 @@ pub mod test {
58475900
}
58485901
}
58495902

5903+
#[test]
5904+
fn test_sip031_addrs() {
5905+
assert_eq!(
5906+
SIP_031_MAINNET_ADDR.to_string(),
5907+
"SM1Z6BP8PDKYKXTZXXSKXFEY6NQ7RAM7DAEAYR045"
5908+
);
5909+
assert_eq!(
5910+
SIP_031_TESTNET_ADDR.to_string(),
5911+
"ST1QCN9YMXMJPJ0Y5EMR627FCWDXQWT1CRK9CWN23"
5912+
);
5913+
5914+
assert_eq!(
5915+
get_sip_031_recipient_addr(true),
5916+
SIP_031_MAINNET_ADDR.clone()
5917+
);
5918+
assert_eq!(
5919+
get_sip_031_recipient_addr(false),
5920+
SIP_031_TESTNET_ADDR.clone()
5921+
);
5922+
5923+
let transient = StacksAddress::from(StandardPrincipalData::transient().clone());
5924+
TEST_SIP_031_ADDR.set(Some(transient.clone()));
5925+
assert_eq!(get_sip_031_recipient_addr(false), transient.clone());
5926+
assert_eq!(
5927+
get_sip_031_recipient_addr(true),
5928+
SIP_031_MAINNET_ADDR.clone()
5929+
);
5930+
}
5931+
58505932
// TODO: need Stacking-rejection with a BTC address -- contract name in OP_RETURN? (NEXT)
58515933
}

stackslib/src/clarity_vm/clarity.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ use stacks_common::types::chainstate::{StacksBlockId, TrieHash};
3939
use crate::burnchains::PoxConstants;
4040
use crate::chainstate::nakamoto::signer_set::NakamotoSigners;
4141
use crate::chainstate::stacks::boot::{
42-
BOOT_CODE_COSTS, BOOT_CODE_COSTS_2, BOOT_CODE_COSTS_2_TESTNET, BOOT_CODE_COSTS_3,
43-
BOOT_CODE_COST_VOTING_TESTNET as BOOT_CODE_COST_VOTING, BOOT_CODE_POX_TESTNET, COSTS_2_NAME,
44-
COSTS_3_NAME, POX_2_MAINNET_CODE, POX_2_NAME, POX_2_TESTNET_CODE, POX_3_MAINNET_CODE,
45-
POX_3_NAME, POX_3_TESTNET_CODE, POX_4_CODE, POX_4_NAME, SIGNERS_BODY, SIGNERS_DB_0_BODY,
46-
SIGNERS_DB_1_BODY, SIGNERS_NAME, SIGNERS_VOTING_BODY, SIGNERS_VOTING_NAME, SIP_031_BODY,
47-
SIP_031_NAME,
42+
make_sip_031_body, BOOT_CODE_COSTS, BOOT_CODE_COSTS_2, BOOT_CODE_COSTS_2_TESTNET,
43+
BOOT_CODE_COSTS_3, BOOT_CODE_COST_VOTING_TESTNET as BOOT_CODE_COST_VOTING,
44+
BOOT_CODE_POX_TESTNET, COSTS_2_NAME, COSTS_3_NAME, POX_2_MAINNET_CODE, POX_2_NAME,
45+
POX_2_TESTNET_CODE, POX_3_MAINNET_CODE, POX_3_NAME, POX_3_TESTNET_CODE, POX_4_CODE, POX_4_NAME,
46+
SIGNERS_BODY, SIGNERS_DB_0_BODY, SIGNERS_DB_1_BODY, SIGNERS_NAME, SIGNERS_VOTING_BODY,
47+
SIGNERS_VOTING_NAME, SIP_031_NAME,
4848
};
4949
use crate::chainstate::stacks::db::{StacksAccount, StacksChainState};
5050
use crate::chainstate::stacks::events::{StacksTransactionEvent, StacksTransactionReceipt};
@@ -1643,7 +1643,7 @@ impl<'a> ClarityBlockConnection<'a, '_> {
16431643
TransactionSmartContract {
16441644
name: ContractName::try_from(SIP_031_NAME)
16451645
.expect("FATAL: invalid boot-code contract name"),
1646-
code_body: StacksString::from_str(SIP_031_BODY)
1646+
code_body: StacksString::from_str(&make_sip_031_body(mainnet))
16471647
.expect("FATAL: invalid boot code body"),
16481648
},
16491649
Some(ClarityVersion::Clarity3),

0 commit comments

Comments
 (0)