Skip to content

Commit

Permalink
Merge branch 'master' into py-mg
Browse files Browse the repository at this point in the history
  • Loading branch information
smartgoo committed Nov 29, 2024
2 parents 955f7dc + 233552b commit cdbdc43
Show file tree
Hide file tree
Showing 80 changed files with 965 additions and 379 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ members = [
]

[workspace.package]
rust-version = "1.81.0"
rust-version = "1.82.0"
version = "0.15.3"
authors = ["Kaspa developers"]
license = "ISC"
Expand Down
10 changes: 1 addition & 9 deletions cli/src/modules/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,7 @@ impl History {
}
};
let length = ids.size_hint().0;
let skip = if let Some(last) = last {
if last > length {
0
} else {
length - last
}
} else {
0
};
let skip = if let Some(last) = last { length.saturating_sub(last) } else { 0 };
let mut index = 0;
let page = 25;

Expand Down
58 changes: 47 additions & 11 deletions consensus/benches/check_scripts.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion, SamplingMode};
use kaspa_addresses::{Address, Prefix, Version};
use kaspa_consensus::processes::transaction_validator::transaction_validator_populated::{
use kaspa_consensus::processes::transaction_validator::tx_validation_in_utxo_context::{
check_scripts_par_iter, check_scripts_par_iter_pool, check_scripts_sequential,
};
use kaspa_consensus_core::hashing::sighash::{calc_schnorr_signature_hash, SigHashReusedValuesUnsync};
Expand All @@ -13,8 +13,10 @@ use kaspa_utils::iter::parallelism_in_power_steps;
use rand::{thread_rng, Rng};
use secp256k1::Keypair;

// You may need to add more detailed mocks depending on your actual code.
fn mock_tx(inputs_count: usize, non_uniq_signatures: usize) -> (Transaction, Vec<UtxoEntry>) {
fn mock_tx_with_payload(inputs_count: usize, non_uniq_signatures: usize, payload_size: usize) -> (Transaction, Vec<UtxoEntry>) {
let mut payload = vec![0u8; payload_size];
thread_rng().fill(&mut payload[..]);

let reused_values = SigHashReusedValuesUnsync::new();
let dummy_prev_out = TransactionOutpoint::new(kaspa_hashes::Hash::from_u64_word(1), 1);
let mut tx = Transaction::new(
Expand All @@ -24,10 +26,11 @@ fn mock_tx(inputs_count: usize, non_uniq_signatures: usize) -> (Transaction, Vec
0,
SubnetworkId::from_bytes([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
0,
vec![],
payload,
);
let mut utxos = vec![];
let mut kps = vec![];

for _ in 0..inputs_count - non_uniq_signatures {
let kp = Keypair::new(secp256k1::SECP256K1, &mut thread_rng());
tx.inputs.push(TransactionInput { previous_outpoint: dummy_prev_out, signature_script: vec![], sequence: 0, sig_op_count: 1 });
Expand All @@ -40,6 +43,7 @@ fn mock_tx(inputs_count: usize, non_uniq_signatures: usize) -> (Transaction, Vec
});
kps.push(kp);
}

for _ in 0..non_uniq_signatures {
let kp = kps.last().unwrap();
tx.inputs.push(TransactionInput { previous_outpoint: dummy_prev_out, signature_script: vec![], sequence: 0, sig_op_count: 1 });
Expand All @@ -51,31 +55,32 @@ fn mock_tx(inputs_count: usize, non_uniq_signatures: usize) -> (Transaction, Vec
is_coinbase: false,
});
}

for (i, kp) in kps.iter().enumerate().take(inputs_count - non_uniq_signatures) {
let mut_tx = MutableTransaction::with_entries(&tx, utxos.clone());
let sig_hash = calc_schnorr_signature_hash(&mut_tx.as_verifiable(), i, SIG_HASH_ALL, &reused_values);
let msg = secp256k1::Message::from_digest_slice(sig_hash.as_bytes().as_slice()).unwrap();
let sig: [u8; 64] = *kp.sign_schnorr(msg).as_ref();
// This represents OP_DATA_65 <SIGNATURE+SIGHASH_TYPE> (since signature length is 64 bytes and SIGHASH_TYPE is one byte)
tx.inputs[i].signature_script = std::iter::once(65u8).chain(sig).chain([SIG_HASH_ALL.to_u8()]).collect();
}

let length = tx.inputs.len();
for i in (inputs_count - non_uniq_signatures)..length {
let kp = kps.last().unwrap();
let mut_tx = MutableTransaction::with_entries(&tx, utxos.clone());
let sig_hash = calc_schnorr_signature_hash(&mut_tx.as_verifiable(), i, SIG_HASH_ALL, &reused_values);
let msg = secp256k1::Message::from_digest_slice(sig_hash.as_bytes().as_slice()).unwrap();
let sig: [u8; 64] = *kp.sign_schnorr(msg).as_ref();
// This represents OP_DATA_65 <SIGNATURE+SIGHASH_TYPE> (since signature length is 64 bytes and SIGHASH_TYPE is one byte)
tx.inputs[i].signature_script = std::iter::once(65u8).chain(sig).chain([SIG_HASH_ALL.to_u8()]).collect();
}

(tx, utxos)
}

fn benchmark_check_scripts(c: &mut Criterion) {
for inputs_count in [100, 50, 25, 10, 5, 2] {
for non_uniq_signatures in [0, inputs_count / 2] {
let (tx, utxos) = mock_tx(inputs_count, non_uniq_signatures);
let (tx, utxos) = mock_tx_with_payload(inputs_count, non_uniq_signatures, 0);
let mut group = c.benchmark_group(format!("inputs: {inputs_count}, non uniq: {non_uniq_signatures}"));
group.sampling_mode(SamplingMode::Flat);

Expand All @@ -97,12 +102,10 @@ fn benchmark_check_scripts(c: &mut Criterion) {
})
});

// Iterate powers of two up to available parallelism
for i in parallelism_in_power_steps() {
if inputs_count >= i {
group.bench_function(format!("rayon, custom thread pool, thread count {i}"), |b| {
let tx = MutableTransaction::with_entries(tx.clone(), utxos.clone());
// Create a custom thread pool with the specified number of threads
let pool = rayon::ThreadPoolBuilder::new().num_threads(i).build().unwrap();
let cache = Cache::new(inputs_count as u64);
b.iter(|| {
Expand All @@ -117,11 +120,44 @@ fn benchmark_check_scripts(c: &mut Criterion) {
}
}

/// Benchmarks script checking performance with different payload sizes and input counts.
///
/// This benchmark evaluates the performance impact of transaction payload size
/// on script validation, testing multiple scenarios:
///
/// * Payload sizes: 0KB, 16KB, 32KB, 64KB, 128KB
/// * Input counts: 1, 2, 10, 50 transactions
///
/// The benchmark helps understand:
/// 1. How payload size affects validation performance
/// 2. The relationship between input count and payload processing overhead
fn benchmark_check_scripts_with_payload(c: &mut Criterion) {
let payload_sizes = [0, 16_384, 32_768, 65_536, 131_072]; // 0, 16KB, 32KB, 64KB, 128KB
let input_counts = [1, 2, 10, 50];
let non_uniq_signatures = 0;

for inputs_count in input_counts {
for &payload_size in &payload_sizes {
let (tx, utxos) = mock_tx_with_payload(inputs_count, non_uniq_signatures, payload_size);
let mut group = c.benchmark_group(format!("script_check/inputs_{}/payload_{}_kb", inputs_count, payload_size / 1024));
group.sampling_mode(SamplingMode::Flat);

group.bench_function("parallel_validation", |b| {
let tx = MutableTransaction::with_entries(tx.clone(), utxos.clone());
let cache = Cache::new(inputs_count as u64);
b.iter(|| {
cache.clear();
check_scripts_par_iter(black_box(&cache), black_box(&tx.as_verifiable()), false).unwrap();
})
});
}
}
}

criterion_group! {
name = benches;
// This can be any expression that returns a `Criterion` object.
config = Criterion::default().with_output_color(true).measurement_time(std::time::Duration::new(20, 0));
targets = benchmark_check_scripts
targets = benchmark_check_scripts, benchmark_check_scripts_with_payload
}

criterion_main!(benches);
2 changes: 1 addition & 1 deletion consensus/client/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ impl Header {

impl TryCastFromJs for Header {
type Error = Error;
fn try_cast_from<'a, R>(value: &'a R) -> Result<Cast<Self>, Self::Error>
fn try_cast_from<'a, R>(value: &'a R) -> Result<Cast<'a, Self>, Self::Error>
where
R: AsRef<JsValue> + 'a,
{
Expand Down
2 changes: 1 addition & 1 deletion consensus/client/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ impl AsRef<TransactionInput> for TransactionInput {

impl TryCastFromJs for TransactionInput {
type Error = Error;
fn try_cast_from<'a, R>(value: &'a R) -> std::result::Result<Cast<Self>, Self::Error>
fn try_cast_from<'a, R>(value: &'a R) -> std::result::Result<Cast<'a, Self>, Self::Error>
where
R: AsRef<JsValue> + 'a,
{
Expand Down
2 changes: 1 addition & 1 deletion consensus/client/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl From<&TransactionOutput> for cctx::TransactionOutput {

impl TryCastFromJs for TransactionOutput {
type Error = Error;
fn try_cast_from<'a, R>(value: &'a R) -> std::result::Result<Cast<Self>, Self::Error>
fn try_cast_from<'a, R>(value: &'a R) -> std::result::Result<Cast<'a, Self>, Self::Error>
where
R: AsRef<JsValue> + 'a,
{
Expand Down
2 changes: 1 addition & 1 deletion consensus/client/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ impl Transaction {

impl TryCastFromJs for Transaction {
type Error = Error;
fn try_cast_from<'a, R>(value: &'a R) -> std::result::Result<Cast<Self>, Self::Error>
fn try_cast_from<'a, R>(value: &'a R) -> std::result::Result<Cast<'a, Self>, Self::Error>
where
R: AsRef<JsValue> + 'a,
{
Expand Down
4 changes: 2 additions & 2 deletions consensus/client/src/utxo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ impl TryIntoUtxoEntryReferences for JsValue {

impl TryCastFromJs for UtxoEntry {
type Error = Error;
fn try_cast_from<'a, R>(value: &'a R) -> Result<Cast<Self>, Self::Error>
fn try_cast_from<'a, R>(value: &'a R) -> Result<Cast<'a, Self>, Self::Error>
where
R: AsRef<JsValue> + 'a,
{
Expand Down Expand Up @@ -522,7 +522,7 @@ impl TryFrom<JsValue> for UtxoEntries {

impl TryCastFromJs for UtxoEntryReference {
type Error = Error;
fn try_cast_from<'a, R>(value: &'a R) -> Result<Cast<Self>, Self::Error>
fn try_cast_from<'a, R>(value: &'a R) -> Result<Cast<'a, Self>, Self::Error>
where
R: AsRef<JsValue> + 'a,
{
Expand Down
5 changes: 2 additions & 3 deletions consensus/core/src/config/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub mod consensus {

/// Size of the **sampled** median time window (independent of BPS)
pub const MEDIAN_TIME_SAMPLED_WINDOW_SIZE: u64 =
((2 * NEW_TIMESTAMP_DEVIATION_TOLERANCE - 1) + PAST_MEDIAN_TIME_SAMPLE_INTERVAL - 1) / PAST_MEDIAN_TIME_SAMPLE_INTERVAL;
(2 * NEW_TIMESTAMP_DEVIATION_TOLERANCE - 1).div_ceil(PAST_MEDIAN_TIME_SAMPLE_INTERVAL);

//
// ~~~~~~~~~~~~~~~~~~~~~~~~~ Max difficulty target ~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -71,8 +71,7 @@ pub mod consensus {
pub const DIFFICULTY_WINDOW_SAMPLE_INTERVAL: u64 = 4;

/// Size of the **sampled** difficulty window (independent of BPS)
pub const DIFFICULTY_SAMPLED_WINDOW_SIZE: u64 =
(NEW_DIFFICULTY_WINDOW_DURATION + DIFFICULTY_WINDOW_SAMPLE_INTERVAL - 1) / DIFFICULTY_WINDOW_SAMPLE_INTERVAL;
pub const DIFFICULTY_SAMPLED_WINDOW_SIZE: u64 = NEW_DIFFICULTY_WINDOW_DURATION.div_ceil(DIFFICULTY_WINDOW_SAMPLE_INTERVAL);

//
// ~~~~~~~~~~~~~~~~~~~ Finality & Pruning ~~~~~~~~~~~~~~~~~~~
Expand Down
13 changes: 13 additions & 0 deletions consensus/core/src/config/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ pub struct Params {
pub skip_proof_of_work: bool,
pub max_block_level: BlockLevel,
pub pruning_proof_m: u64,

/// Activation rules for when to enable using the payload field in transactions
pub payload_activation: ForkActivation,
}

fn unix_now() -> u64 {
Expand Down Expand Up @@ -406,6 +409,8 @@ pub const MAINNET_PARAMS: Params = Params {
skip_proof_of_work: false,
max_block_level: 225,
pruning_proof_m: 1000,

payload_activation: ForkActivation::never(),
};

pub const TESTNET_PARAMS: Params = Params {
Expand Down Expand Up @@ -469,6 +474,8 @@ pub const TESTNET_PARAMS: Params = Params {
skip_proof_of_work: false,
max_block_level: 250,
pruning_proof_m: 1000,

payload_activation: ForkActivation::never(),
};

pub const TESTNET11_PARAMS: Params = Params {
Expand Down Expand Up @@ -530,6 +537,8 @@ pub const TESTNET11_PARAMS: Params = Params {

skip_proof_of_work: false,
max_block_level: 250,

payload_activation: ForkActivation::never(),
};

pub const SIMNET_PARAMS: Params = Params {
Expand Down Expand Up @@ -584,6 +593,8 @@ pub const SIMNET_PARAMS: Params = Params {

skip_proof_of_work: true, // For simnet only, PoW can be simulated by default
max_block_level: 250,

payload_activation: ForkActivation::never(),
};

pub const DEVNET_PARAMS: Params = Params {
Expand Down Expand Up @@ -641,4 +652,6 @@ pub const DEVNET_PARAMS: Params = Params {
skip_proof_of_work: false,
max_block_level: 250,
pruning_proof_m: 1000,

payload_activation: ForkActivation::never(),
};
Loading

0 comments on commit cdbdc43

Please sign in to comment.