Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion ledger/src/proofs/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4755,7 +4755,12 @@ pub(super) mod tests {
}

let rsa_private_key = {
let Ok(string) = std::fs::read_to_string("~/.openmina/debug/rsa.priv") else {
let Ok(home) = std::env::var("HOME") else {
eprintln!("$HOME not set");
return;
};
let Ok(string) = std::fs::read_to_string(format!("{home}/.openmina/debug/rsa.priv"))
else {
eprintln!("Missing private key");
return;
};
Expand Down
43 changes: 28 additions & 15 deletions ledger/src/transaction_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1315,13 +1315,13 @@ impl IndexedPool {
let current_balance = account
.liquid_balance_at_slot(global_slot_since_genesis)
.to_amount();
let first_cmd = queue.front().unwrap();
let first_cmd = queue.front().cloned().unwrap();
let first_nonce = first_cmd.data.forget_check().applicable_at_nonce();

if !(account.has_permission_to_send() && account.has_permission_to_increment_nonce())
|| account.nonce < first_nonce
{
let this_dropped = self.remove_with_dependents_exn(first_cmd)?;
let this_dropped = self.remove_with_dependents_exn(&first_cmd)?;
dropped.extend(this_dropped);
} else {
// current_nonce >= first_nonce
Expand All @@ -1330,50 +1330,63 @@ impl IndexedPool {
nonce == account.nonce
});

let keep_queue = match first_applicable_nonce_index {
let retained_for_nonce = match first_applicable_nonce_index {
Some(index) => queue.split_off(index),
None => Default::default(),
};
let drop_queue = queue;
let dropped_for_nonce = queue;

for cmd in &drop_queue {
for cmd in &dropped_for_nonce {
currency_reserved = currency_reserved
.checked_sub(&currency_consumed(&cmd.data.forget_check())?)
.unwrap();
}

let (keep_queue, currency_reserved, dropped_for_balance) =
Self::drop_until_sufficient_balance(
keep_queue,
retained_for_nonce,
currency_reserved,
current_balance,
)?;

let to_drop: Vec<_> = drop_queue.into_iter().chain(dropped_for_balance).collect();

let Some(head) = to_drop.first() else {
continue;
};

self.remove_applicable_exn(head);
self.update_remove_all_by_fee_and_hash_and_expiration(to_drop.clone());
let keeping_prefix = dropped_for_nonce.is_empty();
let keeping_suffix = dropped_for_balance.is_empty();
let to_drop: Vec<_> = dropped_for_nonce
.into_iter()
.chain(dropped_for_balance)
.collect();

match keep_queue.front().cloned() {
_ if keeping_prefix && keeping_suffix => {
// Nothing dropped, nothing needs to be updated
}
None => {
// We drop the entire queue, first element needs to be removed from
// applicable_by_fee
self.remove_applicable_exn(&first_cmd);
self.all_by_sender.remove(&sender);
}
Some(_) if keeping_prefix => {
// We drop only transactions from the end of queue, keeping
// the head untouched, no need to update applicable_by_fee
self.all_by_sender
.insert(sender, (keep_queue, currency_reserved));
}
Some(first_kept) => {
// We need to replace old queue head with the new queue head
// in applicable_by_fee
let first_kept_unchecked = first_kept.data.forget_check();
self.all_by_sender
.insert(sender, (keep_queue, currency_reserved));
self.remove_applicable_exn(&first_cmd);
Self::map_set_insert(
&mut self.applicable_by_fee,
first_kept_unchecked.fee_per_wu(),
first_kept,
);
}
}

self.update_remove_all_by_fee_and_hash_and_expiration(to_drop.clone());
dropped.extend(to_drop);
}
}
Expand Down
Loading