Use vote signer service in fullnode (#2009)

* Use vote signer service in fullnode

* Use native types for signature and pubkey, and address other review comments

* Start local vote signer if a remote service address is not provided

* Rebased to master

* Fixes after rebase
This commit is contained in:
Pankaj Garg
2019-01-05 12:57:52 -08:00
committed by GitHub
parent 71a2b794b4
commit 91bd38504e
23 changed files with 774 additions and 227 deletions

View File

@@ -1,12 +1,19 @@
#[macro_use]
extern crate serde_json;
use clap::{crate_version, App, Arg};
use log::*;
use solana::client::mk_client;
use solana::cluster_info::{Node, NodeInfo, FULLNODE_PORT_RANGE};
use solana::create_vote_account;
use solana::fullnode::{Fullnode, FullnodeReturnType};
use solana::leader_scheduler::LeaderScheduler;
use solana::rpc_request::{RpcClient, RpcRequest};
use solana::socketaddr;
use solana::thin_client::poll_gossip_for_leader;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
use solana_sdk::vote_program::VoteProgram;
use solana_sdk::vote_transaction::VoteTransaction;
use std::fs::File;
@@ -16,6 +23,7 @@ use std::sync::Arc;
use std::thread::sleep;
use std::time::Duration;
#[allow(clippy::cyclomatic_complexity)]
fn main() {
solana_logger::setup();
solana_metrics::set_panic_hook("fullnode");
@@ -48,6 +56,14 @@ fn main() {
.takes_value(true)
.help("Rendezvous with the network at this gossip entry point"),
)
.arg(
Arg::with_name("signer")
.short("s")
.long("signer")
.value_name("HOST:PORT")
.takes_value(true)
.help("Rendezvous with the vote signer at this RPC end point"),
)
.arg(
Arg::with_name("ledger")
.short("l")
@@ -69,7 +85,7 @@ fn main() {
let nosigverify = matches.is_present("nosigverify");
let use_only_bootstrap_leader = matches.is_present("no-leader-rotation");
let (keypair, vote_account_keypair, gossip) = if let Some(i) = matches.value_of("identity") {
let (keypair, _vote_account_keypair, gossip) = if let Some(i) = matches.value_of("identity") {
let path = i.to_string();
if let Ok(file) = File::open(path.clone()) {
let parse: serde_json::Result<solana_fullnode_config::Config> =
@@ -106,13 +122,35 @@ fn main() {
.value_of("network")
.map(|network| network.parse().expect("failed to parse network address"));
let (signer, t_signer, signer_exit) = if let Some(signer_addr) = matches.value_of("signer") {
(
signer_addr.to_string().parse().expect("Signer IP Address"),
None,
None,
)
} else {
// If a remote vote-signer service is not provided, run a local instance
let (signer, t_signer, signer_exit) = create_vote_account::local_vote_signer_service()
.expect("Failed to start vote signer service");
(signer, Some(t_signer), Some(signer_exit))
};
let node = Node::new_with_external_ip(keypair.pubkey(), &gossip);
// save off some stuff for airdrop
let mut node_info = node.info.clone();
let vote_account_keypair = Arc::new(vote_account_keypair);
let vote_account_id = vote_account_keypair.pubkey();
let rpc_client = RpcClient::new_from_socket(signer);
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
.make_rpc_request(&rpc_client, 1, Some(params))
.unwrap();
let vote_account_id: Pubkey = serde_json::from_value(resp).unwrap();
info!("New vote account ID is {:?}", vote_account_id);
let keypair = Arc::new(keypair);
let pubkey = keypair.pubkey();
@@ -125,6 +163,11 @@ fn main() {
let port_number = port.to_string().parse().expect("integer");
if port_number == 0 {
eprintln!("Invalid RPC port requested: {:?}", port);
if let Some(t) = t_signer {
if let Some(exit) = signer_exit {
create_vote_account::stop_local_vote_signer_service(t, &exit);
}
}
exit(1);
}
Some(port_number)
@@ -153,7 +196,8 @@ fn main() {
node,
ledger_path,
keypair.clone(),
vote_account_keypair.clone(),
&vote_account_id,
&signer,
network,
nosigverify,
leader_scheduler,
@@ -165,6 +209,11 @@ fn main() {
info!("balance is {}", balance);
if balance < 1 {
error!("insufficient tokens");
if let Some(t) = t_signer {
if let Some(exit) = signer_exit {
create_vote_account::stop_local_vote_signer_service(t, &exit);
}
}
exit(1);
}
@@ -173,6 +222,11 @@ fn main() {
// Need at least two tokens as one token will be spent on a vote_account_new() transaction
if balance < 2 {
error!("insufficient tokens");
if let Some(t) = t_signer {
if let Some(exit) = signer_exit {
create_vote_account::stop_local_vote_signer_service(t, &exit);
}
}
exit(1);
}
loop {
@@ -212,6 +266,11 @@ fn main() {
_ => {
// Fullnode tpu/tvu exited for some unexpected
// reason, so exit
if let Some(t) = t_signer {
if let Some(exit) = signer_exit {
create_vote_account::stop_local_vote_signer_service(t, &exit);
}
}
exit(1);
}
}