Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

bring snapshotting work into master #1577

Merged
merged 87 commits into from
Jul 12, 2016
Merged
Show file tree
Hide file tree
Changes from 82 commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
5e0ba1c
take_snapshot and block chunking skeleton
rphmeier Jun 10, 2016
997fd93
finish implementing basic block chunking
rphmeier Jun 10, 2016
f12add6
take_snapshot now chunks blocks
rphmeier Jun 10, 2016
c6e83ca
fix warning
rphmeier Jun 10, 2016
f689792
added tracing
rphmeier Jun 10, 2016
b047eb2
removed size tolerance
rphmeier Jun 10, 2016
3b1cca5
add manifestdata struct, write manifest file at the end
rphmeier Jun 10, 2016
5c252f2
output manifest to correct file
rphmeier Jun 11, 2016
c9846b8
skeleton for StateChunker
rphmeier Jun 11, 2016
d696a66
add account reader. trie walking not functional yet
rphmeier Jun 13, 2016
e5ca5e0
[REQUIRES DB UPGRADE] have account_db use address hash
rphmeier Jun 13, 2016
d9743f1
AccountReader -> to_fat_rlp implementation
rphmeier Jun 13, 2016
f400da4
state chunk creation tracing
rphmeier Jun 13, 2016
10c2302
create an AccountDB to extract account storage
rphmeier Jun 13, 2016
4ded1cc
chunk remainder at end of each stage
rphmeier Jun 13, 2016
f478812
remove spammy account trace
rphmeier Jun 13, 2016
446d594
io error handling and slight blockchunker refactoring
rphmeier Jun 13, 2016
98c7677
expose only chunk_blocks and chunk_state APIs
rphmeier Jun 13, 2016
6ec282f
Merge with latest master
rphmeier Jun 13, 2016
22a1981
rename pv64 module to snapshot
rphmeier Jun 13, 2016
c36f47b
rename pv64_snapshot trace target to snapshot
rphmeier Jun 13, 2016
5b6ea41
no longer lock the state db
rphmeier Jun 13, 2016
5cc6a68
push pair onto block chunker buffer
rphmeier Jun 13, 2016
835b158
store account code if it exists
rphmeier Jun 13, 2016
b88eef5
use append_empty_data rather than fibbing it
rphmeier Jun 14, 2016
7501300
simple snappy bindings, enabling alloc free code
rphmeier Jun 13, 2016
16e5895
use snappy compression on buffers
rphmeier Jun 13, 2016
dfb603d
compress into reusable buffers
rphmeier Jun 14, 2016
8ed2b9c
refactor out common parts of write_chunk
rphmeier Jun 14, 2016
874bc80
add some missing header setters
rphmeier Jun 14, 2016
3290f39
block rlp compression
rphmeier Jun 14, 2016
17a6092
adjust comments
rphmeier Jun 14, 2016
53b3a6f
use UntrustedRlp in to_block
rphmeier Jun 15, 2016
9badb31
remove snappy_buffer_size constant in favor of max_compressed_len
rphmeier Jun 15, 2016
d26e038
fix bug in account code storage, add to_thin_rlp for AccountReader
rphmeier Jun 15, 2016
a2bb3f2
account storage decoding implemented
rphmeier Jun 15, 2016
d7498c1
rename AccountReader to Account, give a separate module
rphmeier Jun 15, 2016
0e3a15c
add a state rebuilder
rphmeier Jun 15, 2016
25f1f22
use account_pair in feed
rphmeier Jun 15, 2016
b38f335
validate_compressed_buffer binding
rphmeier Jun 15, 2016
7ca5c11
validate all compressed buffers
rphmeier Jun 15, 2016
53db992
alter snappy methods to do vec resizing themselves
rphmeier Jun 16, 2016
0e917b9
use ZST error type for snappy, use new snappy compression methods
rphmeier Jun 16, 2016
ce87691
bump rocksdb version
rphmeier Jun 16, 2016
f45254d
create chunks using append_raw
rphmeier Jun 16, 2016
e4867d7
properly rebuild state trie
rphmeier Jun 16, 2016
f3c1643
encode the account storage rlp with "append_raw"
rphmeier Jun 16, 2016
3850ee6
have StateRebuilder take a JournalDB and commit post-chunk
rphmeier Jun 17, 2016
49024a4
Merge with master
rphmeier Jun 29, 2016
6977d33
Merge branch 'master' into pv64
rphmeier Jun 29, 2016
6ecd6ea
batch state trie writes
rphmeier Jun 29, 2016
4566190
parallelize account trie creation
rphmeier Jun 30, 2016
d42ea6b
modify account_db to work on address hash, not address
rphmeier Jul 1, 2016
601ebcf
add a database migration for new accountdb
rphmeier Jul 4, 2016
465aae7
merge branch accountdb_migration into pv64
rphmeier Jul 4, 2016
2ea7a8d
partially done alternate migration scheme
rphmeier Jul 1, 2016
1b759c1
finish altering migration framework
rphmeier Jul 5, 2016
d4c9c7c
migrate tests to new migration framework
rphmeier Jul 5, 2016
fd62944
address comments
rphmeier Jul 5, 2016
908104e
remove superfluous newline
rphmeier Jul 6, 2016
21d5e10
TempIdx -> TempIndex
rphmeier Jul 6, 2016
7df0aa2
modify account_db to work on address hash, not address
rphmeier Jul 1, 2016
9b28e97
add a database migration for new accountdb
rphmeier Jul 4, 2016
0bbdcb1
preserve first 96 bits of keys when combining
rphmeier Jul 4, 2016
e411399
handle metadata keys in migration and preserve first 96 bits
rphmeier Jul 4, 2016
e151fbb
fix comments and hash address instead of hash
rphmeier Jul 4, 2016
a7103e2
different migrations based on pruning
rphmeier Jul 5, 2016
aaad0e8
merge with latest master
rphmeier Jul 6, 2016
3e61d6f
migrations mutably borrow self
rphmeier Jul 8, 2016
a160ada
batch abstraction for migration
rphmeier Jul 8, 2016
fe027e8
added missing licence headers
rphmeier Jul 8, 2016
171e937
overlay recent v7 migration
rphmeier Jul 8, 2016
aaf9490
Merge branch 'master' into accountdb_migration
rphmeier Jul 8, 2016
3b0b137
better error handling, migrate version key as well
rphmeier Jul 8, 2016
274e776
fix migration tests
rphmeier Jul 8, 2016
1f88525
commit final batch and migrate journaled insertions
rphmeier Jul 9, 2016
36dfa47
merge accountdb migration
rphmeier Jul 9, 2016
895b027
two passes on journal to migrate all possible deleted keys
rphmeier Jul 9, 2016
c8b5658
merge with master
rphmeier Jul 10, 2016
3dd7ce5
merge accountdb_migration
rphmeier Jul 11, 2016
c7af950
ignore warnings temporarily
rphmeier Jul 11, 2016
b91d339
merge with master
rphmeier Jul 11, 2016
da9e969
remove outdated comment; prove panickers; update manifest
rphmeier Jul 11, 2016
24ec696
rebuild uncles hash from uncle headers
rphmeier Jul 11, 2016
49ba117
add account tests
rphmeier Jul 11, 2016
673cde6
add block tests
rphmeier Jul 11, 2016
4269867
remove unnecessary assertion
rphmeier Jul 11, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use std::path::PathBuf;
use std::collections::{HashSet, HashMap};
use std::ops::Deref;
use std::mem;
use std::collections::VecDeque;
use std::sync::*;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::fmt;
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
use std::time::Instant;
Expand Down
18 changes: 18 additions & 0 deletions ethcore/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ pub enum Error {
PowInvalid,
/// Error concerning TrieDBs
Trie(TrieError),
/// Io error.
Io(::std::io::Error),
/// Snappy error.
Snappy(::util::snappy::InvalidInput),
}

impl fmt::Display for Error {
Expand All @@ -246,6 +250,8 @@ impl fmt::Display for Error {
Error::PowHashInvalid => f.write_str("Invalid or out of date PoW hash."),
Error::PowInvalid => f.write_str("Invalid nonce or mishash"),
Error::Trie(ref err) => f.write_fmt(format_args!("{}", err)),
Error::Io(ref err) => f.write_fmt(format_args!("{}", err)),
Error::Snappy(ref err) => f.write_fmt(format_args!("{}", err)),
}
}
}
Expand Down Expand Up @@ -313,6 +319,18 @@ impl From<TrieError> for Error {
}
}

impl From<::std::io::Error> for Error {
fn from(err: ::std::io::Error) -> Error {
Error::Io(err)
}
}

impl From<::util::snappy::InvalidInput> for Error {
fn from(err: ::util::snappy::InvalidInput) -> Error {
Error::Snappy(err)
}
}

impl From<BlockImportError> for Error {
fn from(err: BlockImportError) -> Error {
match err {
Expand Down
10 changes: 10 additions & 0 deletions ethcore/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@ impl Header {

/// Set the number field of the header.
pub fn set_parent_hash(&mut self, a: H256) { self.parent_hash = a; self.note_dirty(); }
/// Set the uncles hash field of the header.
pub fn set_uncles_hash(&mut self, a: H256) { self.uncles_hash = a; self.note_dirty(); }
/// Set the state root field of the header.
pub fn set_state_root(&mut self, a: H256) { self.state_root = a; self.note_dirty(); }
/// Set the transactions root field of the header.
pub fn set_transactions_root(&mut self, a: H256) { self.transactions_root = a; self.note_dirty() }
/// Set the receipts root field of the header.
pub fn set_receipts_root(&mut self, a: H256) { self.receipts_root = a; self.note_dirty() }
/// Set the log bloom field of the header.
pub fn set_log_bloom(&mut self, a: LogBloom) { self.log_bloom = a; self.note_dirty() }
/// Set the timestamp field of the header.
pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); }
/// Set the timestamp field of the header to the current time.
Expand Down
3 changes: 2 additions & 1 deletion ethcore/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ pub mod pod_state;
pub mod engine;
pub mod migrations;
pub mod miner;
#[macro_use] pub mod evm;
pub mod snapshot;
pub mod action_params;
#[macro_use] pub mod evm;

mod blooms;
mod db;
Expand Down
135 changes: 135 additions & 0 deletions ethcore/src/snapshot/account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

//! Account state encoding and decoding

use account_db::{AccountDB, AccountDBMut};
use error::Error;

use util::{Bytes, HashDB, SHA3_EMPTY, TrieDB};
use util::hash::{FixedHash, H256};
use util::numbers::U256;
use util::rlp::{DecoderError, Rlp, RlpStream, Stream, UntrustedRlp, View};

// An alternate account structure from ::account::Account.
pub struct Account {
nonce: U256,
balance: U256,
storage_root: H256,
code_hash: H256,
}

impl Account {
// decode the account from rlp.
pub fn from_thin_rlp(rlp: &[u8]) -> Self {
let r: Rlp = Rlp::new(rlp);

Account {
nonce: r.val_at(0),
balance: r.val_at(1),
storage_root: r.val_at(2),
code_hash: r.val_at(3),
}
}

// encode the account to a standard rlp.
pub fn to_thin_rlp(&self) -> Bytes {
let mut stream = RlpStream::new_list(4);
stream
.append(&self.nonce)
.append(&self.balance)
.append(&self.storage_root)
.append(&self.code_hash);

stream.out()
}

// walk the account's storage trie, returning an RLP item containing the
// account properties and the storage.
pub fn to_fat_rlp(&self, acct_db: &AccountDB, addr_hash: H256) -> Result<Bytes, Error> {
let db = try!(TrieDB::new(acct_db, &self.storage_root));

let mut pairs = Vec::new();

for (k, v) in db.iter() {
pairs.push((k, v));
}

let mut stream = RlpStream::new_list(pairs.len());

for (k, v) in pairs {
stream.begin_list(2).append(&k).append(&v);
}

let pairs_rlp = stream.out();

let mut account_stream = RlpStream::new_list(5);
account_stream.append(&self.nonce)
.append(&self.balance);

// [has_code, code_hash].
if self.code_hash == SHA3_EMPTY {
account_stream.append(&false).append_empty_data();
} else {
match acct_db.get(&self.code_hash) {
Some(c) => {
account_stream.append(&true).append(&c);
}
None => {
warn!("code lookup failed for account with address hash {}, code hash {}", addr_hash, self.code_hash);
account_stream.append(&false).append_empty_data();
}
}
}

account_stream.append_raw(&pairs_rlp, 1);

Ok(account_stream.out())
}

// decode a fat rlp, and rebuild the storage trie as we go.
pub fn from_fat_rlp(acct_db: &mut AccountDBMut, rlp: UntrustedRlp) -> Result<Self, DecoderError> {
use util::{TrieDBMut, TrieMut};

let nonce = try!(rlp.val_at(0));
let balance = try!(rlp.val_at(1));
let code_hash = if try!(rlp.val_at(2)) {
let code: Bytes = try!(rlp.val_at(3));
acct_db.insert(&code)
} else {
SHA3_EMPTY
};

let mut storage_root = H256::zero();

{
let mut storage_trie = TrieDBMut::new(acct_db, &mut storage_root);
let pairs = try!(rlp.at(4));
for pair_rlp in pairs.iter() {
let k: Bytes = try!(pair_rlp.val_at(0));
let v: Bytes = try!(pair_rlp.val_at(1));

storage_trie.insert(&k, &v);
}
}
Ok(Account {
nonce: nonce,
balance: balance,
storage_root: storage_root,
code_hash: code_hash,
})
}
}
123 changes: 123 additions & 0 deletions ethcore/src/snapshot/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

//! Block RLP compression.

// TODO [rob] remove when BlockRebuilder done.
#![allow(dead_code)]

use block::Block;
use header::Header;

use views::BlockView;
use util::rlp::{DecoderError, RlpStream, Stream, UntrustedRlp, View};
use util::{Bytes, H256};

const HEADER_FIELDS: usize = 11;
const BLOCK_FIELDS: usize = 2;

pub struct AbridgedBlock {
rlp: Bytes,
}

impl AbridgedBlock {
/// Create from a vector of bytes. Does no verification.
pub fn from_raw(rlp: Bytes) -> Self {
AbridgedBlock {
rlp: rlp,
}
}

/// Return the inner bytes.
pub fn into_inner(self) -> Bytes {
self.rlp
}

/// Given a full block view, trim out the parent hash and block number,
/// producing new rlp.
pub fn from_block_view(block_view: &BlockView) -> Self {
let header = block_view.header_view();

let seal_fields = header.seal();

// 11 header fields, unknown amount of seal fields, and 2 block fields.
let mut stream = RlpStream::new_list(
HEADER_FIELDS +
seal_fields.len() +
BLOCK_FIELDS
);

// write header values.
stream
.append(&header.uncles_hash())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uncles hash can be removed as well

.append(&header.author())
.append(&header.state_root())
.append(&header.transactions_root())
.append(&header.receipts_root())
.append(&header.log_bloom())
.append(&header.difficulty())
.append(&header.gas_limit())
.append(&header.gas_used())
.append(&header.timestamp())
.append(&header.extra_data());

// write seal fields.
for field in seal_fields {
stream.append_raw(&field, 1);
}

// write block values.
stream.append(&block_view.transactions()).append(&block_view.uncles());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more optimal to append rlps directly, without converting to transaction/header structure. transactions_rlp and uncles_rlp can be added to BlockView

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we skip a couple of the fields from the header, i think we have to at least decode that.

block chunking is significantly faster than state chunking even so


AbridgedBlock {
rlp: stream.out(),
}
}

/// Flesh out an abridged block view with the provided parent hash and block number.
///
/// Will fail if contains invalid rlp.
pub fn to_block(&self, parent_hash: H256, number: u64) -> Result<Block, DecoderError> {
let rlp = UntrustedRlp::new(&self.rlp);

let mut header = Header {
parent_hash: parent_hash,
uncles_hash: try!(rlp.val_at(0)),
author: try!(rlp.val_at(1)),
state_root: try!(rlp.val_at(2)),
transactions_root: try!(rlp.val_at(3)),
receipts_root: try!(rlp.val_at(4)),
log_bloom: try!(rlp.val_at(5)),
difficulty: try!(rlp.val_at(6)),
number: number,
gas_limit: try!(rlp.val_at(7)),
gas_used: try!(rlp.val_at(8)),
timestamp: try!(rlp.val_at(9)),
extra_data: try!(rlp.val_at(10)),
..Default::default()
};

let seal: Vec<Bytes> = try!(rlp.val_at(11));

header.set_seal(seal);

Ok(Block {
header: header,
transactions: try!(rlp.val_at(12)),
uncles: try!(rlp.val_at(13)),
})
}
}
Loading