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 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,
|
||||||
|
|
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
|
//---------------------------------------------------------------------------------------------------- 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();
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue