mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-22 19:49:22 +00:00
Support v1 transactions
Closes https://github.com/serai-dex/serai/issues/117.
This commit is contained in:
parent
5a4eb0a076
commit
f48a48ec3f
4 changed files with 55 additions and 9 deletions
|
@ -195,6 +195,10 @@ impl Rpc {
|
|||
.collect()
|
||||
}
|
||||
|
||||
pub async fn get_transaction(&self, tx: [u8; 32]) -> Result<Transaction, RpcError> {
|
||||
self.get_transactions(&[tx]).await.map(|mut txs| txs.swap_remove(0))
|
||||
}
|
||||
|
||||
pub async fn get_block(&self, height: usize) -> Result<Block, RpcError> {
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct BlockResponse {
|
||||
|
|
|
@ -94,7 +94,12 @@ pub(crate) fn read_varint<R: io::Read>(r: &mut R) -> io::Result<u64> {
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
// TODO: https://github.com/serai-dex/serai/issues/25
|
||||
// All scalar fields supported by monero-serai are checked to be canonical for valid transactions
|
||||
// While from_bytes_mod_order would be more flexible, it's not currently needed and would be
|
||||
// inaccurate to include now. While casting a wide net may be preferable, it'd also be inaccurate
|
||||
// for now. There's also further edge cases as noted by
|
||||
// https://github.com/monero-project/monero/issues/8438, where some scalars had an archaic
|
||||
// reduction applied
|
||||
pub(crate) fn read_scalar<R: io::Read>(r: &mut R) -> io::Result<Scalar> {
|
||||
Scalar::from_canonical_bytes(read_bytes(r)?)
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "unreduced scalar"))
|
||||
|
|
|
@ -2,12 +2,15 @@ use core::cmp::Ordering;
|
|||
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use curve25519_dalek::edwards::{EdwardsPoint, CompressedEdwardsY};
|
||||
use curve25519_dalek::{
|
||||
scalar::Scalar,
|
||||
edwards::{EdwardsPoint, CompressedEdwardsY},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
Protocol, hash,
|
||||
serialize::*,
|
||||
ringct::{RctPrunable, RctSignatures},
|
||||
ringct::{RctBase, RctPrunable, RctSignatures},
|
||||
};
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
|
@ -189,6 +192,7 @@ impl TransactionPrefix {
|
|||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Transaction {
|
||||
pub prefix: TransactionPrefix,
|
||||
pub signatures: Vec<(Scalar, Scalar)>,
|
||||
pub rct_signatures: RctSignatures,
|
||||
}
|
||||
|
||||
|
@ -205,13 +209,42 @@ impl Transaction {
|
|||
|
||||
pub fn serialize<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
self.prefix.serialize(w)?;
|
||||
self.rct_signatures.serialize(w)
|
||||
if self.prefix.version == 1 {
|
||||
for sig in &self.signatures {
|
||||
write_scalar(&sig.0, w)?;
|
||||
write_scalar(&sig.1, w)?;
|
||||
}
|
||||
Ok(())
|
||||
} else if self.prefix.version == 2 {
|
||||
self.rct_signatures.serialize(w)
|
||||
} else {
|
||||
panic!("Serializing a transaction with an unknown version");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deserialize<R: std::io::Read>(r: &mut R) -> std::io::Result<Transaction> {
|
||||
let prefix = TransactionPrefix::deserialize(r)?;
|
||||
Ok(Transaction {
|
||||
rct_signatures: RctSignatures::deserialize(
|
||||
let mut signatures = vec![];
|
||||
let mut rct_signatures = RctSignatures {
|
||||
base: RctBase { fee: 0, ecdh_info: vec![], commitments: vec![] },
|
||||
prunable: RctPrunable::Null,
|
||||
};
|
||||
|
||||
if prefix.version == 1 {
|
||||
for _ in 0 .. prefix.inputs.len() {
|
||||
signatures.push((read_scalar(r)?, read_scalar(r)?));
|
||||
}
|
||||
rct_signatures.base.fee = prefix
|
||||
.inputs
|
||||
.iter()
|
||||
.map(|input| match input {
|
||||
Input::Gen(..) => 0,
|
||||
Input::ToKey { amount, .. } => *amount,
|
||||
})
|
||||
.sum::<u64>()
|
||||
.saturating_sub(prefix.outputs.iter().map(|output| output.amount).sum());
|
||||
} else if prefix.version == 2 {
|
||||
rct_signatures = RctSignatures::deserialize(
|
||||
prefix
|
||||
.inputs
|
||||
.iter()
|
||||
|
@ -222,9 +255,12 @@ impl Transaction {
|
|||
.collect(),
|
||||
prefix.outputs.len(),
|
||||
r,
|
||||
)?,
|
||||
prefix,
|
||||
})
|
||||
)?;
|
||||
} else {
|
||||
Err(std::io::Error::new(std::io::ErrorKind::Other, "Tried to deserialize unknown version"))?;
|
||||
}
|
||||
|
||||
Ok(Transaction { prefix, signatures, rct_signatures })
|
||||
}
|
||||
|
||||
pub fn hash(&self) -> [u8; 32] {
|
||||
|
|
|
@ -334,6 +334,7 @@ impl SignableTransaction {
|
|||
outputs: tx_outputs,
|
||||
extra,
|
||||
},
|
||||
signatures: vec![],
|
||||
rct_signatures: RctSignatures {
|
||||
base: RctBase {
|
||||
fee: self.fee,
|
||||
|
|
Loading…
Reference in a new issue