mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-04-23 19:31:00 +08:00
clean: remove benchmark files
This commit is contained in:
@@ -1,678 +0,0 @@
|
||||
extern crate blockstack_lib;
|
||||
extern crate rand;
|
||||
extern crate serde_json;
|
||||
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
use std::{env, time::Instant};
|
||||
|
||||
use blockstack_lib::clarity_vm::clarity::ClarityInstance;
|
||||
use blockstack_lib::clarity_vm::database::MemoryBackingStore;
|
||||
use blockstack_lib::core::StacksEpochId;
|
||||
use blockstack_lib::types::chainstate::BlockHeaderHash;
|
||||
use blockstack_lib::types::chainstate::BurnchainHeaderHash;
|
||||
use blockstack_lib::types::chainstate::VRFSeed;
|
||||
use blockstack_lib::types::proof::ClarityMarfTrieId;
|
||||
use blockstack_lib::vm::ast::build_ast;
|
||||
use blockstack_lib::vm::contexts::GlobalContext;
|
||||
use blockstack_lib::vm::costs::LimitedCostTracker;
|
||||
use blockstack_lib::vm::errors::InterpreterResult;
|
||||
use blockstack_lib::vm::{eval_all, ContractContext};
|
||||
use rand::Rng;
|
||||
|
||||
use blockstack_lib::clarity_vm::database::marf::MarfedKV;
|
||||
use blockstack_lib::types::chainstate::{StacksAddress, StacksBlockId};
|
||||
use blockstack_lib::util::boot::boot_code_id;
|
||||
use blockstack_lib::{
|
||||
vm::costs::ExecutionCost,
|
||||
vm::{
|
||||
database::{HeadersDB, NULL_BURN_STATE_DB},
|
||||
types::{PrincipalData, QualifiedContractIdentifier, StandardPrincipalData},
|
||||
Value,
|
||||
},
|
||||
};
|
||||
|
||||
struct TestHeadersDB;
|
||||
|
||||
impl HeadersDB for TestHeadersDB {
|
||||
fn get_stacks_block_header_hash_for_block(
|
||||
&self,
|
||||
id_bhh: &StacksBlockId,
|
||||
) -> Option<BlockHeaderHash> {
|
||||
Some(BlockHeaderHash(id_bhh.0.clone()))
|
||||
}
|
||||
|
||||
fn get_burn_header_hash_for_block(
|
||||
&self,
|
||||
id_bhh: &StacksBlockId,
|
||||
) -> Option<BurnchainHeaderHash> {
|
||||
Some(BurnchainHeaderHash(id_bhh.0.clone()))
|
||||
}
|
||||
|
||||
fn get_vrf_seed_for_block(&self, _id_bhh: &StacksBlockId) -> Option<VRFSeed> {
|
||||
Some(VRFSeed([0; 32]))
|
||||
}
|
||||
|
||||
fn get_burn_block_time_for_block(&self, _id_bhh: &StacksBlockId) -> Option<u64> {
|
||||
Some(1)
|
||||
}
|
||||
|
||||
fn get_burn_block_height_for_block(&self, id_bhh: &StacksBlockId) -> Option<u32> {
|
||||
if id_bhh == &StacksBlockId::sentinel() {
|
||||
Some(0)
|
||||
} else {
|
||||
let mut bytes = [0; 4];
|
||||
bytes.copy_from_slice(&id_bhh.0[0..4]);
|
||||
let height = u32::from_le_bytes(bytes);
|
||||
Some(height)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_miner_address(&self, _id_bhh: &StacksBlockId) -> Option<StacksAddress> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn as_hash160(inp: u32) -> [u8; 20] {
|
||||
let mut out = [0; 20];
|
||||
out[0..4].copy_from_slice(&inp.to_le_bytes());
|
||||
out
|
||||
}
|
||||
|
||||
fn as_hash(inp: u32) -> [u8; 32] {
|
||||
let mut out = [0; 32];
|
||||
out[0..4].copy_from_slice(&inp.to_le_bytes());
|
||||
out
|
||||
}
|
||||
|
||||
fn transfer_test(buildup_count: u32, scaling: u32, genesis_size: u32) -> ExecutionCost {
|
||||
let start = Instant::now();
|
||||
|
||||
let marf = setup_chain_state(genesis_size);
|
||||
let mut clarity_instance = ClarityInstance::new(false, marf);
|
||||
let blocks: Vec<_> = (0..(buildup_count + 1))
|
||||
.into_iter()
|
||||
.map(|i| StacksBlockId(as_hash(i)))
|
||||
.collect();
|
||||
|
||||
let principals: Vec<PrincipalData> = (0..(buildup_count - 1))
|
||||
.into_iter()
|
||||
.map(|i| StandardPrincipalData(0, as_hash160(i)).into())
|
||||
.collect();
|
||||
|
||||
let last_mint_block = blocks.len() - 2;
|
||||
let last_block = blocks.len() - 1;
|
||||
|
||||
for ix in 1..(last_mint_block + 1) {
|
||||
let parent_block = &blocks[ix - 1];
|
||||
let current_block = &blocks[ix];
|
||||
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
parent_block,
|
||||
current_block,
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
// minting phase
|
||||
conn.as_transaction(|tx| {
|
||||
tx.with_clarity_db(|db| {
|
||||
let mut stx_account_0 = db.get_stx_balance_snapshot_genesis(&principals[ix - 1]);
|
||||
stx_account_0.credit(1_000_000);
|
||||
stx_account_0.save();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
conn.commit_to_block(current_block);
|
||||
}
|
||||
|
||||
eprintln!("Finished buildup in {}ms", start.elapsed().as_millis());
|
||||
|
||||
// transfer phase
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
&blocks[last_mint_block],
|
||||
&blocks[last_block],
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
let begin = Instant::now();
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
for _i in 0..scaling {
|
||||
let from = rng.gen_range(0, principals.len());
|
||||
let to = (from + rng.gen_range(1, principals.len())) % principals.len();
|
||||
|
||||
conn.as_transaction(|tx| {
|
||||
tx.run_stx_transfer(&principals[from], &principals[to], 10, &BuffData::empty())
|
||||
.unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
let this_cost = conn.commit_to_block(&blocks[last_block]).get_total();
|
||||
let elapsed = begin.elapsed();
|
||||
|
||||
println!(
|
||||
"{} transfers in {} ms, after {} block buildup with a {} account genesis",
|
||||
scaling,
|
||||
elapsed.as_millis(),
|
||||
buildup_count,
|
||||
genesis_size,
|
||||
);
|
||||
|
||||
this_cost
|
||||
}
|
||||
|
||||
fn setup_chain_state(scaling: u32) -> MarfedKV {
|
||||
let pre_initialized_path = format!("/tmp/block_limit_bench_{}.marf", scaling);
|
||||
let out_path = "/tmp/block_limit_bench_last.marf";
|
||||
|
||||
if fs::metadata(&pre_initialized_path).is_err() {
|
||||
let marf = MarfedKV::open(&pre_initialized_path, None).unwrap();
|
||||
let mut clarity_instance = ClarityInstance::new(false, marf);
|
||||
let mut conn = clarity_instance.begin_test_genesis_block(
|
||||
&StacksBlockId::sentinel(),
|
||||
&StacksBlockId(as_hash(0)),
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
conn.as_transaction(|tx| {
|
||||
for j in 0..scaling {
|
||||
tx.with_clarity_db(|db| {
|
||||
let addr = StandardPrincipalData(0, as_hash160(j + 1)).into();
|
||||
let mut stx_account_0 = db.get_stx_balance_snapshot_genesis(&addr);
|
||||
stx_account_0.credit(1);
|
||||
stx_account_0.save();
|
||||
db.increment_ustx_liquid_supply(1).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
conn.commit_to_block(&StacksBlockId(as_hash(0)));
|
||||
};
|
||||
|
||||
if fs::metadata(&out_path).is_err() {
|
||||
let path = PathBuf::from(out_path);
|
||||
fs::create_dir_all(&path).expect("Error creating directory");
|
||||
}
|
||||
|
||||
fs::copy(
|
||||
&format!("{}/marf.sqlite", pre_initialized_path),
|
||||
&format!("{}/marf.sqlite", out_path),
|
||||
)
|
||||
.unwrap();
|
||||
return MarfedKV::open(out_path, None).unwrap();
|
||||
}
|
||||
|
||||
fn test_via_raw_contract(
|
||||
eval: &str,
|
||||
scaling: u32,
|
||||
buildup_count: u32,
|
||||
genesis_size: u32,
|
||||
) -> ExecutionCost {
|
||||
let start = Instant::now();
|
||||
|
||||
let marf = setup_chain_state(genesis_size);
|
||||
|
||||
let mut clarity_instance = ClarityInstance::new(false, marf);
|
||||
let blocks: Vec<_> = (0..(buildup_count + 1))
|
||||
.into_iter()
|
||||
.map(|i| StacksBlockId(as_hash(i)))
|
||||
.collect();
|
||||
|
||||
let stacker: PrincipalData = StandardPrincipalData(0, as_hash160(0)).into();
|
||||
|
||||
let contract_id =
|
||||
QualifiedContractIdentifier::new(StandardPrincipalData(0, as_hash160(0)), "test".into());
|
||||
|
||||
let mut smart_contract = "".to_string();
|
||||
for _i in 0..scaling {
|
||||
smart_contract.push_str(&format!("{}\n", eval));
|
||||
}
|
||||
|
||||
let last_mint_block = blocks.len() - 2;
|
||||
let last_block = blocks.len() - 1;
|
||||
|
||||
for ix in 1..(last_mint_block + 1) {
|
||||
let parent_block = &blocks[ix - 1];
|
||||
let current_block = &blocks[ix];
|
||||
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
parent_block,
|
||||
current_block,
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
// minting phase
|
||||
conn.as_transaction(|tx| {
|
||||
tx.with_clarity_db(|db| {
|
||||
let mut stx_account_0 = db.get_stx_balance_snapshot_genesis(&stacker);
|
||||
stx_account_0.credit(1_000_000);
|
||||
stx_account_0.save();
|
||||
db.increment_ustx_liquid_supply(1_000_000).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
conn.commit_to_block(current_block);
|
||||
}
|
||||
|
||||
eprintln!("Finished buildup in {}ms", start.elapsed().as_millis());
|
||||
|
||||
// execute the block
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
&blocks[last_mint_block],
|
||||
&blocks[last_block],
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
let begin = Instant::now();
|
||||
|
||||
let exec_cost = conn.as_transaction(|tx| {
|
||||
let analysis_cost = tx.cost_so_far();
|
||||
let (contract_ast, contract_analysis) = tx
|
||||
.analyze_smart_contract(&contract_id, &smart_contract)
|
||||
.unwrap();
|
||||
tx.initialize_smart_contract(
|
||||
&contract_id,
|
||||
&contract_ast,
|
||||
&smart_contract,
|
||||
None,
|
||||
|_, _| false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut initialize_cost = tx.cost_so_far();
|
||||
initialize_cost.sub(&analysis_cost).unwrap();
|
||||
|
||||
tx.save_analysis(&contract_id, &contract_analysis)
|
||||
.expect("FATAL: failed to store contract analysis");
|
||||
|
||||
initialize_cost
|
||||
});
|
||||
|
||||
let _this_cost = conn.commit_to_block(&blocks[last_block]).get_total();
|
||||
let elapsed = begin.elapsed();
|
||||
|
||||
println!(
|
||||
"Completed raw execution scaled at {} in {} ms, after {} block buildup with a {} account genesis",
|
||||
scaling,
|
||||
elapsed.as_millis(),
|
||||
buildup_count,
|
||||
genesis_size,
|
||||
);
|
||||
|
||||
exec_cost
|
||||
}
|
||||
|
||||
fn smart_contract_test(scaling: u32, buildup_count: u32, genesis_size: u32) -> ExecutionCost {
|
||||
let start = Instant::now();
|
||||
|
||||
let marf = setup_chain_state(genesis_size);
|
||||
|
||||
let mut clarity_instance = ClarityInstance::new(false, marf);
|
||||
let blocks: Vec<_> = (0..(buildup_count + 1))
|
||||
.into_iter()
|
||||
.map(|i| StacksBlockId(as_hash(i)))
|
||||
.collect();
|
||||
|
||||
let stacker: PrincipalData = StandardPrincipalData(0, as_hash160(0)).into();
|
||||
|
||||
let contract_id =
|
||||
QualifiedContractIdentifier::new(StandardPrincipalData(0, as_hash160(0)), "test".into());
|
||||
|
||||
let mut smart_contract = "".to_string();
|
||||
for i in 0..scaling {
|
||||
smart_contract.push_str(&format!("(define-public (foo-{}) (ok (+ u2 u3)))\n", i));
|
||||
}
|
||||
|
||||
let last_mint_block = blocks.len() - 2;
|
||||
let last_block = blocks.len() - 1;
|
||||
|
||||
for ix in 1..(last_mint_block + 1) {
|
||||
let parent_block = &blocks[ix - 1];
|
||||
let current_block = &blocks[ix];
|
||||
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
parent_block,
|
||||
current_block,
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
// minting phase
|
||||
conn.as_transaction(|tx| {
|
||||
tx.with_clarity_db(|db| {
|
||||
let mut stx_account_0 = db.get_stx_balance_snapshot_genesis(&stacker);
|
||||
stx_account_0.credit(1_000_000);
|
||||
stx_account_0.save();
|
||||
db.increment_ustx_liquid_supply(1_000_000).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
conn.commit_to_block(current_block);
|
||||
}
|
||||
|
||||
eprintln!("Finished buildup in {}ms", start.elapsed().as_millis());
|
||||
|
||||
// execute the block
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
&blocks[last_mint_block],
|
||||
&blocks[last_block],
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
let begin = Instant::now();
|
||||
|
||||
conn.as_transaction(|tx| {
|
||||
let (contract_ast, contract_analysis) = tx
|
||||
.analyze_smart_contract(&contract_id, &smart_contract)
|
||||
.unwrap();
|
||||
tx.initialize_smart_contract(
|
||||
&contract_id,
|
||||
&contract_ast,
|
||||
&smart_contract,
|
||||
None,
|
||||
|_, _| false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
tx.save_analysis(&contract_id, &contract_analysis)
|
||||
.expect("FATAL: failed to store contract analysis");
|
||||
});
|
||||
|
||||
let this_cost = conn.commit_to_block(&blocks[last_block]).get_total();
|
||||
let elapsed = begin.elapsed();
|
||||
|
||||
println!(
|
||||
"Completed smart-contract scaled at {} in {} ms, after {} block buildup with a {} account genesis",
|
||||
scaling,
|
||||
elapsed.as_millis(),
|
||||
buildup_count,
|
||||
genesis_size,
|
||||
);
|
||||
|
||||
this_cost
|
||||
}
|
||||
|
||||
fn expensive_contract_test(scaling: u32, buildup_count: u32, genesis_size: u32) -> ExecutionCost {
|
||||
let start = Instant::now();
|
||||
|
||||
let marf = setup_chain_state(genesis_size);
|
||||
|
||||
let mut clarity_instance = ClarityInstance::new(false, marf);
|
||||
let blocks: Vec<_> = (0..(buildup_count + 1))
|
||||
.into_iter()
|
||||
.map(|i| StacksBlockId(as_hash(i)))
|
||||
.collect();
|
||||
|
||||
let stacker: PrincipalData = StandardPrincipalData(0, as_hash160(0)).into();
|
||||
|
||||
let contract_id =
|
||||
QualifiedContractIdentifier::new(StandardPrincipalData(0, as_hash160(0)), "test".into());
|
||||
|
||||
let smart_contract = format!(
|
||||
"(define-public (f) (begin {} (ok 1))) (begin (f))",
|
||||
(0..scaling)
|
||||
.map(|_| format!(
|
||||
"(unwrap! (contract-call? '{} submit-proposal '{} \"cost-old\" '{} \"cost-new\") (err 1))",
|
||||
boot_code_id("cost-voting", false),
|
||||
contract_id.clone(),
|
||||
contract_id.clone()
|
||||
))
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
);
|
||||
|
||||
let last_mint_block = blocks.len() - 2;
|
||||
let last_block = blocks.len() - 1;
|
||||
|
||||
for ix in 1..(last_mint_block + 1) {
|
||||
let parent_block = &blocks[ix - 1];
|
||||
let current_block = &blocks[ix];
|
||||
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
parent_block,
|
||||
current_block,
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
// minting phase
|
||||
conn.as_transaction(|tx| {
|
||||
tx.with_clarity_db(|db| {
|
||||
let mut stx_account_0 = db.get_stx_balance_snapshot_genesis(&stacker);
|
||||
stx_account_0.credit(1_000_000);
|
||||
stx_account_0.save();
|
||||
db.increment_ustx_liquid_supply(1_000_000).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
conn.commit_to_block(current_block);
|
||||
}
|
||||
|
||||
eprintln!("Finished buildup in {}ms", start.elapsed().as_millis());
|
||||
|
||||
// execute the block
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
&blocks[last_mint_block],
|
||||
&blocks[last_block],
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
let begin = Instant::now();
|
||||
|
||||
conn.as_transaction(|tx| {
|
||||
let (contract_ast, contract_analysis) = tx
|
||||
.analyze_smart_contract(&contract_id, &smart_contract)
|
||||
.unwrap();
|
||||
tx.initialize_smart_contract(&contract_id, &contract_ast, &smart_contract, |_, _| false)
|
||||
.unwrap();
|
||||
|
||||
tx.save_analysis(&contract_id, &contract_analysis)
|
||||
.expect("FATAL: failed to store contract analysis");
|
||||
});
|
||||
|
||||
let this_cost = conn.commit_to_block(&blocks[last_block]).get_total();
|
||||
let elapsed = begin.elapsed();
|
||||
|
||||
println!(
|
||||
"Completed smart-contract scaled at {} in {} ms, after {} block buildup with a {} account genesis",
|
||||
scaling,
|
||||
elapsed.as_millis(),
|
||||
buildup_count,
|
||||
genesis_size,
|
||||
);
|
||||
|
||||
this_cost
|
||||
}
|
||||
|
||||
pub fn execute_in_epoch(program: &str, epoch: StacksEpochId) -> InterpreterResult<Option<Value>> {
|
||||
let contract_id = QualifiedContractIdentifier::transient();
|
||||
let mut contract_context = ContractContext::new(contract_id.clone());
|
||||
let mut marf = MemoryBackingStore::new();
|
||||
let conn = marf.as_clarity_db();
|
||||
let mut global_context = GlobalContext::new(false, conn, LimitedCostTracker::new_free(), epoch);
|
||||
global_context.execute(|g| {
|
||||
let parsed = build_ast(&contract_id, program, &mut ())?.expressions;
|
||||
eval_all(&parsed, &mut contract_context, g)
|
||||
})
|
||||
}
|
||||
|
||||
fn execute(program: &str) -> InterpreterResult<Option<Value>> {
|
||||
let epoch_200_result = execute_in_epoch(program, StacksEpochId::Epoch20);
|
||||
let epoch_205_result = execute_in_epoch(program, StacksEpochId::Epoch2_05);
|
||||
assert_eq!(
|
||||
epoch_200_result, epoch_205_result,
|
||||
"Epoch 2.0 and 2.05 should have same execution result, but did not for program `{}`",
|
||||
program
|
||||
);
|
||||
epoch_205_result
|
||||
}
|
||||
|
||||
fn stack_stx_test(buildup_count: u32, genesis_size: u32, scaling: u32) -> ExecutionCost {
|
||||
let start = Instant::now();
|
||||
let marf = setup_chain_state(genesis_size);
|
||||
|
||||
let mut clarity_instance = ClarityInstance::new(false, marf);
|
||||
let blocks: Vec<_> = (0..(buildup_count + 1))
|
||||
.into_iter()
|
||||
.map(|i| StacksBlockId(as_hash(i)))
|
||||
.collect();
|
||||
|
||||
let stackers: Vec<PrincipalData> = (0..scaling)
|
||||
.into_iter()
|
||||
.map(|i| StandardPrincipalData(0, as_hash160(i)).into())
|
||||
.collect();
|
||||
|
||||
let stacker_balance = (buildup_count as u128 - 1) * 1_000_000;
|
||||
|
||||
let pox_addrs: Vec<Value> = (0..50u64)
|
||||
.map(|ix| {
|
||||
execute(&format!(
|
||||
"{{ version: 0x00, hashbytes: 0x000000000000000000000000{} }}",
|
||||
&blockstack_lib::util::hash::to_hex(&ix.to_le_bytes())
|
||||
))
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
})
|
||||
.collect();
|
||||
|
||||
let last_mint_block = blocks.len() - 2;
|
||||
let last_block = blocks.len() - 1;
|
||||
|
||||
for ix in 1..(last_mint_block + 1) {
|
||||
let parent_block = &blocks[ix - 1];
|
||||
let current_block = &blocks[ix];
|
||||
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
parent_block,
|
||||
current_block,
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
// minting phase
|
||||
conn.as_transaction(|tx| {
|
||||
tx.with_clarity_db(|db| {
|
||||
for stacker in stackers.iter() {
|
||||
let mut stx_account_0 = db.get_stx_balance_snapshot_genesis(stacker);
|
||||
stx_account_0.credit(1_000_000);
|
||||
stx_account_0.save();
|
||||
db.increment_ustx_liquid_supply(1_000_000).unwrap();
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
conn.commit_to_block(current_block);
|
||||
}
|
||||
|
||||
eprintln!("Finished buildup in {}ms", start.elapsed().as_millis());
|
||||
|
||||
// do the stack-stx block
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
&blocks[last_mint_block],
|
||||
&blocks[last_block],
|
||||
&TestHeadersDB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
let begin = Instant::now();
|
||||
|
||||
conn.as_transaction(|tx| {
|
||||
for stacker in stackers.iter() {
|
||||
let result = tx
|
||||
.run_contract_call(
|
||||
stacker,
|
||||
None,
|
||||
&boot_code_id("pox", false),
|
||||
"stack-stx",
|
||||
&[
|
||||
Value::UInt(stacker_balance),
|
||||
pox_addrs[0].clone(),
|
||||
Value::UInt(buildup_count as u128 + 2),
|
||||
Value::UInt(12),
|
||||
],
|
||||
|_, _| false,
|
||||
)
|
||||
.unwrap()
|
||||
.0;
|
||||
if let Err(v) = result.expect_result() {
|
||||
panic!("Stacking failed: {}", v);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let this_cost = conn.commit_to_block(&blocks[last_block]).get_total();
|
||||
let elapsed = begin.elapsed();
|
||||
|
||||
println!(
|
||||
"Completed {} stack-stx ops in {} ms, after {} block buildup with a {} account genesis",
|
||||
scaling,
|
||||
elapsed.as_millis(),
|
||||
buildup_count,
|
||||
genesis_size,
|
||||
);
|
||||
|
||||
this_cost
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let argv: Vec<_> = env::args().collect();
|
||||
|
||||
if argv.len() < 3 {
|
||||
eprintln!(
|
||||
"Usage: {} [test-name] [scalar-0] ... [scalar-n]
|
||||
|
||||
transfer <block_build_up> <genesis_size> <number_of_ops>
|
||||
smart-contract <block_build_up> <genesis_size> <number_of_ops>
|
||||
stack-stx <block_build_up> <genesis_size> <number_of_ops>
|
||||
clarity-transfer <block_build_up> <genesis_size> <number_of_ops>
|
||||
clarity-verify <block_build_up> <genesis_size> <number_of_ops>
|
||||
clarity-raw <block_build_up> <genesis_size> <number_of_ops> <eval-block>
|
||||
",
|
||||
argv[0]
|
||||
);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let block_build_up = argv[2].parse().expect("Invalid scalar");
|
||||
let genesis_size = argv[3].parse().expect("Invalid scalar");
|
||||
let scaling = argv[4].parse().expect("Invalid scalar");
|
||||
|
||||
let result = match argv[1].as_str() {
|
||||
"transfer" => transfer_test(block_build_up, scaling, genesis_size),
|
||||
"smart-contract" => smart_contract_test(scaling, block_build_up, genesis_size),
|
||||
"clarity-transfer" => test_via_raw_contract(r#"(stx-transfer? u1 tx-sender 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR)"#,
|
||||
scaling, block_build_up, genesis_size),
|
||||
"expensive-contract" => expensive_contract_test(scaling, block_build_up, genesis_size),
|
||||
"clarity-verify" => test_via_raw_contract("(secp256k1-verify 0xde5b9eb9e7c5592930eb2e30a01369c36586d872082ed8181ee83d2a0ec20f04
|
||||
0x8738487ebe69b93d8e51583be8eee50bb4213fc49c767d329632730cc193b873554428fc936ca3569afc15f1c9365f6591d6251a89fee9c9ac661116824d3a1301
|
||||
0x03adb8de4bfb65db2cfd6120d55c6526ae9c52e675db7e47308636534ba7786110)",
|
||||
scaling, block_build_up, genesis_size),
|
||||
"stack-stx" => stack_stx_test(block_build_up, genesis_size, scaling),
|
||||
_ => {
|
||||
eprintln!("bad test name");
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
println!("{}", serde_json::to_string(&result).unwrap());
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
extern crate blockstack_lib;
|
||||
extern crate criterion;
|
||||
extern crate rand;
|
||||
|
||||
use blockstack_lib::address::c32::{c32_address, c32_address_decode};
|
||||
use blockstack_lib::address::c32_old::c32_address_decode as c32_address_decode_old;
|
||||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use rand::Rng;
|
||||
|
||||
fn bench_c32_decoding(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("C32 Decoding");
|
||||
|
||||
let mut addrs: Vec<String> = vec![];
|
||||
for _ in 0..5 {
|
||||
// random version
|
||||
let random_version: u8 = rand::thread_rng().gen_range(0, 31);
|
||||
// random 20 bytes
|
||||
let random_bytes = rand::thread_rng().gen::<[u8; 20]>();
|
||||
let addr = c32_address(random_version, &random_bytes).unwrap();
|
||||
addrs.push(addr);
|
||||
}
|
||||
|
||||
for addr in addrs.iter() {
|
||||
group.bench_with_input(BenchmarkId::new("Legacy", addr), addr, |b, i| {
|
||||
b.iter(|| c32_address_decode_old(i))
|
||||
});
|
||||
group.bench_with_input(BenchmarkId::new("Updated", addr), addr, |b, i| {
|
||||
b.iter(|| c32_address_decode(i))
|
||||
});
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_c32_decoding);
|
||||
criterion_main!(benches);
|
||||
@@ -1,158 +0,0 @@
|
||||
#[macro_use]
|
||||
extern crate criterion;
|
||||
extern crate blockstack_lib;
|
||||
extern crate rand;
|
||||
|
||||
use blockstack_lib::clarity_vm::clarity::ClarityInstance;
|
||||
use blockstack_lib::clarity_vm::database::marf::MarfedKV;
|
||||
use blockstack_lib::types::chainstate::StacksBlockId;
|
||||
use blockstack_lib::types::proof::ClarityMarfTrieId;
|
||||
use blockstack_lib::vm::database::NULL_BURN_STATE_DB;
|
||||
use blockstack_lib::{vm::database::NULL_HEADER_DB, vm::types::QualifiedContractIdentifier};
|
||||
use criterion::Criterion;
|
||||
|
||||
pub fn rollback_log_memory_test() {
|
||||
let marf = MarfedKV::temporary();
|
||||
let mut clarity_instance = ClarityInstance::new(false, marf);
|
||||
let EXPLODE_N = 100;
|
||||
|
||||
let contract_identifier = QualifiedContractIdentifier::local("foo").unwrap();
|
||||
|
||||
{
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
&StacksBlockId::sentinel(),
|
||||
&StacksBlockId::from_bytes(&[0 as u8; 32]).unwrap(),
|
||||
&NULL_HEADER_DB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
let define_data_var = "(define-data-var XZ (buff 1048576) \"a\")";
|
||||
|
||||
let mut contract = define_data_var.to_string();
|
||||
for i in 0..20 {
|
||||
let cur_size = format!("{}", 2u32.pow(i));
|
||||
contract.push_str("\n");
|
||||
contract.push_str(&format!(
|
||||
"(var-set XZ (concat (unwrap-panic (as-max-len? (var-get XZ) u{}))
|
||||
(unwrap-panic (as-max-len? (var-get XZ) u{}))))",
|
||||
cur_size, cur_size
|
||||
));
|
||||
}
|
||||
for i in 0..EXPLODE_N {
|
||||
let exploder = format!("(define-data-var var-{} (buff 1048576) (var-get XZ))", i);
|
||||
contract.push_str("\n");
|
||||
contract.push_str(&exploder);
|
||||
}
|
||||
|
||||
conn.as_transaction(|conn| {
|
||||
let (ct_ast, _ct_analysis) = conn
|
||||
.analyze_smart_contract(&contract_identifier, &contract)
|
||||
.unwrap();
|
||||
|
||||
assert!(format!(
|
||||
"{:?}",
|
||||
conn.initialize_smart_contract(&contract_identifier, &ct_ast, &contract, |_, _| {
|
||||
false
|
||||
})
|
||||
.unwrap_err()
|
||||
)
|
||||
.contains("MemoryBalanceExceeded"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ccall_memory_test() {
|
||||
let marf = MarfedKV::temporary();
|
||||
let mut clarity_instance = ClarityInstance::new(false, marf);
|
||||
let COUNT_PER_CONTRACT = 20;
|
||||
let CONTRACTS = 5;
|
||||
|
||||
{
|
||||
let mut conn = clarity_instance.begin_block(
|
||||
&StacksBlockId::sentinel(),
|
||||
&StacksBlockId::from_bytes(&[0 as u8; 32]).unwrap(),
|
||||
&NULL_HEADER_DB,
|
||||
&NULL_BURN_STATE_DB,
|
||||
);
|
||||
|
||||
let define_data_var = "(define-constant buff-0 \"a\")\n";
|
||||
|
||||
let mut contract = define_data_var.to_string();
|
||||
for i in 0..20 {
|
||||
contract.push_str(&format!(
|
||||
"(define-constant buff-{} (concat buff-{} buff-{}))\n",
|
||||
i + 1,
|
||||
i,
|
||||
i
|
||||
));
|
||||
}
|
||||
|
||||
for i in 0..COUNT_PER_CONTRACT {
|
||||
contract.push_str(&format!("(define-constant var-{} buff-20)\n", i));
|
||||
}
|
||||
|
||||
contract.push_str("(define-public (call)\n");
|
||||
|
||||
let mut contracts = vec![];
|
||||
|
||||
for i in 0..CONTRACTS {
|
||||
let mut my_contract = contract.clone();
|
||||
if i == 0 {
|
||||
my_contract.push_str("(ok 1))\n");
|
||||
} else {
|
||||
my_contract.push_str(&format!("(contract-call? .contract-{} call))\n", i - 1));
|
||||
}
|
||||
my_contract.push_str("(call)\n");
|
||||
contracts.push(my_contract);
|
||||
}
|
||||
|
||||
for (i, contract) in contracts.into_iter().enumerate() {
|
||||
let contract_name = format!("contract-{}", i);
|
||||
let contract_identifier = QualifiedContractIdentifier::local(&contract_name).unwrap();
|
||||
|
||||
if i < (CONTRACTS - 1) {
|
||||
conn.as_transaction(|conn| {
|
||||
let (ct_ast, ct_analysis) = conn
|
||||
.analyze_smart_contract(&contract_identifier, &contract)
|
||||
.unwrap();
|
||||
conn.initialize_smart_contract(
|
||||
&contract_identifier,
|
||||
&ct_ast,
|
||||
&contract,
|
||||
|_, _| false,
|
||||
)
|
||||
.unwrap();
|
||||
conn.save_analysis(&contract_identifier, &ct_analysis)
|
||||
.unwrap();
|
||||
})
|
||||
} else {
|
||||
conn.as_transaction(|conn| {
|
||||
let (ct_ast, _ct_analysis) = conn
|
||||
.analyze_smart_contract(&contract_identifier, &contract)
|
||||
.unwrap();
|
||||
assert!(format!(
|
||||
"{:?}",
|
||||
conn.initialize_smart_contract(
|
||||
&contract_identifier,
|
||||
&ct_ast,
|
||||
&contract,
|
||||
|_, _| false
|
||||
)
|
||||
.unwrap_err()
|
||||
)
|
||||
.contains("MemoryBalanceExceeded"));
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn basic_usage_benchmark(c: &mut Criterion) {
|
||||
c.bench_function("rollback_log_memory_test", |b| {
|
||||
b.iter(|| rollback_log_memory_test())
|
||||
});
|
||||
c.bench_function("ccall_memory_test", |b| b.iter(|| ccall_memory_test()));
|
||||
}
|
||||
|
||||
criterion_group!(benches, basic_usage_benchmark);
|
||||
criterion_main!(benches);
|
||||
@@ -1,136 +0,0 @@
|
||||
#[macro_use]
|
||||
extern crate criterion;
|
||||
extern crate blockstack_lib;
|
||||
extern crate rand;
|
||||
|
||||
use blockstack_lib::chainstate::stacks::Error;
|
||||
use blockstack_lib::types::proof::ClarityMarfTrieId;
|
||||
use criterion::Criterion;
|
||||
use rand::prelude::*;
|
||||
use std::fs;
|
||||
|
||||
use blockstack_lib::chainstate::stacks::index::{marf::MARF, storage::TrieFileStorage};
|
||||
use blockstack_lib::types::chainstate::{MARFValue, StacksBlockId};
|
||||
|
||||
pub fn begin(
|
||||
marf: &mut MARF<StacksBlockId>,
|
||||
chain_tip: &StacksBlockId,
|
||||
next_chain_tip: &StacksBlockId,
|
||||
) -> Result<(), Error> {
|
||||
let mut tx = marf.begin_tx()?;
|
||||
tx.begin(chain_tip, next_chain_tip)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn benchmark_marf_usage(
|
||||
filename: &str,
|
||||
blocks: u32,
|
||||
writes_per_block: u32,
|
||||
reads_per_block: u32,
|
||||
batch: bool,
|
||||
) {
|
||||
if fs::metadata(filename).is_ok() {
|
||||
fs::remove_file(filename).unwrap();
|
||||
};
|
||||
let f = TrieFileStorage::open(filename).unwrap();
|
||||
let mut block_header = StacksBlockId::from_bytes(&[0u8; 32]).unwrap();
|
||||
let mut marf = MARF::from_storage(f);
|
||||
|
||||
begin(&mut marf, &StacksBlockId::sentinel(), &block_header).unwrap();
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let mut values = vec![];
|
||||
|
||||
for i in 0..blocks {
|
||||
if batch {
|
||||
let mut batch_keys = Vec::new();
|
||||
let mut batch_vals = Vec::new();
|
||||
for k in 0..writes_per_block {
|
||||
let key = format!("{}::{}", i, k);
|
||||
let mut value = [0u8; 40];
|
||||
rng.fill_bytes(&mut value);
|
||||
batch_keys.push(key.clone());
|
||||
batch_vals.push(MARFValue(value.clone()));
|
||||
values.push((key, MARFValue(value)));
|
||||
}
|
||||
marf.insert_batch(&batch_keys, batch_vals).unwrap();
|
||||
} else {
|
||||
for k in 0..writes_per_block {
|
||||
let key = format!("{}::{}", i, k);
|
||||
let mut value = [0u8; 40];
|
||||
rng.fill_bytes(&mut value);
|
||||
marf.insert(&key, MARFValue(value.clone())).unwrap();
|
||||
values.push((key, MARFValue(value)));
|
||||
}
|
||||
}
|
||||
|
||||
for _k in 0..reads_per_block {
|
||||
let (key, value) = values.as_slice().choose(&mut rng).unwrap();
|
||||
assert_eq!(
|
||||
marf.get_with_proof(&block_header, key).unwrap().unwrap().0,
|
||||
*value
|
||||
);
|
||||
}
|
||||
|
||||
let mut next_block_header = (i + 1).to_le_bytes().to_vec();
|
||||
next_block_header.resize(32, 0);
|
||||
let next_block_header = StacksBlockId::from_bytes(next_block_header.as_slice()).unwrap();
|
||||
|
||||
marf.commit().unwrap();
|
||||
begin(&mut marf, &block_header, &next_block_header).unwrap();
|
||||
block_header = next_block_header;
|
||||
}
|
||||
marf.commit().unwrap();
|
||||
}
|
||||
|
||||
fn benchmark_marf_read(filename: &str, reads: u32, block: u32, writes_per_block: u32) {
|
||||
let f = TrieFileStorage::open(filename).unwrap();
|
||||
let mut block_header = block.to_le_bytes().to_vec();
|
||||
block_header.resize(32, 0);
|
||||
let block_header = StacksBlockId::from_bytes(block_header.as_slice()).unwrap();
|
||||
|
||||
let mut marf = MARF::from_storage(f);
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
for _i in 0..reads {
|
||||
let i: u32 = rng.gen_range(0, block);
|
||||
let k: u32 = rng.gen_range(0, writes_per_block);
|
||||
let key = format!("{}::{}", i, k);
|
||||
marf.get_with_proof(&block_header, &key).unwrap().unwrap().0;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn basic_usage_benchmark(c: &mut Criterion) {
|
||||
c.bench_function("marf_setup_1000b_5kW", |b| {
|
||||
b.iter(|| benchmark_marf_usage("/tmp/db.1k.sqlite", 1000, 5000, 0, false))
|
||||
});
|
||||
c.bench_function("marf_setup_400b_5kW", |b| {
|
||||
b.iter(|| benchmark_marf_usage("/tmp/db.400.sqlite", 1000, 5000, 0, false))
|
||||
});
|
||||
c.bench_function("marf_read_1000b_1kW", |b| {
|
||||
b.iter(|| benchmark_marf_read("/tmp/db.1k.sqlite", 1000, 1000, 5000))
|
||||
});
|
||||
c.bench_function("marf_read_400b_1kW", |b| {
|
||||
b.iter(|| benchmark_marf_read("/tmp/db.400.sqlite", 1000, 400, 5000))
|
||||
});
|
||||
|
||||
c.bench_function("marf_usage_1b_10kW_0kR", |b| {
|
||||
b.iter(|| benchmark_marf_usage("/tmp/foo.bar.z.sqlite", 1, 10000, 0, false))
|
||||
});
|
||||
c.bench_function("marf_usage_10b_1kW_2kR", |b| {
|
||||
b.iter(|| benchmark_marf_usage("/tmp/foo.bar.z.sqlite", 10, 1000, 2000, false))
|
||||
});
|
||||
c.bench_function("marf_usage_100b_5kW_20kR", |b| {
|
||||
b.iter(|| benchmark_marf_usage("/tmp/foo.bar.z.sqlite", 20, 5000, 20000, false))
|
||||
});
|
||||
c.bench_function("marf_usage_batches_10b_1kW_2kR", |b| {
|
||||
b.iter(|| benchmark_marf_usage("/tmp/foo.bar.z.sqlite", 10, 1000, 2000, true))
|
||||
});
|
||||
}
|
||||
|
||||
pub fn scaling_read_ratio(_c: &mut Criterion) {}
|
||||
|
||||
criterion_group!(benches, basic_usage_benchmark);
|
||||
criterion_main!(benches);
|
||||
Reference in New Issue
Block a user