-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
740 additions
and
206 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,55 @@ | ||
Please note - this is an alpha version of the software; not all features are currently functional. | ||
Before you start, you must configure the default network setting. There are currently | ||
3 networks available. `mainnet`, `testnet-10` and `testnet-11`. If you wish to experiment, | ||
you should select `testnet-11` by entering `network testnet-11` | ||
|
||
For desktop or web versions of this software, you can use Ctrl+'+' or Ctrl+'-' (Command on macOS) to change the terminal font size. | ||
The `server` command configures the target server. You can connect to any Rusty Spectre | ||
node that has wRPC enabled with `--rpclisten-borsh=0.0.0.0`. If the server setting | ||
is set to 'public' the node will connect to the public node infrastructure. | ||
|
||
If using a desktop version, you can use Ctrl+M (Command on macOS) to bring up metrics. | ||
|
||
Type `help` to see the complete list of commands. Type `exit` to exit this application. On Windows, you can use `Alt+F4`, and on macOS `Command+Q` to exit. | ||
Both network and server values are stored in the application settings and are | ||
used when running a local node or connecting to a remote node. | ||
|
||
--- | ||
|
||
Before you start, you must configure the default network settings. There is only one network currently available: `mainnet`. | ||
|
||
The `server` command configures the target server. You can connect to any Rusty Spectre node that has wRPC enabled with `--rpclisten-borsh=0.0.0.0`. If the server setting is set to 'public', the node will connect to the public node infrastructure. | ||
`wallet create [<name>]` Use this command to create a local wallet. The <name> argument | ||
is optional (the default wallet name is "spectre") and allows you to create multiple | ||
named wallets. Only one wallet can be opened at a time. Keep in mind that a wallet can have multiple | ||
accounts, as such you only need one wallet, unless, for example, you want to separate wallets for | ||
personal and business needs (but you can also create isolated accounts within a wallet). | ||
|
||
Both network and server values are stored in the application settings and are used when running a local node or connecting to a remote node. | ||
|
||
--- | ||
Make sure to record your mnemonic, even if working with a testnet, not to lose your | ||
testnet SPR. | ||
|
||
`wallet create [<name>]` - Use this command to create a local wallet. The <name> argument is optional (the default wallet name is "spectre") and allows you to create multiple named wallets. Only one wallet can be opened at a time. Keep in mind that a wallet can have multiple accounts, so you only need one wallet unless, for example, you want to separate wallets for personal and business needs (but you can also create isolated accounts within a wallet). | ||
|
||
Make sure to record your mnemonic, even if working with a testnet, to avoid losing your testnet SPR. | ||
|
||
`open <name>` - Opens the wallet (the wallet is open automatically after creation). | ||
`open <name>` - opens the wallet (the wallet is open automatically after creation). | ||
|
||
`list` - Lists all wallet accounts and their balances. | ||
|
||
`select <account-name>` - Selects an active account. The <account-name> can be the first few letters of the name or ID of the account. | ||
`select <account-name>` - Selects an active account. The <account-name> can be the first few letters of the name or id of the account. | ||
|
||
`account create bip32 [<name>]` - Allows you to create additional HD wallet accounts linked to the default private key of your wallet. | ||
|
||
`address` - Shows your selected account address. Note - you can click on the address to copy it to the clipboard. (When on mainnet, Ctrl+Click on addresses, transactions, and block hashes will open a new browser window with an explorer.) | ||
`address` - shows your selected account address | ||
|
||
Before you transact: The `mute` option (enabled by default) toggles mute on/off. Mute enables terminal output of internal framework events. Rust and JavaScript/TypeScript applications integrating with this platform are meant to update their state by monitoring event notifications. Mute allows you to see these events in the terminal. When mute is off, all events are displayed in the terminal. When mute is on, you can use the 'track' command to enable specific event notifications. | ||
Before you transact: `mute` option (enabled by default) toggles mute on/off. Mute enables terminal | ||
output of internal framework events. Rust and JavaScript/TypeScript applications integrating with this platform | ||
are meant to update their state by monitoring event notifications. Mute allows you to see these events in | ||
the terminal. When mute is off, all events are displayed in the terminal. When mute is on, you can use 'track' | ||
command to enable specific event notification. | ||
|
||
`transfer <account-name> <amount>` - Transfers from the active account to a different account. For example, `transfer p 1` will transfer 1 SPR from the selected account to an account named 'pete' (starting with the letter 'p'). | ||
`transfer <account-name> <amount>` - Transfers from the active to a different account. For example 'transfer p 1' will transfer 1 SPR from | ||
the selected account to an account named 'pete' (starts with a 'p' letter) | ||
|
||
`send <address> <amount>` - Sends funds to a destination address. | ||
`send <address> <amount>` - Send funds to a destination address . | ||
|
||
`estimate <amount>` - Provides a fee and UTXO consumption estimate for a transaction of a given amount. | ||
|
||
`sweep` - Sweeps account UTXOs to reduce the UTXO size. | ||
|
||
`history list` - Shows previous account transactions. | ||
|
||
`history details` - Shows previous account transactions with extended information. | ||
`history details` - Show previous account transactions with extended information. | ||
|
||
`monitor` - A test screen environment that periodically updates account balances. | ||
|
||
`rpc` - Allows you to execute RPC methods against the node (not all methods are currently available). | ||
`rpc` - Allows you to execute RPC methods against the node (not all methods are currently available) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
use criterion::{black_box, criterion_group, criterion_main, Criterion, SamplingMode}; | ||
use spectre_addresses::{Address, Prefix, Version}; | ||
use spectre_consensus::processes::transaction_validator::transaction_validator_populated::{ | ||
check_scripts_par_iter, check_scripts_par_iter_pool, check_scripts_sequential, | ||
}; | ||
use spectre_consensus_core::hashing::sighash::{calc_schnorr_signature_hash, SigHashReusedValuesUnsync}; | ||
use spectre_consensus_core::hashing::sighash_type::SIG_HASH_ALL; | ||
use spectre_consensus_core::subnets::SubnetworkId; | ||
use spectre_consensus_core::tx::{MutableTransaction, Transaction, TransactionInput, TransactionOutpoint, UtxoEntry}; | ||
use spectre_txscript::caches::Cache; | ||
use spectre_txscript::pay_to_address_script; | ||
use rand::{thread_rng, Rng}; | ||
use secp256k1::Keypair; | ||
use std::thread::available_parallelism; | ||
|
||
// 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>) { | ||
let reused_values = SigHashReusedValuesUnsync::new(); | ||
let dummy_prev_out = TransactionOutpoint::new(spectre_hashes::Hash::from_u64_word(1), 1); | ||
let mut tx = Transaction::new( | ||
0, | ||
vec![], | ||
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![], | ||
); | ||
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 }); | ||
let address = Address::new(Prefix::Mainnet, Version::PubKey, &kp.x_only_public_key().0.serialize()); | ||
utxos.push(UtxoEntry { | ||
amount: thread_rng().gen::<u32>() as u64, | ||
script_public_key: pay_to_address_script(&address), | ||
block_daa_score: 333, | ||
is_coinbase: false, | ||
}); | ||
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 }); | ||
let address = Address::new(Prefix::Mainnet, Version::PubKey, &kp.x_only_public_key().0.serialize()); | ||
utxos.push(UtxoEntry { | ||
amount: thread_rng().gen::<u32>() as u64, | ||
script_public_key: pay_to_address_script(&address), | ||
block_daa_score: 444, | ||
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 mut group = c.benchmark_group(format!("inputs: {inputs_count}, non uniq: {non_uniq_signatures}")); | ||
group.sampling_mode(SamplingMode::Flat); | ||
|
||
group.bench_function("single_thread", |b| { | ||
let tx = MutableTransaction::with_entries(&tx, utxos.clone()); | ||
let cache = Cache::new(inputs_count as u64); | ||
b.iter(|| { | ||
cache.clear(); | ||
check_scripts_sequential(black_box(&cache), black_box(&tx.as_verifiable())).unwrap(); | ||
}) | ||
}); | ||
|
||
group.bench_function("rayon par iter", |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())).unwrap(); | ||
}) | ||
}); | ||
|
||
// Iterate powers of two up to available parallelism | ||
for i in (1..=(available_parallelism().unwrap().get() as f64).log2().ceil() as u32).map(|x| 2u32.pow(x) as usize) { | ||
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(|| { | ||
cache.clear(); | ||
check_scripts_par_iter_pool(black_box(&cache), black_box(&tx.as_verifiable()), black_box(&pool)).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 | ||
} | ||
|
||
criterion_main!(benches); |
Oops, something went wrong.