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

@ -120,7 +120,7 @@ Returns all information associated with the account of provided Pubkey
##### Results:
The result field will be a JSON object with the following sub fields:
* `tokens`, number of tokens assigned to this account, as a signed 64-bit integer
* `lamports`, number of lamports assigned to this account, as a signed 64-bit integer
* `owner`, array of 32 bytes representing the program this account has been assigned to
* `userdata`, array of bytes representing any userdata associated with the account
* `executable`, boolean indicating if the account contains a program (and is strictly read-only)
@ -132,7 +132,7 @@ The result field will be a JSON object with the following sub fields:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getAccountInfo", "params":["2gVkYWexTHR5Hb2aLeQN3tnngvWzisFKXDUPrgMHpdST"]}' http://localhost:8899
// Result
{"jsonrpc":"2.0","result":{"executable":false,"loader":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"tokens":1,"userdata":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]},"id":1}
{"jsonrpc":"2.0","result":{"executable":false,"loader":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"lamports":1,"userdata":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]},"id":1}
```
---
@ -204,11 +204,11 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "m
---
### requestAirdrop
Requests an airdrop of tokens to a Pubkey
Requests an airdrop of lamports to a Pubkey
##### Parameters:
* `string` - Pubkey of account to receive tokens, as base-58 encoded string
* `integer` - token quantity, as a signed 64-bit integer
* `string` - Pubkey of account to receive lamports, as base-58 encoded string
* `integer` - lamports, as a signed 64-bit integer
##### Results:
* `string` - Transaction Signature of airdrop, as base-58 encoded string
@ -271,7 +271,7 @@ Subscribe to an account to receive notifications when the userdata for a given a
##### Notification Format:
```bash
{"jsonrpc": "2.0","method": "accountNotification", "params": {"result": {"executable":false,"loader":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"tokens":1,"userdata":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]},"subscription":0}}
{"jsonrpc": "2.0","method": "accountNotification", "params": {"result": {"executable":false,"loader":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"lamports":1,"userdata":[3,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,50,48,53,48,45,48,49,45,48,49,84,48,48,58,48,48,58,48,48,90,252,10,7,28,246,140,88,177,98,82,10,227,89,81,18,30,194,101,199,16,11,73,133,20,246,62,114,39,20,113,189,32,50,0,0,0,0,0,0,0,247,15,36,102,167,83,225,42,133,127,82,34,36,224,207,130,109,230,224,188,163,33,213,13,5,117,211,251,65,159,197,51,0,0,0,0,0,0]},"subscription":0}}
```
---

View File

@ -574,7 +574,7 @@ mod tests {
// ProgramErrors should still be recorded
results[0] = Err(BankError::ProgramError(
1,
ProgramError::ResultWithNegativeTokens,
ProgramError::ResultWithNegativeLamports,
));
BankingStage::record_transactions(&transactions, &results, &poh_recorder).unwrap();
let (_, entries) = entry_receiver.recv().unwrap();

View File

@ -476,7 +476,7 @@ mod tests {
entries.push(entry);
// Add a second Transaction that will produce a
// ProgramError<0, ResultWithNegativeTokens> error when processed
// ProgramError<0, ResultWithNegativeLamports> error when processed
let keypair2 = Keypair::new();
let tx = SystemTransaction::new_account(&keypair, keypair2.pubkey(), 42, blockhash, 0);
let entry = Entry::new(&last_entry_hash, 1, vec![tx]);

View File

@ -32,12 +32,12 @@ impl LeaderConfirmationService {
// Hold an accounts_db read lock as briefly as possible, just long enough to collect all
// the vote states
bank.vote_accounts().for_each(|(_, account)| {
total_stake += account.tokens;
total_stake += account.lamports;
let vote_state = VoteState::deserialize(&account.userdata).unwrap();
if let Some(stake_and_state) = vote_state
.votes
.back()
.map(|vote| (vote.slot, account.tokens))
.map(|vote| (vote.slot, account.lamports))
{
slots_and_stakes.push(stake_and_state);
}
@ -145,7 +145,7 @@ mod tests {
let blockhash = bank.last_blockhash();
// Create a total of 10 vote accounts, each will have a balance of 1 (after giving 1 to
// their vote account), for a total staking pool of 10 tokens.
// their vote account), for a total staking pool of 10 lamports.
let vote_accounts: Vec<_> = (0..10)
.map(|i| {
// Create new validator to vote
@ -153,7 +153,7 @@ mod tests {
let voting_keypair = Keypair::new();
let voting_pubkey = voting_keypair.pubkey();
// Give the validator some tokens
// Give the validator some lamports
bank.transfer(2, &mint_keypair, validator_keypair.pubkey(), blockhash)
.unwrap();
new_vote_account(&validator_keypair, &voting_pubkey, &bank, 1);

View File

@ -49,14 +49,17 @@ pub fn num_ticks_left_in_slot(bank: &Bank, tick_height: u64) -> u64 {
mod tests {
use super::*;
use crate::staking_utils;
use solana_sdk::genesis_block::{GenesisBlock, BOOTSTRAP_LEADER_TOKENS};
use solana_sdk::genesis_block::{GenesisBlock, BOOTSTRAP_LEADER_LAMPORTS};
use solana_sdk::signature::{Keypair, KeypairUtil};
#[test]
fn test_leader_schedule_via_bank() {
let pubkey = Keypair::new().pubkey();
let (genesis_block, _mint_keypair) =
GenesisBlock::new_with_leader(BOOTSTRAP_LEADER_TOKENS, pubkey, BOOTSTRAP_LEADER_TOKENS);
let (genesis_block, _mint_keypair) = GenesisBlock::new_with_leader(
BOOTSTRAP_LEADER_LAMPORTS,
pubkey,
BOOTSTRAP_LEADER_LAMPORTS,
);
let bank = Bank::new(&genesis_block);
let ids_and_stakes: Vec<_> = staking_utils::delegated_stakes(&bank).into_iter().collect();
@ -72,9 +75,12 @@ mod tests {
#[test]
fn test_leader_scheduler1_basic() {
let pubkey = Keypair::new().pubkey();
let genesis_block =
GenesisBlock::new_with_leader(BOOTSTRAP_LEADER_TOKENS, pubkey, BOOTSTRAP_LEADER_TOKENS)
.0;
let genesis_block = GenesisBlock::new_with_leader(
BOOTSTRAP_LEADER_LAMPORTS,
pubkey,
BOOTSTRAP_LEADER_LAMPORTS,
)
.0;
let bank = Bank::new(&genesis_block);
assert_eq!(slot_leader_at(bank.slot(), &bank), pubkey);
}

View File

@ -292,8 +292,8 @@ impl RpcSol for RpcSolImpl {
.get_transaction_count()
}
fn request_airdrop(&self, meta: Self::Metadata, id: String, tokens: u64) -> Result<String> {
trace!("request_airdrop id={} tokens={}", id, tokens);
fn request_airdrop(&self, meta: Self::Metadata, id: String, lamports: u64) -> Result<String> {
trace!("request_airdrop id={} lamports={}", id, lamports);
let pubkey = verify_pubkey(id)?;
let blockhash = meta
@ -302,11 +302,13 @@ impl RpcSol for RpcSolImpl {
.unwrap()
.bank()?
.last_blockhash();
let transaction = request_airdrop_transaction(&meta.drone_addr, &pubkey, tokens, blockhash)
.map_err(|err| {
info!("request_airdrop_transaction failed: {:?}", err);
Error::internal_error()
})?;;
let transaction =
request_airdrop_transaction(&meta.drone_addr, &pubkey, lamports, blockhash).map_err(
|err| {
info!("request_airdrop_transaction failed: {:?}", err);
Error::internal_error()
},
)?;;
let data = serialize(&transaction).map_err(|err| {
info!("request_airdrop: serialize error: {:?}", err);
@ -517,7 +519,7 @@ mod tests {
"jsonrpc":"2.0",
"result":{
"owner": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
"tokens": 20,
"lamports": 20,
"userdata": [],
"executable": false
},

View File

@ -106,6 +106,6 @@ pub fn request_airdrop_transaction(
let key = Keypair::new();
let to = Keypair::new().pubkey();
let blockhash = Hash::default();
let tx = SystemTransaction::new_account(&key, to, 50, blockhash, 0);
let tx = SystemTransaction::new_account(&key, to, lamports, blockhash, 0);
Ok(tx)
}

View File

@ -323,7 +323,7 @@ mod tests {
"params": {
"result": {
"owner": budget_program_id,
"tokens": 1,
"lamports": 1,
"userdata": expected_userdata,
"executable": executable,
@ -359,7 +359,7 @@ mod tests {
"params": {
"result": {
"owner": budget_program_id,
"tokens": 51,
"lamports": 51,
"userdata": expected_userdata,
"executable": executable,
},
@ -393,7 +393,7 @@ mod tests {
"params": {
"result": {
"owner": budget_program_id,
"tokens": 1,
"lamports": 1,
"userdata": expected_userdata,
"executable": executable,
},

View File

@ -185,7 +185,7 @@ mod tests {
subscriptions.check_account(&alice.pubkey(), &account);
let string = transport_receiver.poll();
if let Async::Ready(Some(response)) = string.unwrap() {
let expected = format!(r#"{{"jsonrpc":"2.0","method":"accountNotification","params":{{"result":{{"executable":false,"owner":[129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"tokens":1,"userdata":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},"subscription":0}}}}"#);
let expected = format!(r#"{{"jsonrpc":"2.0","method":"accountNotification","params":{{"result":{{"executable":false,"lamports":1,"owner":[129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"userdata":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},"subscription":0}}}}"#);
assert_eq!(expected, response);
}

View File

@ -493,13 +493,13 @@ mod tests {
let keypair0 = Keypair::new();
let keypair1 = Keypair::new();
let keypairs = vec![&keypair0, &keypair1];
let tokens = 5;
let lamports = 5;
let fee = 2;
let blockhash = Hash::default();
let keys = vec![keypair0.pubkey(), keypair1.pubkey()];
let system_instruction = SystemInstruction::Move { tokens };
let system_instruction = SystemInstruction::Move { lamports };
let program_ids = vec![system_program::id(), solana_budget_api::id()];

View File

@ -121,20 +121,20 @@ impl ThinClient {
/// Creates, signs, and processes a Transaction. Useful for writing unit-tests.
pub fn transfer(
&self,
tokens: u64,
lamports: u64,
keypair: &Keypair,
to: Pubkey,
blockhash: &Hash,
) -> io::Result<Signature> {
debug!(
"transfer: tokens={} from={:?} to={:?} blockhash={:?}",
tokens,
"transfer: lamports={} from={:?} to={:?} blockhash={:?}",
lamports,
keypair.pubkey(),
to,
blockhash
);
let now = Instant::now();
let transaction = SystemTransaction::new_account(keypair, to, tokens, *blockhash, 0);
let transaction = SystemTransaction::new_account(keypair, to, lamports, *blockhash, 0);
let result = self.transfer_signed(&transaction);
solana_metrics::submit(
influxdb::Point::new("thinclient")
@ -184,8 +184,8 @@ impl ThinClient {
let account: Account =
serde_json::from_value(account_json).expect("deserialize account");
trace!("Response account {:?} {:?}", pubkey, account);
trace!("get_balance {:?}", account.tokens);
Ok(account.tokens)
trace!("get_balance {:?}", account.lamports);
Ok(account.lamports)
})
.map_err(|error| {
debug!("Response account {}: None (error: {:?})", pubkey, error);
@ -563,8 +563,8 @@ mod tests {
let mut tr2 = SystemTransaction::new_account(&alice, bob_pubkey, 501, blockhash, 0);
let mut instruction2 = deserialize(tr2.userdata(0)).unwrap();
if let SystemInstruction::Move { ref mut tokens } = instruction2 {
*tokens = 502;
if let SystemInstruction::Move { ref mut lamports } = instruction2 {
*lamports = 502;
}
tr2.instructions[0].userdata = serialize(&instruction2).unwrap();
let signature = client.transfer_signed(&tr2).unwrap();
@ -587,7 +587,7 @@ mod tests {
let mut client = mk_client(&leader_data);
// Create the validator account, transfer some tokens to that account
// Create the validator account, transfer some lamports to that account
let validator_keypair = Keypair::new();
let blockhash = client.get_recent_blockhash();
let signature = client
@ -660,9 +660,9 @@ mod tests {
info!("test_thin_client blockhash: {:?}", blockhash);
let starting_alice_balance = client.poll_get_balance(&alice.pubkey()).unwrap();
info!("Alice has {} tokens", starting_alice_balance);
info!("Alice has {} lamports", starting_alice_balance);
info!("Give Bob 500 tokens");
info!("Give Bob 500 lamports");
let signature = client
.transfer(500, &alice, bob_keypair.pubkey(), &blockhash)
.unwrap();
@ -671,7 +671,7 @@ mod tests {
let bob_balance = client.poll_get_balance(&bob_keypair.pubkey());
assert_eq!(bob_balance.unwrap(), 500);
info!("Take Bob's 500 tokens away");
info!("Take Bob's 500 lamports away");
let signature = client
.transfer(500, &bob_keypair, alice.pubkey(), &blockhash)
.unwrap();

View File

@ -1,5 +1,5 @@
//! The `drone` module provides an object for launching a Solana Drone,
//! which is the custodian of any remaining tokens in a mint.
//! which is the custodian of any remaining lamports in a mint.
//! The Solana Drone builds and send airdrop transactions,
//! checking requests against a request cap for a given time time_slice
//! and (to come) an IP rate limit.
@ -48,7 +48,7 @@ pub const DRONE_PORT: u16 = 9900;
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub enum DroneRequest {
GetAirdrop {
tokens: u64,
lamports: u64,
to: Pubkey,
blockhash: Hash,
},
@ -108,16 +108,16 @@ impl Drone {
trace!("build_airdrop_transaction: {:?}", req);
match req {
DroneRequest::GetAirdrop {
tokens,
lamports,
to,
blockhash,
} => {
if self.check_request_limit(tokens) {
self.request_current += tokens;
if self.check_request_limit(lamports) {
self.request_current += lamports;
solana_metrics::submit(
influxdb::Point::new("drone")
.add_tag("op", influxdb::Value::String("airdrop".to_string()))
.add_field("request_amount", influxdb::Value::Integer(tokens as i64))
.add_field("request_amount", influxdb::Value::Integer(lamports as i64))
.add_field(
"request_current",
influxdb::Value::Integer(self.request_current as i64),
@ -125,10 +125,10 @@ impl Drone {
.to_owned(),
);
info!("Requesting airdrop of {} to {:?}", tokens, to);
info!("Requesting airdrop of {} to {:?}", lamports, to);
let create_instruction = SystemInstruction::CreateAccount {
tokens,
lamports,
space: 0,
program_id: system_program::id(),
};
@ -193,18 +193,18 @@ impl Drop for Drone {
pub fn request_airdrop_transaction(
drone_addr: &SocketAddr,
id: &Pubkey,
tokens: u64,
lamports: u64,
blockhash: Hash,
) -> Result<Transaction, Error> {
info!(
"request_airdrop_transaction: drone_addr={} id={} tokens={} blockhash={}",
drone_addr, id, tokens, blockhash
"request_airdrop_transaction: drone_addr={} id={} lamports={} blockhash={}",
drone_addr, id, lamports, blockhash
);
// TODO: make this async tokio client
let mut stream = TcpStream::connect_timeout(drone_addr, Duration::new(3, 0))?;
stream.set_read_timeout(Some(Duration::new(10, 0)))?;
let req = DroneRequest::GetAirdrop {
tokens,
lamports,
blockhash,
to: *id,
};
@ -355,7 +355,7 @@ mod tests {
let to = Keypair::new().pubkey();
let blockhash = Hash::default();
let request = DroneRequest::GetAirdrop {
tokens: 2,
lamports: 2,
to,
blockhash,
};
@ -376,7 +376,7 @@ mod tests {
assert_eq!(
instruction,
SystemInstruction::CreateAccount {
tokens: 2,
lamports: 2,
space: 0,
program_id: Pubkey::default()
}
@ -392,9 +392,9 @@ mod tests {
fn test_process_drone_request() {
let to = Keypair::new().pubkey();
let blockhash = Hash::new(&to.as_ref());
let tokens = 50;
let lamports = 50;
let req = DroneRequest::GetAirdrop {
tokens,
lamports,
blockhash,
to,
};
@ -404,7 +404,7 @@ mod tests {
let keypair = Keypair::new();
let expected_instruction = SystemInstruction::CreateAccount {
tokens,
lamports,
space: 0,
program_id: system_program::id(),
};

View File

@ -10,10 +10,10 @@ use std::sync::mpsc::channel;
fn test_local_drone() {
let keypair = Keypair::new();
let to = Keypair::new().pubkey();
let tokens = 50;
let lamports = 50;
let blockhash = Hash::new(&to.as_ref());
let expected_instruction = SystemInstruction::CreateAccount {
tokens,
lamports,
space: 0,
program_id: system_program::id(),
};
@ -31,6 +31,6 @@ fn test_local_drone() {
run_local_drone(keypair, sender);
let drone_addr = receiver.recv().unwrap();
let result = request_airdrop_transaction(&drone_addr, &to, tokens, blockhash);
let result = request_airdrop_transaction(&drone_addr, &to, lamports, blockhash);
assert_eq!(expected_tx, result.unwrap());
}

View File

@ -12,10 +12,10 @@ use std::error;
* - one token for the transaction fee
* - one second token to keep the node identity public key valid
*/
//pub const BOOTSTRAP_LEADER_TOKENS: u64 = 3;
//pub const BOOTSTRAP_LEADER_LAMPORTS: u64 = 3;
// TODO: Until https://github.com/solana-labs/solana/issues/2355 is resolved the bootstrap leader
// needs N tokens as its vote account gets re-created on every node restart, costing it tokens
pub const BOOTSTRAP_LEADER_TOKENS: u64 = 1_000_000;
pub const BOOTSTRAP_LEADER_LAMPORTS: u64 = 1_000_000;
fn main() -> Result<(), Box<dyn error::Error>> {
let matches = App::new("solana-genesis")
@ -70,7 +70,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
let (mut genesis_block, _mint_keypair) = GenesisBlock::new_with_leader(
num_tokens,
bootstrap_leader_keypair.pubkey(),
BOOTSTRAP_LEADER_TOKENS,
BOOTSTRAP_LEADER_LAMPORTS,
);
genesis_block.mint_id = mint_keypair.pubkey();
genesis_block.bootstrap_leader_vote_account_id = bootstrap_leader_vote_account_keypair.pubkey();

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

View File

@ -396,11 +396,11 @@ impl AccountsDB {
let start = self.next_id.fetch_add(1, Ordering::Relaxed);
let mut id = self.get_storage_id(start, std::usize::MAX);
// Even if no tokens, need to preserve the account owner so
// Even if no lamports, need to preserve the account owner so
// we can update the vote_accounts correctly if this account is purged
// when squashing.
let acc = &mut account.clone();
if account.tokens == 0 {
if account.lamports == 0 {
acc.userdata.resize(0, 0);
}
@ -480,7 +480,7 @@ impl AccountsDB {
/// Store the account update.
fn store_account(&self, fork: Fork, pubkey: &Pubkey, account: &Account) {
if account.tokens == 0 && self.is_squashed(fork) {
if account.lamports == 0 && self.is_squashed(fork) {
// purge if balance is 0 and no checkpoints
let account_maps = self.account_index.account_maps.read().unwrap();
let map = account_maps.get(&pubkey).unwrap();
@ -576,14 +576,14 @@ impl AccountsDB {
for key in &tx.account_keys {
called_accounts.push(self.load(fork, key, true).unwrap_or_default());
}
if called_accounts.is_empty() || called_accounts[0].tokens == 0 {
if called_accounts.is_empty() || called_accounts[0].lamports == 0 {
error_counters.account_not_found += 1;
Err(BankError::AccountNotFound)
} else if called_accounts[0].tokens < tx.fee {
} else if called_accounts[0].lamports < tx.fee {
error_counters.insufficient_funds += 1;
Err(BankError::InsufficientFundsForFee)
} else {
called_accounts[0].tokens -= tx.fee;
called_accounts[0].lamports -= tx.fee;
Ok(called_accounts)
}
}
@ -735,7 +735,7 @@ impl AccountsDB {
self.insert_account_entry(fork, id, offset, &map);
} else {
let account = self.get_account(id, offset);
if account.tokens == 0 {
if account.lamports == 0 {
if self.remove_account_entries(&[fork], &map) {
keys.push(pubkey.clone());
}
@ -803,14 +803,14 @@ impl Accounts {
pub fn load_slow(&self, fork: Fork, pubkey: &Pubkey) -> Option<Account> {
self.accounts_db
.load(fork, pubkey, true)
.filter(|acc| acc.tokens != 0)
.filter(|acc| acc.lamports != 0)
}
/// Slow because lock is held for 1 operation insted of many
pub fn load_slow_no_parent(&self, fork: Fork, pubkey: &Pubkey) -> Option<Account> {
self.accounts_db
.load(fork, pubkey, false)
.filter(|acc| acc.tokens != 0)
.filter(|acc| acc.lamports != 0)
}
/// Slow because lock is held for 1 operation insted of many
@ -943,7 +943,7 @@ impl Accounts {
self.accounts_db
.get_vote_accounts(fork)
.into_iter()
.filter(|(_, acc)| acc.tokens != 0)
.filter(|(_, acc)| acc.lamports != 0)
}
}
@ -1402,11 +1402,11 @@ mod tests {
// now we have:
//
// root0 -> key.tokens==1
// root0 -> key.lamports==1
// / \
// / \
// key.tokens==0 <- fork1 \
// fork2 -> key.tokens==1
// key.lamports==0 <- fork1 \
// fork2 -> key.lamports==1
// (via root0)
// store value 0 in one child
@ -1426,11 +1426,11 @@ mod tests {
// now we should have:
//
// root0 -> key.tokens==1
// root0 -> key.lamports==1
// \
// \
// key.tokens==ANF <- root1 \
// fork2 -> key.tokens==1 (from root0)
// key.lamports==ANF <- root1 \
// fork2 -> key.lamports==1 (from root0)
//
assert_eq!(db.load(1, &key, true), None); // purged
assert_eq!(&db.load(2, &key, true).unwrap(), &account0); // original value
@ -1447,17 +1447,17 @@ mod tests {
let idx = thread_rng().gen_range(0, 99);
let account = db.load(0, &pubkeys[idx], true).unwrap();
let mut default_account = Account::default();
default_account.tokens = (idx + 1) as u64;
default_account.lamports = (idx + 1) as u64;
assert_eq!(compare_account(&default_account, &account), true);
}
db.add_fork(1, Some(0));
// now we have:
//
// root0 -> key[X].tokens==X
// root0 -> key[X].lamports==X
// /
// /
// key[X].tokens==X <- fork1
// key[X].lamports==X <- fork1
// (via root0)
//
@ -1468,7 +1468,7 @@ mod tests {
// root0 -> purged ??
//
//
// key[X].tokens==X <- root1
// key[X].lamports==X <- root1
//
// check that all the accounts appear in parent after a squash ???
@ -1477,7 +1477,7 @@ mod tests {
let account0 = db.load(0, &pubkeys[idx], true).unwrap();
let account1 = db.load(1, &pubkeys[idx], true).unwrap();
let mut default_account = Account::default();
default_account.tokens = (idx + 1) as u64;
default_account.lamports = (idx + 1) as u64;
assert_eq!(&default_account, &account0);
assert_eq!(&default_account, &account1);
}
@ -1494,7 +1494,7 @@ mod tests {
db0.store(0, &key, &account0);
db0.add_fork(1, Some(0));
// 0 tokens in the child
// 0 lamports in the child
let account1 = Account::new(0, 0, key);
db0.store(1, &key, &account1);
@ -1518,7 +1518,7 @@ mod tests {
let pubkey = Keypair::new().pubkey();
let mut default_account = Account::default();
pubkeys.push(pubkey.clone());
default_account.tokens = (t + 1) as u64;
default_account.lamports = (t + 1) as u64;
assert!(accounts.load(0, &pubkey, true).is_none());
accounts.store(0, &pubkey, &default_account);
}
@ -1527,7 +1527,7 @@ mod tests {
let mut default_account = Account::default();
pubkeys.push(pubkey.clone());
default_account.owner = solana_vote_api::id();
default_account.tokens = (num + t + 1) as u64;
default_account.lamports = (num + t + 1) as u64;
assert!(accounts.load(0, &pubkey, true).is_none());
accounts.store(0, &pubkey, &default_account);
}
@ -1537,13 +1537,13 @@ mod tests {
for _ in 1..1000 {
let idx = thread_rng().gen_range(0, range);
if let Some(mut account) = accounts.load(0, &pubkeys[idx], true) {
account.tokens = account.tokens + 1;
account.lamports = account.lamports + 1;
accounts.store(0, &pubkeys[idx], &account);
if account.tokens == 0 {
if account.lamports == 0 {
assert!(accounts.load(0, &pubkeys[idx], true).is_none());
} else {
let mut default_account = Account::default();
default_account.tokens = account.tokens;
default_account.lamports = account.lamports;
assert_eq!(compare_account(&default_account, &account), true);
}
}
@ -1554,7 +1554,7 @@ mod tests {
if account1.userdata != account2.userdata
|| account1.owner != account2.owner
|| account1.executable != account2.executable
|| account1.tokens != account2.tokens
|| account1.lamports != account2.lamports
{
return false;
}
@ -1569,7 +1569,7 @@ mod tests {
create_account(&accounts, &mut pubkeys, 1, 0);
let account = accounts.load(0, &pubkeys[0], true).unwrap();
let mut default_account = Account::default();
default_account.tokens = 1;
default_account.lamports = 1;
assert_eq!(compare_account(&default_account, &account), true);
}
@ -1583,7 +1583,7 @@ mod tests {
let idx = thread_rng().gen_range(0, 99);
let account = accounts.load(0, &pubkeys[idx], true).unwrap();
let mut default_account = Account::default();
default_account.tokens = (idx + 1) as u64;
default_account.lamports = (idx + 1) as u64;
assert_eq!(compare_account(&default_account, &account), true);
}
}
@ -1669,7 +1669,7 @@ mod tests {
let mut vote_accounts: Vec<_> = accounts.get_vote_accounts(1).collect();
assert_eq!(vote_accounts.len(), 1);
vote_account.tokens = 0;
vote_account.lamports = 0;
accounts.store_slow(1, &key, &vote_account);
vote_accounts = accounts.get_vote_accounts(1).collect();
@ -1685,7 +1685,7 @@ mod tests {
vote_accounts = accounts.get_vote_accounts(1).collect();
assert_eq!(vote_accounts.len(), 1);
vote_account1.tokens = 0;
vote_account1.lamports = 0;
accounts.store_slow(1, &key1, &vote_account1);
accounts.store_slow(0, &key, &vote_account);
@ -1716,11 +1716,11 @@ mod tests {
accounts_db.get_vote_accounts(0)
);
info!("storing tokens=0 to fork 1");
// should store a tokens=0 account in 1
lastaccount.tokens = 0;
info!("storing lamports=0 to fork 1");
// should store a lamports=0 account in 1
lastaccount.lamports = 0;
accounts_db.store(1, &lastkey, &lastaccount);
// len == 2 because tokens=0 accounts are filtered at the Accounts interface.
// len == 2 because lamports=0 accounts are filtered at the Accounts interface.
assert_eq!(accounts_db.get_vote_accounts(1).len(), 2);
accounts_db.squash(1);

View File

@ -40,7 +40,7 @@ pub fn serialize_account(dst_slice: &mut [u8], account: &Account, len: usize) {
let mut at = 0;
write_u64(&mut at, dst_slice, len as u64);
write_u64(&mut at, dst_slice, account.tokens);
write_u64(&mut at, dst_slice, account.lamports);
write_bytes(&mut at, dst_slice, &account.userdata);
write_bytes(&mut at, dst_slice, account.owner.as_ref());
write_bytes(&mut at, dst_slice, &[account.executable as u8]);
@ -81,7 +81,7 @@ pub fn deserialize_account(
let len = size as usize;
assert!(current_offset >= at + len);
let tokens = read_u64(&mut at, &src_slice);
let lamports = read_u64(&mut at, &src_slice);
let userdata_len = len - get_account_size_static();
let mut userdata = vec![0; userdata_len];
@ -96,7 +96,7 @@ pub fn deserialize_account(
let executable: bool = exec[0] != 0;
Ok(Account {
tokens,
lamports,
userdata,
owner,
executable,
@ -255,7 +255,7 @@ pub mod tests {
let av: AppendVec<Account> = AppendVec::new(path, true, START_SIZE, INC_SIZE);
let v1 = vec![1u8; 32];
let mut account1 = Account {
tokens: 1,
lamports: 1,
userdata: v1,
owner: Pubkey::default(),
executable: false,
@ -266,7 +266,7 @@ pub mod tests {
let v2 = vec![4u8; 32];
let mut account2 = Account {
tokens: 1,
lamports: 1,
userdata: v2,
owner: Pubkey::default(),
executable: false,

View File

@ -240,24 +240,27 @@ impl Bank {
assert!(genesis_block.mint_id != Pubkey::default());
assert!(genesis_block.bootstrap_leader_id != Pubkey::default());
assert!(genesis_block.bootstrap_leader_vote_account_id != Pubkey::default());
assert!(genesis_block.tokens >= genesis_block.bootstrap_leader_tokens);
assert!(genesis_block.bootstrap_leader_tokens >= 3);
assert!(genesis_block.lamports >= genesis_block.bootstrap_leader_lamports);
assert!(genesis_block.bootstrap_leader_lamports >= 3);
// Bootstrap leader collects fees until `new_from_parent` is called.
self.collector_id = genesis_block.bootstrap_leader_id;
let mint_tokens = genesis_block.tokens - genesis_block.bootstrap_leader_tokens;
self.deposit(&genesis_block.mint_id, mint_tokens);
let mint_lamports = genesis_block.lamports - genesis_block.bootstrap_leader_lamports;
self.deposit(&genesis_block.mint_id, mint_lamports);
let bootstrap_leader_tokens = 2;
let bootstrap_leader_lamports = 2;
let bootstrap_leader_stake =
genesis_block.bootstrap_leader_tokens - bootstrap_leader_tokens;
self.deposit(&genesis_block.bootstrap_leader_id, bootstrap_leader_tokens);
genesis_block.bootstrap_leader_lamports - bootstrap_leader_lamports;
self.deposit(
&genesis_block.bootstrap_leader_id,
bootstrap_leader_lamports,
);
// Construct a vote account for the bootstrap_leader such that the leader_scheduler
// will be forced to select it as the leader for height 0
let mut bootstrap_leader_vote_account = Account {
tokens: bootstrap_leader_stake,
lamports: bootstrap_leader_stake,
userdata: vec![0; VoteState::max_size() as usize],
owner: solana_vote_api::id(),
executable: false,
@ -645,7 +648,7 @@ impl Bank {
}
/// Create, sign, and process a Transaction from `keypair` to `to` of
/// `n` tokens where `blockhash` is the last Entry ID observed by the client.
/// `n` lamports where `blockhash` is the last Entry ID observed by the client.
pub fn transfer(
&self,
n: u64,
@ -659,7 +662,7 @@ impl Bank {
}
pub fn read_balance(account: &Account) -> u64 {
account.tokens
account.lamports
}
/// Each program would need to be able to introspect its own state
/// this is hard-coded to the Budget language
@ -680,14 +683,14 @@ impl Bank {
parents
}
pub fn withdraw(&self, pubkey: &Pubkey, tokens: u64) -> Result<()> {
pub fn withdraw(&self, pubkey: &Pubkey, lamports: u64) -> Result<()> {
match self.get_account(pubkey) {
Some(mut account) => {
if tokens > account.tokens {
if lamports > account.lamports {
return Err(BankError::InsufficientFundsForFee);
}
account.tokens -= tokens;
account.lamports -= lamports;
self.accounts()
.store_slow(self.accounts_id, pubkey, &account);
Ok(())
@ -696,9 +699,9 @@ impl Bank {
}
}
pub fn deposit(&self, pubkey: &Pubkey, tokens: u64) {
pub fn deposit(&self, pubkey: &Pubkey, lamports: u64) {
let mut account = self.get_account(pubkey).unwrap_or_default();
account.tokens += tokens;
account.lamports += lamports;
self.accounts()
.store_slow(self.accounts_id, pubkey, &account);
}
@ -798,7 +801,7 @@ mod tests {
use super::*;
use bincode::serialize;
use hashbrown::HashSet;
use solana_sdk::genesis_block::{GenesisBlock, BOOTSTRAP_LEADER_TOKENS};
use solana_sdk::genesis_block::{GenesisBlock, BOOTSTRAP_LEADER_LAMPORTS};
use solana_sdk::native_program::ProgramError;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
@ -815,18 +818,21 @@ mod tests {
#[test]
fn test_bank_new_with_leader() {
let dummy_leader_id = Keypair::new().pubkey();
let dummy_leader_tokens = BOOTSTRAP_LEADER_TOKENS;
let dummy_leader_lamports = BOOTSTRAP_LEADER_LAMPORTS;
let (genesis_block, _) =
GenesisBlock::new_with_leader(10_000, dummy_leader_id, dummy_leader_tokens);
assert_eq!(genesis_block.bootstrap_leader_tokens, dummy_leader_tokens);
GenesisBlock::new_with_leader(10_000, dummy_leader_id, dummy_leader_lamports);
assert_eq!(
genesis_block.bootstrap_leader_lamports,
dummy_leader_lamports
);
let bank = Bank::new(&genesis_block);
assert_eq!(
bank.get_balance(&genesis_block.mint_id),
10_000 - dummy_leader_tokens
10_000 - dummy_leader_lamports
);
assert_eq!(
bank.get_balance(&dummy_leader_id),
dummy_leader_tokens - 1 /* 1 token goes to the vote account associated with dummy_leader_tokens */
dummy_leader_lamports - 1 /* 1 token goes to the vote account associated with dummy_leader_lamports */
);
}
@ -878,7 +884,7 @@ mod tests {
let key1 = Keypair::new().pubkey();
let key2 = Keypair::new().pubkey();
let bank = Bank::new(&genesis_block);
let spend = SystemInstruction::Move { tokens: 1 };
let spend = SystemInstruction::Move { lamports: 1 };
let instructions = vec![
Instruction {
program_ids_index: 0,
@ -909,7 +915,7 @@ mod tests {
bank.get_signature_status(&t1.signatures[0]),
Some(Err(BankError::ProgramError(
1,
ProgramError::ResultWithNegativeTokens
ProgramError::ResultWithNegativeLamports
)))
);
}
@ -957,11 +963,11 @@ mod tests {
bank.process_transaction(&tx),
Err(BankError::ProgramError(
0,
ProgramError::ResultWithNegativeTokens
ProgramError::ResultWithNegativeLamports
))
);
// The tokens didn't move, but the from address paid the transaction fee.
// The lamports didn't move, but the from address paid the transaction fee.
assert_eq!(bank.get_balance(&dest.pubkey()), 0);
// This should be the original balance minus the transaction fee.
@ -993,7 +999,7 @@ mod tests {
bank.transfer(10_001, &mint_keypair, pubkey, genesis_block.hash()),
Err(BankError::ProgramError(
0,
ProgramError::ResultWithNegativeTokens
ProgramError::ResultWithNegativeLamports
))
);
assert_eq!(bank.transaction_count(), 1);
@ -1094,7 +1100,7 @@ mod tests {
Ok(()),
Err(BankError::ProgramError(
1,
ProgramError::ResultWithNegativeTokens,
ProgramError::ResultWithNegativeLamports,
)),
];
@ -1135,9 +1141,9 @@ mod tests {
#[test]
fn test_process_genesis() {
let dummy_leader_id = Keypair::new().pubkey();
let dummy_leader_tokens = 3;
let dummy_leader_lamports = 3;
let (genesis_block, _) =
GenesisBlock::new_with_leader(5, dummy_leader_id, dummy_leader_tokens);
GenesisBlock::new_with_leader(5, dummy_leader_id, dummy_leader_lamports);
let bank = Bank::new(&genesis_block);
assert_eq!(bank.get_balance(&genesis_block.mint_id), 2);
assert_eq!(bank.get_balance(&dummy_leader_id), 2);
@ -1418,8 +1424,8 @@ mod tests {
#[test]
fn test_bank_epoch_vote_accounts() {
let leader_id = Keypair::new().pubkey();
let leader_tokens = 3;
let (mut genesis_block, _) = GenesisBlock::new_with_leader(5, leader_id, leader_tokens);
let leader_lamports = 3;
let (mut genesis_block, _) = GenesisBlock::new_with_leader(5, leader_id, leader_lamports);
// set this up weird, forces:
// 1. genesis bank to cover epochs 0, 1, *and* 2
@ -1485,13 +1491,13 @@ mod tests {
let bank = Arc::new(Bank::new(&genesis_block));
let key = Keypair::new();
let move_tokens = SystemInstruction::Move { tokens: 1 };
let move_lamports = SystemInstruction::Move { lamports: 1 };
let mut tx = Transaction::new_unsigned(
&mint_keypair.pubkey(),
&[key.pubkey()],
system_program::id(),
&move_tokens,
&move_lamports,
bank.last_blockhash(),
2,
);

View File

@ -57,7 +57,7 @@ fn process_instruction(
fn verify_instruction(
program_id: &Pubkey,
pre_program_id: &Pubkey,
pre_tokens: u64,
pre_lamports: u64,
pre_userdata: &[u8],
account: &Account,
) -> Result<(), ProgramError> {
@ -68,8 +68,8 @@ fn verify_instruction(
return Err(ProgramError::ModifiedProgramId);
}
// For accounts unassigned to the program, the individual balance of each accounts cannot decrease.
if *program_id != account.owner && pre_tokens > account.tokens {
return Err(ProgramError::ExternalAccountTokenSpend);
if *program_id != account.owner && pre_lamports > account.lamports {
return Err(ProgramError::ExternalAccountLamportSpend);
}
// For accounts unassigned to the program, the userdata may not change.
if *program_id != account.owner
@ -95,10 +95,10 @@ fn execute_instruction(
let program_id = tx.program_id(instruction_index);
// TODO: the runtime should be checking read/write access to memory
// we are trusting the hard-coded programs not to clobber or allocate
let pre_total: u64 = program_accounts.iter().map(|a| a.tokens).sum();
let pre_total: u64 = program_accounts.iter().map(|a| a.lamports).sum();
let pre_data: Vec<_> = program_accounts
.iter_mut()
.map(|a| (a.owner, a.tokens, a.userdata.clone()))
.map(|a| (a.owner, a.lamports, a.userdata.clone()))
.collect();
process_instruction(
@ -110,19 +110,19 @@ fn execute_instruction(
)?;
// Verify the instruction
for ((pre_program_id, pre_tokens, pre_userdata), post_account) in
for ((pre_program_id, pre_lamports, pre_userdata), post_account) in
pre_data.iter().zip(program_accounts.iter())
{
verify_instruction(
&program_id,
pre_program_id,
*pre_tokens,
*pre_lamports,
pre_userdata,
post_account,
)?;
}
// The total sum of all the tokens in all the accounts cannot change.
let post_total: u64 = program_accounts.iter().map(|a| a.tokens).sum();
// The total sum of all the lamports in all the accounts cannot change.
let post_total: u64 = program_accounts.iter().map(|a| a.lamports).sum();
if pre_total != post_total {
return Err(ProgramError::UnbalancedInstruction);
}

View File

@ -5,8 +5,8 @@ use std::{cmp, fmt};
#[repr(C)]
#[derive(Serialize, Deserialize, Clone, Default, Eq, PartialEq)]
pub struct Account {
/// tokens in the account
pub tokens: u64,
/// lamports in the account
pub lamports: u64,
/// data held in this account
pub userdata: Vec<u8>,
/// the program that owns this account. If executable, the program that loads this account.
@ -28,8 +28,8 @@ impl fmt::Debug for Account {
};
write!(
f,
"Account {{ tokens: {} userdata.len: {} owner: {} executable: {}{} }}",
self.tokens,
"Account {{ lamports: {} userdata.len: {} owner: {} executable: {}{} }}",
self.lamports,
self.userdata.len(),
self.owner,
self.executable,
@ -40,9 +40,9 @@ impl fmt::Debug for Account {
impl Account {
// TODO do we want to add executable and leader_owner even though they should always be false/default?
pub fn new(tokens: u64, space: usize, owner: Pubkey) -> Account {
pub fn new(lamports: u64, space: usize, owner: Pubkey) -> Account {
Account {
tokens,
lamports,
userdata: vec![0u8; space],
owner,
executable: false,

View File

@ -8,18 +8,18 @@ use std::fs::File;
use std::io::Write;
use std::path::Path;
// The default (and minimal) amount of tokens given to the bootstrap leader:
// * 2 tokens for the bootstrap leader ID account to later setup another vote account
// * 1 token for the bootstrap leader vote account
pub const BOOTSTRAP_LEADER_TOKENS: u64 = 3;
// The default (and minimal) amount of lamports given to the bootstrap leader:
// * 2 lamports for the bootstrap leader ID account to later setup another vote account
// * 1 lamport for the bootstrap leader vote account
pub const BOOTSTRAP_LEADER_LAMPORTS: u64 = 3;
#[derive(Serialize, Deserialize, Debug)]
pub struct GenesisBlock {
pub bootstrap_leader_id: Pubkey,
pub bootstrap_leader_tokens: u64,
pub bootstrap_leader_lamports: u64,
pub bootstrap_leader_vote_account_id: Pubkey,
pub mint_id: Pubkey,
pub tokens: u64,
pub lamports: u64,
pub ticks_per_slot: u64,
pub slots_per_epoch: u64,
pub stakers_slot_offset: u64,
@ -27,27 +27,27 @@ pub struct GenesisBlock {
impl GenesisBlock {
#[allow(clippy::new_ret_no_self)]
pub fn new(tokens: u64) -> (Self, Keypair) {
let tokens = tokens
.checked_add(BOOTSTRAP_LEADER_TOKENS)
.unwrap_or(tokens);
Self::new_with_leader(tokens, Keypair::new().pubkey(), BOOTSTRAP_LEADER_TOKENS)
pub fn new(lamports: u64) -> (Self, Keypair) {
let lamports = lamports
.checked_add(BOOTSTRAP_LEADER_LAMPORTS)
.unwrap_or(lamports);
Self::new_with_leader(lamports, Keypair::new().pubkey(), BOOTSTRAP_LEADER_LAMPORTS)
}
pub fn new_with_leader(
tokens: u64,
lamports: u64,
bootstrap_leader_id: Pubkey,
bootstrap_leader_tokens: u64,
bootstrap_leader_lamports: u64,
) -> (Self, Keypair) {
let mint_keypair = Keypair::new();
let bootstrap_leader_vote_account_keypair = Keypair::new();
(
Self {
bootstrap_leader_id,
bootstrap_leader_tokens,
bootstrap_leader_lamports,
bootstrap_leader_vote_account_id: bootstrap_leader_vote_account_keypair.pubkey(),
mint_id: mint_keypair.pubkey(),
tokens,
lamports,
ticks_per_slot: DEFAULT_TICKS_PER_SLOT,
slots_per_epoch: DEFAULT_SLOTS_PER_EPOCH,
stakers_slot_offset: DEFAULT_SLOTS_PER_EPOCH,
@ -81,13 +81,13 @@ mod tests {
#[test]
fn test_genesis_block_new() {
let (genesis_block, mint) = GenesisBlock::new(10_000);
assert_eq!(genesis_block.tokens, 10_000 + BOOTSTRAP_LEADER_TOKENS);
assert_eq!(genesis_block.lamports, 10_000 + BOOTSTRAP_LEADER_LAMPORTS);
assert_eq!(genesis_block.mint_id, mint.pubkey());
assert!(genesis_block.bootstrap_leader_id != Pubkey::default());
assert!(genesis_block.bootstrap_leader_vote_account_id != Pubkey::default());
assert_eq!(
genesis_block.bootstrap_leader_tokens,
BOOTSTRAP_LEADER_TOKENS
genesis_block.bootstrap_leader_lamports,
BOOTSTRAP_LEADER_LAMPORTS
);
}
@ -97,9 +97,9 @@ mod tests {
let (genesis_block, mint) =
GenesisBlock::new_with_leader(20_000, leader_keypair.pubkey(), 123);
assert_eq!(genesis_block.tokens, 20_000);
assert_eq!(genesis_block.lamports, 20_000);
assert_eq!(genesis_block.mint_id, mint.pubkey());
assert_eq!(genesis_block.bootstrap_leader_id, leader_keypair.pubkey());
assert_eq!(genesis_block.bootstrap_leader_tokens, 123);
assert_eq!(genesis_block.bootstrap_leader_lamports, 123);
}
}

View File

@ -16,7 +16,7 @@ pub fn check_id(program_id: &Pubkey) -> bool {
/// Create an executable account with the given shared object name.
pub fn create_program_account(name: &str) -> Account {
Account {
tokens: 1,
lamports: 1,
owner: id(),
userdata: name.as_bytes().to_vec(),
executable: true,

View File

@ -14,16 +14,16 @@ pub enum ProgramError {
/// An instruction resulted in an account with a negative balance
/// The difference from InsufficientFundsForFee is that the transaction was executed by the
/// contract
ResultWithNegativeTokens,
ResultWithNegativeLamports,
/// Program's instruction token balance does not equal the balance after the instruction
/// Program's instruction lamport balance does not equal the balance after the instruction
UnbalancedInstruction,
/// Program modified an account's program id
ModifiedProgramId,
/// Program spent the tokens of an account that doesn't belong to it
ExternalAccountTokenSpend,
/// Program spent the lamports of an account that doesn't belong to it
ExternalAccountLamportSpend,
/// Program modified the userdata of an account that doesn't belong to it
ExternalAccountUserdataModified,

View File

@ -7,35 +7,35 @@ pub enum SystemInstruction {
/// Create a new account
/// * Transaction::keys[0] - source
/// * Transaction::keys[1] - new account key
/// * tokens - number of tokens to transfer to the new account
/// * lamports - number of lamports to transfer to the new account
/// * space - memory to allocate if greater then zero
/// * program_id - the program id of the new account
CreateAccount {
tokens: u64,
lamports: u64,
space: u64,
program_id: Pubkey,
},
/// Assign account to a program
/// * Transaction::keys[0] - account to assign
Assign { program_id: Pubkey },
/// Move tokens
/// Move lamports
/// * Transaction::keys[0] - source
/// * Transaction::keys[1] - destination
Move { tokens: u64 },
Move { lamports: u64 },
}
impl SystemInstruction {
pub fn new_program_account(
from_id: Pubkey,
to_id: Pubkey,
tokens: u64,
lamports: u64,
space: u64,
program_id: Pubkey,
) -> BuilderInstruction {
BuilderInstruction::new(
system_program::id(),
&SystemInstruction::CreateAccount {
tokens,
lamports,
space,
program_id,
},
@ -43,10 +43,10 @@ impl SystemInstruction {
)
}
pub fn new_move(from_id: Pubkey, to_id: Pubkey, tokens: u64) -> BuilderInstruction {
pub fn new_move(from_id: Pubkey, to_id: Pubkey, lamports: u64) -> BuilderInstruction {
BuilderInstruction::new(
system_program::id(),
&SystemInstruction::Move { tokens },
&SystemInstruction::Move { lamports },
vec![(from_id, true), (to_id, false)],
)
}

View File

@ -15,13 +15,13 @@ impl SystemTransaction {
from_keypair: &Keypair,
to: Pubkey,
recent_blockhash: Hash,
tokens: u64,
lamports: u64,
space: u64,
program_id: Pubkey,
fee: u64,
) -> Transaction {
let create = SystemInstruction::CreateAccount {
tokens, //TODO, the tokens to allocate might need to be higher then 0 in the future
lamports, //TODO, the lamports to allocate might need to be higher then 0 in the future
space,
program_id,
};
@ -39,7 +39,7 @@ impl SystemTransaction {
pub fn new_account(
from_keypair: &Keypair,
to: Pubkey,
tokens: u64,
lamports: u64,
recent_blockhash: Hash,
fee: u64,
) -> Transaction {
@ -48,7 +48,7 @@ impl SystemTransaction {
from_keypair,
to,
recent_blockhash,
tokens,
lamports,
0,
program_id,
fee,
@ -75,16 +75,16 @@ impl SystemTransaction {
pub fn new_move(
from_keypair: &Keypair,
to: Pubkey,
tokens: u64,
lamports: u64,
recent_blockhash: Hash,
fee: u64,
) -> Transaction {
let move_tokens = SystemInstruction::Move { tokens };
let move_lamports = SystemInstruction::Move { lamports };
Transaction::new(
from_keypair,
&[to],
system_program::id(),
&move_tokens,
&move_lamports,
recent_blockhash,
fee,
)
@ -100,7 +100,7 @@ impl SystemTransaction {
.iter()
.enumerate()
.map(|(i, (_, amount))| {
let spend = SystemInstruction::Move { tokens: *amount };
let spend = SystemInstruction::Move { lamports: *amount };
Instruction::new(0, &spend, vec![0, i as u8 + 1])
})
.collect();

View File

@ -86,7 +86,7 @@ pub struct Transaction {
pub account_keys: Vec<Pubkey>,
/// The id of a recent ledger entry.
pub recent_blockhash: Hash,
/// The number of tokens paid for processing and storing of this transaction.
/// The number of lamports paid for processing and storing of this transaction.
pub fee: u64,
/// All the program id keys used to execute this transaction's instructions
pub program_ids: Vec<Pubkey>,
@ -141,7 +141,7 @@ impl Transaction {
/// Create a signed transaction
/// * `from_keypair` - The key used to sign the transaction. This key is stored as keys[0]
/// * `account_keys` - The keys for the transaction. These are the program state
/// instances or token recipient keys.
/// instances or lamport recipient keys.
/// * `recent_blockhash` - The PoH hash.
/// * `fee` - The transaction fee.
/// * `program_ids` - The keys that identify programs used in the `instruction` vector.

View File

@ -50,7 +50,10 @@ fn test_wallet_deploy_program() {
.make_rpc_request(1, RpcRequest::GetAccountInfo, Some(params))
.unwrap();
let account_info_obj = account_info.as_object().unwrap();
assert_eq!(account_info_obj.get("tokens").unwrap().as_u64().unwrap(), 1);
assert_eq!(
account_info_obj.get("lamports").unwrap().as_u64().unwrap(),
1
);
let owner_array = account_info.get("owner").unwrap();
assert_eq!(owner_array, &json!(bpf_loader::id()));
assert_eq!(