Overhaul wallet rpc/drone command-line arguments
This commit is contained in:
parent
00c4c30d72
commit
a84b6bc7e4
|
@ -168,21 +168,23 @@ $ solana-wallet send-timestamp <PUBKEY> <PROCESS_ID> --date 2018-12-24T23:59:00
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
```manpage
|
```manpage
|
||||||
solana-wallet 0.11.0
|
solana-wallet 0.12.0
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
solana-wallet [OPTIONS] [SUBCOMMAND]
|
solana-wallet [FLAGS] [OPTIONS] [SUBCOMMAND]
|
||||||
|
|
||||||
FLAGS:
|
FLAGS:
|
||||||
-h, --help Prints help information
|
-h, --help Prints help information
|
||||||
|
--rpc-tls Enable TLS for the RPC endpoint
|
||||||
-V, --version Prints version information
|
-V, --version Prints version information
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
|
--drone-host <IP ADDRESS> Drone host to use [default: same as --host]
|
||||||
|
--drone-port <PORT> Drone port to use [default: 9900]
|
||||||
|
-n, --host <IP ADDRESS> Host to use for both RPC and drone [default: 127.0.0.1]
|
||||||
-k, --keypair <PATH> /path/to/id.json
|
-k, --keypair <PATH> /path/to/id.json
|
||||||
-n, --network <HOST:PORT> Rendezvous with the network at this gossip entry point; defaults to 127.0.0.1:8001
|
--rpc-host <IP ADDRESS> RPC host to use [default: same as --host]
|
||||||
--proxy <URL> Address of TLS proxy
|
--rpc-port <PORT> RPC port to use [default: 8899]
|
||||||
--port <NUM> Optional rpc-port configuration to connect to non-default nodes
|
|
||||||
--timeout <SECS> Max seconds to wait to get necessary gossip from the network
|
|
||||||
|
|
||||||
SUBCOMMANDS:
|
SUBCOMMANDS:
|
||||||
address Get your public key
|
address Get your public key
|
||||||
|
|
|
@ -194,7 +194,7 @@ $solana_wallet --keypair "$fullnode_id_path" address
|
||||||
# - one token to keep the node identity public key valid.
|
# - one token to keep the node identity public key valid.
|
||||||
retries=5
|
retries=5
|
||||||
while true; do
|
while true; do
|
||||||
if $solana_wallet --keypair "$fullnode_id_path" --network "$leader_address" airdrop 3; then
|
if $solana_wallet --keypair "$fullnode_id_path" --host "${leader_address%:*}" airdrop 3; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ echo "--- RPC API: getTransactionCount"
|
||||||
echo "--- $entrypointIp: wallet sanity"
|
echo "--- $entrypointIp: wallet sanity"
|
||||||
(
|
(
|
||||||
set -x
|
set -x
|
||||||
scripts/wallet-sanity.sh "$entrypointIp":8001
|
scripts/wallet-sanity.sh --host "$entrypointIp"
|
||||||
)
|
)
|
||||||
|
|
||||||
echo "--- $entrypointIp: verify ledger"
|
echo "--- $entrypointIp: verify ledger"
|
||||||
|
|
|
@ -12,7 +12,7 @@ source multinode-demo/common.sh
|
||||||
if [[ -z $1 ]]; then # no network argument, use default
|
if [[ -z $1 ]]; then # no network argument, use default
|
||||||
entrypoint=()
|
entrypoint=()
|
||||||
else
|
else
|
||||||
entrypoint=(-n "$1")
|
entrypoint=("$@")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Tokens transferred to this address are lost forever...
|
# Tokens transferred to this address are lost forever...
|
||||||
|
|
|
@ -507,7 +507,7 @@ mod tests {
|
||||||
let thread = rpc_service.thread_hdl.thread();
|
let thread = rpc_service.thread_hdl.thread();
|
||||||
assert_eq!(thread.name().unwrap(), "solana-jsonrpc");
|
assert_eq!(thread.name().unwrap(), "solana-jsonrpc");
|
||||||
|
|
||||||
let rpc_string = get_rpc_request_str(rpc_addr);
|
let rpc_string = get_rpc_request_str(rpc_addr, false);
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
let request = json!({
|
let request = json!({
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
|
@ -755,7 +755,7 @@ mod tests {
|
||||||
"params": json!([serial_tx])
|
"params": json!([serial_tx])
|
||||||
});
|
});
|
||||||
let rpc_addr = leader_data.rpc;
|
let rpc_addr = leader_data.rpc;
|
||||||
let rpc_string = get_rpc_request_str(rpc_addr);
|
let rpc_string = get_rpc_request_str(rpc_addr, false);
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.post(&rpc_string)
|
.post(&rpc_string)
|
||||||
.header(CONTENT_TYPE, "application/json")
|
.header(CONTENT_TYPE, "application/json")
|
||||||
|
|
|
@ -21,7 +21,7 @@ impl RpcClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_timeout(addr: SocketAddr, timeout: Duration) -> Self {
|
pub fn new_with_timeout(addr: SocketAddr, timeout: Duration) -> Self {
|
||||||
let addr = get_rpc_request_str(addr);
|
let addr = get_rpc_request_str(addr, false);
|
||||||
let client = reqwest::Client::builder()
|
let client = reqwest::Client::builder()
|
||||||
.timeout(timeout)
|
.timeout(timeout)
|
||||||
.build()
|
.build()
|
||||||
|
@ -30,7 +30,7 @@ impl RpcClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_socket(addr: SocketAddr) -> Self {
|
pub fn new_from_socket(addr: SocketAddr) -> Self {
|
||||||
Self::new(get_rpc_request_str(addr))
|
Self::new(get_rpc_request_str(addr, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn retry_make_rpc_request(
|
pub fn retry_make_rpc_request(
|
||||||
|
@ -77,9 +77,13 @@ impl RpcClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rpc_request_str(rpc_addr: SocketAddr) -> String {
|
pub fn get_rpc_request_str(rpc_addr: SocketAddr, tls: bool) -> String {
|
||||||
|
if tls {
|
||||||
|
format!("https://{}", rpc_addr)
|
||||||
|
} else {
|
||||||
format!("http://{}", rpc_addr)
|
format!("http://{}", rpc_addr)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait RpcRequestHandler {
|
pub trait RpcRequestHandler {
|
||||||
fn make_rpc_request(
|
fn make_rpc_request(
|
||||||
|
|
|
@ -1,22 +1,46 @@
|
||||||
use clap::{crate_version, App, Arg, ArgMatches, SubCommand};
|
use clap::{crate_version, App, Arg, ArgMatches, SubCommand};
|
||||||
use solana::socketaddr;
|
|
||||||
use solana_sdk::signature::{gen_keypair_file, read_keypair, KeypairUtil};
|
use solana_sdk::signature::{gen_keypair_file, read_keypair, KeypairUtil};
|
||||||
use solana_wallet::wallet::{parse_command, process_command, WalletConfig, WalletError};
|
use solana_wallet::wallet::{parse_command, process_command, WalletConfig, WalletError};
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::net::SocketAddr;
|
|
||||||
|
|
||||||
pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn error::Error>> {
|
pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn error::Error>> {
|
||||||
let network = if let Some(addr) = matches.value_of("network") {
|
let host = matches
|
||||||
addr.parse().or_else(|_| {
|
.value_of("host")
|
||||||
Err(WalletError::BadParameter(
|
.unwrap()
|
||||||
"Invalid network location".to_string(),
|
.parse()
|
||||||
))
|
.or_else(|_| Err(WalletError::BadParameter("Invalid host".to_string())))?;
|
||||||
})?
|
|
||||||
|
let drone_host = if let Some(drone_host) = matches.value_of("drone_host") {
|
||||||
|
Some(
|
||||||
|
drone_host
|
||||||
|
.parse()
|
||||||
|
.or_else(|_| Err(WalletError::BadParameter("Invalid drone host".to_string())))?,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
socketaddr!("127.0.0.1:8001")
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let proxy = matches.value_of("proxy").map(|proxy| proxy.to_string());
|
let rpc_host = if let Some(rpc_host) = matches.value_of("rpc_host") {
|
||||||
|
Some(
|
||||||
|
rpc_host
|
||||||
|
.parse()
|
||||||
|
.or_else(|_| Err(WalletError::BadParameter("Invalid rpc host".to_string())))?,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let drone_port = matches
|
||||||
|
.value_of("drone_port")
|
||||||
|
.unwrap()
|
||||||
|
.parse()
|
||||||
|
.or_else(|_| Err(WalletError::BadParameter("Invalid drone port".to_string())))?;
|
||||||
|
|
||||||
|
let rpc_port = matches
|
||||||
|
.value_of("rpc_port")
|
||||||
|
.unwrap()
|
||||||
|
.parse()
|
||||||
|
.or_else(|_| Err(WalletError::BadParameter("Invalid rpc port".to_string())))?;
|
||||||
|
|
||||||
let mut path = dirs::home_dir().expect("home directory");
|
let mut path = dirs::home_dir().expect("home directory");
|
||||||
let id_path = if matches.is_present("keypair") {
|
let id_path = if matches.is_present("keypair") {
|
||||||
|
@ -42,40 +66,83 @@ pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn erro
|
||||||
Ok(WalletConfig {
|
Ok(WalletConfig {
|
||||||
id,
|
id,
|
||||||
command,
|
command,
|
||||||
network,
|
drone_host,
|
||||||
proxy,
|
drone_port,
|
||||||
drone_port: None,
|
host,
|
||||||
rpc_client: None,
|
rpc_client: None,
|
||||||
rpc_port: None,
|
rpc_host,
|
||||||
|
rpc_port,
|
||||||
|
rpc_tls: matches.is_present("rpc_tls"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn error::Error>> {
|
fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
|
||||||
|
let (default_host, default_rpc_port, default_drone_port) = {
|
||||||
|
let defaults = WalletConfig::default();
|
||||||
|
(
|
||||||
|
defaults.host.to_string(),
|
||||||
|
defaults.rpc_port.to_string(),
|
||||||
|
defaults.drone_port.to_string(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let matches = App::new("solana-wallet")
|
let matches = App::new("solana-wallet")
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("network")
|
Arg::with_name("host")
|
||||||
.short("n")
|
.short("n")
|
||||||
.long("network")
|
.long("host")
|
||||||
.value_name("HOST:PORT")
|
.value_name("IP ADDRESS")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Rendezvous with the network at this gossip entry point; defaults to 127.0.0.1:8001"),
|
.default_value(&default_host)
|
||||||
).arg(
|
.help("Host to use for both RPC and drone"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("rpc_host")
|
||||||
|
.long("rpc-host")
|
||||||
|
.value_name("IP ADDRESS")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("RPC host to use [default: same as --host]"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("rpc_port")
|
||||||
|
.long("rpc-port")
|
||||||
|
.value_name("PORT")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value(&default_rpc_port)
|
||||||
|
.help("RPC port to use"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("rpc_tps")
|
||||||
|
.long("rpc-tls")
|
||||||
|
.help("Enable TLS for the RPC endpoint"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("drone_host")
|
||||||
|
.long("drone-host")
|
||||||
|
.value_name("IP ADDRESS")
|
||||||
|
.takes_value(true)
|
||||||
|
.help("Drone host to use [default: same as --host]"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("drone_port")
|
||||||
|
.long("drone-port")
|
||||||
|
.value_name("PORT")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value(&default_drone_port)
|
||||||
|
.help("Drone port to use"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
Arg::with_name("keypair")
|
Arg::with_name("keypair")
|
||||||
.short("k")
|
.short("k")
|
||||||
.long("keypair")
|
.long("keypair")
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("/path/to/id.json"),
|
.help("/path/to/id.json"),
|
||||||
).arg(
|
)
|
||||||
Arg::with_name("proxy")
|
.subcommand(SubCommand::with_name("address").about("Get your public key"))
|
||||||
.long("proxy")
|
|
||||||
.takes_value(true)
|
|
||||||
.value_name("URL")
|
|
||||||
.help("Address of TLS proxy")
|
|
||||||
.conflicts_with("rpc-port")
|
|
||||||
).subcommand(SubCommand::with_name("address").about("Get your public key"))
|
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("airdrop")
|
SubCommand::with_name("airdrop")
|
||||||
.about("Request a batch of tokens")
|
.about("Request a batch of tokens")
|
||||||
|
@ -87,7 +154,8 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The number of tokens to request"),
|
.help("The number of tokens to request"),
|
||||||
),
|
),
|
||||||
).subcommand(SubCommand::with_name("balance").about("Get your balance"))
|
)
|
||||||
|
.subcommand(SubCommand::with_name("balance").about("Get your balance"))
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("cancel")
|
SubCommand::with_name("cancel")
|
||||||
.about("Cancel a transfer")
|
.about("Cancel a transfer")
|
||||||
|
@ -99,7 +167,8 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The process id of the transfer to cancel"),
|
.help("The process id of the transfer to cancel"),
|
||||||
),
|
),
|
||||||
).subcommand(
|
)
|
||||||
|
.subcommand(
|
||||||
SubCommand::with_name("confirm")
|
SubCommand::with_name("confirm")
|
||||||
.about("Confirm transaction by signature")
|
.about("Confirm transaction by signature")
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -110,7 +179,8 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The transaction signature to confirm"),
|
.help("The transaction signature to confirm"),
|
||||||
),
|
),
|
||||||
).subcommand(
|
)
|
||||||
|
.subcommand(
|
||||||
SubCommand::with_name("deploy")
|
SubCommand::with_name("deploy")
|
||||||
.about("Deploy a program")
|
.about("Deploy a program")
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -120,12 +190,12 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("/path/to/program.o"),
|
.help("/path/to/program.o"),
|
||||||
|
), // TODO: Add "loader" argument; current default is bpf_loader
|
||||||
)
|
)
|
||||||
// TODO: Add "loader" argument; current default is bpf_loader
|
.subcommand(
|
||||||
).subcommand(
|
SubCommand::with_name("get-transaction-count").about("Get current transaction count"),
|
||||||
SubCommand::with_name("get-transaction-count")
|
)
|
||||||
.about("Get current transaction count")
|
.subcommand(
|
||||||
).subcommand(
|
|
||||||
SubCommand::with_name("pay")
|
SubCommand::with_name("pay")
|
||||||
.about("Send a payment")
|
.about("Send a payment")
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -135,27 +205,31 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The pubkey of recipient"),
|
.help("The pubkey of recipient"),
|
||||||
).arg(
|
)
|
||||||
|
.arg(
|
||||||
Arg::with_name("tokens")
|
Arg::with_name("tokens")
|
||||||
.index(2)
|
.index(2)
|
||||||
.value_name("NUM")
|
.value_name("NUM")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The number of tokens to send"),
|
.help("The number of tokens to send"),
|
||||||
).arg(
|
)
|
||||||
|
.arg(
|
||||||
Arg::with_name("timestamp")
|
Arg::with_name("timestamp")
|
||||||
.long("after")
|
.long("after")
|
||||||
.value_name("DATETIME")
|
.value_name("DATETIME")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("A timestamp after which transaction will execute"),
|
.help("A timestamp after which transaction will execute"),
|
||||||
).arg(
|
)
|
||||||
|
.arg(
|
||||||
Arg::with_name("timestamp-pubkey")
|
Arg::with_name("timestamp-pubkey")
|
||||||
.long("require-timestamp-from")
|
.long("require-timestamp-from")
|
||||||
.value_name("PUBKEY")
|
.value_name("PUBKEY")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.requires("timestamp")
|
.requires("timestamp")
|
||||||
.help("Require timestamp from this third party"),
|
.help("Require timestamp from this third party"),
|
||||||
).arg(
|
)
|
||||||
|
.arg(
|
||||||
Arg::with_name("witness")
|
Arg::with_name("witness")
|
||||||
.long("require-signature-from")
|
.long("require-signature-from")
|
||||||
.value_name("PUBKEY")
|
.value_name("PUBKEY")
|
||||||
|
@ -163,12 +237,14 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.multiple(true)
|
.multiple(true)
|
||||||
.use_delimiter(true)
|
.use_delimiter(true)
|
||||||
.help("Any third party signatures required to unlock the tokens"),
|
.help("Any third party signatures required to unlock the tokens"),
|
||||||
).arg(
|
)
|
||||||
|
.arg(
|
||||||
Arg::with_name("cancelable")
|
Arg::with_name("cancelable")
|
||||||
.long("cancelable")
|
.long("cancelable")
|
||||||
.takes_value(false),
|
.takes_value(false),
|
||||||
),
|
),
|
||||||
).subcommand(
|
)
|
||||||
|
.subcommand(
|
||||||
SubCommand::with_name("send-signature")
|
SubCommand::with_name("send-signature")
|
||||||
.about("Send a signature to authorize a transfer")
|
.about("Send a signature to authorize a transfer")
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -178,15 +254,17 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The pubkey of recipient"),
|
.help("The pubkey of recipient"),
|
||||||
).arg(
|
)
|
||||||
|
.arg(
|
||||||
Arg::with_name("process-id")
|
Arg::with_name("process-id")
|
||||||
.index(2)
|
.index(2)
|
||||||
.value_name("PROCESS_ID")
|
.value_name("PROCESS_ID")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The process id of the transfer to authorize")
|
.help("The process id of the transfer to authorize"),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
).subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("send-timestamp")
|
SubCommand::with_name("send-timestamp")
|
||||||
.about("Send a timestamp to unlock a transfer")
|
.about("Send a timestamp to unlock a transfer")
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -196,21 +274,24 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The pubkey of recipient"),
|
.help("The pubkey of recipient"),
|
||||||
).arg(
|
)
|
||||||
|
.arg(
|
||||||
Arg::with_name("process-id")
|
Arg::with_name("process-id")
|
||||||
.index(2)
|
.index(2)
|
||||||
.value_name("PROCESS_ID")
|
.value_name("PROCESS_ID")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The process id of the transfer to unlock")
|
.help("The process id of the transfer to unlock"),
|
||||||
).arg(
|
)
|
||||||
|
.arg(
|
||||||
Arg::with_name("datetime")
|
Arg::with_name("datetime")
|
||||||
.long("date")
|
.long("date")
|
||||||
.value_name("DATETIME")
|
.value_name("DATETIME")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Optional arbitrary timestamp to apply")
|
.help("Optional arbitrary timestamp to apply"),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
).get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let config = parse_args(&matches)?;
|
let config = parse_args(&matches)?;
|
||||||
let result = process_command(&config)?;
|
let result = process_command(&config)?;
|
||||||
|
|
|
@ -10,7 +10,6 @@ use solana::rpc_mock::{request_airdrop_transaction, MockRpcClient as RpcClient};
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use solana::rpc_request::RpcClient;
|
use solana::rpc_request::RpcClient;
|
||||||
use solana::rpc_request::{get_rpc_request_str, RpcRequest};
|
use solana::rpc_request::{get_rpc_request_str, RpcRequest};
|
||||||
use solana::socketaddr;
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use solana_drone::drone::request_airdrop_transaction;
|
use solana_drone::drone::request_airdrop_transaction;
|
||||||
use solana_drone::drone::DRONE_PORT;
|
use solana_drone::drone::DRONE_PORT;
|
||||||
|
@ -25,7 +24,7 @@ use solana_sdk::system_transaction::SystemTransaction;
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::Transaction;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::net::{Ipv4Addr, SocketAddr};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -85,41 +84,41 @@ impl error::Error for WalletError {
|
||||||
pub struct WalletConfig {
|
pub struct WalletConfig {
|
||||||
pub id: Keypair,
|
pub id: Keypair,
|
||||||
pub command: WalletCommand,
|
pub command: WalletCommand,
|
||||||
pub network: SocketAddr,
|
pub drone_host: Option<IpAddr>,
|
||||||
pub proxy: Option<String>,
|
pub drone_port: u16,
|
||||||
pub drone_port: Option<u16>,
|
pub host: IpAddr,
|
||||||
pub rpc_client: Option<RpcClient>,
|
pub rpc_client: Option<RpcClient>,
|
||||||
pub rpc_port: Option<u16>,
|
pub rpc_host: Option<IpAddr>,
|
||||||
|
pub rpc_port: u16,
|
||||||
|
pub rpc_tls: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WalletConfig {
|
impl Default for WalletConfig {
|
||||||
fn default() -> WalletConfig {
|
fn default() -> WalletConfig {
|
||||||
let default_addr = socketaddr!(0, 8000);
|
|
||||||
WalletConfig {
|
WalletConfig {
|
||||||
id: Keypair::new(),
|
|
||||||
command: WalletCommand::Balance,
|
command: WalletCommand::Balance,
|
||||||
network: default_addr,
|
drone_host: None,
|
||||||
proxy: None,
|
drone_port: DRONE_PORT,
|
||||||
drone_port: None,
|
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
||||||
|
id: Keypair::new(),
|
||||||
rpc_client: None,
|
rpc_client: None,
|
||||||
rpc_port: None,
|
rpc_host: None,
|
||||||
|
rpc_port: RPC_PORT,
|
||||||
|
rpc_tls: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WalletConfig {
|
impl WalletConfig {
|
||||||
pub fn drone_addr(&self) -> SocketAddr {
|
pub fn drone_addr(&self) -> SocketAddr {
|
||||||
// Assume drone is running on the provided network entrypoint
|
SocketAddr::new(self.drone_host.unwrap_or(self.host), self.drone_port)
|
||||||
let mut drone_addr = self.network;
|
|
||||||
drone_addr.set_port(self.drone_port.unwrap_or(DRONE_PORT));
|
|
||||||
drone_addr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rpc_addr(&self) -> String {
|
pub fn rpc_addr(&self) -> String {
|
||||||
let mut rpc_addr = self.network;
|
get_rpc_request_str(
|
||||||
rpc_addr.set_port(self.rpc_port.unwrap_or(RPC_PORT));
|
SocketAddr::new(self.rpc_host.unwrap_or(self.host), self.rpc_port),
|
||||||
let rpc_addr_str = get_rpc_request_str(rpc_addr);
|
self.rpc_tls,
|
||||||
self.proxy.clone().unwrap_or(rpc_addr_str)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,6 +793,7 @@ mod tests {
|
||||||
use clap::{App, Arg, SubCommand};
|
use clap::{App, Arg, SubCommand};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use solana::rpc_mock::{PUBKEY, SIGNATURE};
|
use solana::rpc_mock::{PUBKEY, SIGNATURE};
|
||||||
|
use solana::socketaddr;
|
||||||
use solana_sdk::signature::{gen_keypair_file, read_keypair, read_pkcs8, Keypair, KeypairUtil};
|
use solana_sdk::signature::{gen_keypair_file, read_keypair, read_pkcs8, Keypair, KeypairUtil};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::net::{Ipv4Addr, SocketAddr};
|
use std::net::{Ipv4Addr, SocketAddr};
|
||||||
|
@ -802,15 +802,29 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wallet_config_drone_addr() {
|
fn test_wallet_config_drone_addr() {
|
||||||
let mut config = WalletConfig::default();
|
let mut config = WalletConfig::default();
|
||||||
assert_eq!(config.drone_addr(), socketaddr!(0, DRONE_PORT));
|
assert_eq!(
|
||||||
|
config.drone_addr(),
|
||||||
|
SocketAddr::new(config.host, config.drone_port)
|
||||||
|
);
|
||||||
|
|
||||||
config.drone_port = Some(1234);
|
config.drone_port = 1234;
|
||||||
assert_eq!(config.drone_addr(), socketaddr!(0, 1234));
|
assert_eq!(config.drone_addr(), SocketAddr::new(config.host, 1234));
|
||||||
|
|
||||||
assert_eq!(config.rpc_addr(), "http://0.0.0.0:8899");
|
config.drone_host = Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)));
|
||||||
|
assert_eq!(
|
||||||
|
config.drone_addr(),
|
||||||
|
SocketAddr::new(config.drone_host.unwrap(), 1234)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
config.rpc_port = Some(1234);
|
#[test]
|
||||||
assert_eq!(config.rpc_addr(), "http://0.0.0.0:1234");
|
fn test_wallet_config_rpc_addr() {
|
||||||
|
let mut config = WalletConfig::default();
|
||||||
|
assert_eq!(config.rpc_addr(), "http://127.0.0.1:8899");
|
||||||
|
config.rpc_port = 1234;
|
||||||
|
assert_eq!(config.rpc_addr(), "http://127.0.0.1:1234");
|
||||||
|
config.rpc_host = Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)));
|
||||||
|
assert_eq!(config.rpc_addr(), "http://127.0.0.2:1234");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -72,14 +72,12 @@ fn test_wallet_timestamp_tx() {
|
||||||
let rpc_client = RpcClient::new_from_socket(leader_data.rpc);
|
let rpc_client = RpcClient::new_from_socket(leader_data.rpc);
|
||||||
|
|
||||||
let mut config_payer = WalletConfig::default();
|
let mut config_payer = WalletConfig::default();
|
||||||
config_payer.network = leader_data.gossip;
|
config_payer.drone_port = drone_addr.port();
|
||||||
config_payer.drone_port = Some(drone_addr.port());
|
config_payer.rpc_port = leader_data.rpc.port();
|
||||||
config_payer.rpc_port = Some(leader_data.rpc.port());
|
|
||||||
|
|
||||||
let mut config_witness = WalletConfig::default();
|
let mut config_witness = WalletConfig::default();
|
||||||
config_witness.network = leader_data.gossip;
|
config_witness.drone_port = drone_addr.port();
|
||||||
config_witness.drone_port = Some(drone_addr.port());
|
config_witness.rpc_port = leader_data.rpc.port();
|
||||||
config_witness.rpc_port = Some(leader_data.rpc.port());
|
|
||||||
|
|
||||||
assert_ne!(config_payer.id.pubkey(), config_witness.id.pubkey());
|
assert_ne!(config_payer.id.pubkey(), config_witness.id.pubkey());
|
||||||
|
|
||||||
|
@ -173,14 +171,12 @@ fn test_wallet_witness_tx() {
|
||||||
let rpc_client = RpcClient::new_from_socket(leader_data.rpc);
|
let rpc_client = RpcClient::new_from_socket(leader_data.rpc);
|
||||||
|
|
||||||
let mut config_payer = WalletConfig::default();
|
let mut config_payer = WalletConfig::default();
|
||||||
config_payer.network = leader_data.gossip;
|
config_payer.drone_port = drone_addr.port();
|
||||||
config_payer.drone_port = Some(drone_addr.port());
|
config_payer.rpc_port = leader_data.rpc.port();
|
||||||
config_payer.rpc_port = Some(leader_data.rpc.port());
|
|
||||||
|
|
||||||
let mut config_witness = WalletConfig::default();
|
let mut config_witness = WalletConfig::default();
|
||||||
config_witness.network = leader_data.gossip;
|
config_witness.drone_port = drone_addr.port();
|
||||||
config_witness.drone_port = Some(drone_addr.port());
|
config_witness.rpc_port = leader_data.rpc.port();
|
||||||
config_witness.rpc_port = Some(leader_data.rpc.port());
|
|
||||||
|
|
||||||
assert_ne!(config_payer.id.pubkey(), config_witness.id.pubkey());
|
assert_ne!(config_payer.id.pubkey(), config_witness.id.pubkey());
|
||||||
|
|
||||||
|
@ -270,14 +266,12 @@ fn test_wallet_cancel_tx() {
|
||||||
let rpc_client = RpcClient::new_from_socket(leader_data.rpc);
|
let rpc_client = RpcClient::new_from_socket(leader_data.rpc);
|
||||||
|
|
||||||
let mut config_payer = WalletConfig::default();
|
let mut config_payer = WalletConfig::default();
|
||||||
config_payer.network = leader_data.gossip;
|
config_payer.drone_port = drone_addr.port();
|
||||||
config_payer.drone_port = Some(drone_addr.port());
|
config_payer.rpc_port = leader_data.rpc.port();
|
||||||
config_payer.rpc_port = Some(leader_data.rpc.port());
|
|
||||||
|
|
||||||
let mut config_witness = WalletConfig::default();
|
let mut config_witness = WalletConfig::default();
|
||||||
config_witness.network = leader_data.gossip;
|
config_witness.drone_port = drone_addr.port();
|
||||||
config_witness.drone_port = Some(drone_addr.port());
|
config_witness.rpc_port = leader_data.rpc.port();
|
||||||
config_witness.rpc_port = Some(leader_data.rpc.port());
|
|
||||||
|
|
||||||
assert_ne!(config_payer.id.pubkey(), config_witness.id.pubkey());
|
assert_ne!(config_payer.id.pubkey(), config_witness.id.pubkey());
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,8 @@ fn test_wallet_request_airdrop() {
|
||||||
let drone_addr = receiver.recv().unwrap();
|
let drone_addr = receiver.recv().unwrap();
|
||||||
|
|
||||||
let mut bob_config = WalletConfig::default();
|
let mut bob_config = WalletConfig::default();
|
||||||
bob_config.network = leader_data.gossip;
|
bob_config.drone_port = drone_addr.port();
|
||||||
bob_config.drone_port = Some(drone_addr.port());
|
bob_config.rpc_port = leader_data.rpc.port();
|
||||||
bob_config.rpc_port = Some(leader_data.rpc.port());
|
|
||||||
bob_config.command = WalletCommand::Airdrop(50);
|
bob_config.command = WalletCommand::Airdrop(50);
|
||||||
|
|
||||||
let sig_response = process_command(&bob_config);
|
let sig_response = process_command(&bob_config);
|
||||||
|
|
Loading…
Reference in New Issue