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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user