From 7159cc40cb3c07a369f6160261181c76e389b3c4 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 2 Jul 2018 11:19:51 -0700 Subject: [PATCH 1/5] Reuse request UDP port for responses --- src/bin/fullnode.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/bin/fullnode.rs b/src/bin/fullnode.rs index 132ea9493a348b..1a886eb3ab78b7 100644 --- a/src/bin/fullnode.rs +++ b/src/bin/fullnode.rs @@ -156,16 +156,22 @@ fn main() { Box::new(stdout()) }; + let requests_socket = UdpSocket::bind(local_requests_addr).unwrap(); + // Responses are sent from the same Udp port as requests are received + // from, in hopes that a NAT sitting in the middle will route the + // response Udp packet correctly back to the requester. + let respond_socket = requests_socket.try_clone().unwrap(); + let server = Server::new_leader( bank, entry_height, //Some(Duration::from_millis(1000)), None, repl_data.clone(), - UdpSocket::bind(local_requests_addr).unwrap(), + requests_socket, UdpSocket::bind(local_transactions_addr).unwrap(), UdpSocket::bind("0.0.0.0:0").unwrap(), - UdpSocket::bind("0.0.0.0:0").unwrap(), + respond_socket, UdpSocket::bind(local_gossip_addr).unwrap(), exit.clone(), outfile, From 8c8290c6f8be53980ec6afb34510249dda25e3dd Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 2 Jul 2018 13:45:40 -0700 Subject: [PATCH 2/5] Bind to 0.0.0.0 --- src/bin/drone.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/bin/drone.rs b/src/bin/drone.rs index 6d2137c650fce1..86046421595f3f 100644 --- a/src/bin/drone.rs +++ b/src/bin/drone.rs @@ -11,7 +11,7 @@ extern crate tokio_io; use atty::{is, Stream as atty_stream}; use bincode::deserialize; use getopts::Options; -use solana::crdt::{get_ip_addr, ReplicatedData}; +use solana::crdt::ReplicatedData; use solana::drone::{Drone, DroneRequest}; use solana::mint::Mint; use std::env; @@ -103,8 +103,7 @@ fn main() { let mint_keypair = mint.keypair(); - let mut drone_addr: SocketAddr = "0.0.0.0:9900".parse().unwrap(); - drone_addr.set_ip(get_ip_addr().unwrap()); + let drone_addr: SocketAddr = "0.0.0.0:9900".parse().unwrap(); let drone = Arc::new(Mutex::new(Drone::new( mint_keypair, From de235270fd160948263b78ce076acd4b3cce6f1d Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 2 Jul 2018 13:49:21 -0700 Subject: [PATCH 3/5] Drop -demo suffix --- .gitignore | 2 +- multinode-demo/client.sh | 2 +- multinode-demo/wallet.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 8c4a32a0532518..e7498d7d52b088 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ Cargo.lock /config-private/ /config-drone/ /config-validator/ -/config-client-demo/ +/config-client/ diff --git a/multinode-demo/client.sh b/multinode-demo/client.sh index 9d9f865609ede8..0e6e8ff739d773 100755 --- a/multinode-demo/client.sh +++ b/multinode-demo/client.sh @@ -6,7 +6,7 @@ here=$(dirname "$0") # shellcheck source=multinode-demo/common.sh source "$here"/common.sh -SOLANA_CONFIG_DIR=config-client-demo +SOLANA_CONFIG_DIR=config-client leader=${1:-${here}/..} # Default to local solana repo count=${2:-1} diff --git a/multinode-demo/wallet.sh b/multinode-demo/wallet.sh index 15da51ca5d5a06..717b3bcdcabf3a 100755 --- a/multinode-demo/wallet.sh +++ b/multinode-demo/wallet.sh @@ -6,7 +6,7 @@ here=$(dirname "$0") # shellcheck source=multinode-demo/common.sh source "$here"/common.sh -SOLANA_CONFIG_DIR=config-client-demo +SOLANA_CONFIG_DIR=config-client leader=${1:-${here}/..} # Default to local solana repo shift From 9f57fdf32a89faf37dbcb0ef4ed1dbdee043ed69 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 2 Jul 2018 13:43:33 -0700 Subject: [PATCH 4/5] Undo UPnP UDP port binding --- src/bin/client-demo.rs | 12 +++++------- src/bin/wallet.rs | 15 ++++++--------- src/drone.rs | 2 -- src/thin_client.rs | 22 ++++++++-------------- tests/multinode.rs | 1 - 5 files changed, 19 insertions(+), 33 deletions(-) diff --git a/src/bin/client-demo.rs b/src/bin/client-demo.rs index e1a0b192a36930..92bc03e06e9db0 100644 --- a/src/bin/client-demo.rs +++ b/src/bin/client-demo.rs @@ -301,20 +301,18 @@ fn main() { } fn mk_client(r: &ReplicatedData) -> ThinClient { - let transactions_socket_pair = udp_public_bind("transactions"); - let requests_socket_pair = udp_public_bind("requests"); + let requests_socket = UdpSocket::bind("0.0.0.0:0").unwrap(); + let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap(); - requests_socket_pair - .receiver + requests_socket .set_read_timeout(Some(Duration::new(1, 0))) .unwrap(); ThinClient::new( r.requests_addr, - requests_socket_pair.sender, - requests_socket_pair.receiver, + requests_socket, r.transactions_addr, - transactions_socket_pair.sender, + transactions_socket, ) } diff --git a/src/bin/wallet.rs b/src/bin/wallet.rs index 6adc10a8a6f8f4..d290de898373e8 100644 --- a/src/bin/wallet.rs +++ b/src/bin/wallet.rs @@ -12,7 +12,6 @@ use clap::{App, Arg, SubCommand}; use solana::crdt::ReplicatedData; use solana::drone::DroneRequest; use solana::mint::Mint; -use solana::nat::udp_public_bind; use solana::signature::{PublicKey, Signature}; use solana::thin_client::ThinClient; use std::error; @@ -20,7 +19,7 @@ use std::fmt; use std::fs::File; use std::io; use std::io::prelude::*; -use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream}; +use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream, UdpSocket}; use std::process::exit; use std::thread::sleep; use std::time::Duration; @@ -288,19 +287,17 @@ fn read_mint(path: String) -> Result> { } fn mk_client(r: &ReplicatedData) -> io::Result { - let transactions_socket_pair = udp_public_bind("transactions"); - let requests_socket_pair = udp_public_bind("requests"); - requests_socket_pair - .receiver + let requests_socket = UdpSocket::bind("0.0.0.0:0").unwrap(); + let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap(); + requests_socket .set_read_timeout(Some(Duration::new(1, 0))) .unwrap(); Ok(ThinClient::new( r.requests_addr, - requests_socket_pair.sender, - requests_socket_pair.receiver, + requests_socket, r.transactions_addr, - transactions_socket_pair.sender, + transactions_socket, )) } diff --git a/src/drone.rs b/src/drone.rs index 53c673c024d7e7..edf10392cf6699 100644 --- a/src/drone.rs +++ b/src/drone.rs @@ -99,7 +99,6 @@ impl Drone { let mut client = ThinClient::new( self.requests_addr, - requests_socket.try_clone().unwrap(), requests_socket, self.transactions_addr, transactions_socket, @@ -293,7 +292,6 @@ mod tests { let mut client = ThinClient::new( leader.data.requests_addr, - requests_socket.try_clone().unwrap(), requests_socket, leader.data.transactions_addr, transactions_socket, diff --git a/src/thin_client.rs b/src/thin_client.rs index f24067cccd5278..bdc25ea1ed1ab9 100644 --- a/src/thin_client.rs +++ b/src/thin_client.rs @@ -15,8 +15,7 @@ use transaction::Transaction; /// An object for querying and sending transactions to the network. pub struct ThinClient { requests_addr: SocketAddr, - requests_sender: UdpSocket, - requests_receiver: UdpSocket, + requests_socket: UdpSocket, transactions_addr: SocketAddr, transactions_socket: UdpSocket, last_id: Option, @@ -31,15 +30,13 @@ impl ThinClient { /// to a public address before invoking ThinClient methods. pub fn new( requests_addr: SocketAddr, - requests_sender: UdpSocket, - requests_receiver: UdpSocket, + requests_socket: UdpSocket, transactions_addr: SocketAddr, transactions_socket: UdpSocket, ) -> Self { let client = ThinClient { requests_addr, - requests_sender, - requests_receiver, + requests_socket, transactions_addr, transactions_socket, last_id: None, @@ -53,7 +50,7 @@ impl ThinClient { pub fn recv_response(&self) -> io::Result { let mut buf = vec![0u8; 1024]; trace!("start recv_from"); - self.requests_receiver.recv_from(&mut buf)?; + self.requests_socket.recv_from(&mut buf)?; trace!("end recv_from"); let resp = deserialize(&buf).expect("deserialize balance in thin_client"); Ok(resp) @@ -115,7 +112,7 @@ impl ThinClient { trace!("get_balance"); let req = Request::GetBalance { key: *pubkey }; let data = serialize(&req).expect("serialize GetBalance in pub fn get_balance"); - self.requests_sender + self.requests_socket .send_to(&data, &self.requests_addr) .expect("buffer error in pub fn get_balance"); let mut done = false; @@ -139,7 +136,7 @@ impl ThinClient { serialize(&req).expect("serialize GetTransactionCount in pub fn transaction_count"); let mut done = false; while !done { - self.requests_sender + self.requests_socket .send_to(&data, &self.requests_addr) .expect("buffer error in pub fn transaction_count"); @@ -163,7 +160,7 @@ impl ThinClient { let mut done = false; while !done { debug!("get_last_id send_to {}", &self.requests_addr); - self.requests_sender + self.requests_socket .send_to(&data, &self.requests_addr) .expect("buffer error in pub fn get_last_id"); @@ -205,7 +202,7 @@ impl ThinClient { let data = serialize(&req).expect("serialize GetSignature in pub fn check_signature"); let mut done = false; while !done { - self.requests_sender + self.requests_socket .send_to(&data, &self.requests_addr) .expect("buffer error in pub fn get_last_id"); @@ -267,7 +264,6 @@ mod tests { let mut client = ThinClient::new( leader.data.requests_addr, - requests_socket.try_clone().unwrap(), requests_socket, leader.data.transactions_addr, transactions_socket, @@ -315,7 +311,6 @@ mod tests { let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap(); let mut client = ThinClient::new( leader.data.requests_addr, - requests_socket.try_clone().unwrap(), requests_socket, leader.data.transactions_addr, transactions_socket, @@ -374,7 +369,6 @@ mod tests { let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap(); let mut client = ThinClient::new( leader.data.requests_addr, - requests_socket.try_clone().unwrap(), requests_socket, leader.data.transactions_addr, transactions_socket, diff --git a/tests/multinode.rs b/tests/multinode.rs index bd2acc3a2c6196..9ef8916318eb84 100644 --- a/tests/multinode.rs +++ b/tests/multinode.rs @@ -246,7 +246,6 @@ fn mk_client(leader: &ReplicatedData) -> ThinClient { ThinClient::new( leader.requests_addr, - requests_socket.try_clone().unwrap(), requests_socket, leader.transactions_addr, transactions_socket, From bdad8fce490ab96247e972d34efe36cf57ff4ddc Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 2 Jul 2018 14:14:34 -0700 Subject: [PATCH 5/5] Add manual wallet sanity test --- multinode-demo/test/wallet-sanity.sh | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100755 multinode-demo/test/wallet-sanity.sh diff --git a/multinode-demo/test/wallet-sanity.sh b/multinode-demo/test/wallet-sanity.sh new file mode 100755 index 00000000000000..7656abad92bd95 --- /dev/null +++ b/multinode-demo/test/wallet-sanity.sh @@ -0,0 +1,35 @@ +#!/bin/bash -e +# +# Wallet sanity test +# + +here=$(dirname "$0") +cd "$here" + +wallet="../wallet.sh $1" + +# Tokens transferred to this address are lost forever... +garbage_address=vS3ngn1TfQmpsW1Z4NkLuqNAQFF3dYQw8UZ6TCx9bmq + +check_balance_output() { + declare expected_output="$1" + exec 42>&1 + output=$($wallet balance | tee >(cat - >&42)) + if [[ ! "$output" =~ $expected_output ]]; then + echo "Balance is incorrect. Expected: $expected_output" + exit 1 + fi +} + +# Ensure a fresh client configuration every time +rm -rf config-client + +$wallet address +check_balance_output "No account found! Request an airdrop to get started" +$wallet airdrop --tokens 100 +check_balance_output "Your balance is: 100" +$wallet pay --to $garbage_address --tokens 100 +check_balance_output "Your balance is: 0" + +echo PASS +exit 0