From 52dac73681b9a3e404c369ce84b940a5dfd16741 Mon Sep 17 00:00:00 2001 From: Hugo CAILLARD <911307+hugocaillard@users.noreply.github.com> Date: Mon, 17 Feb 2025 12:45:45 +0100 Subject: [PATCH 1/2] refactor: remove lazy-static --- Cargo.lock | 4 - Cargo.toml | 1 - components/clarinet-cli/Cargo.toml | 1 - components/clarinet-cli/src/lib.rs | 2 - components/clarinet-deployments/src/lib.rs | 2 +- .../clarinet-deployments/src/onchain/mod.rs | 2 +- components/clarinet-files/Cargo.toml | 1 - .../clarinet-files/src/network_manifest.rs | 10 +- components/clarinet-sdk-wasm/src/core.rs | 4 +- components/clarity-jupyter-kernel/Cargo.toml | 1 - components/clarity-jupyter-kernel/src/main.rs | 2 - components/clarity-lsp/Cargo.toml | 1 - .../src/common/requests/api_ref.rs | 9 +- .../src/common/requests/completion.rs | 83 +++++---- components/clarity-repl/Cargo.toml | 1 - .../src/analysis/ast_dependency_detector.rs | 5 +- .../clarity-repl/src/analysis/ast_visitor.rs | 12 +- components/clarity-repl/src/bin.rs | 2 - components/clarity-repl/src/lib.rs | 2 - components/clarity-repl/src/repl/boot/mod.rs | 169 +++++++++++++----- .../clarity-repl/src/repl/interpreter.rs | 6 +- components/clarity-repl/src/repl/session.rs | 73 ++------ 22 files changed, 204 insertions(+), 189 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f699b84fb..5f74a7947 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -720,7 +720,6 @@ dependencies = [ "crossterm", "fwdansi", "hiro-system-kit 0.1.0", - "lazy_static", "mac_address", "nix 0.24.2", "ratatui", @@ -770,7 +769,6 @@ dependencies = [ "clarity-repl", "dirs", "js-sys", - "lazy_static", "libsecp256k1 0.7.1", "serde", "serde-wasm-bindgen", @@ -857,7 +855,6 @@ dependencies = [ "clarity-repl", "console_error_panic_hook", "js-sys", - "lazy_static", "lsp-types", "regex", "serde", @@ -886,7 +883,6 @@ dependencies = [ "hiro-system-kit 0.1.0", "httparse", "js-sys", - "lazy_static", "log", "memchr", "mockito", diff --git a/Cargo.toml b/Cargo.toml index b8eab3d93..df30abfd3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,6 @@ version = "2.13.0" [workspace.dependencies] clarity = { git = "https://github.com/stacks-network/stacks-core.git", branch="feat/clarity-wasm-develop", package = "clarity", default-features = false } -lazy_static = { version = "1.5.0" } reqwest = { version = "0.12", default-features = false, features = [ "json", "rustls-tls", diff --git a/components/clarinet-cli/Cargo.toml b/components/clarinet-cli/Cargo.toml index 7e08718e9..cd1c008b7 100644 --- a/components/clarinet-cli/Cargo.toml +++ b/components/clarinet-cli/Cargo.toml @@ -24,7 +24,6 @@ serde = { version = "1", features = ["derive"] } serde_json = { version = "1.0.79", features = ["preserve_order"] } serde_derive = "1" tokio = { version = "1.35.1", features = ["full"] } -lazy_static = { workspace = true } atty = "0.2.14" crossterm = "0.27.0" ratatui = { version = "0.27.0", default-features = false, features = ["crossterm"] } diff --git a/components/clarinet-cli/src/lib.rs b/components/clarinet-cli/src/lib.rs index 12995d25f..1798df8e6 100644 --- a/components/clarinet-cli/src/lib.rs +++ b/components/clarinet-cli/src/lib.rs @@ -6,8 +6,6 @@ extern crate serde_json; #[macro_use] extern crate hiro_system_kit; -extern crate lazy_static; - pub extern crate clarity_repl; pub mod deployments; diff --git a/components/clarinet-deployments/src/lib.rs b/components/clarinet-deployments/src/lib.rs index 9c77ab1c8..35a2a82d6 100644 --- a/components/clarinet-deployments/src/lib.rs +++ b/components/clarinet-deployments/src/lib.rs @@ -1,5 +1,6 @@ use clarity_repl::clarity::vm::SymbolicExpression; use clarity_repl::clarity::StacksEpochId; +use clarity_repl::repl::boot::BOOT_CONTRACTS_DATA; use clarity_repl::repl::{ClarityCodeSource, ClarityContract, ContractDeployer}; use clarity_repl::repl::{DEFAULT_CLARITY_VERSION, DEFAULT_EPOCH}; @@ -32,7 +33,6 @@ use clarity_repl::clarity::vm::types::QualifiedContractIdentifier; use clarity_repl::clarity::vm::ContractName; use clarity_repl::clarity::vm::EvaluationResult; use clarity_repl::clarity::vm::ExecutionResult; -use clarity_repl::repl::session::BOOT_CONTRACTS_DATA; use clarity_repl::repl::Session; use clarity_repl::repl::SessionSettings; use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque}; diff --git a/components/clarinet-deployments/src/onchain/mod.rs b/components/clarinet-deployments/src/onchain/mod.rs index 9a2231817..56beae935 100644 --- a/components/clarinet-deployments/src/onchain/mod.rs +++ b/components/clarinet-deployments/src/onchain/mod.rs @@ -12,7 +12,7 @@ use clarity_repl::clarity::vm::types::{ }; use clarity_repl::clarity::vm::{ClarityName, Value}; use clarity_repl::clarity::{ClarityVersion, ContractName, EvaluationResult}; -use clarity_repl::repl::session::{ +use clarity_repl::repl::boot::{ BOOT_MAINNET_ADDRESS, BOOT_TESTNET_ADDRESS, V1_BOOT_CONTRACTS, V2_BOOT_CONTRACTS, V3_BOOT_CONTRACTS, }; diff --git a/components/clarinet-files/Cargo.toml b/components/clarinet-files/Cargo.toml index b12237bfd..0ef9a3737 100644 --- a/components/clarinet-files/Cargo.toml +++ b/components/clarinet-files/Cargo.toml @@ -12,7 +12,6 @@ toml = { version = "0.5.6", features = ["preserve_order"] } url = { version = "2.2.2", features = ["serde"] } bitcoin = { version = "0.31.2", optional = true } libsecp256k1 = "0.7.0" -lazy_static = { workspace = true} dirs = "6.0" clarity = { workspace = true } diff --git a/components/clarinet-files/src/network_manifest.rs b/components/clarinet-files/src/network_manifest.rs index 81b619a96..2b32f2254 100644 --- a/components/clarinet-files/src/network_manifest.rs +++ b/components/clarinet-files/src/network_manifest.rs @@ -1,11 +1,11 @@ use std::collections::BTreeMap; +use std::sync::LazyLock; use clarinet_utils::{get_bip32_keys_from_mnemonic, mnemonic_from_phrase, random_mnemonic}; use clarity::address::AddressHashMode; use clarity::types::chainstate::{StacksAddress, StacksPrivateKey}; use clarity::util::{hash::bytes_to_hex, secp256k1::Secp256k1PublicKey}; use clarity::vm::types::QualifiedContractIdentifier; -use lazy_static::lazy_static; use libsecp256k1::PublicKey; use serde::Serialize; use toml::value::Value; @@ -55,12 +55,12 @@ pub const DEFAULT_POX_PREPARE_LENGTH: u64 = 4; pub const DEFAULT_POX_REWARD_LENGTH: u64 = 10; pub const DEFAULT_FIRST_BURN_HEADER_HEIGHT: u64 = 100; -lazy_static! { - pub static ref DEFAULT_PRIVATE_KEYS: [StacksPrivateKey; 1] = [StacksPrivateKey::from_hex( +pub static DEFAULT_PRIVATE_KEYS: LazyLock<[StacksPrivateKey; 1]> = LazyLock::new(|| { + [StacksPrivateKey::from_hex( "7287ba251d44a4d3fd9276c88ce34c5c52a038955511cccaf77e61068649c17801", ) - .unwrap()]; -} + .unwrap()] +}); #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] diff --git a/components/clarinet-sdk-wasm/src/core.rs b/components/clarinet-sdk-wasm/src/core.rs index 282de63c7..ad7e342dc 100644 --- a/components/clarinet-sdk-wasm/src/core.rs +++ b/components/clarinet-sdk-wasm/src/core.rs @@ -20,7 +20,7 @@ use clarity_repl::clarity::{ Address, ClarityVersion, EvaluationResult, ExecutionResult, StacksEpochId, SymbolicExpression, }; use clarity_repl::repl::clarity_values::{uint8_to_string, uint8_to_value}; -use clarity_repl::repl::session::{CostsReport, BOOT_CONTRACTS_DATA}; +use clarity_repl::repl::session::CostsReport; use clarity_repl::repl::settings::RemoteDataSettings; use clarity_repl::repl::{ clarity_values, ClarityCodeSource, ClarityContract, ContractDeployer, Session, SessionSettings, @@ -1084,6 +1084,8 @@ impl SDK { include_boot_contracts: bool, boot_contracts_path: String, ) -> Result { + use clarity_repl::repl::boot::BOOT_CONTRACTS_DATA; + let contracts_locations = self.contracts_locations.clone(); let session = self.get_session_mut(); diff --git a/components/clarity-jupyter-kernel/Cargo.toml b/components/clarity-jupyter-kernel/Cargo.toml index 6a1dea9e8..18b2bcee5 100644 --- a/components/clarity-jupyter-kernel/Cargo.toml +++ b/components/clarity-jupyter-kernel/Cargo.toml @@ -16,7 +16,6 @@ categories = [ [dependencies] clarity-repl = { path = "../clarity-repl" } -lazy_static = { workspace = true } regex = "1.7" sha2 = "0.8.1" sha3 = "0.8.2" diff --git a/components/clarity-jupyter-kernel/src/main.rs b/components/clarity-jupyter-kernel/src/main.rs index 5eeb0d3f6..f0483ca01 100644 --- a/components/clarity-jupyter-kernel/src/main.rs +++ b/components/clarity-jupyter-kernel/src/main.rs @@ -7,8 +7,6 @@ #![allow(unused_mut)] // todo(ludo): would love to eliminate these directives at some point. -#[macro_use] -extern crate lazy_static; #[macro_use] extern crate json; #[macro_use] diff --git a/components/clarity-lsp/Cargo.toml b/components/clarity-lsp/Cargo.toml index acbd354a8..00a7ddb02 100644 --- a/components/clarity-lsp/Cargo.toml +++ b/components/clarity-lsp/Cargo.toml @@ -4,7 +4,6 @@ version.workspace = true edition = "2021" [dependencies] -lazy_static = { workspace = true } lsp-types = "0.94.0" regex = "1.7" serde = { version = "1", features = ["derive"] } diff --git a/components/clarity-lsp/src/common/requests/api_ref.rs b/components/clarity-lsp/src/common/requests/api_ref.rs index f682eeab1..8dabafca8 100644 --- a/components/clarity-lsp/src/common/requests/api_ref.rs +++ b/components/clarity-lsp/src/common/requests/api_ref.rs @@ -4,8 +4,8 @@ use clarity_repl::clarity::{ variables::NativeVariables, ClarityVersion, }; -use lazy_static::lazy_static; use std::collections::HashMap; +use std::sync::LazyLock; fn code(code: &str) -> String { ["```clarity", code.trim(), "```"].join("\n") @@ -26,8 +26,8 @@ fn format_removed_in(max_version: Option) -> String { .unwrap_or_default() } -lazy_static! { - pub static ref API_REF: HashMap)> = { +pub static API_REF: LazyLock)>> = + LazyLock::new(|| { let mut api_references: HashMap)> = HashMap::new(); let separator = "- - -"; @@ -96,5 +96,4 @@ lazy_static! { } api_references - }; -} + }); diff --git a/components/clarity-lsp/src/common/requests/completion.rs b/components/clarity-lsp/src/common/requests/completion.rs index cfff2f463..36c9e9b1d 100644 --- a/components/clarity-lsp/src/common/requests/completion.rs +++ b/components/clarity-lsp/src/common/requests/completion.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, vec}; +use std::{collections::HashMap, sync::LazyLock, vec}; use clarity_repl::{ analysis::ast_visitor::{traverse, ASTVisitor, TypedVar}, @@ -12,7 +12,6 @@ use clarity_repl::{ }, repl::DEFAULT_EPOCH, }; -use lazy_static::lazy_static; use lsp_types::{ CompletionItem, CompletionItemKind, Documentation, InsertTextFormat, MarkupContent, MarkupKind, Position, @@ -21,60 +20,68 @@ use regex::Regex; use super::helpers::{get_function_at_position, is_position_within_span}; -lazy_static! { - static ref COMPLETION_ITEMS_CLARITY_1: Vec = - build_default_native_keywords_list(ClarityVersion::Clarity1); - static ref COMPLETION_ITEMS_CLARITY_2: Vec = - build_default_native_keywords_list(ClarityVersion::Clarity2); - static ref COMPLETION_ITEMS_CLARITY_3: Vec = - build_default_native_keywords_list(ClarityVersion::Clarity3); - static ref VAR_FUNCTIONS: Vec = vec![ +static COMPLETION_ITEMS_CLARITY_1: LazyLock> = + LazyLock::new(|| build_default_native_keywords_list(ClarityVersion::Clarity1)); +static COMPLETION_ITEMS_CLARITY_2: LazyLock> = + LazyLock::new(|| build_default_native_keywords_list(ClarityVersion::Clarity2)); +static COMPLETION_ITEMS_CLARITY_3: LazyLock> = + LazyLock::new(|| build_default_native_keywords_list(ClarityVersion::Clarity3)); +static VAR_FUNCTIONS: LazyLock> = LazyLock::new(|| { + vec![ NativeFunctions::SetVar.to_string(), NativeFunctions::FetchVar.to_string(), - ]; - static ref MAP_FUNCTIONS: Vec = vec![ + ] +}); +static MAP_FUNCTIONS: LazyLock> = LazyLock::new(|| { + vec![ NativeFunctions::InsertEntry.to_string(), NativeFunctions::FetchEntry.to_string(), NativeFunctions::SetEntry.to_string(), NativeFunctions::DeleteEntry.to_string(), - ]; - static ref FT_FUNCTIONS: Vec = vec![ + ] +}); +static FT_FUNCTIONS: LazyLock> = LazyLock::new(|| { + vec![ NativeFunctions::GetTokenBalance.to_string(), NativeFunctions::GetTokenSupply.to_string(), NativeFunctions::BurnToken.to_string(), NativeFunctions::MintToken.to_string(), NativeFunctions::TransferToken.to_string(), - ]; - static ref NFT_FUNCTIONS: Vec = vec![ + ] +}); +static NFT_FUNCTIONS: LazyLock> = LazyLock::new(|| { + vec![ NativeFunctions::GetAssetOwner.to_string(), NativeFunctions::BurnAsset.to_string(), NativeFunctions::MintAsset.to_string(), NativeFunctions::TransferAsset.to_string(), - ]; - static ref ITERATOR_FUNCTIONS: Vec = vec![ + ] +}); +static ITERATOR_FUNCTIONS: LazyLock> = LazyLock::new(|| { + vec![ NativeFunctions::Map.to_string(), NativeFunctions::Filter.to_string(), NativeFunctions::Fold.to_string(), - ]; - static ref VALID_MAP_FUNCTIONS_CLARITY_1: Vec = - build_map_valid_cb_completion_items(ClarityVersion::Clarity1); - static ref VALID_MAP_FUNCTIONS_CLARITY_2: Vec = - build_map_valid_cb_completion_items(ClarityVersion::Clarity2); - static ref VALID_MAP_FUNCTIONS_CLARITY_3: Vec = - build_map_valid_cb_completion_items(ClarityVersion::Clarity3); - static ref VALID_FILTER_FUNCTIONS_CLARITY_1: Vec = - build_filter_valid_cb_completion_items(ClarityVersion::Clarity1); - static ref VALID_FILTER_FUNCTIONS_CLARITY_2: Vec = - build_filter_valid_cb_completion_items(ClarityVersion::Clarity2); - static ref VALID_FILTER_FUNCTIONS_CLARITY_3: Vec = - build_filter_valid_cb_completion_items(ClarityVersion::Clarity3); - static ref VALID_FOLD_FUNCTIONS_CLARITY_1: Vec = - build_fold_valid_cb_completion_items(ClarityVersion::Clarity1); - static ref VALID_FOLD_FUNCTIONS_CLARITY_2: Vec = - build_fold_valid_cb_completion_items(ClarityVersion::Clarity2); - static ref VALID_FOLD_FUNCTIONS_CLARITY_3: Vec = - build_fold_valid_cb_completion_items(ClarityVersion::Clarity3); -} + ] +}); +static VALID_MAP_FUNCTIONS_CLARITY_1: LazyLock> = + LazyLock::new(|| build_map_valid_cb_completion_items(ClarityVersion::Clarity1)); +static VALID_MAP_FUNCTIONS_CLARITY_2: LazyLock> = + LazyLock::new(|| build_map_valid_cb_completion_items(ClarityVersion::Clarity2)); +static VALID_MAP_FUNCTIONS_CLARITY_3: LazyLock> = + LazyLock::new(|| build_map_valid_cb_completion_items(ClarityVersion::Clarity3)); +static VALID_FILTER_FUNCTIONS_CLARITY_1: LazyLock> = + LazyLock::new(|| build_filter_valid_cb_completion_items(ClarityVersion::Clarity1)); +static VALID_FILTER_FUNCTIONS_CLARITY_2: LazyLock> = + LazyLock::new(|| build_filter_valid_cb_completion_items(ClarityVersion::Clarity2)); +static VALID_FILTER_FUNCTIONS_CLARITY_3: LazyLock> = + LazyLock::new(|| build_filter_valid_cb_completion_items(ClarityVersion::Clarity3)); +static VALID_FOLD_FUNCTIONS_CLARITY_1: LazyLock> = + LazyLock::new(|| build_fold_valid_cb_completion_items(ClarityVersion::Clarity1)); +static VALID_FOLD_FUNCTIONS_CLARITY_2: LazyLock> = + LazyLock::new(|| build_fold_valid_cb_completion_items(ClarityVersion::Clarity2)); +static VALID_FOLD_FUNCTIONS_CLARITY_3: LazyLock> = + LazyLock::new(|| build_fold_valid_cb_completion_items(ClarityVersion::Clarity3)); #[derive(Clone, Debug, Default)] pub struct ContractDefinedData { diff --git a/components/clarity-repl/Cargo.toml b/components/clarity-repl/Cargo.toml index 3ff617081..067bbe39c 100644 --- a/components/clarity-repl/Cargo.toml +++ b/components/clarity-repl/Cargo.toml @@ -25,7 +25,6 @@ categories = [ ansi_term = "0.12.1" # to be replaced with colored in the future chrono = "0.4.31" colored = { workspace = true } -lazy_static = { workspace = true } regex = "1.7" serde = { version = "1", features = ["derive"] } serde_json = { version = "1.0.47", features = ["unbounded_depth"] } diff --git a/components/clarity-repl/src/analysis/ast_dependency_detector.rs b/components/clarity-repl/src/analysis/ast_dependency_detector.rs index 22ad71d33..548db38d5 100644 --- a/components/clarity-repl/src/analysis/ast_dependency_detector.rs +++ b/components/clarity-repl/src/analysis/ast_dependency_detector.rs @@ -16,12 +16,11 @@ use clarity::vm::{ClarityName, ClarityVersion, SymbolicExpressionType}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::iter::FromIterator; use std::ops::{Deref, DerefMut}; +use std::sync::LazyLock; use super::ast_visitor::TypedVar; -lazy_static! { - pub static ref DEFAULT_NAME: ClarityName = ClarityName::from("placeholder"); -} +pub static DEFAULT_NAME: LazyLock = LazyLock::new(|| ClarityName::from("placeholder")); pub struct ASTDependencyDetector<'a> { dependencies: BTreeMap, diff --git a/components/clarity-repl/src/analysis/ast_visitor.rs b/components/clarity-repl/src/analysis/ast_visitor.rs index 240decb78..85aedf1e1 100644 --- a/components/clarity-repl/src/analysis/ast_visitor.rs +++ b/components/clarity-repl/src/analysis/ast_visitor.rs @@ -8,6 +8,7 @@ use clarity::vm::representations::{Span, TraitDefinition}; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier, TraitIdentifier, Value}; use clarity::vm::{ClarityName, ClarityVersion, SymbolicExpression, SymbolicExpressionType}; use std::collections::HashMap; +use std::sync::LazyLock; #[derive(Clone)] pub struct TypedVar<'a> { @@ -16,13 +17,10 @@ pub struct TypedVar<'a> { pub decl_span: Span, } -lazy_static! { - // Since the AST Visitor may be used before other checks have been performed, - // we may need a default value for some expressions. This can be used for a - // missing `ClarityName`. - static ref DEFAULT_NAME: ClarityName = ClarityName::from("placeholder__"); - static ref DEFAULT_EXPR: SymbolicExpression = SymbolicExpression::atom(DEFAULT_NAME.clone()); -} +pub static DEFAULT_NAME: LazyLock = + LazyLock::new(|| ClarityName::from("placeholder__")); +pub static DEFAULT_EXPR: LazyLock = + LazyLock::new(|| SymbolicExpression::atom(DEFAULT_NAME.clone())); pub trait ASTVisitor<'a> { fn traverse_expr(&mut self, expr: &'a SymbolicExpression) -> bool { diff --git a/components/clarity-repl/src/bin.rs b/components/clarity-repl/src/bin.rs index b834e452f..a78e36252 100644 --- a/components/clarity-repl/src/bin.rs +++ b/components/clarity-repl/src/bin.rs @@ -12,8 +12,6 @@ pub mod test_fixtures; #[macro_use] extern crate serde_json; #[macro_use] -extern crate lazy_static; -#[macro_use] extern crate serde_derive; #[macro_use] extern crate prettytable; diff --git a/components/clarity-repl/src/lib.rs b/components/clarity-repl/src/lib.rs index 7f341f240..c26aa1110 100644 --- a/components/clarity-repl/src/lib.rs +++ b/components/clarity-repl/src/lib.rs @@ -5,8 +5,6 @@ pub extern crate prettytable; #[macro_use] extern crate serde_json; #[macro_use] -extern crate lazy_static; -#[macro_use] extern crate serde_derive; #[macro_use] extern crate hiro_system_kit; diff --git a/components/clarity-repl/src/repl/boot/mod.rs b/components/clarity-repl/src/repl/boot/mod.rs index e90ac6340..5c9f1b8ec 100644 --- a/components/clarity-repl/src/repl/boot/mod.rs +++ b/components/clarity-repl/src/repl/boot/mod.rs @@ -14,43 +14,73 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -// This code is copied from stacks-blockchain/src/chainstate/atacks/boot/mod.rs +// This code is inspired from stacks-blockchain/src/chainstate/atacks/boot/mod.rs const BOOT_CODE_GENESIS: &str = std::include_str!("genesis.clar"); const BOOT_CODE_BNS: &str = std::include_str!("bns.clar"); const BOOT_CODE_LOCKUP: &str = std::include_str!("lockup.clar"); -pub const BOOT_CODE_COSTS: &str = std::include_str!("costs.clar"); -pub const BOOT_CODE_COSTS_2: &str = std::include_str!("costs-2.clar"); -pub const BOOT_CODE_COSTS_2_TESTNET: &str = std::include_str!("costs-2-testnet.clar"); -pub const BOOT_CODE_COSTS_3: &str = std::include_str!("costs-3.clar"); +const BOOT_CODE_COSTS: &str = std::include_str!("costs.clar"); +const BOOT_CODE_COSTS_2: &str = std::include_str!("costs-2.clar"); +const BOOT_CODE_COSTS_2_TESTNET: &str = std::include_str!("costs-2-testnet.clar"); +const BOOT_CODE_COSTS_3: &str = std::include_str!("costs-3.clar"); const BOOT_CODE_COST_VOTING_MAINNET: &str = std::include_str!("cost-voting.clar"); -const BOOT_CODE_POX_TESTNET_CONSTS: &str = std::include_str!("pox-testnet.clar"); -const BOOT_CODE_POX_MAINNET_CONSTS: &str = std::include_str!("pox-mainnet.clar"); -const BOOT_CODE_POX_BODY: &str = std::include_str!("pox.clar"); +const POX_TESTNET: &str = std::include_str!("pox-testnet.clar"); +const POX_MAINNET: &str = std::include_str!("pox-mainnet.clar"); +const POX_BODY: &str = std::include_str!("pox.clar"); const POX_2_BODY: &str = std::include_str!("pox-2.clar"); const POX_3_BODY: &str = std::include_str!("pox-3.clar"); const POX_4_BODY: &str = std::include_str!("pox-4.clar"); -pub const BOOT_CODE_SIGNERS: &str = std::include_str!("signers.clar"); -pub const BOOT_CODE_SIGNERS_VOTING: &str = std::include_str!("signers-voting.clar"); - -lazy_static! { - pub static ref BOOT_CODE_POX_MAINNET: String = - format!("{}\n{}", BOOT_CODE_POX_MAINNET_CONSTS, BOOT_CODE_POX_BODY); - pub static ref BOOT_CODE_POX_TESTNET: String = - format!("{}\n{}", BOOT_CODE_POX_TESTNET_CONSTS, BOOT_CODE_POX_BODY); - pub static ref POX_2_MAINNET_CODE: String = - format!("{}\n{}", BOOT_CODE_POX_MAINNET_CONSTS, POX_2_BODY); - pub static ref POX_2_TESTNET_CODE: String = - format!("{}\n{}", BOOT_CODE_POX_TESTNET_CONSTS, POX_2_BODY); - pub static ref POX_3_MAINNET_CODE: String = - format!("{}\n{}", BOOT_CODE_POX_MAINNET_CONSTS, POX_3_BODY); - pub static ref POX_3_TESTNET_CODE: String = - format!("{}\n{}", BOOT_CODE_POX_TESTNET_CONSTS, POX_3_BODY); - pub static ref BOOT_CODE_COST_VOTING_TESTNET: String = make_testnet_cost_voting(); - pub static ref STACKS_BOOT_CODE_MAINNET: [(&'static str, &'static str); 13] = [ +const BOOT_CODE_SIGNERS: &str = std::include_str!("signers.clar"); +const BOOT_CODE_SIGNERS_VOTING: &str = std::include_str!("signers-voting.clar"); + +use std::{collections::BTreeMap, sync::LazyLock}; + +use clarity::{ + types::StacksEpochId, + vm::{ + ast::ContractAST, + types::{PrincipalData, QualifiedContractIdentifier, StandardPrincipalData}, + ClarityVersion, + }, +}; + +use crate::repl::{ + ClarityCodeSource, ClarityContract, ClarityInterpreter, ContractDeployer, Settings, +}; + +fn make_testnet_cost_voting() -> String { + BOOT_CODE_COST_VOTING_MAINNET + .replacen( + "(define-constant VETO_LENGTH u1008)", + "(define-constant VETO_LENGTH u50)", + 1, + ) + .replacen( + "(define-constant REQUIRED_VETOES u500)", + "(define-constant REQUIRED_VETOES u25)", + 1, + ) +} + +static BOOT_CODE_POX_MAINNET: LazyLock = + LazyLock::new(|| format!("{}\n{}", POX_MAINNET, POX_BODY)); +static BOOT_CODE_POX_TESTNET: LazyLock = + LazyLock::new(|| format!("{}\n{}", POX_TESTNET, POX_BODY)); +static BOOT_CODE_POX_2_MAINNET: LazyLock = + LazyLock::new(|| format!("{}\n{}", POX_MAINNET, POX_2_BODY)); +static BOOT_CODE_POX_2_TESTNET: LazyLock = + LazyLock::new(|| format!("{}\n{}", POX_TESTNET, POX_2_BODY)); +static BOOT_CODE_POX_3_MAINNET: LazyLock = + LazyLock::new(|| format!("{}\n{}", POX_MAINNET, POX_3_BODY)); +static BOOT_CODE_POX_3_TESTNET: LazyLock = + LazyLock::new(|| format!("{}\n{}", POX_TESTNET, POX_3_BODY)); +static BOOT_CODE_COST_VOTING_TESTNET: LazyLock = LazyLock::new(make_testnet_cost_voting); + +pub static BOOT_CODE_MAINNET: LazyLock<[(&'static str, &'static str); 13]> = LazyLock::new(|| { + [ ("pox", &BOOT_CODE_POX_MAINNET), ("lockup", BOOT_CODE_LOCKUP), ("costs", BOOT_CODE_COSTS), @@ -58,14 +88,17 @@ lazy_static! { ("bns", BOOT_CODE_BNS), ("genesis", BOOT_CODE_GENESIS), ("costs-2", BOOT_CODE_COSTS_2), - ("pox-2", &POX_2_MAINNET_CODE), + ("pox-2", &BOOT_CODE_POX_2_MAINNET), ("costs-3", BOOT_CODE_COSTS_3), - ("pox-3", &POX_3_MAINNET_CODE), + ("pox-3", &BOOT_CODE_POX_3_MAINNET), ("pox-4", POX_4_BODY), ("signers", BOOT_CODE_SIGNERS), ("signers-voting", BOOT_CODE_SIGNERS_VOTING), - ]; - pub static ref STACKS_BOOT_CODE_TESTNET: [(&'static str, &'static str); 13] = [ + ] +}); + +pub static BOOT_CODE_TESTNET: LazyLock<[(&'static str, &'static str); 13]> = LazyLock::new(|| { + [ ("pox", &BOOT_CODE_POX_TESTNET), ("lockup", BOOT_CODE_LOCKUP), ("costs", BOOT_CODE_COSTS), @@ -73,25 +106,69 @@ lazy_static! { ("bns", BOOT_CODE_BNS), ("genesis", BOOT_CODE_GENESIS), ("costs-2", BOOT_CODE_COSTS_2_TESTNET), - ("pox-2", &POX_2_TESTNET_CODE), + ("pox-2", &BOOT_CODE_POX_2_TESTNET), ("costs-3", BOOT_CODE_COSTS_3), - ("pox-3", &POX_3_TESTNET_CODE), + ("pox-3", &BOOT_CODE_POX_3_TESTNET), ("pox-4", POX_4_BODY), ("signers", BOOT_CODE_SIGNERS), ("signers-voting", BOOT_CODE_SIGNERS_VOTING), + ] +}); + +pub static BOOT_TESTNET_ADDRESS: &str = "ST000000000000000000002AMW42H"; +pub static BOOT_MAINNET_ADDRESS: &str = "SP000000000000000000002Q6VF78"; + +pub static V1_BOOT_CONTRACTS: &[&str] = + &["genesis", "lockup", "bns", "cost-voting", "costs", "pox"]; +pub static V2_BOOT_CONTRACTS: &[&str] = &["costs-2"]; +pub static V3_BOOT_CONTRACTS: &[&str] = &["pox-2", "costs-3"]; +pub static V4_BOOT_CONTRACTS: &[&str] = &["pox-3"]; +pub static V5_BOOT_CONTRACTS: &[&str] = &["pox-4", "signers", "signers-voting"]; + +pub static BOOT_TESTNET_PRINCIPAL: LazyLock = + LazyLock::new(|| PrincipalData::parse_standard_principal(BOOT_TESTNET_ADDRESS).unwrap()); +pub static BOOT_MAINNET_PRINCIPAL: LazyLock = + LazyLock::new(|| PrincipalData::parse_standard_principal(BOOT_MAINNET_ADDRESS).unwrap()); +pub static BOOT_CONTRACTS_DATA: LazyLock< + BTreeMap, +> = LazyLock::new(|| { + let mut result = BTreeMap::new(); + let deploy: [(&StandardPrincipalData, [(&str, &str); 13]); 2] = [ + (&*BOOT_TESTNET_PRINCIPAL, *BOOT_CODE_TESTNET), + // merge BOOT_CODE_COMMON with STACKS_BOOT_CODE_MAINNET + (&*BOOT_MAINNET_PRINCIPAL, *BOOT_CODE_MAINNET), ]; -} -fn make_testnet_cost_voting() -> String { - BOOT_CODE_COST_VOTING_MAINNET - .replacen( - "(define-constant VETO_LENGTH u1008)", - "(define-constant VETO_LENGTH u50)", - 1, - ) - .replacen( - "(define-constant REQUIRED_VETOES u500)", - "(define-constant REQUIRED_VETOES u25)", - 1, - ) -} + let interpreter = + ClarityInterpreter::new(StandardPrincipalData::transient(), Settings::default()); + for (deployer, boot_code) in deploy.iter() { + for (name, code) in boot_code.iter() { + let (epoch, clarity_version) = match *name { + "pox-4" | "signers" | "signers-voting" => { + (StacksEpochId::Epoch25, ClarityVersion::Clarity2) + } + "pox-3" => (StacksEpochId::Epoch24, ClarityVersion::Clarity2), + "pox-2" | "costs-3" => (StacksEpochId::Epoch21, ClarityVersion::Clarity2), + "costs-2" => (StacksEpochId::Epoch2_05, ClarityVersion::Clarity1), + "genesis" | "lockup" | "bns" | "cost-voting" | "costs" | "pox" => { + (StacksEpochId::Epoch20, ClarityVersion::Clarity1) + } + _ => panic!("Unknown boot contract: {}", name), + }; + + let boot_contract = ClarityContract { + code_source: ClarityCodeSource::ContractInMemory(code.to_string()), + deployer: ContractDeployer::Address(deployer.to_address()), + name: name.to_string(), + epoch, + clarity_version, + }; + let (ast, _, _) = interpreter.build_ast(&boot_contract); + result.insert( + boot_contract.expect_resolved_contract_identifier(None), + (boot_contract, ast), + ); + } + } + result +}); diff --git a/components/clarity-repl/src/repl/interpreter.rs b/components/clarity-repl/src/repl/interpreter.rs index f1151eae5..74fcd3d7d 100644 --- a/components/clarity-repl/src/repl/interpreter.rs +++ b/components/clarity-repl/src/repl/interpreter.rs @@ -1192,11 +1192,9 @@ impl ClarityInterpreter { #[cfg(test)] mod tests { use super::*; - use crate::analysis::Settings as AnalysisSettings; use crate::repl::settings::RemoteDataSettings; - use crate::{ - repl::session::BOOT_CONTRACTS_DATA, test_fixtures::clarity_contract::ClarityContractBuilder, - }; + use crate::test_fixtures::clarity_contract::ClarityContractBuilder; + use crate::{analysis::Settings as AnalysisSettings, repl::boot::BOOT_CONTRACTS_DATA}; use clarity::{ types::{chainstate::StacksAddress, Address}, vm::{self, types::TupleData, ClarityVersion}, diff --git a/components/clarity-repl/src/repl/session.rs b/components/clarity-repl/src/repl/session.rs index 16ad03fcb..a604d66b9 100644 --- a/components/clarity-repl/src/repl/session.rs +++ b/components/clarity-repl/src/repl/session.rs @@ -1,9 +1,10 @@ -use super::boot::{STACKS_BOOT_CODE_MAINNET, STACKS_BOOT_CODE_TESTNET}; +use super::boot::{ + BOOT_CODE_MAINNET, BOOT_CODE_TESTNET, BOOT_MAINNET_PRINCIPAL, BOOT_TESTNET_PRINCIPAL, +}; use super::diagnostic::output_diagnostic; use super::{ClarityCodeSource, ClarityContract, ClarityInterpreter, ContractDeployer}; use crate::analysis::coverage::CoverageHook; use crate::repl::clarity_values::value_to_string; -use crate::repl::Settings; use crate::utils; use clarity::codec::StacksMessageCodec; use clarity::types::chainstate::StacksAddress; @@ -13,9 +14,7 @@ use clarity::vm::diagnostic::{Diagnostic, Level}; use clarity::vm::docs::{make_api_reference, make_define_reference, make_keyword_reference}; use clarity::vm::functions::define::DefineFunctions; use clarity::vm::functions::NativeFunctions; -use clarity::vm::types::{ - PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, Value, -}; +use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier, Value}; use clarity::vm::variables::NativeVariables; use clarity::vm::{ ClarityVersion, CostSynthesis, EvalHook, EvaluationResult, ExecutionResult, ParsedContract, @@ -32,58 +31,6 @@ use clarity::vm::analysis::ContractAnalysis; use super::SessionSettings; -pub static BOOT_TESTNET_ADDRESS: &str = "ST000000000000000000002AMW42H"; -pub static BOOT_MAINNET_ADDRESS: &str = "SP000000000000000000002Q6VF78"; - -pub static V1_BOOT_CONTRACTS: &[&str] = &["bns"]; -pub static V2_BOOT_CONTRACTS: &[&str] = &["pox-2", "costs-3"]; -pub static V3_BOOT_CONTRACTS: &[&str] = &["pox-3"]; -pub static V4_BOOT_CONTRACTS: &[&str] = &["pox-4"]; - -lazy_static! { - static ref BOOT_TESTNET_PRINCIPAL: StandardPrincipalData = - PrincipalData::parse_standard_principal(BOOT_TESTNET_ADDRESS).unwrap(); - static ref BOOT_MAINNET_PRINCIPAL: StandardPrincipalData = - PrincipalData::parse_standard_principal(BOOT_MAINNET_ADDRESS).unwrap(); - pub static ref BOOT_CONTRACTS_DATA: BTreeMap = { - let mut result = BTreeMap::new(); - let deploy: [(&StandardPrincipalData, [(&str, &str); 13]); 2] = [ - (&*BOOT_TESTNET_PRINCIPAL, *STACKS_BOOT_CODE_TESTNET), - (&*BOOT_MAINNET_PRINCIPAL, *STACKS_BOOT_CODE_MAINNET), - ]; - - let interpreter = - ClarityInterpreter::new(StandardPrincipalData::transient(), Settings::default()); - for (deployer, boot_code) in deploy.iter() { - for (name, code) in boot_code.iter() { - let (epoch, clarity_version) = match *name { - "pox-4" | "signers" | "signers-voting" => { - (StacksEpochId::Epoch25, ClarityVersion::Clarity2) - } - "pox-3" => (StacksEpochId::Epoch24, ClarityVersion::Clarity2), - "pox-2" | "costs-3" => (StacksEpochId::Epoch21, ClarityVersion::Clarity2), - "cost-2" => (StacksEpochId::Epoch2_05, ClarityVersion::Clarity1), - _ => (StacksEpochId::Epoch20, ClarityVersion::Clarity1), - }; - - let boot_contract = ClarityContract { - code_source: ClarityCodeSource::ContractInMemory(code.to_string()), - deployer: ContractDeployer::Address(deployer.to_address()), - name: name.to_string(), - epoch, - clarity_version, - }; - let (ast, _, _) = interpreter.build_ast(&boot_contract); - result.insert( - boot_contract.expect_resolved_contract_identifier(None), - (boot_contract, ast), - ); - } - } - result - }; -} - #[derive(Clone, Debug, Serialize)] pub struct CostsReport { pub test_name: String, @@ -169,9 +116,9 @@ impl Session { fn deploy_boot_contracts(&mut self, mainnet: bool) { let boot_code = if mainnet { - *STACKS_BOOT_CODE_MAINNET + *BOOT_CODE_MAINNET } else { - *STACKS_BOOT_CODE_TESTNET + *BOOT_CODE_TESTNET }; let tx_sender = self.interpreter.get_tx_sender(); @@ -1144,6 +1091,8 @@ impl Session { #[cfg(feature = "cli")] pub fn get_contracts(&self) -> Option { + use super::boot::{BOOT_MAINNET_ADDRESS, BOOT_TESTNET_ADDRESS}; + if self.contracts.is_empty() { return None; } @@ -1346,7 +1295,11 @@ mod tests { use super::*; use crate::{ - repl::{settings::Account, DEFAULT_EPOCH}, + repl::{ + boot::{BOOT_MAINNET_ADDRESS, BOOT_TESTNET_ADDRESS}, + settings::Account, + DEFAULT_EPOCH, + }, test_fixtures::clarity_contract::ClarityContractBuilder, }; From 7a24be1092230a1bfd6b254ab1e4cc1a22a3e976 Mon Sep 17 00:00:00 2001 From: Hugo CAILLARD <911307+hugocaillard@users.noreply.github.com> Date: Mon, 17 Feb 2025 12:49:48 +0100 Subject: [PATCH 2/2] docs: comments --- components/clarity-repl/src/analysis/ast_visitor.rs | 3 +++ components/clarity-repl/src/repl/boot/mod.rs | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/components/clarity-repl/src/analysis/ast_visitor.rs b/components/clarity-repl/src/analysis/ast_visitor.rs index 85aedf1e1..b2be3fdf4 100644 --- a/components/clarity-repl/src/analysis/ast_visitor.rs +++ b/components/clarity-repl/src/analysis/ast_visitor.rs @@ -17,6 +17,9 @@ pub struct TypedVar<'a> { pub decl_span: Span, } +// Since the AST Visitor may be used before other checks have been performed, +// we may need a default value for some expressions. This can be used for a +// missing `ClarityName`. pub static DEFAULT_NAME: LazyLock = LazyLock::new(|| ClarityName::from("placeholder__")); pub static DEFAULT_EXPR: LazyLock = diff --git a/components/clarity-repl/src/repl/boot/mod.rs b/components/clarity-repl/src/repl/boot/mod.rs index 5c9f1b8ec..356d2ec40 100644 --- a/components/clarity-repl/src/repl/boot/mod.rs +++ b/components/clarity-repl/src/repl/boot/mod.rs @@ -135,7 +135,6 @@ pub static BOOT_CONTRACTS_DATA: LazyLock< let mut result = BTreeMap::new(); let deploy: [(&StandardPrincipalData, [(&str, &str); 13]); 2] = [ (&*BOOT_TESTNET_PRINCIPAL, *BOOT_CODE_TESTNET), - // merge BOOT_CODE_COMMON with STACKS_BOOT_CODE_MAINNET (&*BOOT_MAINNET_PRINCIPAL, *BOOT_CODE_MAINNET), ];