Sign Gossip Vote Messages
This commit is contained in:
@ -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);
|
||||||
|
@ -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,
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user