Rename tokens to lamports in sdk/

This commit is contained in:
Michael Vines
2019-03-05 16:28:14 -08:00
parent bd237a2d6f
commit 53f09c44f3
33 changed files with 324 additions and 306 deletions

View File

@ -147,7 +147,7 @@ fn serialize_parameters(
v.write_u64::<LittleEndian>(info.signer_key().is_some() as u64)
.unwrap();
v.write_all(info.unsigned_key().as_ref()).unwrap();
v.write_u64::<LittleEndian>(info.account.tokens).unwrap();
v.write_u64::<LittleEndian>(info.account.lamports).unwrap();
v.write_u64::<LittleEndian>(info.account.userdata.len() as u64)
.unwrap();
v.write_all(&info.account.userdata).unwrap();
@ -167,9 +167,9 @@ fn deserialize_parameters(keyed_accounts: &mut [KeyedAccount], buffer: &[u8]) {
for info in keyed_accounts.iter_mut() {
start += mem::size_of::<u64>(); // skip signer_key boolean
start += mem::size_of::<Pubkey>(); // skip pubkey
info.account.tokens = LittleEndian::read_u64(&buffer[start..]);
info.account.lamports = LittleEndian::read_u64(&buffer[start..]);
start += mem::size_of::<u64>() // skip tokens
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]);

View File

@ -27,8 +27,8 @@ fn apply_signature(
if let Some(key) = keyed_accounts[0].signer_key() {
if &payment.to == key {
budget_state.pending_budget = None;
keyed_accounts[1].account.tokens -= payment.tokens;
keyed_accounts[0].account.tokens += payment.tokens;
keyed_accounts[1].account.lamports -= payment.tokens;
keyed_accounts[0].account.lamports += payment.tokens;
return Ok(());
}
}
@ -37,8 +37,8 @@ fn apply_signature(
return Err(BudgetError::DestinationMissing);
}
budget_state.pending_budget = None;
keyed_accounts[1].account.tokens -= payment.tokens;
keyed_accounts[2].account.tokens += payment.tokens;
keyed_accounts[1].account.lamports -= payment.tokens;
keyed_accounts[2].account.lamports += payment.tokens;
}
Ok(())
}
@ -68,8 +68,8 @@ fn apply_timestamp(
return Err(BudgetError::DestinationMissing);
}
budget_state.pending_budget = None;
keyed_accounts[1].account.tokens -= payment.tokens;
keyed_accounts[2].account.tokens += payment.tokens;
keyed_accounts[1].account.lamports -= payment.tokens;
keyed_accounts[2].account.lamports += payment.tokens;
}
Ok(())
}
@ -86,8 +86,8 @@ fn apply_debits(
BudgetInstruction::InitializeAccount(expr) => {
let expr = expr.clone();
if let Some(payment) = expr.final_payment() {
keyed_accounts[1].account.tokens = 0;
keyed_accounts[0].account.tokens += payment.tokens;
keyed_accounts[1].account.lamports = 0;
keyed_accounts[0].account.lamports += payment.tokens;
Ok(())
} else {
let existing = BudgetState::deserialize(&keyed_accounts[1].account.userdata).ok();
@ -97,8 +97,8 @@ fn apply_debits(
} else {
let mut budget_state = BudgetState::default();
budget_state.pending_budget = Some(expr);
keyed_accounts[1].account.tokens += keyed_accounts[0].account.tokens;
keyed_accounts[0].account.tokens = 0;
keyed_accounts[1].account.lamports += keyed_accounts[0].account.lamports;
keyed_accounts[0].account.lamports = 0;
budget_state.initialized = true;
budget_state.serialize(&mut keyed_accounts[1].account.userdata)
}
@ -146,8 +146,8 @@ fn apply_debits(
}
/// Budget DSL contract interface
/// * accounts[0] - The source of the tokens
/// * accounts[1] - The contract context. Once the contract has been completed, the tokens can
/// * accounts[0] - The source of the lamports
/// * accounts[1] - The contract context. Once the contract has been completed, the lamports can
/// be spent from this account .
pub fn process_instruction(
keyed_accounts: &mut [KeyedAccount],
@ -318,8 +318,8 @@ mod test {
Hash::default(),
);
process_transaction(&tx, &mut accounts).unwrap();
assert_eq!(accounts[from_account].tokens, 0);
assert_eq!(accounts[contract_account].tokens, 1);
assert_eq!(accounts[from_account].lamports, 0);
assert_eq!(accounts[contract_account].lamports, 1);
let budget_state = BudgetState::deserialize(&accounts[contract_account].userdata).unwrap();
assert!(budget_state.is_pending());
@ -335,9 +335,9 @@ mod test {
process_transaction(&tx, &mut accounts),
Err(BudgetError::DestinationMissing)
);
assert_eq!(accounts[from_account].tokens, 0);
assert_eq!(accounts[contract_account].tokens, 1);
assert_eq!(accounts[to_account].tokens, 0);
assert_eq!(accounts[from_account].lamports, 0);
assert_eq!(accounts[contract_account].lamports, 1);
assert_eq!(accounts[to_account].lamports, 0);
let budget_state = BudgetState::deserialize(&accounts[contract_account].userdata).unwrap();
assert!(budget_state.is_pending());
@ -352,9 +352,9 @@ mod test {
Hash::default(),
);
process_transaction(&tx, &mut accounts).unwrap();
assert_eq!(accounts[from_account].tokens, 0);
assert_eq!(accounts[contract_account].tokens, 0);
assert_eq!(accounts[to_account].tokens, 1);
assert_eq!(accounts[from_account].lamports, 0);
assert_eq!(accounts[contract_account].lamports, 0);
assert_eq!(accounts[to_account].lamports, 1);
let budget_state = BudgetState::deserialize(&accounts[contract_account].userdata).unwrap();
assert!(!budget_state.is_pending());
@ -364,9 +364,9 @@ mod test {
process_transaction(&tx, &mut accounts),
Err(BudgetError::ContractNotPending)
);
assert_eq!(accounts[from_account].tokens, 0);
assert_eq!(accounts[contract_account].tokens, 0);
assert_eq!(accounts[to_account].tokens, 1);
assert_eq!(accounts[from_account].lamports, 0);
assert_eq!(accounts[contract_account].lamports, 0);
assert_eq!(accounts[to_account].lamports, 1);
}
#[test]
fn test_cancel_transfer() {
@ -393,22 +393,22 @@ mod test {
Hash::default(),
);
process_transaction(&tx, &mut accounts).unwrap();
assert_eq!(accounts[from_account].tokens, 0);
assert_eq!(accounts[contract_account].tokens, 1);
assert_eq!(accounts[from_account].lamports, 0);
assert_eq!(accounts[contract_account].lamports, 1);
let budget_state = BudgetState::deserialize(&accounts[contract_account].userdata).unwrap();
assert!(budget_state.is_pending());
// Attack! try to put the tokens into the wrong account with cancel
// Attack! try to put the lamports into the wrong account with cancel
let tx =
BudgetTransaction::new_signature(&to, contract.pubkey(), to.pubkey(), Hash::default());
// unit test hack, the `from account` is passed instead of the `to` account to avoid
// creating more account vectors
process_transaction(&tx, &mut accounts).unwrap();
// nothing should be changed because apply witness didn't finalize a payment
assert_eq!(accounts[from_account].tokens, 0);
assert_eq!(accounts[contract_account].tokens, 1);
assert_eq!(accounts[from_account].lamports, 0);
assert_eq!(accounts[contract_account].lamports, 1);
// this is the `to.pubkey()` account
assert_eq!(accounts[pay_account].tokens, 0);
assert_eq!(accounts[pay_account].lamports, 0);
// Now, cancel the transaction. from gets her funds back
let tx = BudgetTransaction::new_signature(
@ -418,9 +418,9 @@ mod test {
Hash::default(),
);
process_transaction(&tx, &mut accounts).unwrap();
assert_eq!(accounts[from_account].tokens, 1);
assert_eq!(accounts[contract_account].tokens, 0);
assert_eq!(accounts[pay_account].tokens, 0);
assert_eq!(accounts[from_account].lamports, 1);
assert_eq!(accounts[contract_account].lamports, 0);
assert_eq!(accounts[pay_account].lamports, 0);
// try to replay the cancel contract
let tx = BudgetTransaction::new_signature(
@ -433,9 +433,9 @@ mod test {
process_transaction(&tx, &mut accounts),
Err(BudgetError::ContractNotPending)
);
assert_eq!(accounts[from_account].tokens, 1);
assert_eq!(accounts[contract_account].tokens, 0);
assert_eq!(accounts[pay_account].tokens, 0);
assert_eq!(accounts[from_account].lamports, 1);
assert_eq!(accounts[contract_account].lamports, 0);
assert_eq!(accounts[pay_account].lamports, 0);
}
#[test]

View File

@ -171,13 +171,13 @@ impl BudgetTransaction {
/// Verify only the payment plan.
pub fn verify_plan(tx: &Transaction) -> bool {
if let Some(SystemInstruction::CreateAccount { tokens, .. }) =
if let Some(SystemInstruction::CreateAccount { lamports, .. }) =
Self::system_instruction(tx, 0)
{
if let Some(BudgetInstruction::InitializeAccount(expr)) =
BudgetTransaction::instruction(&tx, 1)
{
if !(tx.fee <= tokens && expr.verify(tokens - tx.fee)) {
if !(tx.fee <= lamports && expr.verify(lamports - tx.fee)) {
return false;
}
}
@ -236,12 +236,15 @@ mod tests {
let pubkey = keypair.pubkey();
let mut tx = BudgetTransaction::new(&keypair, pubkey, 42, zero);
let mut system_instruction = BudgetTransaction::system_instruction(&tx, 0).unwrap();
if let SystemInstruction::CreateAccount { ref mut tokens, .. } = system_instruction {
*tokens = 1_000_000; // <-- attack, part 1!
if let SystemInstruction::CreateAccount {
ref mut lamports, ..
} = system_instruction
{
*lamports = 1_000_000; // <-- attack, part 1!
let mut instruction = BudgetTransaction::instruction(&tx, 1).unwrap();
if let BudgetInstruction::InitializeAccount(ref mut expr) = instruction {
if let BudgetExpr::Pay(ref mut payment) = expr {
payment.tokens = *tokens; // <-- attack, part 2!
payment.tokens = *lamports; // <-- attack, part 2!
}
}
tx.instructions[1].userdata = serialize(&instruction).unwrap();

View File

@ -48,7 +48,7 @@ fn redeem_vote_credits(keyed_accounts: &mut [KeyedAccount]) -> Result<(), Progra
// TODO: This assumes the stake is static. If not, it should use the account value
// at the time of voting, not at credit redemption.
let stake = keyed_accounts[0].account.tokens;
let stake = keyed_accounts[0].account.lamports;
if stake == 0 {
error!("staking account has no stake");
Err(ProgramError::InvalidArgument)?;
@ -57,8 +57,8 @@ fn redeem_vote_credits(keyed_accounts: &mut [KeyedAccount]) -> Result<(), Progra
let lamports = calc_vote_reward(vote_state.credits(), stake)?;
// Transfer rewards from the rewards pool to the staking account.
keyed_accounts[1].account.tokens -= lamports;
keyed_accounts[0].account.tokens += lamports;
keyed_accounts[1].account.lamports -= lamports;
keyed_accounts[0].account.lamports += lamports;
Ok(())
}
@ -90,9 +90,9 @@ mod tests {
use solana_vote_api::vote_instruction::Vote;
use solana_vote_api::vote_state;
fn create_rewards_account(tokens: u64) -> Account {
fn create_rewards_account(lamports: u64) -> Account {
let space = RewardsState::max_size();
Account::new(tokens, space, solana_rewards_api::id())
Account::new(lamports, space, solana_rewards_api::id())
}
fn redeem_vote_credits_(
@ -130,7 +130,7 @@ mod tests {
let rewards_id = Keypair::new().pubkey();
let mut rewards_account = create_rewards_account(100);
let tokens_before = vote_account.tokens;
let lamports_before = vote_account.lamports;
redeem_vote_credits_(
&rewards_id,
@ -139,6 +139,6 @@ mod tests {
&mut vote_account,
)
.unwrap();
assert!(vote_account.tokens > tokens_before);
assert!(vote_account.lamports > lamports_before);
}
}

View File

@ -152,7 +152,7 @@ fn entrypoint(
}
total_validations += num_validations;
if total_validations > 0 {
keyed_accounts[0].account.tokens +=
keyed_accounts[0].account.lamports +=
(TOTAL_VALIDATOR_REWARDS * num_validations) / total_validations;
}
}
@ -360,6 +360,6 @@ mod test {
let tx = StorageTransaction::new_reward_claim(&keypair, Hash::default(), entry_height);
test_transaction(&tx, &mut accounts).unwrap();
assert!(accounts[0].tokens == TOTAL_VALIDATOR_REWARDS);
assert!(accounts[0].lamports == TOTAL_VALIDATOR_REWARDS);
}
}

View File

@ -12,13 +12,13 @@ const TO_ACCOUNT_INDEX: usize = 1;
#[derive(Debug, Clone, PartialEq)]
enum SystemError {
AccountAlreadyInUse,
ResultWithNegativeTokens,
ResultWithNegativeLamports,
SourceNotSystemAccount,
}
fn create_system_account(
keyed_accounts: &mut [KeyedAccount],
tokens: u64,
lamports: u64,
space: u64,
program_id: Pubkey,
) -> Result<(), SystemError> {
@ -36,15 +36,15 @@ fn create_system_account(
);
Err(SystemError::AccountAlreadyInUse)?;
}
if tokens > keyed_accounts[FROM_ACCOUNT_INDEX].account.tokens {
if lamports > keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports {
info!(
"CreateAccount: insufficient tokens ({}, need {})",
keyed_accounts[FROM_ACCOUNT_INDEX].account.tokens, tokens
"CreateAccount: insufficient lamports ({}, need {})",
keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports, lamports
);
Err(SystemError::ResultWithNegativeTokens)?;
Err(SystemError::ResultWithNegativeLamports)?;
}
keyed_accounts[FROM_ACCOUNT_INDEX].account.tokens -= tokens;
keyed_accounts[TO_ACCOUNT_INDEX].account.tokens += tokens;
keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports -= lamports;
keyed_accounts[TO_ACCOUNT_INDEX].account.lamports += lamports;
keyed_accounts[TO_ACCOUNT_INDEX].account.owner = program_id;
keyed_accounts[TO_ACCOUNT_INDEX].account.userdata = vec![0; space as usize];
keyed_accounts[TO_ACCOUNT_INDEX].account.executable = false;
@ -61,16 +61,16 @@ fn assign_account_to_program(
keyed_accounts[FROM_ACCOUNT_INDEX].account.owner = program_id;
Ok(())
}
fn move_tokens(keyed_accounts: &mut [KeyedAccount], tokens: u64) -> Result<(), ProgramError> {
if tokens > keyed_accounts[FROM_ACCOUNT_INDEX].account.tokens {
fn move_lamports(keyed_accounts: &mut [KeyedAccount], lamports: u64) -> Result<(), ProgramError> {
if lamports > keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports {
info!(
"Move: insufficient tokens ({}, need {})",
keyed_accounts[FROM_ACCOUNT_INDEX].account.tokens, tokens
"Move: insufficient lamports ({}, need {})",
keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports, lamports
);
Err(ProgramError::ResultWithNegativeTokens)?;
Err(ProgramError::ResultWithNegativeLamports)?;
}
keyed_accounts[FROM_ACCOUNT_INDEX].account.tokens -= tokens;
keyed_accounts[TO_ACCOUNT_INDEX].account.tokens += tokens;
keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports -= lamports;
keyed_accounts[TO_ACCOUNT_INDEX].account.lamports += lamports;
Ok(())
}
@ -93,24 +93,22 @@ pub fn entrypoint(
match syscall {
SystemInstruction::CreateAccount {
tokens,
lamports,
space,
program_id,
} => {
create_system_account(keyed_accounts, tokens, space, program_id).map_err(
|e| match e {
SystemError::AccountAlreadyInUse => ProgramError::InvalidArgument,
SystemError::ResultWithNegativeTokens => {
ProgramError::ResultWithNegativeTokens
}
SystemError::SourceNotSystemAccount => ProgramError::InvalidArgument,
},
)
}
} => create_system_account(keyed_accounts, lamports, space, program_id).map_err(|e| {
match e {
SystemError::AccountAlreadyInUse => ProgramError::InvalidArgument,
SystemError::ResultWithNegativeLamports => {
ProgramError::ResultWithNegativeLamports
}
SystemError::SourceNotSystemAccount => ProgramError::InvalidArgument,
}
}),
SystemInstruction::Assign { program_id } => {
assign_account_to_program(keyed_accounts, program_id)
}
SystemInstruction::Move { tokens } => move_tokens(keyed_accounts, tokens),
SystemInstruction::Move { lamports } => move_lamports(keyed_accounts, lamports),
}
} else {
info!("Invalid transaction instruction userdata: {:?}", data);
@ -138,19 +136,19 @@ mod tests {
KeyedAccount::new(&to, false, &mut to_account),
];
create_system_account(&mut keyed_accounts, 50, 2, new_program_owner).unwrap();
let from_tokens = from_account.tokens;
let to_tokens = to_account.tokens;
let from_lamports = from_account.lamports;
let to_lamports = to_account.lamports;
let to_owner = to_account.owner;
let to_userdata = to_account.userdata.clone();
assert_eq!(from_tokens, 50);
assert_eq!(to_tokens, 50);
assert_eq!(from_lamports, 50);
assert_eq!(to_lamports, 50);
assert_eq!(to_owner, new_program_owner);
assert_eq!(to_userdata, [0, 0]);
}
#[test]
fn test_create_negative_tokens() {
// Attempt to create account with more tokens than remaining in from_account
fn test_create_negative_lamports() {
// Attempt to create account with more lamports than remaining in from_account
let new_program_owner = Pubkey::new(&[9; 32]);
let from = Keypair::new().pubkey();
let mut from_account = Account::new(100, 0, system_program::id());
@ -164,9 +162,9 @@ mod tests {
KeyedAccount::new(&to, false, &mut to_account),
];
let result = create_system_account(&mut keyed_accounts, 150, 2, new_program_owner);
assert_eq!(result, Err(SystemError::ResultWithNegativeTokens));
let from_tokens = from_account.tokens;
assert_eq!(from_tokens, 100);
assert_eq!(result, Err(SystemError::ResultWithNegativeLamports));
let from_lamports = from_account.lamports;
assert_eq!(from_lamports, 100);
assert_eq!(to_account, unchanged_account);
}
@ -188,8 +186,8 @@ mod tests {
];
let result = create_system_account(&mut keyed_accounts, 50, 2, new_program_owner);
assert_eq!(result, Err(SystemError::AccountAlreadyInUse));
let from_tokens = from_account.tokens;
assert_eq!(from_tokens, 100);
let from_lamports = from_account.lamports;
assert_eq!(from_lamports, 100);
assert_eq!(owned_account, unchanged_account);
}
@ -202,7 +200,7 @@ mod tests {
let populated_key = Keypair::new().pubkey();
let mut populated_account = Account {
tokens: 0,
lamports: 0,
userdata: vec![0, 1, 2, 3],
owner: Pubkey::default(),
executable: false,
@ -215,7 +213,7 @@ mod tests {
];
let result = create_system_account(&mut keyed_accounts, 50, 2, new_program_owner);
assert_eq!(result, Err(SystemError::AccountAlreadyInUse));
assert_eq!(from_account.tokens, 100);
assert_eq!(from_account.lamports, 100);
assert_eq!(populated_account, unchanged_account);
}
@ -255,7 +253,7 @@ mod tests {
}
#[test]
fn test_move_tokens() {
fn test_move_lamports() {
let from = Keypair::new().pubkey();
let mut from_account = Account::new(100, 0, Pubkey::new(&[2; 32])); // account owner should not matter
let to = Keypair::new().pubkey();
@ -264,20 +262,20 @@ mod tests {
KeyedAccount::new(&from, true, &mut from_account),
KeyedAccount::new(&to, false, &mut to_account),
];
move_tokens(&mut keyed_accounts, 50).unwrap();
let from_tokens = from_account.tokens;
let to_tokens = to_account.tokens;
assert_eq!(from_tokens, 50);
assert_eq!(to_tokens, 51);
move_lamports(&mut keyed_accounts, 50).unwrap();
let from_lamports = from_account.lamports;
let to_lamports = to_account.lamports;
assert_eq!(from_lamports, 50);
assert_eq!(to_lamports, 51);
// Attempt to move more tokens than remaining in from_account
// Attempt to move more lamports than remaining in from_account
keyed_accounts = [
KeyedAccount::new(&from, true, &mut from_account),
KeyedAccount::new(&to, false, &mut to_account),
];
let result = move_tokens(&mut keyed_accounts, 100);
assert_eq!(result, Err(ProgramError::ResultWithNegativeTokens));
assert_eq!(from_account.tokens, 50);
assert_eq!(to_account.tokens, 51);
let result = move_lamports(&mut keyed_accounts, 100);
assert_eq!(result, Err(ProgramError::ResultWithNegativeLamports));
assert_eq!(from_account.lamports, 50);
assert_eq!(to_account.lamports, 51);
}
}

View File

@ -40,7 +40,7 @@ fn test_system_unsigned_transaction() {
let tx = TransactionBuilder::default()
.push(BuilderInstruction::new(
system_program::id(),
&SystemInstruction::Move { tokens: 10 },
&SystemInstruction::Move { lamports: 10 },
vec![(from_keypair.pubkey(), false), (to_keypair.pubkey(), true)],
))
.sign(&[&to_keypair], blockhash);