mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 21:49:26 +00:00
Only read transactions with one Input::Gen or all Input::ToKey
Also adds a helper to fetch a transaction's prefix.
This commit is contained in:
@@ -84,12 +84,14 @@ impl Block {
|
|||||||
/// structed as expected, this will return None.
|
/// structed as expected, this will return None.
|
||||||
pub fn number(&self) -> Option<u64> {
|
pub fn number(&self) -> Option<u64> {
|
||||||
match &self.miner_tx {
|
match &self.miner_tx {
|
||||||
Transaction::V1 { prefix, .. } | Transaction::V2 { prefix, .. } => match prefix.inputs.first() {
|
Transaction::V1 { prefix, .. } | Transaction::V2 { prefix, .. } => {
|
||||||
|
match prefix.inputs.first() {
|
||||||
Some(Input::Gen(number)) => Some(*number),
|
Some(Input::Gen(number)) => Some(*number),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Write the Block.
|
/// Write the Block.
|
||||||
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
|
|||||||
@@ -301,6 +301,13 @@ pub enum Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Transaction {
|
impl Transaction {
|
||||||
|
/// Get the TransactionPrefix of this transaction.
|
||||||
|
pub fn prefix(&self) -> &TransactionPrefix {
|
||||||
|
match self {
|
||||||
|
Transaction::V1 { prefix, .. } | Transaction::V2 { prefix, .. } => prefix,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The weight of this Transaction, as relevant for fees.
|
/// The weight of this Transaction, as relevant for fees.
|
||||||
// TODO: Replace ring_len, decoy_weights for &[&[usize]], where the inner buf is the decoy
|
// TODO: Replace ring_len, decoy_weights for &[&[usize]], where the inner buf is the decoy
|
||||||
// offsets
|
// offsets
|
||||||
@@ -318,6 +325,9 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write the Transaction.
|
/// Write the Transaction.
|
||||||
|
///
|
||||||
|
/// Some writable transactions may not be readable if they're malformed, per Monero's consensus
|
||||||
|
/// rules.
|
||||||
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Transaction::V1 { prefix, signatures } => {
|
Transaction::V1 { prefix, signatures } => {
|
||||||
@@ -352,15 +362,22 @@ impl Transaction {
|
|||||||
let prefix = TransactionPrefix::read(r, version)?;
|
let prefix = TransactionPrefix::read(r, version)?;
|
||||||
|
|
||||||
if version == 1 {
|
if version == 1 {
|
||||||
let signatures = prefix
|
let signatures = if (prefix.inputs.len() == 1) && matches!(prefix.inputs[0], Input::Gen(_)) {
|
||||||
.inputs
|
vec![]
|
||||||
.iter()
|
} else {
|
||||||
.filter_map(|input| match input {
|
let mut signatures = Vec::with_capacity(prefix.inputs.len());
|
||||||
// TODO: This allows mixing Gen and ToKey, which is likely undefined behavior?
|
for input in &prefix.inputs {
|
||||||
Input::ToKey { key_offsets, .. } => Some(RingSignature::read(key_offsets.len(), r)),
|
match input {
|
||||||
_ => None,
|
Input::ToKey { key_offsets, .. } => {
|
||||||
})
|
signatures.push(RingSignature::read(key_offsets.len(), r)?)
|
||||||
.collect::<Result<_, _>>()?;
|
}
|
||||||
|
_ => {
|
||||||
|
Err(io::Error::other("reading signatures for a transaction with non-ToKey inputs"))?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
signatures
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Transaction::V1 { prefix, signatures })
|
Ok(Transaction::V1 { prefix, signatures })
|
||||||
} else if version == 2 {
|
} else if version == 2 {
|
||||||
|
|||||||
Reference in New Issue
Block a user