Support for --pruning=auto.

This commit is contained in:
Gav Wood 2016-04-11 15:51:14 -07:00
parent 3fe21f5931
commit 6e97496b27
6 changed files with 58 additions and 4 deletions

View File

@ -126,11 +126,11 @@ Networking Options:
API and Console Options: API and Console Options:
-j --jsonrpc Enable the JSON-RPC API server. -j --jsonrpc Enable the JSON-RPC API server.
--jsonrpc-port PORT Specify the port portion of the JSONRPC API server
[default: 8545].
--jsonrpc-interface IP Specify the hostname portion of the JSONRPC API --jsonrpc-interface IP Specify the hostname portion of the JSONRPC API
server, IP should be an interface's IP address, or server, IP should be an interface's IP address, or
all (all interfaces) or local [default: local]. all (all interfaces) or local [default: local].
--jsonrpc-port PORT Specify the port portion of the JSONRPC API server
[default: 8545].
--jsonrpc-cors URL Specify CORS header for JSON-RPC API responses --jsonrpc-cors URL Specify CORS header for JSON-RPC API responses
[default: null]. [default: null].
--jsonrpc-apis APIS Specify the APIs available through the JSONRPC --jsonrpc-apis APIS Specify the APIs available through the JSONRPC
@ -169,8 +169,14 @@ Sealing/Mining Options:
Footprint Options: Footprint Options:
--pruning METHOD Configure pruning of the state/storage trie. METHOD --pruning METHOD Configure pruning of the state/storage trie. METHOD
may be one of: archive, basic (experimental), fast may be one of auto, archive, basic, fast, light:
(experimental) [default: archive]. archive - keep all state trie data. No pruning.
basic - reference count in disk DB. Slow but light.
fast - maintain journal overlay. Fast but 50MB used.
light - early merges with partial tracking. Fast
and light. Experimental!
auto - use the method most recently synced or
default to archive if none synced [default: auto].
--cache-pref-size BYTES Specify the prefered size of the blockchain cache in --cache-pref-size BYTES Specify the prefered size of the blockchain cache in
bytes [default: 16384]. bytes [default: 16384].
--cache-max-size BYTES Specify the maximum size of the blockchain cache in --cache-max-size BYTES Specify the maximum size of the blockchain cache in
@ -536,6 +542,23 @@ impl Configuration {
ret ret
} }
fn find_best_db(path: &str) -> Option<journaldb::Algorithm> {
let mut ret = None;
let mut latest_era = None;
for i in [journaldb::Algorithm::Archive, journaldb::Algorithm::EarlyMerge, journaldb::Algorithm::OverlayRecent, journaldb::Algorithm::RefCounted].into_iter() {
let db = journaldb::new(path, i);
match (latest_era, db.latest_era()) {
(Some(best), Some(this)) if best >= this => {}
(_, None) => {}
(_, Some(this)) => {
latest_era = Some(this);
ret = Some(i);
}
}
}
ret
}
fn client_config(&self) -> ClientConfig { fn client_config(&self) -> ClientConfig {
let mut client_config = ClientConfig::default(); let mut client_config = ClientConfig::default();
match self.args.flag_cache { match self.args.flag_cache {
@ -553,6 +576,7 @@ impl Configuration {
"light" => journaldb::Algorithm::EarlyMerge, "light" => journaldb::Algorithm::EarlyMerge,
"fast" => journaldb::Algorithm::OverlayRecent, "fast" => journaldb::Algorithm::OverlayRecent,
"basic" => journaldb::Algorithm::RefCounted, "basic" => journaldb::Algorithm::RefCounted,
"auto" => Self::find_best_db().unwrap_or(journaldb::Algorithm::OverlayRecent),
_ => { die!("Invalid pruning method given."); } _ => { die!("Invalid pruning method given."); }
}; };
client_config.name = self.args.flag_identity.clone(); client_config.name = self.args.flag_identity.clone();

View File

@ -168,6 +168,8 @@ impl JournalDB for ArchiveDB {
Ok((inserts + deletes) as u32) Ok((inserts + deletes) as u32)
} }
fn latest_era() -> Option<u64> { self.latest_era }
fn state(&self, id: &H256) -> Option<Bytes> { fn state(&self, id: &H256) -> Option<Bytes> {
self.backing.get_by_prefix(&id.bytes()[0..12]).and_then(|b| Some(b.to_vec())) self.backing.get_by_prefix(&id.bytes()[0..12]).and_then(|b| Some(b.to_vec()))
} }

View File

@ -333,6 +333,8 @@ impl JournalDB for EarlyMergeDB {
self.backing.get(&LATEST_ERA_KEY).expect("Low level database error").is_none() self.backing.get(&LATEST_ERA_KEY).expect("Low level database error").is_none()
} }
fn latest_era() -> Option<u64> { self.latest_era }
fn mem_used(&self) -> usize { fn mem_used(&self) -> usize {
self.overlay.mem_used() + match self.refs { self.overlay.mem_used() + match self.refs {
Some(ref c) => c.read().unwrap().heap_size_of_children(), Some(ref c) => c.read().unwrap().heap_size_of_children(),

View File

@ -213,6 +213,8 @@ impl JournalDB for OverlayRecentDB {
self.backing.get(&LATEST_ERA_KEY).expect("Low level database error").is_none() self.backing.get(&LATEST_ERA_KEY).expect("Low level database error").is_none()
} }
fn latest_era() -> Option<u64> { self.latest_era }
fn commit(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> { fn commit(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
// record new commit's details. // record new commit's details.
trace!("commit: #{} ({}), end era: {:?}", now, id, end); trace!("commit: #{} ({}), end era: {:?}", now, id, end);

View File

@ -112,6 +112,8 @@ impl JournalDB for RefCountedDB {
self.latest_era.is_none() self.latest_era.is_none()
} }
fn latest_era() -> Option<u64> { self.latest_era }
fn commit(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> { fn commit(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError> {
// journal format: // journal format:
// [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ] // [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ]
@ -220,6 +222,25 @@ mod tests {
assert!(!jdb.exists(&h)); assert!(!jdb.exists(&h));
} }
#[test]
fn latest_era_should_work() {
// history is 3
let mut jdb = RefCountedDB::new_temp();
assert_eq!(jdb.latest_era(), None);
let h = jdb.insert(b"foo");
jdb.commit(0, &b"0".sha3(), None).unwrap();
assert_eq!(jdb.latest_era(), Some(0));
jdb.remove(&h);
jdb.commit(1, &b"1".sha3(), None).unwrap();
assert_eq!(jdb.latest_era(), Some(1));
jdb.commit(2, &b"2".sha3(), None).unwrap();
assert_eq!(jdb.latest_era(), Some(2));
jdb.commit(3, &b"3".sha3(), Some((0, b"0".sha3()))).unwrap();
assert_eq!(jdb.latest_era(), Some(3));
jdb.commit(4, &b"4".sha3(), Some((1, b"1".sha3()))).unwrap();
assert_eq!(jdb.latest_era(), Some(4));
}
#[test] #[test]
fn complex() { fn complex() {
// history is 1 // history is 1

View File

@ -31,6 +31,9 @@ pub trait JournalDB : HashDB + Send + Sync {
/// Check if this database has any commits /// Check if this database has any commits
fn is_empty(&self) -> bool; fn is_empty(&self) -> bool;
/// Get the latest era in the DB. None if there isn't yet any data in there.
fn latest_era() -> Option<u64> { self.latest_era }
/// Commit all recent insert operations and canonical historical commits' removals from the /// Commit all recent insert operations and canonical historical commits' removals from the
/// old era to the backing database, reverting any non-canonical historical commit's inserts. /// old era to the backing database, reverting any non-canonical historical commit's inserts.
fn commit(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError>; fn commit(&mut self, now: u64, id: &H256, end: Option<(u64, H256)>) -> Result<u32, UtilError>;