Skip to content

Commit

Permalink
Merge branch 'kaspanet:master' into gamma
Browse files Browse the repository at this point in the history
  • Loading branch information
surinder83singh authored Dec 9, 2024
2 parents d57e954 + 8fe4663 commit b9ebb93
Show file tree
Hide file tree
Showing 17 changed files with 164 additions and 232 deletions.
116 changes: 58 additions & 58 deletions Cargo.lock

Large diffs are not rendered by default.

112 changes: 56 additions & 56 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ members = [

[workspace.package]
rust-version = "1.82.0"
version = "0.15.3"
version = "0.15.4"
authors = ["Kaspa developers"]
license = "ISC"
repository = "https://github.com/kaspanet/rusty-kaspa"
Expand All @@ -80,61 +80,61 @@ include = [
]

[workspace.dependencies]
# kaspa-testing-integration = { version = "0.15.3", path = "testing/integration" }
kaspa-addresses = { version = "0.15.3", path = "crypto/addresses" }
kaspa-addressmanager = { version = "0.15.3", path = "components/addressmanager" }
kaspa-bip32 = { version = "0.15.3", path = "wallet/bip32" }
kaspa-cli = { version = "0.15.3", path = "cli" }
kaspa-connectionmanager = { version = "0.15.3", path = "components/connectionmanager" }
kaspa-consensus = { version = "0.15.3", path = "consensus" }
kaspa-consensus-core = { version = "0.15.3", path = "consensus/core" }
kaspa-consensus-client = { version = "0.15.3", path = "consensus/client" }
kaspa-consensus-notify = { version = "0.15.3", path = "consensus/notify" }
kaspa-consensus-wasm = { version = "0.15.3", path = "consensus/wasm" }
kaspa-consensusmanager = { version = "0.15.3", path = "components/consensusmanager" }
kaspa-core = { version = "0.15.3", path = "core" }
kaspa-daemon = { version = "0.15.3", path = "daemon" }
kaspa-database = { version = "0.15.3", path = "database" }
kaspa-grpc-client = { version = "0.15.3", path = "rpc/grpc/client" }
kaspa-grpc-core = { version = "0.15.3", path = "rpc/grpc/core" }
kaspa-grpc-server = { version = "0.15.3", path = "rpc/grpc/server" }
kaspa-hashes = { version = "0.15.3", path = "crypto/hashes" }
kaspa-index-core = { version = "0.15.3", path = "indexes/core" }
kaspa-index-processor = { version = "0.15.3", path = "indexes/processor" }
kaspa-math = { version = "0.15.3", path = "math" }
kaspa-merkle = { version = "0.15.3", path = "crypto/merkle" }
kaspa-metrics-core = { version = "0.15.3", path = "metrics/core" }
kaspa-mining = { version = "0.15.3", path = "mining" }
kaspa-mining-errors = { version = "0.15.3", path = "mining/errors" }
kaspa-muhash = { version = "0.15.3", path = "crypto/muhash" }
kaspa-notify = { version = "0.15.3", path = "notify" }
kaspa-p2p-flows = { version = "0.15.3", path = "protocol/flows" }
kaspa-p2p-lib = { version = "0.15.3", path = "protocol/p2p" }
kaspa-perf-monitor = { version = "0.15.3", path = "metrics/perf_monitor" }
kaspa-pow = { version = "0.15.3", path = "consensus/pow" }
kaspa-rpc-core = { version = "0.15.3", path = "rpc/core" }
kaspa-rpc-macros = { version = "0.15.3", path = "rpc/macros" }
kaspa-rpc-service = { version = "0.15.3", path = "rpc/service" }
kaspa-txscript = { version = "0.15.3", path = "crypto/txscript" }
kaspa-txscript-errors = { version = "0.15.3", path = "crypto/txscript/errors" }
kaspa-utils = { version = "0.15.3", path = "utils" }
kaspa-utils-tower = { version = "0.15.3", path = "utils/tower" }
kaspa-utxoindex = { version = "0.15.3", path = "indexes/utxoindex" }
kaspa-wallet = { version = "0.15.3", path = "wallet/native" }
kaspa-wallet-cli-wasm = { version = "0.15.3", path = "wallet/wasm" }
kaspa-wallet-keys = { version = "0.15.3", path = "wallet/keys" }
kaspa-wallet-pskt = { version = "0.15.3", path = "wallet/pskt" }
kaspa-wallet-core = { version = "0.15.3", path = "wallet/core" }
kaspa-wallet-macros = { version = "0.15.3", path = "wallet/macros" }
kaspa-wasm = { version = "0.15.3", path = "wasm" }
kaspa-wasm-core = { version = "0.15.3", path = "wasm/core" }
kaspa-wrpc-client = { version = "0.15.3", path = "rpc/wrpc/client" }
kaspa-wrpc-proxy = { version = "0.15.3", path = "rpc/wrpc/proxy" }
kaspa-wrpc-server = { version = "0.15.3", path = "rpc/wrpc/server" }
kaspa-wrpc-wasm = { version = "0.15.3", path = "rpc/wrpc/wasm" }
kaspa-wrpc-example-subscriber = { version = "0.15.3", path = "rpc/wrpc/examples/subscriber" }
kaspad = { version = "0.15.3", path = "kaspad" }
kaspa-alloc = { version = "0.15.3", path = "utils/alloc" }
# kaspa-testing-integration = { version = "0.15.4", path = "testing/integration" }
kaspa-addresses = { version = "0.15.4", path = "crypto/addresses" }
kaspa-addressmanager = { version = "0.15.4", path = "components/addressmanager" }
kaspa-bip32 = { version = "0.15.4", path = "wallet/bip32" }
kaspa-cli = { version = "0.15.4", path = "cli" }
kaspa-connectionmanager = { version = "0.15.4", path = "components/connectionmanager" }
kaspa-consensus = { version = "0.15.4", path = "consensus" }
kaspa-consensus-core = { version = "0.15.4", path = "consensus/core" }
kaspa-consensus-client = { version = "0.15.4", path = "consensus/client" }
kaspa-consensus-notify = { version = "0.15.4", path = "consensus/notify" }
kaspa-consensus-wasm = { version = "0.15.4", path = "consensus/wasm" }
kaspa-consensusmanager = { version = "0.15.4", path = "components/consensusmanager" }
kaspa-core = { version = "0.15.4", path = "core" }
kaspa-daemon = { version = "0.15.4", path = "daemon" }
kaspa-database = { version = "0.15.4", path = "database" }
kaspa-grpc-client = { version = "0.15.4", path = "rpc/grpc/client" }
kaspa-grpc-core = { version = "0.15.4", path = "rpc/grpc/core" }
kaspa-grpc-server = { version = "0.15.4", path = "rpc/grpc/server" }
kaspa-hashes = { version = "0.15.4", path = "crypto/hashes" }
kaspa-index-core = { version = "0.15.4", path = "indexes/core" }
kaspa-index-processor = { version = "0.15.4", path = "indexes/processor" }
kaspa-math = { version = "0.15.4", path = "math" }
kaspa-merkle = { version = "0.15.4", path = "crypto/merkle" }
kaspa-metrics-core = { version = "0.15.4", path = "metrics/core" }
kaspa-mining = { version = "0.15.4", path = "mining" }
kaspa-mining-errors = { version = "0.15.4", path = "mining/errors" }
kaspa-muhash = { version = "0.15.4", path = "crypto/muhash" }
kaspa-notify = { version = "0.15.4", path = "notify" }
kaspa-p2p-flows = { version = "0.15.4", path = "protocol/flows" }
kaspa-p2p-lib = { version = "0.15.4", path = "protocol/p2p" }
kaspa-perf-monitor = { version = "0.15.4", path = "metrics/perf_monitor" }
kaspa-pow = { version = "0.15.4", path = "consensus/pow" }
kaspa-rpc-core = { version = "0.15.4", path = "rpc/core" }
kaspa-rpc-macros = { version = "0.15.4", path = "rpc/macros" }
kaspa-rpc-service = { version = "0.15.4", path = "rpc/service" }
kaspa-txscript = { version = "0.15.4", path = "crypto/txscript" }
kaspa-txscript-errors = { version = "0.15.4", path = "crypto/txscript/errors" }
kaspa-utils = { version = "0.15.4", path = "utils" }
kaspa-utils-tower = { version = "0.15.4", path = "utils/tower" }
kaspa-utxoindex = { version = "0.15.4", path = "indexes/utxoindex" }
kaspa-wallet = { version = "0.15.4", path = "wallet/native" }
kaspa-wallet-cli-wasm = { version = "0.15.4", path = "wallet/wasm" }
kaspa-wallet-keys = { version = "0.15.4", path = "wallet/keys" }
kaspa-wallet-pskt = { version = "0.15.4", path = "wallet/pskt" }
kaspa-wallet-core = { version = "0.15.4", path = "wallet/core" }
kaspa-wallet-macros = { version = "0.15.4", path = "wallet/macros" }
kaspa-wasm = { version = "0.15.4", path = "wasm" }
kaspa-wasm-core = { version = "0.15.4", path = "wasm/core" }
kaspa-wrpc-client = { version = "0.15.4", path = "rpc/wrpc/client" }
kaspa-wrpc-proxy = { version = "0.15.4", path = "rpc/wrpc/proxy" }
kaspa-wrpc-server = { version = "0.15.4", path = "rpc/wrpc/server" }
kaspa-wrpc-wasm = { version = "0.15.4", path = "rpc/wrpc/wasm" }
kaspa-wrpc-example-subscriber = { version = "0.15.4", path = "rpc/wrpc/examples/subscriber" }
kaspad = { version = "0.15.4", path = "kaspad" }
kaspa-alloc = { version = "0.15.4", path = "utils/alloc" }

# external
aes = "0.8.3"
Expand Down
2 changes: 1 addition & 1 deletion consensus/core/src/config/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ pub mod perf {

/// The default slack interval used by the reachability
/// algorithm to encounter for blocks out of the selected chain.
pub const DEFAULT_REINDEX_SLACK: u64 = 1 << 12;
pub const DEFAULT_REINDEX_SLACK: u64 = 1 << 14;

const BASELINE_HEADER_DATA_CACHE_SIZE: usize = 10_000;
const BASELINE_BLOCK_DATA_CACHE_SIZE: usize = 200;
Expand Down
6 changes: 3 additions & 3 deletions consensus/core/src/config/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,12 +533,12 @@ pub const TESTNET11_PARAMS: Params = Params {

storage_mass_parameter: STORAGE_MASS_PARAMETER,
storage_mass_activation: ForkActivation::always(),
kip10_activation: ForkActivation::never(),
// Roughly at Dec 3, 2024 1800 UTC
kip10_activation: ForkActivation::new(287238000),
payload_activation: ForkActivation::new(287238000),

skip_proof_of_work: false,
max_block_level: 250,

payload_activation: ForkActivation::never(),
};

pub const SIMNET_PARAMS: Params = Params {
Expand Down
69 changes: 16 additions & 53 deletions consensus/core/src/mass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,6 @@ 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 Expand Up @@ -121,32 +110,18 @@ impl MassCalculator {
/// 2. At least one input (unless coinbase)
///
/// Otherwise this function should never fail.
pub fn calc_tx_storage_mass(&self, tx: &impl VerifiableTransaction, version: Kip9Version) -> Option<u64> {
pub fn calc_tx_storage_mass(&self, tx: &impl VerifiableTransaction) -> Option<u64> {
calc_storage_mass(
tx.is_coinbase(),
tx.populated_inputs().map(|(_, entry)| entry.amount),
tx.outputs().iter().map(|out| out.value),
version,
self.storage_mass_parameter,
)
}

/// Calculates the overall mass of this transaction, combining both compute and storage masses.
/// The combination strategy depends on the version passed.
pub fn calc_tx_overall_mass(
&self,
tx: &impl VerifiableTransaction,
cached_compute_mass: Option<u64>,
version: Kip9Version,
) -> Option<u64> {
match version {
Kip9Version::Alpha => self
.calc_tx_storage_mass(tx, version)
.and_then(|mass| mass.checked_add(cached_compute_mass.unwrap_or_else(|| self.calc_tx_compute_mass(tx.tx())))),
Kip9Version::Beta => self
.calc_tx_storage_mass(tx, version)
.map(|mass| mass.max(cached_compute_mass.unwrap_or_else(|| self.calc_tx_compute_mass(tx.tx())))),
}
pub fn calc_tx_overall_mass(&self, tx: &impl VerifiableTransaction, cached_compute_mass: Option<u64>) -> Option<u64> {
self.calc_tx_storage_mass(tx).map(|mass| mass.max(cached_compute_mass.unwrap_or_else(|| self.calc_tx_compute_mass(tx.tx()))))
}
}

Expand All @@ -160,7 +135,6 @@ pub fn calc_storage_mass(
is_coinbase: bool,
input_values: impl ExactSizeIterator<Item = u64>,
output_values: impl ExactSizeIterator<Item = u64>,
version: Kip9Version,
storage_mass_parameter: u64,
) -> Option<u64> {
if is_coinbase {
Expand Down Expand Up @@ -199,7 +173,7 @@ pub fn calc_storage_mass(
Note: in the case |I| = 1 both formulas are equal, yet the following code (harmonic_ins) is a bit more efficient.
Hence, we transform the condition to |O| = 1 OR |I| = 1 OR |O| = |I| = 2 which is equivalent (and faster).
*/
if version == Kip9Version::Beta && (outs_len == 1 || ins_len == 1 || (outs_len == 2 && ins_len == 2)) {
if outs_len == 1 || ins_len == 1 || (outs_len == 2 && ins_len == 2) {
let harmonic_ins =
input_values.map(|value| storage_mass_parameter / value).fold(0u64, |total, current| total.saturating_add(current)); // C·|I|/H(I)
return Some(harmonic_outs.saturating_sub(harmonic_ins)); // max( 0 , C·( |O|/H(O) - |I|/H(I) ) );
Expand Down Expand Up @@ -230,70 +204,59 @@ mod tests {
fn test_mass_storage() {
// Tx with less outs than ins
let mut tx = generate_tx_from_amounts(&[100, 200, 300], &[300, 300]);
let test_version = Kip9Version::Alpha;

//
// Assert the formula: max( 0 , C·( |O|/H(O) - |I|/A(I) ) )
//

let storage_mass =
MassCalculator::new(0, 0, 0, 10u64.pow(12)).calc_tx_storage_mass(&tx.as_verifiable(), test_version).unwrap();
let storage_mass = MassCalculator::new(0, 0, 0, 10u64.pow(12)).calc_tx_storage_mass(&tx.as_verifiable()).unwrap();
assert_eq!(storage_mass, 0); // Compounds from 3 to 2, with symmetric outputs and no fee, should be zero

// Create asymmetry
tx.tx.outputs[0].value = 50;
tx.tx.outputs[1].value = 550;
let storage_mass_parameter = 10u64.pow(12);
let storage_mass =
MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable(), test_version).unwrap();
let storage_mass = MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable()).unwrap();
assert_eq!(storage_mass, storage_mass_parameter / 50 + storage_mass_parameter / 550 - 3 * (storage_mass_parameter / 200));

// Create a tx with more outs than ins
let base_value = 10_000 * SOMPI_PER_KASPA;
let mut tx = generate_tx_from_amounts(&[base_value, base_value, base_value * 2], &[base_value; 4]);
let storage_mass_parameter = STORAGE_MASS_PARAMETER;
let storage_mass =
MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable(), test_version).unwrap();
let storage_mass = MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable()).unwrap();
assert_eq!(storage_mass, 4); // Inputs are above C so they don't contribute negative mass, 4 outputs exactly equal C each charge 1

let mut tx2 = tx.clone();
tx2.tx.outputs[0].value = 10 * SOMPI_PER_KASPA;
let storage_mass =
MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx2.as_verifiable(), test_version).unwrap();
let storage_mass = MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx2.as_verifiable()).unwrap();
assert_eq!(storage_mass, 1003);

// Increase values over the lim
for out in tx.tx.outputs.iter_mut() {
out.value += 1
}
tx.entries[0].as_mut().unwrap().amount += tx.tx.outputs.len() as u64;
let storage_mass =
MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable(), test_version).unwrap();
let storage_mass = MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable()).unwrap();
assert_eq!(storage_mass, 0);
}

#[test]
fn test_mass_storage_beta() {
// 2:2 transaction
// Now create 2:2 transaction
// Assert the formula: max( 0 , C·( |O|/H(O) - |I|/H(I) ) )
let mut tx = generate_tx_from_amounts(&[100, 200], &[50, 250]);
let storage_mass_parameter = 10u64.pow(12);
let test_version = Kip9Version::Beta;
// Assert the formula: max( 0 , C·( |O|/H(O) - |I|/O(I) ) )

let storage_mass =
MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable(), test_version).unwrap();
let storage_mass = MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable()).unwrap();
assert_eq!(storage_mass, 9000000000);

// Set outputs to be equal to inputs
tx.tx.outputs[0].value = 100;
tx.tx.outputs[1].value = 200;
let storage_mass =
MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable(), test_version).unwrap();
let storage_mass = MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable()).unwrap();
assert_eq!(storage_mass, 0);

// Remove an output and make sure the other is small enough to make storage mass greater than zero
tx.tx.outputs.pop();
tx.tx.outputs[0].value = 50;
let storage_mass =
MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable(), test_version).unwrap();
let storage_mass = MassCalculator::new(0, 0, 0, storage_mass_parameter).calc_tx_storage_mass(&tx.as_verifiable()).unwrap();
assert_eq!(storage_mass, 5000000000);
}

Expand Down
8 changes: 4 additions & 4 deletions consensus/src/consensus/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ impl ConsensusStorage {
// Budgets in bytes. All byte budgets overall sum up to ~1GB of memory (which obviously takes more low level alloc space)
let daa_excluded_budget = scaled(30_000_000);
let statuses_budget = scaled(30_000_000);
let reachability_data_budget = scaled(20_000_000);
let reachability_sets_budget = scaled(20_000_000); // x 2 for tree children and future covering set
let reachability_data_budget = scaled(100_000_000);
let reachability_sets_budget = scaled(100_000_000); // x 2 for tree children and future covering set
let ghostdag_compact_budget = scaled(15_000_000);
let headers_compact_budget = scaled(5_000_000);
let parents_budget = scaled(40_000_000); // x 3 for reachability and levels
let children_budget = scaled(5_000_000); // x 3 for reachability and levels
let parents_budget = scaled(80_000_000); // x 3 for reachability and levels
let children_budget = scaled(20_000_000); // x 3 for reachability and levels
let ghostdag_budget = scaled(80_000_000); // x 2 for levels
let headers_budget = scaled(80_000_000);
let transactions_budget = scaled(40_000_000);
Expand Down
8 changes: 4 additions & 4 deletions consensus/src/model/services/reachability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ pub trait ReachabilityService {
/// Note that we use the graph theory convention here which defines that a block is also an ancestor of itself.
fn is_chain_ancestor_of(&self, this: Hash, queried: Hash) -> bool;

/// Result version of [`is_dag_ancestor_of`] (avoids unwrapping internally)
/// Result version of [`Self::is_dag_ancestor_of`] (avoids unwrapping internally)
fn is_dag_ancestor_of_result(&self, this: Hash, queried: Hash) -> Result<bool>;

/// Returns true if `this` is a DAG ancestor of `queried` (i.e., `queried ∈ future(this) ∪ {this}`).
/// Note: this method will return true if `this == queried`.
/// The complexity of this method is `O(log(|future_covering_set(this)|))`
fn is_dag_ancestor_of(&self, this: Hash, queried: Hash) -> bool;

/// Checks if `this` is DAG ancestor of any of the blocks in `queried`. See [`is_dag_ancestor_of`] as well.
/// Checks if `this` is DAG ancestor of any of the blocks in `queried`. See [`Self::is_dag_ancestor_of`] as well.
fn is_dag_ancestor_of_any(&self, this: Hash, queried: &mut impl Iterator<Item = Hash>) -> bool;

/// Checks if any of the blocks in `list` is DAG ancestor of `queried`. See [`is_dag_ancestor_of`] as well.
/// Checks if any of the blocks in `list` is DAG ancestor of `queried`. See [`Self::is_dag_ancestor_of`] as well.
fn is_any_dag_ancestor(&self, list: &mut impl Iterator<Item = Hash>, queried: Hash) -> bool;

/// Result version of [`is_any_dag_ancestor`] (avoids unwrapping internally)
/// Result version of [`Self::is_any_dag_ancestor`] (avoids unwrapping internally)
fn is_any_dag_ancestor_result(&self, list: &mut impl Iterator<Item = Hash>, queried: Hash) -> Result<bool>;

/// Finds the tree child of `ancestor` which is also a chain ancestor of `descendant`.
Expand Down
Loading

0 comments on commit b9ebb93

Please sign in to comment.