Move storage_program out of src/
This commit is contained in:
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -1773,6 +1773,7 @@ dependencies = [
|
|||||||
"solana-metrics 0.11.0",
|
"solana-metrics 0.11.0",
|
||||||
"solana-noop 0.11.0",
|
"solana-noop 0.11.0",
|
||||||
"solana-sdk 0.11.0",
|
"solana-sdk 0.11.0",
|
||||||
|
"solana-storage-program 0.11.0",
|
||||||
"solana-system-program 0.11.0",
|
"solana-system-program 0.11.0",
|
||||||
"solana-vote-program 0.11.0",
|
"solana-vote-program 0.11.0",
|
||||||
"solana-vote-signer 0.0.1",
|
"solana-vote-signer 0.0.1",
|
||||||
@ -1958,6 +1959,18 @@ dependencies = [
|
|||||||
"untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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]]
|
[[package]]
|
||||||
name = "solana-system-program"
|
name = "solana-system-program"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
@ -109,6 +109,7 @@ solana-lualoader = { path = "programs/native/lua_loader", version = "0.11.0" }
|
|||||||
solana-metrics = { path = "metrics", version = "0.11.0" }
|
solana-metrics = { path = "metrics", version = "0.11.0" }
|
||||||
solana-noop = { path = "programs/native/noop", version = "0.11.0" }
|
solana-noop = { path = "programs/native/noop", version = "0.11.0" }
|
||||||
solana-sdk = { path = "sdk", 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-system-program = { path = "programs/native/system", version = "0.11.0" }
|
||||||
solana-vote-program = { path = "programs/native/vote", 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" }
|
solana-vote-signer = { path = "vote-signer", version = "0.0.1" }
|
||||||
|
20
programs/native/storage/Cargo.toml
Normal file
20
programs/native/storage/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[package]
|
||||||
|
name = "solana-storage-program"
|
||||||
|
version = "0.11.0"
|
||||||
|
description = "Solana storage program"
|
||||||
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
|
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"]
|
||||||
|
|
64
programs/native/storage/src/lib.rs
Normal file
64
programs/native/storage/src/lib.rs
Normal file
@ -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());
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ pub mod native_program;
|
|||||||
pub mod packet;
|
pub mod packet;
|
||||||
pub mod pubkey;
|
pub mod pubkey;
|
||||||
pub mod signature;
|
pub mod signature;
|
||||||
|
pub mod storage_program;
|
||||||
pub mod system_instruction;
|
pub mod system_instruction;
|
||||||
pub mod system_program;
|
pub mod system_program;
|
||||||
pub mod timing;
|
pub mod timing;
|
||||||
|
40
sdk/src/storage_program.rs
Normal file
40
sdk/src/storage_program.rs
Normal file
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
22
src/bank.rs
22
src/bank.rs
@ -28,11 +28,13 @@ use solana_sdk::native_program::ProgramError;
|
|||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::signature::Keypair;
|
use solana_sdk::signature::Keypair;
|
||||||
use solana_sdk::signature::Signature;
|
use solana_sdk::signature::Signature;
|
||||||
|
use solana_sdk::storage_program;
|
||||||
use solana_sdk::system_instruction::SystemInstruction;
|
use solana_sdk::system_instruction::SystemInstruction;
|
||||||
use solana_sdk::system_program;
|
use solana_sdk::system_program;
|
||||||
use solana_sdk::timing::{duration_as_us, timestamp};
|
use solana_sdk::timing::{duration_as_us, timestamp};
|
||||||
use solana_sdk::token_program;
|
use solana_sdk::token_program;
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::Transaction;
|
||||||
|
use solana_sdk::vote_program;
|
||||||
use std;
|
use std;
|
||||||
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
|
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
|
||||||
use std::result;
|
use std::result;
|
||||||
@ -41,7 +43,6 @@ use std::sync::{Arc, Mutex, RwLock};
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use system_transaction::SystemTransaction;
|
use system_transaction::SystemTransaction;
|
||||||
use tokio::prelude::Future;
|
use tokio::prelude::Future;
|
||||||
use solana_sdk::vote_program;
|
|
||||||
|
|
||||||
/// The number of most recent `last_id` values that the bank will track the signatures
|
/// 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
|
/// 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);
|
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();
|
let mut accounts = self.accounts.write().unwrap();
|
||||||
|
|
||||||
|
// Vote program
|
||||||
let vote_program_account = Account {
|
let vote_program_account = Account {
|
||||||
tokens: 1,
|
tokens: 1,
|
||||||
owner: vote_program::id(),
|
owner: vote_program::id(),
|
||||||
@ -423,12 +426,16 @@ impl Bank {
|
|||||||
loader: native_loader::id(),
|
loader: native_loader::id(),
|
||||||
};
|
};
|
||||||
accounts.store(&vote_program::id(), &vote_program_account);
|
accounts.store(&vote_program::id(), &vote_program_account);
|
||||||
}
|
|
||||||
|
|
||||||
fn add_builtin_programs(&self) {
|
// Storage program
|
||||||
self.add_system_program();
|
let storage_program_account = Account {
|
||||||
self.add_vote_program();
|
tokens: 1,
|
||||||
let mut accounts = self.accounts.write().unwrap();
|
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
|
// Bpf Loader
|
||||||
let bpf_loader_account = Account {
|
let bpf_loader_account = Account {
|
||||||
@ -1418,7 +1425,6 @@ mod tests {
|
|||||||
use solana_sdk::signature::KeypairUtil;
|
use solana_sdk::signature::KeypairUtil;
|
||||||
use solana_sdk::transaction::Instruction;
|
use solana_sdk::transaction::Instruction;
|
||||||
use std;
|
use std;
|
||||||
use storage_program;
|
|
||||||
use system_transaction::SystemTransaction;
|
use system_transaction::SystemTransaction;
|
||||||
use tokio::prelude::{Async, Stream};
|
use tokio::prelude::{Async, Stream};
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@ use solana::fullnode::Config;
|
|||||||
use solana::ledger::LEDGER_DATA_FILE;
|
use solana::ledger::LEDGER_DATA_FILE;
|
||||||
use solana::logger;
|
use solana::logger;
|
||||||
use solana::replicator::{sample_file, Replicator};
|
use solana::replicator::{sample_file, Replicator};
|
||||||
use solana::storage_transaction::StorageTransaction;
|
|
||||||
use solana_drone::drone::{request_airdrop_transaction, DRONE_PORT};
|
use solana_drone::drone::{request_airdrop_transaction, DRONE_PORT};
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
|
use solana_sdk::storage_program::StorageTransaction;
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::Transaction;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::net::{Ipv4Addr, SocketAddr};
|
use std::net::{Ipv4Addr, SocketAddr};
|
||||||
|
@ -68,9 +68,7 @@ pub mod service;
|
|||||||
pub mod signature;
|
pub mod signature;
|
||||||
pub mod sigverify;
|
pub mod sigverify;
|
||||||
pub mod sigverify_stage;
|
pub mod sigverify_stage;
|
||||||
pub mod storage_program;
|
|
||||||
pub mod storage_stage;
|
pub mod storage_stage;
|
||||||
pub mod storage_transaction;
|
|
||||||
pub mod store_ledger_stage;
|
pub mod store_ledger_stage;
|
||||||
pub mod streamer;
|
pub mod streamer;
|
||||||
pub mod system_transaction;
|
pub mod system_transaction;
|
||||||
|
@ -5,7 +5,6 @@ use solana_sdk::native_program::ProgramError;
|
|||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::system_program;
|
use solana_sdk::system_program;
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::Transaction;
|
||||||
use storage_program;
|
|
||||||
|
|
||||||
/// Reasons the runtime might have rejected a transaction.
|
/// Reasons the runtime might have rejected a transaction.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
@ -15,7 +14,7 @@ pub enum RuntimeError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_legacy_program(program_id: &Pubkey) -> bool {
|
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
|
/// Process an instruction
|
||||||
@ -34,8 +33,6 @@ fn process_instruction(
|
|||||||
if is_legacy_program(&program_id) {
|
if is_legacy_program(&program_id) {
|
||||||
if budget_program::check_id(&program_id) {
|
if budget_program::check_id(&program_id) {
|
||||||
budget_program::process(&tx, instruction_index, program_accounts)?;
|
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 {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user