Rename userdata to data (#3282)
* Rename userdata to data Instead of saying "userdata", which is ambiguous and imprecise, say "instruction data" or "account data". Also, add `ProgramError::InvalidInstructionData` Fixes #2761
This commit is contained in:
@ -123,8 +123,8 @@ pub fn sol_log_params(ka: &[SolKeyedAccount], data: &[u8]) {
|
||||
sol_log_key(&k.key);
|
||||
sol_log("- Lamports");
|
||||
sol_log_64(0, 0, 0, 0, k.lamports);
|
||||
sol_log("- Userdata");
|
||||
sol_log_slice(k.userdata);
|
||||
sol_log("- AccountData");
|
||||
sol_log_slice(k.data);
|
||||
sol_log("- Owner");
|
||||
sol_log_key(&k.owner);
|
||||
}
|
||||
@ -148,7 +148,7 @@ pub struct SolKeyedAccount<'a> {
|
||||
/// Number of lamports owned by this account
|
||||
pub lamports: u64,
|
||||
/// On-chain data within this account
|
||||
pub userdata: &'a [u8],
|
||||
pub data: &'a [u8],
|
||||
/// Program that owns this account
|
||||
pub owner: SolPubkey<'a>,
|
||||
}
|
||||
@ -200,15 +200,15 @@ pub extern "C" fn entrypoint(input: *mut u8) -> bool {
|
||||
};
|
||||
offset += size_of::<u64>();
|
||||
|
||||
let userdata_length = unsafe {
|
||||
let data_length = unsafe {
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
let userdata_length_ptr: *const u64 = input.add(offset) as *const u64;
|
||||
*userdata_length_ptr
|
||||
let data_length_ptr: *const u64 = input.add(offset) as *const u64;
|
||||
*data_length_ptr
|
||||
} as usize;
|
||||
offset += size_of::<u64>();
|
||||
|
||||
let userdata = unsafe { from_raw_parts(input.add(offset), userdata_length) };
|
||||
offset += userdata_length;
|
||||
let data = unsafe { from_raw_parts(input.add(offset), data_length) };
|
||||
offset += data_length;
|
||||
|
||||
let owner_slice = unsafe { from_raw_parts(input.add(offset), SIZE_PUBKEY) };
|
||||
let owner = SolPubkey { key: &owner_slice };
|
||||
@ -218,7 +218,7 @@ pub extern "C" fn entrypoint(input: *mut u8) -> bool {
|
||||
key,
|
||||
is_signer,
|
||||
lamports,
|
||||
userdata,
|
||||
data,
|
||||
owner,
|
||||
}];
|
||||
|
||||
@ -386,7 +386,7 @@ mod tests {
|
||||
assert_eq!(SIZE_PUBKEY, ka[0].key.key.len());
|
||||
assert_eq!(key, ka[0].key.key);
|
||||
assert_eq!(48, ka[0].lamports);
|
||||
assert_eq!(1, ka[0].userdata.len());
|
||||
assert_eq!(1, ka[0].data.len());
|
||||
let owner = [0; 32];
|
||||
assert_eq!(SIZE_PUBKEY, ka[0].owner.key.len());
|
||||
assert_eq!(owner, ka[0].owner.key);
|
||||
|
@ -148,9 +148,9 @@ fn serialize_parameters(
|
||||
.unwrap();
|
||||
v.write_all(info.unsigned_key().as_ref()).unwrap();
|
||||
v.write_u64::<LittleEndian>(info.account.lamports).unwrap();
|
||||
v.write_u64::<LittleEndian>(info.account.userdata.len() as u64)
|
||||
v.write_u64::<LittleEndian>(info.account.data.len() as u64)
|
||||
.unwrap();
|
||||
v.write_all(&info.account.userdata).unwrap();
|
||||
v.write_all(&info.account.data).unwrap();
|
||||
v.write_all(info.account.owner.as_ref()).unwrap();
|
||||
}
|
||||
v.write_u64::<LittleEndian>(data.len() as u64).unwrap();
|
||||
@ -171,10 +171,10 @@ fn deserialize_parameters(keyed_accounts: &mut [KeyedAccount], buffer: &[u8]) {
|
||||
|
||||
start += mem::size_of::<u64>() // skip lamports
|
||||
+ mem::size_of::<u64>(); // skip length tag
|
||||
let end = start + info.account.userdata.len();
|
||||
info.account.userdata.clone_from_slice(&buffer[start..end]);
|
||||
let end = start + info.account.data.len();
|
||||
info.account.data.clone_from_slice(&buffer[start..end]);
|
||||
|
||||
start += info.account.userdata.len() // skip userdata
|
||||
start += info.account.data.len() // skip data
|
||||
+ mem::size_of::<Pubkey>(); // skip owner
|
||||
}
|
||||
}
|
||||
@ -190,7 +190,7 @@ fn entrypoint(
|
||||
|
||||
if keyed_accounts[0].account.executable {
|
||||
let (progs, params) = keyed_accounts.split_at_mut(1);
|
||||
let prog = &progs[0].account.userdata;
|
||||
let prog = &progs[0].account.data;
|
||||
info!("Call BPF program");
|
||||
//dump_program(keyed_accounts[0].key, prog);
|
||||
let mut vm = match create_vm(prog) {
|
||||
@ -228,15 +228,15 @@ fn entrypoint(
|
||||
let offset = offset as usize;
|
||||
let len = bytes.len();
|
||||
debug!("Write: offset={} length={}", offset, len);
|
||||
if keyed_accounts[0].account.userdata.len() < offset + len {
|
||||
if keyed_accounts[0].account.data.len() < offset + len {
|
||||
warn!(
|
||||
"Write overflow: {} < {}",
|
||||
keyed_accounts[0].account.userdata.len(),
|
||||
keyed_accounts[0].account.data.len(),
|
||||
offset + len
|
||||
);
|
||||
return Err(ProgramError::GenericError);
|
||||
}
|
||||
keyed_accounts[0].account.userdata[offset..offset + len].copy_from_slice(&bytes);
|
||||
keyed_accounts[0].account.data[offset..offset + len].copy_from_slice(&bytes);
|
||||
}
|
||||
LoaderInstruction::Finalize => {
|
||||
keyed_accounts[0].account.executable = true;
|
||||
|
@ -87,7 +87,7 @@ fn apply_debits(
|
||||
keyed_accounts[0].account.lamports += payment.lamports;
|
||||
Ok(())
|
||||
} else {
|
||||
let existing = BudgetState::deserialize(&keyed_accounts[0].account.userdata).ok();
|
||||
let existing = BudgetState::deserialize(&keyed_accounts[0].account.data).ok();
|
||||
if Some(true) == existing.map(|x| x.initialized) {
|
||||
trace!("contract already exists");
|
||||
Err(BudgetError::ContractAlreadyExists)
|
||||
@ -95,13 +95,12 @@ fn apply_debits(
|
||||
let mut budget_state = BudgetState::default();
|
||||
budget_state.pending_budget = Some(expr);
|
||||
budget_state.initialized = true;
|
||||
budget_state.serialize(&mut keyed_accounts[0].account.userdata)
|
||||
budget_state.serialize(&mut keyed_accounts[0].account.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
BudgetInstruction::ApplyTimestamp(dt) => {
|
||||
if let Ok(mut budget_state) =
|
||||
BudgetState::deserialize(&keyed_accounts[1].account.userdata)
|
||||
if let Ok(mut budget_state) = BudgetState::deserialize(&keyed_accounts[1].account.data)
|
||||
{
|
||||
if !budget_state.is_pending() {
|
||||
Err(BudgetError::ContractNotPending)
|
||||
@ -112,15 +111,14 @@ fn apply_debits(
|
||||
trace!("apply timestamp");
|
||||
apply_timestamp(&mut budget_state, keyed_accounts, *dt)?;
|
||||
trace!("apply timestamp committed");
|
||||
budget_state.serialize(&mut keyed_accounts[1].account.userdata)
|
||||
budget_state.serialize(&mut keyed_accounts[1].account.data)
|
||||
}
|
||||
} else {
|
||||
Err(BudgetError::UninitializedContract)
|
||||
}
|
||||
}
|
||||
BudgetInstruction::ApplySignature => {
|
||||
if let Ok(mut budget_state) =
|
||||
BudgetState::deserialize(&keyed_accounts[1].account.userdata)
|
||||
if let Ok(mut budget_state) = BudgetState::deserialize(&keyed_accounts[1].account.data)
|
||||
{
|
||||
if !budget_state.is_pending() {
|
||||
Err(BudgetError::ContractNotPending)
|
||||
@ -131,7 +129,7 @@ fn apply_debits(
|
||||
trace!("apply signature");
|
||||
apply_signature(&mut budget_state, keyed_accounts)?;
|
||||
trace!("apply signature committed");
|
||||
budget_state.serialize(&mut keyed_accounts[1].account.userdata)
|
||||
budget_state.serialize(&mut keyed_accounts[1].account.data)
|
||||
}
|
||||
} else {
|
||||
Err(BudgetError::UninitializedContract)
|
||||
@ -146,8 +144,8 @@ pub fn process_instruction(
|
||||
data: &[u8],
|
||||
) -> Result<(), BudgetError> {
|
||||
let instruction = deserialize(data).map_err(|err| {
|
||||
info!("Invalid transaction userdata: {:?} {:?}", data, err);
|
||||
BudgetError::UserdataDeserializeFailure
|
||||
info!("Invalid transaction data: {:?} {:?}", data, err);
|
||||
BudgetError::AccountDataDeserializeFailure
|
||||
})?;
|
||||
|
||||
trace!("process_instruction: {:?}", instruction);
|
||||
@ -178,12 +176,12 @@ mod test {
|
||||
let mut accounts = vec![Account::new(1, 0, &id()), Account::new(0, 512, &id())];
|
||||
let from = Keypair::new();
|
||||
let contract = Keypair::new();
|
||||
let userdata = (1u8, 2u8, 3u8);
|
||||
let data = (1u8, 2u8, 3u8);
|
||||
let tx = Transaction::new(
|
||||
&from,
|
||||
&[contract.pubkey()],
|
||||
&id(),
|
||||
&userdata,
|
||||
&data,
|
||||
Hash::default(),
|
||||
0,
|
||||
);
|
||||
@ -285,7 +283,7 @@ mod test {
|
||||
process_transaction(&tx, &mut accounts).unwrap();
|
||||
assert_eq!(accounts[from_account].lamports, 0);
|
||||
assert_eq!(accounts[contract_account].lamports, 1);
|
||||
let budget_state = BudgetState::deserialize(&accounts[contract_account].userdata).unwrap();
|
||||
let budget_state = BudgetState::deserialize(&accounts[contract_account].data).unwrap();
|
||||
assert!(budget_state.is_pending());
|
||||
|
||||
// Attack! Try to payout to a rando key
|
||||
@ -304,7 +302,7 @@ mod test {
|
||||
assert_eq!(accounts[contract_account].lamports, 1);
|
||||
assert_eq!(accounts[to_account].lamports, 0);
|
||||
|
||||
let budget_state = BudgetState::deserialize(&accounts[contract_account].userdata).unwrap();
|
||||
let budget_state = BudgetState::deserialize(&accounts[contract_account].data).unwrap();
|
||||
assert!(budget_state.is_pending());
|
||||
|
||||
// Now, acknowledge the time in the condition occurred and
|
||||
@ -321,7 +319,7 @@ mod test {
|
||||
assert_eq!(accounts[contract_account].lamports, 0);
|
||||
assert_eq!(accounts[to_account].lamports, 1);
|
||||
|
||||
let budget_state = BudgetState::deserialize(&accounts[contract_account].userdata).unwrap();
|
||||
let budget_state = BudgetState::deserialize(&accounts[contract_account].data).unwrap();
|
||||
assert!(!budget_state.is_pending());
|
||||
|
||||
// try to replay the timestamp contract
|
||||
@ -356,7 +354,7 @@ mod test {
|
||||
process_transaction(&tx, &mut accounts).unwrap();
|
||||
assert_eq!(accounts[from_account].lamports, 0);
|
||||
assert_eq!(accounts[contract_account].lamports, 1);
|
||||
let budget_state = BudgetState::deserialize(&accounts[contract_account].userdata).unwrap();
|
||||
let budget_state = BudgetState::deserialize(&accounts[contract_account].data).unwrap();
|
||||
assert!(budget_state.is_pending());
|
||||
|
||||
// Attack! try to put the lamports into the wrong account with cancel
|
||||
|
@ -12,8 +12,8 @@ pub enum BudgetError {
|
||||
UninitializedContract,
|
||||
DestinationMissing,
|
||||
FailedWitness,
|
||||
UserdataTooSmall,
|
||||
UserdataDeserializeFailure,
|
||||
AccountDataTooSmall,
|
||||
AccountDataDeserializeFailure,
|
||||
UnsignedKey,
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ impl BudgetState {
|
||||
|
||||
pub fn serialize(&self, output: &mut [u8]) -> Result<(), BudgetError> {
|
||||
serialize_into(output, self).map_err(|err| match *err {
|
||||
_ => BudgetError::UserdataTooSmall,
|
||||
_ => BudgetError::AccountDataTooSmall,
|
||||
})
|
||||
}
|
||||
|
||||
@ -56,18 +56,18 @@ mod test {
|
||||
fn test_serializer() {
|
||||
let mut a = Account::new(0, 512, &id());
|
||||
let b = BudgetState::default();
|
||||
b.serialize(&mut a.userdata).unwrap();
|
||||
let c = BudgetState::deserialize(&a.userdata).unwrap();
|
||||
b.serialize(&mut a.data).unwrap();
|
||||
let c = BudgetState::deserialize(&a.data).unwrap();
|
||||
assert_eq!(b, c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serializer_userdata_too_small() {
|
||||
fn test_serializer_data_too_small() {
|
||||
let mut a = Account::new(0, 1, &id());
|
||||
let b = BudgetState::default();
|
||||
assert_eq!(
|
||||
b.serialize(&mut a.userdata),
|
||||
Err(BudgetError::UserdataTooSmall)
|
||||
b.serialize(&mut a.data),
|
||||
Err(BudgetError::AccountDataTooSmall)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -151,11 +151,11 @@ impl BudgetTransaction {
|
||||
}
|
||||
|
||||
pub fn system_instruction(tx: &Transaction, index: usize) -> Option<SystemInstruction> {
|
||||
deserialize(&tx.userdata(index)).ok()
|
||||
deserialize(&tx.data(index)).ok()
|
||||
}
|
||||
|
||||
pub fn instruction(tx: &Transaction, index: usize) -> Option<BudgetInstruction> {
|
||||
deserialize(&tx.userdata(index)).ok()
|
||||
deserialize(&tx.data(index)).ok()
|
||||
}
|
||||
|
||||
/// Verify only the payment plan.
|
||||
@ -236,9 +236,9 @@ mod tests {
|
||||
payment.lamports = *lamports; // <-- attack, part 2!
|
||||
}
|
||||
}
|
||||
tx.instructions[1].userdata = serialize(&instruction).unwrap();
|
||||
tx.instructions[1].data = serialize(&instruction).unwrap();
|
||||
}
|
||||
tx.instructions[0].userdata = serialize(&system_instruction).unwrap();
|
||||
tx.instructions[0].data = serialize(&system_instruction).unwrap();
|
||||
assert!(BudgetTransaction::verify_plan(&tx));
|
||||
assert!(!tx.verify_signature());
|
||||
}
|
||||
@ -257,7 +257,7 @@ mod tests {
|
||||
payment.to = thief_keypair.pubkey(); // <-- attack!
|
||||
}
|
||||
}
|
||||
tx.instructions[1].userdata = serialize(&instruction).unwrap();
|
||||
tx.instructions[1].data = serialize(&instruction).unwrap();
|
||||
assert!(BudgetTransaction::verify_plan(&tx));
|
||||
assert!(!tx.verify_signature());
|
||||
}
|
||||
@ -274,7 +274,7 @@ mod tests {
|
||||
payment.lamports = 2; // <-- attack!
|
||||
}
|
||||
}
|
||||
tx.instructions[1].userdata = serialize(&instruction).unwrap();
|
||||
tx.instructions[1].data = serialize(&instruction).unwrap();
|
||||
assert!(!BudgetTransaction::verify_plan(&tx));
|
||||
|
||||
// Also, ensure all branchs of the plan spend all lamports
|
||||
@ -284,7 +284,7 @@ mod tests {
|
||||
payment.lamports = 0; // <-- whoops!
|
||||
}
|
||||
}
|
||||
tx.instructions[1].userdata = serialize(&instruction).unwrap();
|
||||
tx.instructions[1].data = serialize(&instruction).unwrap();
|
||||
assert!(!BudgetTransaction::verify_plan(&tx));
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ fn redeem_vote_credits(keyed_accounts: &mut [KeyedAccount]) -> Result<(), Progra
|
||||
// VoteInstruction::ClearCredits and that it points to the same vote account
|
||||
// as keyed_accounts[0].
|
||||
|
||||
let vote_state = VoteState::deserialize(&keyed_accounts[0].account.userdata)?;
|
||||
let vote_state = VoteState::deserialize(&keyed_accounts[0].account.data)?;
|
||||
|
||||
// TODO: This assumes the stake is static. If not, it should use the account value
|
||||
// at the time of voting, not at credit redemption.
|
||||
@ -75,7 +75,7 @@ fn entrypoint(
|
||||
trace!("process_instruction: {:?}", data);
|
||||
trace!("keyed_accounts: {:?}", keyed_accounts);
|
||||
|
||||
match deserialize(data).map_err(|_| ProgramError::InvalidUserdata)? {
|
||||
match deserialize(data).map_err(|_| ProgramError::InvalidInstructionData)? {
|
||||
RewardsInstruction::RedeemVoteCredits => redeem_vote_credits(keyed_accounts),
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ impl<'a> RewardsBank<'a> {
|
||||
self.bank.register_tick(&hash(blockhash.as_ref()));
|
||||
|
||||
let vote_account = self.bank.get_account(&vote_keypair.pubkey()).unwrap();
|
||||
Ok(VoteState::deserialize(&vote_account.userdata).unwrap())
|
||||
Ok(VoteState::deserialize(&vote_account.data).unwrap())
|
||||
}
|
||||
|
||||
fn redeem_credits(&self, rewards_id: &Pubkey, vote_keypair: &Keypair) -> Result<VoteState> {
|
||||
@ -60,7 +60,7 @@ impl<'a> RewardsBank<'a> {
|
||||
let tx = RewardsTransaction::new_redeem_credits(&vote_keypair, rewards_id, blockhash, 0);
|
||||
self.bank.process_transaction(&tx)?;
|
||||
let vote_account = self.bank.get_account(&vote_keypair.pubkey()).unwrap();
|
||||
Ok(VoteState::deserialize(&vote_account.userdata).unwrap())
|
||||
Ok(VoteState::deserialize(&vote_account.data).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ fn entrypoint(
|
||||
|
||||
if keyed_accounts.len() != 1 {
|
||||
// keyed_accounts[1] should be the main storage key
|
||||
// to access its userdata
|
||||
// to access its data
|
||||
Err(ProgramError::InvalidArgument)?;
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ fn entrypoint(
|
||||
|
||||
if let Ok(syscall) = bincode::deserialize(data) {
|
||||
let mut storage_account_state = if let Ok(storage_account_state) =
|
||||
bincode::deserialize(&keyed_accounts[0].account.userdata)
|
||||
bincode::deserialize(&keyed_accounts[0].account.data)
|
||||
{
|
||||
storage_account_state
|
||||
} else {
|
||||
@ -159,18 +159,18 @@ fn entrypoint(
|
||||
}
|
||||
|
||||
if bincode::serialize_into(
|
||||
&mut keyed_accounts[0].account.userdata[..],
|
||||
&mut keyed_accounts[0].account.data[..],
|
||||
&storage_account_state,
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return Err(ProgramError::UserdataTooSmall);
|
||||
return Err(ProgramError::AccountDataTooSmall);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
info!("Invalid instruction userdata: {:?}", data);
|
||||
Err(ProgramError::InvalidUserdata)
|
||||
info!("Invalid instruction data: {:?}", data);
|
||||
Err(ProgramError::InvalidInstructionData)
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ mod test {
|
||||
assert_eq!(tx.instructions.len(), 1);
|
||||
let Instruction {
|
||||
ref accounts,
|
||||
ref userdata,
|
||||
ref data,
|
||||
..
|
||||
} = tx.instructions[0];
|
||||
|
||||
@ -207,7 +207,7 @@ mod test {
|
||||
.map(|((key, is_signer), account)| KeyedAccount::new(key, is_signer, account))
|
||||
.collect();
|
||||
|
||||
let ret = entrypoint(&id(), &mut keyed_accounts, &userdata, 42);
|
||||
let ret = entrypoint(&id(), &mut keyed_accounts, &data, 42);
|
||||
info!("ret: {:?}", ret);
|
||||
ret
|
||||
}
|
||||
@ -236,8 +236,8 @@ mod test {
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
entrypoint(&id(), &mut keyed_accounts, &tx.instructions[0].userdata, 42),
|
||||
Err(ProgramError::UserdataTooSmall)
|
||||
entrypoint(&id(), &mut keyed_accounts, &tx.instructions[0].data, 42),
|
||||
Err(ProgramError::AccountDataTooSmall)
|
||||
);
|
||||
}
|
||||
|
||||
@ -265,7 +265,7 @@ mod test {
|
||||
solana_logger::setup();
|
||||
let keypair = Keypair::new();
|
||||
let mut accounts = [Account::default(), Account::default()];
|
||||
accounts[1].userdata.resize(16 * 1024, 0);
|
||||
accounts[1].data.resize(16 * 1024, 0);
|
||||
|
||||
let tx = StorageTransaction::new_mining_proof(
|
||||
&keypair,
|
||||
@ -284,7 +284,7 @@ mod test {
|
||||
solana_logger::setup();
|
||||
let keypair = Keypair::new();
|
||||
let mut accounts = [Account::default(), Account::default()];
|
||||
accounts[0].userdata.resize(16 * 1024, 0);
|
||||
accounts[0].data.resize(16 * 1024, 0);
|
||||
|
||||
let tx = StorageTransaction::new_advertise_recent_blockhash(
|
||||
&keypair,
|
||||
@ -311,7 +311,7 @@ mod test {
|
||||
solana_logger::setup();
|
||||
let keypair = Keypair::new();
|
||||
let mut accounts = [Account::default(), Account::default()];
|
||||
accounts[0].userdata.resize(16 * 1024, 0);
|
||||
accounts[0].data.resize(16 * 1024, 0);
|
||||
|
||||
let entry_height = 0;
|
||||
|
||||
|
@ -11,7 +11,7 @@ use solana_storage_api::{StorageTransaction, ENTRIES_PER_SEGMENT};
|
||||
fn get_storage_entry_height(bank: &Bank, account: &Pubkey) -> u64 {
|
||||
match bank.get_account(&account) {
|
||||
Some(storage_system_account) => {
|
||||
let state = deserialize(&storage_system_account.userdata);
|
||||
let state = deserialize(&storage_system_account.data);
|
||||
if let Ok(state) = state {
|
||||
let state: solana_storage_api::StorageProgramState = state;
|
||||
return state.entry_height;
|
||||
@ -26,7 +26,7 @@ fn get_storage_entry_height(bank: &Bank, account: &Pubkey) -> u64 {
|
||||
|
||||
fn get_storage_blockhash(bank: &Bank, account: &Pubkey) -> Hash {
|
||||
if let Some(storage_system_account) = bank.get_account(&account) {
|
||||
let state = deserialize(&storage_system_account.userdata);
|
||||
let state = deserialize(&storage_system_account.data);
|
||||
if let Ok(state) = state {
|
||||
let state: solana_storage_api::StorageProgramState = state;
|
||||
return state.hash;
|
||||
|
@ -413,7 +413,7 @@ impl TokenProgram {
|
||||
.map(|keyed_account| {
|
||||
let account = &keyed_account.account;
|
||||
if account.owner == *program_id {
|
||||
match Self::deserialize(&account.userdata) {
|
||||
match Self::deserialize(&account.data) {
|
||||
Ok(token_program) => token_program,
|
||||
Err(err) => {
|
||||
error!("deserialize failed: {:?}", err);
|
||||
@ -427,7 +427,7 @@ impl TokenProgram {
|
||||
.collect();
|
||||
|
||||
for program_account in &input_program_accounts {
|
||||
info!("input_program_account: userdata={:?}", program_account);
|
||||
info!("input_program_account: data={:?}", program_account);
|
||||
}
|
||||
|
||||
let mut output_program_accounts: Vec<(_, _)> = vec![];
|
||||
@ -468,10 +468,10 @@ impl TokenProgram {
|
||||
|
||||
for (index, program_account) in &output_program_accounts {
|
||||
info!(
|
||||
"output_program_account: index={} userdata={:?}",
|
||||
"output_program_account: index={} data={:?}",
|
||||
index, program_account
|
||||
);
|
||||
Self::serialize(program_account, &mut info[*index].account.userdata)?;
|
||||
Self::serialize(program_account, &mut info[*index].account.data)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -484,7 +484,7 @@ mod test {
|
||||
pub fn serde() {
|
||||
assert_eq!(TokenProgram::deserialize(&[0]), Ok(TokenProgram::default()));
|
||||
|
||||
let mut userdata = vec![0; 256];
|
||||
let mut data = vec![0; 256];
|
||||
|
||||
let account = TokenProgram::Account(TokenAccountInfo {
|
||||
token: Pubkey::new(&[1; 32]),
|
||||
@ -492,8 +492,8 @@ mod test {
|
||||
amount: 123,
|
||||
delegate: None,
|
||||
});
|
||||
account.serialize(&mut userdata).unwrap();
|
||||
assert_eq!(TokenProgram::deserialize(&userdata), Ok(account));
|
||||
account.serialize(&mut data).unwrap();
|
||||
assert_eq!(TokenProgram::deserialize(&data), Ok(account));
|
||||
|
||||
let account = TokenProgram::Token(TokenInfo {
|
||||
supply: 12345,
|
||||
@ -501,23 +501,23 @@ mod test {
|
||||
name: "A test token".to_string(),
|
||||
symbol: "TEST".to_string(),
|
||||
});
|
||||
account.serialize(&mut userdata).unwrap();
|
||||
assert_eq!(TokenProgram::deserialize(&userdata), Ok(account));
|
||||
account.serialize(&mut data).unwrap();
|
||||
assert_eq!(TokenProgram::deserialize(&data), Ok(account));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn serde_expect_fail() {
|
||||
let mut userdata = vec![0; 256];
|
||||
let mut data = vec![0; 256];
|
||||
|
||||
// Certain TokenProgram's may not be serialized
|
||||
let account = TokenProgram::default();
|
||||
assert_eq!(account, TokenProgram::Unallocated);
|
||||
assert!(account.serialize(&mut userdata).is_err());
|
||||
assert!(account.serialize(&mut userdata).is_err());
|
||||
assert!(account.serialize(&mut data).is_err());
|
||||
assert!(account.serialize(&mut data).is_err());
|
||||
let account = TokenProgram::Invalid;
|
||||
assert!(account.serialize(&mut userdata).is_err());
|
||||
assert!(account.serialize(&mut data).is_err());
|
||||
|
||||
// Bad deserialize userdata
|
||||
// Bad deserialize data
|
||||
assert!(TokenProgram::deserialize(&[]).is_err());
|
||||
assert!(TokenProgram::deserialize(&[1]).is_err());
|
||||
assert!(TokenProgram::deserialize(&[1, 2]).is_err());
|
||||
|
@ -22,7 +22,7 @@ fn entrypoint(
|
||||
trace!("process_instruction: {:?}", data);
|
||||
trace!("keyed_accounts: {:?}", keyed_accounts);
|
||||
|
||||
match deserialize(data).map_err(|_| ProgramError::InvalidUserdata)? {
|
||||
match deserialize(data).map_err(|_| ProgramError::InvalidInstructionData)? {
|
||||
VoteInstruction::InitializeAccount => vote_state::initialize_account(keyed_accounts),
|
||||
VoteInstruction::DelegateStake(delegate_id) => {
|
||||
vote_state::delegate_stake(keyed_accounts, &delegate_id)
|
||||
|
@ -64,7 +64,7 @@ impl<'a> VoteBank<'a> {
|
||||
self.bank.register_tick(&hash(blockhash.as_ref()));
|
||||
|
||||
let vote_account = self.bank.get_account(&vote_keypair.pubkey()).unwrap();
|
||||
Ok(VoteState::deserialize(&vote_account.userdata).unwrap())
|
||||
Ok(VoteState::deserialize(&vote_account.data).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ fn test_vote_via_bank_with_no_signature() {
|
||||
|
||||
// And ensure there's no vote.
|
||||
let vote_account = bank.get_account(&vote_id).unwrap();
|
||||
let vote_state = VoteState::deserialize(&vote_account.userdata).unwrap();
|
||||
let vote_state = VoteState::deserialize(&vote_account.data).unwrap();
|
||||
assert_eq!(vote_state.votes.len(), 0);
|
||||
|
||||
assert_eq!(
|
||||
|
@ -74,12 +74,12 @@ impl VoteState {
|
||||
}
|
||||
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProgramError> {
|
||||
deserialize(input).map_err(|_| ProgramError::InvalidUserdata)
|
||||
deserialize(input).map_err(|_| ProgramError::InvalidAccountData)
|
||||
}
|
||||
|
||||
pub fn serialize(&self, output: &mut [u8]) -> Result<(), ProgramError> {
|
||||
serialize_into(output, self).map_err(|err| match *err {
|
||||
ErrorKind::SizeLimit => ProgramError::UserdataTooSmall,
|
||||
ErrorKind::SizeLimit => ProgramError::AccountDataTooSmall,
|
||||
_ => ProgramError::GenericError,
|
||||
})
|
||||
}
|
||||
@ -163,13 +163,13 @@ pub fn delegate_stake(
|
||||
Err(ProgramError::InvalidArgument)?;
|
||||
}
|
||||
|
||||
let vote_state = VoteState::deserialize(&keyed_accounts[0].account.userdata);
|
||||
let vote_state = VoteState::deserialize(&keyed_accounts[0].account.data);
|
||||
if let Ok(mut vote_state) = vote_state {
|
||||
vote_state.delegate_id = *node_id;
|
||||
vote_state.serialize(&mut keyed_accounts[0].account.userdata)?;
|
||||
vote_state.serialize(&mut keyed_accounts[0].account.data)?;
|
||||
} else {
|
||||
error!("account[0] does not valid userdata");
|
||||
Err(ProgramError::InvalidUserdata)?;
|
||||
error!("account[0] does not valid data");
|
||||
Err(ProgramError::InvalidAccountData)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -192,13 +192,13 @@ pub fn authorize_voter(
|
||||
Err(ProgramError::InvalidArgument)?;
|
||||
}
|
||||
|
||||
let vote_state = VoteState::deserialize(&keyed_accounts[0].account.userdata);
|
||||
let vote_state = VoteState::deserialize(&keyed_accounts[0].account.data);
|
||||
if let Ok(mut vote_state) = vote_state {
|
||||
vote_state.authorized_voter_id = *voter_id;
|
||||
vote_state.serialize(&mut keyed_accounts[0].account.userdata)?;
|
||||
vote_state.serialize(&mut keyed_accounts[0].account.data)?;
|
||||
} else {
|
||||
error!("account[0] does not valid userdata");
|
||||
Err(ProgramError::InvalidUserdata)?;
|
||||
error!("account[0] does not valid data");
|
||||
Err(ProgramError::InvalidAccountData)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -214,18 +214,18 @@ pub fn initialize_account(keyed_accounts: &mut [KeyedAccount]) -> Result<(), Pro
|
||||
}
|
||||
|
||||
let staker_id = keyed_accounts[0].unsigned_key();
|
||||
let vote_state = VoteState::deserialize(&keyed_accounts[0].account.userdata);
|
||||
let vote_state = VoteState::deserialize(&keyed_accounts[0].account.data);
|
||||
if let Ok(vote_state) = vote_state {
|
||||
if vote_state.delegate_id == Pubkey::default() {
|
||||
let vote_state = VoteState::new(staker_id);
|
||||
vote_state.serialize(&mut keyed_accounts[0].account.userdata)?;
|
||||
vote_state.serialize(&mut keyed_accounts[0].account.data)?;
|
||||
} else {
|
||||
error!("account[0] userdata already initialized");
|
||||
Err(ProgramError::InvalidUserdata)?;
|
||||
error!("account[0] data already initialized");
|
||||
Err(ProgramError::InvalidAccountData)?;
|
||||
}
|
||||
} else {
|
||||
error!("account[0] does not have valid userdata");
|
||||
Err(ProgramError::InvalidUserdata)?;
|
||||
error!("account[0] does not have valid data");
|
||||
Err(ProgramError::InvalidAccountData)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -237,7 +237,7 @@ pub fn process_vote(keyed_accounts: &mut [KeyedAccount], vote: Vote) -> Result<(
|
||||
Err(ProgramError::InvalidArgument)?;
|
||||
}
|
||||
|
||||
let mut vote_state = VoteState::deserialize(&keyed_accounts[0].account.userdata)?;
|
||||
let mut vote_state = VoteState::deserialize(&keyed_accounts[0].account.data)?;
|
||||
|
||||
// If no voter was authorized, expect account[0] to be the signer, otherwise account[1].
|
||||
let signer_index = if vote_state.authorized_voter_id == *keyed_accounts[0].unsigned_key() {
|
||||
@ -256,7 +256,7 @@ pub fn process_vote(keyed_accounts: &mut [KeyedAccount], vote: Vote) -> Result<(
|
||||
}
|
||||
|
||||
vote_state.process_vote(vote);
|
||||
vote_state.serialize(&mut keyed_accounts[0].account.userdata)?;
|
||||
vote_state.serialize(&mut keyed_accounts[0].account.data)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -266,9 +266,9 @@ pub fn clear_credits(keyed_accounts: &mut [KeyedAccount]) -> Result<(), ProgramE
|
||||
Err(ProgramError::InvalidArgument)?;
|
||||
}
|
||||
|
||||
let mut vote_state = VoteState::deserialize(&keyed_accounts[0].account.userdata)?;
|
||||
let mut vote_state = VoteState::deserialize(&keyed_accounts[0].account.data)?;
|
||||
vote_state.clear_credits();
|
||||
vote_state.serialize(&mut keyed_accounts[0].account.userdata)?;
|
||||
vote_state.serialize(&mut keyed_accounts[0].account.data)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -283,7 +283,7 @@ pub fn initialize_and_deserialize(
|
||||
) -> Result<VoteState, ProgramError> {
|
||||
let mut keyed_accounts = [KeyedAccount::new(vote_id, false, vote_account)];
|
||||
initialize_account(&mut keyed_accounts)?;
|
||||
let vote_state = VoteState::deserialize(&vote_account.userdata).unwrap();
|
||||
let vote_state = VoteState::deserialize(&vote_account.data).unwrap();
|
||||
Ok(vote_state)
|
||||
}
|
||||
|
||||
@ -294,7 +294,7 @@ pub fn vote_and_deserialize(
|
||||
) -> Result<VoteState, ProgramError> {
|
||||
let mut keyed_accounts = [KeyedAccount::new(vote_id, true, vote_account)];
|
||||
process_vote(&mut keyed_accounts, vote)?;
|
||||
let vote_state = VoteState::deserialize(&vote_account.userdata).unwrap();
|
||||
let vote_state = VoteState::deserialize(&vote_account.data).unwrap();
|
||||
Ok(vote_state)
|
||||
}
|
||||
|
||||
@ -324,7 +324,7 @@ mod tests {
|
||||
|
||||
// reinit should fail
|
||||
let res = initialize_account(&mut keyed_accounts);
|
||||
assert_eq!(res, Err(ProgramError::InvalidUserdata));
|
||||
assert_eq!(res, Err(ProgramError::InvalidAccountData));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -108,7 +108,7 @@ impl VoteTransaction {
|
||||
if !check_id(&tx.program_id(ix_index)) {
|
||||
return None;
|
||||
}
|
||||
let instruction = deserialize(&tx.userdata(ix_index)).unwrap();
|
||||
let instruction = deserialize(&tx.data(ix_index)).unwrap();
|
||||
if let VoteInstruction::Vote(vote) = instruction {
|
||||
Some((tx.account_keys[0], vote, tx.recent_blockhash))
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user