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

Support capacity and api port in CLI, deployment scripts and docs #488

Merged
merged 14 commits into from
Feb 25, 2019
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ matrix:
before_script: npm install
script: npm test

# checks that monitoring could be compiled
- name: monitoring
language: node_js
node_js:
- "8"
cache: npm
before_install: cd monitoring
script: npm install

- <<: *_rust_wasm_template
name: rust App SDK
before_script:
Expand All @@ -104,6 +113,7 @@ matrix:

env:
- RUST_TEST_THREADS=1
- RUST_BACKTRACE=1

script:
- pushd ../bootstrap
Expand Down
7 changes: 4 additions & 3 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ The following command will register a node:
--base64_tendermint_key \
--secret_key 0xcb0799337df06a6c73881bab91304a68199a430ccd4bc378e37e51fd1b118133 \
--wait_syncing \
--start_port 25000 \
--last_port 25010
--api_port 25000 \
--capacity 10
```

Parameters are:
Expand All @@ -76,7 +76,8 @@ Parameters are:
- `--secret_key 0xcb0799337df06a6c73881bab91304a68199a430ccd4bc378e37e51fd1b118133` denotes an Ethereum private key, used for offline transaction signing. _Use your Ethereum private key here_
- using `--password` is possible instead of private key, but private key is preferred
- `--wait_syncing` so CLI waits until Ethereum node is fully synced
- `--start_port 25000` and `--last_port 25010` denote ports where apps (workers) will be hosted. 25000:25010 is inclusive, so 10 workers could be started on such a node
- `--api_port 25000` specifies the main port of the Fluence node, so other nodes and users know where to connect
- `--capacity 10` limits number of apps that could be run on the node by 10


### Publish an app
Expand Down
42 changes: 14 additions & 28 deletions cli/src/contract_status/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,13 @@ impl App {
pub struct Cluster {
pub genesis_time: u32,
pub node_ids: Vec<H256>,
pub ports: Vec<u16>,
}

impl Cluster {
pub fn new(genesis_time: u32, node_ids: Vec<H256>, ports: Vec<u16>) -> Cluster {
pub fn new(genesis_time: u32, node_ids: Vec<H256>) -> Cluster {
Cluster {
genesis_time,
node_ids,
ports,
}
}
}
Expand All @@ -88,8 +86,8 @@ pub struct Node {
pub validator_key: H256,
pub tendermint_p2p_id: String,
pub ip_addr: IpAddr,
pub next_port: u16,
pub last_port: u16,
pub api_port: u16,
pub capacity: u16,
pub owner: Address,
pub is_private: bool,
pub app_ids: Option<Vec<u64>>, // Defined if loaded
Expand All @@ -99,8 +97,8 @@ impl Node {
pub fn new(
id: H256,
address: NodeAddress,
next_port: u16,
last_port: u16,
api_port: u16,
capacity: u16,
owner: Address,
is_private: bool,
app_ids: Option<Vec<u64>>,
Expand All @@ -110,8 +108,8 @@ impl Node {
validator_key: id,
tendermint_p2p_id: tendermint_key,
ip_addr,
next_port,
last_port,
api_port,
capacity,
owner,
is_private,
app_ids,
Expand All @@ -127,14 +125,14 @@ pub fn get_nodes(web3: &Web3<Http>, contract_address: Address) -> Result<Vec<Nod
.iter()
.map(|id| {
let (call_data, decoder) = get_node::call(*id);
let (ip_addr, next_port, last_port, owner, is_private, app_ids) =
let (ip_addr, api_port, capacity, owner, is_private, app_ids) =
query_contract(call_data, Box::new(decoder), web3, contract_address)?;

Node::new(
*id,
ip_addr.into(),
Into::<u64>::into(next_port) as u16,
Into::<u64>::into(last_port) as u16,
Into::<u64>::into(api_port) as u16,
Into::<u64>::into(capacity) as u16,
owner,
is_private,
Some(app_ids.into_iter().map(Into::into).collect()),
Expand All @@ -157,26 +155,14 @@ pub fn get_apps(web3: &Web3<Http>, contract_address: Address) -> Result<Vec<App>
.iter()
.map(|id| {
let (call_data, decoder) = get_app::call(*id);
let (
storage_hash,
storage_receipt,
cluster_size,
owner,
pin_to,
genesis,
node_ids,
ports,
) = query_contract(call_data, Box::new(decoder), web3, contract_address)
.context("reading app ids from contract failed")?;
let (storage_hash, storage_receipt, cluster_size, owner, pin_to, genesis, node_ids) =
query_contract(call_data, Box::new(decoder), web3, contract_address)
.context("reading app ids from contract failed")?;

let cluster = if !genesis.is_zero() {
let genesis: u64 = genesis.into();
let ports = ports
.iter()
.map(|p| (Into::<u64>::into(*p) as u16))
.collect();

Some(Cluster::new(genesis as u32, node_ids, ports))
Some(Cluster::new(genesis as u32, node_ids))
} else {
None
};
Expand Down
14 changes: 9 additions & 5 deletions cli/src/contract_status/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub mod app;
pub mod status;
pub mod ui;

use self::status::{get_status, Status};
use self::status::Status;
use crate::command::*;
use crate::contract_status::app::{App, Node};
use crate::contract_status::ui::rich_status;
Expand Down Expand Up @@ -276,14 +276,11 @@ pub fn subcommand<'a, 'b>() -> ClapApp<'a, 'b> {
pub fn get_status_by_args(args: &ArgMatches) -> Result<Option<Status>, Error> {
let eth_url = parse_eth_url(args)?;

let (_eloop, transport) = Http::new(eth_url.as_str()).map_err(SyncFailure::new)?;
let web3 = &web3::Web3::new(transport);

let contract_address: Address = parse_contract_address(args)?;

let filter = StatusFilter::from_args(args)?;

let status = get_status(web3, contract_address)?;
let status = get_status(eth_url.as_str(), contract_address)?;

let status = filter.filter(&status);

Expand All @@ -295,6 +292,13 @@ pub fn get_status_by_args(args: &ArgMatches) -> Result<Option<Status>, Error> {
}
}

pub fn get_status(eth_url: &str, contract_address: Address) -> Result<Status, Error> {
let (_eloop, transport) = Http::new(eth_url).map_err(SyncFailure::new)?;
let web3 = &web3::Web3::new(transport);

status::get_status(web3, contract_address)
}

/// Gets node from status by tendermint key
pub fn find_by_tendermint_key(status: &Status, tendermint_key: H256) -> Option<Node> {
let filter = StatusFilter::new(FilterMode::Or, None, None, None, Some(tendermint_key));
Expand Down
10 changes: 3 additions & 7 deletions cli/src/contract_status/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,7 @@ impl<'a> TabTable<'a, Node> {
pub fn nodes(nodes: Vec<Node>) -> TabTable<'a, Node> {
let header = vec![
// 2 spaces needed to provide left margin
" NodeID",
"IP",
"Next port",
"Owner",
"Private",
" NodeID", "IP", "Api port", "Owner", "Private",
];
let widths = vec![70, 15, 10, 45, 5];

Expand Down Expand Up @@ -96,11 +92,11 @@ impl ToColumns for Node {
fn columns(self) -> Vec<String> {
// 2 spaces needed to provide left margin
let node_id = format!(" {:#x}", self.validator_key);
let next_port = self.next_port.to_string();
let api_port = self.api_port.to_string();
let ip_addr = format!("{}", self.ip_addr);
let owner = format!("{:#x}", self.owner);
let is_private = if self.is_private { "yes" } else { "no" };
vec![node_id, ip_addr, next_port, owner, is_private.to_string()]
vec![node_id, ip_addr, api_port, owner, is_private.to_string()]
}
}

Expand Down
9 changes: 3 additions & 6 deletions cli/src/delete_all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,31 +68,28 @@ impl DeleteAll {
apps.len()
);

let nonce = web3
let mut nonce = web3
.eth()
.transaction_count(self.eth.account, None)
.wait()
.map_err(SyncFailure::new)?;

// to start loop with correct +1 nonce
let mut nonce = nonce - 1;

for app in apps {
let call_data = if app.cluster.is_some() {
delete_app::call(app.app_id).0
} else {
dequeue_app::call(app.app_id).0
};
nonce = nonce + 1;
call_contract(web3, &self.eth, call_data, Some(nonce))?;
nonce = nonce + 1;
}

println!("All nodes have been deleted.");

for node in nodes {
let call_data = delete_node::call(node.validator_key).0;
nonce = nonce + 1;
call_contract(web3, &self.eth, call_data, Some(nonce))?;
nonce = nonce + 1;
}

println!("All apps have been deleted.");
Expand Down
1 change: 1 addition & 0 deletions cli/src/publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ mod tests {
}

#[test]
#[ignore] // ignored because doesn't clean up published app, thus breaking next integration tests
fn publish_to_contract_with_secret_success() -> Result<(), Error> {
let secret_arr: H256 =
"647334ad14cda7f79fecdf2b9e0bb2a0904856c36f175f97c83db181c1060414".parse()?;
Expand Down
59 changes: 30 additions & 29 deletions cli/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

use std::net::IpAddr;

use failure::{err_msg, Error, SyncFailure};
use failure::{Error, SyncFailure};

use clap::{value_t, App, Arg, ArgMatches, SubCommand};
use derive_getters::Getters;
Expand All @@ -34,8 +34,8 @@ use crate::utils;
use web3::transports::Http;
use web3::types::H160;

const START_PORT: &str = "start_port";
const LAST_PORT: &str = "last_port";
const API_PORT: &str = "api_port";
const CAPACITY: &str = "capacity";
const PRIVATE: &str = "private";
const NO_STATUS_CHECK: &str = "no_status_check";

Expand All @@ -44,8 +44,8 @@ pub struct Register {
node_ip: IpAddr,
tendermint_key: H256,
tendermint_node_id: H160,
start_port: u16,
last_port: u16,
api_port: u16,
capacity: u16,
private: bool,
no_status_check: bool,
eth: EthereumArgs,
Expand All @@ -69,22 +69,18 @@ impl Register {
node_address: IpAddr,
tendermint_key: H256,
tendermint_node_id: H160,
start_port: u16,
last_port: u16,
api_port: u16,
capacity: u16,
private: bool,
no_status_check: bool,
eth: EthereumArgs,
) -> Result<Register, Error> {
if last_port < start_port {
return Err(err_msg("last_port should be bigger than start_port"));
}

Ok(Register {
node_ip: node_address,
tendermint_key,
tendermint_node_id,
start_port,
last_port,
api_port,
capacity,
private,
no_status_check,
eth,
Expand Down Expand Up @@ -130,8 +126,8 @@ impl Register {
let (call_data, _) = add_node::call(
self.tendermint_key,
hash_addr,
u64::from(self.start_port),
u64::from(self.last_port),
u64::from(self.api_port),
u64::from(self.capacity),
self.private,
);

Expand Down Expand Up @@ -259,8 +255,8 @@ pub fn parse(args: &ArgMatches) -> Result<Register, Error> {

let tendermint_node_id: H160 = parse_tendermint_node_id(args)?;

let start_port = value_t!(args, START_PORT, u16)?;
let last_port = value_t!(args, LAST_PORT, u16)?;
let api_port = value_t!(args, API_PORT, u16)?;
let capacity = value_t!(args, CAPACITY, u16)?;

let private: bool = args.is_present(PRIVATE);
let no_status_check: bool = args.is_present(NO_STATUS_CHECK);
Expand All @@ -273,8 +269,8 @@ pub fn parse(args: &ArgMatches) -> Result<Register, Error> {
node_address,
tendermint_key,
tendermint_node_id,
start_port,
last_port,
api_port,
capacity,
private,
no_status_check,
eth,
Expand All @@ -288,19 +284,19 @@ pub fn subcommand<'a, 'b>() -> App<'a, 'b> {
tendermint_key().display_order(2),
base64_tendermint_key().display_order(3),
tendermint_node_id().display_order(4),
Arg::with_name(START_PORT)
.alias(START_PORT)
.long(START_PORT)
Arg::with_name(API_PORT)
.alias(API_PORT)
.long(API_PORT)
.default_value("20096")
.takes_value(true)
.help("Minimum port in the port range")
.help("Node API port")
.display_order(5),
Arg::with_name(LAST_PORT)
.alias(LAST_PORT)
Arg::with_name(CAPACITY)
.alias(CAPACITY)
.default_value("20196")
.long(LAST_PORT)
.long(CAPACITY)
.takes_value(true)
.help("Maximum port in the port range")
.help("Maximum number of apps to be run on the node")
.display_order(5),
Arg::with_name(PRIVATE)
.long(PRIVATE)
Expand Down Expand Up @@ -334,15 +330,20 @@ pub mod tests {

use super::Register;

pub fn generate_eth_args(credentials: Credentials) -> EthereumArgs {
let account: Address = "4180fc65d613ba7e1a385181a219f1dbfe7bf11d".parse().unwrap();

EthereumArgs::with_acc_creds(account, credentials)
}

pub fn generate_register(credentials: Credentials) -> Register {
let mut rng = rand::thread_rng();
let rnd_num: u64 = rng.gen();

let tendermint_key: H256 = H256::from(rnd_num);
let tendermint_node_id: H160 = H160::from(rnd_num);
let account: Address = "4180fc65d613ba7e1a385181a219f1dbfe7bf11d".parse().unwrap();

let eth = EthereumArgs::with_acc_creds(account, credentials);
let eth = generate_eth_args(credentials);

Register::new(
"127.0.0.1".parse().unwrap(),
Expand Down
Loading