Add account owner to Storage Accounts (#4537)
* Add account owner to Storage Accounts * Fix tests
This commit is contained in:
@ -45,6 +45,7 @@ pub enum StorageContract {
|
||||
Uninitialized, // Must be first (aka, 0)
|
||||
|
||||
ValidatorStorage {
|
||||
owner: Pubkey,
|
||||
// Most recently advertised slot
|
||||
slot: u64,
|
||||
// Most recently advertised blockhash
|
||||
@ -53,6 +54,7 @@ pub enum StorageContract {
|
||||
reward_validations: HashMap<usize, HashMap<Hash, ProofStatus>>,
|
||||
},
|
||||
ReplicatorStorage {
|
||||
owner: Pubkey,
|
||||
/// Map of Proofs per segment, in a HashMap based on the sha_state
|
||||
proofs: HashMap<usize, HashMap<Hash, Proof>>,
|
||||
/// Map of Rewards per segment, in a HashMap based on the sha_state
|
||||
@ -64,11 +66,12 @@ pub enum StorageContract {
|
||||
}
|
||||
|
||||
// utility function, used by Bank, tests, genesis
|
||||
pub fn create_validator_storage_account(lamports: u64) -> Account {
|
||||
pub fn create_validator_storage_account(owner: Pubkey, lamports: u64) -> Account {
|
||||
let mut storage_account = Account::new(lamports, STORAGE_ACCOUNT_SPACE as usize, &crate::id());
|
||||
|
||||
storage_account
|
||||
.set_state(&StorageContract::ValidatorStorage {
|
||||
owner,
|
||||
slot: 0,
|
||||
hash: Hash::default(),
|
||||
lockout_validations: HashMap::new(),
|
||||
@ -98,10 +101,11 @@ impl<'a> StorageAccount<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initialize_replicator_storage(&mut self) -> Result<(), InstructionError> {
|
||||
pub fn initialize_replicator_storage(&mut self, owner: Pubkey) -> Result<(), InstructionError> {
|
||||
let storage_contract = &mut self.account.state()?;
|
||||
if let StorageContract::Uninitialized = storage_contract {
|
||||
*storage_contract = StorageContract::ReplicatorStorage {
|
||||
owner,
|
||||
proofs: HashMap::new(),
|
||||
reward_validations: HashMap::new(),
|
||||
};
|
||||
@ -111,10 +115,11 @@ impl<'a> StorageAccount<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initialize_validator_storage(&mut self) -> Result<(), InstructionError> {
|
||||
pub fn initialize_validator_storage(&mut self, owner: Pubkey) -> Result<(), InstructionError> {
|
||||
let storage_contract = &mut self.account.state()?;
|
||||
if let StorageContract::Uninitialized = storage_contract {
|
||||
*storage_contract = StorageContract::ValidatorStorage {
|
||||
owner,
|
||||
slot: 0,
|
||||
hash: Hash::default(),
|
||||
lockout_validations: HashMap::new(),
|
||||
@ -179,6 +184,7 @@ impl<'a> StorageAccount<'a> {
|
||||
hash: state_hash,
|
||||
reward_validations,
|
||||
lockout_validations,
|
||||
..
|
||||
} = &mut storage_contract
|
||||
{
|
||||
let current_segment = get_segment_from_slot(current_slot);
|
||||
@ -315,6 +321,7 @@ impl<'a> StorageAccount<'a> {
|
||||
} else if let StorageContract::ReplicatorStorage {
|
||||
proofs,
|
||||
reward_validations,
|
||||
..
|
||||
} = &mut storage_contract
|
||||
{
|
||||
// if current tick height is a full segment away, allow reward collection
|
||||
@ -449,6 +456,7 @@ mod tests {
|
||||
}
|
||||
|
||||
contract = StorageContract::ValidatorStorage {
|
||||
owner: Pubkey::default(),
|
||||
slot: 0,
|
||||
hash: Hash::default(),
|
||||
lockout_validations: HashMap::new(),
|
||||
@ -459,6 +467,7 @@ mod tests {
|
||||
panic!("Wrong contract type");
|
||||
}
|
||||
contract = StorageContract::ReplicatorStorage {
|
||||
owner: Pubkey::default(),
|
||||
proofs: HashMap::new(),
|
||||
reward_validations: HashMap::new(),
|
||||
};
|
||||
@ -502,6 +511,7 @@ mod tests {
|
||||
let mut proofs = HashMap::new();
|
||||
proofs.insert(0, proof_map);
|
||||
*storage_contract = StorageContract::ReplicatorStorage {
|
||||
owner: Pubkey::default(),
|
||||
proofs,
|
||||
reward_validations: HashMap::new(),
|
||||
};
|
||||
|
@ -16,8 +16,12 @@ pub enum StorageInstruction {
|
||||
/// Expects 1 Account:
|
||||
/// 0 - Account to be initialized
|
||||
InitializeMiningPool,
|
||||
InitializeValidatorStorage,
|
||||
InitializeReplicatorStorage,
|
||||
InitializeValidatorStorage {
|
||||
owner: Pubkey,
|
||||
},
|
||||
InitializeReplicatorStorage {
|
||||
owner: Pubkey,
|
||||
},
|
||||
|
||||
SubmitMiningProof {
|
||||
sha_state: Hash,
|
||||
@ -44,6 +48,7 @@ pub enum StorageInstruction {
|
||||
|
||||
pub fn create_validator_storage_account(
|
||||
from_pubkey: &Pubkey,
|
||||
storage_owner: &Pubkey,
|
||||
storage_pubkey: &Pubkey,
|
||||
lamports: u64,
|
||||
) -> Vec<Instruction> {
|
||||
@ -57,7 +62,9 @@ pub fn create_validator_storage_account(
|
||||
),
|
||||
Instruction::new(
|
||||
id(),
|
||||
&StorageInstruction::InitializeValidatorStorage,
|
||||
&StorageInstruction::InitializeValidatorStorage {
|
||||
owner: *storage_owner,
|
||||
},
|
||||
vec![AccountMeta::new(*storage_pubkey, false)],
|
||||
),
|
||||
]
|
||||
@ -65,6 +72,7 @@ pub fn create_validator_storage_account(
|
||||
|
||||
pub fn create_replicator_storage_account(
|
||||
from_pubkey: &Pubkey,
|
||||
storage_owner: &Pubkey,
|
||||
storage_pubkey: &Pubkey,
|
||||
lamports: u64,
|
||||
) -> Vec<Instruction> {
|
||||
@ -78,7 +86,9 @@ pub fn create_replicator_storage_account(
|
||||
),
|
||||
Instruction::new(
|
||||
id(),
|
||||
&StorageInstruction::InitializeReplicatorStorage,
|
||||
&StorageInstruction::InitializeReplicatorStorage {
|
||||
owner: *storage_owner,
|
||||
},
|
||||
vec![AccountMeta::new(*storage_pubkey, false)],
|
||||
),
|
||||
]
|
||||
|
@ -27,17 +27,17 @@ pub fn process_instruction(
|
||||
}
|
||||
storage_account.initialize_mining_pool()
|
||||
}
|
||||
StorageInstruction::InitializeReplicatorStorage => {
|
||||
StorageInstruction::InitializeReplicatorStorage { owner } => {
|
||||
if !rest.is_empty() {
|
||||
Err(InstructionError::InvalidArgument)?;
|
||||
}
|
||||
storage_account.initialize_replicator_storage()
|
||||
storage_account.initialize_replicator_storage(owner)
|
||||
}
|
||||
StorageInstruction::InitializeValidatorStorage => {
|
||||
StorageInstruction::InitializeValidatorStorage { owner } => {
|
||||
if !rest.is_empty() {
|
||||
Err(InstructionError::InvalidArgument)?;
|
||||
}
|
||||
storage_account.initialize_validator_storage()
|
||||
storage_account.initialize_validator_storage(owner)
|
||||
}
|
||||
StorageInstruction::SubmitMiningProof {
|
||||
sha_state,
|
||||
@ -109,6 +109,7 @@ mod tests {
|
||||
use solana_runtime::bank::Bank;
|
||||
use solana_runtime::bank_client::BankClient;
|
||||
use solana_sdk::account::{create_keyed_accounts, Account};
|
||||
use solana_sdk::account_utils::State;
|
||||
use solana_sdk::client::SyncClient;
|
||||
use solana_sdk::genesis_block::create_genesis_block;
|
||||
use solana_sdk::hash::{hash, Hash};
|
||||
@ -140,8 +141,61 @@ mod tests {
|
||||
ret
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_account_owner() {
|
||||
let account_owner = Pubkey::new_rand();
|
||||
let validator_storage_pubkey = Pubkey::new_rand();
|
||||
let replicator_storage_pubkey = Pubkey::new_rand();
|
||||
|
||||
let (genesis_block, mint_keypair) = create_genesis_block(1000);
|
||||
let mut bank = Bank::new(&genesis_block);
|
||||
let mint_pubkey = mint_keypair.pubkey();
|
||||
bank.add_instruction_processor(id(), process_instruction);
|
||||
let bank = Arc::new(bank);
|
||||
let bank_client = BankClient::new_shared(&bank);
|
||||
|
||||
let message = Message::new(storage_instruction::create_validator_storage_account(
|
||||
&mint_pubkey,
|
||||
&account_owner,
|
||||
&validator_storage_pubkey,
|
||||
1,
|
||||
));
|
||||
bank_client
|
||||
.send_message(&[&mint_keypair], message)
|
||||
.expect("failed to create account");
|
||||
let account = bank
|
||||
.get_account(&validator_storage_pubkey)
|
||||
.expect("account not found");
|
||||
let storage_contract = account.state().expect("couldn't unpack account data");
|
||||
if let StorageContract::ValidatorStorage { owner, .. } = storage_contract {
|
||||
assert_eq!(owner, account_owner);
|
||||
} else {
|
||||
assert!(false, "wrong account type found")
|
||||
}
|
||||
|
||||
let message = Message::new(storage_instruction::create_replicator_storage_account(
|
||||
&mint_pubkey,
|
||||
&account_owner,
|
||||
&replicator_storage_pubkey,
|
||||
1,
|
||||
));
|
||||
bank_client
|
||||
.send_message(&[&mint_keypair], message)
|
||||
.expect("failed to create account");
|
||||
let account = bank
|
||||
.get_account(&replicator_storage_pubkey)
|
||||
.expect("account not found");
|
||||
let storage_contract = account.state().expect("couldn't unpack account data");
|
||||
if let StorageContract::ReplicatorStorage { owner, .. } = storage_contract {
|
||||
assert_eq!(owner, account_owner);
|
||||
} else {
|
||||
assert!(false, "wrong account type found")
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_proof_bounds() {
|
||||
let account_owner = Pubkey::new_rand();
|
||||
let pubkey = Pubkey::new_rand();
|
||||
let mut account = Account {
|
||||
data: vec![0; STORAGE_ACCOUNT_SPACE as usize],
|
||||
@ -149,7 +203,9 @@ mod tests {
|
||||
};
|
||||
{
|
||||
let mut storage_account = StorageAccount::new(&mut account);
|
||||
storage_account.initialize_replicator_storage().unwrap();
|
||||
storage_account
|
||||
.initialize_replicator_storage(account_owner)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let ix = storage_instruction::mining_proof(
|
||||
@ -233,12 +289,15 @@ mod tests {
|
||||
#[test]
|
||||
fn test_submit_mining_ok() {
|
||||
solana_logger::setup();
|
||||
let account_owner = Pubkey::new_rand();
|
||||
let pubkey = Pubkey::new_rand();
|
||||
let mut account = Account::default();
|
||||
account.data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
|
||||
{
|
||||
let mut storage_account = StorageAccount::new(&mut account);
|
||||
storage_account.initialize_replicator_storage().unwrap();
|
||||
storage_account
|
||||
.initialize_replicator_storage(account_owner)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let ix =
|
||||
@ -448,6 +507,7 @@ mod tests {
|
||||
.flat_map(|account| {
|
||||
storage_instruction::create_validator_storage_account(
|
||||
&mint.pubkey(),
|
||||
&Pubkey::default(),
|
||||
account,
|
||||
lamports,
|
||||
)
|
||||
@ -458,6 +518,7 @@ mod tests {
|
||||
.for_each(|account| {
|
||||
ixs.append(&mut storage_instruction::create_replicator_storage_account(
|
||||
&mint.pubkey(),
|
||||
&Pubkey::default(),
|
||||
account,
|
||||
lamports,
|
||||
))
|
||||
@ -559,6 +620,7 @@ mod tests {
|
||||
|
||||
let message = Message::new(storage_instruction::create_replicator_storage_account(
|
||||
&mint_pubkey,
|
||||
&Pubkey::default(),
|
||||
&replicator_pubkey,
|
||||
1,
|
||||
));
|
||||
@ -566,6 +628,7 @@ mod tests {
|
||||
|
||||
let message = Message::new(storage_instruction::create_validator_storage_account(
|
||||
&mint_pubkey,
|
||||
&Pubkey::default(),
|
||||
&validator_pubkey,
|
||||
1,
|
||||
));
|
||||
|
@ -4,14 +4,18 @@ use solana_sdk::pubkey::Pubkey;
|
||||
use solana_storage_api::storage_contract;
|
||||
|
||||
pub trait GenesisBlockUtil {
|
||||
fn add_storage_program(&mut self, validator_storage_pubkey: &Pubkey);
|
||||
fn add_storage_program(&mut self, validator_pubkey: &Pubkey, validator_storage_pubkey: &Pubkey);
|
||||
}
|
||||
|
||||
impl GenesisBlockUtil for GenesisBlock {
|
||||
fn add_storage_program(&mut self, validator_storage_pubkey: &Pubkey) {
|
||||
fn add_storage_program(
|
||||
&mut self,
|
||||
validator_pubkey: &Pubkey,
|
||||
validator_storage_pubkey: &Pubkey,
|
||||
) {
|
||||
self.accounts.push((
|
||||
*validator_storage_pubkey,
|
||||
storage_contract::create_validator_storage_account(1),
|
||||
storage_contract::create_validator_storage_account(*validator_pubkey, 1),
|
||||
));
|
||||
self.native_instruction_processors
|
||||
.push(solana_storage_program!());
|
||||
|
Reference in New Issue
Block a user