From 042750b6f4fe948c13045946319d4b15f9c1946b Mon Sep 17 00:00:00 2001 From: Hugo CAILLARD <911307+hugocaillard@users.noreply.github.com> Date: Fri, 17 Jan 2025 19:39:30 +0100 Subject: [PATCH] refactor: handle at-block --- .vscode/settings.json | 5 +- Cargo.lock | 2 +- components/clarinet-sdk-wasm/Cargo.toml | 3 +- components/clarinet-sdk-wasm/src/core.rs | 8 +- components/clarinet-sdk/browser/package.json | 4 +- .../clarinet-sdk/common/src/httpClient.ts | 4 + components/clarinet-sdk/node/package.json | 4 +- .../node/tests/remote-data.test.ts | 2 +- components/clarity-repl/src/repl/datastore.rs | 226 ++++++++++++------ .../src/repl/remote_data_store.rs | 162 ------------- components/clarity-repl/src/repl/settings.rs | 2 +- components/clarity-repl/tests/remote_data.rs | 109 +++++++++ package-lock.json | 112 +-------- 13 files changed, 300 insertions(+), 343 deletions(-) delete mode 100644 components/clarity-repl/src/repl/remote_data_store.rs create mode 100644 components/clarity-repl/tests/remote_data.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index d2bf76f02..dafbcf295 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,10 @@ { "rust-analyzer.check.command": "clippy", - "rust-analyzer.check.workspace": true, + // rust-analyzer hack: + // manually set --workspace in extraArgs so that it's always set only one time + "rust-analyzer.check.workspace": false, "rust-analyzer.check.extraArgs": [ + "--workspace", "--exclude=clarinet-sdk-wasm", "--exclude=clarity-jupyter-kernel" ] diff --git a/Cargo.lock b/Cargo.lock index faa2e41ab..9834b974e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -776,7 +776,7 @@ dependencies = [ [[package]] name = "clarinet-sdk-wasm" -version = "2.12.0" +version = "2.13.0-beta1" dependencies = [ "clarinet-deployments", "clarinet-files", diff --git a/components/clarinet-sdk-wasm/Cargo.toml b/components/clarinet-sdk-wasm/Cargo.toml index 920eeebc8..5a28808b7 100644 --- a/components/clarinet-sdk-wasm/Cargo.toml +++ b/components/clarinet-sdk-wasm/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "clarinet-sdk-wasm" -version.workspace = true +# version.workspace = true +version = "2.13.0-beta1" edition = "2021" license = "GPL-3.0" repository = "https://github.com/hirosystems/clarinet" diff --git a/components/clarinet-sdk-wasm/src/core.rs b/components/clarinet-sdk-wasm/src/core.rs index 0e4164a49..db85a9996 100644 --- a/components/clarinet-sdk-wasm/src/core.rs +++ b/components/clarinet-sdk-wasm/src/core.rs @@ -371,6 +371,7 @@ impl SDK { .interpreter .clarity_datastore .set_http_client(self.http_client.clone()); + self.session = Some(session); Ok(()) } @@ -383,7 +384,7 @@ impl SDK { .ok_or("Failed to parse manifest location")?; let ProjectCache { - session, + mut session, contracts_interfaces, contracts_locations, accounts, @@ -392,6 +393,11 @@ impl SDK { None => self.setup_session(&manifest_location).await?, }; + session + .interpreter + .clarity_datastore + .set_http_client(self.http_client.clone()); + self.deployer = session.interpreter.get_tx_sender().to_string(); self.contracts_interfaces = contracts_interfaces; diff --git a/components/clarinet-sdk/browser/package.json b/components/clarinet-sdk/browser/package.json index 6128c703d..7228ae847 100644 --- a/components/clarinet-sdk/browser/package.json +++ b/components/clarinet-sdk/browser/package.json @@ -1,6 +1,6 @@ { "name": "@hirosystems/clarinet-sdk-browser", - "version": "2.12.0", + "version": "2.13.0-beta1", "description": "A SDK to interact with Clarity Smart Contracts in the browser", "homepage": "https://www.hiro.so/clarinet", "repository": { @@ -28,7 +28,7 @@ "license": "GPL-3.0", "readme": "./README.md", "dependencies": { - "@hirosystems/clarinet-sdk-wasm-browser": "^2.12.0", + "@hirosystems/clarinet-sdk-wasm-browser": "2.13.0-beta1", "@stacks/transactions": "^6.13.0", "sync-request": "^6.1.0" } diff --git a/components/clarinet-sdk/common/src/httpClient.ts b/components/clarinet-sdk/common/src/httpClient.ts index 17243acc8..3d60c181e 100644 --- a/components/clarinet-sdk/common/src/httpClient.ts +++ b/components/clarinet-sdk/common/src/httpClient.ts @@ -3,9 +3,13 @@ import request, { HttpVerb, Options as HttpOptions } from "sync-request"; const encoder = new TextEncoder(); export function httpClient(method: HttpVerb, path: string, options?: HttpOptions): Uint8Array { + console.log("-".repeat(20)); + console.log("httpClient", method, path, options); const response = request(method, path, options); if (typeof response.body === "string") { return encoder.encode(response.body); } + console.log("httpClient response", response.statusCode); + console.log("-".repeat(20)); return response.body; } diff --git a/components/clarinet-sdk/node/package.json b/components/clarinet-sdk/node/package.json index e355582cc..5b2ea7234 100644 --- a/components/clarinet-sdk/node/package.json +++ b/components/clarinet-sdk/node/package.json @@ -1,6 +1,6 @@ { "name": "@hirosystems/clarinet-sdk", - "version": "2.12.0", + "version": "2.13.0-beta1", "description": "A SDK to interact with Clarity Smart Contracts in node.js", "homepage": "https://www.hiro.so/clarinet", "repository": { @@ -61,7 +61,7 @@ "license": "GPL-3.0", "readme": "./README.md", "dependencies": { - "@hirosystems/clarinet-sdk-wasm": "^2.12.0", + "@hirosystems/clarinet-sdk-wasm": "2.13.0-beta1", "@stacks/transactions": "^6.13.0", "kolorist": "^1.8.0", "prompts": "^2.4.2", diff --git a/components/clarinet-sdk/node/tests/remote-data.test.ts b/components/clarinet-sdk/node/tests/remote-data.test.ts index f0a851a0e..57c8e4c37 100644 --- a/components/clarinet-sdk/node/tests/remote-data.test.ts +++ b/components/clarinet-sdk/node/tests/remote-data.test.ts @@ -30,7 +30,7 @@ beforeEach(async () => { await simnet.initEmptySession({ enabled: true, api_url: "http://localhost:3999", - initial_height: 186, + initial_height: 56, }); }); diff --git a/components/clarity-repl/src/repl/datastore.rs b/components/clarity-repl/src/repl/datastore.rs index b5095a7ad..3569b71ed 100644 --- a/components/clarity-repl/src/repl/datastore.rs +++ b/components/clarity-repl/src/repl/datastore.rs @@ -13,6 +13,7 @@ use clarity::vm::errors::InterpreterResult as Result; use clarity::vm::types::{QualifiedContractIdentifier, TupleData}; use clarity::vm::StacksEpoch; use pox_locking::handle_contract_call_special_cases; +use serde::Deserialize; use sha2::{Digest, Sha512_256}; #[cfg(target_arch = "wasm32")] use wasm_bindgen::JsValue; @@ -41,6 +42,57 @@ fn epoch_to_peer_version(epoch: StacksEpochId) -> u8 { } } +#[derive(Deserialize)] +struct ClarityDataResponse { + pub data: String, +} + +#[derive(Clone, Debug, Deserialize)] +struct RpcBlockInfoResponse { + pub height: u32, + pub burn_block_height: u32, + pub tenure_height: u32, + pub block_time: u64, + pub burn_block_time: u64, + pub hash: String, + pub index_block_hash: String, + pub burn_block_hash: String, +} + +#[derive(Clone, Debug, Deserialize)] +#[allow(dead_code)] +struct RpcBlockInfo { + pub height: u32, + pub burn_block_height: u32, + pub tenure_height: u32, + pub block_time: u64, + pub burn_block_time: u64, + pub hash: BlockHeaderHash, + pub index_block_hash: StacksBlockId, + pub burn_block_hash: BurnchainHeaderHash, +} + +impl From for RpcBlockInfo { + fn from(response: RpcBlockInfoResponse) -> Self { + let hash = BlockHeaderHash::from_hex(&response.hash.replacen("0x", "", 1)).unwrap(); + let index_block_hash = + StacksBlockId::from_hex(&response.index_block_hash.replacen("0x", "", 1)).unwrap(); + let burn_block_hash = + BurnchainHeaderHash::from_hex(&response.burn_block_hash.replacen("0x", "", 1)).unwrap(); + + RpcBlockInfo { + height: response.height, + burn_block_height: response.burn_block_height, + tenure_height: response.tenure_height, + block_time: response.block_time, + burn_block_time: response.burn_block_time, + hash, + index_block_hash, + burn_block_hash, + } + } +} + #[derive(Clone, Debug)] struct StoreEntry(StacksBlockId, String); @@ -54,22 +106,12 @@ pub struct ClarityDatastore { height_at_chain_tip: HashMap, remote_data_settings: RemoteDataSettings, - remote_chaintip_cache: HashMap, + remote_block_info_cache: HashMap, #[cfg(target_arch = "wasm32")] http_client: Option, } -#[derive(Deserialize)] -struct ClarityDataResponse { - pub data: String, -} - -#[derive(Deserialize)] -struct BlockInfoResponse { - pub index_block_hash: String, -} - #[derive(Clone, Debug)] struct BurnBlockInfo { burn_block_time: u64, @@ -146,7 +188,7 @@ impl Default for ClarityDatastore { impl ClarityDatastore { pub fn new(remote_data_settings: RemoteDataSettings) -> Self { let block_height = if remote_data_settings.enabled { - remote_data_settings.initial_height.unwrap_or(32) + remote_data_settings.initial_height.unwrap_or(0) } else { 0 }; @@ -160,7 +202,7 @@ impl ClarityDatastore { height_at_chain_tip: HashMap::from([(id, block_height)]), remote_data_settings, - remote_chaintip_cache: HashMap::new(), + remote_block_info_cache: HashMap::new(), #[cfg(target_arch = "wasm32")] http_client: None, } @@ -280,29 +322,62 @@ impl ClarityDatastore { } } - fn get_remote_chaintip(&mut self, height: u32) -> String { - if let Some(cached) = self.remote_chaintip_cache.get(&height) { - println!("using cached chaintip for height: {}", height); - return cached.to_string(); - } - println!("fetching remote chaintip for height: {}", height); - - let url = format!("/extended/v2/blocks/{}", height); - - let data = self - .fetch_data::(&url) + fn fetch_block_info(&self, url: &str) -> RpcBlockInfo { + let raw_block_info = self + .fetch_data::(url) .unwrap_or_else(|e| { panic!("unable to parse json, error: {}", e); }) .unwrap_or_else(|| { - panic!("unable to get remote chaintip"); + panic!("unable to get remote block info"); }); - let block_hash = data.index_block_hash.replacen("0x", "", 1); - self.remote_chaintip_cache - .insert(height, block_hash.clone()); + RpcBlockInfo::from(raw_block_info.clone()) + } + + fn get_remote_block_info_from_height(&mut self, height: u32) -> RpcBlockInfo { + let url = format!("/extended/v2/blocks/{}", height); + + if let Some(cached) = self.remote_block_info_cache.get(&height) { + return cached.clone(); + } - block_hash + let block_info = self.fetch_block_info(&url); + + self.remote_block_info_cache + .insert(height, block_info.clone()); + + self.height_at_chain_tip + .insert(block_info.index_block_hash, height); + + block_info + } + + fn get_remote_block_info_from_hash(&mut self, hash: &StacksBlockId) -> RpcBlockInfo { + if let Some(height) = self.height_at_chain_tip.get(hash) { + return self.get_remote_block_info_from_height(*height); + } + + let url = format!("/extended/v2/blocks/{}", hash); + + let block_info = self.fetch_block_info(&url); + + self.remote_block_info_cache + .insert(block_info.height, block_info.clone()); + + self.height_at_chain_tip + .insert(block_info.index_block_hash, block_info.height); + + block_info + } + + fn get_remote_chaintip(&mut self) -> String { + let height = self + .get_current_block_height() + .min(self.remote_data_settings.initial_height.unwrap()); + println!("get_remote_chaintip: {}", height); + let block_info = self.get_remote_block_info_from_height(height); + block_info.index_block_hash.to_string() } fn fetch_remote_data(&mut self, path: &str) -> Result> { @@ -327,15 +402,9 @@ impl ClarityDatastore { fn fetch_clarity_marf_value(&mut self, key: &str) -> Result> { let key_hash = TrieHash::from_key(key); - // the block height should be the min value between current block height and initial height - // making sure we don't ever try reading data on remote network with a higher block height than the initial one - let block_height = self.get_current_block_height(); - let remote_chaintip = self.get_remote_chaintip(block_height); - let path = format!( - "/v2/clarity/marf/{}?tip={}&proof=false", - key_hash, remote_chaintip - ); - self.fetch_remote_data(&path) + let tip = self.get_remote_chaintip(); + let url = format!("/v2/clarity/marf/{}?tip={}&proof=false", key_hash, tip); + self.fetch_remote_data(&url) } fn fetch_clarity_metadata( @@ -345,20 +414,12 @@ impl ClarityDatastore { ) -> Result> { let addr = contract.issuer.to_string(); let contract = contract.name.to_string(); - // the block height should be the min value between current block height and initial height - // making sure we don't ever try reading data on remote network with a higher block height than the initial one - let block_height = self.get_current_block_height(); - let remote_chaintip = self.get_remote_chaintip(block_height); - uprint!( - "fetching METADATA from network, {}/{}/{}", - addr, - contract, - key - ); - + println!("CURRENT {}", self.current_chain_tip); + println!("OPEN {}", self.open_chain_tip); + let tip = self.get_remote_chaintip(); let url = format!( "/v2/clarity/metadata/{}/{}/{}?tip={}", - addr, contract, key, remote_chaintip + addr, contract, key, tip ); self.fetch_remote_data(&url) } @@ -374,21 +435,24 @@ impl ClarityBackingStore for ClarityDatastore { /// fetch K-V out of the committed datastore fn get_data(&mut self, key: &str) -> Result> { - println!("get_data({})", key); - - match self.store.get(key) { - Some(data) => Ok(self.get_latest_data(data)), - None => { - if self.remote_data_settings.enabled { - let data = self.fetch_clarity_marf_value(key); - if let Ok(Some(value)) = &data { - self.put(key, value); - } - return data; + if let Some(data) = self.store.get(key) { + if self.remote_data_settings.enabled && self.current_chain_tip != self.open_chain_tip { + let data = self.fetch_clarity_marf_value(key); + if let Ok(Some(value)) = &data { + self.put(key, value); } - Ok(None) + return data; + } + return Ok(self.get_latest_data(data)); + } + if self.remote_data_settings.enabled { + let data = self.fetch_clarity_marf_value(key); + if let Ok(Some(value)) = &data { + self.put(key, value); } + return data; } + Ok(None) } fn get_data_from_path(&mut self, _hash: &TrieHash) -> Result> { @@ -420,6 +484,13 @@ impl ClarityBackingStore for ClarityDatastore { } fn get_block_at_height(&mut self, height: u32) -> Option { + println!("calling get_block_at_height"); + if self.remote_data_settings.enabled + && height <= self.remote_data_settings.initial_height.unwrap() + { + let block_info = self.get_remote_block_info_from_height(height); + return Some(block_info.index_block_hash); + } Some(height_to_id(height)) } @@ -427,13 +498,22 @@ impl ClarityBackingStore for ClarityDatastore { /// i.e., it changes on time-shifted evaluation. the open_chain_tip functions always /// return data about the chain tip that is currently open for writing. fn get_current_block_height(&mut self) -> u32 { - *self - .height_at_chain_tip - .get(&self.current_chain_tip) - .unwrap_or(&u32::MAX) + if let Some(height) = self.height_at_chain_tip.get(&self.current_chain_tip) { + return *height; + } + if self.remote_data_settings.enabled { + let hash = self.current_chain_tip; + let block_info = self.get_remote_block_info_from_hash(&hash); + if block_info.height <= self.remote_data_settings.initial_height.unwrap() { + return block_info.height; + } + } + + u32::MAX } fn get_open_chain_tip_height(&mut self) -> u32 { + println!("calling get_open_chain_tip_height"); self.height_at_chain_tip .get(&self.open_chain_tip) .copied() @@ -441,6 +521,7 @@ impl ClarityBackingStore for ClarityDatastore { } fn get_open_chain_tip(&mut self) -> StacksBlockId { + println!("calling get_open_chain_tip"); self.open_chain_tip } @@ -466,7 +547,6 @@ impl ClarityBackingStore for ClarityDatastore { contract: &QualifiedContractIdentifier, key: &str, ) -> Result> { - println!("get_metadata({}, {})", contract, key); let metadata = self.metadata.get(&(contract.to_string(), key.to_string())); if metadata.is_some() { return Ok(metadata.cloned()); @@ -498,6 +578,7 @@ impl ClarityBackingStore for ClarityDatastore { } fn get_cc_special_cases_handler(&self) -> Option { + println!("calling get_cc_special_cases_handler"); Some(&handle_contract_call_special_cases) } @@ -723,6 +804,7 @@ impl HeadersDB for Datastore { id_bhh: &StacksBlockId, _epoch_id: &StacksEpochId, ) -> Option { + println!("calling get_stacks_block_header_hash_for_block"); self.stacks_blocks .get(id_bhh) .map(|id| id.block_header_hash) @@ -732,6 +814,7 @@ impl HeadersDB for Datastore { &self, id_bhh: &StacksBlockId, ) -> Option { + println!("calling get_burn_header_hash_for_block"); self.stacks_blocks .get(id_bhh) .map(|block| block.burn_block_header_hash) @@ -742,6 +825,7 @@ impl HeadersDB for Datastore { id_bhh: &StacksBlockId, _epoch_id: &StacksEpochId, ) -> Option { + println!("calling get_consensus_hash_for_block"); self.stacks_blocks.get(id_bhh).map(|id| id.consensus_hash) } @@ -750,10 +834,12 @@ impl HeadersDB for Datastore { id_bhh: &StacksBlockId, _epoch_id: &StacksEpochId, ) -> Option { + println!("calling get_vrf_seed_for_block"); self.stacks_blocks.get(id_bhh).map(|id| id.vrf_seed) } fn get_stacks_block_time_for_block(&self, id_bhh: &StacksBlockId) -> Option { + println!("calling get_stacks_block_time_for_block"); self.stacks_blocks .get(id_bhh) .map(|id| id.stacks_block_time) @@ -764,12 +850,14 @@ impl HeadersDB for Datastore { id_bhh: &StacksBlockId, _epoch_id: Option<&StacksEpochId>, ) -> Option { + println!("calling get_burn_block_time_for_block"); self.get_burn_header_hash_for_block(id_bhh) .and_then(|hash| self.burn_blocks.get(&hash)) .map(|b| b.burn_block_time) } fn get_burn_block_height_for_block(&self, id_bhh: &StacksBlockId) -> Option { + println!("calling get_burn_block_height_for_block"); self.get_burn_header_hash_for_block(id_bhh) .and_then(|hash| self.burn_blocks.get(&hash)) .map(|b| b.burn_block_height) @@ -780,6 +868,7 @@ impl HeadersDB for Datastore { _id_bhh: &StacksBlockId, tenure_height: u32, ) -> Option { + println!("calling get_stacks_height_for_tenure_height"); self.tenure_blocks_height.get(&tenure_height).copied() } @@ -860,6 +949,7 @@ impl BurnStateDB for Datastore { } fn get_tip_sortition_id(&self) -> Option { + println!("calling get_tip_sortition_id"); let bytes = height_to_hashed_bytes(self.stacks_chain_height); let sortition_id = SortitionId(bytes); Some(sortition_id) @@ -900,6 +990,7 @@ impl BurnStateDB for Datastore { _height: u32, sortition_id: &SortitionId, ) -> Option { + println!("calling get_burn_header_hash"); self.sortition_lookup .get(sortition_id) .and_then(|id| self.stacks_blocks.get(id)) @@ -913,6 +1004,7 @@ impl BurnStateDB for Datastore { &self, consensus_hash: &ConsensusHash, ) -> Option { + println!("calling get_sortition_id_from_consensus_hash"); self.consensus_hash_lookup.get(consensus_hash).copied() } diff --git a/components/clarity-repl/src/repl/remote_data_store.rs b/components/clarity-repl/src/repl/remote_data_store.rs deleted file mode 100644 index 52e797965..000000000 --- a/components/clarity-repl/src/repl/remote_data_store.rs +++ /dev/null @@ -1,162 +0,0 @@ -use clarity::vm::errors::{Error, InterpreterError, InterpreterResult as Result}; -use clarity::vm::representations::{ClarityName, Span, TraitDefinition}; -use clarity::vm::types::{TraitIdentifier, Value}; - -use serde_json::Value as JsonValue; - -#[derive(Debug, Serialize, Deserialize, Clone)] -struct RawSymbolicExpression { - pub expr: RawSymbolicExpressionType, - pub id: u64, - - #[serde(default)] - pub span: Span, - #[serde(default)] - pub pre_comments: Vec<(String, Span)>, - #[serde(default)] - pub post_comments: Vec<(String, Span)>, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -enum RawSymbolicExpressionType { - AtomValue(Value), - Atom(ClarityName), - List(Vec), - LiteralValue(Value), - Field(TraitIdentifier), - TraitReference(ClarityName, TraitDefinition), -} - -// fn add_symbolic_expr_properties(mut exprs: Vec) { -// for mut expr in exprs.into_iter() { -// expr.span = Some(Span::zero()); -// expr.pre_comments = Some(vec![]); -// expr.post_comments = Some(vec![]); -// if let RawSymbolicExpressionType::List(mut list) = expr.expr { -// add_symbolic_expr_properties(list); -// } -// } -// } - -pub fn modify_function_bodies(json_str: &str) -> Result { - let mut value: JsonValue = serde_json::from_str(json_str) - .map_err(|e| Error::Interpreter(InterpreterError::Expect(e.to_string())))?; - - // Navigate to the functions - if let Some(contract) = value.get_mut("contract_context") { - if let Some(functions) = contract.get_mut("functions") { - if let Some(obj) = functions.as_object_mut() { - // Iterate through all functions - for (_name, function) in obj { - if let Some(body) = function.get_mut("body") { - // Deserialize the body into our known type - let expr: RawSymbolicExpression = serde_json::from_value(body.clone()) - .map_err(|e| { - Error::Interpreter(InterpreterError::Expect(e.to_string())) - })?; - - // add_symbolic_expr_properties(vec![expr.clone()]); - - // Replace the old body with the modified version - *body = serde_json::to_value(expr).map_err(|e| { - Error::Interpreter(InterpreterError::Expect(e.to_string())) - })?; - } - } - } - } - } - - serde_json::to_string(&value) - .map_err(|e| Error::Interpreter(InterpreterError::Expect(e.to_string()))) -} - -#[cfg(test)] -mod tests { - use super::*; - use serde_json::json; - - #[test] - fn test_modify_function_bodies_with_function() { - let raw_json = r#"{ - "contract_context": { - "variables": { - "ERR_BLOCK_NOT_FOUND": { - "Response": { "committed": false, "data": { "UInt": 1003 } } - } - }, - "functions": { - "get-count": { - "identifier": { - "identifier": "ST1SJ3DTE5DN7X54YDH5D64R3BCB6A2AG2ZQ8YPD5.counter:get-count" - }, - "name": "get-count", - "arg_types": [], - "define_type": "ReadOnly", - "arguments": [], - "body": { - "expr": { - "List": [ - { "expr": { "Atom": "var-get" }, "id": 2 }, - { "expr": { "Atom": "count" }, "id": 3 } - ] - }, - "id": 1 - } - } - }, - "persisted_names": ["cost"] - } - }"#; - - let result = modify_function_bodies(raw_json).unwrap(); - let expected = json!({ - "contract_context": { - "variables": { - "ERR_BLOCK_NOT_FOUND": { - "Response": { "committed": false, "data": { "UInt": 1003 } } - } - }, - "functions": { - "get-count": { - "identifier": { - "identifier": "ST1SJ3DTE5DN7X54YDH5D64R3BCB6A2AG2ZQ8YPD5.counter:get-count" - }, - "name": "get-count", - "arg_types": [], - "define_type": "ReadOnly", - "arguments": [], - "body": { - "expr": { - "List": [ - { - "expr": { "Atom": "var-get" }, - "id": 2, - "span": Span::zero(), - "pre_comments": [], - "post_comments": [] - }, - { - "expr": { "Atom": "count" }, - "id": 3, - "span": Span::zero(), - "pre_comments": [], - "post_comments": [] - } - ] - }, - "id": 1, - "span": Span::zero(), - "pre_comments": [], - "post_comments": [] - } - } - }, - "persisted_names": ["cost"] - } - }) - .to_string(); - - assert_eq!(result, expected); - } -} diff --git a/components/clarity-repl/src/repl/settings.rs b/components/clarity-repl/src/repl/settings.rs index ed875b22d..751c09180 100644 --- a/components/clarity-repl/src/repl/settings.rs +++ b/components/clarity-repl/src/repl/settings.rs @@ -54,7 +54,7 @@ pub struct SessionSettings { } #[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] -pub struct ApiUrl(String); +pub struct ApiUrl(pub String); impl Default for ApiUrl { fn default() -> Self { ApiUrl("http://api.hiro.so".to_string()) diff --git a/components/clarity-repl/tests/remote_data.rs b/components/clarity-repl/tests/remote_data.rs new file mode 100644 index 000000000..947985566 --- /dev/null +++ b/components/clarity-repl/tests/remote_data.rs @@ -0,0 +1,109 @@ +use clarity::{ + types::StacksEpochId, + vm::{EvaluationResult, Value}, +}; +use clarity_repl::repl::{ + settings::{ApiUrl, RemoteDataSettings}, + Session, SessionSettings, +}; + +#[track_caller] +fn eval_snippet(session: &mut Session, snippet: &str) -> Value { + let execution_res = session.eval(snippet.to_string(), false).unwrap(); + match execution_res.result { + EvaluationResult::Contract(_) => unreachable!(), + EvaluationResult::Snippet(res) => res.result, + } +} + +fn init_session(initial_heigth: u32) -> Session { + let mut settings = SessionSettings::default(); + + settings.repl_settings.remote_data = RemoteDataSettings { + enabled: true, + api_url: ApiUrl("https://api.testnet.hiro.so".to_string()), + initial_height: Some(initial_heigth), + }; + + let mut session = Session::new(settings); + session.update_epoch(StacksEpochId::Epoch30); + session +} + +// the counter contract is delpoyed on testnet at height #41613 +// the initial count value is 0 and is incremented by 1 at #56232 + +const COUNTER_CONTRACT: &str = "STJCAB2T9TR2EJM7YS4DM2CGBBVTF7BV237Y8KNV.counter"; + +#[ignore] +#[test] +fn it_handles_not_found_contract() { + let mut session = init_session(40000); + + let snippet = format!("(contract-call? '{} get-count)", COUNTER_CONTRACT); + let result = eval_snippet(&mut session, &snippet); + println!("result: {:?}", result); +} + +#[test] +fn it_can_fetch_remote() { + // count at block 42000 is 0 + let mut session = init_session(42000); + let snippet = format!("(contract-call? '{} get-count)", COUNTER_CONTRACT); + let result = eval_snippet(&mut session, &snippet); + assert_eq!(result, Value::UInt(0)); + + // count at block 57000 is 1 + let mut session = init_session(57000); + let snippet = format!("(contract-call? '{} get-count)", COUNTER_CONTRACT); + let result = eval_snippet(&mut session, &snippet); + assert_eq!(result, Value::UInt(1)); +} + +#[test] +fn it_can_fork_state() { + let mut session = init_session(57000); + let snippet_get_count = format!("(contract-call? '{} get-count)", COUNTER_CONTRACT); + let result = eval_snippet(&mut session, &snippet_get_count); + assert_eq!(result, Value::UInt(1)); + + let snippet = format!("(contract-call? '{} increment)", COUNTER_CONTRACT); + let _ = eval_snippet(&mut session, &snippet); + session.advance_burn_chain_tip(1); + + let result = eval_snippet(&mut session, &snippet_get_count); + assert_eq!(result, Value::UInt(2)); +} + +#[test] +fn it_handles_at_block() { + let mut session = init_session(60000); + + // block 42000 hash + let id_header_hash = "0xb4678e059aa9b82b1473597087876ef61a5c6a0c35910cd4b797201d6b423a07"; + + // let snippet = format!("(at-block {} stacks-block-height)", id_header_hash); + // let result = eval_snippet(&mut session, &snippet); + // assert_eq!(result, Value::UInt(42000)); + + let snippet_get_count_at_10k = format!( + "(contract-call? '{} get-count-at-block u10000)", + COUNTER_CONTRACT + ); + let result = eval_snippet(&mut session, &snippet_get_count_at_10k); + assert_eq!(result, Value::okay(Value::none()).unwrap()); + + // let snippet_get_count_at_42k = format!( + // "(contract-call? '{} get-count-at-block u42000)", + // COUNTER_CONTRACT + // ); + // let result = eval_snippet(&mut session, &snippet_get_count_at_42k); + // assert_eq!(result, Value::okay(Value::UInt(0)).unwrap()); + + // let snippet_get_count_at_57k = format!( + // "(contract-call? '{} get-count-at-block u57000)", + // COUNTER_CONTRACT + // ); + // let result = eval_snippet(&mut session, &snippet_get_count_at_57k); + // assert_eq!(result, Value::okay(Value::UInt(1)).unwrap()); +} diff --git a/package-lock.json b/package-lock.json index 4f789fb51..ee91ec9fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,20 +25,20 @@ }, "components/clarinet-sdk-wasm/pkg-browser": { "name": "@hirosystems/clarinet-sdk-wasm-browser", - "version": "2.12.0", + "version": "2.13.0-beta1", "license": "GPL-3.0" }, "components/clarinet-sdk-wasm/pkg-node": { "name": "@hirosystems/clarinet-sdk-wasm", - "version": "2.12.0", + "version": "2.13.0-beta1", "license": "GPL-3.0" }, "components/clarinet-sdk/browser": { "name": "@hirosystems/clarinet-sdk-browser", - "version": "2.12.0", + "version": "2.13.0-beta1", "license": "GPL-3.0", "dependencies": { - "@hirosystems/clarinet-sdk-wasm-browser": "^2.12.0", + "@hirosystems/clarinet-sdk-wasm-browser": "2.13.0-beta1", "@stacks/transactions": "^6.13.0", "sync-request": "^6.1.0" } @@ -49,10 +49,10 @@ }, "components/clarinet-sdk/node": { "name": "@hirosystems/clarinet-sdk", - "version": "2.12.0", + "version": "2.13.0-beta1", "license": "GPL-3.0", "dependencies": { - "@hirosystems/clarinet-sdk-wasm": "^2.12.0", + "@hirosystems/clarinet-sdk-wasm": "2.13.0-beta1", "@stacks/transactions": "^6.13.0", "kolorist": "^1.8.0", "prompts": "^2.4.2", @@ -354,8 +354,6 @@ }, "node_modules/@types/concat-stream": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -387,8 +385,6 @@ }, "node_modules/@types/form-data": { "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -418,8 +414,6 @@ }, "node_modules/@types/qs": { "version": "6.9.17", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", - "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", "license": "MIT" }, "node_modules/@types/yargs": { @@ -762,8 +756,6 @@ }, "node_modules/asap": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "license": "MIT" }, "node_modules/assertion-error": { @@ -775,8 +767,6 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/balanced-match": { @@ -890,8 +880,6 @@ }, "node_modules/call-bind-apply-helpers": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -903,8 +891,6 @@ }, "node_modules/call-bound": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -918,7 +904,7 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001689", + "version": "1.0.30001690", "dev": true, "funding": [ { @@ -939,8 +925,6 @@ }, "node_modules/caseless": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "license": "Apache-2.0" }, "node_modules/chai": { @@ -1069,8 +1053,6 @@ }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -1087,8 +1069,6 @@ }, "node_modules/concat-stream": { "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "engines": [ "node >= 0.8" ], @@ -1106,8 +1086,6 @@ }, "node_modules/core-util-is": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, "node_modules/cross-fetch": { @@ -1156,8 +1134,6 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -1172,8 +1148,6 @@ }, "node_modules/dunder-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -1214,8 +1188,6 @@ }, "node_modules/es-define-property": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1223,8 +1195,6 @@ }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1238,8 +1208,6 @@ }, "node_modules/es-object-atoms": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -1417,8 +1385,6 @@ }, "node_modules/form-data": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz", - "integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -1443,8 +1409,6 @@ }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1466,8 +1430,6 @@ }, "node_modules/get-intrinsic": { "version": "1.2.6", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", - "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -1490,8 +1452,6 @@ }, "node_modules/get-port": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", "license": "MIT", "engines": { "node": ">=4" @@ -1537,8 +1497,6 @@ }, "node_modules/gopd": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1562,8 +1520,6 @@ }, "node_modules/has-symbols": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1574,8 +1530,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -1586,8 +1540,6 @@ }, "node_modules/http-basic": { "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", "license": "MIT", "dependencies": { "caseless": "^0.12.0", @@ -1601,8 +1553,6 @@ }, "node_modules/http-response-object": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", "license": "MIT", "dependencies": { "@types/node": "^10.0.3" @@ -1610,8 +1560,6 @@ }, "node_modules/http-response-object/node_modules/@types/node": { "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", "license": "MIT" }, "node_modules/human-signals": { @@ -1623,8 +1571,6 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/is-fullwidth-code-point": { @@ -1654,8 +1600,6 @@ }, "node_modules/isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "license": "MIT" }, "node_modules/isexe": { @@ -1783,8 +1727,6 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1940,8 +1882,6 @@ }, "node_modules/object-inspect": { "version": "1.13.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1982,9 +1922,7 @@ "license": "BlueOak-1.0.0" }, "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" + "version": "1.0.1" }, "node_modules/path-key": { "version": "3.1.1", @@ -2107,14 +2045,10 @@ }, "node_modules/process-nextick-args": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, "node_modules/promise": { "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", "license": "MIT", "dependencies": { "asap": "~2.0.6" @@ -2142,8 +2076,6 @@ }, "node_modules/qs": { "version": "6.13.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz", - "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" @@ -2170,8 +2102,6 @@ }, "node_modules/readable-stream": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", @@ -2185,8 +2115,6 @@ }, "node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, "node_modules/require-directory": { @@ -2341,8 +2269,6 @@ }, "node_modules/side-channel": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -2360,8 +2286,6 @@ }, "node_modules/side-channel-list": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -2376,8 +2300,6 @@ }, "node_modules/side-channel-map": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -2394,8 +2316,6 @@ }, "node_modules/side-channel-weakmap": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -2473,8 +2393,6 @@ }, "node_modules/string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" @@ -2482,8 +2400,6 @@ }, "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, "node_modules/string-width": { @@ -2607,8 +2523,6 @@ }, "node_modules/sync-request": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", "license": "MIT", "dependencies": { "http-response-object": "^3.0.1", @@ -2621,8 +2535,6 @@ }, "node_modules/sync-rpc": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", "license": "MIT", "dependencies": { "get-port": "^3.1.0" @@ -2743,8 +2655,6 @@ }, "node_modules/then-request": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", "license": "MIT", "dependencies": { "@types/concat-stream": "^1.6.0", @@ -2765,8 +2675,6 @@ }, "node_modules/then-request/node_modules/@types/node": { "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", "license": "MIT" }, "node_modules/tinybench": { @@ -2830,8 +2738,6 @@ }, "node_modules/typedarray": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "license": "MIT" }, "node_modules/typescript": { @@ -2895,8 +2801,6 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/varuint-bitcoin": {