Finish merging in the develop branch

This commit is contained in:
Luke Parker
2025-01-30 03:14:24 -05:00
parent 258c02ff39
commit a275023cfc
62 changed files with 452 additions and 508 deletions

View File

@@ -2,7 +2,7 @@ use core::marker::PhantomData;
use group::GroupEncoding;
use serai_primitives::{Coin, Amount};
use serai_primitives::{ExternalCoin, Amount};
use serai_db::{Get, DbTxn, create_db};
@@ -11,28 +11,28 @@ use scanner::{ScannerFeed, KeyFor, AddressFor, OutputFor};
create_db! {
TransactionChainingScheduler {
OperatingCosts: (coin: Coin) -> Amount,
SerializedOutputs: (key: &[u8], coin: Coin) -> Vec<u8>,
OperatingCosts: (coin: ExternalCoin) -> Amount,
SerializedOutputs: (key: &[u8], coin: ExternalCoin) -> Vec<u8>,
AlreadyAccumulatedOutput: (id: &[u8]) -> (),
// We should be immediately able to schedule the fulfillment of payments, yet this may not be
// possible if we're in the middle of a multisig rotation (as our output set will be split)
SerializedQueuedPayments: (key: &[u8], coin: Coin) -> Vec<u8>,
SerializedQueuedPayments: (key: &[u8], coin: ExternalCoin) -> Vec<u8>,
}
}
pub(crate) struct Db<S: ScannerFeed>(PhantomData<S>);
impl<S: ScannerFeed> Db<S> {
pub(crate) fn operating_costs(getter: &impl Get, coin: Coin) -> Amount {
pub(crate) fn operating_costs(getter: &impl Get, coin: ExternalCoin) -> Amount {
OperatingCosts::get(getter, coin).unwrap_or(Amount(0))
}
pub(crate) fn set_operating_costs(txn: &mut impl DbTxn, coin: Coin, amount: Amount) {
pub(crate) fn set_operating_costs(txn: &mut impl DbTxn, coin: ExternalCoin, amount: Amount) {
OperatingCosts::set(txn, coin, &amount)
}
pub(crate) fn outputs(
getter: &impl Get,
key: KeyFor<S>,
coin: Coin,
coin: ExternalCoin,
) -> Option<Vec<OutputFor<S>>> {
let buf = SerializedOutputs::get(getter, key.to_bytes().as_ref(), coin)?;
let mut buf = buf.as_slice();
@@ -46,7 +46,7 @@ impl<S: ScannerFeed> Db<S> {
pub(crate) fn set_outputs(
txn: &mut impl DbTxn,
key: KeyFor<S>,
coin: Coin,
coin: ExternalCoin,
outputs: &[OutputFor<S>],
) {
let mut buf = Vec::with_capacity(outputs.len() * 128);
@@ -55,7 +55,7 @@ impl<S: ScannerFeed> Db<S> {
}
SerializedOutputs::set(txn, key.to_bytes().as_ref(), coin, &buf);
}
pub(crate) fn del_outputs(txn: &mut impl DbTxn, key: KeyFor<S>, coin: Coin) {
pub(crate) fn del_outputs(txn: &mut impl DbTxn, key: KeyFor<S>, coin: ExternalCoin) {
SerializedOutputs::del(txn, key.to_bytes().as_ref(), coin);
}
@@ -75,7 +75,7 @@ impl<S: ScannerFeed> Db<S> {
pub(crate) fn queued_payments(
getter: &impl Get,
key: KeyFor<S>,
coin: Coin,
coin: ExternalCoin,
) -> Option<Vec<Payment<AddressFor<S>>>> {
let buf = SerializedQueuedPayments::get(getter, key.to_bytes().as_ref(), coin)?;
let mut buf = buf.as_slice();
@@ -89,7 +89,7 @@ impl<S: ScannerFeed> Db<S> {
pub(crate) fn set_queued_payments(
txn: &mut impl DbTxn,
key: KeyFor<S>,
coin: Coin,
coin: ExternalCoin,
queued: &[Payment<AddressFor<S>>],
) {
let mut buf = Vec::with_capacity(queued.len() * 128);
@@ -98,7 +98,7 @@ impl<S: ScannerFeed> Db<S> {
}
SerializedQueuedPayments::set(txn, key.to_bytes().as_ref(), coin, &buf);
}
pub(crate) fn del_queued_payments(txn: &mut impl DbTxn, key: KeyFor<S>, coin: Coin) {
pub(crate) fn del_queued_payments(txn: &mut impl DbTxn, key: KeyFor<S>, coin: ExternalCoin) {
SerializedQueuedPayments::del(txn, key.to_bytes().as_ref(), coin);
}
}

View File

@@ -7,7 +7,7 @@ use std::collections::HashMap;
use group::GroupEncoding;
use serai_primitives::{Coin, Amount};
use serai_primitives::{ExternalCoin, Amount};
use serai_db::DbTxn;
@@ -72,7 +72,7 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
block: &BlockFor<S>,
key_for_change: KeyFor<S>,
key: KeyFor<S>,
coin: Coin,
coin: ExternalCoin,
) -> Result<Vec<EventualityFor<S>>, <Self as SchedulerTrait<S>>::EphemeralError> {
let mut eventualities = vec![];
@@ -112,7 +112,7 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
txn: &mut impl DbTxn,
operating_costs: &mut u64,
key: KeyFor<S>,
coin: Coin,
coin: ExternalCoin,
value_of_outputs: u64,
) -> Vec<Payment<AddressFor<S>>> {
// Fetch all payments for this key
@@ -184,8 +184,6 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
let branch_address = P::branch_address(key);
'coin: for coin in S::NETWORK.coins() {
let coin = *coin;
// Perform any input aggregation we should
eventualities
.append(&mut self.aggregate_inputs(txn, block, key_for_change, key, coin).await?);
@@ -360,7 +358,7 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
block: &BlockFor<S>,
from: KeyFor<S>,
to: KeyFor<S>,
coin: Coin,
coin: ExternalCoin,
) -> Result<(), <Self as SchedulerTrait<S>>::EphemeralError> {
let from_bytes = from.to_bytes().as_ref().to_vec();
// Ensure our inputs are aggregated
@@ -404,10 +402,10 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
fn activate_key(txn: &mut impl DbTxn, key: KeyFor<S>) {
for coin in S::NETWORK.coins() {
assert!(Db::<S>::outputs(txn, key, *coin).is_none());
Db::<S>::set_outputs(txn, key, *coin, &[]);
assert!(Db::<S>::queued_payments(txn, key, *coin).is_none());
Db::<S>::set_queued_payments(txn, key, *coin, &[]);
assert!(Db::<S>::outputs(txn, key, coin).is_none());
Db::<S>::set_outputs(txn, key, coin, &[]);
assert!(Db::<S>::queued_payments(txn, key, coin).is_none());
Db::<S>::set_queued_payments(txn, key, coin, &[]);
}
}
@@ -423,18 +421,18 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
for coin in S::NETWORK.coins() {
// Move the payments to the new key
{
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 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;
queued.append(&mut new_queued);
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, retiring_key, coin, &[]);
Db::<S>::set_queued_payments(txn, new_key, coin, &queued);
}
// Move the outputs to the new key
self.flush_outputs(txn, &mut eventualities, block, retiring_key, new_key, *coin).await?;
self.flush_outputs(txn, &mut eventualities, block, retiring_key, new_key, coin).await?;
}
Ok(eventualities)
}
@@ -442,10 +440,10 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
fn retire_key(txn: &mut impl DbTxn, key: KeyFor<S>) {
for coin in S::NETWORK.coins() {
assert!(Db::<S>::outputs(txn, key, *coin).unwrap().is_empty());
Db::<S>::del_outputs(txn, key, *coin);
assert!(Db::<S>::queued_payments(txn, key, *coin).unwrap().is_empty());
Db::<S>::del_queued_payments(txn, key, *coin);
assert!(Db::<S>::outputs(txn, key, coin).unwrap().is_empty());
Db::<S>::del_outputs(txn, key, coin);
assert!(Db::<S>::queued_payments(txn, key, coin).unwrap().is_empty());
Db::<S>::del_queued_payments(txn, key, coin);
}
}
@@ -481,7 +479,7 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
block,
active_keys[0].0,
active_keys[1].0,
*coin,
coin,
)
.await?;
}
@@ -570,10 +568,10 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, EffectedReceivedOutputs<S>>> Sched
// Queue the payments for this key
for coin in S::NETWORK.coins() {
let mut queued_payments = Db::<S>::queued_payments(txn, fulfillment_key, *coin).unwrap();
let mut queued_payments = Db::<S>::queued_payments(txn, fulfillment_key, coin).unwrap();
queued_payments
.extend(payments.iter().filter(|payment| payment.balance().coin == *coin).cloned());
Db::<S>::set_queued_payments(txn, fulfillment_key, *coin, &queued_payments);
.extend(payments.iter().filter(|payment| payment.balance().coin == coin).cloned());
Db::<S>::set_queued_payments(txn, fulfillment_key, coin, &queued_payments);
}
// Handle the queued payments