mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Outline of the transaction-chaining scheduler
This commit is contained in:
@@ -19,7 +19,6 @@ workspace = true
|
||||
[dependencies]
|
||||
# Macros
|
||||
async-trait = { version = "0.1", default-features = false }
|
||||
thiserror = { version = "1", default-features = false }
|
||||
|
||||
# Encoders
|
||||
hex = { version = "0.4", default-features = false, features = ["std"] }
|
||||
@@ -37,7 +36,6 @@ serai-db = { path = "../../common/db" }
|
||||
|
||||
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
|
||||
serai-in-instructions-primitives = { path = "../../substrate/in-instructions/primitives", default-features = false, features = ["std"] }
|
||||
serai-coins-primitives = { path = "../../substrate/coins/primitives", default-features = false, features = ["std"] }
|
||||
serai-coins-primitives = { path = "../../substrate/coins/primitives", default-features = false, features = ["std", "borsh"] }
|
||||
|
||||
messages = { package = "serai-processor-messages", path = "../messages" }
|
||||
primitives = { package = "serai-processor-primitives", path = "../primitives" }
|
||||
|
||||
@@ -4,7 +4,7 @@ use group::GroupEncoding;
|
||||
|
||||
use serai_db::{Get, DbTxn, Db};
|
||||
|
||||
use primitives::{task::ContinuallyRan, OutputType, ReceivedOutput, Eventuality, Block};
|
||||
use primitives::{task::ContinuallyRan, OutputType, ReceivedOutput, Eventuality, Block, Payment};
|
||||
|
||||
use crate::{
|
||||
lifetime::LifetimeStage,
|
||||
@@ -12,7 +12,7 @@ use crate::{
|
||||
SeraiKey, OutputWithInInstruction, ReceiverScanData, ScannerGlobalDb, SubstrateToEventualityDb,
|
||||
ScanToEventualityDb,
|
||||
},
|
||||
BlockExt, ScannerFeed, KeyFor, OutputFor, EventualityFor, Payment, SchedulerUpdate, Scheduler,
|
||||
BlockExt, ScannerFeed, KeyFor, AddressFor, OutputFor, EventualityFor, SchedulerUpdate, Scheduler,
|
||||
sort_outputs,
|
||||
scan::{next_to_scan_for_outputs_block, queue_output_until_block},
|
||||
};
|
||||
@@ -168,7 +168,10 @@ impl<D: Db, S: ScannerFeed, Sch: Scheduler<S>> EventualityTask<D, S, Sch> {
|
||||
let new_eventualities = self.scheduler.fulfill(
|
||||
&mut txn,
|
||||
&keys_with_stages,
|
||||
burns.into_iter().filter_map(|burn| Payment::try_from(burn).ok()).collect(),
|
||||
burns
|
||||
.into_iter()
|
||||
.filter_map(|burn| Payment::<AddressFor<S>>::try_from(burn).ok())
|
||||
.collect(),
|
||||
);
|
||||
intake_eventualities::<S>(&mut txn, new_eventualities);
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ use group::GroupEncoding;
|
||||
|
||||
use serai_db::{Get, DbTxn, Db};
|
||||
|
||||
use serai_primitives::{NetworkId, Coin, Amount, Balance, Data};
|
||||
use serai_primitives::{NetworkId, Coin, Amount};
|
||||
use serai_in_instructions_primitives::Batch;
|
||||
use serai_coins_primitives::OutInstructionWithBalance;
|
||||
|
||||
use primitives::{task::*, Address, ReceivedOutput, Block};
|
||||
use primitives::{task::*, Address, ReceivedOutput, Block, Payment};
|
||||
|
||||
// Logic for deciding where in its lifetime a multisig is.
|
||||
mod lifetime;
|
||||
@@ -195,6 +195,16 @@ impl<S: ScannerFeed> Return<S> {
|
||||
let output = OutputFor::<S>::read(reader)?;
|
||||
Ok(Return { address, output })
|
||||
}
|
||||
|
||||
/// The address to return the output to.
|
||||
pub fn address(&self) -> &AddressFor<S> {
|
||||
&self.address
|
||||
}
|
||||
|
||||
/// The output to return.
|
||||
pub fn output(&self) -> &OutputFor<S> {
|
||||
&self.output
|
||||
}
|
||||
}
|
||||
|
||||
/// An update for the scheduler.
|
||||
@@ -219,40 +229,6 @@ impl<S: ScannerFeed> SchedulerUpdate<S> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A payment to fulfill.
|
||||
#[derive(Clone)]
|
||||
pub struct Payment<S: ScannerFeed> {
|
||||
address: AddressFor<S>,
|
||||
balance: Balance,
|
||||
data: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl<S: ScannerFeed> TryFrom<OutInstructionWithBalance> for Payment<S> {
|
||||
type Error = ();
|
||||
fn try_from(out_instruction_with_balance: OutInstructionWithBalance) -> Result<Self, ()> {
|
||||
Ok(Payment {
|
||||
address: out_instruction_with_balance.instruction.address.try_into().map_err(|_| ())?,
|
||||
balance: out_instruction_with_balance.balance,
|
||||
data: out_instruction_with_balance.instruction.data.map(Data::consume),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ScannerFeed> Payment<S> {
|
||||
/// The address to pay.
|
||||
pub fn address(&self) -> &AddressFor<S> {
|
||||
&self.address
|
||||
}
|
||||
/// The balance to transfer.
|
||||
pub fn balance(&self) -> Balance {
|
||||
self.balance
|
||||
}
|
||||
/// The data to associate with this payment.
|
||||
pub fn data(&self) -> &Option<Vec<u8>> {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
||||
/// The object responsible for accumulating outputs and planning new transactions.
|
||||
pub trait Scheduler<S: ScannerFeed>: 'static + Send {
|
||||
/// Activate a key.
|
||||
@@ -327,7 +303,7 @@ pub trait Scheduler<S: ScannerFeed>: 'static + Send {
|
||||
&mut self,
|
||||
txn: &mut impl DbTxn,
|
||||
active_keys: &[(KeyFor<S>, LifetimeStage)],
|
||||
payments: Vec<Payment<S>>,
|
||||
payments: Vec<Payment<AddressFor<S>>>,
|
||||
) -> HashMap<Vec<u8>, Vec<EventualityFor<S>>>;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::ScannerFeed;
|
||||
/// rotation process. Steps 7-8 regard a multisig which isn't retiring yet retired, and
|
||||
/// accordingly, no longer exists, so they are not modelled here (as this only models active
|
||||
/// multisigs. Inactive multisigs aren't represented in the first place).
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub enum LifetimeStage {
|
||||
/// A new multisig, once active, shouldn't actually start receiving coins until several blocks
|
||||
/// later. If any UI is premature in sending to this multisig, we delay to report the outputs to
|
||||
|
||||
Reference in New Issue
Block a user