Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add credit-debit rent handling #6947

Merged
merged 13 commits into from
Nov 20, 2019
4 changes: 2 additions & 2 deletions core/src/rpc_pubsub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ mod tests {
"lamports": 51,
"data": expected_data,
"executable": false,
"rent_epoch": 0,
"rent_epoch": 1,
},
"subscription": 0,
}
Expand Down Expand Up @@ -576,7 +576,7 @@ mod tests {
"lamports": 100,
"data": [],
"executable": false,
"rent_epoch": 0,
"rent_epoch": 1,
},
"subscription": 0,
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/rpc_subscriptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ mod tests {
subscriptions.check_account(&alice.pubkey(), 0, &bank_forks);
let string = transport_receiver.poll();
if let Async::Ready(Some(response)) = string.unwrap() {
let expected = format!(r#"{{"jsonrpc":"2.0","method":"accountNotification","params":{{"result":{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rent_epoch":0}},"subscription":0}}}}"#);
let expected = format!(r#"{{"jsonrpc":"2.0","method":"accountNotification","params":{{"result":{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rent_epoch":1}},"subscription":0}}}}"#);
assert_eq!(expected, response);
}

Expand Down Expand Up @@ -401,7 +401,7 @@ mod tests {
subscriptions.check_program(&solana_budget_api::id(), 0, &bank_forks);
let string = transport_receiver.poll();
if let Async::Ready(Some(response)) = string.unwrap() {
let expected = format!(r#"{{"jsonrpc":"2.0","method":"programNotification","params":{{"result":["{:?}",{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rent_epoch":0}}],"subscription":0}}}}"#, alice.pubkey());
let expected = format!(r#"{{"jsonrpc":"2.0","method":"programNotification","params":{{"result":["{:?}",{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rent_epoch":1}}],"subscription":0}}}}"#, alice.pubkey());
assert_eq!(expected, response);
}

Expand Down
55 changes: 37 additions & 18 deletions runtime/src/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ pub struct Accounts {

// for the load instructions
pub type TransactionAccounts = Vec<Account>;
pub type TransactionRents = Vec<u64>;
pub type TransactionRent = u64;
pub type TransactionLoaders = Vec<Vec<(Pubkey, Account)>>;

pub type TransactionLoadResult = (TransactionAccounts, TransactionLoaders, TransactionRents);
pub type TransactionLoadResult = (TransactionAccounts, TransactionLoaders, TransactionRent);

impl Accounts {
pub fn new(paths: Option<String>) -> Self {
Expand Down Expand Up @@ -92,7 +92,7 @@ impl Accounts {
fee: u64,
error_counters: &mut ErrorCounters,
rent_collector: &RentCollector,
) -> Result<(TransactionAccounts, TransactionRents)> {
) -> Result<(TransactionAccounts, TransactionRent)> {
// Copy all the accounts
let message = tx.message();
if tx.signatures.is_empty() && fee != 0 {
Expand All @@ -107,21 +107,27 @@ impl Accounts {
// There is no way to predict what program will execute without an error
// If a fee can pay for execution then the program will be scheduled
let mut accounts: TransactionAccounts = Vec::with_capacity(message.account_keys.len());
let mut rents: TransactionRents = Vec::with_capacity(message.account_keys.len());
for key in message
let mut tx_rent: TransactionRent = 0;
for (i, key) in message
.account_keys
.iter()
.filter(|key| !message.program_ids().contains(key))
.enumerate()
.filter(|(_, key)| !message.program_ids().contains(key))
{
let (account, rent) = AccountsDB::load(storage, ancestors, accounts_index, key)
.and_then(|(mut account, _)| {
let rent_due = rent_collector.update(&mut account);
Some((account, rent_due))
let rent_due: u64;
if message.is_writable(i) {
rent_due = rent_collector.update(&mut account);
Some((account, rent_due))
} else {
Some((account, 0))
}
})
.unwrap_or_default();

accounts.push(account);
rents.push(rent);
tx_rent += rent;
}

if accounts.is_empty() || accounts[0].lamports == 0 {
Expand All @@ -135,7 +141,7 @@ impl Accounts {
Err(TransactionError::InsufficientFundsForFee)
} else {
accounts[0].lamports -= fee;
Ok((accounts, rents))
Ok((accounts, tx_rent))
}
}
}
Expand Down Expand Up @@ -514,9 +520,10 @@ impl Accounts {
txs_iteration_order: Option<&[usize]>,
res: &[Result<()>],
loaded: &mut [Result<TransactionLoadResult>],
rent_collector: &RentCollector,
rob-solana marked this conversation as resolved.
Show resolved Hide resolved
) {
let accounts_to_store =
self.collect_accounts_to_store(txs, txs_iteration_order, res, loaded);
self.collect_accounts_to_store(txs, txs_iteration_order, res, loaded, rent_collector);
self.accounts_db.store(slot, &accounts_to_store);
}

Expand All @@ -536,6 +543,7 @@ impl Accounts {
txs_iteration_order: Option<&'a [usize]>,
res: &'a [Result<()>],
loaded: &'a mut [Result<TransactionLoadResult>],
rent_collector: &RentCollector,
) -> Vec<(&'a Pubkey, &'a Account)> {
let mut accounts = Vec::with_capacity(loaded.len());
for (i, (raccs, tx)) in loaded
Expand All @@ -549,9 +557,18 @@ impl Accounts {

let message = &tx.message();
let acc = raccs.as_mut().unwrap();
for ((i, key), account) in message.account_keys.iter().enumerate().zip(acc.0.iter()) {
for ((i, key), account) in message
.account_keys
.iter()
.enumerate()
.zip(acc.0.iter_mut())
{
if message.is_writable(i) {
accounts.push((key, account));
if account.rent_epoch == 0 {
account.rent_epoch = rent_collector.epoch;
acc.2 += rent_collector.update(account);
}
accounts.push((key, &*account));
}
}
}
Expand Down Expand Up @@ -1327,6 +1344,8 @@ mod tests {
let keypair1 = Keypair::new();
let pubkey = Pubkey::new_rand();

let rent_collector = RentCollector::default();

let instructions = vec![CompiledInstruction::new(2, &(), vec![0, 1])];
let message = Message::new_with_compiled_instructions(
1,
Expand Down Expand Up @@ -1358,20 +1377,20 @@ mod tests {

let transaction_accounts0 = vec![account0, account2.clone()];
let transaction_loaders0 = vec![];
let transaction_rents0 = vec![0, 0];
let transaction_rent0 = 0;
let loaded0 = Ok((
transaction_accounts0,
transaction_loaders0,
transaction_rents0,
transaction_rent0,
));

let transaction_accounts1 = vec![account1, account2.clone()];
let transaction_loaders1 = vec![];
let transaction_rents1 = vec![0, 0];
let transaction_rent1 = 0;
let loaded1 = Ok((
transaction_accounts1,
transaction_loaders1,
transaction_rents1,
transaction_rent1,
));

let mut loaded = vec![loaded0, loaded1];
Expand All @@ -1388,7 +1407,7 @@ mod tests {
);
}
let collected_accounts =
accounts.collect_accounts_to_store(&txs, None, &loaders, &mut loaded);
accounts.collect_accounts_to_store(&txs, None, &loaders, &mut loaded, &rent_collector);
assert_eq!(collected_accounts.len(), 2);
assert!(collected_accounts
.iter()
Expand Down
Loading