diff --git a/Cargo.lock b/Cargo.lock index 000a90994..96640e779 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2001,18 +2001,6 @@ dependencies = [ "solana-sdk 0.12.0", ] -[[package]] -name = "solana-jsonrpc-core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "solana-jsonrpc-core" version = "0.4.0" @@ -2025,19 +2013,6 @@ dependencies = [ "serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "solana-jsonrpc-http-server" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hyper 0.12.20 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-jsonrpc-core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-jsonrpc-server-utils 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "solana-jsonrpc-http-server" version = "0.4.0" @@ -2051,16 +2026,6 @@ dependencies = [ "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "solana-jsonrpc-macros" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-jsonrpc-core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-jsonrpc-pubsub 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "solana-jsonrpc-macros" version = "0.4.0" @@ -2071,16 +2036,6 @@ dependencies = [ "solana-jsonrpc-pubsub 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "solana-jsonrpc-pubsub" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-jsonrpc-core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "solana-jsonrpc-pubsub" version = "0.4.0" @@ -2091,22 +2046,6 @@ dependencies = [ "solana-jsonrpc-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "solana-jsonrpc-server-utils" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-jsonrpc-core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "solana-jsonrpc-server-utils" version = "0.4.0" @@ -2306,9 +2245,9 @@ dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-jsonrpc-core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-jsonrpc-http-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-jsonrpc-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-jsonrpc-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-jsonrpc-http-server 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-jsonrpc-macros 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "solana-metrics 0.12.0", "solana-sdk 0.12.0", ] @@ -2327,6 +2266,7 @@ dependencies = [ "solana-drone 0.12.0", "solana-logger 0.12.0", "solana-sdk 0.12.0", + "solana-vote-signer 0.12.0", ] [[package]] @@ -3122,15 +3062,10 @@ dependencies = [ "checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" "checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db" "checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7" -"checksum solana-jsonrpc-core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "247e9ed914dc7ce8c58bc7c9bb48a771d8a116f0609051a3dc1a600224ab4aa5" "checksum solana-jsonrpc-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3aef27e39614157ee2cc67296cba379b6209de8c82a3598f870f55577559979b" -"checksum solana-jsonrpc-http-server 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee59f62767d9711e86951a8a1a98771d6d710f620892aa26d425e0f39fbe2a5b" "checksum solana-jsonrpc-http-server 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e46cbb534bfac8c38e3e6e41133310819652b185367c8c530a63513aae8dbc6a" -"checksum solana-jsonrpc-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98ae0adfbe6fa32b77221a41a8ee069291b89d9589563d925e79db144cd8a511" "checksum solana-jsonrpc-macros 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df31df489ec11f5fab95423dc58b581fdc8363ebee781c89aa50722437f7c9bb" -"checksum solana-jsonrpc-pubsub 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70944e2d62a6af2b10ec7a99f2756f8002764fe9112d8292f1094b444e8a6e6a" "checksum solana-jsonrpc-pubsub 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a06b40e7885b7f8c21685e9dafe8c4da3276db20344eb4a50623f16e99853933" -"checksum solana-jsonrpc-server-utils 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "025a89986a6b9e633e0a837e667479a88fa085f413d2ce36ac970339defc9583" "checksum solana-jsonrpc-server-utils 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6acfebc12e709d8525f039e7135b922fb7efaf49cd536ad97bbedd0391dcf989" "checksum solana-jsonrpc-ws-server 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a21f3c0cd97c2673854b1e4558cea4dba59fce27ec9f0e130f847da9e10355c" "checksum solana-ws 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de774a72a468e65a10791246f0335869a19bed7d85ba3c05381c4bb6247acb7f" diff --git a/fullnode/src/main.rs b/fullnode/src/main.rs index bf2749426..e8847c556 100644 --- a/fullnode/src/main.rs +++ b/fullnode/src/main.rs @@ -11,7 +11,7 @@ use solana::local_vote_signer_service::LocalVoteSignerService; use solana::service::Service; use solana::socketaddr; use solana::thin_client::poll_gossip_for_leader; -use solana::vote_signer_proxy::VoteSignerProxy; +use solana::vote_signer_proxy::{RemoteVoteSigner, VoteSignerProxy}; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::vote_program::VoteProgram; use solana_sdk::vote_transaction::VoteTransaction; @@ -168,15 +168,15 @@ fn main() { }; let mut client = mk_client(&leader); - let vote_signer = VoteSignerProxy::new(&keypair, signer); - info!("New vote account ID is {:?}", vote_signer.vote_account); + let vote_signer = VoteSignerProxy::new(&keypair, Box::new(RemoteVoteSigner::new(signer))); + let vote_account = vote_signer.vote_account; + info!("New vote account ID is {:?}", vote_account); let mut fullnode = Fullnode::new( node, ledger_path, keypair.clone(), - &vote_signer.vote_account, - &signer, + Arc::new(vote_signer), network, nosigverify, leader_scheduler, @@ -194,11 +194,7 @@ fn main() { } // Create the vote account if necessary - if client - .poll_get_balance(&vote_signer.vote_account) - .unwrap_or(0) - == 0 - { + if client.poll_get_balance(&vote_account).unwrap_or(0) == 0 { // Need at least two tokens as one token will be spent on a vote_account_new() transaction if balance < 2 { error!("insufficient tokens, two tokens required"); @@ -209,21 +205,14 @@ fn main() { } loop { let last_id = client.get_last_id(); - let transaction = VoteTransaction::vote_account_new( - &keypair, - vote_signer.vote_account, - last_id, - 1, - 1, - ); + let transaction = + VoteTransaction::vote_account_new(&keypair, vote_account, last_id, 1, 1); if client.transfer_signed(&transaction).is_err() { sleep(Duration::from_secs(2)); continue; } - let balance = client - .poll_get_balance(&vote_signer.vote_account) - .unwrap_or(0); + let balance = client.poll_get_balance(&vote_account).unwrap_or(0); if balance > 0 { break; } @@ -232,7 +221,7 @@ fn main() { } loop { - let vote_account_user_data = client.get_account_userdata(&vote_signer.vote_account); + let vote_account_user_data = client.get_account_userdata(&vote_account); if let Ok(Some(vote_account_user_data)) = vote_account_user_data { if let Ok(vote_state) = VoteProgram::deserialize(&vote_account_user_data) { if vote_state.node_id == pubkey { diff --git a/src/compute_leader_confirmation_service.rs b/src/compute_leader_confirmation_service.rs index 3eb66b90a..b20de6888 100644 --- a/src/compute_leader_confirmation_service.rs +++ b/src/compute_leader_confirmation_service.rs @@ -159,12 +159,11 @@ pub mod tests { use crate::compute_leader_confirmation_service::ComputeLeaderConfirmationService; use crate::vote_signer_proxy::VoteSignerProxy; - use crate::local_vote_signer_service::LocalVoteSignerService; use crate::mint::Mint; - use crate::service::Service; use bincode::serialize; use solana_sdk::hash::hash; use solana_sdk::signature::{Keypair, KeypairUtil}; + use solana_vote_signer::rpc::LocalVoteSigner; use std::sync::Arc; use std::thread::sleep; use std::time::Duration; @@ -187,7 +186,6 @@ pub mod tests { }) .collect(); - let (signer_service, addr) = LocalVoteSignerService::new(); // Create a total of 10 vote accounts, each will have a balance of 1 (after giving 1 to // their vote account), for a total staking pool of 10 tokens. let vote_accounts: Vec<_> = (0..10) @@ -195,7 +193,8 @@ pub mod tests { // Create new validator to vote let validator_keypair = Arc::new(Keypair::new()); let last_id = ids[i]; - let vote_signer = VoteSignerProxy::new(&validator_keypair, addr.clone()); + let vote_signer = + VoteSignerProxy::new(&validator_keypair, Box::new(LocalVoteSigner::default())); // Give the validator some tokens bank.transfer(2, &mint.keypair(), validator_keypair.pubkey(), last_id) @@ -233,6 +232,5 @@ pub mod tests { ); assert!(bank.confirmation_time() != std::usize::MAX); assert!(last_confirmation_time > 0); - signer_service.join().unwrap(); } } diff --git a/src/fullnode.rs b/src/fullnode.rs index df6779f80..2e868f577 100644 --- a/src/fullnode.rs +++ b/src/fullnode.rs @@ -13,10 +13,10 @@ use crate::service::Service; use crate::tpu::{Tpu, TpuReturnType}; use crate::tpu_forwarder::TpuForwarder; use crate::tvu::{Sockets, Tvu, TvuReturnType}; +use crate::vote_signer_proxy::VoteSignerProxy; use crate::window::{new_window, SharedWindow}; use log::Level; use solana_sdk::hash::Hash; -use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::timing::timestamp; use std::net::UdpSocket; @@ -91,7 +91,6 @@ pub enum FullnodeReturnType { pub struct Fullnode { pub node_role: Option, keypair: Arc, - vote_account_id: Pubkey, exit: Arc, rpc_service: Option, rpc_pubsub_service: Option, @@ -108,8 +107,8 @@ pub struct Fullnode { rpc_addr: SocketAddr, rpc_pubsub_addr: SocketAddr, drone_addr: SocketAddr, - vote_signer_addr: SocketAddr, db_ledger: Arc, + vote_signer: Arc, } impl Fullnode { @@ -117,8 +116,7 @@ impl Fullnode { node: Node, ledger_path: &str, keypair: Arc, - vote_account_id: &Pubkey, - vote_signer_addr: &SocketAddr, + vote_signer: Arc, leader_addr: Option, sigverify_disabled: bool, leader_scheduler: LeaderScheduler, @@ -147,8 +145,7 @@ impl Fullnode { let leader_info = leader_addr.map(|i| NodeInfo::new_entry_point(&i)); let server = Self::new_with_bank( keypair, - vote_account_id, - vote_signer_addr, + vote_signer, bank, Some(db_ledger), entry_height, @@ -179,8 +176,7 @@ impl Fullnode { #[allow(clippy::too_many_arguments)] pub fn new_with_bank( keypair: Arc, - vote_account_id: &Pubkey, - vote_signer_addr: &SocketAddr, + vote_signer: Arc, bank: Bank, db_ledger: Option>, entry_height: u64, @@ -271,8 +267,7 @@ impl Fullnode { }; let tvu = Tvu::new( - vote_account_id, - vote_signer_addr, + &vote_signer, &bank, entry_height, *last_entry_id, @@ -335,7 +330,6 @@ impl Fullnode { Fullnode { keypair, - vote_account_id: *vote_account_id, cluster_info, shared_window, bank, @@ -353,8 +347,8 @@ impl Fullnode { rpc_addr, rpc_pubsub_addr, drone_addr, - vote_signer_addr: *vote_signer_addr, db_ledger, + vote_signer, } } @@ -437,8 +431,7 @@ impl Fullnode { }; let tvu = Tvu::new( - &self.vote_account_id, - &self.vote_signer_addr, + &self.vote_signer, &self.bank, entry_height, last_entry_id, @@ -658,15 +651,14 @@ mod tests { use crate::leader_scheduler::{ make_active_set_entries, LeaderScheduler, LeaderSchedulerConfig, }; - use crate::local_vote_signer_service::LocalVoteSignerService; use crate::service::Service; use crate::streamer::responder; use crate::vote_signer_proxy::VoteSignerProxy; use solana_sdk::signature::{Keypair, KeypairUtil}; + use solana_vote_signer::rpc::LocalVoteSigner; use std::cmp; use std::fs::remove_dir_all; use std::net::UdpSocket; - use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::mpsc::channel; use std::sync::{Arc, RwLock}; @@ -687,10 +679,11 @@ mod tests { bank.leader_scheduler = leader_scheduler; let last_id = bank.last_id(); + let keypair = Arc::new(keypair); + let signer = VoteSignerProxy::new(&keypair, Box::new(LocalVoteSigner::default())); let v = Fullnode::new_with_bank( - Arc::new(keypair), - &Keypair::new().pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + keypair, + Arc::new(signer), bank, None, entry_height, @@ -729,10 +722,11 @@ mod tests { let entry_height = mint.create_entries().len() as u64; let last_id = bank.last_id(); + let keypair = Arc::new(keypair); + let signer = VoteSignerProxy::new(&keypair, Box::new(LocalVoteSigner::default())); Fullnode::new_with_bank( - Arc::new(keypair), - &Keypair::new().pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + keypair, + Arc::new(signer), bank, None, entry_height, @@ -801,13 +795,17 @@ mod tests { Some(active_window_length), ); + let bootstrap_leader_keypair = Arc::new(bootstrap_leader_keypair); + let signer = VoteSignerProxy::new( + &bootstrap_leader_keypair, + Box::new(LocalVoteSigner::default()), + ); // Start up the leader let mut bootstrap_leader = Fullnode::new( bootstrap_leader_node, &bootstrap_leader_ledger_path, - Arc::new(bootstrap_leader_keypair), - &Keypair::new().pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + bootstrap_leader_keypair, + Arc::new(signer), Some(bootstrap_leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -860,10 +858,9 @@ mod tests { // Write the entries to the ledger that will cause leader rotation // after the bootstrap height - let (signer_service, signer) = LocalVoteSignerService::new(); + let validator_keypair = Arc::new(validator_keypair); let (active_set_entries, validator_vote_account_id) = make_active_set_entries( &validator_keypair, - signer, &mint.keypair(), &last_id, &last_id, @@ -912,14 +909,15 @@ mod tests { { // Test that a node knows to transition to a validator based on parsing the ledger - let vote_signer = VoteSignerProxy::new(&bootstrap_leader_keypair, signer); - let leader_vote_id = vote_signer.vote_account.clone(); + let vote_signer = VoteSignerProxy::new( + &bootstrap_leader_keypair, + Box::new(LocalVoteSigner::default()), + ); let bootstrap_leader = Fullnode::new( bootstrap_leader_node, &bootstrap_leader_ledger_path, bootstrap_leader_keypair, - &leader_vote_id, - &signer, + Arc::new(vote_signer), Some(bootstrap_leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -937,9 +935,8 @@ mod tests { let validator = Fullnode::new( validator_node, &validator_ledger_path, - Arc::new(validator_keypair), - &validator_vote_account_id, - &signer, + validator_keypair, + Arc::new(validator_vote_account_id), Some(bootstrap_leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -962,7 +959,6 @@ mod tests { DbLedger::destroy(&path).expect("Expected successful database destruction"); let _ignored = remove_dir_all(&path); } - signer_service.join().unwrap(); } #[test] @@ -992,6 +988,7 @@ mod tests { .expect("expected at least one genesis entry") .id; + let validator_keypair = Arc::new(validator_keypair); // Write two entries so that the validator is in the active set: // // 1) Give the validator a nonzero number of tokens @@ -999,15 +996,8 @@ mod tests { // after the bootstrap height // // 2) A vote from the validator - let (signer_service, signer) = LocalVoteSignerService::new(); - let (active_set_entries, _validator_vote_account_id) = make_active_set_entries( - &validator_keypair, - signer, - &mint.keypair(), - &last_id, - &last_id, - 0, - ); + let (active_set_entries, _validator_vote_account_id) = + make_active_set_entries(&validator_keypair, &mint.keypair(), &last_id, &last_id, 0); let initial_tick_height = genesis_entries .iter() .skip(2) @@ -1041,16 +1031,14 @@ mod tests { Some(bootstrap_height), ); - let validator_keypair = Arc::new(validator_keypair); - let vote_signer = VoteSignerProxy::new(&validator_keypair, signer); - let vote_id = vote_signer.vote_account.clone(); + let vote_signer = + VoteSignerProxy::new(&validator_keypair, Box::new(LocalVoteSigner::default())); // Start the validator let mut validator = Fullnode::new( validator_node, &validator_ledger_path, validator_keypair, - &vote_id, - &signer, + Arc::new(vote_signer), Some(leader_gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -1119,7 +1107,6 @@ mod tests { ); // Shut down - signer_service.join().unwrap(); t_responder.join().expect("responder thread join"); validator.close().unwrap(); DbLedger::destroy(&validator_ledger_path) diff --git a/src/leader_scheduler.rs b/src/leader_scheduler.rs index 220c0ddc4..d6f77aa26 100644 --- a/src/leader_scheduler.rs +++ b/src/leader_scheduler.rs @@ -4,7 +4,7 @@ use crate::bank::Bank; use crate::entry::{create_ticks, Entry}; -use crate::rpc_request::{RpcClient, RpcRequest}; +use crate::vote_signer_proxy::VoteSignerProxy; use bincode::serialize; use byteorder::{LittleEndian, ReadBytesExt}; use hashbrown::HashSet; @@ -15,8 +15,9 @@ use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::transaction::Transaction; use solana_sdk::vote_program::{self, Vote, VoteProgram}; use solana_sdk::vote_transaction::VoteTransaction; +use solana_vote_signer::rpc::LocalVoteSigner; use std::io::Cursor; -use std::net::SocketAddr; +use std::sync::Arc; pub const DEFAULT_BOOTSTRAP_HEIGHT: u64 = 1000; pub const DEFAULT_LEADER_ROTATION_INTERVAL: u64 = 100; @@ -480,13 +481,12 @@ impl Default for LeaderScheduler { // 1) Give the node a nonzero number of tokens, // 2) A vote from the validator pub fn make_active_set_entries( - active_keypair: &Keypair, - signer: SocketAddr, + active_keypair: &Arc, token_source: &Keypair, last_entry_id: &Hash, last_tick_id: &Hash, num_ending_ticks: usize, -) -> (Vec, Pubkey) { +) -> (Vec, VoteSignerProxy) { // 1) Create transfer token entry let transfer_tx = Transaction::system_new(&token_source, active_keypair.pubkey(), 3, *last_tick_id); @@ -494,16 +494,8 @@ pub fn make_active_set_entries( let mut last_entry_id = transfer_entry.id; // 2) Create and register the vote account - let rpc_client = RpcClient::new_from_socket(signer); - - let msg = "Registering a new node"; - let sig = Signature::new(&active_keypair.sign(msg.as_bytes()).as_ref()); - - let params = json!([active_keypair.pubkey(), sig, msg.as_bytes()]); - let resp = RpcRequest::RegisterNode - .retry_make_rpc_request(&rpc_client, 1, Some(params), 5) - .unwrap(); - let vote_account_id: Pubkey = serde_json::from_value(resp).unwrap(); + let vote_signer = VoteSignerProxy::new(active_keypair, Box::new(LocalVoteSigner::default())); + let vote_account_id: Pubkey = vote_signer.vote_account; let new_vote_account_tx = Transaction::vote_account_new(active_keypair, vote_account_id, *last_tick_id, 1, 1); @@ -530,7 +522,7 @@ pub fn make_active_set_entries( let mut txs = vec![transfer_entry, new_vote_account_entry, vote_entry]; let empty_ticks = create_ticks(num_ending_ticks, last_entry_id); txs.extend(empty_ticks); - (txs, vote_account_id) + (txs, vote_signer) } #[cfg(test)] @@ -540,14 +532,13 @@ mod tests { LeaderScheduler, LeaderSchedulerConfig, DEFAULT_BOOTSTRAP_HEIGHT, DEFAULT_LEADER_ROTATION_INTERVAL, DEFAULT_SEED_ROTATION_INTERVAL, }; - use crate::local_vote_signer_service::LocalVoteSignerService; use crate::mint::Mint; - use crate::service::Service; use crate::vote_signer_proxy::VoteSignerProxy; use hashbrown::HashSet; use solana_sdk::hash::Hash; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; + use solana_vote_signer::rpc::LocalVoteSigner; use std::hash::Hash as StdHash; use std::iter::FromIterator; use std::sync::Arc; @@ -599,11 +590,13 @@ mod tests { .last() .expect("Mint should not create empty genesis entries") .id; - let (signer_service, signer) = LocalVoteSignerService::new(); for i in 0..num_validators { let new_validator = Keypair::new(); let new_pubkey = new_validator.pubkey(); - let vote_signer = VoteSignerProxy::new(&Arc::new(new_validator), signer.clone()); + let vote_signer = VoteSignerProxy::new( + &Arc::new(new_validator), + Box::new(LocalVoteSigner::default()), + ); validators.push(new_pubkey); // Give the validator some tokens bank.transfer( @@ -697,7 +690,6 @@ mod tests { Some((current_leader, slot)) ); } - signer_service.join().unwrap(); } #[test] @@ -717,7 +709,6 @@ mod tests { let start_height = 3; let num_old_ids = 20; let mut old_ids = HashSet::new(); - let (signer_service, signer) = LocalVoteSignerService::new(); for _ in 0..num_old_ids { let new_keypair = Keypair::new(); let pk = new_keypair.pubkey(); @@ -728,7 +719,8 @@ mod tests { .unwrap(); // Create a vote account - let vote_signer = VoteSignerProxy::new(&Arc::new(new_keypair), signer); + let vote_signer = + VoteSignerProxy::new(&Arc::new(new_keypair), Box::new(LocalVoteSigner::default())); vote_signer .new_vote_account(&bank, 1 as u64, mint.last_id()) .unwrap(); @@ -749,7 +741,8 @@ mod tests { .unwrap(); // Create a vote account - let vote_signer = VoteSignerProxy::new(&Arc::new(new_keypair), signer); + let vote_signer = + VoteSignerProxy::new(&Arc::new(new_keypair), Box::new(LocalVoteSigner::default())); vote_signer .new_vote_account(&bank, 1 as u64, mint.last_id()) .unwrap(); @@ -777,7 +770,6 @@ mod tests { let result = leader_scheduler.get_active_set(2 * active_window_length + start_height, &bank); assert!(result.is_empty()); - signer_service.join().unwrap(); } #[test] @@ -1020,11 +1012,13 @@ mod tests { .last() .expect("Mint should not create empty genesis entries") .id; - let (signer_service, signer) = LocalVoteSignerService::new(); for i in 0..num_validators { let new_validator = Keypair::new(); let new_pubkey = new_validator.pubkey(); - let vote_signer = VoteSignerProxy::new(&Arc::new(new_validator), signer); + let vote_signer = VoteSignerProxy::new( + &Arc::new(new_validator), + Box::new(LocalVoteSigner::default()), + ); validators.push(new_pubkey); // Give the validator some tokens bank.transfer( @@ -1063,7 +1057,6 @@ mod tests { assert_eq!(vec![expected], *result); } - signer_service.join().unwrap(); } #[test] @@ -1084,8 +1077,10 @@ mod tests { // window let initial_vote_height = 1; - let (signer_service, signer) = LocalVoteSignerService::new(); - let vote_signer = VoteSignerProxy::new(&Arc::new(leader_keypair), signer); + let vote_signer = VoteSignerProxy::new( + &Arc::new(leader_keypair), + Box::new(LocalVoteSigner::default()), + ); // Create a vote account vote_signer .new_vote_account(&bank, 1 as u64, mint.last_id()) @@ -1101,7 +1096,6 @@ mod tests { let result = leader_scheduler.get_active_set(initial_vote_height + active_window_length + 1, &bank); assert!(result.is_empty()); - signer_service.join().unwrap(); } #[test] @@ -1222,12 +1216,14 @@ mod tests { // Create and add validator to the active set let validator_keypair = Keypair::new(); let validator_id = validator_keypair.pubkey(); - let (signer_service, signer) = LocalVoteSignerService::new(); if add_validator { bank.transfer(5, &mint.keypair(), validator_id, last_id) .unwrap(); // Create a vote account - let vote_signer = VoteSignerProxy::new(&Arc::new(validator_keypair), signer); + let vote_signer = VoteSignerProxy::new( + &Arc::new(validator_keypair), + Box::new(LocalVoteSigner::default()), + ); vote_signer .new_vote_account(&bank, 1 as u64, mint.last_id()) .unwrap(); @@ -1259,7 +1255,10 @@ mod tests { .unwrap(); // Create a vote account - let vote_signer = VoteSignerProxy::new(&Arc::new(bootstrap_leader_keypair), signer); + let vote_signer = VoteSignerProxy::new( + &Arc::new(bootstrap_leader_keypair), + Box::new(LocalVoteSigner::default()), + ); vote_signer .new_vote_account(&bank, vote_account_tokens as u64, mint.last_id()) .unwrap(); @@ -1276,7 +1275,6 @@ mod tests { } else { assert!(leader_scheduler.leader_schedule[0] == bootstrap_leader_id); } - signer_service.join().unwrap(); } #[test] @@ -1381,8 +1379,10 @@ mod tests { // Create a vote account for the validator bank.transfer(5, &mint.keypair(), validator_id, last_id) .unwrap(); - let (signer_service, signer) = LocalVoteSignerService::new(); - let vote_signer = VoteSignerProxy::new(&Arc::new(validator_keypair), signer); + let vote_signer = VoteSignerProxy::new( + &Arc::new(validator_keypair), + Box::new(LocalVoteSigner::default()), + ); vote_signer .new_vote_account(&bank, 1 as u64, mint.last_id()) .unwrap(); @@ -1391,7 +1391,10 @@ mod tests { // Create a vote account for the leader bank.transfer(5, &mint.keypair(), bootstrap_leader_id, last_id) .unwrap(); - let vote_signer = VoteSignerProxy::new(&Arc::new(bootstrap_leader_keypair), signer); + let vote_signer = VoteSignerProxy::new( + &Arc::new(bootstrap_leader_keypair), + Box::new(LocalVoteSigner::default()), + ); vote_signer .new_vote_account(&bank, 1 as u64, mint.last_id()) .unwrap(); @@ -1455,6 +1458,5 @@ mod tests { .max_height_for_leader(bootstrap_height + 2 * seed_rotation_interval + 1), None ); - signer_service.join().unwrap(); } } diff --git a/src/replay_stage.rs b/src/replay_stage.rs index bef38ad65..47c09a10c 100644 --- a/src/replay_stage.rs +++ b/src/replay_stage.rs @@ -14,10 +14,9 @@ use crate::streamer::{responder, BlobSender}; use crate::vote_signer_proxy::VoteSignerProxy; use log::Level; use solana_metrics::{influxdb, submit}; -use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::timing::duration_as_ms; -use std::net::{SocketAddr, UdpSocket}; +use std::net::UdpSocket; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::mpsc::channel; use std::sync::mpsc::RecvTimeoutError; @@ -65,8 +64,7 @@ impl ReplayStage { cluster_info: &Arc>, window_receiver: &EntryReceiver, keypair: &Arc, - _vote_account_id: &Pubkey, - vote_signer: &VoteSignerProxy, + vote_signer: &Arc, vote_blob_sender: Option<&BlobSender>, ledger_entry_sender: &EntrySender, entry_height: &mut u64, @@ -196,8 +194,7 @@ impl ReplayStage { #[allow(clippy::new_ret_no_self)] pub fn new( keypair: Arc, - vote_account_id: &Pubkey, - vote_signer_addr: &SocketAddr, + vote_signer: Arc, bank: Arc, cluster_info: Arc>, window_receiver: EntryReceiver, @@ -211,15 +208,12 @@ impl ReplayStage { let t_responder = responder("replay_stage", Arc::new(send), vote_blob_receiver); let keypair = Arc::new(keypair); - let vote_account_id = *vote_account_id; - let vote_signer_addr = *vote_signer_addr; let t_replay = Builder::new() .name("solana-replay-stage".to_string()) .spawn(move || { let _exit = Finalizer::new(exit); let mut entry_height_ = entry_height; let mut last_entry_id = last_entry_id; - let vote_signer = VoteSignerProxy::new(&keypair, vote_signer_addr); loop { let (leader_id, _) = bank .get_current_leader() @@ -242,7 +236,6 @@ impl ReplayStage { &cluster_info, &window_receiver, &keypair, - &vote_account_id, &vote_signer, Some(&vote_blob_sender), &ledger_entry_sender, @@ -292,7 +285,6 @@ mod test { make_active_set_entries, LeaderScheduler, LeaderSchedulerConfig, }; - use crate::local_vote_signer_service::LocalVoteSignerService; use crate::packet::BlobError; use crate::replay_stage::{ReplayStage, ReplayStageReturnType}; use crate::result::Error; @@ -300,6 +292,7 @@ mod test { use crate::vote_signer_proxy::VoteSignerProxy; use solana_sdk::hash::Hash; use solana_sdk::signature::{Keypair, KeypairUtil}; + use solana_vote_signer::rpc::LocalVoteSigner; use std::fs::remove_dir_all; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::channel; @@ -332,12 +325,12 @@ mod test { .expect("expected at least one genesis entry") .id; + let my_keypair = Arc::new(my_keypair); // Write two entries to the ledger so that the validator is in the active set: // 1) Give the validator a nonzero number of tokens 2) A vote from the validator . // This will cause leader rotation after the bootstrap height - let (signer_service, signer) = LocalVoteSignerService::new(); let (active_set_entries, vote_account_id) = - make_active_set_entries(&my_keypair, signer, &mint.keypair(), &last_id, &last_id, 0); + make_active_set_entries(&my_keypair, &mint.keypair(), &last_id, &last_id, 0); last_id = active_set_entries.last().unwrap().id; let initial_tick_height = genesis_entries .iter() @@ -381,9 +374,8 @@ mod test { let (entry_sender, entry_receiver) = channel(); let exit = Arc::new(AtomicBool::new(false)); let (replay_stage, ledger_writer_recv) = ReplayStage::new( - Arc::new(my_keypair), - &vote_account_id, - &signer, + my_keypair, + Arc::new(vote_account_id), Arc::new(bank), Arc::new(RwLock::new(cluster_info_me)), entry_receiver, @@ -434,8 +426,6 @@ mod test { &entries_to_send[..leader_rotation_index + 1] ); - signer_service.join().unwrap(); - assert_eq!(exit.load(Ordering::Relaxed), true); let _ignored = remove_dir_all(&my_ledger_path); @@ -471,17 +461,17 @@ mod test { let cluster_info_me = Arc::new(RwLock::new(ClusterInfo::new(my_node.info.clone()))); // Set up the replay stage - let (signer_service, signer) = LocalVoteSignerService::new(); let bank = Arc::new(bank); let (entry_sender, entry_receiver) = channel(); let exit = Arc::new(AtomicBool::new(false)); let my_keypair = Arc::new(my_keypair); - let vote_signer = VoteSignerProxy::new(&my_keypair, signer); - let vote_account_id = vote_signer.vote_account.clone(); + let vote_signer = Arc::new(VoteSignerProxy::new( + &my_keypair, + Box::new(LocalVoteSigner::default()), + )); let (replay_stage, ledger_writer_recv) = ReplayStage::new( my_keypair.clone(), - &vote_account_id, - &signer, + vote_signer.clone(), bank.clone(), cluster_info_me.clone(), entry_receiver, @@ -512,7 +502,6 @@ mod test { assert_eq!(next_tick, received_tick); drop(entry_sender); - signer_service.join().unwrap(); replay_stage .join() .expect("Expect successful ReplayStage exit"); @@ -543,12 +532,12 @@ mod test { .expect("expected at least one genesis entry") .id; + let my_keypair = Arc::new(my_keypair); // Write two entries to the ledger so that the validator is in the active set: // 1) Give the validator a nonzero number of tokens 2) A vote from the validator. // This will cause leader rotation after the bootstrap height - let (signer_service, signer) = LocalVoteSignerService::new(); let (active_set_entries, vote_account_id) = - make_active_set_entries(&my_keypair, signer, &mint.keypair(), &last_id, &last_id, 0); + make_active_set_entries(&my_keypair, &mint.keypair(), &last_id, &last_id, 0); last_id = active_set_entries.last().unwrap().id; let initial_tick_height = genesis_entries .iter() @@ -592,16 +581,13 @@ mod test { let cluster_info_me = Arc::new(RwLock::new(ClusterInfo::new(my_node.info.clone()))); // Set up the replay stage - let my_keypair = Arc::new(my_keypair); - let signer_proxy = VoteSignerProxy::new(&my_keypair, signer); - let vote_account_id = Arc::new(vote_account_id); + let signer_proxy = Arc::new(vote_account_id); let bank = Arc::new(bank); let (entry_sender, entry_receiver) = channel(); let exit = Arc::new(AtomicBool::new(false)); let (replay_stage, ledger_writer_recv) = ReplayStage::new( my_keypair.clone(), - &vote_account_id, - &signer, + signer_proxy.clone(), bank.clone(), cluster_info_me.clone(), entry_receiver, @@ -653,7 +639,6 @@ mod test { )), replay_stage.join().expect("replay stage join") ); - signer_service.join().unwrap(); assert_eq!(exit.load(Ordering::Relaxed), true); let _ignored = remove_dir_all(&my_ledger_path); } @@ -663,7 +648,6 @@ mod test { // Set up dummy node to host a ReplayStage let my_keypair = Keypair::new(); let my_id = my_keypair.pubkey(); - let vote_keypair = Keypair::new(); let my_node = Node::new_localhost_with_pubkey(my_id); // Set up the cluster info let cluster_info_me = Arc::new(RwLock::new(ClusterInfo::new(my_node.info.clone()))); @@ -694,14 +678,15 @@ mod test { .expect("Expected to err out"); let my_keypair = Arc::new(my_keypair); - let (signer_service, signer) = LocalVoteSignerService::new(); - let vote_signer = VoteSignerProxy::new(&my_keypair, signer); + let vote_signer = Arc::new(VoteSignerProxy::new( + &my_keypair, + Box::new(LocalVoteSigner::default()), + )); let res = ReplayStage::process_entries( &Arc::new(Bank::default()), &cluster_info_me, &entry_receiver, &my_keypair, - &vote_keypair.pubkey(), &vote_signer, None, &ledger_entry_sender, @@ -728,7 +713,6 @@ mod test { &cluster_info_me, &entry_receiver, &Arc::new(Keypair::new()), - &Keypair::new().pubkey(), &vote_signer, None, &ledger_entry_sender, @@ -745,7 +729,6 @@ mod test { e ), } - signer_service.join().unwrap(); let _ignored = remove_dir_all(&my_ledger_path); } } diff --git a/src/rpc.rs b/src/rpc.rs index 8a250d1e5..16db44f9e 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -411,6 +411,7 @@ mod tests { use crate::leader_scheduler::LeaderScheduler; use crate::mint::Mint; use crate::rpc_request::get_rpc_request_str; + use crate::vote_signer_proxy::VoteSignerProxy; use bincode::serialize; use reqwest; use reqwest::header::CONTENT_TYPE; @@ -418,6 +419,7 @@ mod tests { use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::transaction::Transaction; + use solana_vote_signer::rpc::LocalVoteSigner; use std::fs::remove_dir_all; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; @@ -686,11 +688,12 @@ mod tests { bank.leader_scheduler = leader_scheduler; let vote_account_keypair = Arc::new(Keypair::new()); + let vote_signer = + VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); let entry_height = alice.create_entries().len() as u64; let server = Fullnode::new_with_bank( leader_keypair, - &vote_account_keypair.pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(vote_signer), bank, None, entry_height, diff --git a/src/thin_client.rs b/src/thin_client.rs index 2ed0fef1e..63a7ee7b3 100644 --- a/src/thin_client.rs +++ b/src/thin_client.rs @@ -430,15 +430,15 @@ mod tests { use crate::db_ledger::create_tmp_ledger_with_mint; use crate::fullnode::Fullnode; use crate::leader_scheduler::LeaderScheduler; - use crate::mint::Mint; + use crate::vote_signer_proxy::VoteSignerProxy; use bincode::deserialize; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::vote_program::VoteProgram; use solana_sdk::vote_transaction::VoteTransaction; + use solana_vote_signer::rpc::LocalVoteSigner; use std::fs::remove_dir_all; - use std::net::{IpAddr, Ipv4Addr, SocketAddr}; #[test] fn test_thin_client() { @@ -458,11 +458,12 @@ mod tests { ))); bank.leader_scheduler = leader_scheduler; let vote_account_keypair = Arc::new(Keypair::new()); + let vote_signer = + VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); let last_id = bank.last_id(); let server = Fullnode::new_with_bank( leader_keypair, - &vote_account_keypair.pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(vote_signer), bank, None, entry_height, @@ -513,11 +514,12 @@ mod tests { ))); bank.leader_scheduler = leader_scheduler; let vote_account_keypair = Arc::new(Keypair::new()); + let vote_signer = + VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); let last_id = bank.last_id(); let server = Fullnode::new_with_bank( leader_keypair, - &vote_account_keypair.pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(vote_signer), bank, None, 0, @@ -572,12 +574,13 @@ mod tests { ))); bank.leader_scheduler = leader_scheduler; let vote_account_keypair = Arc::new(Keypair::new()); + let vote_signer = + VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); let entry_height = alice.create_entries().len() as u64; let last_id = bank.last_id(); let server = Fullnode::new_with_bank( leader_keypair, - &vote_account_keypair.pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(vote_signer), bank, None, entry_height, @@ -621,10 +624,13 @@ mod tests { ))); bank.leader_scheduler = leader_scheduler; let leader_vote_account_keypair = Arc::new(Keypair::new()); + let vote_signer = VoteSignerProxy::new( + &leader_vote_account_keypair, + Box::new(LocalVoteSigner::default()), + ); let server = Fullnode::new_with_bank( leader_keypair, - &leader_vote_account_keypair.pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(vote_signer), bank, None, entry_height, @@ -714,12 +720,13 @@ mod tests { ))); bank.leader_scheduler = leader_scheduler; let vote_account_keypair = Arc::new(Keypair::new()); + let vote_signer = + VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); let last_id = bank.last_id(); let entry_height = alice.create_entries().len() as u64; let server = Fullnode::new_with_bank( leader_keypair, - &vote_account_keypair.pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(vote_signer), bank, None, entry_height, diff --git a/src/tvu.rs b/src/tvu.rs index 419b21f20..7e0297475 100644 --- a/src/tvu.rs +++ b/src/tvu.rs @@ -20,10 +20,10 @@ use crate::replay_stage::{ReplayStage, ReplayStageReturnType}; use crate::retransmit_stage::RetransmitStage; use crate::service::Service; use crate::storage_stage::StorageStage; +use crate::vote_signer_proxy::VoteSignerProxy; use solana_sdk::hash::Hash; -use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::Keypair; -use std::net::{SocketAddr, UdpSocket}; +use std::net::UdpSocket; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, RwLock}; use std::thread; @@ -51,7 +51,6 @@ impl Tvu { /// This service receives messages from a leader in the network and processes the transactions /// on the bank state. /// # Arguments - /// * `vote_account_id` - Vote public key /// * `bank` - The bank state. /// * `entry_height` - Initial ledger height /// * `last_entry_id` - Hash of the last entry @@ -59,8 +58,7 @@ impl Tvu { /// * `sockets` - My fetch, repair, and restransmit sockets /// * `db_ledger` - the ledger itself pub fn new( - vote_account_id: &Pubkey, - vote_signer_addr: &SocketAddr, + vote_signer: &Arc, bank: &Arc, entry_height: u64, last_entry_id: Hash, @@ -105,8 +103,7 @@ impl Tvu { let (replay_stage, ledger_entry_receiver) = ReplayStage::new( keypair.clone(), - vote_account_id, - vote_signer_addr, + vote_signer.clone(), bank.clone(), cluster_info.clone(), blob_window_receiver, @@ -184,14 +181,15 @@ pub mod tests { use crate::service::Service; use crate::streamer; use crate::tvu::{Sockets, Tvu}; + use crate::vote_signer_proxy::VoteSignerProxy; use bincode::serialize; use solana_sdk::hash::Hash; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::transaction::Transaction; + use solana_vote_signer::rpc::LocalVoteSigner; use std::fs::remove_dir_all; use std::net::UdpSocket; - use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::channel; use std::sync::{Arc, RwLock}; @@ -265,14 +263,15 @@ pub mod tests { let cref1 = Arc::new(RwLock::new(cluster_info1)); let dr_1 = new_gossip(cref1.clone(), target1.sockets.gossip, exit.clone()); - let vote_account_id = Keypair::new().pubkey(); let mut cur_hash = Hash::default(); let db_ledger_path = get_tmp_ledger_path("test_replay"); let db_ledger = DbLedger::open(&db_ledger_path).expect("Expected to successfully open ledger"); + let vote_account_keypair = Arc::new(Keypair::new()); + let vote_signer = + VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); let tvu = Tvu::new( - &vote_account_id, - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + &Arc::new(vote_signer), &bank, 0, cur_hash, diff --git a/src/vote_signer_proxy.rs b/src/vote_signer_proxy.rs index 78909d1b4..a5f46c7ae 100644 --- a/src/vote_signer_proxy.rs +++ b/src/vote_signer_proxy.rs @@ -3,6 +3,7 @@ use crate::bank::Bank; use crate::cluster_info::ClusterInfo; use crate::counter::Counter; +use crate::jsonrpc_core; use crate::packet::SharedBlob; use crate::result::{Error, Result}; use crate::rpc_request::{RpcClient, RpcRequest}; @@ -15,6 +16,7 @@ use solana_sdk::signature::{Keypair, KeypairUtil, Signature}; use solana_sdk::transaction::Transaction; use solana_sdk::vote_program::Vote; use solana_sdk::vote_transaction::VoteTransaction; +use solana_vote_signer::rpc::VoteSigner; use std::net::SocketAddr; use std::sync::atomic::AtomicUsize; use std::sync::{Arc, RwLock}; @@ -26,27 +28,65 @@ pub enum VoteError { LeaderInfoNotFound, } -pub struct VoteSignerProxy { +pub struct RemoteVoteSigner { rpc_client: RpcClient, +} + +impl RemoteVoteSigner { + pub fn new(signer: SocketAddr) -> Self { + Self { + rpc_client: RpcClient::new_from_socket(signer), + } + } +} + +impl VoteSigner for RemoteVoteSigner { + fn register( + &self, + pubkey: Pubkey, + sig: &Signature, + msg: &[u8], + ) -> jsonrpc_core::Result { + let params = json!([pubkey, sig, msg]); + let resp = RpcRequest::RegisterNode + .retry_make_rpc_request(&self.rpc_client, 1, Some(params), 5) + .unwrap(); + let vote_account: Pubkey = serde_json::from_value(resp).unwrap(); + Ok(vote_account) + } + fn sign(&self, pubkey: Pubkey, sig: &Signature, msg: &[u8]) -> jsonrpc_core::Result { + let params = json!([pubkey, sig, msg]); + let resp = RpcRequest::SignVote + .make_rpc_request(&self.rpc_client, 1, Some(params)) + .unwrap(); + let vote_signature: Signature = serde_json::from_value(resp).unwrap(); + Ok(vote_signature) + } + fn deregister(&self, pubkey: Pubkey, sig: &Signature, msg: &[u8]) -> jsonrpc_core::Result<()> { + let params = json!([pubkey, sig, msg]); + let _resp = RpcRequest::DeregisterNode + .retry_make_rpc_request(&self.rpc_client, 1, Some(params), 5) + .unwrap(); + Ok(()) + } +} + +pub struct VoteSignerProxy { keypair: Arc, + signer: Box, pub vote_account: Pubkey, } impl VoteSignerProxy { - pub fn new(keypair: &Arc, signer: SocketAddr) -> Self { - let rpc_client = RpcClient::new_from_socket(signer); - + pub fn new(keypair: &Arc, signer: Box) -> Self { let msg = "Registering a new node"; let sig = Signature::new(&keypair.sign(msg.as_bytes()).as_ref()); - let params = json!([keypair.pubkey(), sig, msg.as_bytes()]); - let resp = RpcRequest::RegisterNode - .retry_make_rpc_request(&rpc_client, 1, Some(params), 5) + let vote_account = signer + .register(keypair.pubkey(), &sig, msg.as_bytes()) .unwrap(); - let vote_account: Pubkey = serde_json::from_value(resp).unwrap(); - Self { - rpc_client, keypair: keypair.clone(), + signer, vote_account, } } @@ -83,12 +123,7 @@ impl VoteSignerProxy { let sig = Signature::new(&self.keypair.sign(&msg).as_ref()); let keypair = self.keypair.clone(); - let params = json!([keypair.pubkey(), sig, &msg]); - let resp = RpcRequest::SignVote - .make_rpc_request(&self.rpc_client, 1, Some(params)) - .unwrap(); - let vote_signature: Signature = serde_json::from_value(resp).unwrap(); - + let vote_signature = self.signer.sign(keypair.pubkey(), &sig, &msg).unwrap(); Transaction { signatures: vec![vote_signature], account_keys: tx.account_keys, diff --git a/tests/multinode.rs b/tests/multinode.rs index 8f50ed93e..256df68bf 100644 --- a/tests/multinode.rs +++ b/tests/multinode.rs @@ -16,7 +16,6 @@ use solana::entry::{reconstruct_entries_from_blobs, Entry}; use solana::fullnode::{Fullnode, FullnodeReturnType}; use solana::gossip_service::GossipService; use solana::leader_scheduler::{make_active_set_entries, LeaderScheduler, LeaderSchedulerConfig}; -use solana::local_vote_signer_service::LocalVoteSignerService; use solana::mint::Mint; use solana::packet::SharedBlob; use solana::poh_service::NUM_TICKS_PER_SECOND; @@ -30,10 +29,10 @@ use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::timing::{duration_as_ms, duration_as_s}; use solana_sdk::transaction::Transaction; +use solana_vote_signer::rpc::LocalVoteSigner; use std::collections::{HashSet, VecDeque}; use std::env; use std::fs::remove_dir_all; -use std::net::SocketAddr; use std::net::UdpSocket; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, RwLock}; @@ -158,15 +157,12 @@ fn test_multi_node_ledger_window() -> result::Result<()> { .unwrap(); } - let (signer_service, signer) = LocalVoteSignerService::new(); - let signer_proxy = VoteSignerProxy::new(&leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let leader = Fullnode::new( leader, &leader_ledger_path, leader_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), None, false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -179,14 +175,12 @@ fn test_multi_node_ledger_window() -> result::Result<()> { let validator_pubkey = keypair.pubkey().clone(); let validator = Node::new_localhost_with_pubkey(keypair.pubkey()); let validator_data = validator.info.clone(); - let signer_proxy = VoteSignerProxy::new(&keypair, signer); - let validator_vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&keypair, Box::new(LocalVoteSigner::default())); let validator = Fullnode::new( validator, &zero_ledger_path, keypair, - &validator_vote_id, - &signer, + Arc::new(signer_proxy), Some(leader_data.gossip), false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -225,8 +219,6 @@ fn test_multi_node_ledger_window() -> result::Result<()> { validator.close()?; leader.close()?; - signer_service.join().unwrap(); - for path in ledger_paths { remove_dir_all(path).unwrap(); } @@ -261,15 +253,12 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> { ); ledger_paths.push(zero_ledger_path.clone()); - let (signer_service, signer) = LocalVoteSignerService::new(); - let signer_proxy = VoteSignerProxy::new(&leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let server = Fullnode::new( leader, &leader_ledger_path, leader_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), None, false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -293,14 +282,12 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> { .unwrap(); info!("validator balance {}", validator_balance); - let signer_proxy = VoteSignerProxy::new(&keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&keypair, Box::new(LocalVoteSigner::default())); let val = Fullnode::new( validator, &ledger_path, keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(leader_data.gossip), false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -334,14 +321,12 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> { // balances let keypair = Arc::new(Keypair::new()); let validator = Node::new_localhost_with_pubkey(keypair.pubkey()); - let signer_proxy = VoteSignerProxy::new(&keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&keypair, Box::new(LocalVoteSigner::default())); let val = Fullnode::new( validator, &zero_ledger_path, keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(leader_data.gossip), false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -384,8 +369,6 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> { node.close()?; } - signer_service.join().unwrap(); - for path in ledger_paths { remove_dir_all(path).unwrap(); } @@ -409,15 +392,12 @@ fn test_multi_node_basic() { let (alice, leader_ledger_path) = create_tmp_genesis("multi_node_basic", 10_000, leader_data.id, 500); ledger_paths.push(leader_ledger_path.clone()); - let (signer_service, signer) = LocalVoteSignerService::new(); - let signer_proxy = VoteSignerProxy::new(&leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let server = Fullnode::new( leader, &leader_ledger_path, leader_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), None, false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -437,14 +417,12 @@ fn test_multi_node_basic() { send_tx_and_retry_get_balance(&leader_data, &alice, &validator_pubkey, 500, None) .unwrap(); info!("validator balance {}", validator_balance); - let signer_proxy = VoteSignerProxy::new(&keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&keypair, Box::new(LocalVoteSigner::default())); let val = Fullnode::new( validator, &ledger_path, keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(leader_data.gossip), false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -475,7 +453,6 @@ fn test_multi_node_basic() { for node in nodes { node.close().unwrap(); } - signer_service.join().unwrap(); for path in ledger_paths { remove_dir_all(path).unwrap(); @@ -496,15 +473,12 @@ fn test_boot_validator_from_file() -> result::Result<()> { ledger_paths.push(leader_ledger_path.clone()); let leader_data = leader.info.clone(); - let (signer_service, signer) = LocalVoteSignerService::new(); - let signer_proxy = VoteSignerProxy::new(&leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let leader_fullnode = Fullnode::new( leader, &leader_ledger_path, leader_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), None, false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -522,14 +496,12 @@ fn test_boot_validator_from_file() -> result::Result<()> { let validator_data = validator.info.clone(); let ledger_path = tmp_copy_ledger(&leader_ledger_path, "boot_validator_from_file"); ledger_paths.push(ledger_path.clone()); - let signer_proxy = VoteSignerProxy::new(&keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&keypair, Box::new(LocalVoteSigner::default())); let val_fullnode = Fullnode::new( validator, &ledger_path, keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(leader_data.gossip), false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -541,7 +513,6 @@ fn test_boot_validator_from_file() -> result::Result<()> { val_fullnode.close()?; leader_fullnode.close()?; - signer_service.join().unwrap(); for path in ledger_paths { remove_dir_all(path)?; @@ -553,8 +524,7 @@ fn test_boot_validator_from_file() -> result::Result<()> { fn create_leader( ledger_path: &str, leader_keypair: Arc, - vote_id: &Pubkey, - signer: &SocketAddr, + signer: Arc, ) -> (NodeInfo, Fullnode) { let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); let leader_data = leader.info.clone(); @@ -562,8 +532,7 @@ fn create_leader( leader, &ledger_path, leader_keypair, - &vote_id, - &signer, + signer, None, false, LeaderScheduler::from_bootstrap_leader(leader_data.id), @@ -590,11 +559,12 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> { ); let bob_pubkey = Keypair::new().pubkey(); - let (signer_service, signer) = LocalVoteSignerService::new(); - let signer_proxy = VoteSignerProxy::new(&leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = Arc::new(VoteSignerProxy::new( + &leader_keypair, + Box::new(LocalVoteSigner::default()), + )); let (leader_data, leader_fullnode) = - create_leader(&ledger_path, leader_keypair.clone(), &vote_id, &signer); + create_leader(&ledger_path, leader_keypair.clone(), signer_proxy.clone()); // lengthen the ledger let leader_balance = @@ -610,7 +580,7 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> { // restart the leader leader_fullnode.close()?; let (leader_data, leader_fullnode) = - create_leader(&ledger_path, leader_keypair.clone(), &vote_id, &signer); + create_leader(&ledger_path, leader_keypair.clone(), signer_proxy.clone()); // lengthen the ledger let leader_balance = @@ -620,21 +590,19 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> { // restart the leader leader_fullnode.close()?; let (leader_data, leader_fullnode) = - create_leader(&ledger_path, leader_keypair, &vote_id, &signer); + create_leader(&ledger_path, leader_keypair, signer_proxy.clone()); // start validator from old ledger let keypair = Arc::new(Keypair::new()); let validator = Node::new_localhost_with_pubkey(keypair.pubkey()); let validator_data = validator.info.clone(); - let signer_proxy = VoteSignerProxy::new(&keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&keypair, Box::new(LocalVoteSigner::default())); let val_fullnode = Fullnode::new( validator, &stale_ledger_path, keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(leader_data.gossip), false, LeaderScheduler::from_bootstrap_leader(leader_data.id), @@ -664,7 +632,6 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> { val_fullnode.close()?; leader_fullnode.close()?; - signer_service.join().unwrap(); remove_dir_all(ledger_path)?; remove_dir_all(stale_ledger_path)?; @@ -698,15 +665,12 @@ fn test_multi_node_dynamic_network() { let alice_arc = Arc::new(RwLock::new(alice)); let leader_data = leader.info.clone(); - let (signer_service, signer) = LocalVoteSignerService::new(); - let signer_proxy = VoteSignerProxy::new(&leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let server = Fullnode::new( leader, &leader_ledger_path, leader_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), None, true, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -771,14 +735,13 @@ fn test_multi_node_dynamic_network() { let rd = validator.info.clone(); info!("starting {} {}", keypair.pubkey(), rd.id); let keypair = Arc::new(keypair); - let signer_proxy = VoteSignerProxy::new(&keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = + VoteSignerProxy::new(&keypair, Box::new(LocalVoteSigner::default())); let val = Fullnode::new( validator, &ledger_path, keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(leader_data.gossip), true, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -863,7 +826,6 @@ fn test_multi_node_dynamic_network() { } } - signer_service.join().unwrap(); assert_eq!(consecutive_success, 10); for (_, node) in &validators { node.exit(); @@ -885,7 +847,7 @@ fn test_leader_to_validator_transition() { let leader_rotation_interval = 20; // Make a dummy validator id to be the next leader - let validator_keypair = Keypair::new(); + let validator_keypair = Arc::new(Keypair::new()); // Create the leader node information let leader_keypair = Arc::new(Keypair::new()); @@ -910,15 +872,8 @@ fn test_leader_to_validator_transition() { // Write the bootstrap entries to the ledger that will cause leader rotation // after the bootstrap height - let (signer_service, signer) = LocalVoteSignerService::new(); - let (bootstrap_entries, _) = make_active_set_entries( - &validator_keypair, - signer, - &mint.keypair(), - &last_id, - &last_id, - 0, - ); + let (bootstrap_entries, _) = + make_active_set_entries(&validator_keypair, &mint.keypair(), &last_id, &last_id, 0); { let db_ledger = DbLedger::open(&leader_ledger_path).unwrap(); db_ledger @@ -939,14 +894,12 @@ fn test_leader_to_validator_transition() { Some(bootstrap_height), ); - let signer_proxy = VoteSignerProxy::new(&leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let mut leader = Fullnode::new( leader_node, &leader_ledger_path, leader_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -1022,7 +975,6 @@ fn test_leader_to_validator_transition() { ); assert_eq!(bank.tick_height(), bootstrap_height); - signer_service.join().unwrap(); remove_dir_all(leader_ledger_path).unwrap(); } @@ -1067,15 +1019,8 @@ fn test_leader_validator_basic() { // Write the bootstrap entries to the ledger that will cause leader rotation // after the bootstrap height - let (signer_service, signer) = LocalVoteSignerService::new(); - let (active_set_entries, _vote_account_keypair) = make_active_set_entries( - &validator_keypair, - signer, - &mint.keypair(), - &last_id, - &last_id, - 0, - ); + let (active_set_entries, _vote_account_keypair) = + make_active_set_entries(&validator_keypair, &mint.keypair(), &last_id, &last_id, 0); { let db_ledger = DbLedger::open(&leader_ledger_path).unwrap(); db_ledger @@ -1098,14 +1043,13 @@ fn test_leader_validator_basic() { ); // Start the validator node - let signer_proxy = VoteSignerProxy::new(&validator_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = + VoteSignerProxy::new(&validator_keypair, Box::new(LocalVoteSigner::default())); let mut validator = Fullnode::new( validator_node, &validator_ledger_path, validator_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -1113,14 +1057,12 @@ fn test_leader_validator_basic() { ); // Start the leader fullnode - let signer_proxy = VoteSignerProxy::new(&leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let mut leader = Fullnode::new( leader_node, &leader_ledger_path, leader_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -1189,7 +1131,6 @@ fn test_leader_validator_basic() { for (v, l) in validator_entries.iter().zip(leader_entries) { assert_eq!(*v, l); } - signer_service.join().unwrap(); for path in ledger_paths { DbLedger::destroy(&path).expect("Expected successful database destruction"); @@ -1262,15 +1203,8 @@ fn test_dropped_handoff_recovery() { // Make the entries to give the next_leader validator some stake so that they will be in // leader election active set - let (signer_service, signer) = LocalVoteSignerService::new(); - let (active_set_entries, _vote_account_keypair) = make_active_set_entries( - &next_leader_keypair, - signer, - &mint.keypair(), - &last_id, - &last_id, - 0, - ); + let (active_set_entries, _vote_account_keypair) = + make_active_set_entries(&next_leader_keypair, &mint.keypair(), &last_id, &last_id, 0); // Write the entries { @@ -1306,15 +1240,16 @@ fn test_dropped_handoff_recovery() { Some(leader_rotation_interval), ); - let signer_proxy = VoteSignerProxy::new(&bootstrap_leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new( + &bootstrap_leader_keypair, + Box::new(LocalVoteSigner::default()), + ); // Start up the bootstrap leader fullnode let bootstrap_leader = Fullnode::new( bootstrap_leader_node, &bootstrap_leader_ledger_path, bootstrap_leader_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(bootstrap_leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -1333,14 +1268,12 @@ fn test_dropped_handoff_recovery() { ledger_paths.push(validator_ledger_path.clone()); let validator_id = kp.pubkey(); let validator_node = Node::new_localhost_with_pubkey(validator_id); - let signer_proxy = VoteSignerProxy::new(&kp, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&kp, Box::new(LocalVoteSigner::default())); let validator = Fullnode::new( validator_node, &validator_ledger_path, kp, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(bootstrap_leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -1362,14 +1295,13 @@ fn test_dropped_handoff_recovery() { // Now start up the "next leader" node let next_leader_node = Node::new_localhost_with_pubkey(next_leader_keypair.pubkey()); - let signer_proxy = VoteSignerProxy::new(&next_leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = + VoteSignerProxy::new(&next_leader_keypair, Box::new(LocalVoteSigner::default())); let mut next_leader = Fullnode::new( next_leader_node, &next_leader_ledger_path, next_leader_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(bootstrap_leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -1384,7 +1316,6 @@ fn test_dropped_handoff_recovery() { nodes.push(next_leader); - signer_service.join().unwrap(); for node in nodes { node.close().unwrap(); } @@ -1409,11 +1340,11 @@ fn test_full_leader_validator_network() { let bootstrap_leader_info = bootstrap_leader_node.info.clone(); let mut node_keypairs = VecDeque::new(); - node_keypairs.push_back(bootstrap_leader_keypair); + node_keypairs.push_back(Arc::new(bootstrap_leader_keypair)); // Create the validator keypairs for _ in 0..N { - let validator_keypair = Keypair::new(); + let validator_keypair = Arc::new(Keypair::new()); node_keypairs.push_back(validator_keypair); } @@ -1445,14 +1376,12 @@ fn test_full_leader_validator_network() { let mut ledger_paths = Vec::new(); ledger_paths.push(bootstrap_leader_ledger_path.clone()); - let (signer_service, signer) = LocalVoteSignerService::new(); let mut vote_account_keypairs = VecDeque::new(); for node_keypair in node_keypairs.iter() { // Make entries to give each node some stake so that they will be in the // leader election active set let (bootstrap_entries, vote_account_keypair) = make_active_set_entries( node_keypair, - signer, &mint.keypair(), &last_entry_id, &last_tick_id, @@ -1514,15 +1443,12 @@ fn test_full_leader_validator_network() { let validator_id = kp.pubkey(); let validator_node = Node::new_localhost_with_pubkey(validator_id); - let kp = Arc::new(kp); - let signer_proxy = VoteSignerProxy::new(&kp, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&kp, Box::new(LocalVoteSigner::default())); let validator = Arc::new(RwLock::new(Fullnode::new( validator_node, &validator_ledger_path, - kp, - &vote_id, - &signer, + kp.clone(), + Arc::new(signer_proxy), Some(bootstrap_leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -1534,15 +1460,12 @@ fn test_full_leader_validator_network() { } // Start up the bootstrap leader - let leader_keypair = Arc::new(leader_keypair); - let signer_proxy = VoteSignerProxy::new(&leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let bootstrap_leader = Arc::new(RwLock::new(Fullnode::new( bootstrap_leader_node, &bootstrap_leader_ledger_path, - leader_keypair, - &vote_id, - &signer, + leader_keypair.clone(), + Arc::new(signer_proxy), Some(bootstrap_leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -1656,7 +1579,6 @@ fn test_full_leader_validator_network() { assert!(shortest.unwrap() >= target_height); - signer_service.join().unwrap(); for path in ledger_paths { DbLedger::destroy(&path).expect("Expected successful database destruction"); remove_dir_all(path).unwrap(); @@ -1720,15 +1642,15 @@ fn test_broadcast_last_tick() { // Start up the bootstrap leader fullnode let bootstrap_leader_keypair = Arc::new(bootstrap_leader_keypair); - let (signer_service, signer) = LocalVoteSignerService::new(); - let signer_proxy = VoteSignerProxy::new(&bootstrap_leader_keypair, signer); - let vote_id = signer_proxy.vote_account.clone(); + let signer_proxy = VoteSignerProxy::new( + &bootstrap_leader_keypair, + Box::new(LocalVoteSigner::default()), + ); let mut bootstrap_leader = Fullnode::new( bootstrap_leader_node, &bootstrap_leader_ledger_path, bootstrap_leader_keypair, - &vote_id, - &signer, + Arc::new(signer_proxy), Some(bootstrap_leader_info.gossip), false, LeaderScheduler::new(&leader_scheduler_config), @@ -1778,7 +1700,6 @@ fn test_broadcast_last_tick() { bf.join().unwrap(); } - signer_service.join().unwrap(); // Shut down the listeners for node in listening_nodes { node.0.close().unwrap(); diff --git a/tests/replicator.rs b/tests/replicator.rs index e2e5f4e6d..8b9389e28 100644 --- a/tests/replicator.rs +++ b/tests/replicator.rs @@ -13,14 +13,13 @@ use solana::db_ledger::{create_tmp_genesis, get_tmp_ledger_path, tmp_copy_ledger use solana::entry::Entry; use solana::fullnode::Fullnode; use solana::leader_scheduler::LeaderScheduler; -use solana::local_vote_signer_service::LocalVoteSignerService; use solana::replicator::Replicator; -use solana::service::Service; use solana::streamer::blob_receiver; use solana::vote_signer_proxy::VoteSignerProxy; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::transaction::Transaction; +use solana_vote_signer::rpc::LocalVoteSigner; use std::fs::remove_dir_all; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::channel; @@ -45,16 +44,14 @@ fn test_replicator_startup() { tmp_copy_ledger(&leader_ledger_path, "replicator_test_validator_ledger"); { - let (signer_service, signer) = LocalVoteSignerService::new(); - let signer_proxy = VoteSignerProxy::new(&leader_keypair, signer); - let vote_account_id = signer_proxy.vote_account.clone(); + let signer_proxy = + VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let leader = Fullnode::new( leader_node, &leader_ledger_path, leader_keypair, - &vote_account_id, - &signer, + Arc::new(signer_proxy), None, false, LeaderScheduler::from_bootstrap_leader(leader_info.id.clone()), @@ -62,8 +59,8 @@ fn test_replicator_startup() { ); let validator_keypair = Arc::new(Keypair::new()); - let signer_proxy = VoteSignerProxy::new(&validator_keypair, signer); - let vote_account_id = signer_proxy.vote_account.clone(); + let signer_proxy = + VoteSignerProxy::new(&validator_keypair, Box::new(LocalVoteSigner::default())); let validator_node = Node::new_localhost_with_pubkey(validator_keypair.pubkey()); #[cfg(feature = "chacha")] let validator_node_info = validator_node.info.clone(); @@ -72,8 +69,7 @@ fn test_replicator_startup() { validator_node, &validator_ledger_path, validator_keypair, - &vote_account_id, - &signer, + Arc::new(signer_proxy), Some(leader_info.gossip), false, LeaderScheduler::from_bootstrap_leader(leader_info.id), @@ -182,7 +178,6 @@ fn test_replicator_startup() { // Check that some ledger was downloaded assert!(num_txs != 0); - signer_service.join().unwrap(); replicator.close(); validator.exit(); diff --git a/vote-signer/Cargo.toml b/vote-signer/Cargo.toml index 390f218f1..d32b32def 100644 --- a/vote-signer/Cargo.toml +++ b/vote-signer/Cargo.toml @@ -14,9 +14,9 @@ log = "0.4.2" serde_json = "1.0.34" solana-sdk = { path = "../sdk", version = "0.12.0" } solana-metrics = { path = "../metrics", version = "0.12.0" } -solana-jsonrpc-core = "0.3.0" -solana-jsonrpc-http-server = "0.3.0" -solana-jsonrpc-macros = "0.3.0" +solana-jsonrpc-core = "0.4.0" +solana-jsonrpc-http-server = "0.4.0" +solana-jsonrpc-macros = "0.4.0" [lib] name = "solana_vote_signer" diff --git a/vote-signer/src/rpc.rs b/vote-signer/src/rpc.rs index 11655343a..40245afd2 100644 --- a/vote-signer/src/rpc.rs +++ b/vote-signer/src/rpc.rs @@ -18,7 +18,7 @@ pub struct VoteSignerRpcService { impl VoteSignerRpcService { pub fn new(rpc_addr: SocketAddr, exit: Arc) -> Self { - let request_processor = VoteSignRequestProcessor::default(); + let request_processor = LocalVoteSigner::default(); let exit_ = exit.clone(); let thread_hdl = Builder::new() .name("solana-vote-signer-jsonrpc".to_string()) @@ -64,7 +64,7 @@ impl VoteSignerRpcService { #[derive(Clone)] pub struct Meta { - pub request_processor: VoteSignRequestProcessor, + pub request_processor: LocalVoteSigner, } impl Metadata for Meta {} @@ -95,8 +95,7 @@ impl VoteSignerRpc for VoteSignerRpcImpl { signed_msg: Vec, ) -> Result { info!("register rpc request received: {:?}", id); - verify_signature(&sig, &id, &signed_msg)?; - meta.request_processor.register(id) + meta.request_processor.register(id, &sig, &signed_msg) } fn sign( @@ -107,8 +106,7 @@ impl VoteSignerRpc for VoteSignerRpcImpl { signed_msg: Vec, ) -> Result { info!("sign rpc request received: {:?}", id); - verify_signature(&sig, &id, &signed_msg)?; - meta.request_processor.sign(id, &signed_msg) + meta.request_processor.sign(id, &sig, &signed_msg) } fn deregister( @@ -119,8 +117,7 @@ impl VoteSignerRpc for VoteSignerRpcImpl { signed_msg: Vec, ) -> Result<()> { info!("deregister rpc request received: {:?}", id); - verify_signature(&sig, &id, &signed_msg)?; - meta.request_processor.deregister(id) + meta.request_processor.deregister(id, &sig, &signed_msg) } } @@ -132,13 +129,20 @@ fn verify_signature(sig: &Signature, pubkey: &Pubkey, msg: &[u8]) -> Result<()> } } +pub trait VoteSigner { + fn register(&self, pubkey: Pubkey, sig: &Signature, signed_msg: &[u8]) -> Result; + fn sign(&self, pubkey: Pubkey, sig: &Signature, msg: &[u8]) -> Result; + fn deregister(&self, pubkey: Pubkey, sig: &Signature, msg: &[u8]) -> Result<()>; +} + #[derive(Clone)] -pub struct VoteSignRequestProcessor { +pub struct LocalVoteSigner { nodes: Arc>>, } -impl VoteSignRequestProcessor { +impl VoteSigner for LocalVoteSigner { /// Process JSON-RPC request items sent via JSON-RPC. - pub fn register(&self, pubkey: Pubkey) -> Result { + fn register(&self, pubkey: Pubkey, sig: &Signature, msg: &[u8]) -> Result { + verify_signature(&sig, &pubkey, &msg)?; { if let Some(voting_keypair) = self.nodes.read().unwrap().get(&pubkey) { return Ok(voting_keypair.pubkey()); @@ -148,9 +152,9 @@ impl VoteSignRequestProcessor { let voting_pubkey = voting_keypair.pubkey(); self.nodes.write().unwrap().insert(pubkey, voting_keypair); Ok(voting_pubkey) - //Ok(bs58::encode(voting_pubkey).into_string()) } - pub fn sign(&self, pubkey: Pubkey, msg: &[u8]) -> Result { + fn sign(&self, pubkey: Pubkey, sig: &Signature, msg: &[u8]) -> Result { + verify_signature(&sig, &pubkey, &msg)?; match self.nodes.read().unwrap().get(&pubkey) { Some(voting_keypair) => { let sig = Signature::new(&voting_keypair.sign(&msg).as_ref()); @@ -159,15 +163,16 @@ impl VoteSignRequestProcessor { None => Err(Error::invalid_request()), } } - pub fn deregister(&self, pubkey: Pubkey) -> Result<()> { + fn deregister(&self, pubkey: Pubkey, sig: &Signature, msg: &[u8]) -> Result<()> { + verify_signature(&sig, &pubkey, &msg)?; self.nodes.write().unwrap().remove(&pubkey); Ok(()) } } -impl Default for VoteSignRequestProcessor { +impl Default for LocalVoteSigner { fn default() -> Self { - VoteSignRequestProcessor { + LocalVoteSigner { nodes: Arc::new(RwLock::new(HashMap::new())), } } @@ -181,7 +186,7 @@ mod tests { use std::mem; fn start_rpc_handler() -> (MetaIoHandler, Meta) { - let request_processor = VoteSignRequestProcessor::default(); + let request_processor = LocalVoteSigner::default(); let mut io = MetaIoHandler::default(); let rpc = VoteSignerRpcImpl; io.extend_with(rpc.to_delegate()); diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml index c33cfa4c9..beba19b19 100644 --- a/wallet/Cargo.toml +++ b/wallet/Cargo.toml @@ -19,6 +19,7 @@ solana = { path = "..", version = "0.12.0" } solana-drone = { path = "../drone", version = "0.12.0" } solana-logger = { path = "../logger", version = "0.12.0" } solana-sdk = { path = "../sdk", version = "0.12.0" } +solana-vote-signer = { path = "../vote-signer", version = "0.12.0" } [features] cuda = [] diff --git a/wallet/src/wallet.rs b/wallet/src/wallet.rs index d12563d37..75c0a2e1a 100644 --- a/wallet/src/wallet.rs +++ b/wallet/src/wallet.rs @@ -816,11 +816,12 @@ mod tests { use solana::db_ledger::create_tmp_genesis; use solana::fullnode::Fullnode; use solana::leader_scheduler::LeaderScheduler; + use solana::vote_signer_proxy::VoteSignerProxy; use solana_drone::drone::run_local_drone; use solana_sdk::signature::{gen_keypair_file, read_keypair, read_pkcs8, Keypair, KeypairUtil}; + use solana_vote_signer::rpc::LocalVoteSigner; use std::fs; use std::fs::remove_dir_all; - use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::path::Path; use std::sync::mpsc::channel; use std::sync::{Arc, RwLock}; @@ -835,12 +836,12 @@ mod tests { let leader_data = leader.info.clone(); let (_alice, ledger_path) = create_tmp_genesis("wallet_request_airdrop", 10_000_000, leader_data.id, 1000); + let signer = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let _server = Fullnode::new( leader, &ledger_path, leader_keypair, - &leader_pubkey, - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(signer), None, false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -1203,12 +1204,12 @@ mod tests { let leader_data = leader.info.clone(); let (alice, ledger_path) = create_tmp_genesis("wallet_process_command", 10_000_000, leader_data.id, 1000); + let signer = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let server = Fullnode::new( leader, &ledger_path, leader_keypair, - &leader_pubkey, - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(signer), None, false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -1264,12 +1265,12 @@ mod tests { let leader_data = leader.info.clone(); let (alice, ledger_path) = create_tmp_genesis("wallet_request_airdrop", 10_000_000, leader_data.id, 1000); + let signer = VoteSignerProxy::new(&leader_keypair, Box::new(LocalVoteSigner::default())); let server = Fullnode::new( leader, &ledger_path, leader_keypair, - &leader_pubkey, - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(signer), None, false, LeaderScheduler::from_bootstrap_leader(leader_pubkey), @@ -1343,10 +1344,11 @@ mod tests { bank.leader_scheduler = leader_scheduler; let vote_account_keypair = Arc::new(Keypair::new()); let last_id = bank.last_id(); + let signer = + VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); let server = Fullnode::new_with_bank( leader_keypair, - &vote_account_keypair.pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(signer), bank, None, 0, @@ -1470,10 +1472,11 @@ mod tests { bank.leader_scheduler = leader_scheduler; let vote_account_keypair = Arc::new(Keypair::new()); let last_id = bank.last_id(); + let signer = + VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); let server = Fullnode::new_with_bank( leader_keypair, - &vote_account_keypair.pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(signer), bank, None, 0, @@ -1586,10 +1589,11 @@ mod tests { bank.leader_scheduler = leader_scheduler; let vote_account_keypair = Arc::new(Keypair::new()); let last_id = bank.last_id(); + let signer = + VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); let server = Fullnode::new_with_bank( leader_keypair, - &vote_account_keypair.pubkey(), - &SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0), + Arc::new(signer), bank, None, 0,