From c28ab0102c02a54757ff995a072f81e288776748 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Sat, 1 Jun 2019 13:24:50 +0800 Subject: [PATCH 01/17] feat: initial windows support --- Cargo.lock | 19 ++++----- ckb-bin/Cargo.toml | 1 + ckb-bin/src/subcommand/init.rs | 3 ++ db/src/rocksdb.rs | 56 ++++++++++++++++++++++++-- resource/ckb.toml | 4 +- resource/src/lib.rs | 5 ++- resource/src/template.rs | 14 +------ script/Cargo.toml | 2 +- script/src/lib.rs | 25 ++++++++++++ script/src/verify.rs | 65 +++++++++++++++++++++++++++++-- util/app-config/src/app_config.rs | 4 ++ util/hash/Cargo.toml | 2 +- 12 files changed, 168 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5911cbb0ec..c34f34789f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,7 +187,7 @@ dependencies = [ [[package]] name = "blake2b-rs" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -375,6 +375,7 @@ dependencies = [ "ckb-pow 0.14.0-pre", "ckb-resource 0.14.0-pre", "ckb-rpc 0.14.0-pre", + "ckb-script 0.14.0-pre", "ckb-shared 0.14.0-pre", "ckb-store 0.14.0-pre", "ckb-sync 0.14.0-pre", @@ -705,7 +706,7 @@ dependencies = [ "ckb-protocol 0.14.0-pre", "ckb-resource 0.14.0-pre", "ckb-store 0.14.0-pre", - "ckb-vm 0.13.0-pre (git+https://github.com/nervosnetwork/ckb-vm?rev=85e38f0)", + "ckb-vm 0.13.0-pre (git+https://github.com/nervosnetwork/ckb-vm?rev=d926277)", "crypto 0.14.0-pre", "dao 0.14.0-pre", "faster-hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -879,12 +880,12 @@ dependencies = [ [[package]] name = "ckb-vm" version = "0.13.0-pre" -source = "git+https://github.com/nervosnetwork/ckb-vm?rev=85e38f0#85e38f07ed3de5334ebc06d74b18702d0ec87bdc" +source = "git+https://github.com/nervosnetwork/ckb-vm?rev=d926277#d9262775dbffdf4e5cbb894e1ea9ea7555be094f" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "ckb-vm-definitions 0.13.0-pre (git+https://github.com/nervosnetwork/ckb-vm?rev=85e38f0)", + "ckb-vm-definitions 0.13.0-pre (git+https://github.com/nervosnetwork/ckb-vm?rev=d926277)", "goblin 0.0.22 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -892,7 +893,7 @@ dependencies = [ [[package]] name = "ckb-vm-definitions" version = "0.13.0-pre" -source = "git+https://github.com/nervosnetwork/ckb-vm?rev=85e38f0#85e38f07ed3de5334ebc06d74b18702d0ec87bdc" +source = "git+https://github.com/nervosnetwork/ckb-vm?rev=d926277#d9262775dbffdf4e5cbb894e1ea9ea7555be094f" [[package]] name = "clang-sys" @@ -1489,7 +1490,7 @@ dependencies = [ name = "hash" version = "0.14.0-pre" dependencies = [ - "blake2b-rs 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2b-rs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "faster-hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3713,7 +3714,7 @@ dependencies = [ "checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91721a6330935673395a0607df4d49a9cb90ae12d259f1b3e0a3f6e1d486872e" -"checksum blake2b-rs 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "895ae726056ce2ab1b19854be889ca43a4a2c0b02c355bee90aa9e8ee6d0379b" +"checksum blake2b-rs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9527b166a2d75fc95f72e09bc57030cd115960a5357cf55f6b7af7bffe678aab" "checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d" "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d75255892aeb580d3c566f213a2b6fdc1c66667839f45719ee1d30ebf2aea591" @@ -3728,8 +3729,8 @@ dependencies = [ "checksum cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7fa24eb00d5ffab90eaeaf1092ac85c04c64aaf358ea6f84505b8116d24c6af" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" -"checksum ckb-vm 0.13.0-pre (git+https://github.com/nervosnetwork/ckb-vm?rev=85e38f0)" = "" -"checksum ckb-vm-definitions 0.13.0-pre (git+https://github.com/nervosnetwork/ckb-vm?rev=85e38f0)" = "" +"checksum ckb-vm 0.13.0-pre (git+https://github.com/nervosnetwork/ckb-vm?rev=d926277)" = "" +"checksum ckb-vm-definitions 0.13.0-pre (git+https://github.com/nervosnetwork/ckb-vm?rev=d926277)" = "" "checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9" diff --git a/ckb-bin/Cargo.toml b/ckb-bin/Cargo.toml index 21423e52bc..e069e97d7e 100644 --- a/ckb-bin/Cargo.toml +++ b/ckb-bin/Cargo.toml @@ -40,3 +40,4 @@ sentry = "^0.15.4" ckb-verification = { path = "../verification" } tempfile = "3.0" faster-hex = "0.3" +ckb-script = { path = "../script" } diff --git a/ckb-bin/src/subcommand/init.rs b/ckb-bin/src/subcommand/init.rs index 7ffefe3069..6303322304 100644 --- a/ckb-bin/src/subcommand/init.rs +++ b/ckb-bin/src/subcommand/init.rs @@ -3,6 +3,7 @@ use ckb_resource::{ TemplateContext, AVAILABLE_SPECS, CKB_CONFIG_FILE_NAME, DEFAULT_SPEC, MINER_CONFIG_FILE_NAME, SPEC_DEV_FILE_NAME, }; +use ckb_script::Runner; pub fn init(args: InitArgs) -> Result<(), ExitCode> { if args.list_chains { @@ -12,12 +13,14 @@ pub fn init(args: InitArgs) -> Result<(), ExitCode> { return Ok(()); } + let runner = Runner::default().to_string(); let context = TemplateContext { spec: &args.chain, rpc_port: &args.rpc_port, p2p_port: &args.p2p_port, log_to_file: args.log_to_file, log_to_stdout: args.log_to_stdout, + runner: &runner, }; let exported = args.locator.exported(); diff --git a/db/src/rocksdb.rs b/db/src/rocksdb.rs index 1b230736d1..86c51a3261 100644 --- a/db/src/rocksdb.rs +++ b/db/src/rocksdb.rs @@ -1,7 +1,9 @@ use crate::{Col, DBConfig, DbBatch, Error, KeyValueDB, Result}; use log::{info, warn}; use rocksdb::{ColumnFamily, Error as RdbError, IteratorMode, Options, WriteBatch, DB}; +use std::ffi::OsString; use std::ops::Range; +use std::path::{Component, PathBuf}; use std::sync::Arc; // If any data format in database was changed, we have to update this constant manually. @@ -15,6 +17,50 @@ pub struct RocksDB { inner: Arc, } +// This is a windows-specific fix. Even though we are using correct path joins +// throughout this project, rocksdb has a quirk where it would uses unix paths: +// https://github.com/facebook/rocksdb/blob/000b9ec217663faad1d0196b28c623149e01e024/file/filename.cc#L159 +// The result here is that we might have paths like \\?\C:\ckb\node\data\db/LOCK, +// which would be rejected by windows. This method would process pathes such as +// \\?\C:\ckb\node\data\db into //?/C:/ckb/node/data/db, making the final LOCK path +// as //?/C:/ckb/node/data/db/LOCK and it should work here. +// The same code also works on UNIX systems, so we are keeping it in both cases +// to detect build errors earlier. +fn normalize_path(path: &PathBuf) -> OsString { + let mut s = OsString::new(); + for c in path.components() { + match c { + Component::Prefix(prefix_component) => { + // Prefix component is a windows-specific path prefix, such as + // C: or \\server\share. Since OsString does not have a replace + // method, we have to cast it to a normal str, do the replacement + // and convert it back. This might bring a problem when we have + // a prefix that is not UTF-8. Let's revisit it later when it indeed + // is an issue. + let prefix: OsString = prefix_component + .as_os_str() + .to_str() + .expect("invalid prefix on windows!") + .replace("\\", "/") + .to_string() + .into(); + if !s.is_empty() { + s.push("/"); + } + s.push(prefix); + } + Component::Normal(part) => { + if !s.is_empty() { + s.push("/"); + } + s.push(part.to_os_string()); + } + _ => (), + } + } + s +} + impl RocksDB { pub(crate) fn open_with_check( config: &DBConfig, @@ -29,14 +75,16 @@ impl RocksDB { let cfnames: Vec<_> = (0..columns).map(|c| c.to_string()).collect(); let cf_options: Vec<&str> = cfnames.iter().map(|n| n as &str).collect(); - let db = DB::open_cf(&opts, &config.path, &cf_options).or_else(|err| { + let path = normalize_path(&config.path); + + let db = DB::open_cf(&opts, &path, &cf_options).or_else(|err| { let err_str = err.as_ref(); if err_str.starts_with("Invalid argument:") && err_str.ends_with("does not exist (create_if_missing is false)") { info!("Initialize a new database"); opts.create_if_missing(true); - let db = DB::open_cf(&opts, &config.path, &cf_options).map_err(|err| { + let db = DB::open_cf(&opts, &path, &cf_options).map_err(|err| { Error::DBError(format!("failed to open a new created database: {}", err)) })?; db.put(ver_key, ver_val).map_err(|err| { @@ -48,11 +96,11 @@ impl RocksDB { let mut repair_opts = Options::default(); repair_opts.create_if_missing(false); repair_opts.create_missing_column_families(false); - DB::repair(repair_opts, &config.path).map_err(|err| { + DB::repair(repair_opts, &path).map_err(|err| { Error::DBError(format!("failed to repair the database: {}", err)) })?; warn!("Opening the repaired rocksdb ..."); - DB::open_cf(&opts, &config.path, &cf_options).map_err(|err| { + DB::open_cf(&opts, &path, &cf_options).map_err(|err| { Error::DBError(format!("failed to open the repaired database: {}", err)) }) } else { diff --git a/resource/ckb.toml b/resource/ckb.toml index 319105028a..6a6f1a6f03 100644 --- a/resource/ckb.toml +++ b/resource/ckb.toml @@ -76,7 +76,9 @@ max_cycles = 200_000_000_000 max_verfify_cache_size = 100_000 [script] -runner = "Assembly" +runner = "Assembly" # {{ +# _ => runner = "{runner}" +# }} [store] header_cache_size = 4096 diff --git a/resource/src/lib.rs b/resource/src/lib.rs index 82f12a1cd1..e25ab8843f 100644 --- a/resource/src/lib.rs +++ b/resource/src/lib.rs @@ -169,7 +169,10 @@ impl ResourceLocator { } pub fn export<'a>(&self, name: &str, context: &TemplateContext<'a>) -> Result<()> { - let target = self.root_dir.join(name); + // We need to do the join one part at a time to handle Windows paths. + let target = name + .split('/') + .fold(self.root_dir.clone(), |path, name| path.join(name)); let resource = Resource::Bundled(name.to_string()); let template = Template::new(from_utf8(resource.get()?)?); let mut out = NamedTempFile::new_in(&self.root_dir)?; diff --git a/resource/src/template.rs b/resource/src/template.rs index 222fde0049..831230a2b6 100644 --- a/resource/src/template.rs +++ b/resource/src/template.rs @@ -17,18 +17,7 @@ pub struct TemplateContext<'a> { pub p2p_port: &'a str, pub log_to_file: bool, pub log_to_stdout: bool, -} - -impl<'a> Default for TemplateContext<'a> { - fn default() -> Self { - TemplateContext { - spec: DEFAULT_SPEC, - rpc_port: DEFAULT_RPC_PORT, - p2p_port: DEFAULT_P2P_PORT, - log_to_file: true, - log_to_stdout: true, - } - } + pub runner: &'a str, } impl Template { @@ -48,6 +37,7 @@ fn writeln(w: &mut W, s: &str, context: &TemplateContext) -> io::R .replace("{p2p_port}", context.p2p_port) .replace("{log_to_file}", &format!("{}", context.log_to_file)) .replace("{log_to_stdout}", &format!("{}", context.log_to_stdout)) + .replace("{runner}", &context.runner.to_string()) ) } diff --git a/script/Cargo.toml b/script/Cargo.toml index 74dedf2421..ff9f3bcad3 100644 --- a/script/Cargo.toml +++ b/script/Cargo.toml @@ -12,7 +12,7 @@ crypto = {path = "../util/crypto"} ckb-core = { path = "../core" } ckb-store = { path = "../store" } hash = {path = "../util/hash"} -ckb-vm = { git = "https://github.com/nervosnetwork/ckb-vm", rev = "85e38f0", features = ["asm"] } +ckb-vm = { git = "https://github.com/nervosnetwork/ckb-vm", rev = "d926277", features = ["asm"] } faster-hex = "0.3" fnv = "1.0.3" flatbuffers = "0.6.0" diff --git a/script/src/lib.rs b/script/src/lib.rs index 73244c5962..63d1cc8d0b 100644 --- a/script/src/lib.rs +++ b/script/src/lib.rs @@ -4,19 +4,44 @@ mod verify; use ckb_vm::Error as VMInternalError; use serde_derive::{Deserialize, Serialize}; +use std::fmt; pub use crate::verify::TransactionScriptsVerifier; #[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash, Debug)] pub enum Runner { + #[cfg(all(unix, target_pointer_width = "64"))] Assembly, Rust, } +impl fmt::Display for Runner { + #[cfg(all(unix, target_pointer_width = "64"))] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Runner::Assembly => write!(f, "Assembly"), + Runner::Rust => write!(f, "Rust"), + } + } + + #[cfg(not(all(unix, target_pointer_width = "64")))] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Runner::Rust => write!(f, "Rust"), + } + } +} + impl Default for Runner { + #[cfg(all(unix, target_pointer_width = "64"))] fn default() -> Runner { Runner::Assembly } + + #[cfg(not(all(unix, target_pointer_width = "64")))] + fn default() -> Runner { + Runner::Rust + } } #[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash, Debug, Default)] diff --git a/script/src/verify.rs b/script/src/verify.rs index feabbfd0a0..72765ef85d 100644 --- a/script/src/verify.rs +++ b/script/src/verify.rs @@ -3,7 +3,7 @@ use crate::{ syscalls::{ Debugger, LoadCell, LoadHeader, LoadInput, LoadScriptHash, LoadTxHash, LoadWitness, }, - Runner, ScriptConfig, ScriptError, + ScriptConfig, ScriptError, }; use ckb_core::cell::{CellMeta, ResolvedOutPoint, ResolvedTransaction}; use ckb_core::extras::BlockExt; @@ -15,7 +15,6 @@ use ckb_logger::info; use ckb_resource::bundled; use ckb_store::{ChainStore, LazyLoadCellOutput}; use ckb_vm::{ - machine::asm::{AsmCoreMachine, AsmMachine}, DefaultCoreMachine, DefaultMachineBuilder, SparseMemory, SupportMachine, TraceMachine, WXorXMemory, }; @@ -26,6 +25,11 @@ use std::cmp::min; use std::path::PathBuf; use std::sync::Arc; +#[cfg(all(unix, target_pointer_width = "64"))] +use crate::Runner; +#[cfg(all(unix, target_pointer_width = "64"))] +use ckb_vm::machine::asm::{AsmCoreMachine, AsmMachine}; + pub const SYSTEM_DAO_CYCLES: u64 = 5000; // TODO: tweak those values later @@ -57,7 +61,6 @@ impl ScriptGroup { // future, we might refactor this to share buffer to achive zero-copy pub struct TransactionScriptsVerifier<'a, CS> { store: Arc, - config: &'a ScriptConfig, // TODO: those are all cached data directly from ResolvedTransaction, // should we change the code to include ResolvedTransaction directly? @@ -72,6 +75,12 @@ pub struct TransactionScriptsVerifier<'a, CS> { block_data: FnvHashMap, lock_groups: FnvHashMap, type_groups: FnvHashMap, + + // On windows we won't need this config right now, but removing it + // on windows alone is too much effort comparing to simply allowing + // it here. + #[allow(dead_code)] + config: &'a ScriptConfig, } impl<'a, CS: ChainStore> TransactionScriptsVerifier<'a, CS> { @@ -390,6 +399,7 @@ impl<'a, CS: ChainStore> TransactionScriptsVerifier<'a, CS> { self.run(&program.into_owned().into(), &script_group, max_cycles) } + #[cfg(all(unix, target_pointer_width = "64"))] fn run( &self, program: &Bytes, @@ -469,6 +479,55 @@ impl<'a, CS: ChainStore> TransactionScriptsVerifier<'a, CS> { } } + #[cfg(not(all(unix, target_pointer_width = "64")))] + fn run( + &self, + program: &Bytes, + script_group: &ScriptGroup, + max_cycles: Cycle, + ) -> Result { + let current_script_hash = script_group.script.hash(); + let prefix = format!("script group: {:x}", current_script_hash); + let current_script_hash_bytes = current_script_hash.as_bytes(); + let mut args = vec!["verify".into()]; + args.extend_from_slice(&script_group.script.args); + let core_machine = + DefaultCoreMachine::>>::new_with_max_cycles( + max_cycles, + ); + let machine = DefaultMachineBuilder::< + DefaultCoreMachine>>, + >::new(core_machine) + .instruction_cycle_func(Box::new(instruction_cycles)) + .syscall(Box::new( + self.build_load_script_hash(current_script_hash_bytes), + )) + .syscall(Box::new(self.build_load_tx_hash())) + .syscall(Box::new(self.build_load_cell( + &script_group.input_indices, + &script_group.output_indices, + ))) + .syscall(Box::new(self.build_load_input(&script_group.input_indices))) + .syscall(Box::new( + self.build_load_header(&script_group.input_indices), + )) + .syscall(Box::new( + self.build_load_witness(&script_group.input_indices), + )) + .syscall(Box::new(Debugger::new(&prefix))) + .build(); + let mut machine = TraceMachine::new(machine); + machine + .load_program(&program, &args) + .map_err(ScriptError::VMError)?; + let code = machine.run().map_err(ScriptError::VMError)?; + if code == 0 { + Ok(machine.machine.cycles()) + } else { + Err(ScriptError::ValidationFailure(code)) + } + } + fn valid_dao_withdraw_transaction(&self) -> bool { self.resolved_inputs.iter().any(|input| { input diff --git a/util/app-config/src/app_config.rs b/util/app-config/src/app_config.rs index 2cd1ccd8a8..f563b26921 100644 --- a/util/app-config/src/app_config.rs +++ b/util/app-config/src/app_config.rs @@ -264,6 +264,7 @@ mod tests { p2p_port: "8000", log_to_file: true, log_to_stdout: true, + runner: "Assembly", }; { locator.export_ckb(&context).expect("export config files"); @@ -300,6 +301,7 @@ mod tests { p2p_port: "8000", log_to_file: false, log_to_stdout: true, + runner: "Assembly", }; { locator.export_ckb(&context).expect("export config files"); @@ -331,6 +333,7 @@ mod tests { p2p_port: "8000", log_to_file: true, log_to_stdout: true, + runner: "Assembly", }; locator.export_ckb(&context).expect("export config files"); { @@ -367,6 +370,7 @@ mod tests { p2p_port: "8000", log_to_file: true, log_to_stdout: true, + runner: "Assembly", }; locator.export_ckb(&context).expect("export config files"); { diff --git a/util/hash/Cargo.toml b/util/hash/Cargo.toml index d543522d91..9db1040213 100644 --- a/util/hash/Cargo.toml +++ b/util/hash/Cargo.toml @@ -6,7 +6,7 @@ authors = ["Nervos Core Dev "] edition = "2018" [dependencies] -blake2b-rs = "0.1.0" +blake2b-rs = "0.1.4" [dev-dependencies] faster-hex = "0.3" From 6b759754a8d4b060361c92c3292a2124b73b69ba Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Mon, 3 Jun 2019 15:28:29 +0800 Subject: [PATCH 02/17] fix: unit tests on windows --- resource/src/lib.rs | 6 +- script/src/verify.rs | 248 +++++++++++++++++------------- util/app-config/src/app_config.rs | 48 +++++- 3 files changed, 187 insertions(+), 115 deletions(-) diff --git a/resource/src/lib.rs b/resource/src/lib.rs index e25ab8843f..76120e52cb 100644 --- a/resource/src/lib.rs +++ b/resource/src/lib.rs @@ -246,7 +246,7 @@ mod tests { #[test] fn test_resource_locator_resolve() { let dir = mkdir(); - let spec_dev_path = touch(dir.path().join("specs/dev.toml")); + let spec_dev_path = touch(dir.path().join("specs").join("dev.toml")); let locator = ResourceLocator::with_root_dir(dir.path().to_path_buf()) .expect("resource root dir exists"); @@ -257,11 +257,11 @@ mod tests { ); assert_eq!( - locator.resolve("specs/testnet.toml".into()), + locator.resolve(PathBuf::from("specs").join("testnet.toml")), Some(Resource::Bundled("specs/testnet.toml".into())) ); assert_eq!( - locator.resolve("specs/dev.toml".into()), + locator.resolve(PathBuf::from("specs").join("dev.toml")), Some(Resource::FileSystem(spec_dev_path.clone())) ); diff --git a/script/src/verify.rs b/script/src/verify.rs index 72765ef85d..4a1aa20a76 100644 --- a/script/src/verify.rs +++ b/script/src/verify.rs @@ -545,6 +545,8 @@ impl<'a, CS: ChainStore> TransactionScriptsVerifier<'a, CS> { #[cfg(test)] mod tests { use super::*; + #[cfg(not(all(unix, target_pointer_width = "64")))] + use crate::Runner; use ckb_core::cell::{BlockInfo, CellMetaBuilder}; use ckb_core::extras::DaoStats; use ckb_core::header::HeaderBuilder; @@ -608,13 +610,10 @@ mod tests { let store = Arc::new(new_memory_store()); - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100).is_ok()); } @@ -685,19 +684,94 @@ mod tests { }; let store = Arc::new(new_memory_store()); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); + + assert!(verifier.verify(100_000_000).is_ok()); + } + + #[test] + fn check_signature_rust() { + let mut file = open_cell_verify(); + let mut buffer = Vec::new(); + file.read_to_end(&mut buffer).unwrap(); + + let gen = Generator::new(); + let privkey = gen.random_privkey(); + let mut args = vec![Bytes::from(b"foo".to_vec()), Bytes::from(b"bar".to_vec())]; + + let mut bytes = vec![]; + for argument in &args { + bytes.write_all(argument).unwrap(); + } + let hash1 = sha3_256(&bytes); + let hash2 = sha3_256(hash1); + let signature = privkey.sign_recoverable(&hash2.into()).unwrap(); + + let pubkey = privkey.pubkey().unwrap().serialize(); + let mut hex_pubkey = vec![0; pubkey.len() * 2]; + hex_encode(&pubkey, &mut hex_pubkey).expect("hex pubkey"); + args.push(Bytes::from(hex_pubkey)); + + let signature_der = signature.serialize_der(); + let mut hex_signature = vec![0; signature_der.len() * 2]; + hex_encode(&signature_der, &mut hex_signature).expect("hex signature"); + args.push(Bytes::from(hex_signature)); + + let code_hash: H256 = (&blake2b_256(&buffer)).into(); + let dep_out_point = OutPoint::new_cell(h256!("0x123"), 8); + let output = CellOutput::new( + Capacity::bytes(buffer.len()).unwrap(), + Bytes::from(buffer), + Script::default(), + None, + ); + let dep_cell = ResolvedOutPoint::cell_only( + CellMetaBuilder::from_cell_output(output) + .block_info(BlockInfo::new(1, 0)) + .data_hash(code_hash.to_owned()) + .out_point(dep_out_point.cell.clone().unwrap()) + .build(), + ); + + let script = Script::new(args, code_hash); + let input = CellInput::new(OutPoint::null(), 0); + + let transaction = TransactionBuilder::default() + .input(input.clone()) + .dep(dep_out_point) + .build(); + + let output = CellOutput::new(capacity_bytes!(100), Bytes::default(), script, None); + let dummy_cell = ResolvedOutPoint::cell_only( + CellMetaBuilder::from_cell_output(output.to_owned()) + .block_info(BlockInfo::new(1, 0)) + .build(), + ); + + let rtx = ResolvedTransaction { + transaction: &transaction, + resolved_deps: vec![dep_cell], + resolved_inputs: vec![dummy_cell], + }; + let store = Arc::new(new_memory_store()); + let verifier = TransactionScriptsVerifier::new( &rtx, store, &ScriptConfig { - runner: Runner::Assembly, + runner: Runner::Rust, }, ); assert!(verifier.verify(100_000_000).is_ok()); } + #[cfg(all(unix, target_pointer_width = "64"))] #[test] - fn check_signature_rust() { + fn check_signature_assembly() { let mut file = open_cell_verify(); let mut buffer = Vec::new(); file.read_to_end(&mut buffer).unwrap(); @@ -766,7 +840,7 @@ mod tests { &rtx, store, &ScriptConfig { - runner: Runner::Rust, + runner: Runner::Assembly, }, ); @@ -840,13 +914,10 @@ mod tests { let store = Arc::new(new_memory_store()); - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100).is_err()); } @@ -919,13 +990,10 @@ mod tests { }; let store = Arc::new(new_memory_store()); - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_err()); } @@ -983,13 +1051,10 @@ mod tests { }; let store = Arc::new(new_memory_store()); - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_err()); } @@ -1078,13 +1143,10 @@ mod tests { }; let store = Arc::new(new_memory_store()); - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_ok()); } @@ -1176,13 +1238,10 @@ mod tests { let store = Arc::new(new_memory_store()); - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_err()); } @@ -1207,13 +1266,10 @@ mod tests { }; let store = Arc::new(new_memory_store()); - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_err()); } @@ -1317,13 +1373,10 @@ mod tests { ], }; - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_ok()); } @@ -1427,13 +1480,10 @@ mod tests { ], }; - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_ok()); } @@ -1524,13 +1574,10 @@ mod tests { ], }; - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_err()); } @@ -1634,13 +1681,10 @@ mod tests { ], }; - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100).is_err()); } @@ -1732,13 +1776,10 @@ mod tests { ], }; - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_err()); } @@ -1842,13 +1883,10 @@ mod tests { ], }; - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_err()); } @@ -1952,13 +1990,10 @@ mod tests { ], }; - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); assert!(verifier.verify(100_000_000).is_err()); } @@ -2033,13 +2068,10 @@ mod tests { }; let store = Arc::new(new_memory_store()); - let verifier = TransactionScriptsVerifier::new( - &rtx, - store, - &ScriptConfig { - runner: Runner::Assembly, - }, - ); + let config = ScriptConfig { + runner: Runner::default(), + }; + let verifier = TransactionScriptsVerifier::new(&rtx, store, &config); // Cycles can tell that both lock and type scripts are executed assert_eq!(verifier.verify(100_000_000), Ok(2_818_104)); diff --git a/util/app-config/src/app_config.rs b/util/app-config/src/app_config.rs index f563b26921..8e7a26daf0 100644 --- a/util/app-config/src/app_config.rs +++ b/util/app-config/src/app_config.rs @@ -221,6 +221,7 @@ mod tests { .unwrap() } + #[cfg(all(unix, target_pointer_width = "64"))] #[test] fn test_ckb_toml() { let dir = mkdir(); @@ -240,6 +241,7 @@ mod tests { ); } + #[cfg(all(unix, target_pointer_width = "64"))] #[test] fn test_miner_toml() { let dir = mkdir(); @@ -264,7 +266,7 @@ mod tests { p2p_port: "8000", log_to_file: true, log_to_stdout: true, - runner: "Assembly", + runner: "Rust", }; { locator.export_ckb(&context).expect("export config files"); @@ -301,7 +303,7 @@ mod tests { p2p_port: "8000", log_to_file: false, log_to_stdout: true, - runner: "Assembly", + runner: "Rust", }; { locator.export_ckb(&context).expect("export config files"); @@ -333,7 +335,7 @@ mod tests { p2p_port: "8000", log_to_file: true, log_to_stdout: true, - runner: "Assembly", + runner: "Rust", }; locator.export_ckb(&context).expect("export config files"); { @@ -370,7 +372,7 @@ mod tests { p2p_port: "8000", log_to_file: true, log_to_stdout: true, - runner: "Assembly", + runner: "Rust", }; locator.export_ckb(&context).expect("export config files"); { @@ -399,4 +401,42 @@ mod tests { assert_eq!(miner_config.miner.rpc_url, "http://127.0.0.1:7000/"); } } + + #[cfg(all(unix, target_pointer_width = "64"))] + #[test] + fn test_export_dev_config_files_assembly() { + let dir = mkdir(); + let locator = ResourceLocator::with_root_dir(dir.path().to_path_buf()).unwrap(); + let context = TemplateContext { + spec: "dev", + rpc_port: "7000", + p2p_port: "8000", + log_to_file: true, + log_to_stdout: true, + runner: "Assembly", + }; + { + locator.export_ckb(&context).expect("export config files"); + let app_config = AppConfig::load_for_subcommand(&locator, cli::CMD_RUN) + .unwrap_or_else(|err| panic!(err)); + let ckb_config = app_config.into_ckb().unwrap_or_else(|err| panic!(err)); + assert_eq!(ckb_config.logger.filter, Some("info".to_string())); + assert_eq!(ckb_config.chain.spec, PathBuf::from("specs/dev.toml")); + assert_eq!( + ckb_config.network.listen_addresses, + vec!["/ip4/0.0.0.0/tcp/8000".parse().unwrap()] + ); + assert_eq!(ckb_config.network.connect_outbound_interval_secs, 15); + assert_eq!(ckb_config.rpc.listen_address, "127.0.0.1:7000"); + } + { + locator.export_miner(&context).expect("export config files"); + let app_config = AppConfig::load_for_subcommand(&locator, cli::CMD_MINER) + .unwrap_or_else(|err| panic!(err)); + let miner_config = app_config.into_miner().unwrap_or_else(|err| panic!(err)); + assert_eq!(miner_config.logger.filter, Some("info".to_string())); + assert_eq!(miner_config.chain.spec, PathBuf::from("specs/dev.toml")); + assert_eq!(miner_config.miner.rpc_url, "http://127.0.0.1:7000/"); + } + } } From 77552fe798df88cb54aeaf554614858555d44daa Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Mon, 3 Jun 2019 18:35:49 +0800 Subject: [PATCH 03/17] fix: integration test on windows --- resource/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resource/src/lib.rs b/resource/src/lib.rs index 76120e52cb..69451febb1 100644 --- a/resource/src/lib.rs +++ b/resource/src/lib.rs @@ -198,7 +198,11 @@ fn path_as_key(path: &PathBuf) -> Cow { } fn file_system(path: PathBuf) -> Option { - path.canonicalize().ok().map(Resource::FileSystem) + if path.exists() { + Some(Resource::FileSystem(path)) + } else { + None + } } pub fn bundled(path: PathBuf) -> Option { From 620f8646a9af7c9f5d4b388d0efdbe2133053d26 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Tue, 4 Jun 2019 07:03:32 +0000 Subject: [PATCH 04/17] feat: add initial appveyor CI configuration file --- appveyor.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000000..0d927d2a07 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,29 @@ +platform: + - x64 +environment: + RUST_INSTALL_DIR: C:\Rust + matrix: + - RUST_INSTALL_TRIPLE: x86_64-pc-windows-msvc + VCVARS: "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\vcvars64.bat" + RUST_VERSION: 1.34.2 + +install: + - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:RUST_VERSION}-${env:RUST_INSTALL_TRIPLE}.exe" + - cmd: rust-%RUST_VERSION%-%RUST_INSTALL_TRIPLE%.exe /VERYSILENT /NORESTART /DIR="%RUST_INSTALL_DIR%" + # Use clean path to work around cyghead base mismatch issue + - cmd: SET PATH=C:\Windows\System32;C:\Windows;C:\Windows\System32\Wbem;C:\msys64\usr\bin + - cmd: CALL "%VCVARS%" + - cmd: SET PATH=%PATH%;%RUST_INSTALL_DIR%\bin + - rustc --version + - cargo --version + - make --version + - cp --version + +build: false +test_script: + - cmd: SET RUST_BACKTRACE=full + # The plan we are using for appveyor now cannot finish unit tests + # and integration tests in one run, so we have to separate them to + # run unit in branches, and integration tests in PRs + - if NOT defined APPVEYOR_PULL_REQUEST_NUMBER make test + - if defined APPVEYOR_PULL_REQUEST_NUMBER make integration From 25676ac205fdc2a98897c5c81b3b2b6d6b203f05 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Mon, 3 Jun 2019 18:45:56 +0800 Subject: [PATCH 05/17] fix: simplify the code now that we know the problem is canonicalize --- db/src/rocksdb.rs | 56 +++---------------------------- resource/src/lib.rs | 22 +++++------- util/app-config/src/app_config.rs | 5 ++- 3 files changed, 16 insertions(+), 67 deletions(-) diff --git a/db/src/rocksdb.rs b/db/src/rocksdb.rs index 86c51a3261..1b230736d1 100644 --- a/db/src/rocksdb.rs +++ b/db/src/rocksdb.rs @@ -1,9 +1,7 @@ use crate::{Col, DBConfig, DbBatch, Error, KeyValueDB, Result}; use log::{info, warn}; use rocksdb::{ColumnFamily, Error as RdbError, IteratorMode, Options, WriteBatch, DB}; -use std::ffi::OsString; use std::ops::Range; -use std::path::{Component, PathBuf}; use std::sync::Arc; // If any data format in database was changed, we have to update this constant manually. @@ -17,50 +15,6 @@ pub struct RocksDB { inner: Arc, } -// This is a windows-specific fix. Even though we are using correct path joins -// throughout this project, rocksdb has a quirk where it would uses unix paths: -// https://github.com/facebook/rocksdb/blob/000b9ec217663faad1d0196b28c623149e01e024/file/filename.cc#L159 -// The result here is that we might have paths like \\?\C:\ckb\node\data\db/LOCK, -// which would be rejected by windows. This method would process pathes such as -// \\?\C:\ckb\node\data\db into //?/C:/ckb/node/data/db, making the final LOCK path -// as //?/C:/ckb/node/data/db/LOCK and it should work here. -// The same code also works on UNIX systems, so we are keeping it in both cases -// to detect build errors earlier. -fn normalize_path(path: &PathBuf) -> OsString { - let mut s = OsString::new(); - for c in path.components() { - match c { - Component::Prefix(prefix_component) => { - // Prefix component is a windows-specific path prefix, such as - // C: or \\server\share. Since OsString does not have a replace - // method, we have to cast it to a normal str, do the replacement - // and convert it back. This might bring a problem when we have - // a prefix that is not UTF-8. Let's revisit it later when it indeed - // is an issue. - let prefix: OsString = prefix_component - .as_os_str() - .to_str() - .expect("invalid prefix on windows!") - .replace("\\", "/") - .to_string() - .into(); - if !s.is_empty() { - s.push("/"); - } - s.push(prefix); - } - Component::Normal(part) => { - if !s.is_empty() { - s.push("/"); - } - s.push(part.to_os_string()); - } - _ => (), - } - } - s -} - impl RocksDB { pub(crate) fn open_with_check( config: &DBConfig, @@ -75,16 +29,14 @@ impl RocksDB { let cfnames: Vec<_> = (0..columns).map(|c| c.to_string()).collect(); let cf_options: Vec<&str> = cfnames.iter().map(|n| n as &str).collect(); - let path = normalize_path(&config.path); - - let db = DB::open_cf(&opts, &path, &cf_options).or_else(|err| { + let db = DB::open_cf(&opts, &config.path, &cf_options).or_else(|err| { let err_str = err.as_ref(); if err_str.starts_with("Invalid argument:") && err_str.ends_with("does not exist (create_if_missing is false)") { info!("Initialize a new database"); opts.create_if_missing(true); - let db = DB::open_cf(&opts, &path, &cf_options).map_err(|err| { + let db = DB::open_cf(&opts, &config.path, &cf_options).map_err(|err| { Error::DBError(format!("failed to open a new created database: {}", err)) })?; db.put(ver_key, ver_val).map_err(|err| { @@ -96,11 +48,11 @@ impl RocksDB { let mut repair_opts = Options::default(); repair_opts.create_if_missing(false); repair_opts.create_missing_column_families(false); - DB::repair(repair_opts, &path).map_err(|err| { + DB::repair(repair_opts, &config.path).map_err(|err| { Error::DBError(format!("failed to repair the database: {}", err)) })?; warn!("Opening the repaired rocksdb ..."); - DB::open_cf(&opts, &path, &cf_options).map_err(|err| { + DB::open_cf(&opts, &config.path, &cf_options).map_err(|err| { Error::DBError(format!("failed to open the repaired database: {}", err)) }) } else { diff --git a/resource/src/lib.rs b/resource/src/lib.rs index 69451febb1..4836c6b391 100644 --- a/resource/src/lib.rs +++ b/resource/src/lib.rs @@ -82,16 +82,13 @@ impl ResourceLocator { pub fn with_root_dir(root_dir: PathBuf) -> Result { fs::create_dir_all(&root_dir)?; - root_dir - .canonicalize() - .map(|root_dir| ResourceLocator { root_dir }) + Ok(ResourceLocator { root_dir }) } pub fn current_dir() -> Result { let root_dir = ::std::env::current_dir()?; - root_dir - .canonicalize() - .map(|root_dir| ResourceLocator { root_dir }) + + Ok(ResourceLocator { root_dir }) } pub fn ckb(&self) -> Resource { @@ -169,10 +166,7 @@ impl ResourceLocator { } pub fn export<'a>(&self, name: &str, context: &TemplateContext<'a>) -> Result<()> { - // We need to do the join one part at a time to handle Windows paths. - let target = name - .split('/') - .fold(self.root_dir.clone(), |path, name| path.join(name)); + let target = self.root_dir.join(name); let resource = Resource::Bundled(name.to_string()); let template = Template::new(from_utf8(resource.get()?)?); let mut out = NamedTempFile::new_in(&self.root_dir)?; @@ -244,13 +238,13 @@ mod tests { .open(&path) .expect("touch file in test"); - path.as_ref().canonicalize().expect("touch file in test") + path.as_ref().to_path_buf() } #[test] fn test_resource_locator_resolve() { let dir = mkdir(); - let spec_dev_path = touch(dir.path().join("specs").join("dev.toml")); + let spec_dev_path = touch(dir.path().join("specs/dev.toml")); let locator = ResourceLocator::with_root_dir(dir.path().to_path_buf()) .expect("resource root dir exists"); @@ -261,11 +255,11 @@ mod tests { ); assert_eq!( - locator.resolve(PathBuf::from("specs").join("testnet.toml")), + locator.resolve("specs/testnet.toml".into()), Some(Resource::Bundled("specs/testnet.toml".into())) ); assert_eq!( - locator.resolve(PathBuf::from("specs").join("dev.toml")), + locator.resolve("specs/dev.toml".into()), Some(Resource::FileSystem(spec_dev_path.clone())) ); diff --git a/util/app-config/src/app_config.rs b/util/app-config/src/app_config.rs index 8e7a26daf0..f7ad819705 100644 --- a/util/app-config/src/app_config.rs +++ b/util/app-config/src/app_config.rs @@ -197,7 +197,10 @@ fn canonicalize_data_dir(data_dir: PathBuf, root_dir: &Path) -> Result Result { fs::create_dir_all(&dir)?; - dir.canonicalize().map_err(Into::into) + // TODO: Use https://github.com/danreeves/path-clean to clean the + // path if needed. std::fs::canonicalize will bring windows compatibility + // problems + Ok(dir) } fn touch(path: PathBuf) -> Result { From 1bce658c3a2f0f63cec46a0c5f27124395ebd9b0 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Tue, 4 Jun 2019 08:00:43 +0000 Subject: [PATCH 06/17] fix: skip target linking on windows --- Makefile | 5 +++++ appveyor.yml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index de1bedf12d..ec9722e6a4 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,11 @@ integration: setup-ckb-test ## Run integration tests in "test" dir. cargo build ${VERBOSE} cd test && cargo run ../target/debug/ckb +integration-windows: + cp -f Cargo.lock test/Cargo.lock + cargo build ${VERBOSE} + cd test && cargo run ../target/debug/ckb + integration-release: setup-ckb-test cargo build ${VERBOSE} --release cd test && cargo run --release -- ../target/release/ckb diff --git a/appveyor.yml b/appveyor.yml index 0d927d2a07..af723ab5e3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,4 +26,4 @@ test_script: # and integration tests in one run, so we have to separate them to # run unit in branches, and integration tests in PRs - if NOT defined APPVEYOR_PULL_REQUEST_NUMBER make test - - if defined APPVEYOR_PULL_REQUEST_NUMBER make integration + - if defined APPVEYOR_PULL_REQUEST_NUMBER make integration-windows From 34983bf65198bf20d9b1b1a64c61fcfc02496ad7 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Tue, 4 Jun 2019 11:25:53 +0000 Subject: [PATCH 07/17] feat: add Azure Pipeline CI configuration files --- ci/azure-pipelines.yml | 20 ++++++++++++++++++++ ci/windows-dependencies.yml | 17 +++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 ci/azure-pipelines.yml create mode 100644 ci/windows-dependencies.yml diff --git a/ci/azure-pipelines.yml b/ci/azure-pipelines.yml new file mode 100644 index 0000000000..0b9823ab3e --- /dev/null +++ b/ci/azure-pipelines.yml @@ -0,0 +1,20 @@ +jobs: + - job: UnitTest + pool: + vmImage: 'VS2017-Win2016' + steps: + - template: windows-dependencies.yml + parameters: + rustup_toolchain: '1.34.2-x86_64-pc-windows-msvc' + - script: make test + displayName: Run unit tests + - job: IntegrationTest + condition: eq(variables['Build.Reason'], 'PullRequest') + pool: + vmImage: 'VS2017-Win2016' + steps: + - template: windows-dependencies.yml + parameters: + rustup_toolchain: '1.34.2-x86_64-pc-windows-msvc' + - script: make integration-windows + displayName: Run integration tests diff --git a/ci/windows-dependencies.yml b/ci/windows-dependencies.yml new file mode 100644 index 0000000000..e08d977157 --- /dev/null +++ b/ci/windows-dependencies.yml @@ -0,0 +1,17 @@ +parameters: + rustup_toolchain: '' +steps: +- script: choco install -y llvm + displayName: Install LLVM +- script: choco install -y msys2 + displayName: Install msys2 +- script: | + curl -sSf -o rustup-init.exe https://win.rustup.rs + rustup-init.exe -y --default-toolchain ${{ parameters.rustup_toolchain }} + set PATH=%PATH%;%USERPROFILE%\.cargo\bin + echo "##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin" + displayName: Install rust +- script: | + rustc --version + cargo --version + displayName: Test/query rust and cargo versions From fa1a8e82e5acc7ddca43bfa2bcb4378e54bc5653 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Tue, 4 Jun 2019 13:22:13 +0000 Subject: [PATCH 08/17] fix: integration test triggering logic --- appveyor.yml | 4 ++-- ci/azure-pipelines.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index af723ab5e3..b67895ffcf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -25,5 +25,5 @@ test_script: # The plan we are using for appveyor now cannot finish unit tests # and integration tests in one run, so we have to separate them to # run unit in branches, and integration tests in PRs - - if NOT defined APPVEYOR_PULL_REQUEST_NUMBER make test - - if defined APPVEYOR_PULL_REQUEST_NUMBER make integration-windows + - if defined APPVEYOR_PULL_REQUEST_NUMBER make test + - if NOT defined APPVEYOR_PULL_REQUEST_NUMBER make integration-windows diff --git a/ci/azure-pipelines.yml b/ci/azure-pipelines.yml index 0b9823ab3e..4b41b2eb62 100644 --- a/ci/azure-pipelines.yml +++ b/ci/azure-pipelines.yml @@ -9,7 +9,7 @@ jobs: - script: make test displayName: Run unit tests - job: IntegrationTest - condition: eq(variables['Build.Reason'], 'PullRequest') + condition: ne(variables['Build.Reason'], 'PullRequest') pool: vmImage: 'VS2017-Win2016' steps: From 2e613a2693af03cab09227c19157547058bc8b4c Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Tue, 4 Jun 2019 13:23:15 +0000 Subject: [PATCH 09/17] chore: move azure pipeline configuration files to devtools --- ci/azure-pipelines.yml => devtools/azure/pipelines.yml | 0 {ci => devtools/azure}/windows-dependencies.yml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename ci/azure-pipelines.yml => devtools/azure/pipelines.yml (100%) rename {ci => devtools/azure}/windows-dependencies.yml (100%) diff --git a/ci/azure-pipelines.yml b/devtools/azure/pipelines.yml similarity index 100% rename from ci/azure-pipelines.yml rename to devtools/azure/pipelines.yml diff --git a/ci/windows-dependencies.yml b/devtools/azure/windows-dependencies.yml similarity index 100% rename from ci/windows-dependencies.yml rename to devtools/azure/windows-dependencies.yml From 806481be870d96e3c6fd89ead2dd885c0bfe23df Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Tue, 4 Jun 2019 13:48:20 +0000 Subject: [PATCH 10/17] fix: only run integration test in branch CIs --- devtools/azure/pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/devtools/azure/pipelines.yml b/devtools/azure/pipelines.yml index 4b41b2eb62..dcf5820c37 100644 --- a/devtools/azure/pipelines.yml +++ b/devtools/azure/pipelines.yml @@ -1,5 +1,6 @@ jobs: - job: UnitTest + condition: eq(variables['Build.Reason'], 'PullRequest') pool: vmImage: 'VS2017-Win2016' steps: From 97b28f7e484dc8ae230eaa1813821b1f6d0742e0 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Tue, 4 Jun 2019 13:57:50 +0000 Subject: [PATCH 11/17] fix: unit test triggering logic --- devtools/azure/pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/azure/pipelines.yml b/devtools/azure/pipelines.yml index dcf5820c37..ed1251a530 100644 --- a/devtools/azure/pipelines.yml +++ b/devtools/azure/pipelines.yml @@ -1,6 +1,6 @@ jobs: - job: UnitTest - condition: eq(variables['Build.Reason'], 'PullRequest') + condition: or(eq(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranchName'], 'master'), startsWith(variables['Build.SourceBranchName'], 'test')) pool: vmImage: 'VS2017-Win2016' steps: From 553552b2bb1347d9ec2f666b13c5206d9970bd31 Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 4 Jun 2019 22:21:13 +0800 Subject: [PATCH 12/17] chore(ci): move azure-pipelines.yml to top level --- devtools/azure/pipelines.yml => azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename devtools/azure/pipelines.yml => azure-pipelines.yml (85%) diff --git a/devtools/azure/pipelines.yml b/azure-pipelines.yml similarity index 85% rename from devtools/azure/pipelines.yml rename to azure-pipelines.yml index ed1251a530..ac581116b4 100644 --- a/devtools/azure/pipelines.yml +++ b/azure-pipelines.yml @@ -4,7 +4,7 @@ jobs: pool: vmImage: 'VS2017-Win2016' steps: - - template: windows-dependencies.yml + - template: devtools/azure/windows-dependencies.yml parameters: rustup_toolchain: '1.34.2-x86_64-pc-windows-msvc' - script: make test @@ -14,7 +14,7 @@ jobs: pool: vmImage: 'VS2017-Win2016' steps: - - template: windows-dependencies.yml + - template: devtools/azure/windows-dependencies.yml parameters: rustup_toolchain: '1.34.2-x86_64-pc-windows-msvc' - script: make integration-windows From 0a4eb7acf85694fe9675693f503cb569e68e2ad2 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 1 Jun 2019 21:10:13 +0800 Subject: [PATCH 13/17] chore: group sentry events via fingerprint --- miner/src/client.rs | 4 ---- network/src/network.rs | 30 ++++++++++++++++--------- rpc/src/module/miner.rs | 15 ++++++++----- sync/src/relayer/transaction_process.rs | 21 ++++++++++++----- 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/miner/src/client.rs b/miner/src/client.rs index cdc1444dd1..3676e74575 100644 --- a/miner/src/client.rs +++ b/miner/src/client.rs @@ -149,10 +149,6 @@ impl Client { } Err(e) => { error!("rpc call submit_block error: {:?}", e); - sentry::capture_message( - &format!("rpc call submit_block error: {:?}", e), - sentry::Level::Error, - ); } } } diff --git a/network/src/network.rs b/network/src/network.rs index 8e5233546a..0014b1df30 100644 --- a/network/src/network.rs +++ b/network/src/network.rs @@ -363,14 +363,21 @@ impl NetworkState { addr ); if dial_started.elapsed() > DIAL_HANG_TIMEOUT { - sentry::capture_message( - &format!( - "Dialing {:?}, {:?} for more than {} seconds, something is wrong in network service", - peer_id, - addr, - DIAL_HANG_TIMEOUT.as_secs(), - ), - sentry::Level::Warning, + use sentry::{capture_message, with_scope, Level}; + with_scope( + |scope| scope.set_fingerprint(Some(&["ckb-network", "dialing-timeout"])), + || { + capture_message( + &format!( + "Dialing {:?}, {:?} for more than {} seconds, \ + something is wrong in network service", + peer_id, + addr, + DIAL_HANG_TIMEOUT.as_secs(), + ), + Level::Warning, + ) + }, ); } return false; @@ -507,9 +514,10 @@ impl ServiceHandle for EventHandler { } err => { debug!("p2p service error: {:?}", err); - sentry::capture_message( - &format!("p2p service error: {:?}", err), - sentry::Level::Warning, + use sentry::{capture_message, with_scope, Level}; + with_scope( + |scope| scope.set_fingerprint(Some(&["ckb-network", "p2p-service-error"])), + || capture_message(&format!("p2p service error: {:?}", err), Level::Warning), ); } } diff --git a/rpc/src/module/miner.rs b/rpc/src/module/miner.rs index 9fa00ddc0b..d97d6dc872 100644 --- a/rpc/src/module/miner.rs +++ b/rpc/src/module/miner.rs @@ -108,11 +108,16 @@ impl MinerRpc for MinerRpcImpl { Ok(Some(block.header().hash().to_owned())) } else { error!("[{}] submit_block process_block {:?}", work_id, ret); - sentry::capture_event(sentry::protocol::Event { - message: Some(format!("submit_block process_block {:?}", ret)), - level: sentry::Level::Error, - ..Default::default() - }); + use sentry::{capture_message, with_scope, Level}; + with_scope( + |scope| scope.set_fingerprint(Some(&["ckb-rpc", "miner", "submit_block"])), + || { + capture_message( + &format!("submit_block process_block {:?}", ret), + Level::Error, + ) + }, + ); Ok(None) } } else { diff --git a/sync/src/relayer/transaction_process.rs b/sync/src/relayer/transaction_process.rs index 03cb937d1d..42e230fd8f 100644 --- a/sync/src/relayer/transaction_process.rs +++ b/sync/src/relayer/transaction_process.rs @@ -109,12 +109,21 @@ impl<'a, CS: ChainStore + Sync + 'static> TransactionProcess<'a, CS> { tx_hash, err ); - sentry::capture_message( - &format!( - "ban peer {} {:?}, reason: relay invalid tx: {:?}, error: {:?}", - self_peer, DEFAULT_BAN_TIME, tx, err - ), - sentry::Level::Info, + use sentry::{capture_message, with_scope, Level}; + with_scope( + |scope| { + scope.set_fingerprint(Some(&["ckb-sync", "relay-invalid-tx"])) + }, + || { + capture_message( + &format!( + "ban peer {} {:?}, reason: \ + relay invalid tx: {:?}, error: {:?}", + self_peer, DEFAULT_BAN_TIME, tx, err + ), + Level::Info, + ) + }, ); nc.ban_peer(self_peer, DEFAULT_BAN_TIME); } else { From 4f45aace6713ac24b48ad835a3713ce0975e2cf2 Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 5 Jun 2019 07:30:21 +0800 Subject: [PATCH 14/17] chore(ci): remove appveyor --- appveyor.yml | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index b67895ffcf..0000000000 --- a/appveyor.yml +++ /dev/null @@ -1,29 +0,0 @@ -platform: - - x64 -environment: - RUST_INSTALL_DIR: C:\Rust - matrix: - - RUST_INSTALL_TRIPLE: x86_64-pc-windows-msvc - VCVARS: "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\vcvars64.bat" - RUST_VERSION: 1.34.2 - -install: - - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:RUST_VERSION}-${env:RUST_INSTALL_TRIPLE}.exe" - - cmd: rust-%RUST_VERSION%-%RUST_INSTALL_TRIPLE%.exe /VERYSILENT /NORESTART /DIR="%RUST_INSTALL_DIR%" - # Use clean path to work around cyghead base mismatch issue - - cmd: SET PATH=C:\Windows\System32;C:\Windows;C:\Windows\System32\Wbem;C:\msys64\usr\bin - - cmd: CALL "%VCVARS%" - - cmd: SET PATH=%PATH%;%RUST_INSTALL_DIR%\bin - - rustc --version - - cargo --version - - make --version - - cp --version - -build: false -test_script: - - cmd: SET RUST_BACKTRACE=full - # The plan we are using for appveyor now cannot finish unit tests - # and integration tests in one run, so we have to separate them to - # run unit in branches, and integration tests in PRs - - if defined APPVEYOR_PULL_REQUEST_NUMBER make test - - if NOT defined APPVEYOR_PULL_REQUEST_NUMBER make integration-windows From ff293b48e49f537067248e015d8d0e5fbcc3e46b Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 5 Jun 2019 08:10:11 +0800 Subject: [PATCH 15/17] chore: create windows package via azure --- azure-pipelines.yml | 54 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ac581116b4..31c6c6d3d8 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,6 +1,22 @@ +trigger: + branches: + include: + - '*' + tags: + include: + - '*' + jobs: - job: UnitTest - condition: or(eq(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranchName'], 'master'), startsWith(variables['Build.SourceBranchName'], 'test')) + condition: | + and( + not(startsWith(variables['Build.SourceBranch'], 'refs/tags/')), + or( + eq(variables['Build.Reason'], 'PullRequest'), + eq(variables['Build.SourceBranch'], 'refs/heads/master'), + startsWith(variables['Build.SourceBranch'], 'refs/heads/test') + ) + ) pool: vmImage: 'VS2017-Win2016' steps: @@ -9,8 +25,13 @@ jobs: rustup_toolchain: '1.34.2-x86_64-pc-windows-msvc' - script: make test displayName: Run unit tests + - job: IntegrationTest - condition: ne(variables['Build.Reason'], 'PullRequest') + condition: | + and( + not(startsWith(variables['Build.SourceBranch'], 'refs/tags/')), + ne(variables['Build.Reason'], 'PullRequest') + ) pool: vmImage: 'VS2017-Win2016' steps: @@ -19,3 +40,32 @@ jobs: rustup_toolchain: '1.34.2-x86_64-pc-windows-msvc' - script: make integration-windows displayName: Run integration tests + + - job: Package + condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/') + pool: + vmImage: 'VS2017-Win2016' + steps: + - template: devtools/azure/windows-dependencies.yml + parameters: + rustup_toolchain: '1.34.2-x86_64-pc-windows-msvc' + - script: make prod + displayName: Build + - powershell: | + mkdir ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc + cp -r target/release/ckb,README.md,CHANGELOG.md,COPYING,devtools/init,docs ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc + cp rpc/README.md ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc/docs/rpc.md + displayName: Prepare archive + - task: ArchiveFiles@2 + inputs: + rootFolderOrFile: 'ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc' + archiveFile: '$(Build.ArtifactStagingDirectory)/ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc.zip' + - task: GitHubRelease@0 + inputs: + gitHubConnection: nervos-bot + repositoryName: nervosnetwork/ckb + action: edit + tag: $(Build.SourceBranchName) + assets: '$(Build.ArtifactStagingDirectory)/*.zip' + assetUploadMode: replace + isPreRelease: true From 1d7b8f727b4756b0f93dd0cb8304a274cba7c46f Mon Sep 17 00:00:00 2001 From: Quake Wang Date: Wed, 5 Jun 2019 17:02:46 +0900 Subject: [PATCH 16/17] chore: use large timeout value for integration test (#954) --- test/src/net.rs | 5 +-- test/src/node.rs | 6 ++-- test/src/specs/relay/compact_block.rs | 4 +-- test/src/specs/relay/transaction_relay.rs | 4 +-- test/src/specs/sync/chain_forks.rs | 42 +++++++++++------------ test/src/specs/sync/sync_timeout.rs | 8 ++--- test/src/specs/tx_pool/pool_reconcile.rs | 2 +- test/src/specs/tx_pool/pool_resurrect.rs | 2 +- 8 files changed, 36 insertions(+), 37 deletions(-) diff --git a/test/src/net.rs b/test/src/net.rs index e857720ac5..9565369f5e 100644 --- a/test/src/net.rs +++ b/test/src/net.rs @@ -122,10 +122,11 @@ impl Net { }); } - pub fn waiting_for_sync(&self, target: BlockNumber, timeout: u64) { + pub fn waiting_for_sync(&self, target: BlockNumber) { let rpc_clients: Vec<_> = self.nodes.iter().map(Node::rpc_client).collect(); let mut tip_numbers: HashSet = HashSet::with_capacity(self.nodes.len()); - let result = wait_until(timeout, || { + // 60 seconds is a reasonable timeout to sync, even for poor CI server + let result = wait_until(60, || { tip_numbers = rpc_clients .iter() .map(|rpc_client| rpc_client.get_tip_block_number()) diff --git a/test/src/node.rs b/test/src/node.rs index 4b417aa8b4..4eafcdf588 100644 --- a/test/src/node.rs +++ b/test/src/node.rs @@ -145,12 +145,12 @@ impl Node { } } - pub fn waiting_for_sync(&self, node: &Node, target: BlockNumber, timeout: u64) { + pub fn waiting_for_sync(&self, node: &Node, target: BlockNumber) { let self_rpc_client = self.rpc_client(); let node_rpc_client = node.rpc_client(); let (mut self_tip_number, mut node_tip_number) = (0, 0); - - let result = wait_until(timeout, || { + // 60 seconds is a reasonable timeout to sync, even for poor CI server + let result = wait_until(60, || { self_tip_number = self_rpc_client.get_tip_block_number(); node_tip_number = node_rpc_client.get_tip_block_number(); self_tip_number == node_tip_number && target == self_tip_number diff --git a/test/src/specs/relay/compact_block.rs b/test/src/specs/relay/compact_block.rs index ea97f83a85..3996841eeb 100644 --- a/test/src/specs/relay/compact_block.rs +++ b/test/src/specs/relay/compact_block.rs @@ -161,7 +161,7 @@ impl CompactBlockBasic { // Make node0 and node1 reach the same height node1.generate_block(); node0.connect(node1); - node0.waiting_for_sync(node1, node0.get_tip_block().header().number(), 20); + node0.waiting_for_sync(node1, node0.get_tip_block().header().number()); // Net consume and ignore the recent blocks clear_messages(net); @@ -191,7 +191,7 @@ impl CompactBlockBasic { // Submit the new block to node1. We expect node1 will relay the new block to node0. node1.submit_block(&block); - node1.waiting_for_sync(node0, node1.get_tip_block().header().number(), 20); + node1.waiting_for_sync(node0, node1.get_tip_block().header().number()); } } diff --git a/test/src/specs/relay/transaction_relay.rs b/test/src/specs/relay/transaction_relay.rs index 9e7afe3b0a..e3de84db72 100644 --- a/test/src/specs/relay/transaction_relay.rs +++ b/test/src/specs/relay/transaction_relay.rs @@ -78,7 +78,7 @@ impl Spec for TransactionRelayMultiple { node0.generate_block(); node0.generate_block(); node0.generate_block(); - net.waiting_for_sync(4, 10); + net.waiting_for_sync(4); info!("Send multiple transactions to node0"); let tx_hash = transaction.hash().to_owned(); @@ -101,7 +101,7 @@ impl Spec for TransactionRelayMultiple { node0.generate_block(); node0.generate_block(); node0.generate_block(); - net.waiting_for_sync(7, 30); + net.waiting_for_sync(7); info!("All transactions should be relayed and mined"); node0.assert_tx_pool_size(0, 0); diff --git a/test/src/specs/sync/chain_forks.rs b/test/src/specs/sync/chain_forks.rs index bafa4773b1..c8fee92d97 100644 --- a/test/src/specs/sync/chain_forks.rs +++ b/test/src/specs/sync/chain_forks.rs @@ -23,7 +23,7 @@ impl Spec for ChainFork1 { info!("Connect node0 to node1"); node0.connect(node1); - node0.waiting_for_sync(node1, 2, 10); + node0.waiting_for_sync(node1, 2); info!("Disconnect node1"); node0.disconnect(node1); @@ -34,7 +34,7 @@ impl Spec for ChainFork1 { info!("Reconnect node0 to node1"); node0.connect(node1); - net.waiting_for_sync(4, 10); + net.waiting_for_sync(4); } fn num_nodes(&self) -> usize { @@ -66,14 +66,14 @@ impl Spec for ChainFork2 { info!("Connect all nodes"); node0.connect(node1); node0.connect(node2); - net.waiting_for_sync(2, 10); + net.waiting_for_sync(2); info!("Disconnect all nodes"); net.disconnect_all(); info!("Generate 1 block (C) on node0"); node0.generate_blocks(1); node0.connect(node2); - node0.waiting_for_sync(node2, 3, 10); + node0.waiting_for_sync(node2, 3); info!("Disconnect node2"); node0.disconnect(node2); @@ -81,14 +81,14 @@ impl Spec for ChainFork2 { node1.generate_blocks(2); info!("Reconnect node1"); node0.connect(node1); - node0.waiting_for_sync(node1, 4, 10); + node0.waiting_for_sync(node1, 4); info!("Generate 2 blocks (F, G) on node2"); node2.generate_blocks(2); info!("Reconnect node2"); node0.connect(node2); node1.connect(node2); - net.waiting_for_sync(5, 10); + net.waiting_for_sync(5); } fn num_nodes(&self) -> usize { @@ -125,7 +125,7 @@ impl Spec for ChainFork3 { info!("Connect all nodes"); node0.connect(node1); node0.connect(node2); - net.waiting_for_sync(2, 10); + net.waiting_for_sync(2); info!("Disconnect all nodes"); net.disconnect_all(); @@ -133,7 +133,7 @@ impl Spec for ChainFork3 { info!("Generate 1 block (C) on node0"); node0.generate_blocks(1); node0.connect(node2); - node0.waiting_for_sync(node2, 3, 10); + node0.waiting_for_sync(node2, 3); info!("Disconnect node2"); node0.disconnect(node2); @@ -160,7 +160,7 @@ impl Spec for ChainFork3 { info!("Reconnect node2"); node0.connect(node2); node1.connect(node2); - node0.waiting_for_sync(node2, 4, 10); + node0.waiting_for_sync(node2, 4); } fn num_nodes(&self) -> usize { @@ -197,7 +197,7 @@ impl Spec for ChainFork4 { info!("Connect all nodes"); node0.connect(node1); node0.connect(node2); - net.waiting_for_sync(2, 10); + net.waiting_for_sync(2); info!("Disconnect all nodes"); net.disconnect_all(); @@ -205,7 +205,7 @@ impl Spec for ChainFork4 { info!("Generate 1 block (C) on node0"); node0.generate_blocks(1); node0.connect(node2); - node0.waiting_for_sync(node2, 3, 10); + node0.waiting_for_sync(node2, 3); info!("Disconnect node2"); node0.disconnect(node2); @@ -232,7 +232,7 @@ impl Spec for ChainFork4 { info!("Reconnect node2"); node0.connect(node2); node1.connect(node2); - node0.waiting_for_sync(node2, 4, 10); + node0.waiting_for_sync(node2, 4); } fn num_nodes(&self) -> usize { @@ -272,7 +272,7 @@ impl Spec for ChainFork5 { info!("Connect all nodes"); node0.connect(node1); node0.connect(node2); - net.waiting_for_sync(2, 10); + net.waiting_for_sync(2); info!("Disconnect all nodes"); net.disconnect_all(); @@ -280,7 +280,7 @@ impl Spec for ChainFork5 { info!("Generate 1 block (C) on node0"); node0.generate_blocks(1); node0.connect(node2); - node0.waiting_for_sync(node2, 3, 10); + node0.waiting_for_sync(node2, 3); info!("Disconnect node2"); node0.disconnect(node2); @@ -308,7 +308,7 @@ impl Spec for ChainFork5 { info!("Reconnect node2"); node0.connect(node2); node1.connect(node2); - node0.waiting_for_sync(node2, 4, 10); + node0.waiting_for_sync(node2, 4); } fn num_nodes(&self) -> usize { @@ -345,7 +345,7 @@ impl Spec for ChainFork6 { info!("Connect all nodes"); node0.connect(node1); node0.connect(node2); - net.waiting_for_sync(2, 10); + net.waiting_for_sync(2); info!("Disconnect all nodes"); net.disconnect_all(); @@ -353,7 +353,7 @@ impl Spec for ChainFork6 { info!("Generate 1 block (C) on node0"); node0.generate_blocks(1); node0.connect(node2); - node0.waiting_for_sync(node2, 3, 10); + node0.waiting_for_sync(node2, 3); info!("Disconnect node2"); node0.disconnect(node2); @@ -376,7 +376,7 @@ impl Spec for ChainFork6 { info!("Reconnect node2"); node0.connect(node2); node1.connect(node2); - node0.waiting_for_sync(node2, 4, 10); + node0.waiting_for_sync(node2, 4); } fn num_nodes(&self) -> usize { @@ -413,7 +413,7 @@ impl Spec for ChainFork7 { info!("Connect all nodes"); node0.connect(node1); node0.connect(node2); - net.waiting_for_sync(2, 10); + net.waiting_for_sync(2); info!("Disconnect all nodes"); net.disconnect_all(); @@ -421,7 +421,7 @@ impl Spec for ChainFork7 { info!("Generate 1 block (C) on node0"); node0.generate_blocks(1); node0.connect(node2); - node0.waiting_for_sync(node2, 3, 10); + node0.waiting_for_sync(node2, 3); info!("Disconnect node2"); node0.disconnect(node2); @@ -452,7 +452,7 @@ impl Spec for ChainFork7 { info!("Reconnect node2"); node0.connect(node2); node1.connect(node2); - node0.waiting_for_sync(node2, 4, 10); + node0.waiting_for_sync(node2, 4); } fn num_nodes(&self) -> usize { diff --git a/test/src/specs/sync/sync_timeout.rs b/test/src/specs/sync/sync_timeout.rs index 7b7e2130cb..f156101d9b 100644 --- a/test/src/specs/sync/sync_timeout.rs +++ b/test/src/specs/sync/sync_timeout.rs @@ -21,7 +21,7 @@ impl Spec for SyncTimeout { node0.connect(node2); node0.connect(node3); node0.connect(node4); - net.waiting_for_sync(2, 10); + net.waiting_for_sync(2); info!("Disconnect all nodes"); net.disconnect_all(); @@ -30,9 +30,8 @@ impl Spec for SyncTimeout { node0.generate_blocks(200); node0.connect(node1); - // 60 seconds is a reasonable timeout to sync, even for poor CI server info!("Waiting for node0 and node1 sync"); - node0.waiting_for_sync(node1, 202, 60); + node0.waiting_for_sync(node1, 202); info!("Generate 200 blocks on node1"); node1.generate_blocks(200); @@ -43,9 +42,8 @@ impl Spec for SyncTimeout { node3.connect(node1); node4.connect(node0); node4.connect(node1); - // 60 seconds is a reasonable timeout to sync, even for poor CI server info!("Waiting for all nodes sync"); - net.waiting_for_sync(402, 60); + net.waiting_for_sync(402); } fn num_nodes(&self) -> usize { diff --git a/test/src/specs/tx_pool/pool_reconcile.rs b/test/src/specs/tx_pool/pool_reconcile.rs index 7b251b106f..9ce43be17b 100644 --- a/test/src/specs/tx_pool/pool_reconcile.rs +++ b/test/src/specs/tx_pool/pool_reconcile.rs @@ -33,7 +33,7 @@ impl Spec for PoolReconcile { info!("Connect node0 to node1"); node0.connect(node1); - net.waiting_for_sync(5, 10); + net.waiting_for_sync(5); info!("Tx should be re-added to node0's pool"); assert!(node0 diff --git a/test/src/specs/tx_pool/pool_resurrect.rs b/test/src/specs/tx_pool/pool_resurrect.rs index 9420919da9..d5830ee439 100644 --- a/test/src/specs/tx_pool/pool_resurrect.rs +++ b/test/src/specs/tx_pool/pool_resurrect.rs @@ -35,7 +35,7 @@ impl Spec for PoolResurrect { info!("Connect node0 to node1, waiting for sync"); node0.connect(node1); - net.waiting_for_sync(5, 10); + net.waiting_for_sync(5); info!("6 txs should be returned to node0 pending pool"); node0.assert_tx_pool_size(txs_hash.len() as u64, 0); From bc6fa223fe79de12a52707414922641c904db5c8 Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 6 Jun 2019 20:01:47 +0800 Subject: [PATCH 17/17] chore: sign git release assets (#962) * feat: sign git release assets * chore: fix windows package script * docs: integrity check guide * chore: travis replaces existing release asset * docs: Windows build guide --- .travis.yml | 11 +++++- azure-pipelines.yml | 19 +++++++++-- devtools/ci/package.sh | 4 +++ devtools/ci/travis-secret.asc.enc | Bin 0 -> 9824 bytes docs/get-ckb.md | 24 +++++++++++-- docs/integrity-check.md | 54 ++++++++++++++++++++++++++++++ 6 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 devtools/ci/travis-secret.asc.enc create mode 100644 docs/integrity-check.md diff --git a/.travis.yml b/.travis.yml index fd0b537b36..c379cebd02 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,9 +41,12 @@ before_cache: deploy: provider: releases api_key: "$GITHUB_TOKEN" - file: "releases/ckb_${TRAVIS_TAG}_${REL_PKG}" + file: + - "releases/ckb_${TRAVIS_TAG}_${REL_PKG}" + - "releases/ckb_${TRAVIS_TAG}_${REL_PKG}.asc" skip_cleanup: true prerelease: true + overwrite: true on: tags: true condition: '"$GITHUB_TOKEN" != "" && "$REL_PKG" != ""' @@ -102,6 +105,8 @@ matrix: - rm -rf $HOME/.cargo/registry script: - make prod + - openssl aes-256-cbc -K $encrypted_82dff4145bbf_key -iv $encrypted_82dff4145bbf_iv -in devtools/ci/travis-secret.asc.enc -out devtools/ci/travis-secret.asc -d + - gpg --import devtools/ci/travis-secret.asc - devtools/ci/package.sh target/release/ckb - name: Package for Linux if: 'tag IS present AND env(GITHUB_TOKEN) IS present' @@ -116,6 +121,8 @@ matrix: script: - mkdir -p $HOME/.cargo/git - docker run --rm -it -w /ckb -v $(pwd):/ckb -v $HOME/.cargo/git:/root/.cargo/git -e OPENSSL_STATIC=1 -e OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu -e OPENSSL_INCLUDE_DIR=/usr/include/openssl $BUILDER_IMAGE make prod + - openssl aes-256-cbc -K $encrypted_82dff4145bbf_key -iv $encrypted_82dff4145bbf_iv -in devtools/ci/travis-secret.asc.enc -out devtools/ci/travis-secret.asc -d + - gpg --import devtools/ci/travis-secret.asc - devtools/ci/package.sh target/release/ckb - name: Package for Centos if: 'tag IS present AND env(GITHUB_TOKEN) IS present' @@ -130,4 +137,6 @@ matrix: script: - mkdir -p $HOME/.cargo/git - docker run --rm -it -w /ckb -v $(pwd):/ckb -v $HOME/.cargo/git:/root/.cargo/git $BUILDER_IMAGE scl enable llvm-toolset-7 'make prod' + - openssl aes-256-cbc -K $encrypted_82dff4145bbf_key -iv $encrypted_82dff4145bbf_iv -in devtools/ci/travis-secret.asc.enc -out devtools/ci/travis-secret.asc -d + - gpg --import devtools/ci/travis-secret.asc - devtools/ci/package.sh target/release/ckb diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 31c6c6d3d8..779f653fe3 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -53,19 +53,34 @@ jobs: displayName: Build - powershell: | mkdir ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc - cp -r target/release/ckb,README.md,CHANGELOG.md,COPYING,devtools/init,docs ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc + cp -r target/release/ckb.exe,README.md,CHANGELOG.md,COPYING,devtools/init,docs ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc cp rpc/README.md ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc/docs/rpc.md displayName: Prepare archive - task: ArchiveFiles@2 inputs: rootFolderOrFile: 'ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc' archiveFile: '$(Build.ArtifactStagingDirectory)/ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc.zip' + - script: choco install -y gpg4win + displayName: Install GPG4Win + - task: DownloadSecureFile@1 + inputs: + secureFile: azure-secret.asc + - script: | + set PATH=%PATH%;%ProgramFiles(x86)%/GnuPG/bin + gpg --import %DOWNLOADSECUREFILE_SECUREFILEPATH% + echo "##vso[task.setvariable variable=PATH;]%PATH%;%ProgramFiles(x86)%/GnuPG/bin" + displayName: Setup GPG + - script: | + gpg -u "Nervos Azure Builder " -ab "$(Build.ArtifactStagingDirectory)/ckb_$(Build.SourceBranchName)_x86_64-pc-windows-msvc.zip" + displayName: Sign Archive - task: GitHubRelease@0 inputs: gitHubConnection: nervos-bot repositoryName: nervosnetwork/ckb action: edit tag: $(Build.SourceBranchName) - assets: '$(Build.ArtifactStagingDirectory)/*.zip' + assets: | + $(Build.ArtifactStagingDirectory)/*.zip + $(Build.ArtifactStagingDirectory)/*.asc assetUploadMode: replace isPreRelease: true diff --git a/devtools/ci/package.sh b/devtools/ci/package.sh index f7af150657..33b4505c83 100755 --- a/devtools/ci/package.sh +++ b/devtools/ci/package.sh @@ -11,6 +11,7 @@ if [ -z "${REL_PKG:-}" ]; then fi PKG_NAME="ckb_${TRAVIS_TAG}_${REL_PKG%%.*}" +ARCHIVE_NAME="ckb_${TRAVIS_TAG}_${REL_PKG}" rm -rf releases mkdir releases @@ -28,4 +29,7 @@ if [ "${REL_PKG#*.}" = "tar.gz" ]; then else zip -r $PKG_NAME.zip $PKG_NAME fi +if [ -n "${GPG_SIGNER:-}" ]; then + gpg -u "$GPG_SIGNER" -ab "$ARCHIVE_NAME" +fi popd diff --git a/devtools/ci/travis-secret.asc.enc b/devtools/ci/travis-secret.asc.enc new file mode 100644 index 0000000000000000000000000000000000000000..0e13aab42f4d6033f43eb5e620449b438a898bf8 GIT binary patch literal 9824 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 Gkdh^2D<3ET literal 0 HcmV?d00001 diff --git a/docs/get-ckb.md b/docs/get-ckb.md index 2a77f81313..bb06373095 100644 --- a/docs/get-ckb.md +++ b/docs/get-ckb.md @@ -5,10 +5,9 @@ We will publish binaries for each release via [Github Releases]. If your system is listed there, you can download the package directory. -[Github Releases]: https://github.com/nervosnetwork/ckb/releases +CKB releases are signed. It is wise and more secure to check out for their [integrity](integrity-check.md). -There is also a repository [ckb-builds](https://github.com/ckb-builds/ckb-builds/releases) containing the nightly builds from the develop -branch. +[Github Releases]: https://github.com/nervosnetwork/ckb/releases CentOS users please use the `x86_64-unknown-centos-gnu` package, which also requires OpenSSL 1.0 to run: @@ -17,6 +16,13 @@ requires OpenSSL 1.0 to run: sudo yum install openssl-libs ``` +The Windows packages are for experiments only, they have significant +performance issues, we don't recommend to use them in production environment. +They requires *The Visual C++ Redistributable Packages*, which can be downloaded +under section *Other Tools and Frameworks* +[here](https://visualstudio.microsoft.com/downloads/) or +[here](https://www.microsoft.com/en-us/download/details.aspx?id=48145). + We also provides docker images, see [how to run CKB with docker](run-ckb-with-docker.md). ## Build from Source @@ -63,6 +69,15 @@ scl enable llvm-toolset-7 bash Remember to run following commands in this console. +#### Windows + +Install Visual Studio with Desktop C++ workload, and install following +packages via [Chocolatey](https://chocolatey.org) + +``` +choco install -y llvm msys2 +``` + ### Add Environment Variables If your OS contains pre-compiled `rocksdb` or `snappy` libraries, @@ -112,3 +127,6 @@ export PATH="$(pwd)/target/release:$PATH" # or # ln -snf "$(pwd)/target/release/ckb" /usr/local/bin/ckb ``` + +In Windows, use `cargo build --release` instead and the executable is +`target/release/ckb.exe`. diff --git a/docs/integrity-check.md b/docs/integrity-check.md new file mode 100644 index 0000000000..ed14fd7390 --- /dev/null +++ b/docs/integrity-check.md @@ -0,0 +1,54 @@ +# CKB Release Integrity Check + +All the binaries available from GitHub releases are signed via following PGP keys. + +| Version | Package | Unique ID | OpenPGP Key | Fingerprint | +| --------- | -------------------- | -------------------------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------- | +| >= 0.13.0 | macOS, Linux, CentOS | Nervos Travis Builder | [F4631C0A](https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x4F37F694F4631C0A) | 64B7 05B5 6078 1FC5 4047  7B82 4F37 F694 F463 1C0A | +| >= 0.14.0 | Windows | Nervos Azure Builder | [AD748F26](https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x5EBA64ECAD748F26) | 0849 A2D2 4CA7 CFFC FA80  BCD4 5EBA 64EC AD74 8F26 | + +You can import the public keys from the keyserver network: + +``` +gpg --recv-keys 4F37F694F4631C0A 5EBA64ECAD748F26 +``` + +Once you have already imported the public keys, please download both the archive and +the corresponding `.asc` file to verify the signature. For example, to check +the signature of the file `ckb_v0.13.0_x86_64-apple-darwin.zip` + +``` +gpg --verify ckb_v0.13.0_x86_64-apple-darwin.zip.asc ckb_v0.13.0_x86_64-apple-darwin.zip +``` + +Note: you should never use a GnuPG version you just downloaded to check the integrity of the source — use an existing, trusted GnuPG installation, e.g., the one provided by your distribution. + +If the output of the above command is similar to the following, then either you don't have our public keys or the signature was generated by someone else and the file should be treated suspiciously. + +``` +gpg: Signature made Wed 05 Jun 2019 10:12:22 PM UTC using RSA key ID F4631C0A +gpg: Can't check signature: No public key +``` + +If you instead see: + +``` +gpg: Signature made Wed 05 Jun 2019 10:12:22 PM UTC using RSA key ID F4631C0A +gpg: Good signature from "Nervos Travis Builder " +gpg: WARNING: This key is not certified with a trusted signature! +gpg: There is no indication that the signature belongs to the owner. +Primary key fingerprint: 64B7 05B5 6078 1FC5 4047 7B82 4F37 F694 F463 1C0A +``` + +then you have a copy of our keys and the signatures are valid, but either you have not marked the keys as trusted or the keys are a forgery. In this case, at the very least, you should compare the fingerprints that are shown above. + +Ideally, you'll see something like: + +``` +gpg: Signature made Wed 05 Jun 2019 10:12:22 PM UTC using RSA key ID F4631C0A +gpg: checking the trustdb +gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model +gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u +gpg: next trustdb check due at 2023-06-05 +gpg: Good signature from "Nervos Travis Builder " +```