diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 151a02cd6..a4709e655 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -64,20 +64,41 @@ jobs: if [ ${{ matrix.workflow }} = "router-pay" ]; then export START_BOOTNODE=y fi + export ON_GITHUB_ACTION=y ./tests/nodes/start.sh & # Wait for the nodes to start, the initialization takes some time - # check port 127.0.0.1:(41714 ~ 41716) are open + # check all the ports are open + + # when .ports file is not generated, we will retry 20 times to check if all ports are open + port_file=./tests/nodes/.ports + retry_count=0 + while [ $retry_count -lt 100 ]; do + if [ -f $port_file ]; then + break + else + echo "File $port_file not found. Retrying in 2 seconds..." + sleep 2 + retry_count=$((retry_count + 1)) + fi + done + + ports=() + while IFS= read -r line; do + ports+=("$line") + done < ./tests/nodes/.ports + for i in {1..20}; do all_open=true - for port in 41714 41715 41716 8114; do + for port in $ports; do + echo "Checking port $port" if ! nc -z 127.0.0.1 $port; then all_open=false break fi done if $all_open; then - echo "All ports are open" + echo "All ports are open now ..." break else echo "Not all ports are open, waiting 3 seconds before retrying" diff --git a/.gitignore b/.gitignore index b42b7d855..6d2a099ab 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ /tests/nodes/*/fiber/store /tests/nodes/*/config.yml /tests/deploy/udt-init/target +tests/nodes/.ports diff --git a/tests/bruno/environments/test.bru b/tests/bruno/environments/test.bru index d230d78b4..8d2121e0e 100644 --- a/tests/bruno/environments/test.bru +++ b/tests/bruno/environments/test.bru @@ -1,8 +1,8 @@ vars { CKB_RPC_URL: http://127.0.0.1:8114 - NODE1_RPC_URL: http://127.0.0.1:41714 - NODE2_RPC_URL: http://127.0.0.1:41715 - NODE3_RPC_URL: http://127.0.0.1:41716 + NODE1_RPC_URL: http://127.0.0.1:21714 + NODE2_RPC_URL: http://127.0.0.1:21715 + NODE3_RPC_URL: http://127.0.0.1:21716 NODE1_ADDR: /ip4/127.0.0.1/tcp/8344/p2p/QmbvRjJHAQDmj3cgnUBGQ5zVnGxUKwb2qJygwNs2wk41h8 NODE2_ADDR: /ip4/127.0.0.1/tcp/8345/p2p/QmSRcPqUn4aQrKHXyCDjGn2qBVf43tWBDS2Wj9QDUZXtZp NODE3_ADDR: /ip4/127.0.0.1/tcp/8346/p2p/QmaFDJb9CkMrXy7nhTWBY5y9mvuykre3EzzRsCJUAVXprZ diff --git a/tests/bruno/environments/xudt-test.bru b/tests/bruno/environments/xudt-test.bru index 83d7bc283..f5cc31133 100644 --- a/tests/bruno/environments/xudt-test.bru +++ b/tests/bruno/environments/xudt-test.bru @@ -1,8 +1,8 @@ vars { CKB_RPC_URL: http://127.0.0.1:8114 - NODE1_RPC_URL: http://127.0.0.1:41714 - NODE2_RPC_URL: http://127.0.0.1:41715 - NODE3_RPC_URL: http://127.0.0.1:41716 + NODE1_RPC_URL: http://127.0.0.1:21714 + NODE2_RPC_URL: http://127.0.0.1:21715 + NODE3_RPC_URL: http://127.0.0.1:21716 NODE1_ADDR: /ip4/127.0.0.1/tcp/8344/p2p/QmbvRjJHAQDmj3cgnUBGQ5zVnGxUKwb2qJygwNs2wk41h8 NODE2_ADDR: /ip4/127.0.0.1/tcp/8345/p2p/QmSRcPqUn4aQrKHXyCDjGn2qBVf43tWBDS2Wj9QDUZXtZp NODE3_ADDR: /ip4/127.0.0.1/tcp/8346/p2p/QmaFDJb9CkMrXy7nhTWBY5y9mvuykre3EzzRsCJUAVXprZ diff --git a/tests/deploy/deploy.sh b/tests/deploy/deploy.sh index 8a70ddb6c..d9cf9ed69 100755 --- a/tests/deploy/deploy.sh +++ b/tests/deploy/deploy.sh @@ -47,7 +47,7 @@ function deploy() { } generate_blocks() { - ./generate-blocks.sh 4 + ./generate-blocks.sh 8 sleep 1 } diff --git a/tests/deploy/init-dev-chain.sh b/tests/deploy/init-dev-chain.sh index a29e70b06..ec464f9d0 100755 --- a/tests/deploy/init-dev-chain.sh +++ b/tests/deploy/init-dev-chain.sh @@ -45,7 +45,15 @@ if ! [[ -d "$data_dir" ]]; then # Don't continue until the default account has some money. # Transfer some money from the default account (node 3) to node 1 for later use. echo "begin to setup wallet states for nodes" - sleep 3 + for i in {1..20}; do + if ! nc -z 127.0.0.1 8114; then + echo "waiting CKB ready $i ..." + sleep 2 + else + echo "CKB is ready now ..." + break + fi + done # Transfer some money to the node 1. # The address of node 1 can be seen with the following command: diff --git a/tests/deploy/udt-init/Cargo.lock b/tests/deploy/udt-init/Cargo.lock index 308b95b81..637d0c64f 100644 --- a/tests/deploy/udt-init/Cargo.lock +++ b/tests/deploy/udt-init/Cargo.lock @@ -223,7 +223,7 @@ dependencies = [ "ckb-fixed-hash", "faster-hex", "lazy_static", - "rand", + "rand 0.7.3", "secp256k1", "thiserror", ] @@ -542,7 +542,7 @@ dependencies = [ "derive_more", "goblin 0.2.3", "goblin 0.4.0", - "rand", + "rand 0.7.3", "scroll", "serde", ] @@ -1342,7 +1342,7 @@ checksum = "6aab1d6457b97b49482f22a92f0f58a2f39bdd7f3b2f977eae67e8bc206aa980" dependencies = [ "heapsize", "numext-constructor", - "rand", + "rand 0.7.3", "serde", "thiserror", ] @@ -1479,7 +1479,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" dependencies = [ "phf_shared", - "rand", + "rand 0.7.3", ] [[package]] @@ -1571,12 +1571,23 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom 0.1.16", "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.2.2", + "rand_core 0.5.1", "rand_hc", "rand_pcg", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -1584,7 +1595,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", ] [[package]] @@ -1596,13 +1617,22 @@ dependencies = [ "getrandom 0.1.16", ] +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -1611,7 +1641,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -2188,6 +2218,7 @@ dependencies = [ "ckb-sdk", "ckb-types", "hex", + "rand 0.8.5", "serde", "serde_derive", "serde_json", diff --git a/tests/deploy/udt-init/Cargo.toml b/tests/deploy/udt-init/Cargo.toml index a39ea2caa..0b5b21467 100644 --- a/tests/deploy/udt-init/Cargo.toml +++ b/tests/deploy/udt-init/Cargo.toml @@ -15,3 +15,4 @@ serde_json = "1.0" thiserror = "1.0.30" hex = "0.4.3" serde_yaml = "0.9.34" +rand = "0.8.5" diff --git a/tests/deploy/udt-init/src/main.rs b/tests/deploy/udt-init/src/main.rs index af05decf7..30299f35e 100644 --- a/tests/deploy/udt-init/src/main.rs +++ b/tests/deploy/udt-init/src/main.rs @@ -16,7 +16,10 @@ use ckb_types::{ H256, }; use ckb_types::{packed::CellDep, prelude::Builder}; +use rand::Rng; use serde::{Deserialize, Serialize}; +use std::collections::HashSet; +use std::net::TcpListener; use std::{error::Error as StdErr, str::FromStr}; @@ -196,6 +199,31 @@ struct UdtInfos { infos: Vec, } +fn is_port_available(port: u16) -> bool { + match TcpListener::bind(("127.0.0.1", port)) { + Ok(listener) => { + drop(listener); // Close the listener + true + } + Err(_) => false, + } +} + +fn generate_ports(num_ports: usize) -> Vec { + let mut ports = HashSet::new(); + let mut rng = rand::thread_rng(); + + while ports.len() < num_ports { + // avoid https://en.wikipedia.org/wiki/Ephemeral_port + let port: u16 = rng.gen_range(1024..32768); + if is_port_available(port) { + ports.insert(port); + } + } + + ports.into_iter().collect() +} + fn genrate_nodes_config() { let nodes_dir = std::env::var("NODES_DIR").expect("env var"); let yaml_file_path = format!("{}/deployer/config.yml", nodes_dir); @@ -225,18 +253,32 @@ fn genrate_nodes_config() { "# you can edit nodes/deployer/config.yml and run `REMOVE_OLD_STATE=y ./tests/nodes/start.sh` to regenerate" ); let config_dirs = vec!["bootnode", "1", "2", "3"]; + let mut ports_map = vec![]; + let on_github_action = std::env::var("ON_GITHUB_ACTION").is_ok(); + let gen_ports = generate_ports(6); + let mut ports_iter = gen_ports.iter(); for (i, config_dir) in config_dirs.iter().enumerate() { + let use_gen_port = on_github_action && i != 0; + let default_fiber_port = (8343 + i) as u16; + let default_rpc_port = (21713 + i) as u16; + let (fiber_port, rpc_port) = if use_gen_port { + (*ports_iter.next().unwrap(), *ports_iter.next().unwrap()) + } else { + (default_fiber_port, default_rpc_port) + }; + ports_map.push((default_fiber_port, fiber_port)); + ports_map.push((default_rpc_port, rpc_port)); let mut data = data.clone(); data["fiber"]["listening_addr"] = - serde_yaml::Value::String(format!("/ip4/0.0.0.0/tcp/{}", 8343 + i)); + serde_yaml::Value::String(format!("/ip4/0.0.0.0/tcp/{}", fiber_port)); data["fiber"]["announced_addrs"] = serde_yaml::Value::Sequence(vec![serde_yaml::Value::String(format!( "/ip4/127.0.0.1/tcp/{}", - 8343 + i + fiber_port ))]); data["fiber"]["announced_node_name"] = serde_yaml::Value::String(format!("fiber-{}", i)); data["rpc"]["listening_addr"] = - serde_yaml::Value::String(format!("127.0.0.1:{}", 41713 + i)); + serde_yaml::Value::String(format!("127.0.0.1:{}", rpc_port)); data["ckb"]["udt_whitelist"] = serde_yaml::to_value(&udt_infos).unwrap(); // Node 3 acts as a CCH node. @@ -249,20 +291,49 @@ fn genrate_nodes_config() { let new_yaml = header.to_string() + &serde_yaml::to_string(&data).unwrap(); let config_path = format!("{}/{}/config.yml", nodes_dir, config_dir); + std::fs::write(config_path, new_yaml).expect("write failed"); } + + if on_github_action { + let bruno_dir = format!("{}/../bruno/environments/", nodes_dir); + for config in std::fs::read_dir(bruno_dir).expect("read dir") { + let config = config.expect("read config"); + for (default_port, port) in ports_map.iter() { + eprintln!( + "update bruno config: {:?} {} -> {}", + config, default_port, port + ); + let content = std::fs::read_to_string(config.path()).expect("read config"); + let new_content = content.replace(&default_port.to_string(), &port.to_string()); + std::fs::write(config.path(), new_content).expect("write config"); + } + } + } + + // write the real ports into a file so that later script can use it to double check the ports + let content = ports_map + .iter() + .skip(2) // bootnode node was not always started + .map(|(_, port)| port.to_string()) + .collect::>() + .join("\n"); + + let port_file_path = format!("{}/.ports", nodes_dir); + std::fs::write(port_file_path, content).expect("write ports list"); } fn init_udt_accounts() -> Result<(), Box> { let udt_owner = get_nodes_info("deployer"); for udt in UDT_KINDS { + eprintln!("begin init udt: {} ...", udt); init_or_send_udt(udt, &udt_owner.0, &udt_owner, None, 1000000000000, true) .expect("init udt"); generate_blocks(8).expect("ok"); std::thread::sleep(std::time::Duration::from_millis(1000)); - for i in 0..3 { let wallet = get_nodes_info(&(i + 1).to_string()); + eprintln!("begin send udt: {} to node {} ...", udt, i); init_or_send_udt( udt, &udt_owner.0, diff --git a/tests/nodes/start.sh b/tests/nodes/start.sh index 183316582..ae979e306 100755 --- a/tests/nodes/start.sh +++ b/tests/nodes/start.sh @@ -1,14 +1,15 @@ #!/usr/bin/env bash - set -euo pipefail export SHELLOPTS export RUST_BACKTRACE=full RUST_LOG=info,fnn=debug should_remove_old_state="${REMOVE_OLD_STATE:-}" should_start_bootnode="${START_BOOTNODE:-}" +should_generate_port="${ON_GITHUB_ACTION:-}" script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" nodes_dir="$(dirname "$script_dir")/nodes" deploy_dir="$(dirname "$script_dir")/deploy" +bruno_dir="$(dirname "$script_dir")/bruno/environments" # The following environment variables are used in the contract tests. # We may load all contracts within the following folder to the test environment. @@ -38,6 +39,9 @@ if [[ -f "$deploy_dir/.env.local" ]]; then export $(xargs <"$deploy_dir/.env.local") fi +echo "Initializing finished, begin to start services ...." +sleep 1 + ckb run -C "$deploy_dir/node-data" --indexer & # Start the dev node in the background.