Move SLOTS_PER_SEGMENT to genesis (#4992)

automerge
This commit is contained in:
Sagar Dhawan
2019-07-09 16:48:40 -07:00
committed by Grimes
parent 32b55e6703
commit b8e7736af2
19 changed files with 315 additions and 162 deletions

View File

@ -194,7 +194,7 @@ mod tests {
.iter()
.map(|meta| {
if syscall::current::check_id(&meta.pubkey) {
syscall::current::create_account(1, 0, 0, 0)
syscall::current::create_account(1, 0, 0, 0, 0)
} else if syscall::rewards::check_id(&meta.pubkey) {
syscall::rewards::create_account(1, 0.0, 0.0)
} else {
@ -288,7 +288,7 @@ mod tests {
KeyedAccount::new(
&syscall::current::id(),
false,
&mut syscall::current::create_account(1, 0, 0, 0)
&mut syscall::current::create_account(1, 0, 0, 0, 0)
),
],
&serialize(&StakeInstruction::DelegateStake(0)).unwrap(),

View File

@ -3,12 +3,6 @@ pub mod storage_contract;
pub mod storage_instruction;
pub mod storage_processor;
pub const SLOTS_PER_SEGMENT: u64 = 16;
pub fn get_segment_from_slot(slot: u64) -> usize {
((slot + (SLOTS_PER_SEGMENT - 1)) / SLOTS_PER_SEGMENT) as usize
}
const STORAGE_PROGRAM_ID: [u8; 32] = [
6, 162, 25, 123, 127, 68, 233, 59, 131, 151, 21, 152, 162, 120, 90, 37, 154, 88, 86, 5, 156,
221, 182, 201, 142, 103, 151, 112, 0, 0, 0, 0,

View File

@ -1,4 +1,3 @@
use crate::get_segment_from_slot;
use log::*;
use num_derive::FromPrimitive;
use serde_derive::{Deserialize, Serialize};
@ -68,8 +67,8 @@ pub struct Proof {
pub blockhash: Hash,
/// The resulting sampled state
pub sha_state: Hash,
/// The start index of the segment proof is for
pub segment_index: usize,
/// The segment this proof is for
pub segment_index: u64,
}
#[derive(Debug, Serialize, Deserialize)]
@ -78,13 +77,13 @@ pub enum StorageContract {
ValidatorStorage {
owner: Pubkey,
// Most recently advertised slot
slot: u64,
// Most recently advertised segment
segment: u64,
// Most recently advertised blockhash
hash: Hash,
// Lockouts and Rewards are per segment per replicator. It needs to remain this way until
// the challenge stage is added.
lockout_validations: BTreeMap<usize, BTreeMap<Pubkey, Vec<ProofStatus>>>,
lockout_validations: BTreeMap<u64, BTreeMap<Pubkey, Vec<ProofStatus>>>,
// Used to keep track of ongoing credits
credits: Credits,
},
@ -93,10 +92,10 @@ pub enum StorageContract {
owner: Pubkey,
// TODO what to do about duplicate proofs across segments? - Check the blockhashes
// Map of Proofs per segment, in a Vec
proofs: BTreeMap<usize, Vec<Proof>>,
proofs: BTreeMap<u64, Vec<Proof>>,
// Map of Rewards per segment, in a BTreeMap based on the validator account that verified
// the proof. This can be used for challenge stage when its added
validations: BTreeMap<usize, BTreeMap<Pubkey, Vec<ProofStatus>>>,
validations: BTreeMap<u64, BTreeMap<Pubkey, Vec<ProofStatus>>>,
// Used to keep track of ongoing credits
credits: Credits,
},
@ -111,7 +110,7 @@ pub fn create_validator_storage_account(owner: Pubkey, lamports: u64) -> Account
storage_account
.set_state(&StorageContract::ValidatorStorage {
owner,
slot: 0,
segment: 0,
hash: Hash::default(),
lockout_validations: BTreeMap::new(),
credits: Credits::default(),
@ -151,7 +150,7 @@ impl<'a> StorageAccount<'a> {
if let StorageContract::Uninitialized = storage_contract {
*storage_contract = StorageContract::ValidatorStorage {
owner,
slot: 0,
segment: 0,
hash: Hash::default(),
lockout_validations: BTreeMap::new(),
credits: Credits::default(),
@ -165,7 +164,7 @@ impl<'a> StorageAccount<'a> {
pub fn submit_mining_proof(
&mut self,
sha_state: Hash,
segment_index: usize,
segment_index: u64,
signature: Signature,
blockhash: Hash,
current: syscall::current::Current,
@ -178,7 +177,7 @@ impl<'a> StorageAccount<'a> {
..
} = &mut storage_contract
{
let current_segment = get_segment_from_slot(current.slot);
let current_segment = current.segment;
// clean up the account
// TODO check for time correctness - storage seems to run at a delay of about 3
@ -242,32 +241,29 @@ impl<'a> StorageAccount<'a> {
pub fn advertise_storage_recent_blockhash(
&mut self,
hash: Hash,
slot: u64,
segment: u64,
current: syscall::current::Current,
) -> Result<(), InstructionError> {
let mut storage_contract = &mut self.account.state()?;
if let StorageContract::ValidatorStorage {
slot: state_slot,
segment: state_segment,
hash: state_hash,
lockout_validations,
credits,
..
} = &mut storage_contract
{
let current_segment = get_segment_from_slot(current.slot);
let original_segment = get_segment_from_slot(*state_slot);
let segment = get_segment_from_slot(slot);
debug!(
"advertise new segment: {} orig: {}",
segment, current_segment
segment, current.segment
);
if segment < original_segment || segment >= current_segment {
if segment < *state_segment || segment > current.segment {
return Err(InstructionError::CustomError(
StorageError::InvalidSegment as u32,
));
}
*state_slot = slot;
*state_segment = segment;
*state_hash = hash;
// storage epoch updated, move the lockout_validations to credits
@ -285,21 +281,18 @@ impl<'a> StorageAccount<'a> {
&mut self,
me: &Pubkey,
current: syscall::current::Current,
segment: u64,
segment_index: u64,
proofs_per_account: Vec<Vec<ProofStatus>>,
replicator_accounts: &mut [StorageAccount],
) -> Result<(), InstructionError> {
let mut storage_contract = &mut self.account.state()?;
if let StorageContract::ValidatorStorage {
slot: state_slot,
segment: state_segment,
lockout_validations,
..
} = &mut storage_contract
{
let segment_index = segment as usize;
let state_segment = get_segment_from_slot(*state_slot);
if segment_index > state_segment {
if segment_index > *state_segment {
return Err(InstructionError::CustomError(
StorageError::InvalidSegment as u32,
));
@ -460,7 +453,7 @@ fn store_validation_result(
me: &Pubkey,
current: &syscall::current::Current,
storage_account: &mut StorageAccount,
segment: usize,
segment: u64,
proof_mask: &[ProofStatus],
) -> Result<(), InstructionError> {
let mut storage_contract = storage_account.account.state()?;
@ -494,7 +487,7 @@ fn store_validation_result(
}
fn count_valid_proofs(
validations: &BTreeMap<usize, BTreeMap<Pubkey, Vec<ProofStatus>>>,
validations: &BTreeMap<u64, BTreeMap<Pubkey, Vec<ProofStatus>>>,
) -> (u64, u64) {
let proofs = validations
.iter()
@ -537,7 +530,7 @@ mod tests {
contract = StorageContract::ValidatorStorage {
owner: Pubkey::default(),
slot: 0,
segment: 0,
hash: Hash::default(),
lockout_validations: BTreeMap::new(),
credits: Credits::default(),
@ -569,7 +562,7 @@ mod tests {
executable: false,
},
};
let segment_index = 0_usize;
let segment_index = 0;
let proof = Proof {
segment_index,
..Proof::default()

View File

@ -23,13 +23,13 @@ pub enum StorageInstruction {
SubmitMiningProof {
sha_state: Hash,
segment_index: usize,
segment_index: u64,
signature: Signature,
blockhash: Hash,
},
AdvertiseStorageRecentBlockhash {
hash: Hash,
slot: u64,
segment: u64,
},
/// Redeem storage reward credits
///
@ -132,7 +132,7 @@ pub fn create_replicator_storage_account(
pub fn mining_proof(
storage_pubkey: &Pubkey,
sha_state: Hash,
segment_index: usize,
segment_index: u64,
signature: Signature,
blockhash: Hash,
) -> Instruction {
@ -152,11 +152,11 @@ pub fn mining_proof(
pub fn advertise_recent_blockhash(
storage_pubkey: &Pubkey,
storage_hash: Hash,
slot: u64,
segment: u64,
) -> Instruction {
let storage_instruction = StorageInstruction::AdvertiseStorageRecentBlockhash {
hash: storage_hash,
slot,
segment,
};
let account_metas = vec![
AccountMeta::new(*storage_pubkey, true),

View File

@ -51,13 +51,13 @@ pub fn process_instruction(
current,
)
}
StorageInstruction::AdvertiseStorageRecentBlockhash { hash, slot } => {
StorageInstruction::AdvertiseStorageRecentBlockhash { hash, segment } => {
if me_unsigned || rest.len() != 1 {
// This instruction must be signed by `me`
Err(InstructionError::InvalidArgument)?;
}
let current = syscall::current::from_keyed_account(&rest[0])?;
storage_account.advertise_storage_recent_blockhash(hash, slot, current)
storage_account.advertise_storage_recent_blockhash(hash, segment, current)
}
StorageInstruction::ClaimStorageReward => {
if rest.len() != 4 {

View File

@ -16,17 +16,18 @@ use solana_sdk::syscall::current::Current;
use solana_sdk::syscall::rewards::Rewards;
use solana_sdk::syscall::{current, rewards};
use solana_sdk::system_instruction;
use solana_sdk::timing::DEFAULT_TICKS_PER_SLOT;
use solana_sdk::timing::{
get_segment_from_slot, DEFAULT_SLOTS_PER_SEGMENT, DEFAULT_TICKS_PER_SLOT,
};
use solana_storage_api::id;
use solana_storage_api::storage_contract::StorageAccount;
use solana_storage_api::storage_contract::{ProofStatus, StorageContract, STORAGE_ACCOUNT_SPACE};
use solana_storage_api::storage_instruction;
use solana_storage_api::storage_processor::process_instruction;
use solana_storage_api::SLOTS_PER_SEGMENT;
use solana_storage_api::{get_segment_from_slot, id};
use std::collections::HashMap;
use std::sync::Arc;
const TICKS_IN_SEGMENT: u64 = SLOTS_PER_SEGMENT * DEFAULT_TICKS_PER_SLOT;
const TICKS_IN_SEGMENT: u64 = DEFAULT_SLOTS_PER_SEGMENT * DEFAULT_TICKS_PER_SLOT;
fn test_instruction(
ix: &Instruction,
@ -125,10 +126,11 @@ fn test_proof_bounds() {
Hash::default(),
);
// the proof is for segment 0, need to move the slot into segment 2
let mut current_account = current::create_account(1, 0, 0, 0);
let mut current_account = current::create_account(1, 0, 0, 0, 0);
Current::to(
&Current {
slot: SLOTS_PER_SEGMENT * 2,
slot: DEFAULT_SLOTS_PER_SEGMENT * 2,
segment: 2,
epoch: 0,
stakers_epoch: 0,
},
@ -155,15 +157,11 @@ fn test_serialize_overflow() {
let current_id = current::id();
let mut keyed_accounts = Vec::new();
let mut user_account = Account::default();
let mut current_account = current::create_account(1, 0, 0, 0);
let mut current_account = current::create_account(1, 0, 0, 0, 0);
keyed_accounts.push(KeyedAccount::new(&pubkey, true, &mut user_account));
keyed_accounts.push(KeyedAccount::new(&current_id, false, &mut current_account));
let ix = storage_instruction::advertise_recent_blockhash(
&pubkey,
Hash::default(),
SLOTS_PER_SEGMENT,
);
let ix = storage_instruction::advertise_recent_blockhash(&pubkey, Hash::default(), 1);
assert_eq!(
process_instruction(&id(), &mut keyed_accounts, &ix.data),
@ -184,10 +182,11 @@ fn test_invalid_accounts_len() {
Hash::default(),
);
// move tick height into segment 1
let mut current_account = current::create_account(1, 0, 0, 0);
let mut current_account = current::create_account(1, 0, 0, 0, 0);
Current::to(
&Current {
slot: 16,
segment: 1,
epoch: 0,
stakers_epoch: 0,
},
@ -243,10 +242,11 @@ fn test_submit_mining_ok() {
Hash::default(),
);
// move slot into segment 1
let mut current_account = current::create_account(1, 0, 0, 0);
let mut current_account = current::create_account(1, 0, 0, 0, 0);
Current::to(
&Current {
slot: SLOTS_PER_SEGMENT,
slot: DEFAULT_SLOTS_PER_SEGMENT,
segment: 1,
epoch: 0,
stakers_epoch: 0,
},
@ -300,7 +300,7 @@ fn test_validate_mining() {
let bank = Arc::new(Bank::new_from_parent(
&bank,
&Pubkey::default(),
SLOTS_PER_SEGMENT * 2,
DEFAULT_SLOTS_PER_SEGMENT * 2,
));
let bank_client = BankClient::new_shared(&bank);
@ -309,7 +309,7 @@ fn test_validate_mining() {
vec![storage_instruction::advertise_recent_blockhash(
&validator_storage_id,
Hash::default(),
SLOTS_PER_SEGMENT,
1,
)],
Some(&mint_pubkey),
);
@ -344,17 +344,17 @@ fn test_validate_mining() {
vec![storage_instruction::advertise_recent_blockhash(
&validator_storage_id,
Hash::default(),
SLOTS_PER_SEGMENT * 2,
2,
)],
Some(&mint_pubkey),
);
// move banks into the next segment
let proof_segment = get_segment_from_slot(bank.slot());
let proof_segment = get_segment_from_slot(bank.slot(), bank.slots_per_segment());
let bank = Arc::new(Bank::new_from_parent(
&bank,
&Pubkey::default(),
SLOTS_PER_SEGMENT + bank.slot(),
DEFAULT_SLOTS_PER_SEGMENT + bank.slot(),
));
let bank_client = BankClient::new_shared(&bank);
@ -381,7 +381,7 @@ fn test_validate_mining() {
vec![storage_instruction::advertise_recent_blockhash(
&validator_storage_id,
Hash::default(),
SLOTS_PER_SEGMENT * 3,
3,
)],
Some(&mint_pubkey),
);
@ -390,7 +390,7 @@ fn test_validate_mining() {
let bank = Arc::new(Bank::new_from_parent(
&bank,
&Pubkey::default(),
SLOTS_PER_SEGMENT + bank.slot(),
DEFAULT_SLOTS_PER_SEGMENT + bank.slot(),
));
let bank_client = BankClient::new_shared(&bank);
@ -505,21 +505,21 @@ fn init_storage_accounts(
client.send_message(&[mint], message).unwrap();
}
fn get_storage_slot<C: SyncClient>(client: &C, account: &Pubkey) -> u64 {
fn get_storage_segment<C: SyncClient>(client: &C, account: &Pubkey) -> u64 {
match client.get_account_data(&account).unwrap() {
Some(storage_system_account_data) => {
let contract = deserialize(&storage_system_account_data);
if let Ok(contract) = contract {
match contract {
StorageContract::ValidatorStorage { slot, .. } => {
return slot;
StorageContract::ValidatorStorage { segment, .. } => {
return segment;
}
_ => info!("error in reading slot"),
_ => info!("error in reading segment"),
}
}
}
None => {
info!("error in reading slot");
info!("error in reading segment");
}
}
0
@ -536,7 +536,7 @@ fn submit_proof(
vec![storage_instruction::mining_proof(
&storage_keypair.pubkey(),
sha_state,
segment_index as usize,
segment_index,
Signature::default(),
bank_client.get_recent_blockhash().unwrap().0,
)],
@ -584,7 +584,11 @@ fn test_bank_storage() {
let bank = Bank::new(&genesis_block);
// tick the bank up until it's moved into storage segment 2
// create a new bank in storage segment 2
let bank = Bank::new_from_parent(&Arc::new(bank), &Pubkey::new_rand(), SLOTS_PER_SEGMENT * 2);
let bank = Bank::new_from_parent(
&Arc::new(bank),
&Pubkey::new_rand(),
DEFAULT_SLOTS_PER_SEGMENT * 2,
);
let bank_client = BankClient::new(bank);
let x = 42;
@ -615,7 +619,7 @@ fn test_bank_storage() {
vec![storage_instruction::advertise_recent_blockhash(
&validator_pubkey,
storage_blockhash,
SLOTS_PER_SEGMENT as u64,
1,
)],
Some(&mint_pubkey),
);
@ -641,10 +645,7 @@ fn test_bank_storage() {
Ok(_)
);
assert_eq!(
get_storage_slot(&bank_client, &validator_pubkey),
SLOTS_PER_SEGMENT
);
assert_eq!(get_storage_segment(&bank_client, &validator_pubkey), 1);
assert_eq!(
get_storage_blockhash(&bank_client, &validator_pubkey),
storage_blockhash

View File

@ -168,7 +168,7 @@ mod tests {
.iter()
.map(|meta| {
if syscall::current::check_id(&meta.pubkey) {
syscall::current::create_account(1, 0, 0, 0)
syscall::current::create_account(1, 0, 0, 0, 0)
} else if syscall::slot_hashes::check_id(&meta.pubkey) {
syscall::slot_hashes::create_account(1, &[])
} else {