Finish routing output flushing

Completes the transaction-chaining scheduler.
This commit is contained in:
Luke Parker
2024-09-04 02:06:21 -04:00
parent 653ead1e8c
commit 0c1aec29bb
3 changed files with 73 additions and 13 deletions

View File

@@ -455,7 +455,9 @@ impl<D: Db, S: ScannerFeed, Sch: Scheduler<S>> ContinuallyRan for EventualityTas
key.key != keys.last().unwrap().key, key.key != keys.last().unwrap().key,
"key which was forwarding was the last key (which has no key after it to forward to)" "key which was forwarding was the last key (which has no key after it to forward to)"
); );
Sch::flush_key(&mut txn, &block, key.key, keys.last().unwrap().key); let new_eventualities =
Sch::flush_key(&mut txn, &block, key.key, keys.last().unwrap().key);
intake_eventualities::<S>(&mut txn, new_eventualities);
} }
// Now that we've intaked any Eventualities caused, check if we're retiring any keys // Now that we've intaked any Eventualities caused, check if we're retiring any keys

View File

@@ -259,13 +259,12 @@ pub trait Scheduler<S: ScannerFeed>: 'static + Send {
/// ///
/// If the retiring key has any unfulfilled payments associated with it, those MUST be made /// If the retiring key has any unfulfilled payments associated with it, those MUST be made
/// the responsibility of the new key. /// the responsibility of the new key.
// TODO: This needs to return a HashMap for the eventualities
fn flush_key( fn flush_key(
txn: &mut impl DbTxn, txn: &mut impl DbTxn,
block: &BlockFor<S>, block: &BlockFor<S>,
retiring_key: KeyFor<S>, retiring_key: KeyFor<S>,
new_key: KeyFor<S>, new_key: KeyFor<S>,
); ) -> HashMap<Vec<u8>, Vec<EventualityFor<S>>>;
/// Retire a key as it'll no longer be used. /// Retire a key as it'll no longer be used.
/// ///

View File

@@ -454,6 +454,42 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
eventualities eventualities
} }
fn flush_outputs(
txn: &mut impl DbTxn,
eventualities: &mut HashMap<Vec<u8>, Vec<EventualityFor<S>>>,
block: &BlockFor<S>,
from: KeyFor<S>,
to: KeyFor<S>,
coin: Coin,
) {
let from_bytes = from.to_bytes().as_ref().to_vec();
// Ensure our inputs are aggregated
eventualities
.entry(from_bytes.clone())
.or_insert(vec![])
.append(&mut Self::aggregate_inputs(txn, block, to, from, coin));
// Now that our inputs are aggregated, transfer all of them to the new key
let mut operating_costs = Db::<S>::operating_costs(txn, coin).0;
let outputs = Db::<S>::outputs(txn, from, coin).unwrap();
if outputs.is_empty() {
return;
}
let planned = P::plan_transaction_with_fee_amortization(
&mut operating_costs,
P::fee_rate(block, coin),
outputs,
vec![],
Some(to),
);
Db::<S>::set_operating_costs(txn, coin, Amount(operating_costs));
let Some(planned) = planned else { return };
TransactionsToSign::<P::SignableTransaction>::send(txn, &from, &planned.signable);
eventualities.get_mut(&from_bytes).unwrap().push(planned.eventuality);
Self::accumulate_outputs(txn, planned.auxilliary.0, false);
}
} }
impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> SchedulerTrait<S> impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> SchedulerTrait<S>
@@ -470,22 +506,28 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
fn flush_key( fn flush_key(
txn: &mut impl DbTxn, txn: &mut impl DbTxn,
_block: &BlockFor<S>, block: &BlockFor<S>,
retiring_key: KeyFor<S>, retiring_key: KeyFor<S>,
new_key: KeyFor<S>, new_key: KeyFor<S>,
) { ) -> HashMap<Vec<u8>, Vec<EventualityFor<S>>> {
let mut eventualities = HashMap::new();
for coin in S::NETWORK.coins() { for coin in S::NETWORK.coins() {
let still_queued = Db::<S>::queued_payments(txn, retiring_key, *coin).unwrap(); // Move the payments to the new key
let mut new_queued = Db::<S>::queued_payments(txn, new_key, *coin).unwrap(); {
let still_queued = Db::<S>::queued_payments(txn, retiring_key, *coin).unwrap();
let mut new_queued = Db::<S>::queued_payments(txn, new_key, *coin).unwrap();
let mut queued = still_queued; let mut queued = still_queued;
queued.append(&mut new_queued); queued.append(&mut new_queued);
Db::<S>::set_queued_payments(txn, retiring_key, *coin, &[]); Db::<S>::set_queued_payments(txn, retiring_key, *coin, &[]);
Db::<S>::set_queued_payments(txn, new_key, *coin, &queued); Db::<S>::set_queued_payments(txn, new_key, *coin, &queued);
}
// TODO: Forward all existing outputs // Move the outputs to the new key
Self::flush_outputs(txn, &mut eventualities, block, retiring_key, new_key, *coin);
} }
eventualities
} }
fn retire_key(txn: &mut impl DbTxn, key: KeyFor<S>) { fn retire_key(txn: &mut impl DbTxn, key: KeyFor<S>) {
@@ -512,7 +554,24 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
.insert(key.to_bytes().as_ref().to_vec(), Self::step(txn, active_keys, block, *key)); .insert(key.to_bytes().as_ref().to_vec(), Self::step(txn, active_keys, block, *key));
} }
// TODO: If this key has been flushed, forward all outputs // If this key has been flushed, forward all outputs
match active_keys[0].1 {
LifetimeStage::ActiveYetNotReporting |
LifetimeStage::Active |
LifetimeStage::UsingNewForChange => {}
LifetimeStage::Forwarding | LifetimeStage::Finishing => {
for coin in S::NETWORK.coins() {
Self::flush_outputs(
txn,
&mut eventualities,
block,
active_keys[0].0,
active_keys[1].0,
*coin,
);
}
}
}
// Create the transactions for the forwards/burns // Create the transactions for the forwards/burns
{ {