Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove WASM32 mass calculator + change createTransaction() signature #81

Merged
merged 13 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ ipnet = "2.9.0"
itertools = "0.11.0"
js-sys = "0.3.67"
keccak = "0.1.4"
lazy_static = "1.4.0"
local-ip-address = "0.5.6"
log = "0.4.20"
log4rs = "1.2.0"
Expand Down
8 changes: 6 additions & 2 deletions consensus/client/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const TS_TRANSACTION: &'static str = r#"
*/
export interface ITransactionInput {
previousOutpoint: ITransactionOutpoint;
signatureScript: HexString;
signatureScript?: HexString;
sequence: bigint;
sigOpCount: number;
utxo?: UtxoEntryReference;
Expand Down Expand Up @@ -95,6 +95,10 @@ impl TransactionInput {
self.inner().sig_op_count
}

pub fn signature_script_length(&self) -> usize {
self.inner().signature_script.len()
}

pub fn utxo(&self) -> Option<UtxoEntryReference> {
self.inner().utxo.clone()
}
Expand Down Expand Up @@ -187,7 +191,7 @@ impl TryCastFromJs for TransactionInput {
Self::resolve_cast(&value, || {
if let Some(object) = Object::try_from(value.as_ref()) {
let previous_outpoint: TransactionOutpoint = object.get_value("previousOutpoint")?.as_ref().try_into()?;
let signature_script = object.get_vec_u8("signatureScript")?;
let signature_script = object.get_vec_u8("signatureScript").unwrap_or_default();
let sequence = object.get_u64("sequence")?;
let sig_op_count = object.get_u8("sigOpCount")?;
let utxo = object.try_get_cast::<UtxoEntryReference>("utxo")?.map(Cast::into_owned);
Expand Down
4 changes: 2 additions & 2 deletions consensus/client/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl TransactionOutput {
self.inner.lock().unwrap()
}

pub fn script_length(&self) -> usize {
pub fn script_public_key_length(&self) -> usize {
self.inner().script_public_key.script().len()
}
}
Expand All @@ -79,7 +79,7 @@ impl TransactionOutput {
}

#[wasm_bindgen(getter, js_name = value)]
pub fn get_value(&self) -> u64 {
pub fn value(&self) -> u64 {
self.inner().value
}

Expand Down
2 changes: 1 addition & 1 deletion consensus/client/src/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub fn sign_with_multiple_v3(tx: Transaction, privkeys: &[[u8; 32]]) -> crate::r
let mut additional_signatures_required = false;
{
let input_len = tx.inner().inputs.len();
let (cctx, utxos) = tx.tx_and_utxos();
let (cctx, utxos) = tx.tx_and_utxos()?;
let populated_transaction = PopulatedTransaction::new(&cctx, utxos);
for i in 0..input_len {
let script_pub_key = match tx.inner().inputs[i].script_public_key() {
Expand Down
52 changes: 45 additions & 7 deletions consensus/client/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,18 +359,18 @@ impl Transaction {
})
}

pub fn tx_and_utxos(&self) -> (cctx::Transaction, Vec<UtxoEntry>) {
let mut utxos = vec![];
pub fn tx_and_utxos(&self) -> Result<(cctx::Transaction, Vec<UtxoEntry>)> {
let mut inputs = vec![];
let inner = self.inner();
let inputs: Vec<cctx::TransactionInput> = inner
let utxos: Vec<cctx::UtxoEntry> = inner
.inputs
.clone()
.into_iter()
.map(|input| {
utxos.push((&input.get_utxo().unwrap().entry()).into());
input.as_ref().into()
inputs.push(input.as_ref().into());
Ok(input.get_utxo().ok_or(Error::MissingUtxoEntry)?.entry().as_ref().into())
})
.collect::<Vec<cctx::TransactionInput>>();
.collect::<Result<Vec<_>>>()?;
let outputs: Vec<cctx::TransactionOutput> =
inner.outputs.clone().into_iter().map(|output| output.as_ref().into()).collect::<Vec<cctx::TransactionOutput>>();
let tx = cctx::Transaction::new(
Expand All @@ -383,7 +383,37 @@ impl Transaction {
inner.payload.clone(),
);

(tx, utxos)
Ok((tx, utxos))
}

pub fn utxo_entry_references(&self) -> Result<Vec<UtxoEntryReference>> {
let inner = self.inner();
let utxo_entry_references = inner
.inputs
.clone()
.into_iter()
.map(|input| input.get_utxo().ok_or(Error::MissingUtxoEntry))
.collect::<Result<Vec<UtxoEntryReference>>>()?;
Ok(utxo_entry_references)
}

pub fn outputs(&self) -> Vec<cctx::TransactionOutput> {
let inner = self.inner();
let outputs = inner.outputs.iter().map(|output| output.into()).collect::<Vec<cctx::TransactionOutput>>();
outputs
}

pub fn inputs(&self) -> Vec<cctx::TransactionInput> {
let inner = self.inner();
let inputs = inner.inputs.iter().map(Into::into).collect::<Vec<cctx::TransactionInput>>();
inputs
}

pub fn inputs_outputs(&self) -> (Vec<cctx::TransactionInput>, Vec<cctx::TransactionOutput>) {
let inner = self.inner();
let inputs = inner.inputs.iter().map(Into::into).collect::<Vec<cctx::TransactionInput>>();
let outputs = inner.outputs.iter().map(Into::into).collect::<Vec<cctx::TransactionOutput>>();
(inputs, outputs)
}

pub fn set_signature_script(&self, input_index: usize, signature_script: Vec<u8>) -> Result<()> {
Expand All @@ -393,6 +423,14 @@ impl Transaction {
self.inner().inputs[input_index].set_signature_script(signature_script);
Ok(())
}

pub fn payload(&self) -> Vec<u8> {
self.inner().payload.clone()
}

pub fn payload_len(&self) -> usize {
self.inner().payload.len()
}
}

#[wasm_bindgen]
Expand Down
6 changes: 6 additions & 0 deletions consensus/client/src/utxo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ impl UtxoEntry {
}
}

impl AsRef<UtxoEntry> for UtxoEntry {
fn as_ref(&self) -> &UtxoEntry {
self
}
}

impl From<&UtxoEntry> for cctx::UtxoEntry {
fn from(utxo: &UtxoEntry) -> Self {
cctx::UtxoEntry {
Expand Down
11 changes: 11 additions & 0 deletions consensus/core/src/mass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ use crate::{
};
use kaspa_hashes::HASH_SIZE;

/// Temp enum for the transition phases of KIP9
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Kip9Version {
/// Initial KIP9 mass calculation, w/o the relaxed formula and summing storage mass and compute mass
Alpha,

/// Currently proposed KIP9 mass calculation, with the relaxed formula (for the cases `|O| = 1 OR |O| <= |I| <= 2`),
/// and using a maximum operator over storage and compute mass
Beta,
}

// transaction_estimated_serialized_size is the estimated size of a transaction in some
// serialization. This has to be deterministic, but not necessarily accurate, since
// it's only used as the size component in the transaction and block mass limit
Expand Down
12 changes: 1 addition & 11 deletions consensus/src/processes/mass.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
pub use kaspa_consensus_core::mass::Kip9Version;
use kaspa_consensus_core::{
mass::transaction_estimated_serialized_size,
tx::{Transaction, VerifiableTransaction},
};

/// Temp enum for the transition phases of KIP9
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Kip9Version {
/// Initial KIP9 mass calculation, w/o the relaxed formula and summing storage mass and compute mass
Alpha,

/// Currently proposed KIP9 mass calculation, with the relaxed formula (for the cases `|O| = 1 OR |O| <= |I| <= 2`),
/// and using a maximum operator over storage and compute mass
Beta,
}

// TODO (aspect) - review and potentially merge this with the new MassCalculator currently located in the wallet core
// (i.e. migrate mass calculator from wallet core here or to consensus core)
#[derive(Clone)]
Expand Down
1 change: 0 additions & 1 deletion wallet/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ kaspa-wallet-macros.workspace = true
kaspa-wasm-core.workspace = true
kaspa-wrpc-client.workspace = true
kaspa-wrpc-wasm.workspace = true
lazy_static.workspace = true
md-5.workspace = true
pad.workspace = true
pbkdf2.workspace = true
Expand Down
3 changes: 1 addition & 2 deletions wallet/core/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ pub use crate::rpc::Rpc;
pub use crate::rpc::{DynRpcApi, RpcCtl};
pub use crate::serializer::*;
pub use crate::storage::*;
pub use crate::tx::MassCombinationStrategy;
pub use crate::utxo::balance::Balance;
pub use crate::utxo::scan::{Scan, ScanExtent};
pub use crate::utxo::{Maturity, NetworkParams, OutgoingTransaction, UtxoContext, UtxoEntryReference, UtxoProcessor};
Expand Down Expand Up @@ -49,7 +48,7 @@ pub use std::collections::{HashMap, HashSet};
pub use std::pin::Pin;
pub use std::str::FromStr;
pub use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
pub use std::sync::{Arc, Mutex, MutexGuard, RwLock};
pub use std::sync::{Arc, Mutex, MutexGuard, OnceLock, RwLock};
pub use std::task::{Context, Poll};
pub use wasm_bindgen::prelude::*;
pub use workflow_core::prelude::*;
Expand Down
24 changes: 14 additions & 10 deletions wallet/core/src/tx/generator/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ use crate::tx::{
use crate::utxo::{NetworkParams, UtxoContext, UtxoEntryReference};
use kaspa_consensus_client::UtxoEntry;
use kaspa_consensus_core::constants::UNACCEPTED_DAA_SCORE;
use kaspa_consensus_core::mass::Kip9Version;
use kaspa_consensus_core::subnets::SUBNETWORK_ID_NATIVE;
use kaspa_consensus_core::tx::{Transaction, TransactionInput, TransactionOutpoint, TransactionOutput};
use kaspa_txscript::pay_to_address_script;
Expand Down Expand Up @@ -215,7 +216,7 @@ struct Data {

impl Data {
fn new(calc: &MassCalculator) -> Self {
let aggregate_mass = calc.blank_transaction_mass();
let aggregate_mass = calc.blank_transaction_compute_mass();

Data {
inputs: vec![],
Expand Down Expand Up @@ -266,7 +267,7 @@ struct Inner {
// Current network id
network_id: NetworkId,
// Current network params
network_params: NetworkParams,
network_params: &'static NetworkParams,

// Source Utxo Context (Used for source UtxoEntry aggregation)
source_utxo_context: Option<UtxoContext>,
Expand Down Expand Up @@ -357,7 +358,7 @@ impl Generator {

let network_type = NetworkType::from(network_id);
let network_params = NetworkParams::from(network_id);
let mass_calculator = MassCalculator::new(&network_id.into(), &network_params);
let mass_calculator = MassCalculator::new(&network_id.into(), network_params);

let (final_transaction_outputs, final_transaction_amount) = match final_transaction_destination {
PaymentDestination::Change => {
Expand Down Expand Up @@ -402,11 +403,11 @@ impl Generator {
}

let standard_change_output_mass =
mass_calculator.calc_mass_for_output(&TransactionOutput::new(0, pay_to_address_script(&change_address)));
let signature_mass_per_input = mass_calculator.calc_signature_mass(minimum_signatures);
let final_transaction_outputs_compute_mass = mass_calculator.calc_mass_for_outputs(&final_transaction_outputs);
mass_calculator.calc_compute_mass_for_output(&TransactionOutput::new(0, pay_to_address_script(&change_address)));
let signature_mass_per_input = mass_calculator.calc_compute_mass_for_signature(minimum_signatures);
let final_transaction_outputs_compute_mass = mass_calculator.calc_compute_mass_for_outputs(&final_transaction_outputs);
let final_transaction_payload = final_transaction_payload.unwrap_or_default();
let final_transaction_payload_mass = mass_calculator.calc_mass_for_payload(final_transaction_payload.len());
let final_transaction_payload_mass = mass_calculator.calc_compute_mass_for_payload(final_transaction_payload.len());
let final_transaction_outputs_harmonic =
mass_calculator.calc_storage_mass_output_harmonic(&final_transaction_outputs).ok_or(Error::MassCalculationError)?;

Expand Down Expand Up @@ -477,7 +478,7 @@ impl Generator {

/// Returns current [`NetworkParams`]
pub fn network_params(&self) -> &NetworkParams {
&self.inner.network_params
self.inner.network_params
}

/// The underlying [`UtxoContext`] (if available).
Expand Down Expand Up @@ -662,7 +663,7 @@ impl Generator {

let input = TransactionInput::new(utxo.outpoint.clone().into(), vec![], 0, self.inner.sig_op_count);
let input_amount = utxo.amount();
let input_compute_mass = calc.calc_mass_for_input(&input) + self.inner.signature_mass_per_input;
let input_compute_mass = calc.calc_compute_mass_for_input(&input) + self.inner.signature_mass_per_input;

// NOTE: relay transactions have no storage mass
// mass threshold reached, yield transaction
Expand Down Expand Up @@ -865,8 +866,11 @@ impl Generator {
calc.calc_storage_mass_output_harmonic_single(change_value) + self.inner.final_transaction_outputs_harmonic;
let storage_mass_with_change = self.calc_storage_mass(data, output_harmonic_with_change);

// TODO - review and potentially simplify:
// this profiles the storage mass with change and without change
// and decides which one to use based on the fees
if storage_mass_with_change == 0
|| (self.inner.network_params.mass_combination_strategy() == MassCombinationStrategy::Max
|| (self.inner.network_params.kip9_version() == Kip9Version::Beta // max(compute vs storage)
&& storage_mass_with_change < compute_mass_with_change)
{
0
Expand Down
8 changes: 4 additions & 4 deletions wallet/core/src/tx/generator/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,10 @@ fn validate(pt: &PendingTransaction) {

let calc = MassCalculator::new(&pt.network_type().into(), network_params);
let additional_mass = if pt.is_final() { 0 } else { network_params.additional_compound_transaction_mass() };
let compute_mass = calc.calc_mass_for_signed_transaction(&tx, 1);
let compute_mass = calc.calc_compute_mass_for_signed_transaction(&tx, 1);

let utxo_entries = pt.utxo_entries().values().cloned().collect::<Vec<_>>();
let storage_mass = calc.calc_storage_mass_for_transaction(false, &utxo_entries, &tx.outputs).unwrap_or_default();
let storage_mass = calc.calc_storage_mass_for_transaction_parts(&utxo_entries, &tx.outputs).unwrap_or_default();

let calculated_mass = calc.combine_mass(compute_mass, storage_mass) + additional_mass;

Expand Down Expand Up @@ -201,10 +201,10 @@ where
let calc = MassCalculator::new(&pt.network_type().into(), network_params);
let additional_mass = if pt.is_final() { 0 } else { network_params.additional_compound_transaction_mass() };

let compute_mass = calc.calc_mass_for_signed_transaction(&tx, 1);
let compute_mass = calc.calc_compute_mass_for_signed_transaction(&tx, 1);

let utxo_entries = pt.utxo_entries().values().cloned().collect::<Vec<_>>();
let storage_mass = calc.calc_storage_mass_for_transaction(false, &utxo_entries, &tx.outputs).unwrap_or_default();
let storage_mass = calc.calc_storage_mass_for_transaction_parts(&utxo_entries, &tx.outputs).unwrap_or_default();
if DISPLAY_LOGS && storage_mass != 0 {
println!(
"calculated storage mass: {} calculated_compute_mass: {} total: {}",
Expand Down
Loading