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:
@ -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);
|
||||
|
||||
|
@ -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) => {
|
||||
|
@ -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);
|
||||
|
@ -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()");
|
||||
|
@ -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();
|
||||
|
||||
|
@ -8,7 +8,6 @@ fn entrypoint(
|
||||
_program_id: &Pubkey,
|
||||
_keyed_accounts: &mut [KeyedAccount],
|
||||
_data: &[u8],
|
||||
_tick_height: u64,
|
||||
) -> Result<(), InstructionError> {
|
||||
Err(InstructionError::GenericError)
|
||||
}
|
||||
|
@ -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(())
|
||||
}
|
||||
|
@ -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),
|
||||
);
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -8,7 +8,6 @@ pub fn process_instruction(
|
||||
program_id: &Pubkey,
|
||||
info: &mut [KeyedAccount],
|
||||
input: &[u8],
|
||||
_tick_height: u64,
|
||||
) -> Result<(), InstructionError> {
|
||||
solana_logger::setup();
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user