refactored blockchain extras keys building
This commit is contained in:
parent
ca4ddfb963
commit
295efdba55
@ -30,6 +30,7 @@ use blockchain::bloom_indexer::BloomIndexer;
|
|||||||
use blockchain::tree_route::TreeRoute;
|
use blockchain::tree_route::TreeRoute;
|
||||||
use blockchain::update::ExtrasUpdate;
|
use blockchain::update::ExtrasUpdate;
|
||||||
use blockchain::{CacheSize, ImportRoute};
|
use blockchain::{CacheSize, ImportRoute};
|
||||||
|
use db::{Writable, Readable, Key};
|
||||||
|
|
||||||
const BLOOM_INDEX_SIZE: usize = 16;
|
const BLOOM_INDEX_SIZE: usize = 16;
|
||||||
const BLOOM_LEVELS: u8 = 3;
|
const BLOOM_LEVELS: u8 = 3;
|
||||||
@ -314,8 +315,8 @@ impl BlockChain {
|
|||||||
bc.blocks_db.put(&hash, genesis).unwrap();
|
bc.blocks_db.put(&hash, genesis).unwrap();
|
||||||
|
|
||||||
let batch = DBTransaction::new();
|
let batch = DBTransaction::new();
|
||||||
batch.put_extras(&hash, &details);
|
batch.write(&hash, &details);
|
||||||
batch.put_extras(&header.number(), &hash);
|
batch.write(&header.number(), &hash);
|
||||||
batch.put(b"best", &hash).unwrap();
|
batch.put(b"best", &hash).unwrap();
|
||||||
bc.extras_db.write(batch).unwrap();
|
bc.extras_db.write(batch).unwrap();
|
||||||
|
|
||||||
@ -467,7 +468,7 @@ impl BlockChain {
|
|||||||
{
|
{
|
||||||
let mut write_details = self.block_details.write().unwrap();
|
let mut write_details = self.block_details.write().unwrap();
|
||||||
for (hash, details) in update.block_details.into_iter() {
|
for (hash, details) in update.block_details.into_iter() {
|
||||||
batch.put_extras(&hash, &details);
|
batch.write(&hash, &details);
|
||||||
self.note_used(CacheID::Extras(ExtrasIndex::BlockDetails, hash.clone()));
|
self.note_used(CacheID::Extras(ExtrasIndex::BlockDetails, hash.clone()));
|
||||||
write_details.insert(hash, details);
|
write_details.insert(hash, details);
|
||||||
}
|
}
|
||||||
@ -476,7 +477,7 @@ impl BlockChain {
|
|||||||
{
|
{
|
||||||
let mut write_receipts = self.block_receipts.write().unwrap();
|
let mut write_receipts = self.block_receipts.write().unwrap();
|
||||||
for (hash, receipt) in &update.block_receipts {
|
for (hash, receipt) in &update.block_receipts {
|
||||||
batch.put_extras(hash, receipt);
|
batch.write(hash, receipt);
|
||||||
write_receipts.remove(hash);
|
write_receipts.remove(hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -484,7 +485,7 @@ impl BlockChain {
|
|||||||
{
|
{
|
||||||
let mut write_blocks_blooms = self.blocks_blooms.write().unwrap();
|
let mut write_blocks_blooms = self.blocks_blooms.write().unwrap();
|
||||||
for (bloom_hash, blocks_bloom) in &update.blocks_blooms {
|
for (bloom_hash, blocks_bloom) in &update.blocks_blooms {
|
||||||
batch.put_extras(bloom_hash, blocks_bloom);
|
batch.write(bloom_hash, blocks_bloom);
|
||||||
write_blocks_blooms.remove(bloom_hash);
|
write_blocks_blooms.remove(bloom_hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -508,12 +509,12 @@ impl BlockChain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (number, hash) in &update.block_hashes {
|
for (number, hash) in &update.block_hashes {
|
||||||
batch.put_extras(number, hash);
|
batch.write(number, hash);
|
||||||
write_hashes.remove(number);
|
write_hashes.remove(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (hash, tx_address) in &update.transactions_addresses {
|
for (hash, tx_address) in &update.transactions_addresses {
|
||||||
batch.put_extras(hash, tx_address);
|
batch.write(hash, tx_address);
|
||||||
write_txs.remove(hash);
|
write_txs.remove(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -747,8 +748,9 @@ impl BlockChain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn query_extras<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> Option<T> where
|
fn query_extras<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> Option<T> where
|
||||||
T: Clone + Decodable + ExtrasIndexable,
|
T: ExtrasIndexable + Clone + Decodable,
|
||||||
K: ExtrasSliceConvertable + Eq + Hash + Clone {
|
K: Key<T> + Eq + Hash + Clone,
|
||||||
|
H256: From<K> {
|
||||||
{
|
{
|
||||||
let read = cache.read().unwrap();
|
let read = cache.read().unwrap();
|
||||||
if let Some(v) = read.get(hash) {
|
if let Some(v) = read.get(hash) {
|
||||||
@ -756,11 +758,9 @@ impl BlockChain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(h) = hash.as_h256() {
|
self.note_used(CacheID::Extras(T::index(), H256::from(hash.clone())));
|
||||||
self.note_used(CacheID::Extras(T::extras_index(), h.clone()));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.extras_db.get_extras(hash).map(| t: T | {
|
self.extras_db.read(hash).map(|t: T| {
|
||||||
let mut write = cache.write().unwrap();
|
let mut write = cache.write().unwrap();
|
||||||
write.insert(hash.clone(), t.clone());
|
write.insert(hash.clone(), t.clone());
|
||||||
t
|
t
|
||||||
@ -768,8 +768,7 @@ impl BlockChain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn query_extras_exist<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> bool where
|
fn query_extras_exist<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> bool where
|
||||||
K: ExtrasSliceConvertable + Eq + Hash + Clone,
|
K: Key<T> + Eq + Hash + Clone {
|
||||||
T: ExtrasIndexable {
|
|
||||||
{
|
{
|
||||||
let read = cache.read().unwrap();
|
let read = cache.read().unwrap();
|
||||||
if let Some(_) = read.get(hash) {
|
if let Some(_) = read.get(hash) {
|
||||||
@ -777,7 +776,7 @@ impl BlockChain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.extras_db.extras_exists::<_, T>(hash)
|
self.extras_db.exists::<T>(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get current cache size.
|
/// Get current cache size.
|
||||||
|
61
ethcore/src/db.rs
Normal file
61
ethcore/src/db.rs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
//! Extras db utils.
|
||||||
|
|
||||||
|
use util::{H264, DBTransaction, Database};
|
||||||
|
use util::rlp::{encode, Encodable, decode, Decodable};
|
||||||
|
|
||||||
|
/// Should be used to get database key associated with given value.
|
||||||
|
pub trait Key<T> {
|
||||||
|
/// Returns db key.
|
||||||
|
fn key(&self) -> H264;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Should be used to write value into database.
|
||||||
|
pub trait Writable {
|
||||||
|
/// Writes key into database.
|
||||||
|
fn write<T>(&self, key: &Key<T>, value: &T) where T: Encodable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Should be used to read values from database.
|
||||||
|
pub trait Readable {
|
||||||
|
/// Returns value for given key.
|
||||||
|
fn read<T>(&self, key: &Key<T>) -> Option<T> where T: Decodable;
|
||||||
|
/// Returns true if given value exists.
|
||||||
|
fn exists<T>(&self, key: &Key<T>) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Writable for DBTransaction {
|
||||||
|
fn write<T>(&self, key: &Key<T>, value: &T) where T: Encodable {
|
||||||
|
self.put(&key.key(), &encode(value))
|
||||||
|
.expect("db put failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Readable for Database {
|
||||||
|
fn read<T>(&self, key: &Key<T>) -> Option<T> where T: Decodable {
|
||||||
|
self.get(&key.key())
|
||||||
|
.expect("db get failed")
|
||||||
|
.map(|v| decode(&v))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exists<T>(&self, key: &Key<T>) -> bool {
|
||||||
|
self.get(&key.key())
|
||||||
|
.expect("db get failed")
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
use util::*;
|
use util::*;
|
||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
use receipt::Receipt;
|
use receipt::Receipt;
|
||||||
|
use db::Key;
|
||||||
|
|
||||||
/// Represents index of extra data in database
|
/// Represents index of extra data in database
|
||||||
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
|
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
|
||||||
@ -37,95 +38,88 @@ pub enum ExtrasIndex {
|
|||||||
BlockReceipts = 5,
|
BlockReceipts = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// trait used to write Extras data to db
|
fn with_index(hash: &H256, i: ExtrasIndex) -> H264 {
|
||||||
pub trait ExtrasWritable {
|
let mut slice = H264::from_slice(hash);
|
||||||
/// Write extra data to db
|
slice[32] = i as u8;
|
||||||
fn put_extras<K, T>(&self, hash: &K, value: &T) where
|
slice
|
||||||
T: ExtrasIndexable + Encodable,
|
|
||||||
K: ExtrasSliceConvertable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// trait used to read Extras data from db
|
|
||||||
pub trait ExtrasReadable {
|
|
||||||
/// Read extra data from db
|
|
||||||
fn get_extras<K, T>(&self, hash: &K) -> Option<T> where
|
|
||||||
T: ExtrasIndexable + Decodable,
|
|
||||||
K: ExtrasSliceConvertable;
|
|
||||||
|
|
||||||
/// Check if extra data exists in the db
|
|
||||||
fn extras_exists<K, T>(&self, hash: &K) -> bool where
|
|
||||||
T: ExtrasIndexable,
|
|
||||||
K: ExtrasSliceConvertable;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExtrasWritable for DBTransaction {
|
|
||||||
fn put_extras<K, T>(&self, hash: &K, value: &T) where
|
|
||||||
T: ExtrasIndexable + Encodable,
|
|
||||||
K: ExtrasSliceConvertable {
|
|
||||||
|
|
||||||
self.put(&hash.to_extras_slice(T::extras_index()), &encode(value)).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExtrasReadable for Database {
|
|
||||||
fn get_extras<K, T>(&self, hash: &K) -> Option<T> where
|
|
||||||
T: ExtrasIndexable + Decodable,
|
|
||||||
K: ExtrasSliceConvertable {
|
|
||||||
|
|
||||||
self.get(&hash.to_extras_slice(T::extras_index())).unwrap()
|
|
||||||
.map(|v| decode(&v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extras_exists<K, T>(&self, hash: &K) -> bool where
|
|
||||||
T: ExtrasIndexable,
|
|
||||||
K: ExtrasSliceConvertable {
|
|
||||||
|
|
||||||
self.get(&hash.to_extras_slice(T::extras_index())).unwrap().is_some()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementations should convert arbitrary type to database key slice
|
|
||||||
pub trait ExtrasSliceConvertable {
|
|
||||||
/// Convert self, with `i` (the index), to a 264-bit extras DB key.
|
|
||||||
fn to_extras_slice(&self, i: ExtrasIndex) -> H264;
|
|
||||||
/// Interpret self as a 256-bit hash, if natively `H256`.
|
|
||||||
fn as_h256(&self) -> Option<&H256> { None }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExtrasSliceConvertable for H256 {
|
|
||||||
fn to_extras_slice(&self, i: ExtrasIndex) -> H264 {
|
|
||||||
let mut slice = H264::from_slice(self);
|
|
||||||
slice[32] = i as u8;
|
|
||||||
slice
|
|
||||||
}
|
|
||||||
fn as_h256(&self) -> Option<&H256> { Some(self) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExtrasSliceConvertable for U256 {
|
|
||||||
fn to_extras_slice(&self, i: ExtrasIndex) -> H264 {
|
|
||||||
H256::from(self).to_extras_slice(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NICE: make less horrible.
|
|
||||||
impl ExtrasSliceConvertable for BlockNumber {
|
|
||||||
fn to_extras_slice(&self, i: ExtrasIndex) -> H264 {
|
|
||||||
U256::from(*self).to_extras_slice(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Types implementing this trait can be indexed in extras database
|
|
||||||
pub trait ExtrasIndexable {
|
pub trait ExtrasIndexable {
|
||||||
/// Returns this data index
|
fn index() -> ExtrasIndex;
|
||||||
fn extras_index() -> ExtrasIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtrasIndexable for H256 {
|
impl ExtrasIndexable for H256 {
|
||||||
fn extras_index() -> ExtrasIndex {
|
fn index() -> ExtrasIndex {
|
||||||
ExtrasIndex::BlockHash
|
ExtrasIndex::BlockHash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ExtrasIndexable for BlockDetails {
|
||||||
|
fn index() -> ExtrasIndex {
|
||||||
|
ExtrasIndex::BlockDetails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtrasIndexable for TransactionAddress {
|
||||||
|
fn index() -> ExtrasIndex {
|
||||||
|
ExtrasIndex::TransactionAddress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtrasIndexable for BlockLogBlooms {
|
||||||
|
fn index() -> ExtrasIndex {
|
||||||
|
ExtrasIndex::BlockLogBlooms
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtrasIndexable for BlocksBlooms {
|
||||||
|
fn index() -> ExtrasIndex {
|
||||||
|
ExtrasIndex::BlocksBlooms
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtrasIndexable for BlockReceipts {
|
||||||
|
fn index() -> ExtrasIndex {
|
||||||
|
ExtrasIndex::BlockReceipts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Key<H256> for BlockNumber {
|
||||||
|
fn key(&self) -> H264 {
|
||||||
|
with_index(&H256::from(*self), ExtrasIndex::BlockHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Key<BlockDetails> for H256 {
|
||||||
|
fn key(&self) -> H264 {
|
||||||
|
with_index(self, ExtrasIndex::BlockDetails)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Key<TransactionAddress> for H256 {
|
||||||
|
fn key(&self) -> H264 {
|
||||||
|
with_index(self, ExtrasIndex::TransactionAddress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Key<BlockLogBlooms> for H256 {
|
||||||
|
fn key(&self) -> H264 {
|
||||||
|
with_index(self, ExtrasIndex::BlockLogBlooms)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Key<BlocksBlooms> for H256 {
|
||||||
|
fn key(&self) -> H264 {
|
||||||
|
with_index(self, ExtrasIndex::BlocksBlooms)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Key<BlockReceipts> for H256 {
|
||||||
|
fn key(&self) -> H264 {
|
||||||
|
with_index(self, ExtrasIndex::BlockReceipts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Familial details concerning a block
|
/// Familial details concerning a block
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BlockDetails {
|
pub struct BlockDetails {
|
||||||
@ -139,12 +133,6 @@ pub struct BlockDetails {
|
|||||||
pub children: Vec<H256>
|
pub children: Vec<H256>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtrasIndexable for BlockDetails {
|
|
||||||
fn extras_index() -> ExtrasIndex {
|
|
||||||
ExtrasIndex::BlockDetails
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HeapSizeOf for BlockDetails {
|
impl HeapSizeOf for BlockDetails {
|
||||||
fn heap_size_of_children(&self) -> usize {
|
fn heap_size_of_children(&self) -> usize {
|
||||||
self.children.heap_size_of_children()
|
self.children.heap_size_of_children()
|
||||||
@ -181,12 +169,6 @@ pub struct BlockLogBlooms {
|
|||||||
pub blooms: Vec<H2048>
|
pub blooms: Vec<H2048>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtrasIndexable for BlockLogBlooms {
|
|
||||||
fn extras_index() -> ExtrasIndex {
|
|
||||||
ExtrasIndex::BlockLogBlooms
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HeapSizeOf for BlockLogBlooms {
|
impl HeapSizeOf for BlockLogBlooms {
|
||||||
fn heap_size_of_children(&self) -> usize {
|
fn heap_size_of_children(&self) -> usize {
|
||||||
self.blooms.heap_size_of_children()
|
self.blooms.heap_size_of_children()
|
||||||
@ -227,12 +209,6 @@ impl BlocksBlooms {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtrasIndexable for BlocksBlooms {
|
|
||||||
fn extras_index() -> ExtrasIndex {
|
|
||||||
ExtrasIndex::BlocksBlooms
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HeapSizeOf for BlocksBlooms {
|
impl HeapSizeOf for BlocksBlooms {
|
||||||
fn heap_size_of_children(&self) -> usize { 0 }
|
fn heap_size_of_children(&self) -> usize { 0 }
|
||||||
}
|
}
|
||||||
@ -277,12 +253,6 @@ pub struct TransactionAddress {
|
|||||||
pub index: usize
|
pub index: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtrasIndexable for TransactionAddress {
|
|
||||||
fn extras_index() -> ExtrasIndex {
|
|
||||||
ExtrasIndex::TransactionAddress
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HeapSizeOf for TransactionAddress {
|
impl HeapSizeOf for TransactionAddress {
|
||||||
fn heap_size_of_children(&self) -> usize { 0 }
|
fn heap_size_of_children(&self) -> usize { 0 }
|
||||||
}
|
}
|
||||||
@ -340,9 +310,3 @@ impl HeapSizeOf for BlockReceipts {
|
|||||||
self.receipts.heap_size_of_children()
|
self.receipts.heap_size_of_children()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtrasIndexable for BlockReceipts {
|
|
||||||
fn extras_index() -> ExtrasIndex {
|
|
||||||
ExtrasIndex::BlockReceipts
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -104,6 +104,7 @@ pub mod views;
|
|||||||
pub mod receipt;
|
pub mod receipt;
|
||||||
pub mod pod_state;
|
pub mod pod_state;
|
||||||
|
|
||||||
|
mod db;
|
||||||
mod common;
|
mod common;
|
||||||
mod basic_types;
|
mod basic_types;
|
||||||
#[macro_use] mod evm;
|
#[macro_use] mod evm;
|
||||||
|
Loading…
Reference in New Issue
Block a user