Add stop node command to solana-gossip (#3928)
This commit is contained in:
parent
95a16426f3
commit
05bcb7f292
|
@ -2483,6 +2483,7 @@ dependencies = [
|
||||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"solana 0.14.0",
|
"solana 0.14.0",
|
||||||
|
"solana-client 0.14.0",
|
||||||
"solana-netutil 0.14.0",
|
"solana-netutil 0.14.0",
|
||||||
"solana-sdk 0.14.0",
|
"solana-sdk 0.14.0",
|
||||||
]
|
]
|
||||||
|
|
|
@ -41,7 +41,7 @@ Inspect the blockexplorer at [http://beta.testnet.solana.com/](http://beta.testn
|
||||||
|
|
||||||
Run the following command to join the gossip network and view all the other nodes in the cluster:
|
Run the following command to join the gossip network and view all the other nodes in the cluster:
|
||||||
```bash
|
```bash
|
||||||
$ solana-gossip --network beta.testnet.solana.com:8001
|
$ solana-gossip --network beta.testnet.solana.com:8001 spy
|
||||||
```
|
```
|
||||||
|
|
||||||
View the [metrics dashboard](
|
View the [metrics dashboard](
|
||||||
|
|
|
@ -306,8 +306,7 @@ while [[ $iteration -le $iterations ]]; do
|
||||||
set -x
|
set -x
|
||||||
client_id=/tmp/client-id.json-$$
|
client_id=/tmp/client-id.json-$$
|
||||||
$solana_keygen -o $client_id || exit $?
|
$solana_keygen -o $client_id || exit $?
|
||||||
$solana_gossip \
|
$solana_gossip spy --num-nodes-exactly $numNodes || exit $?
|
||||||
--num-nodes-exactly $numNodes || exit $?
|
|
||||||
rm -rf $client_id
|
rm -rf $client_id
|
||||||
) || flag_error
|
) || flag_error
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ homepage = "https://solana.com/"
|
||||||
clap = "2.33.0"
|
clap = "2.33.0"
|
||||||
env_logger = "0.6.1"
|
env_logger = "0.6.1"
|
||||||
solana = { path = "../core", version = "0.14.0" }
|
solana = { path = "../core", version = "0.14.0" }
|
||||||
|
solana-client = { path = "../client", version = "0.14.0" }
|
||||||
solana-netutil = { path = "../netutil", version = "0.14.0" }
|
solana-netutil = { path = "../netutil", version = "0.14.0" }
|
||||||
solana-sdk = { path = "../sdk", version = "0.14.0" }
|
solana-sdk = { path = "../sdk", version = "0.14.0" }
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
//! A command-line executable for monitoring a cluster's gossip plane.
|
//! A command-line executable for monitoring a cluster's gossip plane.
|
||||||
|
|
||||||
use clap::{crate_description, crate_name, crate_version, App, Arg};
|
use clap::{crate_description, crate_name, crate_version, App, AppSettings, Arg, SubCommand};
|
||||||
|
use solana::contact_info::ContactInfo;
|
||||||
use solana::gossip_service::discover;
|
use solana::gossip_service::discover;
|
||||||
|
use solana_client::rpc_client::RpcClient;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
@ -22,6 +24,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
let matches = App::new(crate_name!())
|
let matches = App::new(crate_name!())
|
||||||
.about(crate_description!())
|
.about(crate_description!())
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
|
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("network")
|
Arg::with_name("network")
|
||||||
.short("n")
|
.short("n")
|
||||||
|
@ -31,38 +34,58 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.default_value(&network_string)
|
.default_value(&network_string)
|
||||||
.help("Rendezvous with the cluster at this gossip entry point"),
|
.help("Rendezvous with the cluster at this gossip entry point"),
|
||||||
)
|
)
|
||||||
.arg(
|
.subcommand(
|
||||||
Arg::with_name("num_nodes")
|
SubCommand::with_name("spy")
|
||||||
.short("N")
|
.about("Monitor the gossip network")
|
||||||
.long("num-nodes")
|
.setting(AppSettings::DisableVersion)
|
||||||
.value_name("NUM")
|
.arg(
|
||||||
.takes_value(true)
|
Arg::with_name("num_nodes")
|
||||||
.conflicts_with("num_nodes_exactly")
|
.short("N")
|
||||||
.help("Wait for at least NUM nodes to converge"),
|
.long("num-nodes")
|
||||||
|
.value_name("NUM")
|
||||||
|
.takes_value(true)
|
||||||
|
.conflicts_with("num_nodes_exactly")
|
||||||
|
.help("Wait for at least NUM nodes to converge"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("num_nodes_exactly")
|
||||||
|
.short("E")
|
||||||
|
.long("num-nodes-exactly")
|
||||||
|
.value_name("NUM")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("Wait for exactly NUM nodes to converge"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("node_pubkey")
|
||||||
|
.short("p")
|
||||||
|
.long("pubkey")
|
||||||
|
.value_name("PUBKEY")
|
||||||
|
.takes_value(true)
|
||||||
|
.validator(pubkey_validator)
|
||||||
|
.help("Public key of a specific node to wait for"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("timeout")
|
||||||
|
.long("timeout")
|
||||||
|
.value_name("SECS")
|
||||||
|
.takes_value(true)
|
||||||
|
.help(
|
||||||
|
"Maximum time to wait for cluster to converge [default: wait forever]",
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
.subcommand(
|
||||||
Arg::with_name("num_nodes_exactly")
|
SubCommand::with_name("stop")
|
||||||
.short("E")
|
.about("Send stop request to a node")
|
||||||
.long("num-nodes-exactly")
|
.setting(AppSettings::DisableVersion)
|
||||||
.value_name("NUM")
|
.arg(
|
||||||
.takes_value(true)
|
Arg::with_name("node_pubkey")
|
||||||
.help("Wait for exactly NUM nodes to converge"),
|
.index(1)
|
||||||
)
|
.required(true)
|
||||||
.arg(
|
.value_name("PUBKEY")
|
||||||
Arg::with_name("node_pubkey")
|
.validator(pubkey_validator)
|
||||||
.short("p")
|
.help("Public key of a specific node to stop"),
|
||||||
.long("pubkey")
|
),
|
||||||
.value_name("PUBKEY")
|
|
||||||
.takes_value(true)
|
|
||||||
.validator(pubkey_validator)
|
|
||||||
.help("Public key of a specific node to wait for"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("timeout")
|
|
||||||
.long("timeout")
|
|
||||||
.value_name("SECS")
|
|
||||||
.takes_value(true)
|
|
||||||
.help("Maximum time to wait for cluster to converge [default: wait forever]"),
|
|
||||||
)
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
|
@ -72,48 +95,74 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
exit(1)
|
exit(1)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
match matches.subcommand() {
|
||||||
|
("spy", Some(matches)) => {
|
||||||
|
let num_nodes_exactly = matches
|
||||||
|
.value_of("num_nodes_exactly")
|
||||||
|
.map(|num| num.to_string().parse().unwrap());
|
||||||
|
let num_nodes = matches
|
||||||
|
.value_of("num_nodes")
|
||||||
|
.map(|num| num.to_string().parse().unwrap())
|
||||||
|
.or(num_nodes_exactly);
|
||||||
|
let timeout = matches
|
||||||
|
.value_of("timeout")
|
||||||
|
.map(|secs| secs.to_string().parse().unwrap());
|
||||||
|
let pubkey = matches
|
||||||
|
.value_of("node_pubkey")
|
||||||
|
.map(|pubkey_str| pubkey_str.parse::<Pubkey>().unwrap());
|
||||||
|
|
||||||
let num_nodes_exactly = matches
|
let nodes = discover(&network_addr, num_nodes, timeout, pubkey)?;
|
||||||
.value_of("num_nodes_exactly")
|
|
||||||
.map(|num| num.to_string().parse().unwrap());
|
|
||||||
let num_nodes = matches
|
|
||||||
.value_of("num_nodes")
|
|
||||||
.map(|num| num.to_string().parse().unwrap())
|
|
||||||
.or(num_nodes_exactly);
|
|
||||||
let timeout = matches
|
|
||||||
.value_of("timeout")
|
|
||||||
.map(|secs| secs.to_string().parse().unwrap());
|
|
||||||
let pubkey = matches
|
|
||||||
.value_of("node_pubkey")
|
|
||||||
.map(|pubkey_str| pubkey_str.parse::<Pubkey>().unwrap());
|
|
||||||
|
|
||||||
let nodes = discover(&network_addr, num_nodes, timeout, pubkey)?;
|
if timeout.is_some() {
|
||||||
|
if let Some(num) = num_nodes {
|
||||||
if timeout.is_some() {
|
if nodes.len() < num {
|
||||||
if let Some(num) = num_nodes {
|
let add = if num_nodes_exactly.is_some() {
|
||||||
if nodes.len() < num {
|
""
|
||||||
let add = if num_nodes_exactly.is_some() {
|
} else {
|
||||||
""
|
" or more"
|
||||||
} else {
|
};
|
||||||
" or more"
|
eprintln!(
|
||||||
};
|
"Error: Insufficient nodes discovered. Expecting {}{}",
|
||||||
|
num, add,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(node) = pubkey {
|
||||||
|
if nodes.iter().find(|x| x.id == node).is_none() {
|
||||||
|
eprintln!("Error: Could not find node {:?}", node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if num_nodes_exactly.is_some() && nodes.len() > num_nodes_exactly.unwrap() {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Error: Insufficient nodes discovered. Expecting {}{}",
|
"Error: Extra nodes discovered. Expecting exactly {}",
|
||||||
num, add,
|
num_nodes_exactly.unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(node) = pubkey {
|
("stop", Some(matches)) => {
|
||||||
if nodes.iter().find(|x| x.id == node).is_none() {
|
let pubkey = matches
|
||||||
eprintln!("Error: Could not find node {:?}", node);
|
.value_of("node_pubkey")
|
||||||
|
.unwrap()
|
||||||
|
.parse::<Pubkey>()
|
||||||
|
.unwrap();
|
||||||
|
let nodes = discover(&network_addr, None, None, Some(pubkey))?;
|
||||||
|
let node = nodes.iter().find(|x| x.id == pubkey).unwrap();
|
||||||
|
|
||||||
|
if !ContactInfo::is_valid_address(&node.rpc) {
|
||||||
|
eprintln!("Error: RPC service is not enabled on node {:?}", pubkey);
|
||||||
|
}
|
||||||
|
println!("\nSending stop request to node {:?}", pubkey);
|
||||||
|
|
||||||
|
let result = RpcClient::new_socket(node.rpc).fullnode_exit()?;
|
||||||
|
if result {
|
||||||
|
println!("Stop signal accepted");
|
||||||
|
} else {
|
||||||
|
eprintln!("Error: Stop signal ignored");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
if num_nodes_exactly.is_some() && nodes.len() > num_nodes_exactly.unwrap() {
|
|
||||||
eprintln!(
|
|
||||||
"Error: Extra nodes discovered. Expecting exactly {}",
|
|
||||||
num_nodes_exactly.unwrap()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,12 +81,13 @@ local|tar)
|
||||||
fi
|
fi
|
||||||
./multinode-demo/drone.sh > drone.log 2>&1 &
|
./multinode-demo/drone.sh > drone.log 2>&1 &
|
||||||
|
|
||||||
maybePublicAddress=
|
args=()
|
||||||
if $publicNetwork; then
|
if $publicNetwork; then
|
||||||
maybePublicAddress="--public-address"
|
args+=(--public-address)
|
||||||
fi
|
fi
|
||||||
|
args+=(--enable-rpc-exit)
|
||||||
|
|
||||||
./multinode-demo/bootstrap-leader.sh $maybePublicAddress > bootstrap-leader.log 2>&1 &
|
./multinode-demo/bootstrap-leader.sh "${args[@]}" > bootstrap-leader.log 2>&1 &
|
||||||
ln -sTf bootstrap-leader.log fullnode.log
|
ln -sTf bootstrap-leader.log fullnode.log
|
||||||
;;
|
;;
|
||||||
fullnode|blockstreamer)
|
fullnode|blockstreamer)
|
||||||
|
@ -116,6 +117,7 @@ local|tar)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
args+=(
|
args+=(
|
||||||
|
--enable-rpc-exit
|
||||||
--gossip-port 8001
|
--gossip-port 8001
|
||||||
--rpc-port 8899
|
--rpc-port 8899
|
||||||
)
|
)
|
||||||
|
@ -147,7 +149,9 @@ local|tar)
|
||||||
# Confirm the blockexplorer is now globally accessible
|
# Confirm the blockexplorer is now globally accessible
|
||||||
curl --head "$(curl ifconfig.io)"
|
curl --head "$(curl ifconfig.io)"
|
||||||
fi
|
fi
|
||||||
./multinode-demo/fullnode.sh "${args[@]}" "$entrypointIp":~/solana "$entrypointIp:8001" > fullnode.log 2>&1 &
|
|
||||||
|
args+=("$entrypointIp":~/solana "$entrypointIp:8001")
|
||||||
|
./multinode-demo/fullnode.sh "${args[@]}" > fullnode.log 2>&1 &
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Error: unknown node type: $nodeType"
|
echo "Error: unknown node type: $nodeType"
|
||||||
|
|
|
@ -89,9 +89,8 @@ echo "+++ $entrypointIp: node count ($numNodes expected)"
|
||||||
nodeArg="num-nodes-exactly"
|
nodeArg="num-nodes-exactly"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
timeout 2m $solana_gossip \
|
timeout 2m $solana_gossip --network "$entrypointIp:8001" \
|
||||||
--network "$entrypointIp:8001" \
|
spy --$nodeArg "$numNodes" \
|
||||||
--$nodeArg "$numNodes" \
|
|
||||||
)
|
)
|
||||||
|
|
||||||
echo "--- RPC API: getTransactionCount"
|
echo "--- RPC API: getTransactionCount"
|
||||||
|
|
Loading…
Reference in New Issue