From 27d456bf93fdf5faccfcca4d753cd3b48533c79a Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 4 Dec 2018 08:20:41 -0800 Subject: [PATCH] Move storage_program out of src/ --- Cargo.lock | 13 ++++++ Cargo.toml | 1 + programs/native/storage/Cargo.toml | 20 +++++++++ programs/native/storage/src/lib.rs | 64 ++++++++++++++++++++++++++++ sdk/src/lib.rs | 1 + sdk/src/storage_program.rs | 40 ++++++++++++++++++ src/bank.rs | 22 ++++++---- src/bin/replicator.rs | 2 +- src/lib.rs | 2 - src/runtime.rs | 5 +-- src/storage_program.rs | 67 ------------------------------ src/storage_transaction.rs | 22 ---------- 12 files changed, 155 insertions(+), 104 deletions(-) create mode 100644 programs/native/storage/Cargo.toml create mode 100644 programs/native/storage/src/lib.rs create mode 100644 sdk/src/storage_program.rs delete mode 100644 src/storage_program.rs delete mode 100644 src/storage_transaction.rs diff --git a/Cargo.lock b/Cargo.lock index d111af4de..3c6515dd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1773,6 +1773,7 @@ dependencies = [ "solana-metrics 0.11.0", "solana-noop 0.11.0", "solana-sdk 0.11.0", + "solana-storage-program 0.11.0", "solana-system-program 0.11.0", "solana-vote-program 0.11.0", "solana-vote-signer 0.0.1", @@ -1958,6 +1959,18 @@ dependencies = [ "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "solana-storage-program" +version = "0.11.0" +dependencies = [ + "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.6.0 (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-system-program" version = "0.11.0" diff --git a/Cargo.toml b/Cargo.toml index 15503f799..8a2ff2197 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -109,6 +109,7 @@ solana-lualoader = { path = "programs/native/lua_loader", version = "0.11.0" } 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-storage-program = { path = "programs/native/storage", 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" } diff --git a/programs/native/storage/Cargo.toml b/programs/native/storage/Cargo.toml new file mode 100644 index 000000000..c2ecf23c3 --- /dev/null +++ b/programs/native/storage/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "solana-storage-program" +version = "0.11.0" +description = "Solana storage 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_storage_program" +crate-type = ["dylib"] + diff --git a/programs/native/storage/src/lib.rs b/programs/native/storage/src/lib.rs new file mode 100644 index 000000000..2615178ad --- /dev/null +++ b/programs/native/storage/src/lib.rs @@ -0,0 +1,64 @@ +//! storage program +//! Receive mining proofs from miners, validate the answers +//! and give reward for good proofs. + +extern crate bincode; +extern crate env_logger; +#[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::storage_program::*; +use std::sync::{Once, ONCE_INIT}; + +solana_entrypoint!(entrypoint); +fn entrypoint( + _program_id: &Pubkey, + keyed_accounts: &mut [KeyedAccount], + data: &[u8], + _tick_height: u64, +) -> Result<(), ProgramError> { + static INIT: Once = ONCE_INIT; + INIT.call_once(|| { + // env_logger can only be initialized once + env_logger::init(); + }); + + // accounts_keys[0] must be signed + if keyed_accounts[0].signer_key().is_none() { + info!("account[0] is unsigned"); + Err(ProgramError::InvalidArgument)?; + } + + if let Ok(syscall) = deserialize(data) { + match syscall { + StorageProgram::SubmitMiningProof { sha_state } => { + info!("Mining proof submitted with state {:?}", sha_state); + } + } + Ok(()) + } else { + info!("Invalid instruction userdata: {:?}", data); + Err(ProgramError::InvalidUserdata) + } +} + +#[cfg(test)] +mod test { + use super::*; + use solana_sdk::account::create_keyed_accounts; + use solana_sdk::signature::{Keypair, KeypairUtil}; + + #[test] + fn test_storage_tx() { + let keypair = Keypair::new(); + let mut accounts = [(keypair.pubkey(), Default::default())]; + let mut keyed_accounts = create_keyed_accounts(&mut accounts); + assert!(entrypoint(&id(), &mut keyed_accounts, &[], 42).is_err()); + } +} diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index a35ac8a0d..aa8b9b5c7 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -7,6 +7,7 @@ pub mod native_program; pub mod packet; pub mod pubkey; pub mod signature; +pub mod storage_program; pub mod system_instruction; pub mod system_program; pub mod timing; diff --git a/sdk/src/storage_program.rs b/sdk/src/storage_program.rs new file mode 100644 index 000000000..5759f1bda --- /dev/null +++ b/sdk/src/storage_program.rs @@ -0,0 +1,40 @@ +use hash::Hash; +use pubkey::Pubkey; +use signature::{Keypair, KeypairUtil}; +use transaction::Transaction; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum StorageProgram { + SubmitMiningProof { sha_state: Hash }, +} + +pub const STORAGE_PROGRAM_ID: [u8; 32] = [ + 130, 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() == STORAGE_PROGRAM_ID +} + +pub fn id() -> Pubkey { + Pubkey::new(&STORAGE_PROGRAM_ID) +} + +pub trait StorageTransaction { + fn storage_new_mining_proof(from_keypair: &Keypair, sha_state: Hash, last_id: Hash) -> Self; +} + +impl StorageTransaction for Transaction { + fn storage_new_mining_proof(from_keypair: &Keypair, sha_state: Hash, last_id: Hash) -> Self { + let program = StorageProgram::SubmitMiningProof { sha_state }; + Transaction::new( + from_keypair, + &[from_keypair.pubkey()], + id(), + &program, + last_id, + 0, + ) + } +} diff --git a/src/bank.rs b/src/bank.rs index deab14c5e..be33cd2cc 100644 --- a/src/bank.rs +++ b/src/bank.rs @@ -28,11 +28,13 @@ use solana_sdk::native_program::ProgramError; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::Keypair; use solana_sdk::signature::Signature; +use solana_sdk::storage_program; use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::system_program; use solana_sdk::timing::{duration_as_us, timestamp}; use solana_sdk::token_program; use solana_sdk::transaction::Transaction; +use solana_sdk::vote_program; use std; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::result; @@ -41,7 +43,6 @@ 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 @@ -412,9 +413,11 @@ impl Bank { accounts.store(&system_program::id(), &system_program_account); } - fn add_vote_program(&self) { + fn add_builtin_programs(&self) { + self.add_system_program(); let mut accounts = self.accounts.write().unwrap(); + // Vote program let vote_program_account = Account { tokens: 1, owner: vote_program::id(), @@ -423,12 +426,16 @@ impl Bank { 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(); + // Storage program + let storage_program_account = Account { + tokens: 1, + owner: storage_program::id(), + userdata: b"solana_storage_program".to_vec(), + executable: true, + loader: native_loader::id(), + }; + accounts.store(&storage_program::id(), &storage_program_account); // Bpf Loader let bpf_loader_account = Account { @@ -1418,7 +1425,6 @@ mod tests { use solana_sdk::signature::KeypairUtil; use solana_sdk::transaction::Instruction; use std; - use storage_program; use system_transaction::SystemTransaction; use tokio::prelude::{Async, Stream}; diff --git a/src/bin/replicator.rs b/src/bin/replicator.rs index ca4369ee1..459443db2 100644 --- a/src/bin/replicator.rs +++ b/src/bin/replicator.rs @@ -15,9 +15,9 @@ use solana::fullnode::Config; use solana::ledger::LEDGER_DATA_FILE; use solana::logger; use solana::replicator::{sample_file, Replicator}; -use solana::storage_transaction::StorageTransaction; use solana_drone::drone::{request_airdrop_transaction, DRONE_PORT}; use solana_sdk::signature::{Keypair, KeypairUtil}; +use solana_sdk::storage_program::StorageTransaction; use solana_sdk::transaction::Transaction; use std::fs::File; use std::net::{Ipv4Addr, SocketAddr}; diff --git a/src/lib.rs b/src/lib.rs index 0da982565..1a01e4528 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,9 +68,7 @@ pub mod service; pub mod signature; pub mod sigverify; pub mod sigverify_stage; -pub mod storage_program; pub mod storage_stage; -pub mod storage_transaction; pub mod store_ledger_stage; pub mod streamer; pub mod system_transaction; diff --git a/src/runtime.rs b/src/runtime.rs index 482d40fbe..12cd187a7 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -5,7 +5,6 @@ use solana_sdk::native_program::ProgramError; use solana_sdk::pubkey::Pubkey; use solana_sdk::system_program; use solana_sdk::transaction::Transaction; -use storage_program; /// Reasons the runtime might have rejected a transaction. #[derive(Debug, PartialEq, Eq, Clone)] @@ -15,7 +14,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) + budget_program::check_id(program_id) } /// Process an instruction @@ -34,8 +33,6 @@ fn process_instruction( if is_legacy_program(&program_id) { if budget_program::check_id(&program_id) { 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 { unreachable!(); }; diff --git a/src/storage_program.rs b/src/storage_program.rs deleted file mode 100644 index 530561d74..000000000 --- a/src/storage_program.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! storage program -//! Receive mining proofs from miners, validate the answers -//! and give reward for good proofs. - -use bincode::deserialize; -use solana_sdk::account::Account; -use solana_sdk::hash::Hash; -use solana_sdk::native_program::ProgramError; -use solana_sdk::pubkey::Pubkey; -use solana_sdk::transaction::Transaction; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub enum StorageProgram { - SubmitMiningProof { sha_state: Hash }, -} - -const STORAGE_PROGRAM_ID: [u8; 32] = [ - 130, 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() == STORAGE_PROGRAM_ID -} - -pub fn id() -> Pubkey { - Pubkey::new(&STORAGE_PROGRAM_ID) -} - -pub fn get_balance(account: &Account) -> u64 { - account.tokens -} - -pub fn process( - tx: &Transaction, - pix: usize, - _accounts: &mut [&mut Account], -) -> Result<(), ProgramError> { - // accounts_keys[0] must be signed - if tx.signer_key(pix, 0).is_none() { - Err(ProgramError::InvalidArgument)?; - } - - if let Ok(syscall) = deserialize(tx.userdata(pix)) { - match syscall { - StorageProgram::SubmitMiningProof { sha_state } => { - info!("Mining proof submitted with state {:?}", sha_state); - return Ok(()); - } - } - } else { - return Err(ProgramError::InvalidUserdata); - } -} - -#[cfg(test)] -mod test { - use super::*; - use solana_sdk::signature::{Keypair, KeypairUtil}; - - #[test] - fn test_storage_tx() { - let keypair = Keypair::new(); - let tx = Transaction::new(&keypair, &[], id(), &(), Default::default(), 0); - assert!(process(&tx, 0, &mut []).is_err()); - } -} diff --git a/src/storage_transaction.rs b/src/storage_transaction.rs deleted file mode 100644 index a46974d12..000000000 --- a/src/storage_transaction.rs +++ /dev/null @@ -1,22 +0,0 @@ -use solana_sdk::hash::Hash; -use solana_sdk::signature::{Keypair, KeypairUtil}; -use solana_sdk::transaction::Transaction; -use storage_program::{self, StorageProgram}; - -pub trait StorageTransaction { - fn storage_new_mining_proof(from_keypair: &Keypair, sha_state: Hash, last_id: Hash) -> Self; -} - -impl StorageTransaction for Transaction { - fn storage_new_mining_proof(from_keypair: &Keypair, sha_state: Hash, last_id: Hash) -> Self { - let program = StorageProgram::SubmitMiningProof { sha_state }; - Transaction::new( - from_keypair, - &[from_keypair.pubkey()], - storage_program::id(), - &program, - last_id, - 0, - ) - } -}