From ea6e042a6fa33c8d7f10918a84c7d1972a667162 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 4 Dec 2018 07:45:32 -0800 Subject: [PATCH] Move vote_program out of src/ --- Cargo.lock | 13 ++ Cargo.toml | 1 + programs/native/vote/Cargo.toml | 20 +++ programs/native/vote/src/lib.rs | 78 +++++++++++ sdk/Cargo.toml | 1 + sdk/src/lib.rs | 2 + sdk/src/vote_program.rs | 98 ++++++++++++++ src/bank.rs | 16 ++- src/bin/fullnode.rs | 2 +- src/compute_leader_finality_service.rs | 4 +- src/leader_scheduler.rs | 4 +- src/ledger.rs | 4 +- src/lib.rs | 1 - src/runtime.rs | 7 +- src/storage_stage.rs | 4 +- src/thin_client.rs | 2 +- src/vote_program.rs | 172 ------------------------- src/vote_stage.rs | 2 +- src/vote_transaction.rs | 2 +- tests/programs.rs | 1 - 20 files changed, 241 insertions(+), 193 deletions(-) create mode 100644 programs/native/vote/Cargo.toml create mode 100644 programs/native/vote/src/lib.rs create mode 100644 sdk/src/vote_program.rs delete mode 100644 src/vote_program.rs diff --git a/Cargo.lock b/Cargo.lock index fd80d50c36..d111af4de0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1774,6 +1774,7 @@ dependencies = [ "solana-noop 0.11.0", "solana-sdk 0.11.0", "solana-system-program 0.11.0", + "solana-vote-program 0.11.0", "solana-vote-signer 0.0.1", "sys-info 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1946,6 +1947,7 @@ version = "0.11.0" dependencies = [ "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1967,6 +1969,17 @@ dependencies = [ "solana-sdk 0.11.0", ] +[[package]] +name = "solana-vote-program" +version = "0.11.0" +dependencies = [ + "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk 0.11.0", +] + [[package]] name = "solana-vote-signer" version = "0.0.1" diff --git a/Cargo.toml b/Cargo.toml index 05b532fb43..15503f7998 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -110,6 +110,7 @@ solana-metrics = { path = "metrics", version = "0.11.0" } solana-noop = { path = "programs/native/noop", version = "0.11.0" } solana-sdk = { path = "sdk", version = "0.11.0" } solana-system-program = { path = "programs/native/system", version = "0.11.0" } +solana-vote-program = { path = "programs/native/vote", version = "0.11.0" } solana-vote-signer = { path = "vote-signer", version = "0.0.1" } sys-info = "0.5.6" tokio = "0.1" diff --git a/programs/native/vote/Cargo.toml b/programs/native/vote/Cargo.toml new file mode 100644 index 0000000000..ecb347803e --- /dev/null +++ b/programs/native/vote/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "solana-vote-program" +version = "0.11.0" +description = "Solana vote program" +authors = ["Solana Maintainers "] +repository = "https://github.com/solana-labs/solana" +license = "Apache-2.0" + +[dependencies] +bincode = "1.0.0" +env_logger = "0.6.0" +log = "0.4.2" +serde = "1.0.27" +serde_derive = "1.0.27" +solana-sdk = { path = "../../../sdk", version = "0.11.0" } + +[lib] +name = "solana_vote_program" +crate-type = ["cdylib"] + diff --git a/programs/native/vote/src/lib.rs b/programs/native/vote/src/lib.rs new file mode 100644 index 0000000000..76059cffe7 --- /dev/null +++ b/programs/native/vote/src/lib.rs @@ -0,0 +1,78 @@ +//! Vote program +//! Receive and processes votes from validators + +extern crate bincode; +#[macro_use] +extern crate log; +#[macro_use] +extern crate solana_sdk; + +use bincode::deserialize; +use solana_sdk::account::KeyedAccount; +use solana_sdk::native_program::ProgramError; +use solana_sdk::pubkey::Pubkey; +use solana_sdk::vote_program::*; +use std::collections::VecDeque; + +solana_entrypoint!(entrypoint); +fn entrypoint( + _program_id: &Pubkey, + keyed_accounts: &mut [KeyedAccount], + data: &[u8], + _tick_height: u64, +) -> Result<(), ProgramError> { + trace!("process_instruction: {:?}", data); + trace!("keyed_accounts: {:?}", keyed_accounts); + + // all vote instructions require that accounts_keys[0] be a signer + if keyed_accounts[0].signer_key().is_none() { + error!("account[0] is unsigned"); + Err(ProgramError::InvalidArgument)?; + } + + match deserialize(data) { + Ok(VoteInstruction::RegisterAccount) => { + if !check_id(&keyed_accounts[1].account.owner) { + error!("account[1] is not assigned to the VOTE_PROGRAM"); + Err(ProgramError::InvalidArgument)?; + } + + // TODO: a single validator could register multiple "vote accounts" + // which would clutter the "accounts" structure. See github issue 1654. + let mut vote_state = VoteProgram { + votes: VecDeque::new(), + node_id: *keyed_accounts[0].signer_key().unwrap(), + }; + + vote_state.serialize(&mut keyed_accounts[1].account.userdata)?; + + Ok(()) + } + Ok(VoteInstruction::NewVote(vote)) => { + if !check_id(&keyed_accounts[0].account.owner) { + error!("account[0] is not assigned to the VOTE_PROGRAM"); + Err(ProgramError::InvalidArgument)?; + } + + let mut vote_state = VoteProgram::deserialize(&keyed_accounts[0].account.userdata)?; + + // TODO: Integrity checks + // a) Verify the vote's bank hash matches what is expected + // b) Verify vote is older than previous votes + + // Only keep around the most recent MAX_VOTE_HISTORY votes + if vote_state.votes.len() == MAX_VOTE_HISTORY { + vote_state.votes.pop_front(); + } + + vote_state.votes.push_back(vote); + vote_state.serialize(&mut keyed_accounts[0].account.userdata)?; + + Ok(()) + } + Err(_) => { + info!("Invalid transaction instruction userdata: {:?}", data); + Err(ProgramError::InvalidUserdata) + } + } +} diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index ce11cbef40..d869c0fb62 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -8,6 +8,7 @@ license = "Apache-2.0" [dependencies] bincode = "1.0.0" +byteorder = "1.2.1" bs58 = "0.2.0" generic-array = { version = "0.12.0", default-features = false, features = ["serde"] } log = "0.4.2" diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index dd58148d79..a35ac8a0de 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -12,9 +12,11 @@ pub mod system_program; pub mod timing; pub mod token_program; pub mod transaction; +pub mod vote_program; extern crate bincode; extern crate bs58; +extern crate byteorder; extern crate generic_array; extern crate log; extern crate ring; diff --git a/sdk/src/vote_program.rs b/sdk/src/vote_program.rs new file mode 100644 index 0000000000..6af4b9ffac --- /dev/null +++ b/sdk/src/vote_program.rs @@ -0,0 +1,98 @@ +//! Vote program +//! Receive and processes votes from validators + +use bincode::{deserialize, serialize}; +use byteorder::{ByteOrder, LittleEndian}; +use native_program::ProgramError; +use pubkey::Pubkey; +use std::collections::VecDeque; +use std::mem; + +pub const VOTE_PROGRAM_ID: [u8; 32] = [ + 132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +]; + +pub fn check_id(program_id: &Pubkey) -> bool { + program_id.as_ref() == VOTE_PROGRAM_ID +} + +pub fn id() -> Pubkey { + Pubkey::new(&VOTE_PROGRAM_ID) +} + +// Maximum number of votes to keep around +pub const MAX_VOTE_HISTORY: usize = 32; + +#[derive(Serialize, Default, Deserialize, Debug, PartialEq, Eq, Clone)] +pub struct Vote { + // TODO: add signature of the state here as well + /// A vote for height tick_height + pub tick_height: u64, +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] +pub enum VoteInstruction { + /// Register a new "vote account" to represent a particular validator in the Vote Contract, + /// and initialize the VoteState for this "vote account" + /// * Transaction::keys[0] - the validator id + /// * Transaction::keys[1] - the new "vote account" to be associated with the validator + /// identified by keys[0] for voting + RegisterAccount, + NewVote(Vote), +} + +#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] +pub struct VoteProgram { + pub votes: VecDeque, + pub node_id: Pubkey, +} + +pub fn get_max_size() -> usize { + // Upper limit on the size of the Vote State. Equal to + // sizeof(VoteProgram) + MAX_VOTE_HISTORY * sizeof(Vote) + + // 32 (the size of the Pubkey) + 2 (2 bytes for the size) + mem::size_of::() + + MAX_VOTE_HISTORY * mem::size_of::() + + mem::size_of::() + + mem::size_of::() +} + +impl VoteProgram { + pub fn deserialize(input: &[u8]) -> Result { + let len = LittleEndian::read_u16(&input[0..2]) as usize; + + if len == 0 || input.len() < len + 2 { + Err(ProgramError::InvalidUserdata) + } else { + deserialize(&input[2..=len + 1]).map_err(|_| ProgramError::InvalidUserdata) + } + } + + pub fn serialize(self: &VoteProgram, output: &mut [u8]) -> Result<(), ProgramError> { + let self_serialized = serialize(self).unwrap(); + + if output.len() + 2 < self_serialized.len() { + return Err(ProgramError::UserdataTooSmall); + } + + let serialized_len = self_serialized.len() as u16; + LittleEndian::write_u16(&mut output[0..2], serialized_len); + output[2..=serialized_len as usize + 1].clone_from_slice(&self_serialized); + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_serde() { + let mut buffer: Vec = vec![0; get_max_size()]; + let mut vote_program = VoteProgram::default(); + vote_program.votes = (0..MAX_VOTE_HISTORY).map(|_| Vote::default()).collect(); + vote_program.serialize(&mut buffer).unwrap(); + assert_eq!(VoteProgram::deserialize(&buffer).unwrap(), vote_program); + } +} diff --git a/src/bank.rs b/src/bank.rs index c25a440b17..deab14c5e1 100644 --- a/src/bank.rs +++ b/src/bank.rs @@ -41,6 +41,7 @@ use std::sync::{Arc, Mutex, RwLock}; use std::time::Instant; use system_transaction::SystemTransaction; use tokio::prelude::Future; +use solana_sdk::vote_program; /// The number of most recent `last_id` values that the bank will track the signatures /// of. Once the bank discards a `last_id`, it will reject any transactions that use @@ -411,8 +412,22 @@ impl Bank { accounts.store(&system_program::id(), &system_program_account); } + fn add_vote_program(&self) { + let mut accounts = self.accounts.write().unwrap(); + + let vote_program_account = Account { + tokens: 1, + owner: vote_program::id(), + userdata: b"solana_vote_program".to_vec(), + executable: true, + loader: native_loader::id(), + }; + accounts.store(&vote_program::id(), &vote_program_account); + } + fn add_builtin_programs(&self) { self.add_system_program(); + self.add_vote_program(); let mut accounts = self.accounts.write().unwrap(); // Bpf Loader @@ -1406,7 +1421,6 @@ mod tests { use storage_program; use system_transaction::SystemTransaction; use tokio::prelude::{Async, Stream}; - use vote_program; #[test] fn test_bank_new() { diff --git a/src/bin/fullnode.rs b/src/bin/fullnode.rs index c5d68c1d66..b5db1a72b6 100644 --- a/src/bin/fullnode.rs +++ b/src/bin/fullnode.rs @@ -17,9 +17,9 @@ use solana::leader_scheduler::LeaderScheduler; use solana::logger; use solana::netutil::find_available_port_in_range; use solana::thin_client::poll_gossip_for_leader; -use solana::vote_program::VoteProgram; use solana::vote_transaction::VoteTransaction; use solana_sdk::signature::{Keypair, KeypairUtil}; +use solana_sdk::vote_program::VoteProgram; use std::fs::File; use std::net::{Ipv4Addr, SocketAddr}; use std::process::exit; diff --git a/src/compute_leader_finality_service.rs b/src/compute_leader_finality_service.rs index 7e335e512c..48ac28ad4f 100644 --- a/src/compute_leader_finality_service.rs +++ b/src/compute_leader_finality_service.rs @@ -13,7 +13,7 @@ use std::sync::Arc; use std::thread::sleep; use std::thread::{self, Builder, JoinHandle}; use std::time::Duration; -use vote_program::{self, VoteProgram}; +use solana_sdk::vote_program::{self, VoteProgram}; #[derive(Debug, PartialEq, Eq)] pub enum FinalityError { @@ -144,7 +144,7 @@ pub mod tests { use std::sync::Arc; use std::thread::sleep; use std::time::Duration; - use vote_program::Vote; + use solana_sdk::vote_program::Vote; use vote_transaction::{create_vote_account, VoteTransaction}; #[test] diff --git a/src/leader_scheduler.rs b/src/leader_scheduler.rs index c2d30d12c6..096e551084 100644 --- a/src/leader_scheduler.rs +++ b/src/leader_scheduler.rs @@ -14,7 +14,7 @@ use solana_sdk::transaction::Transaction; use std::collections::HashSet; use std::io::Cursor; use system_transaction::SystemTransaction; -use vote_program::{self, Vote, VoteProgram}; +use solana_sdk::vote_program::{self, Vote, VoteProgram}; use vote_transaction::VoteTransaction; pub const DEFAULT_BOOTSTRAP_HEIGHT: u64 = 1000; @@ -518,7 +518,7 @@ mod tests { use std::collections::HashSet; use std::hash::Hash as StdHash; use std::iter::FromIterator; - use vote_program::Vote; + use solana_sdk::vote_program::Vote; use vote_transaction::{create_vote_account, VoteTransaction}; fn to_hashset_owned(slice: &[T]) -> HashSet diff --git a/src/ledger.rs b/src/ledger.rs index b3145970af..8b3bdae9a5 100644 --- a/src/ledger.rs +++ b/src/ledger.rs @@ -20,7 +20,7 @@ use std::io::{self, BufReader, BufWriter, Seek, SeekFrom}; use std::mem::size_of; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::path::Path; -use vote_program::Vote; +use solana_sdk::vote_program::Vote; use vote_transaction::VoteTransaction; // @@ -709,7 +709,7 @@ mod tests { use solana_sdk::transaction::Transaction; use std; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; - use vote_program::Vote; + use solana_sdk::vote_program::Vote; #[test] fn test_verify_slice() { diff --git a/src/lib.rs b/src/lib.rs index cf173900d2..0da982565c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,7 +78,6 @@ pub mod thin_client; pub mod tpu; pub mod tpu_forwarder; pub mod tvu; -pub mod vote_program; pub mod vote_stage; pub mod vote_transaction; pub mod wallet; diff --git a/src/runtime.rs b/src/runtime.rs index f0dca5fb0b..482d40fbe2 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -6,7 +6,6 @@ use solana_sdk::pubkey::Pubkey; use solana_sdk::system_program; use solana_sdk::transaction::Transaction; use storage_program; -use vote_program; /// Reasons the runtime might have rejected a transaction. #[derive(Debug, PartialEq, Eq, Clone)] @@ -16,9 +15,7 @@ pub enum RuntimeError { } pub fn is_legacy_program(program_id: &Pubkey) -> bool { - budget_program::check_id(program_id) - || storage_program::check_id(program_id) - || vote_program::check_id(program_id) + budget_program::check_id(program_id) || storage_program::check_id(program_id) } /// Process an instruction @@ -39,8 +36,6 @@ fn process_instruction( budget_program::process(&tx, instruction_index, program_accounts)?; } else if storage_program::check_id(&program_id) { storage_program::process(&tx, instruction_index, program_accounts)?; - } else if vote_program::check_id(&program_id) { - vote_program::process(&tx, instruction_index, program_accounts)?; } else { unreachable!(); }; diff --git a/src/storage_stage.rs b/src/storage_stage.rs index 2d98904f10..96d85aab44 100644 --- a/src/storage_stage.rs +++ b/src/storage_stage.rs @@ -18,7 +18,7 @@ use std::sync::mpsc::RecvTimeoutError; use std::sync::{Arc, RwLock}; use std::thread::{self, Builder, JoinHandle}; use std::time::Duration; -use vote_program; +use solana_sdk::vote_program; // Block of hash answers to validate against // Vec of [ledger blocks] x [keys] @@ -278,7 +278,7 @@ mod tests { use storage_stage::StorageState; use storage_stage::NUM_IDENTITIES; use storage_stage::{get_identity_index_from_pubkey, StorageStage}; - use vote_program::Vote; + use solana_sdk::vote_program::Vote; use vote_transaction::VoteTransaction; #[test] diff --git a/src/thin_client.rs b/src/thin_client.rs index ac0312ef76..46a2dc5a02 100644 --- a/src/thin_client.rs +++ b/src/thin_client.rs @@ -439,7 +439,7 @@ mod tests { use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction::SystemInstruction; use std::fs::remove_dir_all; - use vote_program::VoteProgram; + use solana_sdk::vote_program::VoteProgram; use vote_transaction::VoteTransaction; #[test] diff --git a/src/vote_program.rs b/src/vote_program.rs deleted file mode 100644 index d66012259a..0000000000 --- a/src/vote_program.rs +++ /dev/null @@ -1,172 +0,0 @@ -//! Vote program -//! Receive and processes votes from validators - -use bincode::{deserialize, serialize}; -use byteorder::{ByteOrder, LittleEndian}; -use solana_sdk::account::Account; -use solana_sdk::native_program::ProgramError; -use solana_sdk::pubkey::Pubkey; -use solana_sdk::transaction::Transaction; -use std; -use std::collections::VecDeque; -use std::mem; - -// Maximum number of votes to keep around -const MAX_VOTE_HISTORY: usize = 32; - -pub type Result = std::result::Result; - -#[derive(Serialize, Default, Deserialize, Debug, PartialEq, Eq, Clone)] -pub struct Vote { - // TODO: add signature of the state here as well - /// A vote for height tick_height - pub tick_height: u64, -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -pub enum VoteInstruction { - /// Register a new "vote account" to represent a particular validator in the Vote Contract, - /// and initialize the VoteState for this "vote account" - /// * Transaction::keys[0] - the validator id - /// * Transaction::keys[1] - the new "vote account" to be associated with the validator - /// identified by keys[0] for voting - RegisterAccount, - NewVote(Vote), -} - -#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] -pub struct VoteProgram { - pub votes: VecDeque, - pub node_id: Pubkey, -} - -const VOTE_PROGRAM_ID: [u8; 32] = [ - 132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -]; - -pub fn check_id(program_id: &Pubkey) -> bool { - program_id.as_ref() == VOTE_PROGRAM_ID -} - -pub fn id() -> Pubkey { - Pubkey::new(&VOTE_PROGRAM_ID) -} - -pub fn process( - tx: &Transaction, - instruction_index: usize, - accounts: &mut [&mut Account], -) -> Result<()> { - // all vote instructions require that accounts_keys[0] be a signer - if tx.signer_key(instruction_index, 0).is_none() { - Err(ProgramError::InvalidArgument)?; - } - - match deserialize(tx.userdata(instruction_index)) { - Ok(VoteInstruction::RegisterAccount) => { - if !check_id(&accounts[1].owner) { - error!("accounts[1] is not assigned to the VOTE_PROGRAM"); - Err(ProgramError::InvalidArgument)?; - } - - // TODO: a single validator could register multiple "vote accounts" - // which would clutter the "accounts" structure. See github issue 1654. - let mut vote_state = VoteProgram { - votes: VecDeque::new(), - node_id: *tx.from(), - }; - - vote_state.serialize(&mut accounts[1].userdata)?; - - Ok(()) - } - Ok(VoteInstruction::NewVote(vote)) => { - if !check_id(&accounts[0].owner) { - error!("accounts[0] is not assigned to the VOTE_PROGRAM"); - Err(ProgramError::InvalidArgument)?; - } - - let mut vote_state = VoteProgram::deserialize(&accounts[0].userdata)?; - - // TODO: Integrity checks - // a) Verify the vote's bank hash matches what is expected - // b) Verify vote is older than previous votes - - // Only keep around the most recent MAX_VOTE_HISTORY votes - if vote_state.votes.len() == MAX_VOTE_HISTORY { - vote_state.votes.pop_front(); - } - - vote_state.votes.push_back(vote); - vote_state.serialize(&mut accounts[0].userdata)?; - - Ok(()) - } - Err(_) => { - info!( - "Invalid vote transaction userdata: {:?}", - tx.userdata(instruction_index) - ); - Err(ProgramError::InvalidUserdata) - } - } -} - -pub fn get_max_size() -> usize { - // Upper limit on the size of the Vote State. Equal to - // sizeof(VoteProgram) + MAX_VOTE_HISTORY * sizeof(Vote) + - // 32 (the size of the Pubkey) + 2 (2 bytes for the size) - mem::size_of::() - + MAX_VOTE_HISTORY * mem::size_of::() - + mem::size_of::() - + mem::size_of::() -} - -impl VoteProgram { - pub fn deserialize(input: &[u8]) -> Result { - let len = LittleEndian::read_u16(&input[0..2]) as usize; - - if len == 0 || input.len() < len + 2 { - Err(ProgramError::InvalidUserdata) - } else { - deserialize(&input[2..=len + 1]).map_err(|err| { - error!("Unable to deserialize vote state: {:?}", err); - ProgramError::InvalidUserdata - }) - } - } - - pub fn serialize(self: &VoteProgram, output: &mut [u8]) -> Result<()> { - let self_serialized = serialize(self).unwrap(); - - if output.len() + 2 < self_serialized.len() { - warn!( - "{} bytes required to serialize but only have {} bytes", - self_serialized.len(), - output.len() + 2, - ); - return Err(ProgramError::UserdataTooSmall); - } - - let serialized_len = self_serialized.len() as u16; - LittleEndian::write_u16(&mut output[0..2], serialized_len); - output[2..=serialized_len as usize + 1].clone_from_slice(&self_serialized); - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_serde() -> Result<()> { - let mut buffer: Vec = vec![0; get_max_size()]; - let mut vote_program = VoteProgram::default(); - vote_program.votes = (0..MAX_VOTE_HISTORY).map(|_| Vote::default()).collect(); - vote_program.serialize(&mut buffer).unwrap(); - assert_eq!(VoteProgram::deserialize(&buffer).unwrap(), vote_program); - Ok(()) - } -} diff --git a/src/vote_stage.rs b/src/vote_stage.rs index a749b84fa8..3a035ee31d 100644 --- a/src/vote_stage.rs +++ b/src/vote_stage.rs @@ -14,7 +14,7 @@ use std::net::SocketAddr; use std::sync::atomic::AtomicUsize; use std::sync::{Arc, RwLock}; use streamer::BlobSender; -use vote_program::Vote; +use solana_sdk::vote_program::Vote; use vote_transaction::VoteTransaction; #[derive(Debug, PartialEq, Eq)] diff --git a/src/vote_transaction.rs b/src/vote_transaction.rs index 640af96243..d0d4d8b447 100644 --- a/src/vote_transaction.rs +++ b/src/vote_transaction.rs @@ -13,7 +13,7 @@ use solana_sdk::signature::KeypairUtil; use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::system_program; use solana_sdk::transaction::{Instruction, Transaction}; -use vote_program::{self, Vote, VoteInstruction}; +use solana_sdk::vote_program::{self, Vote, VoteInstruction}; pub trait VoteTransaction { fn vote_new(vote_account: &Keypair, vote: Vote, last_id: Hash, fee: u64) -> Self; diff --git a/tests/programs.rs b/tests/programs.rs index ad186ef099..c25413a8c0 100644 --- a/tests/programs.rs +++ b/tests/programs.rs @@ -2,7 +2,6 @@ extern crate bincode; extern crate elf; extern crate serde_derive; extern crate solana; -#[cfg(feature = "bpf_c")] extern crate solana_sdk; use solana::bank::Bank;