Rename tokens to lamports in programs/
This commit is contained in:
parent
0604bbb473
commit
3129e299e4
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ pub enum BudgetError {
|
|||
ContractNotPending,
|
||||
SourceIsPendingContract,
|
||||
UninitializedContract,
|
||||
NegativeTokens,
|
||||
DestinationMissing,
|
||||
FailedWitness,
|
||||
UserdataTooSmall,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(),
|
||||
))
|
||||
|
|
Loading…
Reference in New Issue