Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tendermint loadtester #921

Merged
merged 12 commits into from
Apr 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions ops/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ WORKDIR /near
COPY . .

ENV CARGO_TARGET_DIR=/tmp/target
RUN --mount=type=cache,target=/tmp/target \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/usr/local/cargo/registry \
cargo build -p nearmint --release && \
RUN cargo build -p nearmint --release && \
cp /tmp/target/release/nearmint /usr/local/bin/ && \
cargo build -p keystore --release && \
cp /tmp/target/release/keystore /usr/local/bin/ && \
Expand Down
9 changes: 6 additions & 3 deletions ops/deploy_local.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#!/bin/bash
set -e

IMAGE=${1:-nearprotocol/nearcore:0.1.3}
IMAGE=${1:-nearprotocol/nearcore:0.1.5}
STUDIO_IMAGE=${2:-nearprotocol/studio:0.2.4}
TOTAL_NODES=${2:-2}
TOTAL_NODES=${3:-2}
NUM_ACCOUNTS=${4:-10}
NEARLIB_COMMIT="348509b526cf4ca0495d86cb211d1013d84629a2"
NEARLIB_VERSION="0.5.2"
STUDIO_IP=localhost
Expand All @@ -13,15 +14,17 @@ sudo docker run -d --name testnet-0 -p 3030:3030 -p 26656:26656 --rm \
-e "TOTAL_NODES=${TOTAL_NODES}" \
-e "NODE_KEY=53Mr7IhcJXu3019FX+Ra+VbxSQ5y2q+pknmM463jzoFzldWZb16dSYRxrhYrLRXe/UA0wR2zFy4c3fY5yDHjlA==" \
-e "PRIVATE_NETWORK=y" \
-e "NUM_ACCOUNTS=${NUM_ACCOUNTS}" \
${IMAGE}

for NODE_ID in $(seq 1 `expr $TOTAL_NODES - 1`)
do
sudo docker run -d --name testnet-${NODE_ID} -p $((3030+${NODE_ID})):3030 -p $((26656+${NODE_ID})):26656 \
--add-host=testnet-0:172.17.0.2 --rm \
--add-host=testnet-0:172.17.0.2 \
-e "BOOT_NODES=6f99d7b49a10fff319cd8bbbd13c3a964dcd0248@172.17.0.2:26656" \
-e "NODE_ID=${NODE_ID}" \
-e "TOTAL_NODES=${TOTAL_NODES}" \
-e "NUM_ACCOUNTS=${NUM_ACCOUNTS}" \
-e "PRIVATE_NETWORK=y" \
${IMAGE}
done
Expand Down
31 changes: 15 additions & 16 deletions ops/deploy_remote.sh
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
#!/bin/bash
set -e

IMAGE=${1:-nearprotocol/nearcore:0.1.3}
IMAGE=${1:-nearprotocol/nearcore:0.1.5}
PREFIX=${2:-testnet-${USER}}
STUDIO_IMAGE=${3:-nearprotocol/studio:0.2.4}
ZONE=${4:-us-west2-a}
REGION=${5:-us-west2}
NUM_NODES=${6:-4}
NUM_NODES=${6:-10}
NUM_ACCOUNTS=${7:-400}

echo "Starting ${NUM_NODES} nodes prefixed ${PREFIX} of ${IMAGE} on GCloud ${ZONE} zone..."

set +e
gcloud compute firewall-rules describe nearmint-instance > /dev/null 2>&1
INSTANCE_FIRE_WALL_EXISTS=$?
gcloud compute disks describe ${PREFIX}-persistent-0 --zone ${ZONE} > /dev/null 2>&1
STORAGE_EXISTS=$?
gcloud beta compute addresses describe ${PREFIX}-0 --region ${REGION} > /dev/null 2>&1
ADDRESS_EXISTS=$?
gcloud beta compute instances describe ${PREFIX}-0 --zone ${ZONE} > /dev/null 2>&1
Expand All @@ -27,14 +26,6 @@ gcloud compute firewall-rules create nearmint-instance \
--target-tags=nearmint-instance
fi

if [[ ! ${STORAGE_EXISTS} -eq 0 ]]; then
gcloud compute disks create --size 200GB --zone ${ZONE} \
${PREFIX}-persistent-0 \
${PREFIX}-persistent-1 \
${PREFIX}-persistent-2 \
${PREFIX}-persistent-3
fi

if [[ ! ${ADDRESS_EXISTS} -eq 0 ]]; then
gcloud beta compute addresses create ${PREFIX}-0 --region ${REGION}
fi
Expand All @@ -43,11 +34,12 @@ if [[ ! ${BOOTNODE_EXISTS} -eq 0 ]]; then
gcloud beta compute instances create-with-container ${PREFIX}-0 \
--container-env NODE_ID=0 \
--container-env TOTAL_NODES=${NUM_NODES} \
--container-env NUM_ACCOUNTS=${NUM_ACCOUNTS} \
--container-env NODE_KEY="53Mr7IhcJXu3019FX+Ra+VbxSQ5y2q+pknmM463jzoFzldWZb16dSYRxrhYrLRXe/UA0wR2zFy4c3fY5yDHjlA==" \
--container-image ${IMAGE} \
--zone ${ZONE} \
--tags=nearmint-instance \
--disk name=${PREFIX}-persistent-0 \
--create-disk=name=${PREFIX}-persistent-0,auto-delete=yes \
--container-mount-disk mount-path="/srv/near" \
--boot-disk-size 200GB \
--address ${PREFIX}-0 \
Expand All @@ -71,17 +63,24 @@ do
gcloud beta compute instances create-with-container ${PREFIX}-${NODE_ID} \
--container-env BOOT_NODES="6f99d7b49a10fff319cd8bbbd13c3a964dcd0248@${BOOT_NODE_IP}:26656" \
--container-env NODE_ID=${NODE_ID} \
--container-env TOTAL_NODES=${NUM_NODES} \
--container-env TOTAL_NODES=${NUM_NODES} \
--container-env NUM_ACCOUNTS=${NUM_ACCOUNTS} \
--container-image ${IMAGE} \
--zone ${ZONE} \
--tags=testnet-instance \
--disk=name=${PREFIX}-persistent-${NODE_ID} \
--create-disk=name=${PREFIX}-persistent-${NODE_ID},auto-delete=yes \
--container-mount-disk=mount-path="/srv/near" \
--boot-disk-size 200GB \
--machine-type n1-highcpu-4
--machine-type n1-highcpu-4 &

fi
done
wait

echo "RPCs of the nodes"
for NODE_IP in $(gcloud compute instances list --filter="name:${PREFIX}*" | grep "RUNNING" | awk '{print $5}')
do
echo "\"${NODE_IP}:3030\","
done

set +e
Expand Down
2 changes: 1 addition & 1 deletion ops/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ EOF

if [[ -z ${CHAIN_SPEC_PATH} ]]
then
generate-test-spec -n ${TOTAL_NODES} -c ${TMHOME}/chain_spec.json
generate-test-spec -a ${TOTAL_NODES} -c ${TMHOME}/chain_spec.json -n ${NUM_ACCOUNTS}
CHAIN_SPEC_PATH="${TMHOME}/chain_spec.json"
fi

Expand Down
1 change: 1 addition & 0 deletions ops/teardown_local.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/bin/bash

sudo docker stop $(sudo docker ps -q)
sudo docker rm $(sudo docker ps -q --all)
12 changes: 12 additions & 0 deletions ops/teardown_remote.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
set -e

PREFIX=${1:-testnet-${USER}}
NUM_NODES=${2:-50}
ZONE=${3:-us-west2-a}

for NODE_ID in $(seq 0 `expr $NUM_NODES - 1`)
do
yes | gcloud beta compute instances delete ${PREFIX}-${NODE_ID} --zone=${ZONE} &
done
wait
2 changes: 1 addition & 1 deletion runtime/runtime/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl ChainSpec {

/// Default ChainSpec used by DevNet for testing.
pub fn default_devnet() -> Self {
Self::testing_spec(DefaultIdType::Named, 3, 1, AuthorityRotation::ProofOfAuthority).0
Self::testing_spec(DefaultIdType::Named, 18, 1, AuthorityRotation::ProofOfAuthority).0
}
}

Expand Down
14 changes: 14 additions & 0 deletions test-utils/loadtester/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ edition = "2018"
clap = "2.32"
log = "0.4"
env_logger = "0.6.0"
rand = "0.6"
rand_xorshift = "0.1"
hex = "0.3"
futures = "0.1.25"
tokio = "0.1"
protobuf = { version = "2.2.4", features = ["with-bytes"] }
serde_json = "1.0.0"
base64 = "0.10.0"

primitives = { path = "../../runtime/primitives" }
testlib = { path = "../testlib" }
near-protos = { path = "../../runtime/protos", features = ["with-serde"] }
node-runtime = { path = "../../runtime/runtime" }

[dependencies.reqwest]
version = "0.9"
features = ["rustls-tls", "trust-dns"]
165 changes: 46 additions & 119 deletions test-utils/loadtester/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,99 +1,17 @@
//! A tool that does load testing of the remotely running nodes.
//! Usage example:
//! ```
//! loadtester --key-files-path /tmp/keys --addresses 35.235.94.193:3030 35.236.51.32:3030 35.236.103.128:3030 --public-keys CTVkQMjLyr4QzoXrTDVzfCUp95sCJPwLJZ34JTiekxMV EJ1DMa6s2ngC5GtZb3Z2DZzat2xFZ34j15VLY37dcdXX 3DToePHssYc75SsxZgzgVLwXE8XQXKjdpdL7CT7D34UE --account-ids near.1 near.2 near.3
//! ```
//! where `/tmp/keys` contains keys of the accounts of the nodes that we are testing.
use clap::{App, Arg};
use crate::transactions_executor::Executor;
use env_logger::Builder;
use primitives::crypto::signer::InMemorySigner;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::{Arc, RwLock};
use testlib::node::Node;

const NUMBER_OF_NODES_ERR: &str =
"Number of addresses, public keys, and account ids should be the same";

#[allow(dead_code)]
fn parse_args() -> Vec<(Arc<InMemorySigner>, SocketAddr)> {
let matches = App::new("Near Load Tester")
.arg(
Arg::with_name("key_files_path")
.long("key-files-path")
.value_name("KEY_FILES_PATH")
.help("The path to the folder with key files.")
.takes_value(true)
.required(true),
)
.arg(
Arg::with_name("addresses")
.long("addresses")
.value_name("ADDRESSES")
.help(
"A list of addresses of the nodes. In the form: --boot_nodes <ip1>:<port1> <ip2>:<port2>",
)
.multiple(true)
.takes_value(true),
)
.arg(
Arg::with_name("public_keys")
.long("public-keys")
.value_name("PUBLIC_KEYS")
.help("Public keys of the nodes we are connecting two.")
.multiple(true)
.takes_value(true),
)
.arg(
Arg::with_name("account_ids")
.long("account-ids")
.value_name("ACCOUNT_IDS")
.help("Account ids of the corresponding nodes")
.multiple(true)
.takes_value(true),
)
.get_matches();

let key_files_path: PathBuf = matches.value_of("key_files_path").map(PathBuf::from).unwrap();
let parsed_addrs =
matches.values_of("addresses").unwrap_or_else(clap::Values::default).map(String::from);
let addrs: Vec<_> = parsed_addrs
.map(|addr_id| SocketAddr::from_str(&addr_id).expect("Cannot parse address"))
.clone()
.collect();
let public_keys: Vec<String> = matches
.values_of("public_keys")
.unwrap_or_else(clap::Values::default)
.map(String::from)
.collect();
let account_ids: Vec<String> = matches
.values_of("account_ids")
.unwrap_or_else(clap::Values::default)
.map(String::from)
.collect();

assert_eq!(addrs.len(), public_keys.len(), "{}", NUMBER_OF_NODES_ERR);
assert_eq!(account_ids.len(), public_keys.len(), "{}", NUMBER_OF_NODES_ERR);
let mut res = vec![];
for i in 0..addrs.len() {
let signer = Arc::new(InMemorySigner::from_key_file(
account_ids[i].clone(),
key_files_path.as_path(),
Some(public_keys[i].clone()),
));
res.push((signer, addrs[i]));
}
res
}

#[allow(dead_code)]
fn connect_nodes(_args: Vec<(Arc<InMemorySigner>, SocketAddr)>) -> Vec<Arc<RwLock<dyn Node>>> {
unimplemented!()
// args.into_iter()
// .map(|(signer, addr)| Node::new_sharable(NodeConfig::Remote { signer, addr }))
// .collect()
}
pub mod remote_node;
pub mod sampler;
pub mod stats;
pub mod transactions_executor;
pub mod transactions_generator;
use crate::transactions_generator::TransactionType;
use node_runtime::chain_spec::{AuthorityRotation, ChainSpec, DefaultIdType};
use remote_node::RemoteNode;
use std::time::Duration;

#[allow(dead_code)]
fn configure_logging(log_level: log::LevelFilter) {
Expand All @@ -107,31 +25,40 @@ fn configure_logging(log_level: log::LevelFilter) {
}

fn main() {
// configure_logging(log::LevelFilter::Debug);
// let args = parse_args();
// let nodes = connect_nodes(args);
// let nodes_monitor =
// Arc::new(NodesMonitor::new(nodes.to_vec(), Duration::from_secs(1), Duration::from_secs(1)));
// nodes_monitor.start();
// // Wait for all nodes to start running.
// while !nodes_monitor.all_nodes_running() {}
// println!("All nodes started.");
//
// // Start the monitor.
// {
// let nodes_monitor = nodes_monitor.clone();
// thread::spawn(move || loop {
// let tps = nodes_monitor
// .average_tps(Duration::from_secs(10))
// .map(|d| format!("{}", d))
// .unwrap_or_else(|| "Pending".to_owned());
// println!("TPS: {}", tps);
// thread::sleep(Duration::from_secs(1));
// });
// }
//
// // Start the executor.
// let handle =
// Executor::spawn(nodes, TransactionType::Monetary, None, None, 700, TrafficType::Regular);
// handle.join().unwrap();
configure_logging(log::LevelFilter::Debug);
let (chain_spec, _) = ChainSpec::testing_spec(
DefaultIdType::Enumerated,
400,
10,
AuthorityRotation::ProofOfAuthority,
);
let accounts: Vec<_> = chain_spec.accounts.into_iter().map(|t| t.0).collect();

let addrs = [
"35.236.106.188:3030",
"35.235.115.64:3030",
"35.235.75.161:3030",
"35.236.113.178:3030",
"35.236.42.186:3030",
"35.236.29.55:3030",
"35.235.84.221:3030",
"35.236.44.50:3030",
"35.236.84.38:3030",
"35.236.37.104:3030",
];

let num_nodes = addrs.len();
let accounts_per_node = accounts.len() / num_nodes;
let mut nodes = vec![];
for (i, addr) in addrs.iter().enumerate() {
let node = RemoteNode::new(
SocketAddr::from_str(addr).unwrap(),
&accounts[(i * accounts_per_node)..((i + 1) * accounts_per_node)],
);
nodes.push(node);
}

// Start the executor.
let handle = Executor::spawn(nodes, Some(Duration::from_secs(10)), 1600, TransactionType::Set);
handle.join().unwrap();
}
Loading