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:
Greg Fitzgerald
2019-03-14 10:48:27 -06:00
committed by GitHub
parent de13082347
commit c1eec0290e
42 changed files with 245 additions and 254 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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)
);
}
}

View File

@ -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));
}
}

View File

@ -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),
}
}

View File

@ -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())
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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());

View File

@ -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)

View File

@ -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!(

View File

@ -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]

View File

@ -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 {