mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 13:39:25 +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,9 +84,11 @@ impl Block {
|
||||
/// structed as expected, this will return None.
|
||||
pub fn number(&self) -> Option<u64> {
|
||||
match &self.miner_tx {
|
||||
Transaction::V1 { prefix, .. } | Transaction::V2 { prefix, .. } => match prefix.inputs.first() {
|
||||
Some(Input::Gen(number)) => Some(*number),
|
||||
_ => None,
|
||||
Transaction::V1 { prefix, .. } | Transaction::V2 { prefix, .. } => {
|
||||
match prefix.inputs.first() {
|
||||
Some(Input::Gen(number)) => Some(*number),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,6 +301,13 @@ pub enum 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.
|
||||
// TODO: Replace ring_len, decoy_weights for &[&[usize]], where the inner buf is the decoy
|
||||
// offsets
|
||||
@@ -318,6 +325,9 @@ impl 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<()> {
|
||||
match self {
|
||||
Transaction::V1 { prefix, signatures } => {
|
||||
@@ -352,15 +362,22 @@ impl Transaction {
|
||||
let prefix = TransactionPrefix::read(r, version)?;
|
||||
|
||||
if version == 1 {
|
||||
let signatures = prefix
|
||||
.inputs
|
||||
.iter()
|
||||
.filter_map(|input| match input {
|
||||
// TODO: This allows mixing Gen and ToKey, which is likely undefined behavior?
|
||||
Input::ToKey { key_offsets, .. } => Some(RingSignature::read(key_offsets.len(), r)),
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
let signatures = if (prefix.inputs.len() == 1) && matches!(prefix.inputs[0], Input::Gen(_)) {
|
||||
vec![]
|
||||
} else {
|
||||
let mut signatures = Vec::with_capacity(prefix.inputs.len());
|
||||
for input in &prefix.inputs {
|
||||
match input {
|
||||
Input::ToKey { key_offsets, .. } => {
|
||||
signatures.push(RingSignature::read(key_offsets.len(), r)?)
|
||||
}
|
||||
_ => {
|
||||
Err(io::Error::other("reading signatures for a transaction with non-ToKey inputs"))?
|
||||
}
|
||||
}
|
||||
}
|
||||
signatures
|
||||
};
|
||||
|
||||
Ok(Transaction::V1 { prefix, signatures })
|
||||
} else if version == 2 {
|
||||
|
||||
Reference in New Issue
Block a user