2019-03-02 10:25:16 -08:00
|
|
|
//! The `vote_signer_proxy` votes on the `blockhash` of the bank at a regular cadence
|
2019-01-10 09:21:38 -08:00
|
|
|
|
2019-02-04 16:41:03 -08:00
|
|
|
use jsonrpc_core;
|
2019-03-16 22:37:20 -07:00
|
|
|
use solana_client::rpc_client::RpcClient;
|
|
|
|
use solana_client::rpc_request::RpcRequest;
|
2019-01-10 09:21:38 -08:00
|
|
|
use solana_sdk::pubkey::Pubkey;
|
|
|
|
use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
|
2019-01-25 18:47:05 -08:00
|
|
|
use solana_vote_signer::rpc::LocalVoteSigner;
|
2019-01-11 12:58:31 -08:00
|
|
|
use solana_vote_signer::rpc::VoteSigner;
|
2019-01-10 09:21:38 -08:00
|
|
|
use std::net::SocketAddr;
|
2019-01-31 15:51:29 -08:00
|
|
|
use std::sync::Arc;
|
2019-01-10 09:21:38 -08:00
|
|
|
|
2019-01-11 12:58:31 -08:00
|
|
|
pub struct RemoteVoteSigner {
|
2019-01-10 09:21:38 -08:00
|
|
|
rpc_client: RpcClient,
|
2019-01-11 12:58:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl RemoteVoteSigner {
|
|
|
|
pub fn new(signer: SocketAddr) -> Self {
|
2019-03-15 22:42:36 -07:00
|
|
|
let rpc_client = RpcClient::new_socket(signer);
|
2019-01-31 19:53:48 -08:00
|
|
|
Self { rpc_client }
|
2019-01-11 12:58:31 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl VoteSigner for RemoteVoteSigner {
|
|
|
|
fn register(
|
|
|
|
&self,
|
2019-03-09 19:28:43 -08:00
|
|
|
pubkey: &Pubkey,
|
2019-01-11 12:58:31 -08:00
|
|
|
sig: &Signature,
|
|
|
|
msg: &[u8],
|
|
|
|
) -> jsonrpc_core::Result<Pubkey> {
|
|
|
|
let params = json!([pubkey, sig, msg]);
|
2019-01-13 23:10:03 -08:00
|
|
|
let resp = self
|
|
|
|
.rpc_client
|
2019-03-15 23:49:28 -07:00
|
|
|
.retry_make_rpc_request(&RpcRequest::RegisterNode, Some(params), 5)
|
2019-01-11 12:58:31 -08:00
|
|
|
.unwrap();
|
|
|
|
let vote_account: Pubkey = serde_json::from_value(resp).unwrap();
|
|
|
|
Ok(vote_account)
|
|
|
|
}
|
2019-03-09 19:28:43 -08:00
|
|
|
fn sign(
|
|
|
|
&self,
|
|
|
|
pubkey: &Pubkey,
|
|
|
|
sig: &Signature,
|
|
|
|
msg: &[u8],
|
|
|
|
) -> jsonrpc_core::Result<Signature> {
|
2019-01-11 12:58:31 -08:00
|
|
|
let params = json!([pubkey, sig, msg]);
|
2019-01-13 23:10:03 -08:00
|
|
|
let resp = self
|
|
|
|
.rpc_client
|
2019-03-15 23:49:28 -07:00
|
|
|
.retry_make_rpc_request(&RpcRequest::SignVote, Some(params), 0)
|
2019-01-11 12:58:31 -08:00
|
|
|
.unwrap();
|
|
|
|
let vote_signature: Signature = serde_json::from_value(resp).unwrap();
|
|
|
|
Ok(vote_signature)
|
|
|
|
}
|
2019-03-09 19:28:43 -08:00
|
|
|
fn deregister(&self, pubkey: &Pubkey, sig: &Signature, msg: &[u8]) -> jsonrpc_core::Result<()> {
|
2019-01-11 12:58:31 -08:00
|
|
|
let params = json!([pubkey, sig, msg]);
|
2019-01-13 23:10:03 -08:00
|
|
|
let _resp = self
|
|
|
|
.rpc_client
|
2019-03-15 23:49:28 -07:00
|
|
|
.retry_make_rpc_request(&RpcRequest::DeregisterNode, Some(params), 5)
|
2019-01-11 12:58:31 -08:00
|
|
|
.unwrap();
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-31 20:12:51 -08:00
|
|
|
impl KeypairUtil for VotingKeypair {
|
|
|
|
/// Return a local VotingKeypair with a new keypair. Used for unit-tests.
|
2019-01-29 08:33:23 -08:00
|
|
|
fn new() -> Self {
|
2019-03-05 07:52:53 -08:00
|
|
|
Self::new_with_signer(
|
|
|
|
&Arc::new(Keypair::new()),
|
|
|
|
Box::new(LocalVoteSigner::default()),
|
|
|
|
)
|
2019-01-29 08:33:23 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Return the public key of the keypair used to sign votes
|
|
|
|
fn pubkey(&self) -> Pubkey {
|
|
|
|
self.vote_account
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sign_message(&self, msg: &[u8]) -> Signature {
|
|
|
|
let sig = self.keypair.sign_message(msg);
|
2019-03-09 19:28:43 -08:00
|
|
|
self.signer
|
|
|
|
.sign(&self.keypair.pubkey(), &sig, &msg)
|
|
|
|
.unwrap()
|
2019-01-29 08:33:23 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-31 20:12:51 -08:00
|
|
|
pub struct VotingKeypair {
|
2019-01-10 09:21:38 -08:00
|
|
|
keypair: Arc<Keypair>,
|
2019-01-11 12:58:31 -08:00
|
|
|
signer: Box<VoteSigner + Send + Sync>,
|
2019-01-29 08:33:23 -08:00
|
|
|
vote_account: Pubkey,
|
2019-01-10 09:21:38 -08:00
|
|
|
}
|
|
|
|
|
2019-01-31 20:12:51 -08:00
|
|
|
impl VotingKeypair {
|
2019-01-29 08:33:23 -08:00
|
|
|
pub fn new_with_signer(keypair: &Arc<Keypair>, signer: Box<VoteSigner + Send + Sync>) -> Self {
|
2019-01-10 09:21:38 -08:00
|
|
|
let msg = "Registering a new node";
|
2019-01-25 22:41:20 -08:00
|
|
|
let sig = keypair.sign_message(msg.as_bytes());
|
2019-01-11 12:58:31 -08:00
|
|
|
let vote_account = signer
|
2019-03-09 19:28:43 -08:00
|
|
|
.register(&keypair.pubkey(), &sig, msg.as_bytes())
|
2019-01-10 09:21:38 -08:00
|
|
|
.unwrap();
|
|
|
|
Self {
|
|
|
|
keypair: keypair.clone(),
|
2019-01-11 12:58:31 -08:00
|
|
|
signer,
|
2019-01-10 09:21:38 -08:00
|
|
|
vote_account,
|
|
|
|
}
|
|
|
|
}
|
2019-01-16 06:14:55 -08:00
|
|
|
}
|
2019-02-23 21:00:55 -08:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
pub mod tests {
|
|
|
|
use solana_runtime::bank::Bank;
|
2019-03-25 15:08:22 -07:00
|
|
|
use solana_sdk::instruction::Instruction;
|
2019-02-23 21:00:55 -08:00
|
|
|
use solana_sdk::pubkey::Pubkey;
|
|
|
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
2019-03-25 15:08:22 -07:00
|
|
|
use solana_sdk::transaction::Transaction;
|
2019-04-10 17:52:47 -07:00
|
|
|
use solana_vote_api::vote_instruction;
|
|
|
|
use solana_vote_api::vote_state::Vote;
|
2019-03-25 15:08:22 -07:00
|
|
|
|
|
|
|
fn process_instructions<T: KeypairUtil>(bank: &Bank, keypairs: &[&T], ixs: Vec<Instruction>) {
|
|
|
|
let blockhash = bank.last_blockhash();
|
2019-03-29 16:29:20 -07:00
|
|
|
let tx = Transaction::new_signed_instructions(keypairs, ixs, blockhash);
|
2019-03-25 15:08:22 -07:00
|
|
|
bank.process_transaction(&tx).unwrap();
|
|
|
|
}
|
2019-02-23 21:00:55 -08:00
|
|
|
|
|
|
|
pub fn new_vote_account(
|
2019-03-11 17:58:21 -07:00
|
|
|
from_keypair: &Keypair,
|
|
|
|
voting_keypair: &Keypair,
|
2019-04-10 17:52:47 -07:00
|
|
|
node_id: &Pubkey,
|
2019-03-11 17:58:21 -07:00
|
|
|
bank: &Bank,
|
|
|
|
lamports: u64,
|
|
|
|
) {
|
2019-03-25 15:08:22 -07:00
|
|
|
let voting_pubkey = voting_keypair.pubkey();
|
2019-04-10 17:52:47 -07:00
|
|
|
let ixs = vote_instruction::create_account(
|
|
|
|
&from_keypair.pubkey(),
|
|
|
|
&voting_pubkey,
|
|
|
|
node_id,
|
|
|
|
0,
|
|
|
|
lamports,
|
|
|
|
);
|
|
|
|
process_instructions(bank, &[from_keypair], ixs);
|
2019-03-11 17:58:21 -07:00
|
|
|
}
|
|
|
|
|
2019-03-05 14:18:29 -08:00
|
|
|
pub fn push_vote<T: KeypairUtil>(voting_keypair: &T, bank: &Bank, slot: u64) {
|
2019-04-11 14:48:36 -07:00
|
|
|
let ix = vote_instruction::vote(&voting_keypair.pubkey(), vec![Vote::new(slot)]);
|
2019-03-25 15:08:22 -07:00
|
|
|
process_instructions(bank, &[voting_keypair], vec![ix]);
|
2019-02-23 21:00:55 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_vote_account_with_vote<T: KeypairUtil>(
|
2019-03-25 15:08:22 -07:00
|
|
|
from_keypair: &T,
|
2019-02-23 21:00:55 -08:00
|
|
|
voting_keypair: &T,
|
2019-04-10 17:52:47 -07:00
|
|
|
node_id: &Pubkey,
|
2019-02-23 21:00:55 -08:00
|
|
|
bank: &Bank,
|
2019-03-05 16:58:52 -08:00
|
|
|
lamports: u64,
|
2019-03-05 14:18:29 -08:00
|
|
|
slot: u64,
|
2019-02-23 21:00:55 -08:00
|
|
|
) {
|
2019-03-25 15:08:22 -07:00
|
|
|
let voting_pubkey = voting_keypair.pubkey();
|
2019-04-10 17:52:47 -07:00
|
|
|
let mut ixs = vote_instruction::create_account(
|
|
|
|
&from_keypair.pubkey(),
|
|
|
|
&voting_pubkey,
|
|
|
|
node_id,
|
|
|
|
0,
|
|
|
|
lamports,
|
|
|
|
);
|
2019-04-11 14:48:36 -07:00
|
|
|
ixs.push(vote_instruction::vote(
|
|
|
|
&voting_pubkey,
|
|
|
|
vec![Vote::new(slot)],
|
|
|
|
));
|
2019-03-25 15:08:22 -07:00
|
|
|
process_instructions(bank, &[from_keypair, voting_keypair], ixs);
|
2019-02-23 21:00:55 -08:00
|
|
|
}
|
|
|
|
}
|