utxoset: Fix parallel script checking to use only as many threads as CPUs
This commit is contained in:
parent
fc04462682
commit
c28c261b74
|
@ -18,8 +18,10 @@
|
||||||
//! index of UTXOs.
|
//! index of UTXOs.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
|
use std::cmp;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::os::num_cpus;
|
||||||
use std::sync::Future;
|
use std::sync::Future;
|
||||||
|
|
||||||
use blockdata::transaction::{Transaction, TxOut};
|
use blockdata::transaction::{Transaction, TxOut};
|
||||||
|
@ -207,38 +209,45 @@ impl UtxoSet {
|
||||||
let mut future_vec = Vec::with_capacity(block.txdata.len() - 1);
|
let mut future_vec = Vec::with_capacity(block.txdata.len() - 1);
|
||||||
// skip the genesis since we don't validate this script. (TODO this might
|
// skip the genesis since we don't validate this script. (TODO this might
|
||||||
// be a consensus bug since we don't even check that the opcodes make sense.)
|
// be a consensus bug since we don't even check that the opcodes make sense.)
|
||||||
for tx in block.txdata.iter().skip(1) {
|
let n_threads = cmp::min(block.txdata.len() - 1, num_cpus());
|
||||||
|
for j in range(0, n_threads) {
|
||||||
|
let n_elems = block.txdata.len() - 1;
|
||||||
|
let start = 1 + j * n_elems / n_threads;
|
||||||
|
let end = cmp::min(n_elems, 1 + (j + 1) * n_elems / n_threads);
|
||||||
|
|
||||||
let s = self as *mut _ as *const UtxoSet;
|
let s = self as *mut _ as *const UtxoSet;
|
||||||
let tx = tx as *const _;
|
let txes = &block.txdata as *const _;
|
||||||
future_vec.push(Future::spawn(proc() {
|
future_vec.push(Future::spawn(proc() {
|
||||||
let tx = unsafe {&*tx};
|
let txes = unsafe {&*txes};
|
||||||
for (n, input) in tx.input.iter().enumerate() {
|
for tx in txes.slice(start, end).iter() {
|
||||||
let txo = unsafe { (*s).get_utxo(input.prev_hash, input.prev_index) };
|
for (n, input) in tx.input.iter().enumerate() {
|
||||||
match txo {
|
let txo = unsafe { (*s).get_utxo(input.prev_hash, input.prev_index) };
|
||||||
Some(txo) => {
|
match txo {
|
||||||
let mut stack = Vec::with_capacity(6);
|
Some(txo) => {
|
||||||
if input.script_sig.evaluate(&mut stack, Some((tx, n))).is_err() {
|
let mut stack = Vec::with_capacity(6);
|
||||||
println!("txid was {}", tx.bitcoin_hash());
|
if input.script_sig.evaluate(&mut stack, Some((tx, n))).is_err() {
|
||||||
return false;
|
println!("txid was {}", tx.bitcoin_hash());
|
||||||
}
|
return false;
|
||||||
if txo.script_pubkey.evaluate(&mut stack, Some((tx, n))).is_err() {
|
}
|
||||||
println!("txid was {}", tx.bitcoin_hash());
|
if txo.script_pubkey.evaluate(&mut stack, Some((tx, n))).is_err() {
|
||||||
return false;
|
println!("txid was {}", tx.bitcoin_hash());
|
||||||
}
|
return false;
|
||||||
match stack.pop() {
|
}
|
||||||
Some(v) => {
|
match stack.pop() {
|
||||||
if !read_scriptbool(v.as_slice()) {
|
Some(v) => {
|
||||||
use serialize::json::ToJson;
|
if !read_scriptbool(v.as_slice()) {
|
||||||
println!("txid was {}", tx.bitcoin_hash());
|
use serialize::json::ToJson;
|
||||||
println!("tx was {}", tx.to_json().to_string());
|
println!("txid was {}", tx.bitcoin_hash());
|
||||||
println!("script ended with stack {}", stack);
|
println!("tx was {}", tx.to_json().to_string());
|
||||||
return false;
|
println!("script ended with stack {}", stack);
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => { return false; }
|
||||||
}
|
}
|
||||||
None => { return false; }
|
|
||||||
}
|
}
|
||||||
|
None => { return false; }
|
||||||
}
|
}
|
||||||
None => { return false; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
|
Loading…
Reference in New Issue