Add storage reward pools (#4779)

This commit is contained in:
Sagar Dhawan 2019-06-22 17:18:35 -07:00 committed by GitHub
parent 0cc8a841ab
commit 11992946a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 122 additions and 164 deletions

1
Cargo.lock generated
View File

@ -2726,6 +2726,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-logger 0.17.0", "solana-logger 0.17.0",

View File

@ -23,7 +23,6 @@ use solana_sdk::account_utils::State;
use solana_sdk::client::{AsyncClient, SyncClient}; use solana_sdk::client::{AsyncClient, SyncClient};
use solana_sdk::hash::{Hash, Hasher}; use solana_sdk::hash::{Hash, Hasher};
use solana_sdk::message::Message; use solana_sdk::message::Message;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil, Signature}; use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
use solana_sdk::timing::timestamp; use solana_sdk::timing::timestamp;
use solana_sdk::transaction::Transaction; use solana_sdk::transaction::Transaction;
@ -303,7 +302,7 @@ impl Replicator {
}) })
} }
pub fn run(&mut self, mining_pool_pubkey: Pubkey) { pub fn run(&mut self) {
info!("waiting for ledger download"); info!("waiting for ledger download");
self.thread_handles.pop().unwrap().join().unwrap(); self.thread_handles.pop().unwrap().join().unwrap();
self.encrypt_ledger() self.encrypt_ledger()
@ -330,11 +329,11 @@ impl Replicator {
} }
}; };
self.blockhash = storage_blockhash; self.blockhash = storage_blockhash;
self.redeem_rewards(&mining_pool_pubkey); self.redeem_rewards();
} }
} }
fn redeem_rewards(&self, mining_pool_pubkey: &Pubkey) { fn redeem_rewards(&self) {
let nodes = self.cluster_info.read().unwrap().tvu_peers(); let nodes = self.cluster_info.read().unwrap().tvu_peers();
let client = crate::gossip_service::get_client(&nodes); let client = crate::gossip_service::get_client(&nodes);
@ -347,7 +346,6 @@ impl Replicator {
let ix = storage_instruction::claim_reward( let ix = storage_instruction::claim_reward(
&self.keypair.pubkey(), &self.keypair.pubkey(),
&self.storage_keypair.pubkey(), &self.storage_keypair.pubkey(),
mining_pool_pubkey,
); );
let message = Message::new_with_payer(vec![ix], Some(&self.keypair.pubkey())); let message = Message::new_with_payer(vec![ix], Some(&self.keypair.pubkey()));
if let Err(e) = client.send_message(&[&self.keypair], message) { if let Err(e) = client.send_message(&[&self.keypair], message) {

View File

@ -147,14 +147,6 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.required(true) .required(true)
.help("Path to file containing the bootstrap leader's storage keypair"), .help("Path to file containing the bootstrap leader's storage keypair"),
) )
.arg(
Arg::with_name("storage_mining_pool_lamports")
.long("storage-mining-pool-lamports")
.value_name("LAMPORTS")
.takes_value(true)
.required(true)
.help("Number of lamports to assign to the storage mining pool"),
)
.arg( .arg(
Arg::with_name("bootstrap_leader_lamports") Arg::with_name("bootstrap_leader_lamports")
.long("bootstrap-leader-lamports") .long("bootstrap-leader-lamports")
@ -261,7 +253,6 @@ fn main() -> Result<(), Box<dyn error::Error>> {
let bootstrap_leader_lamports = value_t_or_exit!(matches, "bootstrap_leader_lamports", u64); let bootstrap_leader_lamports = value_t_or_exit!(matches, "bootstrap_leader_lamports", u64);
let bootstrap_leader_stake_lamports = let bootstrap_leader_stake_lamports =
value_t_or_exit!(matches, "bootstrap_leader_stake_lamports", u64); value_t_or_exit!(matches, "bootstrap_leader_stake_lamports", u64);
let storage_pool_lamports = value_t_or_exit!(matches, "storage_mining_pool_lamports", u64);
let bootstrap_leader_keypair = read_keypair(bootstrap_leader_keypair_file)?; let bootstrap_leader_keypair = read_keypair(bootstrap_leader_keypair_file)?;
let bootstrap_vote_keypair = read_keypair(bootstrap_vote_keypair_file)?; let bootstrap_vote_keypair = read_keypair(bootstrap_vote_keypair_file)?;
@ -306,12 +297,6 @@ fn main() -> Result<(), Box<dyn error::Error>> {
1, 1,
), ),
), ),
(
"StorageMiningPoo111111111111111111111111111"
.parse()
.unwrap(),
storage_contract::create_mining_pool_account(storage_pool_lamports),
),
]) ])
.native_instruction_processors(&[ .native_instruction_processors(&[
solana_bpf_loader_program!(), solana_bpf_loader_program!(),
@ -524,6 +509,8 @@ mod tests {
) )
.expect("builder"); .expect("builder");
builder = solana_storage_api::rewards_pools::genesis(builder);
remove_file(path).unwrap(); remove_file(path).unwrap();
let genesis_block = builder.clone().build(); let genesis_block = builder.clone().build();

View File

@ -23,7 +23,6 @@ default_arg --ledger "$SOLANA_RSYNC_CONFIG_DIR"/ledger
default_arg --mint "$SOLANA_CONFIG_DIR"/mint-keypair.json default_arg --mint "$SOLANA_CONFIG_DIR"/mint-keypair.json
default_arg --lamports 100000000000000 default_arg --lamports 100000000000000
default_arg --bootstrap-leader-lamports 424242 default_arg --bootstrap-leader-lamports 424242
default_arg --storage-mining-pool-lamports 100000000
default_arg --target-lamports-per-signature 42 default_arg --target-lamports-per-signature 42
default_arg --target-signatures-per-slot 42 default_arg --target-signatures-per-slot 42
default_arg --hashes-per-tick auto default_arg --hashes-per-tick auto

View File

@ -12,6 +12,7 @@ edition = "2018"
assert_matches = "1.3.0" assert_matches = "1.3.0"
bincode = "1.1.4" bincode = "1.1.4"
log = "0.4.2" log = "0.4.2"
rand = "0.6.5"
num-derive = "0.2" num-derive = "0.2"
num-traits = "0.2" num-traits = "0.2"
serde = "1.0.92" serde = "1.0.92"

View File

@ -1,3 +1,4 @@
pub mod rewards_pools;
pub mod storage_contract; pub mod storage_contract;
pub mod storage_instruction; pub mod storage_instruction;
pub mod storage_processor; pub mod storage_processor;

View File

@ -0,0 +1,63 @@
//! rewards_pools
//! * initialize genesis with rewards pools
//! * keep track of rewards
//! * own mining pools
use crate::storage_contract::create_rewards_pool;
use rand::{thread_rng, Rng};
use solana_sdk::genesis_block::Builder;
use solana_sdk::hash::{hash, Hash};
use solana_sdk::pubkey::Pubkey;
// base rewards pool ID
const ID: [u8; 32] = [
6, 162, 25, 123, 127, 71, 141, 232, 129, 171, 58, 183, 79, 88, 181, 17, 163, 11, 51, 111, 22,
123, 67, 115, 5, 131, 109, 161, 16, 0, 0, 0,
];
solana_sdk::solana_name_id!(ID, "StorageMiningPoo111111111111111111111111111");
// to cut down on collisions for redemptions, we make multiple accounts
pub const NUM_REWARDS_POOLS: usize = 32;
pub fn genesis(mut builder: Builder) -> Builder {
let mut pubkey = id();
for _i in 0..NUM_REWARDS_POOLS {
builder = builder.rewards_pool(pubkey, create_rewards_pool());
pubkey = Pubkey::new(hash(pubkey.as_ref()).as_ref());
}
builder
}
pub fn random_id() -> Pubkey {
let mut id = Hash::new(&ID);
for _i in 0..thread_rng().gen_range(0, NUM_REWARDS_POOLS) {
id = hash(id.as_ref());
}
Pubkey::new(id.as_ref())
}
#[cfg(test)]
mod tests {
use super::*;
use solana_sdk::genesis_block::Builder;
#[test]
fn test() {
let builder = Builder::new();
let genesis_block = genesis(builder).build();
for _i in 0..NUM_REWARDS_POOLS {
let id = random_id();
assert!(genesis_block
.rewards_pools
.iter()
.position(|x| x.0 == id)
.is_some());
}
}
}

View File

@ -79,7 +79,7 @@ pub enum StorageContract {
reward_validations: BTreeMap<usize, BTreeMap<Pubkey, Vec<ProofStatus>>>, reward_validations: BTreeMap<usize, BTreeMap<Pubkey, Vec<ProofStatus>>>,
}, },
MiningPool, RewardsPool,
} }
// utility function, used by Bank, tests, genesis // utility function, used by Bank, tests, genesis
@ -99,17 +99,6 @@ pub fn create_validator_storage_account(owner: Pubkey, lamports: u64) -> Account
storage_account storage_account
} }
// utility function, used by genesis
pub fn create_mining_pool_account(lamports: u64) -> Account {
let mut storage_account = Account::new(lamports, STORAGE_ACCOUNT_SPACE as usize, &crate::id());
storage_account
.set_state(&StorageContract::MiningPool)
.expect("set_state");
storage_account
}
pub struct StorageAccount<'a> { pub struct StorageAccount<'a> {
pub(crate) id: Pubkey, pub(crate) id: Pubkey,
account: &'a mut Account, account: &'a mut Account,
@ -120,16 +109,6 @@ impl<'a> StorageAccount<'a> {
Self { id, account } Self { id, account }
} }
pub fn initialize_mining_pool(&mut self) -> Result<(), InstructionError> {
let storage_contract = &mut self.account.state()?;
if let StorageContract::Uninitialized = storage_contract {
*storage_contract = StorageContract::MiningPool;
self.account.set_state(storage_contract)
} else {
Err(InstructionError::AccountAlreadyInitialized)?
}
}
pub fn initialize_replicator_storage(&mut self, owner: Pubkey) -> Result<(), InstructionError> { pub fn initialize_replicator_storage(&mut self, owner: Pubkey) -> Result<(), InstructionError> {
let storage_contract = &mut self.account.state()?; let storage_contract = &mut self.account.state()?;
if let StorageContract::Uninitialized = storage_contract { if let StorageContract::Uninitialized = storage_contract {
@ -379,7 +358,7 @@ impl<'a> StorageAccount<'a> {
pub fn claim_storage_reward( pub fn claim_storage_reward(
&mut self, &mut self,
mining_pool: &mut KeyedAccount, rewards_pool: &mut KeyedAccount,
owner: &mut StorageAccount, owner: &mut StorageAccount,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
let mut storage_contract = &mut self.account.state()?; let mut storage_contract = &mut self.account.state()?;
@ -397,12 +376,13 @@ impl<'a> StorageAccount<'a> {
} }
let pending = *pending_lamports; let pending = *pending_lamports;
if mining_pool.account.lamports < pending { if rewards_pool.account.lamports < pending {
println!("reward pool has {}", rewards_pool.account.lamports);
Err(InstructionError::CustomError( Err(InstructionError::CustomError(
StorageError::RewardPoolDepleted as u32, StorageError::RewardPoolDepleted as u32,
))? ))?
} }
mining_pool.account.lamports -= pending; rewards_pool.account.lamports -= pending;
owner.account.lamports += pending; owner.account.lamports += pending;
//clear pending_lamports //clear pending_lamports
*pending_lamports = 0; *pending_lamports = 0;
@ -432,7 +412,7 @@ impl<'a> StorageAccount<'a> {
let total_proofs = checked_proofs.len() as u64; let total_proofs = checked_proofs.len() as u64;
let num_validations = count_valid_proofs(&checked_proofs); let num_validations = count_valid_proofs(&checked_proofs);
let reward = num_validations * REPLICATOR_REWARD * (num_validations / total_proofs); let reward = num_validations * REPLICATOR_REWARD * (num_validations / total_proofs);
mining_pool.account.lamports -= reward; rewards_pool.account.lamports -= reward;
owner.account.lamports += reward; owner.account.lamports += reward;
self.account.set_state(storage_contract) self.account.set_state(storage_contract)
} else { } else {
@ -441,6 +421,10 @@ impl<'a> StorageAccount<'a> {
} }
} }
pub fn create_rewards_pool() -> Account {
Account::new_data(std::u64::MAX, &StorageContract::RewardsPool, &crate::id()).unwrap()
}
/// Store the result of a proof validation into the replicator account /// Store the result of a proof validation into the replicator account
fn store_validation_result( fn store_validation_result(
me: &Pubkey, me: &Pubkey,

View File

@ -1,5 +1,5 @@
use crate::id;
use crate::storage_contract::{ProofStatus, STORAGE_ACCOUNT_SPACE}; use crate::storage_contract::{ProofStatus, STORAGE_ACCOUNT_SPACE};
use crate::{id, rewards_pools};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use solana_sdk::hash::Hash; use solana_sdk::hash::Hash;
use solana_sdk::instruction::{AccountMeta, Instruction}; use solana_sdk::instruction::{AccountMeta, Instruction};
@ -10,11 +10,10 @@ use solana_sdk::system_instruction;
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub enum StorageInstruction { pub enum StorageInstruction {
/// Initialize the account as a mining pool, validator or replicator /// Initialize the account as a validator or replicator
/// ///
/// Expects 1 Account: /// Expects 1 Account:
/// 0 - Account to be initialized /// 0 - Account to be initialized
InitializeMiningPool,
InitializeValidatorStorage { InitializeValidatorStorage {
owner: Pubkey, owner: Pubkey,
}, },
@ -128,27 +127,6 @@ pub fn create_replicator_storage_account(
] ]
} }
pub fn create_mining_pool_account(
from_pubkey: &Pubkey,
storage_pubkey: &Pubkey,
lamports: u64,
) -> Vec<Instruction> {
vec![
system_instruction::create_account(
from_pubkey,
storage_pubkey,
lamports,
STORAGE_ACCOUNT_SPACE,
&id(),
),
Instruction::new(
id(),
&StorageInstruction::InitializeMiningPool,
vec![AccountMeta::new(*storage_pubkey, false)],
),
]
}
pub fn mining_proof( pub fn mining_proof(
storage_pubkey: &Pubkey, storage_pubkey: &Pubkey,
sha_state: Hash, sha_state: Hash,
@ -200,15 +178,11 @@ pub fn proof_validation(
Instruction::new(id(), &storage_instruction, account_metas) Instruction::new(id(), &storage_instruction, account_metas)
} }
pub fn claim_reward( pub fn claim_reward(owner_pubkey: &Pubkey, storage_pubkey: &Pubkey) -> Instruction {
owner_pubkey: &Pubkey,
storage_pubkey: &Pubkey,
mining_pool_pubkey: &Pubkey,
) -> Instruction {
let storage_instruction = StorageInstruction::ClaimStorageReward; let storage_instruction = StorageInstruction::ClaimStorageReward;
let account_metas = vec![ let account_metas = vec![
AccountMeta::new(*storage_pubkey, false), AccountMeta::new(*storage_pubkey, false),
AccountMeta::new(*mining_pool_pubkey, false), AccountMeta::new(rewards_pools::random_id(), false),
AccountMeta::new(*owner_pubkey, false), AccountMeta::new(*owner_pubkey, false),
]; ];
Instruction::new(id(), &storage_instruction, account_metas) Instruction::new(id(), &storage_instruction, account_metas)

View File

@ -20,12 +20,6 @@ pub fn process_instruction(
let mut storage_account = StorageAccount::new(*me[0].unsigned_key(), &mut me[0].account); let mut storage_account = StorageAccount::new(*me[0].unsigned_key(), &mut me[0].account);
match bincode::deserialize(data).map_err(|_| InstructionError::InvalidInstructionData)? { match bincode::deserialize(data).map_err(|_| InstructionError::InvalidInstructionData)? {
StorageInstruction::InitializeMiningPool => {
if !rest.is_empty() {
Err(InstructionError::InvalidArgument)?;
}
storage_account.initialize_mining_pool()
}
StorageInstruction::InitializeReplicatorStorage { owner } => { StorageInstruction::InitializeReplicatorStorage { owner } => {
if !rest.is_empty() { if !rest.is_empty() {
Err(InstructionError::InvalidArgument)?; Err(InstructionError::InvalidArgument)?;

View File

@ -3,10 +3,10 @@ use bincode::deserialize;
use log::*; use log::*;
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_runtime::bank_client::BankClient; use solana_runtime::bank_client::BankClient;
use solana_runtime::genesis_utils::{create_genesis_block, GenesisBlockInfo};
use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount}; use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount};
use solana_sdk::account_utils::State; use solana_sdk::account_utils::State;
use solana_sdk::client::SyncClient; use solana_sdk::client::SyncClient;
use solana_sdk::genesis_block::create_genesis_block;
use solana_sdk::hash::{hash, Hash}; use solana_sdk::hash::{hash, Hash};
use solana_sdk::instruction::{Instruction, InstructionError}; use solana_sdk::instruction::{Instruction, InstructionError};
use solana_sdk::message::Message; use solana_sdk::message::Message;
@ -53,7 +53,11 @@ fn test_account_owner() {
let validator_storage_pubkey = Pubkey::new_rand(); let validator_storage_pubkey = Pubkey::new_rand();
let replicator_storage_pubkey = Pubkey::new_rand(); let replicator_storage_pubkey = Pubkey::new_rand();
let (genesis_block, mint_keypair) = create_genesis_block(1000); let GenesisBlockInfo {
genesis_block,
mint_keypair,
..
} = create_genesis_block(1000);
let mut bank = Bank::new(&genesis_block); let mut bank = Bank::new(&genesis_block);
let mint_pubkey = mint_keypair.pubkey(); let mint_pubkey = mint_keypair.pubkey();
bank.add_instruction_processor(id(), process_instruction); bank.add_instruction_processor(id(), process_instruction);
@ -259,7 +263,11 @@ fn test_submit_mining_ok() {
#[test] #[test]
fn test_validate_mining() { fn test_validate_mining() {
solana_logger::setup(); solana_logger::setup();
let (mut genesis_block, mint_keypair) = create_genesis_block(100_000); let GenesisBlockInfo {
mut genesis_block,
mint_keypair,
..
} = create_genesis_block(100_000);
genesis_block genesis_block
.native_instruction_processors .native_instruction_processors
.push(solana_storage_program::solana_storage_program!()); .push(solana_storage_program::solana_storage_program!());
@ -276,9 +284,6 @@ fn test_validate_mining() {
let validator_storage_keypair = Keypair::new(); let validator_storage_keypair = Keypair::new();
let validator_storage_id = validator_storage_keypair.pubkey(); let validator_storage_id = validator_storage_keypair.pubkey();
let mining_pool_keypair = Keypair::new();
let mining_pool_pubkey = mining_pool_keypair.pubkey();
let bank = Bank::new(&genesis_block); let bank = Bank::new(&genesis_block);
let bank = Arc::new(bank); let bank = Arc::new(bank);
let bank_client = BankClient::new_shared(&bank); let bank_client = BankClient::new_shared(&bank);
@ -291,12 +296,6 @@ fn test_validate_mining() {
&[&replicator_1_storage_id, &replicator_2_storage_id], &[&replicator_1_storage_id, &replicator_2_storage_id],
10, 10,
); );
let message = Message::new(storage_instruction::create_mining_pool_account(
&mint_pubkey,
&mining_pool_pubkey,
10_000,
));
bank_client.send_message(&[&mint_keypair], message).unwrap();
// create a new bank in segment 2 // create a new bank in segment 2
let bank = Arc::new(Bank::new_from_parent( let bank = Arc::new(Bank::new_from_parent(
@ -407,7 +406,6 @@ fn test_validate_mining() {
vec![storage_instruction::claim_reward( vec![storage_instruction::claim_reward(
&owner_pubkey, &owner_pubkey,
&validator_storage_id, &validator_storage_id,
&mining_pool_pubkey,
)], )],
Some(&mint_pubkey), Some(&mint_pubkey),
); );
@ -431,7 +429,6 @@ fn test_validate_mining() {
vec![storage_instruction::claim_reward( vec![storage_instruction::claim_reward(
&owner_pubkey, &owner_pubkey,
&replicator_1_storage_id, &replicator_1_storage_id,
&mining_pool_pubkey,
)], )],
Some(&mint_pubkey), Some(&mint_pubkey),
); );
@ -447,7 +444,6 @@ fn test_validate_mining() {
vec![storage_instruction::claim_reward( vec![storage_instruction::claim_reward(
&owner_pubkey, &owner_pubkey,
&replicator_2_storage_id, &replicator_2_storage_id,
&mining_pool_pubkey,
)], )],
Some(&mint_pubkey), Some(&mint_pubkey),
); );
@ -561,7 +557,11 @@ fn get_storage_blockhash<C: SyncClient>(client: &C, account: &Pubkey) -> Hash {
#[test] #[test]
fn test_bank_storage() { fn test_bank_storage() {
let (mut genesis_block, mint_keypair) = create_genesis_block(1000); let GenesisBlockInfo {
mut genesis_block,
mint_keypair,
..
} = create_genesis_block(1000);
genesis_block genesis_block
.native_instruction_processors .native_instruction_processors
.push(solana_storage_program::solana_storage_program!()); .push(solana_storage_program::solana_storage_program!());

View File

@ -2,7 +2,6 @@ use clap::{crate_description, crate_name, crate_version, App, Arg};
use solana::cluster_info::{Node, FULLNODE_PORT_RANGE}; use solana::cluster_info::{Node, FULLNODE_PORT_RANGE};
use solana::contact_info::ContactInfo; use solana::contact_info::ContactInfo;
use solana::replicator::Replicator; use solana::replicator::Replicator;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{read_keypair, Keypair, KeypairUtil}; use solana_sdk::signature::{read_keypair, Keypair, KeypairUtil};
use std::net::SocketAddr; use std::net::SocketAddr;
use std::process::exit; use std::process::exit;
@ -70,10 +69,6 @@ fn main() {
Keypair::new() Keypair::new()
}; };
let storage_mining_pool_pubkey = "StorageMiningPoo111111111111111111111111111"
.parse::<Pubkey>()
.unwrap();
let entrypoint_addr = matches let entrypoint_addr = matches
.value_of("entrypoint") .value_of("entrypoint")
.map(|entrypoint| { .map(|entrypoint| {
@ -106,6 +101,6 @@ fn main() {
) )
.unwrap(); .unwrap();
replicator.run(storage_mining_pool_pubkey); replicator.run();
replicator.close(); replicator.close();
} }

View File

@ -70,6 +70,7 @@ pub fn create_genesis_block_with_leader(
]); ]);
builder = solana_stake_api::rewards_pools::genesis(builder); builder = solana_stake_api::rewards_pools::genesis(builder);
builder = solana_storage_api::rewards_pools::genesis(builder);
GenesisBlockInfo { GenesisBlockInfo {
genesis_block: builder.build(), genesis_block: builder.build(),

View File

@ -186,7 +186,10 @@ impl MessageProcessor {
let program_id = instruction.program_id(&message.account_keys); let program_id = instruction.program_id(&message.account_keys);
// TODO: the runtime should be checking read/write access to memory // TODO: the runtime should be checking read/write access to memory
// we are trusting the hard-coded programs not to clobber or allocate // we are trusting the hard-coded programs not to clobber or allocate
let pre_total: u64 = program_accounts.iter().map(|a| a.lamports).sum(); let pre_total: u128 = program_accounts
.iter()
.map(|a| u128::from(a.lamports))
.sum();
let pre_data: Vec<_> = program_accounts let pre_data: Vec<_> = program_accounts
.iter_mut() .iter_mut()
.map(|a| (a.owner, a.lamports, a.data.clone())) .map(|a| (a.owner, a.lamports, a.data.clone()))
@ -215,7 +218,10 @@ impl MessageProcessor {
} }
} }
// The total sum of all the lamports in all the accounts cannot change. // The total sum of all the lamports in all the accounts cannot change.
let post_total: u64 = program_accounts.iter().map(|a| a.lamports).sum(); let post_total: u128 = program_accounts
.iter()
.map(|a| u128::from(a.lamports))
.sum();
if pre_total != post_total { if pre_total != post_total {
return Err(InstructionError::UnbalancedInstruction); return Err(InstructionError::UnbalancedInstruction);
} }

View File

@ -56,10 +56,9 @@ pub enum WalletCommand {
DeactivateStake(Keypair), DeactivateStake(Keypair),
RedeemVoteCredits(Pubkey, Pubkey), RedeemVoteCredits(Pubkey, Pubkey),
ShowStakeAccount(Pubkey), ShowStakeAccount(Pubkey),
CreateStorageMiningPoolAccount(Pubkey, u64),
CreateReplicatorStorageAccount(Pubkey, Pubkey), CreateReplicatorStorageAccount(Pubkey, Pubkey),
CreateValidatorStorageAccount(Pubkey, Pubkey), CreateValidatorStorageAccount(Pubkey, Pubkey),
ClaimStorageReward(Pubkey, Pubkey, Pubkey), ClaimStorageReward(Pubkey, Pubkey),
ShowStorageAccount(Pubkey), ShowStorageAccount(Pubkey),
Deploy(String), Deploy(String),
GetTransactionCount, GetTransactionCount,
@ -297,12 +296,9 @@ pub fn parse_command(
} }
("claim-storage-reward", Some(matches)) => { ("claim-storage-reward", Some(matches)) => {
let node_account_pubkey = value_of(matches, "node_account_pubkey").unwrap(); let node_account_pubkey = value_of(matches, "node_account_pubkey").unwrap();
let storage_mining_pool_account_pubkey =
value_of(matches, "storage_mining_pool_account_pubkey").unwrap();
let storage_account_pubkey = value_of(matches, "storage_account_pubkey").unwrap(); let storage_account_pubkey = value_of(matches, "storage_account_pubkey").unwrap();
Ok(WalletCommand::ClaimStorageReward( Ok(WalletCommand::ClaimStorageReward(
node_account_pubkey, node_account_pubkey,
storage_mining_pool_account_pubkey,
storage_account_pubkey, storage_account_pubkey,
)) ))
} }
@ -689,23 +685,6 @@ fn process_show_stake_account(
} }
} }
fn process_create_storage_mining_pool_account(
rpc_client: &RpcClient,
config: &WalletConfig,
storage_account_pubkey: &Pubkey,
lamports: u64,
) -> ProcessResult {
let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let ixs = storage_instruction::create_mining_pool_account(
&config.keypair.pubkey(),
storage_account_pubkey,
lamports,
);
let mut tx = Transaction::new_signed_instructions(&[&config.keypair], ixs, recent_blockhash);
let signature_str = rpc_client.send_and_confirm_transaction(&mut tx, &[&config.keypair])?;
Ok(signature_str.to_string())
}
fn process_create_replicator_storage_account( fn process_create_replicator_storage_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &WalletConfig,
@ -746,16 +725,12 @@ fn process_claim_storage_reward(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &WalletConfig,
node_account_pubkey: &Pubkey, node_account_pubkey: &Pubkey,
storage_mining_pool_account_pubkey: &Pubkey,
storage_account_pubkey: &Pubkey, storage_account_pubkey: &Pubkey,
) -> ProcessResult { ) -> ProcessResult {
let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?; let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?;
let instruction = storage_instruction::claim_reward( let instruction =
node_account_pubkey, storage_instruction::claim_reward(node_account_pubkey, storage_account_pubkey);
storage_account_pubkey,
storage_mining_pool_account_pubkey,
);
let signers = [&config.keypair]; let signers = [&config.keypair];
let message = Message::new_with_payer(vec![instruction], Some(&signers[0].pubkey())); let message = Message::new_with_payer(vec![instruction], Some(&signers[0].pubkey()));
@ -1115,15 +1090,6 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
process_show_stake_account(&rpc_client, config, &staking_account_pubkey) process_show_stake_account(&rpc_client, config, &staking_account_pubkey)
} }
WalletCommand::CreateStorageMiningPoolAccount(storage_account_pubkey, lamports) => {
process_create_storage_mining_pool_account(
&rpc_client,
config,
&storage_account_pubkey,
*lamports,
)
}
WalletCommand::CreateReplicatorStorageAccount( WalletCommand::CreateReplicatorStorageAccount(
storage_account_owner, storage_account_owner,
storage_account_pubkey, storage_account_pubkey,
@ -1143,17 +1109,14 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
) )
} }
WalletCommand::ClaimStorageReward( WalletCommand::ClaimStorageReward(node_account_pubkey, storage_account_pubkey) => {
node_account_pubkey, process_claim_storage_reward(
storage_mining_pool_account_pubkey, &rpc_client,
storage_account_pubkey, config,
) => process_claim_storage_reward( node_account_pubkey,
&rpc_client, &storage_account_pubkey,
config, )
node_account_pubkey, }
&storage_mining_pool_account_pubkey,
&storage_account_pubkey,
),
WalletCommand::ShowStorageAccount(storage_account_pubkey) => { WalletCommand::ShowStorageAccount(storage_account_pubkey) => {
process_show_storage_account(&rpc_client, config, &storage_account_pubkey) process_show_storage_account(&rpc_client, config, &storage_account_pubkey)
@ -1639,15 +1602,6 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
.validator(is_pubkey) .validator(is_pubkey)
.help("The node account to credit the rewards to"), .help("The node account to credit the rewards to"),
) )
.arg(
Arg::with_name("storage_mining_pool_account_pubkey")
.index(2)
.value_name("MINING POOL PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey)
.help("Mining pool account to redeem credits from"),
)
.arg( .arg(
Arg::with_name("storage_account_pubkey") Arg::with_name("storage_account_pubkey")
.index(3) .index(3)