Rlp decode returns Result (#8527)
rlp::decode returns Result Make a best effort to handle decoding errors gracefully throughout the code, using `expect` where the value is guaranteed to be valid (and in other places where it makes sense).
This commit is contained in:
parent
a7a46f4253
commit
28c731881f
@ -228,7 +228,7 @@ impl HeaderChain {
|
|||||||
let decoded_header = spec.genesis_header();
|
let decoded_header = spec.genesis_header();
|
||||||
|
|
||||||
let chain = if let Some(current) = db.get(col, CURRENT_KEY)? {
|
let chain = if let Some(current) = db.get(col, CURRENT_KEY)? {
|
||||||
let curr : BestAndLatest = ::rlp::decode(¤t);
|
let curr : BestAndLatest = ::rlp::decode(¤t).expect("decoding db value failed");
|
||||||
|
|
||||||
let mut cur_number = curr.latest_num;
|
let mut cur_number = curr.latest_num;
|
||||||
let mut candidates = BTreeMap::new();
|
let mut candidates = BTreeMap::new();
|
||||||
@ -236,7 +236,7 @@ impl HeaderChain {
|
|||||||
// load all era entries, referenced headers within them,
|
// load all era entries, referenced headers within them,
|
||||||
// and live epoch proofs.
|
// and live epoch proofs.
|
||||||
while let Some(entry) = db.get(col, era_key(cur_number).as_bytes())? {
|
while let Some(entry) = db.get(col, era_key(cur_number).as_bytes())? {
|
||||||
let entry: Entry = ::rlp::decode(&entry);
|
let entry: Entry = ::rlp::decode(&entry).expect("decoding db value failed");
|
||||||
trace!(target: "chain", "loaded header chain entry for era {} with {} candidates",
|
trace!(target: "chain", "loaded header chain entry for era {} with {} candidates",
|
||||||
cur_number, entry.candidates.len());
|
cur_number, entry.candidates.len());
|
||||||
|
|
||||||
@ -524,7 +524,10 @@ impl HeaderChain {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
Ok(None) => panic!("stored candidates always have corresponding headers; qed"),
|
Ok(None) => panic!("stored candidates always have corresponding headers; qed"),
|
||||||
Ok(Some(header)) => Some((epoch_transition, ::rlp::decode(&header))),
|
Ok(Some(header)) => Some((
|
||||||
|
epoch_transition,
|
||||||
|
::rlp::decode(&header).expect("decoding value from db failed")
|
||||||
|
)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -591,7 +594,7 @@ impl HeaderChain {
|
|||||||
in an inconsistent state", h_num);
|
in an inconsistent state", h_num);
|
||||||
ErrorKind::Database(msg.into())
|
ErrorKind::Database(msg.into())
|
||||||
})?;
|
})?;
|
||||||
::rlp::decode(&bytes)
|
::rlp::decode(&bytes).expect("decoding db value failed")
|
||||||
};
|
};
|
||||||
|
|
||||||
let total_difficulty = entry.candidates.iter()
|
let total_difficulty = entry.candidates.iter()
|
||||||
@ -604,9 +607,9 @@ impl HeaderChain {
|
|||||||
.total_difficulty;
|
.total_difficulty;
|
||||||
|
|
||||||
break Ok(Some(SpecHardcodedSync {
|
break Ok(Some(SpecHardcodedSync {
|
||||||
header: header,
|
header,
|
||||||
total_difficulty: total_difficulty,
|
total_difficulty,
|
||||||
chts: chts,
|
chts,
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
@ -742,7 +745,7 @@ impl HeaderChain {
|
|||||||
/// so including it within a CHT would be redundant.
|
/// so including it within a CHT would be redundant.
|
||||||
pub fn cht_root(&self, n: usize) -> Option<H256> {
|
pub fn cht_root(&self, n: usize) -> Option<H256> {
|
||||||
match self.db.get(self.col, cht_key(n as u64).as_bytes()) {
|
match self.db.get(self.col, cht_key(n as u64).as_bytes()) {
|
||||||
Ok(val) => val.map(|x| ::rlp::decode(&x)),
|
Ok(db_fetch) => db_fetch.map(|bytes| ::rlp::decode(&bytes).expect("decoding value from db failed")),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!(target: "chain", "Error reading from database: {}", e);
|
warn!(target: "chain", "Error reading from database: {}", e);
|
||||||
None
|
None
|
||||||
@ -793,7 +796,7 @@ impl HeaderChain {
|
|||||||
pub fn pending_transition(&self, hash: H256) -> Option<PendingEpochTransition> {
|
pub fn pending_transition(&self, hash: H256) -> Option<PendingEpochTransition> {
|
||||||
let key = pending_transition_key(hash);
|
let key = pending_transition_key(hash);
|
||||||
match self.db.get(self.col, &*key) {
|
match self.db.get(self.col, &*key) {
|
||||||
Ok(val) => val.map(|x| ::rlp::decode(&x)),
|
Ok(db_fetch) => db_fetch.map(|bytes| ::rlp::decode(&bytes).expect("decoding value from db failed")),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!(target: "chain", "Error reading from database: {}", e);
|
warn!(target: "chain", "Error reading from database: {}", e);
|
||||||
None
|
None
|
||||||
@ -1192,7 +1195,7 @@ mod tests {
|
|||||||
|
|
||||||
let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::from_secs(6 * 3600))));
|
let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::from_secs(6 * 3600))));
|
||||||
|
|
||||||
let chain = HeaderChain::new(db.clone(), None, &spec, cache, HardcodedSync::Allow).unwrap();
|
let chain = HeaderChain::new(db.clone(), None, &spec, cache, HardcodedSync::Allow).expect("failed to instantiate a new HeaderChain");
|
||||||
|
|
||||||
let mut parent_hash = genesis_header.hash();
|
let mut parent_hash = genesis_header.hash();
|
||||||
let mut rolling_timestamp = genesis_header.timestamp();
|
let mut rolling_timestamp = genesis_header.timestamp();
|
||||||
@ -1211,14 +1214,14 @@ mod tests {
|
|||||||
parent_hash = header.hash();
|
parent_hash = header.hash();
|
||||||
|
|
||||||
let mut tx = db.transaction();
|
let mut tx = db.transaction();
|
||||||
let pending = chain.insert(&mut tx, header, None).unwrap();
|
let pending = chain.insert(&mut tx, header, None).expect("failed inserting a transaction");
|
||||||
db.write(tx).unwrap();
|
db.write(tx).unwrap();
|
||||||
chain.apply_pending(pending);
|
chain.apply_pending(pending);
|
||||||
|
|
||||||
rolling_timestamp += 10;
|
rolling_timestamp += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hardcoded_sync = chain.read_hardcoded_sync().unwrap().unwrap();
|
let hardcoded_sync = chain.read_hardcoded_sync().expect("failed reading hardcoded sync").expect("failed unwrapping hardcoded sync");
|
||||||
assert_eq!(hardcoded_sync.chts.len(), 3);
|
assert_eq!(hardcoded_sync.chts.len(), 3);
|
||||||
assert_eq!(hardcoded_sync.total_difficulty, total_difficulty);
|
assert_eq!(hardcoded_sync.total_difficulty, total_difficulty);
|
||||||
let decoded: Header = hardcoded_sync.header.decode();
|
let decoded: Header = hardcoded_sync.header.decode();
|
||||||
|
@ -407,7 +407,7 @@ mod tests {
|
|||||||
let costs = CostTable::default();
|
let costs = CostTable::default();
|
||||||
let serialized = ::rlp::encode(&costs);
|
let serialized = ::rlp::encode(&costs);
|
||||||
|
|
||||||
let new_costs: CostTable = ::rlp::decode(&*serialized);
|
let new_costs: CostTable = ::rlp::decode(&*serialized).unwrap();
|
||||||
|
|
||||||
assert_eq!(costs, new_costs);
|
assert_eq!(costs, new_costs);
|
||||||
}
|
}
|
||||||
|
@ -1642,7 +1642,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
// check as single value.
|
// check as single value.
|
||||||
let bytes = ::rlp::encode(&val);
|
let bytes = ::rlp::encode(&val);
|
||||||
let new_val: T = ::rlp::decode(&bytes);
|
let new_val: T = ::rlp::decode(&bytes).unwrap();
|
||||||
assert_eq!(val, new_val);
|
assert_eq!(val, new_val);
|
||||||
|
|
||||||
// check as list containing single value.
|
// check as list containing single value.
|
||||||
|
@ -438,7 +438,7 @@ impl<'a> Iterator for EpochTransitionIter<'a> {
|
|||||||
return None
|
return None
|
||||||
}
|
}
|
||||||
|
|
||||||
let transitions: EpochTransitions = ::rlp::decode(&val[..]);
|
let transitions: EpochTransitions = ::rlp::decode(&val[..]).expect("decode error: the db is corrupted or the data structure has changed");
|
||||||
|
|
||||||
// if there are multiple candidates, at most one will be on the
|
// if there are multiple candidates, at most one will be on the
|
||||||
// canon chain.
|
// canon chain.
|
||||||
@ -462,7 +462,7 @@ impl<'a> Iterator for EpochTransitionIter<'a> {
|
|||||||
impl BlockChain {
|
impl BlockChain {
|
||||||
/// Create new instance of blockchain from given Genesis.
|
/// Create new instance of blockchain from given Genesis.
|
||||||
pub fn new(config: Config, genesis: &[u8], db: Arc<KeyValueDB>) -> BlockChain {
|
pub fn new(config: Config, genesis: &[u8], db: Arc<KeyValueDB>) -> BlockChain {
|
||||||
// 400 is the avarage size of the key
|
// 400 is the average size of the key
|
||||||
let cache_man = CacheManager::new(config.pref_cache_size, config.max_cache_size, 400);
|
let cache_man = CacheManager::new(config.pref_cache_size, config.max_cache_size, 400);
|
||||||
|
|
||||||
let mut bc = BlockChain {
|
let mut bc = BlockChain {
|
||||||
|
@ -218,15 +218,12 @@ impl Writable for DBTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<KVDB: KeyValueDB + ?Sized> Readable for KVDB {
|
impl<KVDB: KeyValueDB + ?Sized> Readable for KVDB {
|
||||||
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where T: rlp::Decodable, R: Deref<Target = [u8]> {
|
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T>
|
||||||
let result = self.get(col, &key.key());
|
where T: rlp::Decodable, R: Deref<Target = [u8]> {
|
||||||
|
self.get(col, &key.key())
|
||||||
|
.expect(&format!("db get failed, key: {:?}", &key.key() as &[u8]))
|
||||||
|
.map(|v| rlp::decode(&v).expect("decode db value failed") )
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(option) => option.map(|v| rlp::decode(&v)),
|
|
||||||
Err(err) => {
|
|
||||||
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: Deref<Target = [u8]> {
|
fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: Deref<Target = [u8]> {
|
||||||
|
@ -24,13 +24,12 @@
|
|||||||
//! decoded object where parts like the hash can be saved.
|
//! decoded object where parts like the hash can be saved.
|
||||||
|
|
||||||
use block::Block as FullBlock;
|
use block::Block as FullBlock;
|
||||||
use header::{BlockNumber, Header as FullHeader};
|
|
||||||
use transaction::UnverifiedTransaction;
|
|
||||||
|
|
||||||
use hash::keccak;
|
|
||||||
use heapsize::HeapSizeOf;
|
|
||||||
use ethereum_types::{H256, Bloom, U256, Address};
|
use ethereum_types::{H256, Bloom, U256, Address};
|
||||||
|
use hash::keccak;
|
||||||
|
use header::{BlockNumber, Header as FullHeader};
|
||||||
|
use heapsize::HeapSizeOf;
|
||||||
use rlp::{Rlp, RlpStream};
|
use rlp::{Rlp, RlpStream};
|
||||||
|
use transaction::UnverifiedTransaction;
|
||||||
use views::{self, BlockView, HeaderView, BodyView};
|
use views::{self, BlockView, HeaderView, BodyView};
|
||||||
|
|
||||||
/// Owning header view.
|
/// Owning header view.
|
||||||
@ -48,7 +47,7 @@ impl Header {
|
|||||||
pub fn new(encoded: Vec<u8>) -> Self { Header(encoded) }
|
pub fn new(encoded: Vec<u8>) -> Self { Header(encoded) }
|
||||||
|
|
||||||
/// Upgrade this encoded view to a fully owned `Header` object.
|
/// Upgrade this encoded view to a fully owned `Header` object.
|
||||||
pub fn decode(&self) -> FullHeader { ::rlp::decode(&self.0) }
|
pub fn decode(&self) -> FullHeader { ::rlp::decode(&self.0).expect("decoding failure") }
|
||||||
|
|
||||||
/// Get a borrowed header view onto the data.
|
/// Get a borrowed header view onto the data.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -205,7 +204,7 @@ impl Block {
|
|||||||
pub fn header_view(&self) -> HeaderView { self.view().header_view() }
|
pub fn header_view(&self) -> HeaderView { self.view().header_view() }
|
||||||
|
|
||||||
/// Decode to a full block.
|
/// Decode to a full block.
|
||||||
pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0) }
|
pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0).expect("decoding failure") }
|
||||||
|
|
||||||
/// Decode the header.
|
/// Decode the header.
|
||||||
pub fn decode_header(&self) -> FullHeader { self.view().rlp().val_at(0) }
|
pub fn decode_header(&self) -> FullHeader { self.view().rlp().val_at(0) }
|
||||||
|
@ -143,8 +143,10 @@ impl <F> super::EpochVerifier<EthereumMachine> for EpochVerifier<F>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_finality_proof(&self, proof: &[u8]) -> Option<Vec<H256>> {
|
fn check_finality_proof(&self, proof: &[u8]) -> Option<Vec<H256>> {
|
||||||
let header: Header = ::rlp::decode(proof);
|
match ::rlp::decode(proof) {
|
||||||
self.verify_light(&header).ok().map(|_| vec![header.hash()])
|
Ok(header) => self.verify_light(&header).ok().map(|_| vec![header.hash()]),
|
||||||
|
Err(_) => None // REVIEW: log perhaps? Not sure what the policy is.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ mod tests {
|
|||||||
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
|
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||||
let nonce_decoded = "ab4e252a7e8c2a23".from_hex().unwrap();
|
let nonce_decoded = "ab4e252a7e8c2a23".from_hex().unwrap();
|
||||||
|
|
||||||
let header: Header = rlp::decode(&header_rlp);
|
let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
|
||||||
let seal_fields = header.seal.clone();
|
let seal_fields = header.seal.clone();
|
||||||
assert_eq!(seal_fields.len(), 2);
|
assert_eq!(seal_fields.len(), 2);
|
||||||
assert_eq!(seal_fields[0], mix_hash);
|
assert_eq!(seal_fields[0], mix_hash);
|
||||||
@ -415,7 +415,7 @@ mod tests {
|
|||||||
// that's rlp of block header created with ethash engine.
|
// that's rlp of block header created with ethash engine.
|
||||||
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
|
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
|
||||||
|
|
||||||
let header: Header = rlp::decode(&header_rlp);
|
let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
|
||||||
let encoded_header = rlp::encode(&header).into_vec();
|
let encoded_header = rlp::encode(&header).into_vec();
|
||||||
|
|
||||||
assert_eq!(header_rlp, encoded_header);
|
assert_eq!(header_rlp, encoded_header);
|
||||||
|
@ -236,7 +236,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let thin_rlp = ::rlp::encode(&account);
|
let thin_rlp = ::rlp::encode(&account);
|
||||||
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
|
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp).unwrap(), account);
|
||||||
|
|
||||||
let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap();
|
let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap();
|
||||||
let fat_rlp = Rlp::new(&fat_rlps[0]).at(1).unwrap();
|
let fat_rlp = Rlp::new(&fat_rlps[0]).at(1).unwrap();
|
||||||
@ -261,7 +261,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let thin_rlp = ::rlp::encode(&account);
|
let thin_rlp = ::rlp::encode(&account);
|
||||||
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
|
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp).unwrap(), account);
|
||||||
|
|
||||||
let fat_rlp = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap();
|
let fat_rlp = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap();
|
||||||
let fat_rlp = Rlp::new(&fat_rlp[0]).at(1).unwrap();
|
let fat_rlp = Rlp::new(&fat_rlp[0]).at(1).unwrap();
|
||||||
@ -286,7 +286,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let thin_rlp = ::rlp::encode(&account);
|
let thin_rlp = ::rlp::encode(&account);
|
||||||
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp), account);
|
assert_eq!(::rlp::decode::<BasicAccount>(&thin_rlp).unwrap(), account);
|
||||||
|
|
||||||
let fat_rlps = to_fat_rlps(&keccak(addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), 500, 1000).unwrap();
|
let fat_rlps = to_fat_rlps(&keccak(addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), 500, 1000).unwrap();
|
||||||
let mut root = KECCAK_NULL_RLP;
|
let mut root = KECCAK_NULL_RLP;
|
||||||
|
@ -281,7 +281,7 @@ pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: &Mutex<SnapshotWriter +
|
|||||||
// account_key here is the address' hash.
|
// account_key here is the address' hash.
|
||||||
for item in account_trie.iter()? {
|
for item in account_trie.iter()? {
|
||||||
let (account_key, account_data) = item?;
|
let (account_key, account_data) = item?;
|
||||||
let account = ::rlp::decode(&*account_data);
|
let account = ::rlp::decode(&*account_data)?;
|
||||||
let account_key_hash = H256::from_slice(&account_key);
|
let account_key_hash = H256::from_slice(&account_key);
|
||||||
|
|
||||||
let account_db = AccountDB::from_hash(db, account_key_hash);
|
let account_db = AccountDB::from_hash(db, account_key_hash);
|
||||||
@ -467,10 +467,10 @@ fn rebuild_accounts(
|
|||||||
*out = (hash, thin_rlp);
|
*out = (hash, thin_rlp);
|
||||||
}
|
}
|
||||||
if let Some(&(ref hash, ref rlp)) = out_chunk.iter().last() {
|
if let Some(&(ref hash, ref rlp)) = out_chunk.iter().last() {
|
||||||
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp).storage_root);
|
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp)?.storage_root);
|
||||||
}
|
}
|
||||||
if let Some(&(ref hash, ref rlp)) = out_chunk.iter().next() {
|
if let Some(&(ref hash, ref rlp)) = out_chunk.iter().next() {
|
||||||
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp).storage_root);
|
known_storage_roots.insert(*hash, ::rlp::decode::<BasicAccount>(rlp)?.storage_root);
|
||||||
}
|
}
|
||||||
Ok(status)
|
Ok(status)
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ impl StateProducer {
|
|||||||
|
|
||||||
// sweep once to alter storage tries.
|
// sweep once to alter storage tries.
|
||||||
for &mut (ref mut address_hash, ref mut account_data) in &mut accounts_to_modify {
|
for &mut (ref mut address_hash, ref mut account_data) in &mut accounts_to_modify {
|
||||||
let mut account: BasicAccount = ::rlp::decode(&*account_data);
|
let mut account: BasicAccount = ::rlp::decode(&*account_data).expect("error decoding basic account");
|
||||||
let acct_db = AccountDBMut::from_hash(db, *address_hash);
|
let acct_db = AccountDBMut::from_hash(db, *address_hash);
|
||||||
fill_storage(acct_db, &mut account.storage_root, &mut self.storage_seed);
|
fill_storage(acct_db, &mut account.storage_root, &mut self.storage_seed);
|
||||||
*account_data = DBValue::from_vec(::rlp::encode(&account).into_vec());
|
*account_data = DBValue::from_vec(::rlp::encode(&account).into_vec());
|
||||||
|
@ -114,7 +114,7 @@ fn get_code_from_prev_chunk() {
|
|||||||
// first one will have code inlined,
|
// first one will have code inlined,
|
||||||
// second will just have its hash.
|
// second will just have its hash.
|
||||||
let thin_rlp = acc_stream.out();
|
let thin_rlp = acc_stream.out();
|
||||||
let acc: BasicAccount = ::rlp::decode(&thin_rlp);
|
let acc: BasicAccount = ::rlp::decode(&thin_rlp).expect("error decoding basic account");
|
||||||
|
|
||||||
let mut make_chunk = |acc, hash| {
|
let mut make_chunk = |acc, hash| {
|
||||||
let mut db = MemoryDB::new();
|
let mut db = MemoryDB::new();
|
||||||
|
@ -21,6 +21,7 @@ use std::sync::Arc;
|
|||||||
use std::collections::{HashMap, BTreeMap};
|
use std::collections::{HashMap, BTreeMap};
|
||||||
use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP, keccak};
|
use hash::{KECCAK_EMPTY, KECCAK_NULL_RLP, keccak};
|
||||||
use ethereum_types::{H256, U256, Address};
|
use ethereum_types::{H256, U256, Address};
|
||||||
|
use error::Error;
|
||||||
use hashdb::HashDB;
|
use hashdb::HashDB;
|
||||||
use kvdb::DBValue;
|
use kvdb::DBValue;
|
||||||
use bytes::{Bytes, ToPretty};
|
use bytes::{Bytes, ToPretty};
|
||||||
@ -144,9 +145,10 @@ impl Account {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new account from RLP.
|
/// Create a new account from RLP.
|
||||||
pub fn from_rlp(rlp: &[u8]) -> Account {
|
pub fn from_rlp(rlp: &[u8]) -> Result<Account, Error> {
|
||||||
let basic: BasicAccount = ::rlp::decode(rlp);
|
::rlp::decode::<BasicAccount>(rlp)
|
||||||
basic.into()
|
.map(|ba| ba.into())
|
||||||
|
.map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new contract account.
|
/// Create a new contract account.
|
||||||
@ -202,8 +204,8 @@ impl Account {
|
|||||||
return Ok(value);
|
return Ok(value);
|
||||||
}
|
}
|
||||||
let db = SecTrieDB::new(db, &self.storage_root)?;
|
let db = SecTrieDB::new(db, &self.storage_root)?;
|
||||||
|
let panicky_decoder = |bytes:&[u8]| ::rlp::decode(&bytes).expect("decoding db value failed");
|
||||||
let item: U256 = db.get_with(key, ::rlp::decode)?.unwrap_or_else(U256::zero);
|
let item: U256 = db.get_with(key, panicky_decoder)?.unwrap_or_else(U256::zero);
|
||||||
let value: H256 = item.into();
|
let value: H256 = item.into();
|
||||||
self.storage_cache.borrow_mut().insert(key.clone(), value.clone());
|
self.storage_cache.borrow_mut().insert(key.clone(), value.clone());
|
||||||
Ok(value)
|
Ok(value)
|
||||||
@ -478,7 +480,8 @@ impl Account {
|
|||||||
|
|
||||||
let trie = TrieDB::new(db, &self.storage_root)?;
|
let trie = TrieDB::new(db, &self.storage_root)?;
|
||||||
let item: U256 = {
|
let item: U256 = {
|
||||||
let query = (&mut recorder, ::rlp::decode);
|
let panicky_decoder = |bytes:&[u8]| ::rlp::decode(bytes).expect("decoding db value failed");
|
||||||
|
let query = (&mut recorder, panicky_decoder);
|
||||||
trie.get_with(&storage_key, query)?.unwrap_or_else(U256::zero)
|
trie.get_with(&storage_key, query)?.unwrap_or_else(U256::zero)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -528,7 +531,7 @@ mod tests {
|
|||||||
a.rlp()
|
a.rlp()
|
||||||
};
|
};
|
||||||
|
|
||||||
let a = Account::from_rlp(&rlp);
|
let a = Account::from_rlp(&rlp).expect("decoding db value failed");
|
||||||
assert_eq!(*a.storage_root().unwrap(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into());
|
assert_eq!(*a.storage_root().unwrap(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into());
|
||||||
assert_eq!(a.storage_at(&db.immutable(), &0x00u64.into()).unwrap(), 0x1234u64.into());
|
assert_eq!(a.storage_at(&db.immutable(), &0x00u64.into()).unwrap(), 0x1234u64.into());
|
||||||
assert_eq!(a.storage_at(&db.immutable(), &0x01u64.into()).unwrap(), H256::default());
|
assert_eq!(a.storage_at(&db.immutable(), &0x01u64.into()).unwrap(), H256::default());
|
||||||
@ -546,10 +549,10 @@ mod tests {
|
|||||||
a.rlp()
|
a.rlp()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut a = Account::from_rlp(&rlp);
|
let mut a = Account::from_rlp(&rlp).expect("decoding db value failed");
|
||||||
assert!(a.cache_code(&db.immutable()).is_some());
|
assert!(a.cache_code(&db.immutable()).is_some());
|
||||||
|
|
||||||
let mut a = Account::from_rlp(&rlp);
|
let mut a = Account::from_rlp(&rlp).expect("decoding db value failed");
|
||||||
assert_eq!(a.note_code(vec![0x55, 0x44, 0xffu8]), Ok(()));
|
assert_eq!(a.note_code(vec![0x55, 0x44, 0xffu8]), Ok(()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,7 +612,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rlpio() {
|
fn rlpio() {
|
||||||
let a = Account::new(69u8.into(), 0u8.into(), HashMap::new(), Bytes::new());
|
let a = Account::new(69u8.into(), 0u8.into(), HashMap::new(), Bytes::new());
|
||||||
let b = Account::from_rlp(&a.rlp());
|
let b = Account::from_rlp(&a.rlp()).unwrap();
|
||||||
assert_eq!(a.balance(), b.balance());
|
assert_eq!(a.balance(), b.balance());
|
||||||
assert_eq!(a.nonce(), b.nonce());
|
assert_eq!(a.nonce(), b.nonce());
|
||||||
assert_eq!(a.code_hash(), b.code_hash());
|
assert_eq!(a.code_hash(), b.code_hash());
|
||||||
|
@ -605,7 +605,8 @@ impl<B: Backend> State<B> {
|
|||||||
|
|
||||||
// account is not found in the global cache, get from the DB and insert into local
|
// account is not found in the global cache, get from the DB and insert into local
|
||||||
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
|
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
|
||||||
let maybe_acc = db.get_with(address, Account::from_rlp)?;
|
let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed");
|
||||||
|
let maybe_acc = db.get_with(address, from_rlp)?;
|
||||||
let r = maybe_acc.as_ref().map_or(Ok(H256::new()), |a| {
|
let r = maybe_acc.as_ref().map_or(Ok(H256::new()), |a| {
|
||||||
let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), a.address_hash(address));
|
let account_db = self.factories.accountdb.readonly(self.db.as_hashdb(), a.address_hash(address));
|
||||||
a.storage_at(account_db.as_hashdb(), key)
|
a.storage_at(account_db.as_hashdb(), key)
|
||||||
@ -983,7 +984,8 @@ impl<B: Backend> State<B> {
|
|||||||
|
|
||||||
// not found in the global cache, get from the DB and insert into local
|
// not found in the global cache, get from the DB and insert into local
|
||||||
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?;
|
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?;
|
||||||
let mut maybe_acc = db.get_with(a, Account::from_rlp)?;
|
let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed");
|
||||||
|
let mut maybe_acc = db.get_with(a, from_rlp)?;
|
||||||
if let Some(ref mut account) = maybe_acc.as_mut() {
|
if let Some(ref mut account) = maybe_acc.as_mut() {
|
||||||
let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a));
|
let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), account.address_hash(a));
|
||||||
Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb());
|
Self::update_account_cache(require, account, &self.db, accountdb.as_hashdb());
|
||||||
@ -1012,7 +1014,8 @@ impl<B: Backend> State<B> {
|
|||||||
None => {
|
None => {
|
||||||
let maybe_acc = if !self.db.is_known_null(a) {
|
let maybe_acc = if !self.db.is_known_null(a) {
|
||||||
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?;
|
let db = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?;
|
||||||
AccountEntry::new_clean(db.get_with(a, Account::from_rlp)?)
|
let from_rlp = |b:&[u8]| { Account::from_rlp(b).expect("decoding db value failed") };
|
||||||
|
AccountEntry::new_clean(db.get_with(a, from_rlp)?)
|
||||||
} else {
|
} else {
|
||||||
AccountEntry::new_clean(None)
|
AccountEntry::new_clean(None)
|
||||||
};
|
};
|
||||||
@ -1064,7 +1067,10 @@ impl<B: Backend> State<B> {
|
|||||||
let mut recorder = Recorder::new();
|
let mut recorder = Recorder::new();
|
||||||
let trie = TrieDB::new(self.db.as_hashdb(), &self.root)?;
|
let trie = TrieDB::new(self.db.as_hashdb(), &self.root)?;
|
||||||
let maybe_account: Option<BasicAccount> = {
|
let maybe_account: Option<BasicAccount> = {
|
||||||
let query = (&mut recorder, ::rlp::decode);
|
let panicky_decoder = |bytes: &[u8]| {
|
||||||
|
::rlp::decode(bytes).expect(&format!("prove_account, could not query trie for account key={}", &account_key))
|
||||||
|
};
|
||||||
|
let query = (&mut recorder, panicky_decoder);
|
||||||
trie.get_with(&account_key, query)?
|
trie.get_with(&account_key, query)?
|
||||||
};
|
};
|
||||||
let account = maybe_account.unwrap_or_else(|| BasicAccount {
|
let account = maybe_account.unwrap_or_else(|| BasicAccount {
|
||||||
@ -1086,7 +1092,8 @@ impl<B: Backend> State<B> {
|
|||||||
// TODO: probably could look into cache somehow but it's keyed by
|
// TODO: probably could look into cache somehow but it's keyed by
|
||||||
// address, not keccak(address).
|
// address, not keccak(address).
|
||||||
let trie = TrieDB::new(self.db.as_hashdb(), &self.root)?;
|
let trie = TrieDB::new(self.db.as_hashdb(), &self.root)?;
|
||||||
let acc = match trie.get_with(&account_key, Account::from_rlp)? {
|
let from_rlp = |b: &[u8]| Account::from_rlp(b).expect("decoding db value failed");
|
||||||
|
let acc = match trie.get_with(&account_key, from_rlp)? {
|
||||||
Some(acc) => acc,
|
Some(acc) => acc,
|
||||||
None => return Ok((Vec::new(), H256::new())),
|
None => return Ok((Vec::new(), H256::new())),
|
||||||
};
|
};
|
||||||
|
@ -244,7 +244,7 @@ mod tests {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
let encoded = ::rlp::encode(&block_traces);
|
let encoded = ::rlp::encode(&block_traces);
|
||||||
let decoded = ::rlp::decode(&encoded);
|
let decoded = ::rlp::decode(&encoded).expect("error decoding block traces");
|
||||||
assert_eq!(block_traces, decoded);
|
assert_eq!(block_traces, decoded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -576,7 +576,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sender_test() {
|
fn sender_test() {
|
||||||
let t: UnverifiedTransaction = rlp::decode(&::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
|
let bytes = ::rustc_hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap();
|
||||||
|
let t: UnverifiedTransaction = rlp::decode(&bytes).expect("decoding UnverifiedTransaction failed");
|
||||||
assert_eq!(t.data, b"");
|
assert_eq!(t.data, b"");
|
||||||
assert_eq!(t.gas, U256::from(0x5208u64));
|
assert_eq!(t.gas, U256::from(0x5208u64));
|
||||||
assert_eq!(t.gas_price, U256::from(0x01u64));
|
assert_eq!(t.gas_price, U256::from(0x01u64));
|
||||||
@ -645,7 +646,7 @@ mod tests {
|
|||||||
use rustc_hex::FromHex;
|
use rustc_hex::FromHex;
|
||||||
|
|
||||||
let test_vector = |tx_data: &str, address: &'static str| {
|
let test_vector = |tx_data: &str, address: &'static str| {
|
||||||
let signed = rlp::decode(&FromHex::from_hex(tx_data).unwrap());
|
let signed = rlp::decode(&FromHex::from_hex(tx_data).unwrap()).expect("decoding tx data failed");
|
||||||
let signed = SignedTransaction::new(signed).unwrap();
|
let signed = SignedTransaction::new(signed).unwrap();
|
||||||
assert_eq!(signed.sender(), address.into());
|
assert_eq!(signed.sender(), address.into());
|
||||||
println!("chainid: {:?}", signed.chain_id());
|
println!("chainid: {:?}", signed.chain_id());
|
||||||
|
@ -193,7 +193,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let encoded = ::rlp::encode(&r);
|
let encoded = ::rlp::encode(&r);
|
||||||
assert_eq!(&encoded[..], &expected[..]);
|
assert_eq!(&encoded[..], &expected[..]);
|
||||||
let decoded: Receipt = ::rlp::decode(&encoded);
|
let decoded: Receipt = ::rlp::decode(&encoded).expect("decoding receipt failed");
|
||||||
assert_eq!(decoded, r);
|
assert_eq!(decoded, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
let encoded = ::rlp::encode(&r);
|
let encoded = ::rlp::encode(&r);
|
||||||
assert_eq!(&encoded[..], &expected[..]);
|
assert_eq!(&encoded[..], &expected[..]);
|
||||||
let decoded: Receipt = ::rlp::decode(&encoded);
|
let decoded: Receipt = ::rlp::decode(&encoded).expect("decoding receipt failed");
|
||||||
assert_eq!(decoded, r);
|
assert_eq!(decoded, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ mod tests {
|
|||||||
fn should_encode_and_decode_call_type() {
|
fn should_encode_and_decode_call_type() {
|
||||||
let original = CallType::Call;
|
let original = CallType::Call;
|
||||||
let encoded = encode(&original);
|
let encoded = encode(&original);
|
||||||
let decoded = decode(&encoded);
|
let decoded = decode(&encoded).expect("failure decoding CallType");
|
||||||
assert_eq!(original, decoded);
|
assert_eq!(original, decoded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -566,7 +566,8 @@ fn rpc_eth_pending_transaction_by_hash() {
|
|||||||
|
|
||||||
let tester = EthTester::default();
|
let tester = EthTester::default();
|
||||||
{
|
{
|
||||||
let tx = rlp::decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
|
let bytes = FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap();
|
||||||
|
let tx = rlp::decode(&bytes).expect("decoding failure");
|
||||||
let tx = SignedTransaction::new(tx).unwrap();
|
let tx = SignedTransaction::new(tx).unwrap();
|
||||||
tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
|
tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
|
||||||
}
|
}
|
||||||
|
@ -45,14 +45,15 @@ pub struct ArchiveDB {
|
|||||||
|
|
||||||
impl ArchiveDB {
|
impl ArchiveDB {
|
||||||
/// Create a new instance from a key-value db.
|
/// Create a new instance from a key-value db.
|
||||||
pub fn new(backing: Arc<KeyValueDB>, col: Option<u32>) -> ArchiveDB {
|
pub fn new(backing: Arc<KeyValueDB>, column: Option<u32>) -> ArchiveDB {
|
||||||
let latest_era = backing.get(col, &LATEST_ERA_KEY).expect("Low-level database error.")
|
let latest_era = backing.get(column, &LATEST_ERA_KEY)
|
||||||
.map(|val| decode::<u64>(&val));
|
.expect("Low-level database error.")
|
||||||
|
.map(|val| decode::<u64>(&val).expect("decoding db value failed"));
|
||||||
ArchiveDB {
|
ArchiveDB {
|
||||||
overlay: MemoryDB::new(),
|
overlay: MemoryDB::new(),
|
||||||
backing: backing,
|
backing,
|
||||||
latest_era: latest_era,
|
latest_era,
|
||||||
column: col,
|
column,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ impl EarlyMergeDB {
|
|||||||
let mut refs = HashMap::new();
|
let mut refs = HashMap::new();
|
||||||
let mut latest_era = None;
|
let mut latest_era = None;
|
||||||
if let Some(val) = db.get(col, &LATEST_ERA_KEY).expect("Low-level database error.") {
|
if let Some(val) = db.get(col, &LATEST_ERA_KEY).expect("Low-level database error.") {
|
||||||
let mut era = decode::<u64>(&val);
|
let mut era = decode::<u64>(&val).expect("decoding db value failed");
|
||||||
latest_era = Some(era);
|
latest_era = Some(era);
|
||||||
loop {
|
loop {
|
||||||
let mut db_key = DatabaseKey {
|
let mut db_key = DatabaseKey {
|
||||||
|
@ -137,7 +137,7 @@ impl OverlayDB {
|
|||||||
fn payload(&self, key: &H256) -> Option<Payload> {
|
fn payload(&self, key: &H256) -> Option<Payload> {
|
||||||
self.backing.get(self.column, key)
|
self.backing.get(self.column, key)
|
||||||
.expect("Low-level database error. Some issue with your hard disk?")
|
.expect("Low-level database error. Some issue with your hard disk?")
|
||||||
.map(|d| decode(&d))
|
.map(|d| decode(&d).expect("decoding db value failed"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Put the refs and value of the given key, possibly deleting it from the db.
|
/// Put the refs and value of the given key, possibly deleting it from the db.
|
||||||
|
@ -186,7 +186,7 @@ impl OverlayRecentDB {
|
|||||||
let mut earliest_era = None;
|
let mut earliest_era = None;
|
||||||
let mut cumulative_size = 0;
|
let mut cumulative_size = 0;
|
||||||
if let Some(val) = db.get(col, &LATEST_ERA_KEY).expect("Low-level database error.") {
|
if let Some(val) = db.get(col, &LATEST_ERA_KEY).expect("Low-level database error.") {
|
||||||
let mut era = decode::<u64>(&val);
|
let mut era = decode::<u64>(&val).expect("decoding db value failed");
|
||||||
latest_era = Some(era);
|
latest_era = Some(era);
|
||||||
loop {
|
loop {
|
||||||
let mut db_key = DatabaseKey {
|
let mut db_key = DatabaseKey {
|
||||||
@ -195,7 +195,7 @@ impl OverlayRecentDB {
|
|||||||
};
|
};
|
||||||
while let Some(rlp_data) = db.get(col, &encode(&db_key)).expect("Low-level database error.") {
|
while let Some(rlp_data) = db.get(col, &encode(&db_key)).expect("Low-level database error.") {
|
||||||
trace!("read_overlay: era={}, index={}", era, db_key.index);
|
trace!("read_overlay: era={}, index={}", era, db_key.index);
|
||||||
let value = decode::<DatabaseValue>(&rlp_data);
|
let value = decode::<DatabaseValue>(&rlp_data).expect(&format!("read_overlay: Error decoding DatabaseValue era={}, index{}", era, db_key.index));
|
||||||
count += value.inserts.len();
|
count += value.inserts.len();
|
||||||
let mut inserted_keys = Vec::new();
|
let mut inserted_keys = Vec::new();
|
||||||
for (k, v) in value.inserts {
|
for (k, v) in value.inserts {
|
||||||
|
@ -62,17 +62,18 @@ pub struct RefCountedDB {
|
|||||||
|
|
||||||
impl RefCountedDB {
|
impl RefCountedDB {
|
||||||
/// Create a new instance given a `backing` database.
|
/// Create a new instance given a `backing` database.
|
||||||
pub fn new(backing: Arc<KeyValueDB>, col: Option<u32>) -> RefCountedDB {
|
pub fn new(backing: Arc<KeyValueDB>, column: Option<u32>) -> RefCountedDB {
|
||||||
let latest_era = backing.get(col, &LATEST_ERA_KEY).expect("Low-level database error.")
|
let latest_era = backing.get(column, &LATEST_ERA_KEY)
|
||||||
.map(|val| decode::<u64>(&val));
|
.expect("Low-level database error.")
|
||||||
|
.map(|v| decode::<u64>(&v).expect("decoding db value failed"));
|
||||||
|
|
||||||
RefCountedDB {
|
RefCountedDB {
|
||||||
forward: OverlayDB::new(backing.clone(), col),
|
forward: OverlayDB::new(backing.clone(), column),
|
||||||
backing: backing,
|
backing,
|
||||||
inserts: vec![],
|
inserts: vec![],
|
||||||
removes: vec![],
|
removes: vec![],
|
||||||
latest_era: latest_era,
|
latest_era,
|
||||||
column: col,
|
column,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,13 +63,13 @@ pub const EMPTY_LIST_RLP: [u8; 1] = [0xC0; 1];
|
|||||||
///
|
///
|
||||||
/// fn main () {
|
/// fn main () {
|
||||||
/// let data = vec![0x83, b'c', b'a', b't'];
|
/// let data = vec![0x83, b'c', b'a', b't'];
|
||||||
/// let animal: String = rlp::decode(&data);
|
/// let animal: String = rlp::decode(&data).expect("could not decode");
|
||||||
/// assert_eq!(animal, "cat".to_owned());
|
/// assert_eq!(animal, "cat".to_owned());
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn decode<T>(bytes: &[u8]) -> T where T: Decodable {
|
pub fn decode<T>(bytes: &[u8]) -> Result<T, DecoderError> where T: Decodable {
|
||||||
let rlp = Rlp::new(bytes);
|
let rlp = Rlp::new(bytes);
|
||||||
rlp.as_val().expect("trusted rlp should be valid")
|
rlp.as_val()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode_list<T>(bytes: &[u8]) -> Vec<T> where T: Decodable {
|
pub fn decode_list<T>(bytes: &[u8]) -> Vec<T> where T: Decodable {
|
||||||
|
@ -209,8 +209,10 @@ struct VDTestPair<T>(Vec<T>, Vec<u8>) where T: Decodable + fmt::Debug + cmp::Eq;
|
|||||||
|
|
||||||
fn run_decode_tests<T>(tests: Vec<DTestPair<T>>) where T: Decodable + fmt::Debug + cmp::Eq {
|
fn run_decode_tests<T>(tests: Vec<DTestPair<T>>) where T: Decodable + fmt::Debug + cmp::Eq {
|
||||||
for t in &tests {
|
for t in &tests {
|
||||||
let res: T = rlp::decode(&t.1);
|
let res : Result<T, DecoderError> = rlp::decode(&t.1);
|
||||||
assert_eq!(res, t.0);
|
assert!(res.is_ok());
|
||||||
|
let res = res.unwrap();
|
||||||
|
assert_eq!(&res, &t.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ fn test_encode_foo() {
|
|||||||
let out = encode(&foo).into_vec();
|
let out = encode(&foo).into_vec();
|
||||||
assert_eq!(out, expected);
|
assert_eq!(out, expected);
|
||||||
|
|
||||||
let decoded = decode(&expected);
|
let decoded = decode(&expected).expect("decode failure");
|
||||||
assert_eq!(foo, decoded);
|
assert_eq!(foo, decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ fn test_encode_foo_wrapper() {
|
|||||||
let out = encode(&foo).into_vec();
|
let out = encode(&foo).into_vec();
|
||||||
assert_eq!(out, expected);
|
assert_eq!(out, expected);
|
||||||
|
|
||||||
let decoded = decode(&expected);
|
let decoded = decode(&expected).expect("decode failure");
|
||||||
assert_eq!(foo, decoded);
|
assert_eq!(foo, decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let encoded = ::rlp::encode(&envelope);
|
let encoded = ::rlp::encode(&envelope);
|
||||||
let decoded = ::rlp::decode(&encoded);
|
let decoded = ::rlp::decode(&encoded).expect("failure decoding Envelope");
|
||||||
|
|
||||||
assert_eq!(envelope, decoded)
|
assert_eq!(envelope, decoded)
|
||||||
}
|
}
|
||||||
@ -462,7 +462,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let encoded = ::rlp::encode(&envelope);
|
let encoded = ::rlp::encode(&envelope);
|
||||||
let decoded = ::rlp::decode(&encoded);
|
let decoded = ::rlp::decode(&encoded).expect("failure decoding Envelope");
|
||||||
|
|
||||||
assert_eq!(envelope, decoded)
|
assert_eq!(envelope, decoded)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user