Sign Gossip Vote Messages

This commit is contained in:
Sagar Dhawan
2019-03-11 16:43:30 -07:00
committed by Grimes
parent da77789881
commit 61f950a60c
3 changed files with 41 additions and 20 deletions

View File

@ -282,7 +282,7 @@ impl ClusterInfo {
pub fn push_vote(&mut self, vote: Transaction) { pub fn push_vote(&mut self, vote: Transaction) {
let now = timestamp(); let now = timestamp();
let vote = Vote::new(vote, now); let vote = Vote::new(&self.id(), vote, now);
let mut entry = CrdsValue::Vote(vote); let mut entry = CrdsValue::Vote(vote);
entry.sign(&self.keypair); entry.sign(&self.keypair);
self.gossip.process_push_message(&[entry], now); self.gossip.process_push_message(&[entry], now);

View File

@ -214,6 +214,7 @@ impl Signable for ContactInfo {
gossip: SocketAddr, gossip: SocketAddr,
tvu: SocketAddr, tvu: SocketAddr,
tpu: SocketAddr, tpu: SocketAddr,
tpu_via_blobs: SocketAddr,
storage_addr: SocketAddr, storage_addr: SocketAddr,
rpc: SocketAddr, rpc: SocketAddr,
rpc_pubsub: SocketAddr, rpc_pubsub: SocketAddr,
@ -227,6 +228,7 @@ impl Signable for ContactInfo {
tvu: me.tvu, tvu: me.tvu,
tpu: me.tpu, tpu: me.tpu,
storage_addr: me.storage_addr, storage_addr: me.storage_addr,
tpu_via_blobs: me.tpu_via_blobs,
rpc: me.rpc, rpc: me.rpc,
rpc_pubsub: me.rpc_pubsub, rpc_pubsub: me.rpc_pubsub,
wallclock: me.wallclock, wallclock: me.wallclock,

View File

@ -1,4 +1,5 @@
use crate::contact_info::ContactInfo; use crate::contact_info::ContactInfo;
use bincode::serialize;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, Signable, Signature}; use solana_sdk::signature::{Keypair, Signable, Signature};
use solana_sdk::transaction::Transaction; use solana_sdk::transaction::Transaction;
@ -15,30 +16,37 @@ pub enum CrdsValue {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct Vote { pub struct Vote {
pub from: Pubkey,
pub transaction: Transaction, pub transaction: Transaction,
pub signature: Signature,
pub wallclock: u64, pub wallclock: u64,
} }
impl Signable for Vote { impl Signable for Vote {
fn sign(&mut self, _keypair: &Keypair) {}
fn verify(&self) -> bool {
self.transaction.verify_signature()
}
fn pubkey(&self) -> Pubkey { fn pubkey(&self) -> Pubkey {
self.transaction.account_keys[0] self.from
} }
fn signable_data(&self) -> Vec<u8> { fn signable_data(&self) -> Vec<u8> {
vec![] #[derive(Serialize)]
struct SignData {
transaction: Transaction,
wallclock: u64,
}
let data = SignData {
transaction: self.transaction.clone(),
wallclock: self.wallclock,
};
serialize(&data).expect("unable to serialize Vote")
} }
fn get_signature(&self) -> Signature { fn get_signature(&self) -> Signature {
Signature::default() self.signature
} }
fn set_signature(&mut self, _signature: Signature) {} fn set_signature(&mut self, signature: Signature) {
self.signature = signature
}
} }
/// Type of the replicated value /// Type of the replicated value
@ -68,10 +76,11 @@ impl CrdsValueLabel {
} }
impl Vote { impl Vote {
// TODO: it might make sense for the transaction to encode the wallclock in the data pub fn new(from: &Pubkey, transaction: Transaction, wallclock: u64) -> Self {
pub fn new(transaction: Transaction, wallclock: u64) -> Self {
Vote { Vote {
from: *from,
transaction, transaction,
signature: Signature::default(),
wallclock, wallclock,
} }
} }
@ -177,21 +186,31 @@ mod test {
let key = v.clone().contact_info().unwrap().id; let key = v.clone().contact_info().unwrap().id;
assert_eq!(v.label(), CrdsValueLabel::ContactInfo(key)); assert_eq!(v.label(), CrdsValueLabel::ContactInfo(key));
let v = CrdsValue::Vote(Vote::new(test_tx(), 0)); let v = CrdsValue::Vote(Vote::new(&Pubkey::default(), test_tx(), 0));
assert_eq!(v.wallclock(), 0); assert_eq!(v.wallclock(), 0);
let key = v.clone().vote().unwrap().transaction.account_keys[0]; let key = v.clone().vote().unwrap().from;
assert_eq!(v.label(), CrdsValueLabel::Vote(key)); assert_eq!(v.label(), CrdsValueLabel::Vote(key));
} }
#[test] #[test]
fn test_signature() { fn test_signature() {
let keypair = Keypair::new(); let keypair = Keypair::new();
let fake_keypair = Keypair::new(); let wrong_keypair = Keypair::new();
let mut v = let mut v =
CrdsValue::ContactInfo(ContactInfo::new_localhost(&keypair.pubkey(), timestamp())); CrdsValue::ContactInfo(ContactInfo::new_localhost(&keypair.pubkey(), timestamp()));
v.sign(&keypair); verify_signatures(&mut v, &keypair, &wrong_keypair);
assert!(v.verify()); v = CrdsValue::Vote(Vote::new(&keypair.pubkey(), test_tx(), timestamp()));
v.sign(&fake_keypair); verify_signatures(&mut v, &keypair, &wrong_keypair);
assert!(!v.verify());
} }
fn verify_signatures(
value: &mut CrdsValue,
correct_keypair: &Keypair,
wrong_keypair: &Keypair,
) {
assert!(!value.verify());
value.sign(&correct_keypair);
assert!(value.verify());
value.sign(&wrong_keypair);
assert!(!value.verify());
}
} }