Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
Add tick height syscall (#4497)
Browse files Browse the repository at this point in the history
* Remove tick_height from entrypoint signature

* Impl tick_height syscall and use in storage program

* Properly remove tick height from bpf handling
  • Loading branch information
Tyera Eulberg authored May 31, 2019
1 parent ce04d2b commit 64e8a21
Show file tree
Hide file tree
Showing 22 changed files with 153 additions and 107 deletions.
2 changes: 0 additions & 2 deletions programs/bpf/rust/noop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
5 changes: 1 addition & 4 deletions programs/bpf_loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>());

Expand All @@ -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
}
Expand Down Expand Up @@ -281,7 +279,6 @@ fn entrypoint(
program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount],
tx_data: &[u8],
tick_height: u64,
) -> Result<(), InstructionError> {
solana_logger::setup();

Expand All @@ -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) => {
Expand Down
1 change: 0 additions & 1 deletion programs/budget_api/src/budget_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion programs/config_api/src/config_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()");
Expand Down
1 change: 0 additions & 1 deletion programs/exchange_api/src/exchange_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
1 change: 0 additions & 1 deletion programs/failure_program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ fn entrypoint(
_program_id: &Pubkey,
_keyed_accounts: &mut [KeyedAccount],
_data: &[u8],
_tick_height: u64,
) -> Result<(), InstructionError> {
Err(InstructionError::GenericError)
}
2 changes: 0 additions & 2 deletions programs/noop_program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
13 changes: 1 addition & 12 deletions programs/stake_api/src/stake_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -234,7 +228,6 @@ mod tests {
&mut Account::default(),
)],
&serialize(&StakeInstruction::DelegateStake).unwrap(),
0,
),
Err(InstructionError::InvalidInstructionData),
);
Expand All @@ -248,7 +241,6 @@ mod tests {
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
],
&serialize(&StakeInstruction::DelegateStake).unwrap(),
0,
),
Err(InstructionError::InvalidInstructionData),
);
Expand All @@ -262,7 +254,6 @@ mod tests {
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
],
&serialize(&StakeInstruction::RedeemVoteCredits).unwrap(),
0,
),
Err(InstructionError::InvalidInstructionData),
);
Expand All @@ -277,7 +268,6 @@ mod tests {
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
],
&serialize(&StakeInstruction::DelegateStake).unwrap(),
0,
),
Err(InstructionError::InvalidAccountData),
);
Expand All @@ -293,7 +283,6 @@ mod tests {
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
],
&serialize(&StakeInstruction::RedeemVoteCredits).unwrap(),
0,
),
Err(InstructionError::InvalidAccountData),
);
Expand Down
12 changes: 10 additions & 2 deletions programs/storage_api/src/storage_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)
}

Expand All @@ -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)
}

Expand Down Expand Up @@ -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)
}
52 changes: 29 additions & 23 deletions programs/storage_api/src/storage_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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,
Expand All @@ -57,20 +58,22 @@ 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,
tick_height / DEFAULT_TICKS_PER_SLOT,
)
}
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,
Expand Down Expand Up @@ -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;

Expand All @@ -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
Expand All @@ -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
}
Expand All @@ -159,27 +162,29 @@ 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]
fn test_storage_tx() {
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,
Expand All @@ -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)
);
}
Expand All @@ -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]
Expand All @@ -222,29 +229,28 @@ 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();
}

let ix =
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]
Expand Down
1 change: 0 additions & 1 deletion programs/token_api/src/token_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ pub fn process_instruction(
program_id: &Pubkey,
info: &mut [KeyedAccount],
input: &[u8],
_tick_height: u64,
) -> Result<(), InstructionError> {
solana_logger::setup();

Expand Down
Loading

0 comments on commit 64e8a21

Please sign in to comment.