diff --git a/Cargo.lock b/Cargo.lock index 13aaee5992..99fd04b7af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1320,7 +1320,6 @@ dependencies = [ name = "ic-http-agent" version = "0.1.0" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crc8 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "error 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/nix/sources.json b/nix/sources.json index 292b201fb9..70b22414b7 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -32,7 +32,7 @@ "dfinity": { "ref": "master", "repo": "ssh://git@github.com/dfinity-lab/dfinity", - "rev": "fd64793ba310671093820f7437c5278cb21f8bb6", + "rev": "0b3071a3f7d489d560a16417d07930687a6709d4", "type": "git" }, "motoko": { diff --git a/src/dfx/src/commands/start.rs b/src/dfx/src/commands/start.rs index 03bae10656..d9831c0bb0 100644 --- a/src/dfx/src/commands/start.rs +++ b/src/dfx/src/commands/start.rs @@ -11,7 +11,7 @@ use futures::future::Future; use indicatif::{ProgressBar, ProgressDrawTarget}; use std::io::{Error, ErrorKind}; use std::net::SocketAddr; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; use std::time::{Duration, Instant}; use sysinfo::{System, SystemExt}; @@ -75,8 +75,10 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult { let client_pathbuf = env.get_cache().get_binary_command_path("client")?; let nodemanager_pathbuf = env.get_cache().get_binary_command_path("nodemanager")?; + let temp_dir = env.get_temp_dir(); + let state_root = env.get_temp_dir().join("state"); - let pid_file_path = env.get_temp_dir().join("pid"); + let pid_file_path = temp_dir.join("pid"); check_previous_process_running(&pid_file_path)?; // We are doing this here to make sure we can write to the temp pid file. @@ -108,6 +110,7 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult { &client_pathbuf.clone(), &nodemanager_pathbuf, &pid_file_path, + &state_root, is_killed_client, request_stop, ) @@ -258,16 +261,24 @@ fn start_client( client_pathbuf: &PathBuf, nodemanager_pathbuf: &PathBuf, pid_file_path: &PathBuf, + state_root: &Path, is_killed_client: Receiver<()>, request_stop: Sender<()>, ) -> DfxResult<()> { - let client = client_pathbuf.as_path(); - let nodemanager = nodemanager_pathbuf.as_path(); + let config = format!( + r#" + [state_manager] + state_root = "{state_root}" + "#, + state_root = state_root.display(), + ); + let client = client_pathbuf.as_path().as_os_str(); + let nodemanager = nodemanager_pathbuf.as_path().as_os_str(); // We use unwrap() here to transmit an error to the parent // thread. while is_killed_client.is_empty() { let mut cmd = std::process::Command::new(nodemanager); - cmd.args(&[client]); + cmd.args(&[client, "--config".as_ref(), config.as_ref()]); cmd.stdout(std::process::Stdio::inherit()); cmd.stderr(std::process::Stdio::inherit()); diff --git a/src/dfx/src/lib/api_client.rs b/src/dfx/src/lib/api_client.rs index a0bc446698..9e8656b0fd 100644 --- a/src/dfx/src/lib/api_client.rs +++ b/src/dfx/src/lib/api_client.rs @@ -293,7 +293,7 @@ mod tests { fn query_request_serialization() { use serde_cbor::Value; - let canister_id = CanisterId::from(1); + let canister_id = CanisterId::from_bytes(&[1]); let method_name = "main".to_string(); let arg = Blob(vec![]); @@ -314,7 +314,10 @@ mod tests { Value::Text("query".to_string()), ), // TODO: when the client moves to using Blobs, move this to being a blob. - (Value::Text("canister_id".to_string()), Value::Integer(1)), + ( + Value::Text("canister_id".to_string()), + Value::Bytes(vec![1]), + ), ( Value::Text("method_name".to_string()), Value::Text(method_name.clone()), @@ -387,7 +390,7 @@ mod tests { let query = query( client, - CanisterId::from(1), + CanisterId::from_bytes(&[1]), "main".to_string(), Some(Blob(vec![])), ); @@ -458,7 +461,7 @@ mod tests { let query = query( client, - CanisterId::from(1), + CanisterId::from_bytes(&[1]), "main".to_string(), Some(Blob(vec![])), ); @@ -478,7 +481,7 @@ mod tests { fn install_code_request_serialization() { use serde_cbor::Value; - let canister_id = CanisterId::from(1); + let canister_id = CanisterId::from_bytes(&[1]); let module = Blob(vec![1]); let arg = Blob(vec![2]); @@ -498,7 +501,10 @@ mod tests { Value::Text("install_code".to_string()), ), // TODO: when the client moves to using Blobs, move this to being a blob. - (Value::Text("canister_id".to_string()), Value::Integer(1)), + ( + Value::Text("canister_id".to_string()), + Value::Bytes(vec![1]), + ), (Value::Text("module".to_string()), Value::Bytes(vec![1])), (Value::Text("arg".to_string()), Value::Bytes(vec![2])), (Value::Text("nonce".to_string()), Value::Null), @@ -523,7 +529,7 @@ mod tests { url: mockito::server_url(), }); - let future = install_code(client, CanisterId::from(1), Blob(vec![1]), None); + let future = install_code(client, CanisterId::from_bytes(&[1]), Blob(vec![1]), None); let mut runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); let result = runtime.block_on(future); @@ -549,7 +555,7 @@ mod tests { url: mockito::server_url(), }); - let future = install_code(client, CanisterId::from(1), Blob(vec![1]), None); + let future = install_code(client, CanisterId::from_bytes(&[1]), Blob(vec![1]), None); let mut runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime"); let result = runtime.block_on(future); diff --git a/src/dfx/src/lib/canister_info.rs b/src/dfx/src/lib/canister_info.rs index 047a3de2c8..21fa0fc107 100644 --- a/src/dfx/src/lib/canister_info.rs +++ b/src/dfx/src/lib/canister_info.rs @@ -2,12 +2,10 @@ use crate::config::dfinity::Config; use crate::lib::error::{DfxError, DfxResult}; use ic_http_agent::{Blob, CanisterId}; -use rand::{thread_rng, Rng}; +use rand::{thread_rng, RngCore}; use std::cell::RefCell; -use std::ops::Shl; use std::path::{Path, PathBuf}; use std::str::FromStr; -use std::time::{SystemTime, UNIX_EPOCH}; /// Information about a canister project (source code, destination, etc). #[derive(Debug)] @@ -148,13 +146,10 @@ impl CanisterInfo { } pub fn generate_canister_id(&self) -> DfxResult { - // Generate a random u64. - let time_since_the_epoch = SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("Time went backwards."); - let cid = u64::from(time_since_the_epoch.as_millis() as u32).shl(32) - + u64::from(thread_rng().gen::()); - - Ok(CanisterId::from(cid)) + let mut rng = thread_rng(); + let mut v: Vec = std::iter::repeat(0u8).take(8).collect(); + rng.fill_bytes(v.as_mut_slice()); + + Ok(CanisterId::from(Blob(v))) } } diff --git a/src/ic_http_agent/Cargo.toml b/src/ic_http_agent/Cargo.toml index eac3642d6e..22f5bc45c0 100644 --- a/src/ic_http_agent/Cargo.toml +++ b/src/ic_http_agent/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -byteorder = "1.3.2" crc8 = "0.1.1" error = "0.1.9" hex = "0.4.0" diff --git a/src/ic_http_agent/src/types/canister_id.rs b/src/ic_http_agent/src/types/canister_id.rs index ab2fbba7df..af473970ad 100644 --- a/src/ic_http_agent/src/types/canister_id.rs +++ b/src/ic_http_agent/src/types/canister_id.rs @@ -1,12 +1,11 @@ use crate::types::blob::Blob; -use byteorder::{ByteOrder, LittleEndian}; use crc8::Crc8; use hex; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::{fmt, num, str}; +use std::{fmt, str}; /// Prefix for [textual form of ID](https://docs.dfinity.systems/spec/public/#textual-ids) -const IC_COLON: &str = "ic:"; +const CANISTER_ID_TEXT_PREFIX: &str = "ic:"; /// A Canister ID. /// @@ -31,21 +30,15 @@ impl std::convert::From for TextualCanisterIdError { } impl CanisterId { - pub(crate) fn from_u64(v: u64) -> CanisterId { - let mut buf = [0 as u8; 8]; - LittleEndian::write_u64(&mut buf, v); - CanisterId(Blob(buf.to_vec())) - } - - pub(crate) fn as_u64(&self) -> u64 { - LittleEndian::read_u64((self.0).0.as_slice()) - } - /// Allow to move canister Ids in blobs. pub fn into_blob(self) -> Blob { self.0 } + pub fn from_bytes>(bytes: S) -> CanisterId { + CanisterId(Blob::from(bytes.as_ref())) + } + /// Parse the text format for canister IDs (e.g., `ic:010840FFAD`). /// /// The text format follows this @@ -57,7 +50,7 @@ impl CanisterId { let (text_prefix, text_rest) = text.as_ref().split_at(3); match std::str::from_utf8(text_prefix) { Ok(ref s) => { - if s != &IC_COLON { + if s != &CANISTER_ID_TEXT_PREFIX { return Err(TextualCanisterIdError::BadPrefix); } } @@ -83,7 +76,7 @@ impl CanisterId { let checksum_byte: u8 = crc8.calc(&(self.0).0, (self.0).0.len() as i32, 0); let mut buf = (self.0).0.clone(); buf.push(checksum_byte); - format!("{}{}", IC_COLON, hex::encode_upper(buf)) + format!("{}{}", CANISTER_ID_TEXT_PREFIX, hex::encode_upper(buf)) } } @@ -93,8 +86,7 @@ impl Serialize for CanisterId { where S: Serializer, { - // TODO(DFN-862): move this to blobs - serializer.serialize_u64(self.as_u64()) + self.0.serialize(serializer) } } @@ -104,7 +96,7 @@ impl<'de> Deserialize<'de> for CanisterId { S: Deserializer<'de>, { // TODO(DFN-862): move this to blobs - Ok(CanisterId::from_u64(u64::deserialize(deserializer)?)) + Ok(CanisterId::from(Blob::deserialize(deserializer)?)) } } @@ -116,18 +108,11 @@ impl From for CanisterId { } } -impl From for CanisterId { - fn from(n: u64) -> CanisterId { - // We don't need to make a copy as this assume ownership. - CanisterId::from_u64(n) - } -} - impl str::FromStr for CanisterId { - type Err = num::ParseIntError; + type Err = TextualCanisterIdError; fn from_str(s: &str) -> Result { - Ok(CanisterId::from_u64(u64::from_str(s)?)) + CanisterId::from_text(s) } } @@ -149,7 +134,7 @@ mod tests { #[test] fn check_serialize_deserialize() { - let id = CanisterId::from_u64(88827); + let id = CanisterId::from_text("ic:ABCD01A7").unwrap(); // Use cbor serialization. let vec = serde_cbor::to_vec(&id).unwrap(); diff --git a/src/ic_http_agent/src/types/request_id.rs b/src/ic_http_agent/src/types/request_id.rs index e485b964b2..dde60adf9b 100644 --- a/src/ic_http_agent/src/types/request_id.rs +++ b/src/ic_http_agent/src/types/request_id.rs @@ -7,7 +7,6 @@ //! A single method is exported, to_request_id, which returns a RequestId //! (a 256 bits slice) or an error. use crate::types::request_id_error::{RequestIdError, RequestIdFromStringError}; -use byteorder::{BigEndian, ByteOrder}; use openssl::sha::Sha256; use serde::{ser, Serialize, Serializer}; use std::collections::BTreeMap; @@ -219,10 +218,8 @@ impl<'a> ser::Serializer for &'a mut RequestIdSerializer { } /// Serialize a `u64` value. - fn serialize_u64(self, v: u64) -> Result { - let mut buf = [0 as u8; 8]; - BigEndian::write_u64(&mut buf, v); - self.serialize_bytes(&buf) + fn serialize_u64(self, _v: u64) -> Result { + Err(RequestIdError::UnsupportedTypeU64) } /// Serialize an `f32` value. @@ -660,7 +657,7 @@ mod tests { }; let data = PublicSpecExampleStruct { request_type: "call", - canister_id: CanisterId::from(1234), + canister_id: CanisterId::from_bytes(&[0, 0, 0, 0, 0, 0, 0x04, 0xD2]), // 1234 in u64 method_name: "hello", arg: Blob(b"DIDL\x00\xFD*".to_vec()), }; @@ -687,7 +684,7 @@ mod tests { }, } let data = PublicSpec::Call { - canister_id: CanisterId::from(1234), + canister_id: CanisterId::from_bytes(&[0, 0, 0, 0, 0, 0, 0x04, 0xD2]), // 1234 in u64 method_name: "hello".to_owned(), arg: Some(Blob(b"DIDL\x00\xFD*".to_vec())), };