mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Finish merging in the develop branch
This commit is contained in:
@@ -90,7 +90,7 @@ use bitcoin_serai::bitcoin::{
|
||||
};
|
||||
|
||||
use serai_client::{
|
||||
primitives::{MAX_DATA_LEN, Coin, NetworkId, Amount, Balance},
|
||||
primitives::{MAX_DATA_LEN, ExternalNetworkId, ExternalCoin, Amount, Balance},
|
||||
networks::bitcoin::Address,
|
||||
};
|
||||
*/
|
||||
|
||||
@@ -14,7 +14,7 @@ use borsh::{BorshSerialize, BorshDeserialize};
|
||||
use serai_db::Get;
|
||||
|
||||
use serai_client::{
|
||||
primitives::{Coin, Amount, Balance, ExternalAddress},
|
||||
primitives::{ExternalCoin, Amount, ExternalBalance, ExternalAddress},
|
||||
networks::bitcoin::Address,
|
||||
};
|
||||
|
||||
@@ -127,8 +127,8 @@ impl ReceivedOutput<<Secp256k1 as Ciphersuite>::G, Address> for Output {
|
||||
self.presumed_origin.clone()
|
||||
}
|
||||
|
||||
fn balance(&self) -> Balance {
|
||||
Balance { coin: Coin::Bitcoin, amount: Amount(self.output.value()) }
|
||||
fn balance(&self) -> ExternalBalance {
|
||||
ExternalBalance { coin: ExternalCoin::Bitcoin, amount: Amount(self.output.value()) }
|
||||
}
|
||||
|
||||
fn data(&self) -> &[u8] {
|
||||
|
||||
@@ -2,7 +2,7 @@ use core::future::Future;
|
||||
|
||||
use bitcoin_serai::rpc::{RpcError, Rpc as BRpc};
|
||||
|
||||
use serai_client::primitives::{NetworkId, Coin, Amount};
|
||||
use serai_client::primitives::{ExternalNetworkId, ExternalCoin, Amount};
|
||||
|
||||
use serai_db::Db;
|
||||
use scanner::ScannerFeed;
|
||||
@@ -21,7 +21,7 @@ pub(crate) struct Rpc<D: Db> {
|
||||
}
|
||||
|
||||
impl<D: Db> ScannerFeed for Rpc<D> {
|
||||
const NETWORK: NetworkId = NetworkId::Bitcoin;
|
||||
const NETWORK: ExternalNetworkId = ExternalNetworkId::Bitcoin;
|
||||
// 6 confirmations is widely accepted as secure and shouldn't occur
|
||||
const CONFIRMATIONS: u64 = 6;
|
||||
// The window length should be roughly an hour
|
||||
@@ -118,8 +118,8 @@ impl<D: Db> ScannerFeed for Rpc<D> {
|
||||
}
|
||||
}
|
||||
|
||||
fn dust(coin: Coin) -> Amount {
|
||||
assert_eq!(coin, Coin::Bitcoin);
|
||||
fn dust(coin: ExternalCoin) -> Amount {
|
||||
assert_eq!(coin, ExternalCoin::Bitcoin);
|
||||
|
||||
/*
|
||||
A Taproot input is:
|
||||
@@ -158,11 +158,11 @@ impl<D: Db> ScannerFeed for Rpc<D> {
|
||||
|
||||
fn cost_to_aggregate(
|
||||
&self,
|
||||
coin: Coin,
|
||||
coin: ExternalCoin,
|
||||
_reference_block: &Self::Block,
|
||||
) -> impl Send + Future<Output = Result<Amount, Self::EphemeralError>> {
|
||||
async move {
|
||||
assert_eq!(coin, Coin::Bitcoin);
|
||||
assert_eq!(coin, ExternalCoin::Bitcoin);
|
||||
// TODO
|
||||
Ok(Amount(0))
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use bitcoin_serai::{
|
||||
};
|
||||
|
||||
use serai_client::{
|
||||
primitives::{Coin, Amount},
|
||||
primitives::{ExternalCoin, Amount},
|
||||
networks::bitcoin::Address,
|
||||
};
|
||||
|
||||
@@ -59,7 +59,7 @@ fn signable_transaction<D: Db>(
|
||||
.map(|payment| {
|
||||
(ScriptBuf::from(payment.address().clone()), {
|
||||
let balance = payment.balance();
|
||||
assert_eq!(balance.coin, Coin::Bitcoin);
|
||||
assert_eq!(balance.coin, ExternalCoin::Bitcoin);
|
||||
balance.amount.0
|
||||
})
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ use scale::{Encode, Decode};
|
||||
use borsh::{BorshSerialize, BorshDeserialize};
|
||||
|
||||
use serai_client::{
|
||||
primitives::{NetworkId, Coin, Amount, Balance},
|
||||
primitives::{ExternalNetworkId, ExternalCoin, Amount, ExternalBalance},
|
||||
networks::ethereum::Address,
|
||||
};
|
||||
|
||||
@@ -17,20 +17,20 @@ use ethereum_router::{Coin as EthereumCoin, InInstruction as EthereumInInstructi
|
||||
|
||||
use crate::{DAI, ETHER_DUST};
|
||||
|
||||
fn coin_to_serai_coin(coin: &EthereumCoin) -> Option<Coin> {
|
||||
fn coin_to_serai_coin(coin: &EthereumCoin) -> Option<ExternalCoin> {
|
||||
match coin {
|
||||
EthereumCoin::Ether => Some(Coin::Ether),
|
||||
EthereumCoin::Ether => Some(ExternalCoin::Ether),
|
||||
EthereumCoin::Erc20(token) => {
|
||||
if *token == DAI {
|
||||
return Some(Coin::Dai);
|
||||
return Some(ExternalCoin::Dai);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn amount_to_serai_amount(coin: Coin, amount: U256) -> Amount {
|
||||
assert_eq!(coin.network(), NetworkId::Ethereum);
|
||||
fn amount_to_serai_amount(coin: ExternalCoin, amount: U256) -> Amount {
|
||||
assert_eq!(coin.network(), ExternalNetworkId::Ethereum);
|
||||
assert_eq!(coin.decimals(), 8);
|
||||
// Remove 10 decimals so we go from 18 decimals to 8 decimals
|
||||
let divisor = U256::from(10_000_000_000u64);
|
||||
@@ -119,7 +119,7 @@ impl ReceivedOutput<<Secp256k1 as Ciphersuite>::G, Address> for Output {
|
||||
}
|
||||
}
|
||||
|
||||
fn balance(&self) -> Balance {
|
||||
fn balance(&self) -> ExternalBalance {
|
||||
match self {
|
||||
Output::Output { key: _, instruction } => {
|
||||
let coin = coin_to_serai_coin(&instruction.coin).unwrap_or_else(|| {
|
||||
@@ -128,9 +128,11 @@ impl ReceivedOutput<<Secp256k1 as Ciphersuite>::G, Address> for Output {
|
||||
"this never should have been yielded"
|
||||
)
|
||||
});
|
||||
Balance { coin, amount: amount_to_serai_amount(coin, instruction.amount) }
|
||||
ExternalBalance { coin, amount: amount_to_serai_amount(coin, instruction.amount) }
|
||||
}
|
||||
Output::Eventuality { .. } => {
|
||||
ExternalBalance { coin: ExternalCoin::Ether, amount: ETHER_DUST }
|
||||
}
|
||||
Output::Eventuality { .. } => Balance { coin: Coin::Ether, amount: ETHER_DUST },
|
||||
}
|
||||
}
|
||||
fn data(&self) -> &[u8] {
|
||||
|
||||
@@ -7,7 +7,7 @@ use alloy_transport::{RpcError, TransportErrorKind};
|
||||
use alloy_simple_request_transport::SimpleRequest;
|
||||
use alloy_provider::{Provider, RootProvider};
|
||||
|
||||
use serai_client::primitives::{NetworkId, Coin, Amount};
|
||||
use serai_client::primitives::{ExternalNetworkId, ExternalCoin, Amount};
|
||||
|
||||
use tokio::task::JoinSet;
|
||||
|
||||
@@ -30,7 +30,7 @@ pub(crate) struct Rpc<D: Db> {
|
||||
}
|
||||
|
||||
impl<D: Db> ScannerFeed for Rpc<D> {
|
||||
const NETWORK: NetworkId = NetworkId::Ethereum;
|
||||
const NETWORK: ExternalNetworkId = ExternalNetworkId::Ethereum;
|
||||
|
||||
// We only need one confirmation as Ethereum properly finalizes
|
||||
const CONFIRMATIONS: u64 = 1;
|
||||
@@ -209,22 +209,22 @@ impl<D: Db> ScannerFeed for Rpc<D> {
|
||||
}
|
||||
}
|
||||
|
||||
fn dust(coin: Coin) -> Amount {
|
||||
assert_eq!(coin.network(), NetworkId::Ethereum);
|
||||
fn dust(coin: ExternalCoin) -> Amount {
|
||||
assert_eq!(coin.network(), ExternalNetworkId::Ethereum);
|
||||
match coin {
|
||||
Coin::Ether => ETHER_DUST,
|
||||
Coin::Dai => DAI_DUST,
|
||||
ExternalCoin::Ether => ETHER_DUST,
|
||||
ExternalCoin::Dai => DAI_DUST,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn cost_to_aggregate(
|
||||
&self,
|
||||
coin: Coin,
|
||||
coin: ExternalCoin,
|
||||
_reference_block: &Self::Block,
|
||||
) -> impl Send + Future<Output = Result<Amount, Self::EphemeralError>> {
|
||||
async move {
|
||||
assert_eq!(coin.network(), NetworkId::Ethereum);
|
||||
assert_eq!(coin.network(), ExternalNetworkId::Ethereum);
|
||||
// There is no cost to aggregate as we receive to an account
|
||||
Ok(Amount(0))
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::collections::HashMap;
|
||||
use alloy_core::primitives::U256;
|
||||
|
||||
use serai_client::{
|
||||
primitives::{NetworkId, Coin, Balance},
|
||||
primitives::{ExternalNetworkId, ExternalCoin, ExternalBalance},
|
||||
networks::ethereum::Address,
|
||||
};
|
||||
|
||||
@@ -17,17 +17,17 @@ use ethereum_router::Coin as EthereumCoin;
|
||||
|
||||
use crate::{DAI, transaction::Action, rpc::Rpc};
|
||||
|
||||
fn coin_to_ethereum_coin(coin: Coin) -> EthereumCoin {
|
||||
assert_eq!(coin.network(), NetworkId::Ethereum);
|
||||
fn coin_to_ethereum_coin(coin: ExternalCoin) -> EthereumCoin {
|
||||
assert_eq!(coin.network(), ExternalNetworkId::Ethereum);
|
||||
match coin {
|
||||
Coin::Ether => EthereumCoin::Ether,
|
||||
Coin::Dai => EthereumCoin::Erc20(DAI),
|
||||
ExternalCoin::Ether => EthereumCoin::Ether,
|
||||
ExternalCoin::Dai => EthereumCoin::Erc20(DAI),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn balance_to_ethereum_amount(balance: Balance) -> U256 {
|
||||
assert_eq!(balance.coin.network(), NetworkId::Ethereum);
|
||||
fn balance_to_ethereum_amount(balance: ExternalBalance) -> U256 {
|
||||
assert_eq!(balance.coin.network(), ExternalNetworkId::Ethereum);
|
||||
assert_eq!(balance.coin.decimals(), 8);
|
||||
// Restore 10 decimals so we go from 8 decimals to 18 decimals
|
||||
// TODO: Document the expectation all integrated coins have 18 decimals
|
||||
@@ -73,17 +73,17 @@ impl<D: Db> smart_contract_scheduler::SmartContract<Rpc<D>> for SmartContract {
|
||||
}
|
||||
|
||||
let mut res = vec![];
|
||||
for coin in [Coin::Ether, Coin::Dai] {
|
||||
for coin in [ExternalCoin::Ether, ExternalCoin::Dai] {
|
||||
let Some(outs) = outs.remove(&coin) else { continue };
|
||||
assert!(!outs.is_empty());
|
||||
|
||||
let fee_per_gas = match coin {
|
||||
// 10 gwei
|
||||
Coin::Ether => {
|
||||
ExternalCoin::Ether => {
|
||||
U256::try_from(10u64).unwrap() * alloy_core::primitives::utils::Unit::GWEI.wei()
|
||||
}
|
||||
// 0.0003 DAI
|
||||
Coin::Dai => {
|
||||
ExternalCoin::Dai => {
|
||||
U256::try_from(30u64).unwrap() * alloy_core::primitives::utils::Unit::TWEI.wei()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
||||
@@ -8,7 +8,7 @@ use scale::{Encode, Decode};
|
||||
use borsh::{BorshSerialize, BorshDeserialize};
|
||||
|
||||
use serai_client::{
|
||||
primitives::{Coin, Amount, Balance},
|
||||
primitives::{ExternalCoin, Amount, ExternalBalance},
|
||||
networks::monero::Address,
|
||||
};
|
||||
|
||||
@@ -76,8 +76,8 @@ impl ReceivedOutput<<Ed25519 as Ciphersuite>::G, Address> for Output {
|
||||
None
|
||||
}
|
||||
|
||||
fn balance(&self) -> Balance {
|
||||
Balance { coin: Coin::Monero, amount: Amount(self.0.commitment().amount) }
|
||||
fn balance(&self) -> ExternalBalance {
|
||||
ExternalBalance { coin: ExternalCoin::Monero, amount: Amount(self.0.commitment().amount) }
|
||||
}
|
||||
|
||||
fn data(&self) -> &[u8] {
|
||||
|
||||
@@ -3,7 +3,7 @@ use core::future::Future;
|
||||
use monero_wallet::rpc::{RpcError, Rpc as RpcTrait};
|
||||
use monero_simple_request_rpc::SimpleRequestRpc;
|
||||
|
||||
use serai_client::primitives::{NetworkId, Coin, Amount};
|
||||
use serai_client::primitives::{ExternalNetworkId, ExternalCoin, Amount};
|
||||
|
||||
use scanner::ScannerFeed;
|
||||
use signers::TransactionPublisher;
|
||||
@@ -19,7 +19,7 @@ pub(crate) struct Rpc {
|
||||
}
|
||||
|
||||
impl ScannerFeed for Rpc {
|
||||
const NETWORK: NetworkId = NetworkId::Monero;
|
||||
const NETWORK: ExternalNetworkId = ExternalNetworkId::Monero;
|
||||
// Outputs aren't spendable until 10 blocks later due to the 10-block lock
|
||||
// Since we assumed scanned outputs are spendable, that sets a minimum confirmation depth of 10
|
||||
// A 10-block reorganization hasn't been observed in years and shouldn't occur
|
||||
@@ -107,8 +107,8 @@ impl ScannerFeed for Rpc {
|
||||
}
|
||||
}
|
||||
|
||||
fn dust(coin: Coin) -> Amount {
|
||||
assert_eq!(coin, Coin::Monero);
|
||||
fn dust(coin: ExternalCoin) -> Amount {
|
||||
assert_eq!(coin, ExternalCoin::Monero);
|
||||
|
||||
// 0.01 XMR
|
||||
Amount(10_000_000_000)
|
||||
@@ -116,11 +116,11 @@ impl ScannerFeed for Rpc {
|
||||
|
||||
fn cost_to_aggregate(
|
||||
&self,
|
||||
coin: Coin,
|
||||
coin: ExternalCoin,
|
||||
_reference_block: &Self::Block,
|
||||
) -> impl Send + Future<Output = Result<Amount, Self::EphemeralError>> {
|
||||
async move {
|
||||
assert_eq!(coin, Coin::Bitcoin);
|
||||
assert_eq!(coin, ExternalCoin::Bitcoin);
|
||||
// TODO
|
||||
Ok(Amount(0))
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use ciphersuite::{Ciphersuite, Ed25519};
|
||||
use monero_wallet::rpc::{FeeRate, RpcError};
|
||||
|
||||
use serai_client::{
|
||||
primitives::{Coin, Amount},
|
||||
primitives::{ExternalCoin, Amount},
|
||||
networks::monero::Address,
|
||||
};
|
||||
|
||||
@@ -106,7 +106,7 @@ async fn signable_transaction(
|
||||
.map(|payment| {
|
||||
(MoneroAddress::from(*payment.address()), {
|
||||
let balance = payment.balance();
|
||||
assert_eq!(balance.coin, Coin::Monero);
|
||||
assert_eq!(balance.coin, ExternalCoin::Monero);
|
||||
balance.amount.0
|
||||
})
|
||||
})
|
||||
|
||||
@@ -5,7 +5,7 @@ use group::GroupEncoding;
|
||||
|
||||
use borsh::{BorshSerialize, BorshDeserialize};
|
||||
|
||||
use serai_primitives::{ExternalAddress, Balance};
|
||||
use serai_primitives::{ExternalAddress, ExternalBalance};
|
||||
|
||||
use crate::Id;
|
||||
|
||||
@@ -133,7 +133,7 @@ pub trait ReceivedOutput<K: GroupEncoding, A: Address>:
|
||||
fn presumed_origin(&self) -> Option<A>;
|
||||
|
||||
/// The balance associated with this output.
|
||||
fn balance(&self) -> Balance;
|
||||
fn balance(&self) -> ExternalBalance;
|
||||
/// The arbitrary data (presumably an InInstruction) associated with this output.
|
||||
fn data(&self) -> &[u8];
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::io;
|
||||
use scale::{Encode, Decode, IoReader};
|
||||
use borsh::{BorshSerialize, BorshDeserialize};
|
||||
|
||||
use serai_primitives::Balance;
|
||||
use serai_primitives::ExternalBalance;
|
||||
use serai_coins_primitives::OutInstructionWithBalance;
|
||||
|
||||
use crate::Address;
|
||||
@@ -12,7 +12,7 @@ use crate::Address;
|
||||
#[derive(Clone, BorshSerialize, BorshDeserialize)]
|
||||
pub struct Payment<A: Address> {
|
||||
address: A,
|
||||
balance: Balance,
|
||||
balance: ExternalBalance,
|
||||
}
|
||||
|
||||
impl<A: Address> TryFrom<OutInstructionWithBalance> for Payment<A> {
|
||||
@@ -27,7 +27,7 @@ impl<A: Address> TryFrom<OutInstructionWithBalance> for Payment<A> {
|
||||
|
||||
impl<A: Address> Payment<A> {
|
||||
/// Create a new Payment.
|
||||
pub fn new(address: A, balance: Balance) -> Self {
|
||||
pub fn new(address: A, balance: ExternalBalance) -> Self {
|
||||
Payment { address, balance }
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ impl<A: Address> Payment<A> {
|
||||
&self.address
|
||||
}
|
||||
/// The balance to transfer.
|
||||
pub fn balance(&self) -> Balance {
|
||||
pub fn balance(&self) -> ExternalBalance {
|
||||
self.balance
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ impl<A: Address> Payment<A> {
|
||||
pub fn read(reader: &mut impl io::Read) -> io::Result<Self> {
|
||||
let address = A::deserialize_reader(reader)?;
|
||||
let reader = &mut IoReader(reader);
|
||||
let balance = Balance::decode(reader).map_err(io::Error::other)?;
|
||||
let balance = ExternalBalance::decode(reader).map_err(io::Error::other)?;
|
||||
Ok(Self { address, balance })
|
||||
}
|
||||
/// Write the Payment.
|
||||
|
||||
@@ -7,7 +7,7 @@ use scale::{Encode, Decode, IoReader};
|
||||
use borsh::{BorshSerialize, BorshDeserialize};
|
||||
use serai_db::{Get, DbTxn, create_db};
|
||||
|
||||
use serai_primitives::Balance;
|
||||
use serai_primitives::ExternalBalance;
|
||||
use serai_validator_sets_primitives::Session;
|
||||
|
||||
use primitives::EncodableG;
|
||||
@@ -39,7 +39,7 @@ create_db!(
|
||||
|
||||
pub(crate) struct ReturnInformation<S: ScannerFeed> {
|
||||
pub(crate) address: AddressFor<S>,
|
||||
pub(crate) balance: Balance,
|
||||
pub(crate) balance: ExternalBalance,
|
||||
}
|
||||
|
||||
pub(crate) struct BatchDb<S: ScannerFeed>(PhantomData<S>);
|
||||
@@ -116,7 +116,7 @@ impl<S: ScannerFeed> BatchDb<S> {
|
||||
|
||||
res.push((opt[0] == 1).then(|| {
|
||||
let address = AddressFor::<S>::deserialize_reader(&mut buf).unwrap();
|
||||
let balance = Balance::decode(&mut IoReader(&mut buf)).unwrap();
|
||||
let balance = ExternalBalance::decode(&mut IoReader(&mut buf)).unwrap();
|
||||
ReturnInformation { address, balance }
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use group::GroupEncoding;
|
||||
use borsh::{BorshSerialize, BorshDeserialize};
|
||||
use serai_db::{Get, DbTxn, Db};
|
||||
|
||||
use serai_primitives::{NetworkId, Coin, Amount};
|
||||
use serai_primitives::{ExternalNetworkId, ExternalCoin, Amount};
|
||||
use serai_coins_primitives::OutInstructionWithBalance;
|
||||
|
||||
use messages::substrate::ExecutedBatch;
|
||||
@@ -64,7 +64,7 @@ impl<B: Block> BlockExt for B {
|
||||
/// This defines the primitive types used, along with various getters necessary for indexing.
|
||||
pub trait ScannerFeed: 'static + Send + Sync + Clone {
|
||||
/// The ID of the network being scanned for.
|
||||
const NETWORK: NetworkId;
|
||||
const NETWORK: ExternalNetworkId;
|
||||
|
||||
/// The amount of confirmations a block must have to be considered finalized.
|
||||
///
|
||||
@@ -175,14 +175,14 @@ pub trait ScannerFeed: 'static + Send + Sync + Clone {
|
||||
///
|
||||
/// This MUST be constant. Serai MUST NOT create internal outputs worth less than this. This
|
||||
/// SHOULD be a value worth handling at a human level.
|
||||
fn dust(coin: Coin) -> Amount;
|
||||
fn dust(coin: ExternalCoin) -> Amount;
|
||||
|
||||
/// The cost to aggregate an input as of the specified block.
|
||||
///
|
||||
/// This is defined as the transaction fee for a 2-input, 1-output transaction.
|
||||
fn cost_to_aggregate(
|
||||
&self,
|
||||
coin: Coin,
|
||||
coin: ExternalCoin,
|
||||
reference_block: &Self::Block,
|
||||
) -> impl Send + Future<Output = Result<Amount, Self::EphemeralError>>;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use borsh::{BorshSerialize, BorshDeserialize};
|
||||
|
||||
use serai_primitives::{Coin, Amount, Balance};
|
||||
use serai_primitives::{ExternalCoin, Amount, ExternalBalance};
|
||||
|
||||
use primitives::{Address, Payment};
|
||||
use scanner::ScannerFeed;
|
||||
@@ -52,7 +52,7 @@ impl<A: Address> TreeTransaction<A> {
|
||||
/// payments should be made.
|
||||
pub fn payments<S: ScannerFeed>(
|
||||
&self,
|
||||
coin: Coin,
|
||||
coin: ExternalCoin,
|
||||
branch_address: &A,
|
||||
input_value: u64,
|
||||
) -> Option<Vec<Payment<A>>> {
|
||||
@@ -115,7 +115,10 @@ impl<A: Address> TreeTransaction<A> {
|
||||
.filter_map(|(payment, amount)| {
|
||||
amount.map(|amount| {
|
||||
// The existing payment, with the new amount
|
||||
Payment::new(payment.address().clone(), Balance { coin, amount: Amount(amount) })
|
||||
Payment::new(
|
||||
payment.address().clone(),
|
||||
ExternalBalance { coin, amount: Amount(amount) },
|
||||
)
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
@@ -126,7 +129,7 @@ impl<A: Address> TreeTransaction<A> {
|
||||
.filter_map(|amount| {
|
||||
amount.map(|amount| {
|
||||
// A branch output with the new amount
|
||||
Payment::new(branch_address.clone(), Balance { coin, amount: Amount(amount) })
|
||||
Payment::new(branch_address.clone(), ExternalBalance { coin, amount: Amount(amount) })
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
||||
@@ -2,7 +2,7 @@ use core::marker::PhantomData;
|
||||
|
||||
use group::GroupEncoding;
|
||||
|
||||
use serai_primitives::{Coin, Amount, Balance};
|
||||
use serai_primitives::{ExternalCoin, Amount, ExternalBalance};
|
||||
|
||||
use borsh::BorshDeserialize;
|
||||
use serai_db::{Get, DbTxn, create_db, db_channel};
|
||||
@@ -13,31 +13,31 @@ use scanner::{ScannerFeed, KeyFor, AddressFor, OutputFor};
|
||||
|
||||
create_db! {
|
||||
UtxoScheduler {
|
||||
OperatingCosts: (coin: Coin) -> Amount,
|
||||
SerializedOutputs: (key: &[u8], coin: Coin) -> Vec<u8>,
|
||||
SerializedQueuedPayments: (key: &[u8], coin: Coin) -> Vec<u8>,
|
||||
OperatingCosts: (coin: ExternalCoin) -> Amount,
|
||||
SerializedOutputs: (key: &[u8], coin: ExternalCoin) -> Vec<u8>,
|
||||
SerializedQueuedPayments: (key: &[u8], coin: ExternalCoin) -> Vec<u8>,
|
||||
}
|
||||
}
|
||||
|
||||
db_channel! {
|
||||
UtxoScheduler {
|
||||
PendingBranch: (key: &[u8], balance: Balance) -> Vec<u8>,
|
||||
PendingBranch: (key: &[u8], balance: ExternalBalance) -> 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();
|
||||
@@ -51,7 +51,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);
|
||||
@@ -60,14 +60,14 @@ 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);
|
||||
}
|
||||
|
||||
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();
|
||||
@@ -81,7 +81,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);
|
||||
@@ -90,14 +90,14 @@ 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);
|
||||
}
|
||||
|
||||
pub(crate) fn queue_pending_branch(
|
||||
txn: &mut impl DbTxn,
|
||||
key: KeyFor<S>,
|
||||
balance: Balance,
|
||||
balance: ExternalBalance,
|
||||
child: &TreeTransaction<AddressFor<S>>,
|
||||
) {
|
||||
PendingBranch::send(txn, key.to_bytes().as_ref(), balance, &borsh::to_vec(child).unwrap())
|
||||
@@ -105,7 +105,7 @@ impl<S: ScannerFeed> Db<S> {
|
||||
pub(crate) fn take_pending_branch(
|
||||
txn: &mut impl DbTxn,
|
||||
key: KeyFor<S>,
|
||||
balance: Balance,
|
||||
balance: ExternalBalance,
|
||||
) -> Option<TreeTransaction<AddressFor<S>>> {
|
||||
PendingBranch::try_recv(txn, key.to_bytes().as_ref(), balance)
|
||||
.map(|bytes| TreeTransaction::<AddressFor<S>>::deserialize(&mut bytes.as_slice()).unwrap())
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::collections::HashMap;
|
||||
|
||||
use group::GroupEncoding;
|
||||
|
||||
use serai_primitives::{Coin, Amount, Balance};
|
||||
use serai_primitives::{ExternalCoin, Amount, ExternalBalance};
|
||||
|
||||
use serai_db::DbTxn;
|
||||
|
||||
@@ -42,7 +42,7 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> Scheduler<S, P> {
|
||||
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![];
|
||||
|
||||
@@ -79,7 +79,7 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> Scheduler<S, P> {
|
||||
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
|
||||
@@ -133,7 +133,7 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> Scheduler<S, P> {
|
||||
fn queue_branches(
|
||||
txn: &mut impl DbTxn,
|
||||
key: KeyFor<S>,
|
||||
coin: Coin,
|
||||
coin: ExternalCoin,
|
||||
effected_payments: Vec<Amount>,
|
||||
tx: TreeTransaction<AddressFor<S>>,
|
||||
) {
|
||||
@@ -149,7 +149,7 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> Scheduler<S, P> {
|
||||
children thanks to our sort.
|
||||
*/
|
||||
for (amount, child) in effected_payments.into_iter().zip(children) {
|
||||
Db::<S>::queue_pending_branch(txn, key, Balance { coin, amount }, &child);
|
||||
Db::<S>::queue_pending_branch(txn, key, ExternalBalance { coin, amount }, &child);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,8 +216,6 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> Scheduler<S, P> {
|
||||
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?);
|
||||
@@ -308,7 +306,7 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> Scheduler<S, P> {
|
||||
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
|
||||
@@ -349,10 +347,10 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> SchedulerTrait<S> for Schedul
|
||||
|
||||
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, &[]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,18 +366,18 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> SchedulerTrait<S> for Schedul
|
||||
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)
|
||||
}
|
||||
@@ -387,10 +385,10 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> SchedulerTrait<S> for Schedul
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,7 +461,7 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> SchedulerTrait<S> for Schedul
|
||||
block,
|
||||
active_keys[0].0,
|
||||
active_keys[1].0,
|
||||
*coin,
|
||||
coin,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
@@ -552,10 +550,10 @@ impl<S: ScannerFeed, P: TransactionPlanner<S, ()>> SchedulerTrait<S> for Schedul
|
||||
|
||||
// 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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user