misc changes

This commit is contained in:
Boog900 2024-08-02 00:10:27 +01:00
parent 4c310720b9
commit f48ea910d9
No known key found for this signature in database
GPG key ID: 42AB1287CB0041C2
6 changed files with 106 additions and 59 deletions

View file

@ -12,11 +12,7 @@ use std::{
}; };
use futures::FutureExt; use futures::FutureExt;
use monero_serai::ringct::bulletproofs::Bulletproof; use monero_serai::transaction::{Input, Timelock, Transaction};
use monero_serai::{
ringct::RctType,
transaction::{Input, Timelock, Transaction},
};
use rayon::prelude::*; use rayon::prelude::*;
use tower::{Service, ServiceExt}; use tower::{Service, ServiceExt};
use tracing::instrument; use tracing::instrument;
@ -38,6 +34,7 @@ use crate::{
}; };
pub mod contextual_data; pub mod contextual_data;
mod free;
/// A struct representing the type of validation that needs to be completed for this transaction. /// A struct representing the type of validation that needs to be completed for this transaction.
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
@ -104,52 +101,9 @@ impl TransactionVerificationData {
let tx_hash = tx.hash(); let tx_hash = tx.hash();
let tx_blob = tx.serialize(); let tx_blob = tx.serialize();
// the tx weight is only different from the blobs length for bp(+) txs. let tx_weight = free::tx_weight(&tx, &tx_blob);
let tx_weight = match &tx {
Transaction::V1 { .. } | Transaction::V2 { proofs: None, .. } => tx_blob.len(),
Transaction::V2 {
proofs: Some(proofs),
..
} => match proofs.rct_type() {
RctType::AggregateMlsagBorromean | RctType::MlsagBorromean => tx_blob.len(),
RctType::MlsagBulletproofs
| RctType::MlsagBulletproofsCompactAmount
| RctType::ClsagBulletproof => {
tx_blob.len()
+ Bulletproof::calculate_bp_clawback(false, tx.prefix().outputs.len()).0
}
RctType::ClsagBulletproofPlus => {
tx_blob.len()
+ Bulletproof::calculate_bp_clawback(true, tx.prefix().outputs.len()).0
}
},
};
let mut fee = 0_u64; let fee = free::tx_fee(&tx)?;
match &tx {
Transaction::V1 { prefix, .. } => {
for input in &prefix.inputs {
if let Input::ToKey { amount, .. } = input {
fee = fee
.checked_add(amount.unwrap_or(0))
.ok_or(TransactionError::InputsOverflow)?;
}
}
for output in &prefix.outputs {
fee.checked_sub(output.amount.unwrap_or(0))
.ok_or(TransactionError::OutputsTooHigh)?;
}
}
Transaction::V2 { proofs, .. } => {
fee = proofs
.as_ref()
.ok_or(TransactionError::TransactionVersionInvalid)?
.base
.fee;
}
};
Ok(TransactionVerificationData { Ok(TransactionVerificationData {
tx_hash, tx_hash,

View file

@ -0,0 +1,64 @@
use monero_serai::{
ringct::{bulletproofs::Bulletproof, RctType},
transaction::{Input, Transaction},
};
use cuprate_consensus_rules::transactions::TransactionError;
/// Calculates the weight of a [`Transaction`].
///
/// This is more efficient that [`Transaction::weight`] if you already have the transaction blob.
pub fn tx_weight(tx: &Transaction, tx_blob: &[u8]) -> usize {
// the tx weight is only different from the blobs length for bp(+) txs.
match &tx {
Transaction::V1 { .. } | Transaction::V2 { proofs: None, .. } => tx_blob.len(),
Transaction::V2 {
proofs: Some(proofs),
..
} => match proofs.rct_type() {
RctType::AggregateMlsagBorromean | RctType::MlsagBorromean => tx_blob.len(),
RctType::MlsagBulletproofs
| RctType::MlsagBulletproofsCompactAmount
| RctType::ClsagBulletproof => {
tx_blob.len()
+ Bulletproof::calculate_bp_clawback(false, tx.prefix().outputs.len()).0
}
RctType::ClsagBulletproofPlus => {
tx_blob.len()
+ Bulletproof::calculate_bp_clawback(true, tx.prefix().outputs.len()).0
}
},
}
}
/// Calculates the fee of the [`Transaction`].
pub fn tx_fee(tx: &Transaction) -> Result<u64, TransactionError> {
let mut fee = 0_u64;
match &tx {
Transaction::V1 { prefix, .. } => {
for input in &prefix.inputs {
if let Input::ToKey { amount, .. } = input {
fee = fee
.checked_add(amount.unwrap_or(0))
.ok_or(TransactionError::InputsOverflow)?;
}
}
for output in &prefix.outputs {
fee.checked_sub(output.amount.unwrap_or(0))
.ok_or(TransactionError::OutputsTooHigh)?;
}
}
Transaction::V2 { proofs, .. } => {
fee = proofs
.as_ref()
.ok_or(TransactionError::TransactionVersionInvalid)?
.base
.fee;
}
};
Ok(fee)
}

View file

@ -8,11 +8,11 @@
//---------------------------------------------------------------------------------------------------- Import //---------------------------------------------------------------------------------------------------- Import
use std::sync::OnceLock; use std::sync::OnceLock;
use hex_literal::hex;
use monero_serai::{block::Block, transaction::Transaction};
use cuprate_helper::map::combine_low_high_bits_to_u128; use cuprate_helper::map::combine_low_high_bits_to_u128;
use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation}; use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
use hex_literal::hex;
use monero_serai::transaction::Input;
use monero_serai::{block::Block, transaction::Transaction};
use crate::data::constants::{ use crate::data::constants::{
BLOCK_43BD1F, BLOCK_5ECB7E, BLOCK_F91043, TX_2180A8, TX_3BC7FF, TX_84D48D, TX_9E3F73, BLOCK_43BD1F, BLOCK_5ECB7E, BLOCK_F91043, TX_2180A8, TX_3BC7FF, TX_84D48D, TX_9E3F73,
@ -104,13 +104,41 @@ fn to_tx_verification_data(tx_blob: impl AsRef<[u8]>) -> VerifiedTransactionInfo
VerifiedTransactionInformation { VerifiedTransactionInformation {
tx_weight: tx.weight(), tx_weight: tx.weight(),
// TODO: // TODO:
fee: 0, fee: tx_fee(&tx),
tx_hash: tx.hash(), tx_hash: tx.hash(),
tx_blob, tx_blob,
tx, tx,
} }
} }
/// Calculates the fee of the [`Transaction`].
///
/// # Panics
/// This will panic if the inputs overflow or the transaction outputs too much.
///
pub fn tx_fee(tx: &Transaction) -> u64 {
let mut fee = 0_u64;
match &tx {
Transaction::V1 { prefix, .. } => {
for input in &prefix.inputs {
if let Input::ToKey { amount, .. } = input {
fee = fee.checked_add(amount.unwrap_or(0)).unwrap();
}
}
for output in &prefix.outputs {
fee.checked_sub(output.amount.unwrap_or(0)).unwrap();
}
}
Transaction::V2 { proofs, .. } => {
fee = proofs.as_ref().unwrap().base.fee;
}
};
fee
}
//---------------------------------------------------------------------------------------------------- Blocks //---------------------------------------------------------------------------------------------------- Blocks
/// Generate a block accessor function with this signature: /// Generate a block accessor function with this signature:
/// `fn() -> &'static VerifiedBlockInformation` /// `fn() -> &'static VerifiedBlockInformation`
@ -256,7 +284,6 @@ macro_rules! transaction_verification_data_fn {
#[doc = concat!("assert_eq!(tx.tx_blob, ", stringify!($tx_blob), ");")] #[doc = concat!("assert_eq!(tx.tx_blob, ", stringify!($tx_blob), ");")]
#[doc = concat!("assert_eq!(tx.tx_weight, ", $weight, ");")] #[doc = concat!("assert_eq!(tx.tx_weight, ", $weight, ");")]
#[doc = concat!("assert_eq!(tx.tx_hash, hex!(\"", $hash, "\"));")] #[doc = concat!("assert_eq!(tx.tx_hash, hex!(\"", $hash, "\"));")]
// #[doc = "assert_eq!(tx.fee, tx.tx.rct_signatures.base.fee);"]
/// ``` /// ```
pub fn $fn_name() -> &'static VerifiedTransactionInformation { pub fn $fn_name() -> &'static VerifiedTransactionInformation {
static TX: OnceLock<VerifiedTransactionInformation> = OnceLock::new(); static TX: OnceLock<VerifiedTransactionInformation> = OnceLock::new();

View file

@ -32,4 +32,6 @@ pub use constants::{
}; };
mod free; mod free;
pub use free::{block_v16_tx0, block_v1_tx2, block_v9_tx3, tx_v1_sig0, tx_v1_sig2, tx_v2_rct3}; pub use free::{
block_v16_tx0, block_v1_tx2, block_v9_tx3, tx_fee, tx_v1_sig0, tx_v1_sig2, tx_v2_rct3,
};

View file

@ -11,6 +11,8 @@ use monero_simple_request_rpc::SimpleRequestRpc;
use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation}; use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
use crate::data::tx_fee;
//---------------------------------------------------------------------------------------------------- Constants //---------------------------------------------------------------------------------------------------- Constants
/// The default URL used for Monero RPC connections. /// The default URL used for Monero RPC connections.
pub const LOCALHOST_RPC_URL: &str = "http://127.0.0.1:18081"; pub const LOCALHOST_RPC_URL: &str = "http://127.0.0.1:18081";
@ -172,8 +174,7 @@ impl HttpRpcClient {
tx_blob: tx.serialize(), tx_blob: tx.serialize(),
tx_weight: tx.weight(), tx_weight: tx.weight(),
tx_hash, tx_hash,
// TODO: fix this. fee: tx_fee(&tx),
fee: 0,
tx, tx,
} }
}) })

View file

@ -21,7 +21,6 @@ cuprate-fixed-bytes = { path = "../net/fixed-bytes" }
bytes = { workspace = true } bytes = { workspace = true }
curve25519-dalek = { workspace = true } curve25519-dalek = { workspace = true }
monero-serai = { workspace = true } monero-serai = { workspace = true }
serde = { workspace = true, features = ["derive"], optional = true } serde = { workspace = true, features = ["derive"], optional = true }
borsh = { workspace = true, optional = true } borsh = { workspace = true, optional = true }