Skip to content

Commit 190c41c

Browse files
committed
remove script cache
1 parent 2df18d9 commit 190c41c

10 files changed

+37
-147
lines changed

Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ log = "0.4"
2525
simple_logger = "0.5.0"
2626
rusqlite = { version = "0.13.0", features = ["bundled"] }
2727
byteorder = "1.2"
28-
lru-cache = "0.1.1"
2928
rayon = "1.0.3"
3029
futures={ git= "https://github.com/tamasblummer/futures-rs.git", tag = "0.2.1" }
3130
futures-timer= { git= "https://github.com/tamasblummer/futures-timer.git", branch = "futures_0.2.1" }

src/bin/client.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ pub fn main() {
6969
}
7070
}
7171

72-
let cache = 0;
73-
7472
let mut peers = get_peers();
7573
if peers.is_empty () {
7674
peers.push(SocketAddr::from(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8333)));
@@ -82,10 +80,10 @@ pub fn main() {
8280
let mut spv;
8381
let listen = get_listeners();
8482
if let Some(path) = find_arg("db") {
85-
spv = Constructor::new("/https://github.com/rust-bitcoin/rust-bitcoin-spv/".to_string(), network, Path::new(path.as_str()), listen, false,cache).unwrap();
83+
spv = Constructor::new("/https://github.com/rust-bitcoin/rust-bitcoin-spv/".to_string(), network, Path::new(path.as_str()), listen, false).unwrap();
8684
}
8785
else {
88-
spv = Constructor::new("/https://github.com/rust-bitcoin/rust-bitcoin-spv/".to_string(), network, Path::new("client.db"), listen, false,cache).unwrap();
86+
spv = Constructor::new("/https://github.com/rust-bitcoin/rust-bitcoin-spv/".to_string(), network, Path::new("client.db"), listen, false).unwrap();
8987
}
9088
spv.run(peers, connections, true).expect("can not start SPV");
9189
}

src/bin/server.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,12 @@ pub fn main() {
3939
println!("--network net: net is one of main|test for corresponding Bitcoin networks");
4040
println!("--listen ip_address:port : accept incoming connection requests");
4141
println!("--nodns : do not use dns seed");
42-
println!("--cache : cache of utxo in millions - set it up to 60 if doing initial load and you have plenty of RAM");
4342
println!("defaults:");
4443
println!("--db server.db");
4544
println!("--log debug");
4645
println!("--listen 127.0.0.1:8333");
4746
println!("--connections 1");
4847
println!("--network main");
49-
println!("--cache 1");
5048
println!("in memory database");
5149
return;
5250
}
@@ -73,11 +71,6 @@ pub fn main() {
7371
}
7472
}
7573

76-
let mut cache = 1024usize *1024usize;
77-
if let Some(numstring) = find_arg("cache") {
78-
cache *= numstring.parse::<usize>().unwrap() as usize;
79-
}
80-
8174
let peers = get_peers();
8275
let mut connections = 1;
8376
if let Some(numstring) = find_arg("connections") {
@@ -89,10 +82,10 @@ pub fn main() {
8982
listen.push(SocketAddr::from(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8333)));
9083
}
9184
if let Some(path) = find_arg("db") {
92-
spv = Constructor::new("/https://github.com/rust-bitcoin/rust-bitcoin-spv/".to_string(), network, Path::new(path.as_str()), listen, true, cache).unwrap();
85+
spv = Constructor::new("/https://github.com/rust-bitcoin/rust-bitcoin-spv/".to_string(), network, Path::new(path.as_str()), listen, true).unwrap();
9386
}
9487
else {
95-
spv = Constructor::new("/https://github.com/rust-bitcoin/rust-bitcoin-spv/".to_string(), network, Path::new("server.db"), listen, true, cache).unwrap();
88+
spv = Constructor::new("/https://github.com/rust-bitcoin/rust-bitcoin-spv/".to_string(), network, Path::new("server.db"), listen, true).unwrap();
9689
}
9790
spv.run(peers, connections, find_opt("nodns")).expect("can not start SPV");
9891
}

src/blockfilter.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ pub struct BlockFilter {
5959

6060
impl BlockFilter {
6161

62-
pub fn compute_script_filter(block: &Block, utxo: impl ScriptAccessor) -> Result<BlockFilter, SPVError> {
62+
pub fn compute_script_filter(block: &Block, height: u32, script_accessor: impl ScriptAccessor) -> Result<BlockFilter, SPVError> {
6363
let mut bytes = Vec::new();
6464
let mut out = Cursor::new(&mut bytes);
6565
{
6666
let mut writer = BlockFilterWriter::new(&mut out, block);
67-
writer.script_filter(utxo)?;
67+
writer.script_filter(height, script_accessor)?;
6868
writer.finish()?;
6969
}
7070
Ok(BlockFilter{block: block.bitcoin_hash(), filter_type: SCRIPT_FILTER, content: out.into_inner().to_vec()})
@@ -108,7 +108,7 @@ impl <'a> BlockFilterWriter<'a> {
108108
}
109109

110110
/// Add consumed output scripts of a block to filter
111-
fn add_consumed_scripts (&mut self, tx_accessor: impl ScriptAccessor) -> Result<(), SPVError> {
111+
fn add_consumed_scripts (&mut self, height: u32, tx_accessor: impl ScriptAccessor) -> Result<(), SPVError> {
112112
let mut coins = Vec::new();
113113
for transaction in &self.block.txdata {
114114
if !transaction.is_coin_base() {
@@ -117,16 +117,16 @@ impl <'a> BlockFilterWriter<'a> {
117117
}
118118
}
119119
}
120-
for script in tx_accessor.get_scripts(coins)? {
120+
for script in tx_accessor.get_scripts(height, coins)? {
121121
self.writer.add_element(script.as_bytes());
122122
}
123123
Ok(())
124124
}
125125

126126
/// compile a filter useful for wallets
127-
pub fn script_filter(&mut self, tx_accessor: impl ScriptAccessor) -> Result<(), SPVError> {
127+
pub fn script_filter(&mut self, height: u32, tx_accessor: impl ScriptAccessor) -> Result<(), SPVError> {
128128
self.add_output_scripts();
129-
self.add_consumed_scripts(tx_accessor)
129+
self.add_consumed_scripts(height, tx_accessor)
130130
}
131131

132132
/// compile a filter useful to find spent outputs
@@ -432,7 +432,7 @@ mod test {
432432
}
433433

434434
impl ScriptAccessor for HashMap<OutPoint, Script> {
435-
fn get_scripts(&self, coins: Vec<OutPoint>) -> Result<Vec<Script>, SPVError> {
435+
fn get_scripts(&self, _: u32, coins: Vec<OutPoint>) -> Result<Vec<Script>, SPVError> {
436436
let mut result = Vec::new();
437437
for coin in coins {
438438
if let Some(ux) = self.get(&coin) {
@@ -483,7 +483,7 @@ mod test {
483483
let mut constructed_filter = Cursor::new(Vec::new());
484484
{
485485
let mut writer = BlockFilterWriter::new(&mut constructed_filter, &block);
486-
writer.script_filter(txmap).unwrap();
486+
writer.script_filter(0, txmap).unwrap();
487487
writer.finish().unwrap();
488488
}
489489

src/chaindb.rs

+16-47
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ use error::SPVError;
3535
use filtercache::FilterCache;
3636
use headercache::{HeaderCache, HeaderIterator};
3737
use blockfilter::{BlockFilter, BlockFilterReader, COIN_FILTER, SCRIPT_FILTER};
38-
use scriptcache::ScriptCache;
3938

4039
use hammersbald::{
4140
BitcoinAdaptor, HammersbaldAPI, persistent, PRef,
@@ -60,38 +59,35 @@ pub struct ChainDB {
6059
heavy: Option<BitcoinAdaptor>,
6160
headercache: HeaderCache,
6261
filtercache: FilterCache,
63-
scriptcache: Mutex<ScriptCache>,
6462
network: Network,
6563
}
6664

6765
impl ChainDB {
6866
/// Create an in-memory database instance
69-
pub fn mem(network: Network, heavy: bool, server: bool, script_cache_size: usize) -> Result<ChainDB, SPVError> {
67+
pub fn mem(network: Network, heavy: bool, server: bool) -> Result<ChainDB, SPVError> {
7068
info!("working with in memory chain db");
7169
let light = BitcoinAdaptor::new(transient(2)?);
7270
let headercache = HeaderCache::new(network);
7371
let filtercache = FilterCache::new(server);
74-
let scriptcache = Mutex::new(ScriptCache::new(script_cache_size));
7572
if heavy {
7673
let heavy = Some(BitcoinAdaptor::new(transient(2)?));
77-
Ok(ChainDB { light, heavy, network, headercache, filtercache, scriptcache })
74+
Ok(ChainDB { light, heavy, network, headercache, filtercache })
7875
} else {
79-
Ok(ChainDB { light, heavy: None, network, headercache, filtercache, scriptcache })
76+
Ok(ChainDB { light, heavy: None, network, headercache, filtercache })
8077
}
8178
}
8279

8380
/// Create or open a persistent database instance identified by the path
84-
pub fn new(path: &Path, network: Network, heavy: bool, server: bool, script_cache_size: usize) -> Result<ChainDB, SPVError> {
81+
pub fn new(path: &Path, network: Network, heavy: bool, server: bool) -> Result<ChainDB, SPVError> {
8582
let basename = path.to_str().unwrap().to_string();
8683
let light = BitcoinAdaptor::new(persistent((basename.clone() + ".h").as_str(), 100, 2)?);
8784
let headercache = HeaderCache::new(network);
8885
let filtercache = FilterCache::new(server);
89-
let scriptcache = Mutex::new(ScriptCache::new(script_cache_size));
9086
if heavy {
9187
let heavy = Some(BitcoinAdaptor::new(persistent((basename + ".b").as_str(), 1000, 2)?));
92-
Ok(ChainDB { light, heavy, network, headercache, filtercache, scriptcache })
88+
Ok(ChainDB { light, heavy, network, headercache, filtercache })
9389
} else {
94-
Ok(ChainDB { light, heavy: None, network, headercache, filtercache, scriptcache })
90+
Ok(ChainDB { light, heavy: None, network, headercache, filtercache })
9591
}
9692
}
9793

@@ -322,44 +318,17 @@ impl ChainDB {
322318
panic!("should not call store block before header is known {}", block.bitcoin_hash());
323319
}
324320

325-
pub fn cache_scripts(&mut self, block: &Block, height: u32) {
326-
let block_id = Arc::new(block.bitcoin_hash());
327-
let mut script_cache = self.scriptcache.lock().unwrap();
328-
for (i, tx) in block.txdata.iter().enumerate() {
329-
let tx_nr = i as u32;
330-
let txid = tx.txid();
331-
for (idx, output) in tx.output.iter().enumerate() {
332-
let vout = idx as u32;
333-
if !output.script_pubkey.is_provably_unspendable() {
334-
script_cache.insert(OutPoint{txid, vout}, output.script_pubkey.clone(), height);
335-
}
336-
}
337-
}
338-
}
339-
340-
pub fn get_scripts(&self, coins: Vec<OutPoint>, mut sofar: Vec<Script>) -> Result<Vec<Script>, SPVError> {
341-
let mut remains = Vec::with_capacity(coins.len());
342-
{
343-
// check in script cache
344-
let mut scriptcache = self.scriptcache.lock().unwrap();
345-
for coin in coins {
346-
if let Some(script) = scriptcache.remove(&coin) {
347-
sofar.push(script);
348-
}
349-
else {
350-
let mut buf = Vec::new();
351-
coin.consensus_encode(&mut buf)?;
352-
remains.push(buf);
353-
}
354-
}
355-
}
321+
pub fn get_scripts(&self, height: u32, coins: Vec<OutPoint>, mut sofar: Vec<Script>) -> Result<Vec<Script>, SPVError> {
322+
let mut remains = coins.iter().map(|coin| {
323+
let mut buf = Vec::new();
324+
coin.consensus_encode(&mut buf).unwrap();
325+
buf
326+
}).collect::<Vec<_>>();
356327
remains.sort();
357328
if remains.len() > 0 {
358-
let from = self.scriptcache.lock().unwrap().complete_after();
359-
360329
let mapped = remains.par_chunks(100).map(|remains| {
361330
let remains = remains.to_vec();
362-
self.resolve_with_filters(from, remains)
331+
self.resolve_with_filters(height, remains)
363332
}).flatten().collect::<Vec<_>>();
364333
sofar.extend (mapped);
365334
}
@@ -592,11 +561,11 @@ impl<'a> DBScriptAccessor<'a> {
592561

593562

594563
pub trait ScriptAccessor {
595-
fn get_scripts(&self, coins: Vec<OutPoint>) -> Result<Vec<Script>, SPVError>;
564+
fn get_scripts(&self, height: u32, coins: Vec<OutPoint>) -> Result<Vec<Script>, SPVError>;
596565
}
597566

598567
impl<'a> ScriptAccessor for DBScriptAccessor<'a> {
599-
fn get_scripts(&self, coins: Vec<OutPoint>) -> Result<Vec<Script>, SPVError> {
568+
fn get_scripts(&self, height: u32, coins: Vec<OutPoint>) -> Result<Vec<Script>, SPVError> {
600569
let mut sofar = Vec::with_capacity(coins.len());
601570
let mut remains = Vec::with_capacity(coins.len());
602571
for coin in coins {
@@ -607,6 +576,6 @@ impl<'a> ScriptAccessor for DBScriptAccessor<'a> {
607576
remains.push(coin);
608577
}
609578
}
610-
self.db.get_scripts(remains, sofar)
579+
self.db.get_scripts(height, remains, sofar)
611580
}
612581
}

src/constructor.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ impl Constructor {
8585
/// db - file path to data
8686
/// The method will read previously stored headers from the database and sync up with the peers
8787
/// then serve the returned ChainWatchInterface
88-
pub fn new(user_agent :String, network: Network, path: &Path, listen: Vec<SocketAddr>, server: bool, script_cache_size: usize) -> Result<Constructor, SPVError> {
88+
pub fn new(user_agent :String, network: Network, path: &Path, listen: Vec<SocketAddr>, server: bool) -> Result<Constructor, SPVError> {
8989
let configdb = Arc::new(Mutex::new(ConfigDB::new(path)?));
90-
let chaindb = Arc::new(RwLock::new(ChainDB::new(path, network,server, server, script_cache_size)?));
90+
let chaindb = Arc::new(RwLock::new(ChainDB::new(path, network,server, server)?));
9191
create_tables(configdb.clone())?;
9292
Ok(Constructor { network, user_agent, configdb, chaindb, listen, server, connector: None })
9393
}
@@ -98,9 +98,9 @@ impl Constructor {
9898
/// bootstrap - peer adresses (only tested to work with one local node for now)
9999
/// The method will start with an empty in-memory database and sync up with the peers
100100
/// then serve the returned ChainWatchInterface
101-
pub fn new_in_memory(user_agent :String, network: Network, listen: Vec<SocketAddr>, server: bool, script_cache_size: usize) -> Result<Constructor, SPVError> {
101+
pub fn new_in_memory(user_agent :String, network: Network, listen: Vec<SocketAddr>, server: bool) -> Result<Constructor, SPVError> {
102102
let configdb = Arc::new(Mutex::new(ConfigDB::mem()?));
103-
let chaindb = Arc::new(RwLock::new(ChainDB::mem( network,server, server, script_cache_size)?));
103+
let chaindb = Arc::new(RwLock::new(ChainDB::mem( network,server, server)?));
104104
create_tables(configdb.clone())?;
105105
Ok(Constructor { network, user_agent, configdb, chaindb, listen, server, connector: None })
106106
}

src/filtercalculator.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,9 @@ impl FilterCalculator {
159159
if missing.last().is_some() && *missing.last().unwrap() == genesis.bitcoin_hash() {
160160
let mut chaindb = self.chaindb.write().unwrap();
161161
let block_ref = chaindb.store_block(&genesis)?;
162-
let script_filter = BlockFilter::compute_script_filter(&genesis, chaindb.get_script_accessor(&genesis))?;
162+
let script_filter = BlockFilter::compute_script_filter(&genesis, 0, chaindb.get_script_accessor(&genesis))?;
163163
let coin_filter = BlockFilter::compute_coin_filter(&genesis)?;
164164
chaindb.store_known_filter(&Sha256dHash::default(), &Sha256dHash::default(), &script_filter, &coin_filter)?;
165-
chaindb.cache_scripts(&genesis, 0);
166165
chaindb.batch()?;
167166
let len = missing.len();
168167
missing.truncate(len - 1);
@@ -195,17 +194,15 @@ impl FilterCalculator {
195194
if let Some(header) = chaindb.get_header(&block_id) {
196195
// do not store fake blocks
197196
if block.check_merkle_root() && block.check_witness_commitment() {
198-
// cache output scripts for later calculation
199-
chaindb.cache_scripts(block, header.height);
200197
// if this is the next block for filter calculation
201198
if let Some(prev_script) = chaindb.get_block_filter(&block.header.prev_blockhash, SCRIPT_FILTER) {
202199
if let Some(prev_coin) = chaindb.get_block_filter(&block.header.prev_blockhash, COIN_FILTER) {
200+
// calculate filters
201+
let script_filter = BlockFilter::compute_script_filter(&block, header.height, chaindb.get_script_accessor(block))?;
202+
let coin_filter = BlockFilter::compute_coin_filter(&block)?;
203203
// store block
204204
debug!("store block {} {} peer={}", header.height, block_id, peer);
205205
chaindb.store_block(block)?;
206-
// calculate filters
207-
let script_filter = BlockFilter::compute_script_filter(&block, chaindb.get_script_accessor(block))?;
208-
let coin_filter = BlockFilter::compute_coin_filter(&block)?;
209206
debug!("store filter {} {} size: {} {} peer={}", header.height, block_id, script_filter.content.len(), coin_filter.content.len(), peer);
210207
// store known filters into header
211208
chaindb.store_known_filter(&prev_script.bitcoin_hash(), &prev_coin.bitcoin_hash(), &script_filter, &coin_filter)?;

src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,13 @@ extern crate log;
3737
extern crate rand;
3838
extern crate rusqlite;
3939
extern crate siphasher;
40-
extern crate lru_cache;
4140
extern crate futures;
4241
extern crate futures_timer;
4342

4443
mod filterdownload;
4544
mod ping;
4645
mod timeout;
4746
mod blockserver;
48-
mod scriptcache;
4947
mod filterserver;
5048
mod headerdownload;
5149
mod headercache;

src/scriptcache.rs

-64
This file was deleted.

0 commit comments

Comments
 (0)