Rename tokens to lamports in programs/

This commit is contained in:
Michael Vines 2019-03-05 17:27:25 -08:00
parent 0604bbb473
commit 3129e299e4
11 changed files with 77 additions and 71 deletions

View File

@ -24,13 +24,13 @@ extern bool entrypoint(const uint8_t *input) {
return false;
}
int64_t tokens = *(int64_t *)params.data;
if (*params.ka[0].tokens >= tokens) {
*params.ka[0].tokens -= tokens;
*params.ka[2].tokens += tokens;
// sol_log_64(0, 0, *ka[0].tokens, *ka[2].tokens, tokens);
int64_t lamports = *(int64_t *)params.data;
if (*params.ka[0].lamports >= lamports) {
*params.ka[0].lamports -= lamports;
*params.ka[2].lamports += lamports;
// sol_log_64(0, 0, *ka[0].lamports, *ka[2].lamports, lamports);
} else {
// sol_log_64(0, 0, 0xFF, *ka[0].tokens, tokens);
// sol_log_64(0, 0, 0xFF, *ka[0].lamports, lamports);
}
return true;
}

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.lamports -= payment.tokens;
keyed_accounts[0].account.lamports += payment.tokens;
keyed_accounts[1].account.lamports -= payment.lamports;
keyed_accounts[0].account.lamports += payment.lamports;
return Ok(());
}
}
@ -37,8 +37,8 @@ fn apply_signature(
return Err(BudgetError::DestinationMissing);
}
budget_state.pending_budget = None;
keyed_accounts[1].account.lamports -= payment.tokens;
keyed_accounts[2].account.lamports += payment.tokens;
keyed_accounts[1].account.lamports -= payment.lamports;
keyed_accounts[2].account.lamports += payment.lamports;
}
Ok(())
}
@ -68,8 +68,8 @@ fn apply_timestamp(
return Err(BudgetError::DestinationMissing);
}
budget_state.pending_budget = None;
keyed_accounts[1].account.lamports -= payment.tokens;
keyed_accounts[2].account.lamports += payment.tokens;
keyed_accounts[1].account.lamports -= payment.lamports;
keyed_accounts[2].account.lamports += payment.lamports;
}
Ok(())
}
@ -87,7 +87,7 @@ fn apply_debits(
let expr = expr.clone();
if let Some(payment) = expr.final_payment() {
keyed_accounts[1].account.lamports = 0;
keyed_accounts[0].account.lamports += payment.tokens;
keyed_accounts[0].account.lamports += payment.lamports;
Ok(())
} else {
let existing = BudgetState::deserialize(&keyed_accounts[1].account.userdata).ok();

View File

@ -51,52 +51,57 @@ pub enum BudgetExpr {
}
impl BudgetExpr {
/// Create the simplest budget - one that pays `tokens` to Pubkey.
pub fn new_payment(tokens: u64, to: Pubkey) -> Self {
BudgetExpr::Pay(Payment { tokens, to })
/// Create the simplest budget - one that pays `lamports` to Pubkey.
pub fn new_payment(lamports: u64, to: Pubkey) -> Self {
BudgetExpr::Pay(Payment { lamports, to })
}
/// Create a budget that pays `tokens` to `to` after being witnessed by `from`.
pub fn new_authorized_payment(from: Pubkey, tokens: u64, to: Pubkey) -> Self {
/// Create a budget that pays `lamports` to `to` after being witnessed by `from`.
pub fn new_authorized_payment(from: Pubkey, lamports: u64, to: Pubkey) -> Self {
BudgetExpr::After(
Condition::Signature(from),
Box::new(Self::new_payment(tokens, to)),
Box::new(Self::new_payment(lamports, to)),
)
}
/// Create a budget that pays tokens` to `to` after being witnessed by 2x `from`s
pub fn new_2_2_multisig_payment(from0: Pubkey, from1: Pubkey, tokens: u64, to: Pubkey) -> Self {
/// Create a budget that pays lamports` to `to` after being witnessed by 2x `from`s
pub fn new_2_2_multisig_payment(
from0: Pubkey,
from1: Pubkey,
lamports: u64,
to: Pubkey,
) -> Self {
BudgetExpr::And(
Condition::Signature(from0),
Condition::Signature(from1),
Box::new(Self::new_payment(tokens, to)),
Box::new(Self::new_payment(lamports, to)),
)
}
/// Create a budget that pays `tokens` to `to` after the given DateTime.
pub fn new_future_payment(dt: DateTime<Utc>, from: Pubkey, tokens: u64, to: Pubkey) -> Self {
/// Create a budget that pays `lamports` to `to` after the given DateTime.
pub fn new_future_payment(dt: DateTime<Utc>, from: Pubkey, lamports: u64, to: Pubkey) -> Self {
BudgetExpr::After(
Condition::Timestamp(dt, from),
Box::new(Self::new_payment(tokens, to)),
Box::new(Self::new_payment(lamports, to)),
)
}
/// Create a budget that pays `tokens` to `to` after the given DateTime
/// Create a budget that pays `lamports` to `to` after the given DateTime
/// unless cancelled by `from`.
pub fn new_cancelable_future_payment(
dt: DateTime<Utc>,
from: Pubkey,
tokens: u64,
lamports: u64,
to: Pubkey,
) -> Self {
BudgetExpr::Or(
(
Condition::Timestamp(dt, from),
Box::new(Self::new_payment(tokens, to)),
Box::new(Self::new_payment(lamports, to)),
),
(
Condition::Signature(from),
Box::new(Self::new_payment(tokens, to)),
Box::new(Self::new_payment(lamports, to)),
),
)
}
@ -109,14 +114,16 @@ impl BudgetExpr {
}
}
/// Return true if the budget spends exactly `spendable_tokens`.
pub fn verify(&self, spendable_tokens: u64) -> bool {
/// Return true if the budget spends exactly `spendable_lamports`.
pub fn verify(&self, spendable_lamports: u64) -> bool {
match self {
BudgetExpr::Pay(payment) => payment.tokens == spendable_tokens,
BudgetExpr::Pay(payment) => payment.lamports == spendable_lamports,
BudgetExpr::After(_, sub_expr) | BudgetExpr::And(_, _, sub_expr) => {
sub_expr.verify(spendable_tokens)
sub_expr.verify(spendable_lamports)
}
BudgetExpr::Or(a, b) => {
a.1.verify(spendable_lamports) && b.1.verify(spendable_lamports)
}
BudgetExpr::Or(a, b) => a.1.verify(spendable_tokens) && b.1.verify(spendable_tokens),
}
}

View File

@ -8,8 +8,8 @@ use solana_sdk::transaction_builder::BuilderInstruction;
/// A smart contract.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Contract {
/// The number of tokens allocated to the `BudgetExpr` and any transaction fees.
pub tokens: u64,
/// The number of lamports allocated to the `BudgetExpr` and any transaction fees.
pub lamports: u64,
pub budget_expr: BudgetExpr,
}

View File

@ -10,7 +10,6 @@ pub enum BudgetError {
ContractNotPending,
SourceIsPendingContract,
UninitializedContract,
NegativeTokens,
DestinationMissing,
FailedWitness,
UserdataTooSmall,

View File

@ -20,19 +20,19 @@ impl BudgetTransaction {
pub fn new_payment(
from_keypair: &Keypair,
to: Pubkey,
tokens: u64,
lamports: u64,
recent_blockhash: Hash,
fee: u64,
) -> Transaction {
let contract = Keypair::new().pubkey();
let from = from_keypair.pubkey();
let payment = BudgetExpr::new_payment(tokens - fee, to);
let payment = BudgetExpr::new_payment(lamports - fee, to);
let space = serialized_size(&BudgetState::new(payment.clone())).unwrap();
TransactionBuilder::new(fee)
.push(SystemInstruction::new_program_account(
from,
contract,
tokens,
lamports,
space,
id(),
))
@ -45,10 +45,10 @@ impl BudgetTransaction {
pub fn new(
from_keypair: &Keypair,
to: Pubkey,
tokens: u64,
lamports: u64,
recent_blockhash: Hash,
) -> Transaction {
Self::new_payment(from_keypair, to, tokens, recent_blockhash, 0)
Self::new_payment(from_keypair, to, lamports, recent_blockhash, 0)
}
/// Create and sign a new Witness Timestamp. Used for unit-testing.
@ -93,24 +93,24 @@ impl BudgetTransaction {
dt: DateTime<Utc>,
dt_pubkey: Pubkey,
cancelable: Option<Pubkey>,
tokens: u64,
lamports: u64,
recent_blockhash: Hash,
) -> Transaction {
let expr = if let Some(from) = cancelable {
BudgetExpr::Or(
(
Condition::Timestamp(dt, dt_pubkey),
Box::new(BudgetExpr::new_payment(tokens, to)),
Box::new(BudgetExpr::new_payment(lamports, to)),
),
(
Condition::Signature(from),
Box::new(BudgetExpr::new_payment(tokens, from)),
Box::new(BudgetExpr::new_payment(lamports, from)),
),
)
} else {
BudgetExpr::After(
Condition::Timestamp(dt, dt_pubkey),
Box::new(BudgetExpr::new_payment(tokens, to)),
Box::new(BudgetExpr::new_payment(lamports, to)),
)
};
let instruction = BudgetInstruction::InitializeAccount(expr);
@ -130,24 +130,24 @@ impl BudgetTransaction {
contract: Pubkey,
witness: Pubkey,
cancelable: Option<Pubkey>,
tokens: u64,
lamports: u64,
recent_blockhash: Hash,
) -> Transaction {
let expr = if let Some(from) = cancelable {
BudgetExpr::Or(
(
Condition::Signature(witness),
Box::new(BudgetExpr::new_payment(tokens, to)),
Box::new(BudgetExpr::new_payment(lamports, to)),
),
(
Condition::Signature(from),
Box::new(BudgetExpr::new_payment(tokens, from)),
Box::new(BudgetExpr::new_payment(lamports, from)),
),
)
} else {
BudgetExpr::After(
Condition::Signature(witness),
Box::new(BudgetExpr::new_payment(tokens, to)),
Box::new(BudgetExpr::new_payment(lamports, to)),
)
};
let instruction = BudgetInstruction::InitializeAccount(expr);
@ -230,7 +230,7 @@ mod tests {
}
#[test]
fn test_token_attack() {
fn test_lamport_attack() {
let zero = Hash::default();
let keypair = Keypair::new();
let pubkey = keypair.pubkey();
@ -244,7 +244,7 @@ mod tests {
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 = *lamports; // <-- attack, part 2!
payment.lamports = *lamports; // <-- attack, part 2!
}
}
tx.instructions[1].userdata = serialize(&instruction).unwrap();
@ -282,17 +282,17 @@ mod tests {
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 = 2; // <-- attack!
payment.lamports = 2; // <-- attack!
}
}
tx.instructions[1].userdata = serialize(&instruction).unwrap();
assert!(!BudgetTransaction::verify_plan(&tx));
// Also, ensure all branchs of the plan spend all tokens
// Also, ensure all branchs of the plan spend all lamports
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 = 0; // <-- whoops!
payment.lamports = 0; // <-- whoops!
}
}
tx.instructions[1].userdata = serialize(&instruction).unwrap();

View File

@ -17,12 +17,12 @@ pub enum Witness {
Signature,
}
/// Some amount of tokens that should be sent to the `to` `Pubkey`.
/// Some amount of lamports that should be sent to the `to` `Pubkey`.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Payment {
/// Amount to be paid.
pub tokens: u64,
pub lamports: u64,
/// The `Pubkey` that `tokens` should be paid to.
/// The `Pubkey` that `lamports` should be paid to.
pub to: Pubkey,
}

View File

@ -64,7 +64,7 @@ fn test_redeem_vote_credits_via_bank() {
let bank = Bank::new(&genesis_block);
let rewards_bank = RewardsBank::new(&bank);
// Create a rewards account to hold all rewards pool tokens.
// Create a rewards account to hold all rewards pool lamports.
let rewards_keypair = Keypair::new();
let rewards_id = rewards_keypair.pubkey();
rewards_bank
@ -91,13 +91,13 @@ fn test_redeem_vote_credits_via_bank() {
// TODO: Add VoteInstruction::RegisterStakerId so that we don't need to point the "to"
// account to the "from" account.
let to_id = vote_id;
let to_tokens = bank.get_balance(&vote_id);
let to_lamports = bank.get_balance(&vote_id);
// Periodically, the staker sumbits its vote account to the rewards pool
// to exchange its credits for lamports.
let vote_state = rewards_bank
.redeem_credits(rewards_id, &vote_keypair)
.unwrap();
assert!(bank.get_balance(&to_id) > to_tokens);
assert!(bank.get_balance(&to_id) > to_lamports);
assert_eq!(vote_state.credits(), 0);
}

View File

@ -19,14 +19,14 @@ impl RewardsTransaction {
from_keypair: &Keypair,
rewards_id: Pubkey,
blockhash: Hash,
num_tokens: u64,
lamports: u64,
fee: u64,
) -> Transaction {
SystemTransaction::new_program_account(
from_keypair,
rewards_id,
blockhash,
num_tokens,
lamports,
RewardsState::max_size() as u64,
id(),
fee,

View File

@ -229,9 +229,9 @@ pub fn clear_credits(keyed_accounts: &mut [KeyedAccount]) -> Result<(), ProgramE
Ok(())
}
pub fn create_vote_account(tokens: u64) -> Account {
pub fn create_vote_account(lamports: u64) -> Account {
let space = VoteState::max_size();
Account::new(tokens, space, id())
Account::new(lamports, space, id())
}
pub fn initialize_and_deserialize(

View File

@ -26,12 +26,12 @@ impl VoteTransaction {
.sign(&[voting_keypair], recent_blockhash)
}
/// Fund or create the staking account with tokens
/// Fund or create the staking account with lamports
pub fn new_account(
from_keypair: &Keypair,
voter_id: Pubkey,
recent_blockhash: Hash,
num_tokens: u64,
lamports: u64,
fee: u64,
) -> Transaction {
let from_id = from_keypair.pubkey();
@ -40,7 +40,7 @@ impl VoteTransaction {
.push(SystemInstruction::new_program_account(
from_id,
voter_id,
num_tokens,
lamports,
space,
id(),
))
@ -48,13 +48,13 @@ impl VoteTransaction {
.sign(&[from_keypair], recent_blockhash)
}
/// Fund or create the staking account with tokens
/// Fund or create the staking account with lamports
pub fn new_account_with_delegate(
from_keypair: &Keypair,
voter_keypair: &Keypair,
delegate_id: Pubkey,
recent_blockhash: Hash,
num_tokens: u64,
lamports: u64,
fee: u64,
) -> Transaction {
let from_id = from_keypair.pubkey();
@ -64,7 +64,7 @@ impl VoteTransaction {
.push(SystemInstruction::new_program_account(
from_id,
voter_id,
num_tokens,
lamports,
space,
id(),
))