Add tick height syscall (#4497)

* Remove tick_height from entrypoint signature

* Impl tick_height syscall and use in storage program

* Properly remove tick height from bpf handling
This commit is contained in:
Tyera Eulberg
2019-05-31 16:29:21 -06:00
committed by GitHub
parent ce04d2bfc2
commit 64e8a21d73
22 changed files with 153 additions and 107 deletions

View File

@ -25,8 +25,6 @@ fn process_instruction(
info: &SolClusterInfo,
data: &[u8],
) -> bool {
sol_log("Tick height:");
sol_log_64(info.tick_height, 0, 0, 0, 0);
sol_log("Program identifier:");
sol_log_key(&info.program_id);

View File

@ -233,7 +233,6 @@ fn serialize_parameters(
program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount],
data: &[u8],
tick_height: u64,
) -> Vec<u8> {
assert_eq!(32, mem::size_of::<Pubkey>());
@ -252,7 +251,6 @@ fn serialize_parameters(
}
v.write_u64::<LittleEndian>(data.len() as u64).unwrap();
v.write_all(data).unwrap();
v.write_u64::<LittleEndian>(tick_height).unwrap();
v.write_all(program_id.as_ref()).unwrap();
v
}
@ -281,7 +279,6 @@ fn entrypoint(
program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount],
tx_data: &[u8],
tick_height: u64,
) -> Result<(), InstructionError> {
solana_logger::setup();
@ -296,7 +293,7 @@ fn entrypoint(
return Err(InstructionError::GenericError);
}
};
let mut v = serialize_parameters(program_id, params, &tx_data, tick_height);
let mut v = serialize_parameters(program_id, params, &tx_data);
match vm.execute_program(v.as_mut_slice(), &[], &[heap_region]) {
Ok(status) => {

View File

@ -74,7 +74,6 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount],
data: &[u8],
_tick_height: u64,
) -> Result<(), InstructionError> {
let instruction = deserialize(data).map_err(|err| {
info!("Invalid transaction data: {:?} {:?}", data, err);

View File

@ -9,7 +9,6 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount],
data: &[u8],
_tick_height: u64,
) -> Result<(), InstructionError> {
if keyed_accounts[0].signer_key().is_none() {
error!("account[0].signer_key().is_none()");

View File

@ -429,7 +429,6 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount],
data: &[u8],
_tick_height: u64,
) -> Result<(), InstructionError> {
solana_logger::setup();

View File

@ -8,7 +8,6 @@ fn entrypoint(
_program_id: &Pubkey,
_keyed_accounts: &mut [KeyedAccount],
_data: &[u8],
_tick_height: u64,
) -> Result<(), InstructionError> {
Err(InstructionError::GenericError)
}

View File

@ -9,12 +9,10 @@ fn entrypoint(
program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount],
data: &[u8],
tick_height: u64,
) -> Result<(), InstructionError> {
solana_logger::setup();
trace!("noop: program_id: {:?}", program_id);
trace!("noop: keyed_accounts: {:#?}", keyed_accounts);
trace!("noop: data: {:?}", data);
trace!("noop: tick_height: {:?}", tick_height);
Ok(())
}

View File

@ -122,7 +122,6 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount],
data: &[u8],
_tick_height: u64,
) -> Result<(), InstructionError> {
solana_logger::setup();
@ -190,12 +189,7 @@ mod tests {
.zip(accounts.iter_mut())
.map(|(meta, account)| KeyedAccount::new(&meta.pubkey, meta.is_signer, account))
.collect();
super::process_instruction(
&Pubkey::default(),
&mut keyed_accounts,
&instruction.data,
0,
)
super::process_instruction(&Pubkey::default(), &mut keyed_accounts, &instruction.data)
}
}
@ -234,7 +228,6 @@ mod tests {
&mut Account::default(),
)],
&serialize(&StakeInstruction::DelegateStake).unwrap(),
0,
),
Err(InstructionError::InvalidInstructionData),
);
@ -248,7 +241,6 @@ mod tests {
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
],
&serialize(&StakeInstruction::DelegateStake).unwrap(),
0,
),
Err(InstructionError::InvalidInstructionData),
);
@ -262,7 +254,6 @@ mod tests {
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
],
&serialize(&StakeInstruction::RedeemVoteCredits).unwrap(),
0,
),
Err(InstructionError::InvalidInstructionData),
);
@ -277,7 +268,6 @@ mod tests {
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
],
&serialize(&StakeInstruction::DelegateStake).unwrap(),
0,
),
Err(InstructionError::InvalidAccountData),
);
@ -293,7 +283,6 @@ mod tests {
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
],
&serialize(&StakeInstruction::RedeemVoteCredits).unwrap(),
0,
),
Err(InstructionError::InvalidAccountData),
);

View File

@ -5,6 +5,7 @@ use solana_sdk::hash::Hash;
use solana_sdk::instruction::{AccountMeta, Instruction};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::Signature;
use solana_sdk::syscall::tick_height;
use solana_sdk::system_instruction;
use std::collections::HashMap;
@ -118,7 +119,10 @@ pub fn mining_proof(
signature,
proof_index,
};
let account_metas = vec![AccountMeta::new(*storage_pubkey, true)];
let account_metas = vec![
AccountMeta::new(*storage_pubkey, true),
AccountMeta::new(tick_height::id(), false),
];
Instruction::new(id(), &storage_instruction, account_metas)
}
@ -131,7 +135,10 @@ pub fn advertise_recent_blockhash(
hash: storage_hash,
slot,
};
let account_metas = vec![AccountMeta::new(*storage_pubkey, true)];
let account_metas = vec![
AccountMeta::new(*storage_pubkey, true),
AccountMeta::new(tick_height::id(), false),
];
Instruction::new(id(), &storage_instruction, account_metas)
}
@ -159,6 +166,7 @@ pub fn claim_reward(
let account_metas = vec![
AccountMeta::new(*storage_pubkey, false),
AccountMeta::new(*mining_pool_pubkey, false),
AccountMeta::new(tick_height::id(), false),
];
Instruction::new(id(), &storage_instruction, account_metas)
}

View File

@ -6,13 +6,13 @@ use crate::storage_instruction::StorageInstruction;
use solana_sdk::account::KeyedAccount;
use solana_sdk::instruction::InstructionError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::syscall::tick_height::TickHeight;
use solana_sdk::timing::DEFAULT_TICKS_PER_SLOT;
pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount],
data: &[u8],
tick_height: u64,
) -> Result<(), InstructionError> {
solana_logger::setup();
@ -45,10 +45,11 @@ pub fn process_instruction(
signature,
..
} => {
if me_unsigned || !rest.is_empty() {
if me_unsigned || rest.len() != 1 {
// This instruction must be signed by `me`
Err(InstructionError::InvalidArgument)?;
}
let tick_height = TickHeight::from(&rest[0].account).unwrap();
storage_account.submit_mining_proof(
sha_state,
slot,
@ -57,10 +58,11 @@ pub fn process_instruction(
)
}
StorageInstruction::AdvertiseStorageRecentBlockhash { hash, slot } => {
if me_unsigned || !rest.is_empty() {
if me_unsigned || rest.len() != 1 {
// This instruction must be signed by `me`
Err(InstructionError::InvalidArgument)?;
}
let tick_height = TickHeight::from(&rest[0].account).unwrap();
storage_account.advertise_storage_recent_blockhash(
hash,
slot,
@ -68,9 +70,10 @@ pub fn process_instruction(
)
}
StorageInstruction::ClaimStorageReward { slot } => {
if rest.len() != 1 {
if rest.len() != 2 {
Err(InstructionError::InvalidArgument)?;
}
let tick_height = TickHeight::from(&rest[1].account).unwrap();
storage_account.claim_storage_reward(
&mut rest[0],
slot,
@ -114,6 +117,7 @@ mod tests {
use solana_sdk::message::Message;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
use solana_sdk::syscall::tick_height;
use std::collections::HashMap;
use std::sync::Arc;
@ -122,7 +126,6 @@ mod tests {
fn test_instruction(
ix: &Instruction,
program_accounts: &mut [Account],
tick_height: u64,
) -> Result<(), InstructionError> {
let mut keyed_accounts: Vec<_> = ix
.accounts
@ -133,7 +136,7 @@ mod tests {
})
.collect();
let ret = process_instruction(&id(), &mut keyed_accounts, &ix.data, tick_height);
let ret = process_instruction(&id(), &mut keyed_accounts, &ix.data);
info!("ret: {:?}", ret);
ret
}
@ -159,11 +162,10 @@ mod tests {
);
// the proof is for slot 16, which is in segment 0, need to move the tick height into segment 2
let ticks_till_next_segment = TICKS_IN_SEGMENT * 2;
let mut tick_account = tick_height::create_account(1);
TickHeight::to(ticks_till_next_segment, &mut tick_account);
assert_eq!(
test_instruction(&ix, &mut [account], ticks_till_next_segment),
Ok(())
);
assert_eq!(test_instruction(&ix, &mut [account, tick_account]), Ok(()));
}
#[test]
@ -171,15 +173,18 @@ mod tests {
let pubkey = Pubkey::new_rand();
let mut accounts = [(pubkey, Account::default())];
let mut keyed_accounts = create_keyed_accounts(&mut accounts);
assert!(process_instruction(&id(), &mut keyed_accounts, &[], 42).is_err());
assert!(process_instruction(&id(), &mut keyed_accounts, &[]).is_err());
}
#[test]
fn test_serialize_overflow() {
let pubkey = Pubkey::new_rand();
let tick_pubkey = Pubkey::new_rand();
let mut keyed_accounts = Vec::new();
let mut user_account = Account::default();
let mut tick_account = tick_height::create_account(1);
keyed_accounts.push(KeyedAccount::new(&pubkey, true, &mut user_account));
keyed_accounts.push(KeyedAccount::new(&tick_pubkey, false, &mut tick_account));
let ix = storage_instruction::advertise_recent_blockhash(
&pubkey,
@ -188,7 +193,7 @@ mod tests {
);
assert_eq!(
process_instruction(&id(), &mut keyed_accounts, &ix.data, 42),
process_instruction(&id(), &mut keyed_accounts, &ix.data),
Err(InstructionError::InvalidAccountData)
);
}
@ -202,12 +207,14 @@ mod tests {
storage_instruction::mining_proof(&pubkey, Hash::default(), 0, Signature::default(), 0);
// move tick height into segment 1
let ticks_till_next_segment = TICKS_IN_SEGMENT + 1;
let mut tick_account = tick_height::create_account(1);
TickHeight::to(ticks_till_next_segment, &mut tick_account);
assert!(test_instruction(&ix, &mut accounts, ticks_till_next_segment).is_err());
assert!(test_instruction(&ix, &mut accounts).is_err());
let mut accounts = [Account::default(), Account::default(), Account::default()];
let mut accounts = [Account::default(), tick_account, Account::default()];
assert!(test_instruction(&ix, &mut accounts, ticks_till_next_segment).is_err());
assert!(test_instruction(&ix, &mut accounts).is_err());
}
#[test]
@ -222,17 +229,17 @@ mod tests {
storage_instruction::mining_proof(&pubkey, Hash::default(), 0, Signature::default(), 0);
// submitting a proof for a slot in the past, so this should fail
assert!(test_instruction(&ix, &mut accounts, 0).is_err());
assert!(test_instruction(&ix, &mut accounts).is_err());
}
#[test]
fn test_submit_mining_ok() {
solana_logger::setup();
let pubkey = Pubkey::new_rand();
let mut accounts = [Account::default(), Account::default()];
accounts[0].data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
let mut account = Account::default();
account.data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
{
let mut storage_account = StorageAccount::new(&mut accounts[0]);
let mut storage_account = StorageAccount::new(&mut account);
storage_account.initialize_replicator_storage().unwrap();
}
@ -240,11 +247,10 @@ mod tests {
storage_instruction::mining_proof(&pubkey, Hash::default(), 0, Signature::default(), 0);
// move tick height into segment 1
let ticks_till_next_segment = TICKS_IN_SEGMENT + 1;
let mut tick_account = tick_height::create_account(1);
TickHeight::to(ticks_till_next_segment, &mut tick_account);
assert_matches!(
test_instruction(&ix, &mut accounts, ticks_till_next_segment),
Ok(_)
);
assert_matches!(test_instruction(&ix, &mut [account, tick_account]), Ok(_));
}
#[test]

View File

@ -8,7 +8,6 @@ pub fn process_instruction(
program_id: &Pubkey,
info: &mut [KeyedAccount],
input: &[u8],
_tick_height: u64,
) -> Result<(), InstructionError> {
solana_logger::setup();

View File

@ -95,7 +95,6 @@ pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount],
data: &[u8],
_tick_height: u64,
) -> Result<(), InstructionError> {
solana_logger::setup();
@ -136,7 +135,7 @@ mod tests {
#[test]
fn test_vote_process_instruction_decode_bail() {
assert_eq!(
super::process_instruction(&Pubkey::default(), &mut [], &[], 0,),
super::process_instruction(&Pubkey::default(), &mut [], &[],),
Err(InstructionError::InvalidInstructionData),
);
}
@ -153,12 +152,7 @@ mod tests {
.zip(accounts.iter_mut())
.map(|(meta, account)| KeyedAccount::new(&meta.pubkey, meta.is_signer, account))
.collect();
super::process_instruction(
&Pubkey::default(),
&mut keyed_accounts,
&instruction.data,
0,
)
super::process_instruction(&Pubkey::default(), &mut keyed_accounts, &instruction.data)
}
}