mirror of
https://github.com/Cuprate/cuprate.git
synced 2025-01-10 04:44:53 +00:00
misc changes
This commit is contained in:
parent
4c310720b9
commit
f48ea910d9
6 changed files with 106 additions and 59 deletions
|
@ -12,11 +12,7 @@ use std::{
|
|||
};
|
||||
|
||||
use futures::FutureExt;
|
||||
use monero_serai::ringct::bulletproofs::Bulletproof;
|
||||
use monero_serai::{
|
||||
ringct::RctType,
|
||||
transaction::{Input, Timelock, Transaction},
|
||||
};
|
||||
use monero_serai::transaction::{Input, Timelock, Transaction};
|
||||
use rayon::prelude::*;
|
||||
use tower::{Service, ServiceExt};
|
||||
use tracing::instrument;
|
||||
|
@ -38,6 +34,7 @@ use crate::{
|
|||
};
|
||||
|
||||
pub mod contextual_data;
|
||||
mod free;
|
||||
|
||||
/// A struct representing the type of validation that needs to be completed for this transaction.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
|
@ -104,52 +101,9 @@ impl TransactionVerificationData {
|
|||
let tx_hash = tx.hash();
|
||||
let tx_blob = tx.serialize();
|
||||
|
||||
// the tx weight is only different from the blobs length for bp(+) txs.
|
||||
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 tx_weight = free::tx_weight(&tx, &tx_blob);
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
let fee = free::tx_fee(&tx)?;
|
||||
|
||||
Ok(TransactionVerificationData {
|
||||
tx_hash,
|
||||
|
|
64
consensus/src/transactions/free.rs
Normal file
64
consensus/src/transactions/free.rs
Normal 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)
|
||||
}
|
|
@ -8,11 +8,11 @@
|
|||
//---------------------------------------------------------------------------------------------------- Import
|
||||
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_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
|
||||
use hex_literal::hex;
|
||||
use monero_serai::transaction::Input;
|
||||
use monero_serai::{block::Block, transaction::Transaction};
|
||||
|
||||
use crate::data::constants::{
|
||||
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 {
|
||||
tx_weight: tx.weight(),
|
||||
// TODO:
|
||||
fee: 0,
|
||||
fee: tx_fee(&tx),
|
||||
tx_hash: tx.hash(),
|
||||
tx_blob,
|
||||
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
|
||||
/// Generate a block accessor function with this signature:
|
||||
/// `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_weight, ", $weight, ");")]
|
||||
#[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 {
|
||||
static TX: OnceLock<VerifiedTransactionInformation> = OnceLock::new();
|
||||
|
|
|
@ -32,4 +32,6 @@ pub use constants::{
|
|||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
|
|
@ -11,6 +11,8 @@ use monero_simple_request_rpc::SimpleRequestRpc;
|
|||
|
||||
use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
|
||||
|
||||
use crate::data::tx_fee;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Constants
|
||||
/// The default URL used for Monero RPC connections.
|
||||
pub const LOCALHOST_RPC_URL: &str = "http://127.0.0.1:18081";
|
||||
|
@ -172,8 +174,7 @@ impl HttpRpcClient {
|
|||
tx_blob: tx.serialize(),
|
||||
tx_weight: tx.weight(),
|
||||
tx_hash,
|
||||
// TODO: fix this.
|
||||
fee: 0,
|
||||
fee: tx_fee(&tx),
|
||||
tx,
|
||||
}
|
||||
})
|
||||
|
|
|
@ -21,7 +21,6 @@ cuprate-fixed-bytes = { path = "../net/fixed-bytes" }
|
|||
bytes = { workspace = true }
|
||||
curve25519-dalek = { workspace = true }
|
||||
monero-serai = { workspace = true }
|
||||
|
||||
serde = { workspace = true, features = ["derive"], optional = true }
|
||||
borsh = { workspace = true, optional = true }
|
||||
|
||||
|
|
Loading…
Reference in a new issue