mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-05 10:29:40 +00:00
Return Timelocked instead of (Timelock, Vec<SpendableOutput>)
Timelocked doesn't expose the Vec yet requires calling not_locked(), unlocked(Timelock), or ignore_timelock().
This commit is contained in:
parent
a4cd1755a5
commit
53267a46c8
5 changed files with 48 additions and 15 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
use curve25519_dalek::edwards::EdwardsPoint;
|
use curve25519_dalek::edwards::EdwardsPoint;
|
||||||
|
|
||||||
use crate::{hash, serialize::*, ringct::{RctPrunable, RctSignatures}};
|
use crate::{hash, serialize::*, ringct::{RctPrunable, RctSignatures}};
|
||||||
|
@ -131,6 +133,17 @@ impl Timelock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Timelock {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
match (self, other) {
|
||||||
|
(Timelock::None, _) => Some(Ordering::Less),
|
||||||
|
(Timelock::Block(a), Timelock::Block(b)) => a.partial_cmp(b),
|
||||||
|
(Timelock::Time(a), Timelock::Time(b)) => a.partial_cmp(b),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub struct TransactionPrefix {
|
pub struct TransactionPrefix {
|
||||||
pub version: u64,
|
pub version: u64,
|
||||||
|
|
|
@ -24,6 +24,30 @@ pub struct SpendableOutput {
|
||||||
pub commitment: Commitment
|
pub commitment: Commitment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Timelocked(Timelock, Vec<SpendableOutput>);
|
||||||
|
impl Timelocked {
|
||||||
|
pub fn timelock(&self) -> Timelock {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn not_locked(&self) -> Vec<SpendableOutput> {
|
||||||
|
if self.0 == Timelock::None {
|
||||||
|
return self.1.clone();
|
||||||
|
}
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns None if the Timelocks aren't comparable. Returns Some(vec![]) if none are unlocked
|
||||||
|
pub fn unlocked(&self, timelock: Timelock) -> Option<Vec<SpendableOutput>> {
|
||||||
|
// If the Timelocks are comparable, return the outputs if they're now unlocked
|
||||||
|
self.0.partial_cmp(&timelock).filter(|_| self.0 <= timelock).map(|_| self.1.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ignore_timelock(&self) -> Vec<SpendableOutput> {
|
||||||
|
self.1.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SpendableOutput {
|
impl SpendableOutput {
|
||||||
pub fn serialize(&self) -> Vec<u8> {
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
let mut res = Vec::with_capacity(32 + 1 + 32 + 32 + 40);
|
let mut res = Vec::with_capacity(32 + 1 + 32 + 32 + 40);
|
||||||
|
@ -57,7 +81,7 @@ impl Transaction {
|
||||||
&self,
|
&self,
|
||||||
view: ViewPair,
|
view: ViewPair,
|
||||||
guaranteed: bool
|
guaranteed: bool
|
||||||
) -> (Vec<SpendableOutput>, Timelock) {
|
) -> Timelocked {
|
||||||
let mut extra = vec![];
|
let mut extra = vec![];
|
||||||
write_varint(&u64::try_from(self.prefix.extra.len()).unwrap(), &mut extra).unwrap();
|
write_varint(&u64::try_from(self.prefix.extra.len()).unwrap(), &mut extra).unwrap();
|
||||||
extra.extend(&self.prefix.extra);
|
extra.extend(&self.prefix.extra);
|
||||||
|
@ -75,7 +99,7 @@ impl Transaction {
|
||||||
|
|
||||||
pubkeys = m_pubkeys.iter().map(|key| key.point.decompress()).filter_map(|key| key).collect();
|
pubkeys = m_pubkeys.iter().map(|key| key.point.decompress()).filter_map(|key| key).collect();
|
||||||
} else {
|
} else {
|
||||||
return (vec![], self.prefix.timelock);
|
return Timelocked(self.prefix.timelock, vec![]);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
|
@ -132,6 +156,6 @@ impl Transaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(res, self.prefix.timelock)
|
Timelocked(self.prefix.timelock, res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ async fn send_core(test: usize, multisig: bool) {
|
||||||
|
|
||||||
// Grab the largest output available
|
// Grab the largest output available
|
||||||
let output = {
|
let output = {
|
||||||
let mut outputs = tx.as_ref().unwrap().scan(view_pair, false).0;
|
let mut outputs = tx.as_ref().unwrap().scan(view_pair, false).ignore_timelock();
|
||||||
outputs.sort_by(|x, y| x.commitment.amount.cmp(&y.commitment.amount).reverse());
|
outputs.sort_by(|x, y| x.commitment.amount.cmp(&y.commitment.amount).reverse());
|
||||||
outputs.swap_remove(0)
|
outputs.swap_remove(0)
|
||||||
};
|
};
|
||||||
|
@ -116,7 +116,7 @@ async fn send_core(test: usize, multisig: bool) {
|
||||||
|
|
||||||
for i in (start + 1) .. (start + 9) {
|
for i in (start + 1) .. (start + 9) {
|
||||||
let tx = rpc.get_block_transactions(i).await.unwrap().swap_remove(0);
|
let tx = rpc.get_block_transactions(i).await.unwrap().swap_remove(0);
|
||||||
let output = tx.scan(view_pair, false).0.swap_remove(0);
|
let output = tx.scan(view_pair, false).ignore_timelock().swap_remove(0);
|
||||||
amount += output.commitment.amount;
|
amount += output.commitment.amount;
|
||||||
outputs.push(output);
|
outputs.push(output);
|
||||||
}
|
}
|
||||||
|
|
3
processor/build.rs
Normal file
3
processor/build.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("cargo:rustc-link-arg=-zmuldefs");
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ use transcript::RecommendedTranscript;
|
||||||
use frost::{curve::Ed25519, FrostKeys};
|
use frost::{curve::Ed25519, FrostKeys};
|
||||||
|
|
||||||
use monero_serai::{
|
use monero_serai::{
|
||||||
transaction::{Timelock, Transaction},
|
transaction::Transaction,
|
||||||
rpc::Rpc,
|
rpc::Rpc,
|
||||||
wallet::{
|
wallet::{
|
||||||
ViewPair, address::{Network, AddressType, Address},
|
ViewPair, address::{Network, AddressType, Address},
|
||||||
|
@ -126,14 +126,7 @@ impl Coin for Monero {
|
||||||
async fn get_outputs(&self, block: &Self::Block, key: dfg::EdwardsPoint) -> Vec<Self::Output> {
|
async fn get_outputs(&self, block: &Self::Block, key: dfg::EdwardsPoint) -> Vec<Self::Output> {
|
||||||
block
|
block
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|tx| {
|
.flat_map(|tx| tx.scan(self.view_pair(key), true).not_locked())
|
||||||
let (outputs, timelock) = tx.scan(self.view_pair(key), true);
|
|
||||||
if timelock == Timelock::None {
|
|
||||||
outputs
|
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map(Output::from)
|
.map(Output::from)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -215,7 +208,7 @@ impl Coin for Monero {
|
||||||
|
|
||||||
let outputs = self.rpc
|
let outputs = self.rpc
|
||||||
.get_block_transactions_possible(height).await.unwrap()
|
.get_block_transactions_possible(height).await.unwrap()
|
||||||
.swap_remove(0).scan(self.empty_view_pair(), false).0;
|
.swap_remove(0).scan(self.empty_view_pair(), false).ignore_timelock();
|
||||||
|
|
||||||
let amount = outputs[0].commitment.amount;
|
let amount = outputs[0].commitment.amount;
|
||||||
let fee = 1000000000; // TODO
|
let fee = 1000000000; // TODO
|
||||||
|
|
Loading…
Reference in a new issue