openethereum/ethcore/light/src/on_demand/request.rs

1336 lines
43 KiB
Rust
Raw Normal View History

// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of Open Ethereum.
2017-01-03 19:13:40 +01:00
// Open Ethereum is free software: you can redistribute it and/or modify
2017-01-03 19:13:40 +01:00
// 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.
// Open Ethereum is distributed in the hope that it will be useful,
2017-01-03 19:13:40 +01:00
// 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 Open Ethereum. If not, see <http://www.gnu.org/licenses/>.
2017-01-03 19:13:40 +01:00
//! Request types, verification, and verification errors.
use std::cmp;
use std::sync::Arc;
use bytes::Bytes;
use common_types::basic_account::BasicAccount;
use common_types::encoded;
use common_types::receipt::Receipt;
use common_types::transaction::SignedTransaction;
Extract the Engine trait (#10958) * Add client-traits crate Move the BlockInfo trait to new crate * New crate `machine` Contains code extracted from ethcore that defines `Machine`, `Externalities` and other execution related code. * Use new machine and client-traits crates in ethcore * Use new crates machine and client-traits instead of ethcore where appropriate * Fix tests * Don't re-export so many types from ethcore::client * Fixing more fallout from removing re-export * fix test * More fallout from not re-exporting types * Add some docs * cleanup * import the macro edition style * Tweak docs * Add missing import * remove unused ethabi_derive imports * Use latest ethabi-contract * Move many traits from ethcore/client/traits to client-traits crate Initial version of extracted Engine trait * Move snapshot related traits to the engine crate (eew) * Move a few snapshot related types to common_types Cleanup Executed as exported from machine crate * fix warning * Gradually introduce new engine crate: snapshot * ethcore typechecks with new engine crate * Sort out types outside ethcore * Add an EpochVerifier to ethash and use that in Engine.epoch_verifier() Cleanup * Document pub members * Sort out tests Sort out default impls for EpochVerifier * Add test-helpers feature and move EngineSigner impl to the right place * Sort out tests * Sort out tests and refactor verification types * Fix missing traits * More missing traits Fix Histogram * Fix tests and cleanup * cleanup * Put back needed logger import * Don't rexport common_types from ethcore/src/client Don't export ethcore::client::* * Remove files no longer used Use types from the engine crate Explicit exports from engine::engine * Get rid of itertools * Move a few more traits from ethcore to client-traits: BlockChainReset, ScheduleInfo, StateClient * Move ProvingBlockChainClient to client-traits * Don't re-export ForkChoice and Transition from ethcore * Address grumbles: sort imports, remove commented out code * Fix merge resolution error * merge failure
2019-08-15 17:59:22 +02:00
use engine::{Engine, StateDependentProof};
Extract engines to own crates (#10966) * Add client-traits crate Move the BlockInfo trait to new crate * New crate `machine` Contains code extracted from ethcore that defines `Machine`, `Externalities` and other execution related code. * Use new machine and client-traits crates in ethcore * Use new crates machine and client-traits instead of ethcore where appropriate * Fix tests * Don't re-export so many types from ethcore::client * Fixing more fallout from removing re-export * fix test * More fallout from not re-exporting types * Add some docs * cleanup * import the macro edition style * Tweak docs * Add missing import * remove unused ethabi_derive imports * Use latest ethabi-contract * Move many traits from ethcore/client/traits to client-traits crate Initial version of extracted Engine trait * Move snapshot related traits to the engine crate (eew) * Move a few snapshot related types to common_types Cleanup Executed as exported from machine crate * fix warning * Gradually introduce new engine crate: snapshot * ethcore typechecks with new engine crate * Sort out types outside ethcore * Add an EpochVerifier to ethash and use that in Engine.epoch_verifier() Cleanup * Document pub members * Sort out tests Sort out default impls for EpochVerifier * Add test-helpers feature and move EngineSigner impl to the right place * Sort out tests * Sort out tests and refactor verification types * Fix missing traits * More missing traits Fix Histogram * Fix tests and cleanup * cleanup * Put back needed logger import * Don't rexport common_types from ethcore/src/client Don't export ethcore::client::* * Remove files no longer used Use types from the engine crate Explicit exports from engine::engine * Get rid of itertools * Move a few more traits from ethcore to client-traits: BlockChainReset, ScheduleInfo, StateClient * Move ProvingBlockChainClient to client-traits * Don't re-export ForkChoice and Transition from ethcore * Address grumbles: sort imports, remove commented out code * Fix merge resolution error * Extract the Clique engine to own crate * Extract NullEngine and the block_reward module from ethcore * Extract InstantSeal engine to own crate * Extract remaining engines * Extract executive_state to own crate so it can be used by engine crates * Remove snapshot stuff from the engine crate * Put snapshot traits back in ethcore * cleanup * Remove stuff from ethcore * Don't use itertools * itertools in aura is legit-ish * More post-merge fixes * Re-export less types in client * cleanup * Update ethcore/block-reward/Cargo.toml Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update ethcore/engines/basic-authority/Cargo.toml Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update ethcore/engines/ethash/Cargo.toml Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update ethcore/engines/clique/src/lib.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * signers is already a ref * Add an EngineType enum to tighten up Engine.name() * Introduce Snapshotting enum to distinguish the type of snapshots a chain uses * Rename supports_warp to snapshot_mode * Missing import * Update ethcore/src/snapshot/consensus/mod.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * remove double-semicolons
2019-08-22 18:25:49 +02:00
use executive_state::{ProvedExecution, self};
use ethereum_types::{H256, U256, Address};
use ethtrie::{TrieError, TrieDB};
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY, KECCAK_EMPTY_LIST_RLP, keccak};
use hash_db::HashDB;
use kvdb::DBValue;
use parking_lot::Mutex;
use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field};
use rlp::RlpStream;
use trie::Trie;
use vm::EnvInfo;
const SUPPLIED_MATCHES: &str = "supplied responses always match produced requests; enforced by `check_response`; qed";
2017-04-06 20:01:09 +02:00
2017-04-05 18:56:01 +02:00
/// Core unit of the API: submit batches of these to be answered with `Response`s.
2017-04-06 17:22:05 +02:00
#[derive(Clone)]
2017-04-05 18:56:01 +02:00
pub enum Request {
/// A request for a header proof.
HeaderProof(HeaderProof),
/// A request for a header by hash.
HeaderByHash(HeaderByHash),
/// A request for a header by hash with a range of its ancestors.
HeaderWithAncestors(HeaderWithAncestors),
/// A request for the index of a transaction.
TransactionIndex(TransactionIndex),
2017-04-05 18:56:01 +02:00
/// A request for block receipts.
Receipts(BlockReceipts),
/// A request for a block body.
Body(Body),
/// A request for an account.
Account(Account),
/// A request for a contract's code.
Code(Code),
/// A request for proof of execution.
Execution(TransactionProof),
/// A request for epoch change signal.
Signal(Signal),
2017-04-05 18:56:01 +02:00
}
2017-04-06 20:01:09 +02:00
/// A request argument.
pub trait RequestArg {
/// the response type.
2017-05-09 14:24:45 +02:00
type Out;
2017-04-06 20:01:09 +02:00
/// Create the request type.
/// `extract` must not fail when presented with the corresponding
/// `Response`.
2017-05-09 14:24:45 +02:00
fn make(self) -> Request;
2017-04-06 20:01:09 +02:00
/// May not panic if the response corresponds with the request
/// from `make`.
/// Is free to panic otherwise.
2017-05-09 14:24:45 +02:00
fn extract(r: Response) -> Self::Out;
2017-04-06 20:01:09 +02:00
}
/// An adapter can be thought of as a grouping of request argument types.
/// This is implemented for various tuples and convenient types.
pub trait RequestAdapter {
/// The output type.
2017-05-09 14:24:45 +02:00
type Out;
2017-04-06 20:01:09 +02:00
/// Infallibly produce requests. When `extract_from` is presented
/// with the corresponding response vector, it may not fail.
2017-05-09 14:24:45 +02:00
fn make_requests(self) -> Vec<Request>;
2017-04-06 20:01:09 +02:00
/// Extract the output type from the given responses.
/// If they are the corresponding responses to the requests
/// made by `make_requests`, do not panic.
2017-05-09 14:24:45 +02:00
fn extract_from(Vec<Response>) -> Self::Out;
2017-04-06 20:01:09 +02:00
}
impl<T: RequestArg> RequestAdapter for Vec<T> {
type Out = Vec<T::Out>;
fn make_requests(self) -> Vec<Request> {
self.into_iter().map(RequestArg::make).collect()
}
fn extract_from(r: Vec<Response>) -> Self::Out {
r.into_iter().map(T::extract).collect()
}
}
2017-04-06 20:01:09 +02:00
// helper to implement `RequestArg` and `From` for a single request kind.
macro_rules! impl_single {
($variant: ident, $me: ty, $out: ty) => {
impl RequestArg for $me {
type Out = $out;
fn make(self) -> Request {
Request::$variant(self)
}
fn extract(r: Response) -> $out {
match r {
Response::$variant(x) => x,
_ => panic!(SUPPLIED_MATCHES),
}
}
}
impl From<$me> for Request {
fn from(me: $me) -> Request {
Request::$variant(me)
}
}
}
}
// implement traits for each kind of request.
impl_single!(HeaderProof, HeaderProof, (H256, U256));
impl_single!(HeaderByHash, HeaderByHash, encoded::Header);
impl_single!(HeaderWithAncestors, HeaderWithAncestors, Vec<encoded::Header>);
impl_single!(TransactionIndex, TransactionIndex, net_request::TransactionIndexResponse);
2017-04-06 20:01:09 +02:00
impl_single!(Receipts, BlockReceipts, Vec<Receipt>);
impl_single!(Body, Body, encoded::Block);
impl_single!(Account, Account, Option<BasicAccount>);
impl_single!(Code, Code, Bytes);
impl_single!(Execution, TransactionProof, super::ExecutionResult);
impl_single!(Signal, Signal, Vec<u8>);
2017-04-06 20:01:09 +02:00
macro_rules! impl_args {
2017-05-09 14:24:45 +02:00
() => {
impl<T: RequestArg> RequestAdapter for T {
type Out = T::Out;
fn make_requests(self) -> Vec<Request> {
vec![self.make()]
}
fn extract_from(mut responses: Vec<Response>) -> Self::Out {
T::extract(responses.pop().expect(SUPPLIED_MATCHES))
}
}
};
($first: ident, $($next: ident,)*) => {
impl<
$first: RequestArg,
$($next: RequestArg,)*
>
RequestAdapter for ($first, $($next,)*) {
type Out = ($first::Out, $($next::Out,)*);
fn make_requests(self) -> Vec<Request> {
let ($first, $($next,)*) = self;
vec![
$first.make(),
$($next.make(),)*
]
}
fn extract_from(responses: Vec<Response>) -> Self::Out {
let mut iter = responses.into_iter();
(
$first::extract(iter.next().expect(SUPPLIED_MATCHES)),
$($next::extract(iter.next().expect(SUPPLIED_MATCHES)),)*
)
}
}
impl_args!($($next,)*);
}
2017-04-06 20:01:09 +02:00
}
mod impls {
2017-05-09 14:24:45 +02:00
#![allow(non_snake_case)]
2017-04-06 20:01:09 +02:00
2017-05-09 14:24:45 +02:00
use super::{RequestAdapter, RequestArg, Request, Response, SUPPLIED_MATCHES};
2017-04-06 20:01:09 +02:00
2017-05-09 14:24:45 +02:00
impl_args!(A, B, C, D, E, F, G, H, I, J, K, L,);
2017-04-06 20:01:09 +02:00
}
/// A block header to be used for verification.
/// May be stored or an unresolved output of a prior request.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum HeaderRef {
/// A stored header.
Stored(encoded::Header),
/// An unresolved header. The first item here is the index of the request which
/// will return the header. The second is a back-reference pointing to a block hash
/// which can be used to make requests until that header is resolved.
Unresolved(usize, Field<H256>),
}
impl HeaderRef {
/// Attempt to inspect the header.
pub fn as_ref(&self) -> Result<&encoded::Header, Error> {
match *self {
HeaderRef::Stored(ref hdr) => Ok(hdr),
HeaderRef::Unresolved(idx, _) => Err(Error::UnresolvedHeader(idx)),
}
}
// get the blockhash field to be used in requests.
fn field(&self) -> Field<H256> {
match *self {
HeaderRef::Stored(ref hdr) => Field::Scalar(hdr.hash()),
HeaderRef::Unresolved(_, field) => field,
}
}
// yield the index of the request which will produce the header.
fn needs_header(&self) -> Option<(usize, Field<H256>)> {
match *self {
HeaderRef::Stored(_) => None,
HeaderRef::Unresolved(idx, field) => Some((idx, field)),
}
}
}
impl From<encoded::Header> for HeaderRef {
fn from(header: encoded::Header) -> Self {
HeaderRef::Stored(header)
}
}
2017-04-05 18:56:01 +02:00
/// Requests coupled with their required data for verification.
/// This is used internally but not part of the public API.
#[derive(Clone)]
#[allow(missing_docs)]
pub enum CheckedRequest {
HeaderProof(HeaderProof, net_request::IncompleteHeaderProofRequest),
HeaderByHash(HeaderByHash, net_request::IncompleteHeadersRequest),
HeaderWithAncestors(HeaderWithAncestors, net_request::IncompleteHeadersRequest),
TransactionIndex(TransactionIndex, net_request::IncompleteTransactionIndexRequest),
2017-04-05 18:56:01 +02:00
Receipts(BlockReceipts, net_request::IncompleteReceiptsRequest),
Body(Body, net_request::IncompleteBodyRequest),
Account(Account, net_request::IncompleteAccountRequest),
Code(Code, net_request::IncompleteCodeRequest),
Execution(TransactionProof, net_request::IncompleteExecutionRequest),
Signal(Signal, net_request::IncompleteSignalRequest)
2017-04-05 18:56:01 +02:00
}
2017-04-05 19:19:04 +02:00
impl From<Request> for CheckedRequest {
fn from(req: Request) -> Self {
match req {
Request::HeaderByHash(req) => {
let net_req = net_request::IncompleteHeadersRequest {
start: req.0.map(Into::into),
2017-04-05 19:19:04 +02:00
skip: 0,
max: 1,
reverse: false,
};
trace!(target: "on_demand", "HeaderByHash Request, {:?}", net_req);
2017-04-05 19:19:04 +02:00
CheckedRequest::HeaderByHash(req, net_req)
}
Request::HeaderWithAncestors(req) => {
let net_req = net_request::IncompleteHeadersRequest {
start: req.block_hash.map(Into::into),
skip: 0,
max: req.ancestor_count + 1,
reverse: true,
};
trace!(target: "on_demand", "HeaderWithAncestors Request, {:?}", net_req);
CheckedRequest::HeaderWithAncestors(req, net_req)
}
2017-04-05 19:19:04 +02:00
Request::HeaderProof(req) => {
let net_req = net_request::IncompleteHeaderProofRequest {
num: req.num().into(),
};
trace!(target: "on_demand", "HeaderProof Request, {:?}", net_req);
2017-04-05 19:19:04 +02:00
CheckedRequest::HeaderProof(req, net_req)
}
Request::TransactionIndex(req) => {
let net_req = net_request::IncompleteTransactionIndexRequest {
hash: req.0,
};
trace!(target: "on_demand", "TransactionIndex Request, {:?}", net_req);
CheckedRequest::TransactionIndex(req, net_req)
}
Request::Body(req) => {
2017-04-05 19:19:04 +02:00
let net_req = net_request::IncompleteBodyRequest {
hash: req.0.field(),
2017-04-05 19:19:04 +02:00
};
trace!(target: "on_demand", "Body Request, {:?}", net_req);
2017-04-05 19:19:04 +02:00
CheckedRequest::Body(req, net_req)
}
Request::Receipts(req) => {
let net_req = net_request::IncompleteReceiptsRequest {
hash: req.0.field(),
2017-04-05 19:19:04 +02:00
};
trace!(target: "on_demand", "Receipt Request, {:?}", net_req);
2017-04-05 19:19:04 +02:00
CheckedRequest::Receipts(req, net_req)
}
Request::Account(req) => {
2017-04-05 19:19:04 +02:00
let net_req = net_request::IncompleteAccountRequest {
block_hash: req.header.field(),
2017-08-31 11:35:41 +02:00
address_hash: ::hash::keccak(&req.address).into(),
2017-04-05 19:19:04 +02:00
};
trace!(target: "on_demand", "Account Request, {:?}", net_req);
2017-04-05 19:19:04 +02:00
CheckedRequest::Account(req, net_req)
}
Request::Code(req) => {
let net_req = net_request::IncompleteCodeRequest {
block_hash: req.header.field(),
code_hash: req.code_hash,
2017-04-05 19:19:04 +02:00
};
trace!(target: "on_demand", "Code Request, {:?}", net_req);
2017-04-05 19:19:04 +02:00
CheckedRequest::Code(req, net_req)
}
Request::Execution(req) => {
let net_req = net_request::IncompleteExecutionRequest {
block_hash: req.header.field(),
2017-04-05 19:19:04 +02:00
from: req.tx.sender(),
gas: req.tx.gas,
gas_price: req.tx.gas_price,
action: req.tx.action.clone(),
value: req.tx.value,
data: req.tx.data.clone(),
};
trace!(target: "on_demand", "Execution request, {:?}", net_req);
2017-04-05 19:19:04 +02:00
CheckedRequest::Execution(req, net_req)
}
Request::Signal(req) => {
let net_req = net_request::IncompleteSignalRequest {
block_hash: req.hash.into(),
};
trace!(target: "on_demand", "Signal Request, {:?}", net_req);
CheckedRequest::Signal(req, net_req)
}
2017-04-05 19:19:04 +02:00
}
}
}
2017-04-06 15:34:48 +02:00
impl CheckedRequest {
/// Convert this into a network request.
pub fn into_net_request(self) -> net_request::Request {
use ::request::Request as NetRequest;
match self {
CheckedRequest::HeaderProof(_, req) => NetRequest::HeaderProof(req),
CheckedRequest::HeaderByHash(_, req) => NetRequest::Headers(req),
CheckedRequest::HeaderWithAncestors(_, req) => NetRequest::Headers(req),
CheckedRequest::TransactionIndex(_, req) => NetRequest::TransactionIndex(req),
2017-04-06 15:34:48 +02:00
CheckedRequest::Receipts(_, req) => NetRequest::Receipts(req),
CheckedRequest::Body(_, req) => NetRequest::Body(req),
CheckedRequest::Account(_, req) => NetRequest::Account(req),
CheckedRequest::Code(_, req) => NetRequest::Code(req),
CheckedRequest::Execution(_, req) => NetRequest::Execution(req),
CheckedRequest::Signal(_, req) => NetRequest::Signal(req),
2017-04-06 15:34:48 +02:00
}
}
/// Whether this needs a header from a prior request.
/// Returns `Some` with the index of the request returning the header
/// and the field giving the hash
/// if so, `None` otherwise.
pub fn needs_header(&self) -> Option<(usize, Field<H256>)> {
match *self {
CheckedRequest::Receipts(ref x, _) => x.0.needs_header(),
CheckedRequest::Body(ref x, _) => x.0.needs_header(),
CheckedRequest::Account(ref x, _) => x.header.needs_header(),
CheckedRequest::Code(ref x, _) => x.header.needs_header(),
CheckedRequest::Execution(ref x, _) => x.header.needs_header(),
_ => None,
}
}
/// Provide a header where one was needed. Should only be called if `needs_header`
/// returns `Some`, and for correctness, only use the header yielded by the correct
/// request.
pub fn provide_header(&mut self, header: encoded::Header) {
match *self {
CheckedRequest::Receipts(ref mut x, _) => x.0 = HeaderRef::Stored(header),
CheckedRequest::Body(ref mut x, _) => x.0 = HeaderRef::Stored(header),
CheckedRequest::Account(ref mut x, _) => x.header = HeaderRef::Stored(header),
CheckedRequest::Code(ref mut x, _) => x.header = HeaderRef::Stored(header),
CheckedRequest::Execution(ref mut x, _) => x.header = HeaderRef::Stored(header),
_ => {},
}
}
/// Attempt to complete the request based on data in the cache.
pub fn respond_local(&self, cache: &Mutex<::cache::Cache>) -> Option<Response> {
match *self {
CheckedRequest::HeaderProof(ref check, _) => {
let mut cache = cache.lock();
cache.block_hash(check.num)
.and_then(|h| cache.chain_score(&h).map(|s| (h, s)))
.map(|(h, s)| Response::HeaderProof((h, s)))
}
CheckedRequest::HeaderByHash(_, ref req) => {
if let Some(&net_request::HashOrNumber::Hash(ref h)) = req.start.as_ref() {
return cache.lock().block_header(h).map(Response::HeaderByHash);
}
None
}
CheckedRequest::HeaderWithAncestors(_, ref req) => {
if req.skip != 1 || !req.reverse {
return None;
}
if let Some(&net_request::HashOrNumber::Hash(start)) = req.start.as_ref() {
let mut result = Vec::with_capacity(req.max as usize);
let mut hash = start;
let mut cache = cache.lock();
for _ in 0..req.max {
match cache.block_header(&hash) {
Some(header) => {
hash = header.parent_hash();
result.push(header);
}
None => return None,
}
}
Some(Response::HeaderWithAncestors(result))
} else { None }
}
CheckedRequest::Receipts(ref check, ref req) => {
// empty transactions -> no receipts
2017-08-31 11:35:41 +02:00
if check.0.as_ref().ok().map_or(false, |hdr| hdr.receipts_root() == KECCAK_NULL_RLP) {
return Some(Response::Receipts(Vec::new()));
}
req.hash.as_ref()
.and_then(|hash| cache.lock().block_receipts(hash))
.map(Response::Receipts)
}
CheckedRequest::Body(ref check, ref req) => {
// check for empty body.
if let Ok(hdr) = check.0.as_ref() {
2017-08-31 11:35:41 +02:00
if hdr.transactions_root() == KECCAK_NULL_RLP && hdr.uncles_hash() == KECCAK_EMPTY_LIST_RLP {
let mut stream = RlpStream::new_list(3);
stream.append_raw(hdr.rlp().as_raw(), 1);
stream.begin_list(0);
stream.begin_list(0);
return Some(Response::Body(encoded::Block::new(stream.out())));
}
}
// otherwise, check for cached body and header.
let block_hash = req.hash.as_ref()
.cloned()
.or_else(|| check.0.as_ref().ok().map(|hdr| hdr.hash()));
let block_hash = match block_hash {
Some(hash) => hash,
None => return None,
};
let mut cache = cache.lock();
let cached_header;
// can't use as_ref here although it seems like you would be able to:
// it complains about uninitialized `cached_header`.
let block_header = match check.0.as_ref().ok() {
Some(hdr) => Some(hdr),
None => {
cached_header = cache.block_header(&block_hash);
cached_header.as_ref()
}
};
block_header
.and_then(|hdr| cache.block_body(&block_hash).map(|b| (hdr, b)))
.map(|(hdr, body)| {
Response::Body(encoded::Block::new_from_header_and_body(&hdr.view(), &body.view()))
})
}
CheckedRequest::Code(_, ref req) => {
2017-08-31 11:35:41 +02:00
if req.code_hash.as_ref().map_or(false, |&h| h == KECCAK_EMPTY) {
Some(Response::Code(Vec::new()))
} else {
None
}
}
_ => None,
}
}
2017-04-06 15:34:48 +02:00
}
2017-05-12 18:00:01 +02:00
macro_rules! match_me {
($me: expr, ($check: pat, $req: pat) => $e: expr) => {
match $me {
CheckedRequest::HeaderProof($check, $req) => $e,
CheckedRequest::HeaderByHash($check, $req) => $e,
CheckedRequest::HeaderWithAncestors($check, $req) => $e,
CheckedRequest::TransactionIndex($check, $req) => $e,
2017-05-12 18:00:01 +02:00
CheckedRequest::Receipts($check, $req) => $e,
CheckedRequest::Body($check, $req) => $e,
CheckedRequest::Account($check, $req) => $e,
CheckedRequest::Code($check, $req) => $e,
CheckedRequest::Execution($check, $req) => $e,
CheckedRequest::Signal($check, $req) => $e,
2017-05-12 18:00:01 +02:00
}
}
}
2017-04-05 18:56:01 +02:00
impl IncompleteRequest for CheckedRequest {
type Complete = CompleteRequest;
2017-04-05 18:56:01 +02:00
type Response = net_request::Response;
fn check_outputs<F>(&self, mut f: F) -> Result<(), net_request::NoSuchOutput>
2017-04-05 18:56:01 +02:00
where F: FnMut(usize, usize, OutputKind) -> Result<(), net_request::NoSuchOutput>
{
match *self {
CheckedRequest::HeaderProof(_, ref req) => req.check_outputs(f),
CheckedRequest::HeaderByHash(ref check, ref req) => {
req.check_outputs(&mut f)?;
// make sure the output given is definitively a hash.
match check.0 {
Field::BackReference(r, idx) => f(r, idx, OutputKind::Hash),
_ => Ok(()),
}
}
CheckedRequest::HeaderWithAncestors(ref check, ref req) => {
req.check_outputs(&mut f)?;
// make sure the output given is definitively a hash.
match check.block_hash {
Field::BackReference(r, idx) => f(r, idx, OutputKind::Hash),
_ => Ok(()),
}
}
CheckedRequest::TransactionIndex(_, ref req) => req.check_outputs(f),
CheckedRequest::Receipts(_, ref req) => req.check_outputs(f),
CheckedRequest::Body(_, ref req) => req.check_outputs(f),
CheckedRequest::Account(_, ref req) => req.check_outputs(f),
CheckedRequest::Code(_, ref req) => req.check_outputs(f),
CheckedRequest::Execution(_, ref req) => req.check_outputs(f),
CheckedRequest::Signal(_, ref req) => req.check_outputs(f),
}
2017-04-05 18:56:01 +02:00
}
fn note_outputs<F>(&self, f: F) where F: FnMut(usize, OutputKind) {
2017-05-12 18:00:01 +02:00
match_me!(*self, (_, ref req) => req.note_outputs(f))
2017-04-05 18:56:01 +02:00
}
fn fill<F>(&mut self, f: F) where F: Fn(usize, usize) -> Result<Output, net_request::NoSuchOutput> {
2017-05-12 18:00:01 +02:00
match_me!(*self, (_, ref mut req) => req.fill(f))
2017-04-05 18:56:01 +02:00
}
fn complete(self) -> Result<Self::Complete, net_request::NoSuchOutput> {
match self {
CheckedRequest::HeaderProof(_, req) => {
trace!(target: "on_demand", "HeaderProof request completed {:?}", req);
req.complete().map(CompleteRequest::HeaderProof)
}
CheckedRequest::HeaderByHash(_, req) => {
trace!(target: "on_demand", "HeaderByHash request completed {:?}", req);
req.complete().map(CompleteRequest::Headers)
}
CheckedRequest::HeaderWithAncestors(_, req) => {
trace!(target: "on_demand", "HeaderWithAncestors request completed {:?}", req);
req.complete().map(CompleteRequest::Headers)
}
CheckedRequest::TransactionIndex(_, req) => {
trace!(target: "on_demand", "TransactionIndex request completed {:?}", req);
req.complete().map(CompleteRequest::TransactionIndex)
}
CheckedRequest::Receipts(_, req) => {
trace!(target: "on_demand", "Receipt request completed {:?}", req);
req.complete().map(CompleteRequest::Receipts)
}
CheckedRequest::Body(_, req) => {
trace!(target: "on_demand", "Block request completed {:?}", req);
req.complete().map(CompleteRequest::Body)
}
CheckedRequest::Account(_, req) => {
trace!(target: "on_demand", "Account request completed {:?}", req);
req.complete().map(CompleteRequest::Account)
}
CheckedRequest::Code(_, req) => {
trace!(target: "on_demand", "Code request completed {:?}", req);
req.complete().map(CompleteRequest::Code)
}
CheckedRequest::Execution(_, req) => {
trace!(target: "on_demand", "Execution request completed {:?}", req);
req.complete().map(CompleteRequest::Execution)
}
CheckedRequest::Signal(_, req) => {
trace!(target: "on_demand", "Signal request completed {:?}", req);
req.complete().map(CompleteRequest::Signal)
}
2017-04-05 18:56:01 +02:00
}
}
2017-04-06 15:34:48 +02:00
fn adjust_refs<F>(&mut self, mapping: F) where F: FnMut(usize) -> usize {
2017-05-12 18:00:01 +02:00
match_me!(*self, (_, ref mut req) => req.adjust_refs(mapping))
2017-04-06 15:34:48 +02:00
}
2017-04-05 18:56:01 +02:00
}
impl net_request::CheckedRequest for CheckedRequest {
type Extract = Response;
type Error = Error;
2017-04-06 17:22:05 +02:00
type Environment = Mutex<::cache::Cache>;
2017-04-05 18:56:01 +02:00
/// Check whether the response matches (beyond the type).
fn check_response(&self, complete: &Self::Complete, cache: &Mutex<::cache::Cache>, response: &Self::Response) -> Result<Response, Error> {
2017-04-05 18:56:01 +02:00
use ::request::Response as NetResponse;
2017-05-12 17:16:38 +02:00
// helper for expecting a specific response for a given request.
macro_rules! expect {
($res: pat => $e: expr) => {{
match (response, complete) {
2017-05-12 17:16:38 +02:00
$res => $e,
_ => Err(Error::WrongKind),
}
}}
2017-05-12 17:16:38 +02:00
}
2017-04-05 18:56:01 +02:00
// check response against contained prover.
2017-05-12 17:16:38 +02:00
match *self {
CheckedRequest::HeaderProof(ref prover, _) =>
expect!((&NetResponse::HeaderProof(ref res), _) =>
prover.check_response(cache, &res.proof).map(Response::HeaderProof)),
CheckedRequest::HeaderByHash(ref prover, _) =>
expect!((&NetResponse::Headers(ref res), &CompleteRequest::Headers(ref req)) =>
prover.check_response(cache, &req.start, &res.headers).map(Response::HeaderByHash)),
CheckedRequest::HeaderWithAncestors(ref prover, _) =>
expect!((&NetResponse::Headers(ref res), &CompleteRequest::Headers(ref req)) =>
prover.check_response(cache, &req.start, &res.headers).map(Response::HeaderWithAncestors)),
CheckedRequest::TransactionIndex(ref prover, _) =>
expect!((&NetResponse::TransactionIndex(ref res), _) =>
prover.check_response(cache, res).map(Response::TransactionIndex)),
CheckedRequest::Receipts(ref prover, _) =>
expect!((&NetResponse::Receipts(ref res), _) =>
prover.check_response(cache, &res.receipts).map(Response::Receipts)),
CheckedRequest::Body(ref prover, _) =>
expect!((&NetResponse::Body(ref res), _) =>
prover.check_response(cache, &res.body).map(Response::Body)),
CheckedRequest::Account(ref prover, _) =>
expect!((&NetResponse::Account(ref res), _) =>
prover.check_response(cache, &res.proof).map(Response::Account)),
CheckedRequest::Code(ref prover, _) =>
expect!((&NetResponse::Code(ref res), &CompleteRequest::Code(ref req)) =>
prover.check_response(cache, &req.code_hash, &res.code).map(Response::Code)),
CheckedRequest::Execution(ref prover, _) =>
expect!((&NetResponse::Execution(ref res), _) =>
prover.check_response(cache, &res.items).map(Response::Execution)),
CheckedRequest::Signal(ref prover, _) =>
expect!((&NetResponse::Signal(ref res), _) =>
prover.check_response(cache, &res.signal).map(Response::Signal)),
2017-04-05 18:56:01 +02:00
}
}
}
/// Responses to on-demand requests.
/// All of these are checked.
pub enum Response {
/// Response to a header proof request.
/// Returns the hash and chain score.
2017-04-06 20:01:09 +02:00
HeaderProof((H256, U256)),
2017-04-05 18:56:01 +02:00
/// Response to a header-by-hash request.
HeaderByHash(encoded::Header),
/// Response to a header-by-hash with ancestors request.
HeaderWithAncestors(Vec<encoded::Header>),
/// Response to a transaction-index request.
TransactionIndex(net_request::TransactionIndexResponse),
2017-04-05 18:56:01 +02:00
/// Response to a receipts request.
Receipts(Vec<Receipt>),
/// Response to a block body request.
Body(encoded::Block),
/// Response to an Account request.
// TODO: `unwrap_or(engine_defaults)`
Account(Option<BasicAccount>),
/// Response to a request for code.
Code(Vec<u8>),
/// Response to a request for proved execution.
2017-04-06 17:22:05 +02:00
Execution(super::ExecutionResult),
/// Response to a request for epoch change signal.
Signal(Vec<u8>),
2017-04-05 18:56:01 +02:00
}
impl net_request::ResponseLike for Response {
fn fill_outputs<F>(&self, mut f: F) where F: FnMut(usize, Output) {
match *self {
Response::HeaderProof((ref hash, _)) => f(0, Output::Hash(*hash)),
Response::Account(None) => {
2017-08-31 11:35:41 +02:00
f(0, Output::Hash(KECCAK_EMPTY)); // code hash
f(1, Output::Hash(KECCAK_NULL_RLP)); // storage root.
}
Response::Account(Some(ref acc)) => {
f(0, Output::Hash(acc.code_hash));
f(1, Output::Hash(acc.storage_root));
}
_ => {}
}
}
}
/// Errors in verification.
#[derive(Debug, PartialEq)]
pub enum Error {
/// RLP decoder error.
Decoder(::rlp::DecoderError),
2017-04-05 18:56:01 +02:00
/// Empty response.
Empty,
/// Response data length exceeds request max.
TooManyResults(u64, u64),
/// Response data is incomplete.
TooFewResults(u64, u64),
/// Trie lookup error (result of bad proof)
Trie(TrieError),
/// Bad inclusion proof
BadProof,
/// Header by number instead of hash.
HeaderByNumber,
/// Unresolved header reference.
UnresolvedHeader(usize),
/// Wrong header number.
WrongNumber(u64, u64),
2017-02-07 15:29:38 +01:00
/// Wrong hash.
WrongHash(H256, H256),
/// Wrong trie root.
WrongTrieRoot(H256, H256),
2017-04-05 18:56:01 +02:00
/// Wrong response kind.
WrongKind,
/// Wrong sequence of headers.
WrongHeaderSequence,
}
impl From<::rlp::DecoderError> for Error {
fn from(err: ::rlp::DecoderError) -> Self {
Error::Decoder(err)
}
}
impl From<Box<TrieError>> for Error {
fn from(err: Box<TrieError>) -> Self {
Error::Trie(*err)
}
}
2017-03-16 20:23:59 +01:00
/// Request for header proof by number
2017-01-04 12:48:07 +01:00
#[derive(Debug, Clone, PartialEq, Eq)]
2017-03-16 20:23:59 +01:00
pub struct HeaderProof {
/// The header's number.
2017-02-07 16:13:56 +01:00
num: u64,
/// The cht number for the given block number.
cht_num: u64,
/// The root of the CHT containing this header.
2017-02-07 16:13:56 +01:00
cht_root: H256,
}
2017-03-16 20:23:59 +01:00
impl HeaderProof {
2017-02-07 16:13:56 +01:00
/// Construct a new header-by-number request. Fails if the given number is 0.
/// Provide the expected CHT root to compare against.
pub fn new(num: u64, cht_root: H256) -> Option<Self> {
2017-03-16 20:23:59 +01:00
::cht::block_to_cht_number(num).map(|cht_num| HeaderProof {
num,
cht_num,
cht_root,
2017-02-07 16:13:56 +01:00
})
}
/// Access the requested block number.
pub fn num(&self) -> u64 { self.num }
/// Access the CHT number.
pub fn cht_num(&self) -> u64 { self.cht_num }
/// Access the expected CHT root.
pub fn cht_root(&self) -> H256 { self.cht_root }
2017-03-16 20:23:59 +01:00
/// Check a response with a CHT proof, get a hash and total difficulty back.
2017-04-06 17:22:05 +02:00
pub fn check_response(&self, cache: &Mutex<::cache::Cache>, proof: &[Bytes]) -> Result<(H256, U256), Error> {
2017-03-16 20:23:59 +01:00
match ::cht::check_proof(proof, self.num, self.cht_root) {
2017-04-06 17:22:05 +02:00
Some((expected_hash, td)) => {
let mut cache = cache.lock();
cache.insert_block_hash(self.num, expected_hash);
cache.insert_chain_score(expected_hash, td);
Ok((expected_hash, td))
}
2017-03-16 20:23:59 +01:00
None => Err(Error::BadProof),
}
}
}
/// Request for a header by hash with a range of ancestors.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HeaderWithAncestors {
/// Hash of the last block in the range to fetch.
pub block_hash: Field<H256>,
/// Number of headers before the last block to fetch in addition.
pub ancestor_count: u64,
}
impl HeaderWithAncestors {
/// Check a response for the headers.
pub fn check_response(
&self,
cache: &Mutex<::cache::Cache>,
start: &net_request::HashOrNumber,
headers: &[encoded::Header]
) -> Result<Vec<encoded::Header>, Error> {
let expected_hash = match (self.block_hash, start) {
(Field::Scalar(h), &net_request::HashOrNumber::Hash(h2)) => {
if h != h2 { return Err(Error::WrongHash(h, h2)) }
h
}
(_, &net_request::HashOrNumber::Hash(h2)) => h2,
_ => return Err(Error::HeaderByNumber),
};
let start_header = headers.first().ok_or(Error::Empty)?;
let start_hash = start_header.hash();
if start_hash != expected_hash {
return Err(Error::WrongHash(expected_hash, start_hash));
}
let expected_len = 1 + cmp::min(self.ancestor_count, start_header.number());
let actual_len = headers.len() as u64;
match actual_len.cmp(&expected_len) {
cmp::Ordering::Less =>
return Err(Error::TooFewResults(expected_len, actual_len)),
cmp::Ordering::Greater =>
return Err(Error::TooManyResults(expected_len, actual_len)),
cmp::Ordering::Equal => (),
};
for (header, prev_header) in headers.iter().zip(headers[1..].iter()) {
if header.number() != prev_header.number() + 1 ||
header.parent_hash() != prev_header.hash()
{
return Err(Error::WrongHeaderSequence)
}
}
let mut cache = cache.lock();
for header in headers {
cache.insert_block_header(header.hash(), header.clone());
}
Ok(headers.to_vec())
}
}
/// Request for a header by hash.
2017-01-04 12:48:07 +01:00
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HeaderByHash(pub Field<H256>);
impl HeaderByHash {
/// Check a response for the header.
pub fn check_response(
&self,
cache: &Mutex<::cache::Cache>,
start: &net_request::HashOrNumber,
headers: &[encoded::Header]
) -> Result<encoded::Header, Error> {
let expected_hash = match (self.0, start) {
(Field::Scalar(h), &net_request::HashOrNumber::Hash(h2)) => {
if h != h2 { return Err(Error::WrongHash(h, h2)) }
h
}
(_, &net_request::HashOrNumber::Hash(h2)) => h2,
_ => return Err(Error::HeaderByNumber),
};
2017-04-05 18:56:01 +02:00
let header = headers.get(0).ok_or(Error::Empty)?;
2017-08-31 11:35:41 +02:00
let hash = header.hash();
if hash == expected_hash {
cache.lock().insert_block_header(hash, header.clone());
Ok(header.clone())
} else {
Err(Error::WrongHash(expected_hash, hash))
}
}
}
/// Request for a transaction index.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TransactionIndex(pub Field<H256>);
impl TransactionIndex {
/// Check a response for the transaction index.
//
// TODO: proper checking involves looking at canonicality of the
// hash w.r.t. the current best block header.
//
// unlike all other forms of request, we don't know the header to check
// until we make this request.
//
// This would require lookups in the database or perhaps CHT requests,
// which aren't currently possible.
//
// Also, returning a result that is not locally canonical doesn't necessarily
// indicate misbehavior, so the punishment scheme would need to be revised.
pub fn check_response(
&self,
_cache: &Mutex<::cache::Cache>,
res: &net_request::TransactionIndexResponse,
) -> Result<net_request::TransactionIndexResponse, Error> {
Ok(res.clone())
}
}
/// Request for a block, with header for verification.
2017-01-04 12:48:07 +01:00
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Body(pub HeaderRef);
impl Body {
/// Check a response for this block body.
2017-04-06 17:22:05 +02:00
pub fn check_response(&self, cache: &Mutex<::cache::Cache>, body: &encoded::Body) -> Result<encoded::Block, Error> {
// check the integrity of the the body against the header
let header = self.0.as_ref()?;
let tx_root = ::triehash::ordered_trie_root(body.transactions_rlp().iter().map(|r| r.as_raw()));
if tx_root != header.transactions_root() {
trace!(target: "on_demand", "Body Response: \"WrongTrieRoot\" tx_root: {:?} header_root: {:?}", tx_root, header.transactions_root());
return Err(Error::WrongTrieRoot(header.transactions_root(), tx_root));
}
let uncles_hash = keccak(body.uncles_rlp().as_raw());
if uncles_hash != header.uncles_hash() {
trace!(target: "on_demand", "Body Response: \"WrongHash\" tx_root: {:?} header_root: {:?}", uncles_hash, header.uncles_hash());
return Err(Error::WrongHash(header.uncles_hash(), uncles_hash));
}
// concatenate the header and the body.
let block = encoded::Block::new_from_header_and_body(&header.view(), &body.view());
cache.lock().insert_block_body(header.hash(), body.clone());
Ok(block)
}
}
/// Request for a block's receipts with header for verification.
2017-01-04 12:48:07 +01:00
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BlockReceipts(pub HeaderRef);
impl BlockReceipts {
/// Check a response with receipts against the stored header.
2017-04-06 17:22:05 +02:00
pub fn check_response(&self, cache: &Mutex<::cache::Cache>, receipts: &[Receipt]) -> Result<Vec<Receipt>, Error> {
let receipts_root = self.0.as_ref()?.receipts_root();
2018-02-16 20:24:16 +01:00
let found_root = ::triehash::ordered_trie_root(receipts.iter().map(|r| ::rlp::encode(r)));
if receipts_root == found_root {
cache.lock().insert_block_receipts(receipts_root, receipts.to_vec());
Ok(receipts.to_vec())
} else {
trace!(target: "on_demand", "Receipt Reponse: \"WrongTrieRoot\" receipts_root: {:?} found_root: {:?}", receipts_root, found_root);
Err(Error::WrongTrieRoot(receipts_root, found_root))
}
}
}
/// Request for an account structure.
2017-01-04 12:48:07 +01:00
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Account {
/// Header for verification.
pub header: HeaderRef,
/// Address requested.
pub address: Address,
}
impl Account {
/// Check a response with an account against the stored header.
2017-04-06 17:22:05 +02:00
pub fn check_response(&self, _: &Mutex<::cache::Cache>, proof: &[Bytes]) -> Result<Option<BasicAccount>, Error> {
let header = self.header.as_ref()?;
let state_root = header.state_root();
let mut db = journaldb::new_memory_db();
for node in proof { db.insert(hash_db::EMPTY_PREFIX, &node[..]); }
2017-01-03 19:13:40 +01:00
Upgrade ethereum types (#10670) * cargo upgrade "ethereum-types" --all --allow-prerelease * [ethash] fix compilation errors * [ethkey] fix compilation errors * [journaldb] fix compilation errors * [dir] fix compilation errors * [ethabi] update to 0.7 * wip * [eip-712] fix compilation errors * [ethjson] fix compilation errors * [Cargo.toml] add TODO to remove patches * [ethstore] fix compilation errors * use patched keccak-hash with new primitive-types * wip * [ethcore-network-devp2p] fix compilation errors * [vm] fix compilation errors * [common-types, evm, wasm] fix compilation errors * [ethcore-db] Require AsRef instead of Deref for keys * [ethcore-blockchain] fix some compilation errors * [blooms-db] fix compilation errors Thanks a lot @dvdplm :) * we don't need no rlp ethereum feature * [ethcore] fix some compilation errors * [parity-ipfs-api] fix compilation error * [ethcore-light] fix compilation errors * [Cargo.lock] update parity-common * [ethcore-private-tx] fix some compilation errors * wip * [ethcore-private-tx] fix compilation errors * [parity-updater] fix compilation errors * [parity-rpc] fix compilation errors * [parity-bin] fix other compilation errors * update to new ethereum-types * update keccak-hash * [fastmap] fix compilation in tests * [blooms-db] fix compilation in tests * [common-types] fix compilation in tests * [triehash-ethereum] fix compilation in tests * [ethkey] fix compilation in tests * [pwasm-run-test] fix compilation errors * [wasm] fix compilation errors * [ethjson] fix compilation in tests * [eip-712] fix compilation in tests * [ethcore-blockchain] fix compilation in tests * [ethstore] fix compilation in tests * [ethstore-accounts] fix compilation in tests * [parity-hash-fetch] fix compilation in tests * [parity-whisper] fix compilation in tests * [ethcore-miner] fix compilation in tests * [ethcore-network-devp2p] fix compilation in tests * [*] upgrade rand to 0.6 * [evm] get rid of num-bigint conversions * [ethcore] downgrade trie-standardmap and criterion * [ethcore] fix some warnings * [ethcore] fix compilation in tests * [evmbin] fix compilation in tests * [updater] fix compilation in tests * [ethash] fix compilation in tests * [ethcore-secretstore] fix compilation in tests * [ethcore-sync] fix compilation in tests * [parity-rpc] fix compilation in tests * [ethcore] finally fix compilation in tests FUCK YEAH!!! * [ethstore] lazy_static is unused * [ethcore] fix test * fix up bad merge * [Cargo.toml] remove unused patches * [*] replace some git dependencies with crates.io * [Cargo.toml] remove unused lazy_static * [*] clean up * [ethcore] fix transaction_filter_deprecated test * [private-tx] fix serialization tests * fix more serialization tests * [ethkey] fix smoky test * [rpc] fix tests, please? * [ethcore] remove commented out code * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * [ethstore] remove unused dev-dependency * [ethcore] remove resolved TODO * [*] resolve keccak-hash TODO * [*] s/Address::default()/Address::zero() * [rpc] remove Subscribers::new_test * [rpc] remove EthPubSubClient::new_test * [ethcore] use trie-standardmap from crates.io * [dir] fix db_root_path * [ethcore] simplify snapshot::tests::helpers::fill_storage * Apply suggestions from code review Co-Authored-By: David <dvdplm@gmail.com> * [ethcore-secretstore] resolve TODO in serialization * [ethcore-network-devp2p] resolve TODO in save_key * [Cargo.lock] update triehash * [*] use ethabi from crates.io * [ethkey] use secp256k1 from master branch * [Cargo.lock] update eth-secp256k1
2019-06-03 15:36:21 +02:00
match TrieDB::new(&db, &state_root).and_then(|t| t.get(keccak(&self.address).as_bytes()))? {
2017-01-03 19:13:40 +01:00
Some(val) => {
Ok(Some(rlp::decode::<BasicAccount>(&val)?))
2017-01-03 19:13:40 +01:00
},
None => {
trace!(target: "on_demand", "Account {:?} not found", self.address);
Ok(None)
}
}
}
}
2017-01-04 12:48:07 +01:00
2017-02-07 15:29:38 +01:00
/// Request for account code.
2017-04-05 18:56:01 +02:00
#[derive(Debug, Clone, PartialEq, Eq)]
2017-02-07 15:29:38 +01:00
pub struct Code {
/// Header reference.
pub header: HeaderRef,
2017-02-07 15:29:38 +01:00
/// Account's code hash.
pub code_hash: Field<H256>,
2017-02-07 15:29:38 +01:00
}
impl Code {
/// Check a response with code against the code hash.
pub fn check_response(
&self,
_: &Mutex<::cache::Cache>,
code_hash: &H256,
code: &[u8]
) -> Result<Vec<u8>, Error> {
2017-08-31 11:35:41 +02:00
let found_hash = keccak(code);
if &found_hash == code_hash {
2017-04-05 18:56:01 +02:00
Ok(code.to_vec())
2017-02-07 15:29:38 +01:00
} else {
Err(Error::WrongHash(*code_hash, found_hash))
2017-02-07 15:29:38 +01:00
}
}
}
/// Request for transaction execution, along with the parts necessary to verify the proof.
2017-04-05 18:56:01 +02:00
#[derive(Clone)]
pub struct TransactionProof {
/// The transaction to request proof of.
pub tx: SignedTransaction,
/// Block header.
pub header: HeaderRef,
/// Transaction environment info.
// TODO: it's not really possible to provide this if the header is unknown.
pub env_info: EnvInfo,
/// Consensus engine.
pub engine: Arc<dyn Engine>,
}
impl TransactionProof {
/// Check the proof, returning the proved execution or indicate that the proof was bad.
2017-04-06 17:22:05 +02:00
pub fn check_response(&self, _: &Mutex<::cache::Cache>, state_items: &[DBValue]) -> Result<super::ExecutionResult, Error> {
let root = self.header.as_ref()?.state_root();
let mut env_info = self.env_info.clone();
env_info.gas_limit = self.tx.gas;
Move more code into state-account (#10840) * WIP move errors, pod_account and state account to own crates * Sort out dependencies, fix broken code and tests Remove botched ethcore-error crate * remove template line * fix review feedback * Remove test-only AccountDBMut::new * Extract AccountDB to account-db * Move Substate to state-account – wip * Add lib.rs * cleanup * test failure * test failure 2 * third time's the charm * Add factories crate * Use new factories crate * Use factories crate * Extract trace * Fix tests * Sort out parity-util-mem and parking_lot * cleanup * WIP port over the rest of state from ethcore * Collect all impls for Machine * some notes * Rename pod-account to pod * Move PodState to pod crate * Use PodState from pod crate * Fix use clause for json tests * Sort out evmbin * Add missing code and use PodState * Move code that depends on Machine and Executive to own module * Sort out cloning errors, fix ethcore to use new state crate * Do without funky From impls * Fix ethcore tests * Fixes around the project to use new state crate * Add back the more specific impls of StateOrBlock From conversions * Move execute to freestanding function and remove it from trait Sort out the error handling in executive_state by moving the result types from state to ethcore Undo the verbose code added to work around the StateOrBlock From conversions * cleanup * Fix "error: enum variants on type aliases are experimental" * Bring back the state tests Fix whitespace * remove ethcore/state/mod.rs * cleanup * cleanup * Cleanup state-account errors * Fix more todos Add module docs * Add error.rs * Fixup Cargo.lock * Smaller ethcore API is fine * Add `to-pod-full` feature to state-account Fix evmbin * Fix a few more test failures * Fix RPC test build * Baptize the new trait * Remove resolved TODOs * Rename state-account to account-state * Do not re-export the trace crate * Don't export state_db from ethcore * Let private-tx use StateDB. :( * Remove ethcore/src/pod_state.rs * Inner type does not need to be pub/pub(crate) * optimise imports * Revert "Inner type does not need to be pub/pub(crate)" This reverts commit 2f839f8a0f72f71334da64620f57e6dd6039f06b. * Move DatabaseExtras to ethcore-blockchain * Add database_extra module to ethcore-blockchain * Remove to-pod-full feature * Sort out the merge * sort imports * address grumbles * rename crate * address more grumbles
2019-07-08 18:17:48 +02:00
let proved_execution = executive_state::check_proof(
state_items,
root,
&self.tx,
self.engine.machine(),
&self.env_info,
2017-04-06 17:22:05 +02:00
);
match proved_execution {
ProvedExecution::BadProof => {
trace!(target: "on_demand", "BadExecution Proof");
Err(Error::BadProof)
}
ProvedExecution::Failed(e) => {
trace!(target: "on_demand", "Execution Proof failed: {:?}", e);
Ok(Err(e))
}
ProvedExecution::Complete(e) => {
trace!(target: "on_demand", "Execution successful: {:?}", e);
Ok(Ok(e))
}
2017-04-06 17:22:05 +02:00
}
}
}
/// Request for epoch signal.
/// Provide engine and state-dependent proof checker.
#[derive(Clone)]
pub struct Signal {
/// Block hash and number to fetch proof for.
pub hash: H256,
/// Consensus engine, used to check the proof.
pub engine: Arc<dyn Engine>,
/// Special checker for the proof.
pub proof_check: Arc<dyn StateDependentProof>,
}
impl Signal {
/// Check the signal, returning the signal or indicate that it's bad.
pub fn check_response(&self, _: &Mutex<::cache::Cache>, signal: &[u8]) -> Result<Vec<u8>, Error> {
self.proof_check.check_proof(self.engine.machine(), signal)
.map(|_| signal.to_owned())
.map_err(|_| Error::BadProof)
}
}
2017-01-04 12:48:07 +01:00
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
use ethereum_types::{H256, Address};
use parking_lot::Mutex;
use trie::{Trie, TrieMut};
use ethtrie::{SecTrieDB, SecTrieDBMut};
use trie::Recorder;
2017-08-31 11:35:41 +02:00
use hash::keccak;
2017-01-04 12:48:07 +01:00
use ethcore::test_helpers::{TestBlockChainClient, EachBlockWith};
Extract the Engine trait (#10958) * Add client-traits crate Move the BlockInfo trait to new crate * New crate `machine` Contains code extracted from ethcore that defines `Machine`, `Externalities` and other execution related code. * Use new machine and client-traits crates in ethcore * Use new crates machine and client-traits instead of ethcore where appropriate * Fix tests * Don't re-export so many types from ethcore::client * Fixing more fallout from removing re-export * fix test * More fallout from not re-exporting types * Add some docs * cleanup * import the macro edition style * Tweak docs * Add missing import * remove unused ethabi_derive imports * Use latest ethabi-contract * Move many traits from ethcore/client/traits to client-traits crate Initial version of extracted Engine trait * Move snapshot related traits to the engine crate (eew) * Move a few snapshot related types to common_types Cleanup Executed as exported from machine crate * fix warning * Gradually introduce new engine crate: snapshot * ethcore typechecks with new engine crate * Sort out types outside ethcore * Add an EpochVerifier to ethash and use that in Engine.epoch_verifier() Cleanup * Document pub members * Sort out tests Sort out default impls for EpochVerifier * Add test-helpers feature and move EngineSigner impl to the right place * Sort out tests * Sort out tests and refactor verification types * Fix missing traits * More missing traits Fix Histogram * Fix tests and cleanup * cleanup * Put back needed logger import * Don't rexport common_types from ethcore/src/client Don't export ethcore::client::* * Remove files no longer used Use types from the engine crate Explicit exports from engine::engine * Get rid of itertools * Move a few more traits from ethcore to client-traits: BlockChainReset, ScheduleInfo, StateClient * Move ProvingBlockChainClient to client-traits * Don't re-export ForkChoice and Transition from ethcore * Address grumbles: sort imports, remove commented out code * Fix merge resolution error * merge failure
2019-08-15 17:59:22 +02:00
use client_traits::{BlockInfo, BlockChainClient};
use common_types::header::Header;
use common_types::encoded;
use common_types::receipt::{Receipt, TransactionOutcome};
2017-01-04 12:48:07 +01:00
2017-04-06 17:22:05 +02:00
fn make_cache() -> ::cache::Cache {
::cache::Cache::new(Default::default(), Duration::from_secs(1))
2017-04-06 17:22:05 +02:00
}
2017-02-07 16:13:56 +01:00
#[test]
fn no_invalid_header_by_number() {
2017-03-16 20:23:59 +01:00
assert!(HeaderProof::new(0, Default::default()).is_none())
2017-02-07 16:13:56 +01:00
}
2017-01-04 12:48:07 +01:00
#[test]
2017-03-16 20:23:59 +01:00
fn check_header_proof() {
2017-02-04 17:47:06 +01:00
use ::cht;
let test_client = TestBlockChainClient::new();
test_client.add_blocks(10500, EachBlockWith::Nothing);
let cht = {
let fetcher = |id| {
let hdr = test_client.block_header(id).unwrap();
let td = test_client.block_total_difficulty(id).unwrap();
Some(cht::BlockInfo {
hash: hdr.hash(),
parent_hash: hdr.parent_hash(),
total_difficulty: td,
})
};
2017-01-04 12:48:07 +01:00
2017-02-04 17:47:06 +01:00
cht::build(cht::block_to_cht_number(10_000).unwrap(), fetcher).unwrap()
2017-01-04 12:48:07 +01:00
};
2017-02-04 17:47:06 +01:00
let proof = cht.prove(10_000, 0).unwrap().unwrap();
2017-03-16 20:23:59 +01:00
let req = HeaderProof::new(10_000, cht.root()).unwrap();
2017-01-04 12:48:07 +01:00
2017-04-06 17:22:05 +02:00
let cache = Mutex::new(make_cache());
assert!(req.check_response(&cache, &proof[..]).is_ok());
2017-01-04 12:48:07 +01:00
}
#[test]
fn check_header_by_hash() {
let mut header = Header::new();
header.set_number(10_000);
2017-06-28 16:41:08 +02:00
header.set_extra_data(b"test_header".to_vec());
2017-01-04 12:48:07 +01:00
let hash = header.hash();
let raw_header = encoded::Header::new(::rlp::encode(&header));
2017-01-04 12:48:07 +01:00
2017-04-06 17:22:05 +02:00
let cache = Mutex::new(make_cache());
assert!(HeaderByHash(hash.into()).check_response(&cache, &hash.into(), &[raw_header]).is_ok())
2017-01-04 12:48:07 +01:00
}
#[test]
fn check_header_with_ancestors() {
Upgrade ethereum types (#10670) * cargo upgrade "ethereum-types" --all --allow-prerelease * [ethash] fix compilation errors * [ethkey] fix compilation errors * [journaldb] fix compilation errors * [dir] fix compilation errors * [ethabi] update to 0.7 * wip * [eip-712] fix compilation errors * [ethjson] fix compilation errors * [Cargo.toml] add TODO to remove patches * [ethstore] fix compilation errors * use patched keccak-hash with new primitive-types * wip * [ethcore-network-devp2p] fix compilation errors * [vm] fix compilation errors * [common-types, evm, wasm] fix compilation errors * [ethcore-db] Require AsRef instead of Deref for keys * [ethcore-blockchain] fix some compilation errors * [blooms-db] fix compilation errors Thanks a lot @dvdplm :) * we don't need no rlp ethereum feature * [ethcore] fix some compilation errors * [parity-ipfs-api] fix compilation error * [ethcore-light] fix compilation errors * [Cargo.lock] update parity-common * [ethcore-private-tx] fix some compilation errors * wip * [ethcore-private-tx] fix compilation errors * [parity-updater] fix compilation errors * [parity-rpc] fix compilation errors * [parity-bin] fix other compilation errors * update to new ethereum-types * update keccak-hash * [fastmap] fix compilation in tests * [blooms-db] fix compilation in tests * [common-types] fix compilation in tests * [triehash-ethereum] fix compilation in tests * [ethkey] fix compilation in tests * [pwasm-run-test] fix compilation errors * [wasm] fix compilation errors * [ethjson] fix compilation in tests * [eip-712] fix compilation in tests * [ethcore-blockchain] fix compilation in tests * [ethstore] fix compilation in tests * [ethstore-accounts] fix compilation in tests * [parity-hash-fetch] fix compilation in tests * [parity-whisper] fix compilation in tests * [ethcore-miner] fix compilation in tests * [ethcore-network-devp2p] fix compilation in tests * [*] upgrade rand to 0.6 * [evm] get rid of num-bigint conversions * [ethcore] downgrade trie-standardmap and criterion * [ethcore] fix some warnings * [ethcore] fix compilation in tests * [evmbin] fix compilation in tests * [updater] fix compilation in tests * [ethash] fix compilation in tests * [ethcore-secretstore] fix compilation in tests * [ethcore-sync] fix compilation in tests * [parity-rpc] fix compilation in tests * [ethcore] finally fix compilation in tests FUCK YEAH!!! * [ethstore] lazy_static is unused * [ethcore] fix test * fix up bad merge * [Cargo.toml] remove unused patches * [*] replace some git dependencies with crates.io * [Cargo.toml] remove unused lazy_static * [*] clean up * [ethcore] fix transaction_filter_deprecated test * [private-tx] fix serialization tests * fix more serialization tests * [ethkey] fix smoky test * [rpc] fix tests, please? * [ethcore] remove commented out code * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * [ethstore] remove unused dev-dependency * [ethcore] remove resolved TODO * [*] resolve keccak-hash TODO * [*] s/Address::default()/Address::zero() * [rpc] remove Subscribers::new_test * [rpc] remove EthPubSubClient::new_test * [ethcore] use trie-standardmap from crates.io * [dir] fix db_root_path * [ethcore] simplify snapshot::tests::helpers::fill_storage * Apply suggestions from code review Co-Authored-By: David <dvdplm@gmail.com> * [ethcore-secretstore] resolve TODO in serialization * [ethcore-network-devp2p] resolve TODO in save_key * [Cargo.lock] update triehash * [*] use ethabi from crates.io * [ethkey] use secp256k1 from master branch * [Cargo.lock] update eth-secp256k1
2019-06-03 15:36:21 +02:00
let mut last_header_hash = H256::zero();
let mut headers = (0..11).map(|num| {
let mut header = Header::new();
header.set_number(num);
header.set_parent_hash(last_header_hash);
last_header_hash = header.hash();
header
}).collect::<Vec<_>>();
headers.reverse(); // because responses are in reverse order
let raw_headers = headers.iter()
.map(|hdr| encoded::Header::new(::rlp::encode(hdr)))
.collect::<Vec<_>>();
let mut invalid_successor = Header::new();
invalid_successor.set_number(11);
invalid_successor.set_parent_hash(headers[1].hash());
let raw_invalid_successor = encoded::Header::new(::rlp::encode(&invalid_successor));
let cache = Mutex::new(make_cache());
let header_with_ancestors = |hash, count| {
HeaderWithAncestors {
block_hash: hash,
ancestor_count: count
}
};
// Correct responses
assert!(header_with_ancestors(headers[0].hash().into(), 0)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..1]).is_ok());
assert!(header_with_ancestors(headers[0].hash().into(), 2)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..3]).is_ok());
assert!(header_with_ancestors(headers[0].hash().into(), 10)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..11]).is_ok());
assert!(header_with_ancestors(headers[2].hash().into(), 2)
.check_response(&cache, &headers[2].hash().into(), &raw_headers[2..5]).is_ok());
assert!(header_with_ancestors(headers[2].hash().into(), 10)
.check_response(&cache, &headers[2].hash().into(), &raw_headers[2..11]).is_ok());
assert!(header_with_ancestors(invalid_successor.hash().into(), 0)
.check_response(&cache, &invalid_successor.hash().into(), &[raw_invalid_successor.clone()]).is_ok());
// Incorrect responses
assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 0)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..1]),
Err(Error::WrongHash(invalid_successor.hash(), headers[0].hash())));
assert_eq!(header_with_ancestors(headers[0].hash().into(), 0)
.check_response(&cache, &headers[0].hash().into(), &[]),
Err(Error::Empty));
assert_eq!(header_with_ancestors(headers[0].hash().into(), 10)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..10]),
Err(Error::TooFewResults(11, 10)));
assert_eq!(header_with_ancestors(headers[0].hash().into(), 9)
.check_response(&cache, &headers[0].hash().into(), &raw_headers[0..11]),
Err(Error::TooManyResults(10, 11)));
let response = &[raw_headers[0].clone(), raw_headers[2].clone()];
assert_eq!(header_with_ancestors(headers[0].hash().into(), 1)
.check_response(&cache, &headers[0].hash().into(), response),
Err(Error::WrongHeaderSequence));
let response = &[raw_invalid_successor.clone(), raw_headers[0].clone()];
assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 1)
.check_response(&cache, &invalid_successor.hash().into(), response),
Err(Error::WrongHeaderSequence));
let response = &[raw_invalid_successor.clone(), raw_headers[1].clone()];
assert_eq!(header_with_ancestors(invalid_successor.hash().into(), 1)
.check_response(&cache, &invalid_successor.hash().into(), response),
Err(Error::WrongHeaderSequence));
}
2017-01-04 12:48:07 +01:00
#[test]
fn check_body() {
use rlp::RlpStream;
2017-01-04 12:48:07 +01:00
let header = Header::new();
let mut body_stream = RlpStream::new_list(2);
body_stream.begin_list(0).begin_list(0);
let req = Body(encoded::Header::new(::rlp::encode(&header)).into());
2017-01-04 12:48:07 +01:00
2017-04-06 17:22:05 +02:00
let cache = Mutex::new(make_cache());
let response = encoded::Body::new(body_stream.drain());
2017-04-06 17:22:05 +02:00
assert!(req.check_response(&cache, &response).is_ok())
2017-01-04 12:48:07 +01:00
}
#[test]
fn check_receipts() {
let receipts = (0..5).map(|_| Receipt {
outcome: TransactionOutcome::StateRoot(H256::random()),
2017-01-04 12:48:07 +01:00
gas_used: 21_000u64.into(),
log_bloom: Default::default(),
logs: Vec::new(),
}).collect::<Vec<_>>();
let mut header = Header::new();
let receipts_root = ::triehash::ordered_trie_root(
2018-02-16 20:24:16 +01:00
receipts.iter().map(|x| ::rlp::encode(x))
2017-01-04 12:48:07 +01:00
);
header.set_receipts_root(receipts_root);
let req = BlockReceipts(encoded::Header::new(::rlp::encode(&header)).into());
2017-01-04 12:48:07 +01:00
2017-04-06 17:22:05 +02:00
let cache = Mutex::new(make_cache());
assert!(req.check_response(&cache, &receipts).is_ok())
2017-01-04 12:48:07 +01:00
}
#[test]
fn check_state_proof() {
use rlp::RlpStream;
2017-01-04 16:12:58 +01:00
Upgrade ethereum types (#10670) * cargo upgrade "ethereum-types" --all --allow-prerelease * [ethash] fix compilation errors * [ethkey] fix compilation errors * [journaldb] fix compilation errors * [dir] fix compilation errors * [ethabi] update to 0.7 * wip * [eip-712] fix compilation errors * [ethjson] fix compilation errors * [Cargo.toml] add TODO to remove patches * [ethstore] fix compilation errors * use patched keccak-hash with new primitive-types * wip * [ethcore-network-devp2p] fix compilation errors * [vm] fix compilation errors * [common-types, evm, wasm] fix compilation errors * [ethcore-db] Require AsRef instead of Deref for keys * [ethcore-blockchain] fix some compilation errors * [blooms-db] fix compilation errors Thanks a lot @dvdplm :) * we don't need no rlp ethereum feature * [ethcore] fix some compilation errors * [parity-ipfs-api] fix compilation error * [ethcore-light] fix compilation errors * [Cargo.lock] update parity-common * [ethcore-private-tx] fix some compilation errors * wip * [ethcore-private-tx] fix compilation errors * [parity-updater] fix compilation errors * [parity-rpc] fix compilation errors * [parity-bin] fix other compilation errors * update to new ethereum-types * update keccak-hash * [fastmap] fix compilation in tests * [blooms-db] fix compilation in tests * [common-types] fix compilation in tests * [triehash-ethereum] fix compilation in tests * [ethkey] fix compilation in tests * [pwasm-run-test] fix compilation errors * [wasm] fix compilation errors * [ethjson] fix compilation in tests * [eip-712] fix compilation in tests * [ethcore-blockchain] fix compilation in tests * [ethstore] fix compilation in tests * [ethstore-accounts] fix compilation in tests * [parity-hash-fetch] fix compilation in tests * [parity-whisper] fix compilation in tests * [ethcore-miner] fix compilation in tests * [ethcore-network-devp2p] fix compilation in tests * [*] upgrade rand to 0.6 * [evm] get rid of num-bigint conversions * [ethcore] downgrade trie-standardmap and criterion * [ethcore] fix some warnings * [ethcore] fix compilation in tests * [evmbin] fix compilation in tests * [updater] fix compilation in tests * [ethash] fix compilation in tests * [ethcore-secretstore] fix compilation in tests * [ethcore-sync] fix compilation in tests * [parity-rpc] fix compilation in tests * [ethcore] finally fix compilation in tests FUCK YEAH!!! * [ethstore] lazy_static is unused * [ethcore] fix test * fix up bad merge * [Cargo.toml] remove unused patches * [*] replace some git dependencies with crates.io * [Cargo.toml] remove unused lazy_static * [*] clean up * [ethcore] fix transaction_filter_deprecated test * [private-tx] fix serialization tests * fix more serialization tests * [ethkey] fix smoky test * [rpc] fix tests, please? * [ethcore] remove commented out code * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * [ethstore] remove unused dev-dependency * [ethcore] remove resolved TODO * [*] resolve keccak-hash TODO * [*] s/Address::default()/Address::zero() * [rpc] remove Subscribers::new_test * [rpc] remove EthPubSubClient::new_test * [ethcore] use trie-standardmap from crates.io * [dir] fix db_root_path * [ethcore] simplify snapshot::tests::helpers::fill_storage * Apply suggestions from code review Co-Authored-By: David <dvdplm@gmail.com> * [ethcore-secretstore] resolve TODO in serialization * [ethcore-network-devp2p] resolve TODO in save_key * [Cargo.lock] update triehash * [*] use ethabi from crates.io * [ethkey] use secp256k1 from master branch * [Cargo.lock] update eth-secp256k1
2019-06-03 15:36:21 +02:00
let mut root = H256::zero();
let mut db = journaldb::new_memory_db();
2017-01-04 12:48:07 +01:00
let mut header = Header::new();
header.set_number(123_456);
2017-06-28 16:41:08 +02:00
header.set_extra_data(b"test_header".to_vec());
2017-01-04 12:48:07 +01:00
let addr = Address::random();
let rand_acc = || {
let mut stream = RlpStream::new_list(4);
stream.append(&2u64)
.append(&100_000_000u64)
.append(&H256::random())
.append(&H256::random());
stream.out()
};
{
let mut trie = SecTrieDBMut::new(&mut db, &mut root);
for _ in 0..100 {
let address = Address::random();
Upgrade ethereum types (#10670) * cargo upgrade "ethereum-types" --all --allow-prerelease * [ethash] fix compilation errors * [ethkey] fix compilation errors * [journaldb] fix compilation errors * [dir] fix compilation errors * [ethabi] update to 0.7 * wip * [eip-712] fix compilation errors * [ethjson] fix compilation errors * [Cargo.toml] add TODO to remove patches * [ethstore] fix compilation errors * use patched keccak-hash with new primitive-types * wip * [ethcore-network-devp2p] fix compilation errors * [vm] fix compilation errors * [common-types, evm, wasm] fix compilation errors * [ethcore-db] Require AsRef instead of Deref for keys * [ethcore-blockchain] fix some compilation errors * [blooms-db] fix compilation errors Thanks a lot @dvdplm :) * we don't need no rlp ethereum feature * [ethcore] fix some compilation errors * [parity-ipfs-api] fix compilation error * [ethcore-light] fix compilation errors * [Cargo.lock] update parity-common * [ethcore-private-tx] fix some compilation errors * wip * [ethcore-private-tx] fix compilation errors * [parity-updater] fix compilation errors * [parity-rpc] fix compilation errors * [parity-bin] fix other compilation errors * update to new ethereum-types * update keccak-hash * [fastmap] fix compilation in tests * [blooms-db] fix compilation in tests * [common-types] fix compilation in tests * [triehash-ethereum] fix compilation in tests * [ethkey] fix compilation in tests * [pwasm-run-test] fix compilation errors * [wasm] fix compilation errors * [ethjson] fix compilation in tests * [eip-712] fix compilation in tests * [ethcore-blockchain] fix compilation in tests * [ethstore] fix compilation in tests * [ethstore-accounts] fix compilation in tests * [parity-hash-fetch] fix compilation in tests * [parity-whisper] fix compilation in tests * [ethcore-miner] fix compilation in tests * [ethcore-network-devp2p] fix compilation in tests * [*] upgrade rand to 0.6 * [evm] get rid of num-bigint conversions * [ethcore] downgrade trie-standardmap and criterion * [ethcore] fix some warnings * [ethcore] fix compilation in tests * [evmbin] fix compilation in tests * [updater] fix compilation in tests * [ethash] fix compilation in tests * [ethcore-secretstore] fix compilation in tests * [ethcore-sync] fix compilation in tests * [parity-rpc] fix compilation in tests * [ethcore] finally fix compilation in tests FUCK YEAH!!! * [ethstore] lazy_static is unused * [ethcore] fix test * fix up bad merge * [Cargo.toml] remove unused patches * [*] replace some git dependencies with crates.io * [Cargo.toml] remove unused lazy_static * [*] clean up * [ethcore] fix transaction_filter_deprecated test * [private-tx] fix serialization tests * fix more serialization tests * [ethkey] fix smoky test * [rpc] fix tests, please? * [ethcore] remove commented out code * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * [ethstore] remove unused dev-dependency * [ethcore] remove resolved TODO * [*] resolve keccak-hash TODO * [*] s/Address::default()/Address::zero() * [rpc] remove Subscribers::new_test * [rpc] remove EthPubSubClient::new_test * [ethcore] use trie-standardmap from crates.io * [dir] fix db_root_path * [ethcore] simplify snapshot::tests::helpers::fill_storage * Apply suggestions from code review Co-Authored-By: David <dvdplm@gmail.com> * [ethcore-secretstore] resolve TODO in serialization * [ethcore-network-devp2p] resolve TODO in save_key * [Cargo.lock] update triehash * [*] use ethabi from crates.io * [ethkey] use secp256k1 from master branch * [Cargo.lock] update eth-secp256k1
2019-06-03 15:36:21 +02:00
trie.insert(address.as_bytes(), &rand_acc()).unwrap();
2017-01-04 12:48:07 +01:00
}
Upgrade ethereum types (#10670) * cargo upgrade "ethereum-types" --all --allow-prerelease * [ethash] fix compilation errors * [ethkey] fix compilation errors * [journaldb] fix compilation errors * [dir] fix compilation errors * [ethabi] update to 0.7 * wip * [eip-712] fix compilation errors * [ethjson] fix compilation errors * [Cargo.toml] add TODO to remove patches * [ethstore] fix compilation errors * use patched keccak-hash with new primitive-types * wip * [ethcore-network-devp2p] fix compilation errors * [vm] fix compilation errors * [common-types, evm, wasm] fix compilation errors * [ethcore-db] Require AsRef instead of Deref for keys * [ethcore-blockchain] fix some compilation errors * [blooms-db] fix compilation errors Thanks a lot @dvdplm :) * we don't need no rlp ethereum feature * [ethcore] fix some compilation errors * [parity-ipfs-api] fix compilation error * [ethcore-light] fix compilation errors * [Cargo.lock] update parity-common * [ethcore-private-tx] fix some compilation errors * wip * [ethcore-private-tx] fix compilation errors * [parity-updater] fix compilation errors * [parity-rpc] fix compilation errors * [parity-bin] fix other compilation errors * update to new ethereum-types * update keccak-hash * [fastmap] fix compilation in tests * [blooms-db] fix compilation in tests * [common-types] fix compilation in tests * [triehash-ethereum] fix compilation in tests * [ethkey] fix compilation in tests * [pwasm-run-test] fix compilation errors * [wasm] fix compilation errors * [ethjson] fix compilation in tests * [eip-712] fix compilation in tests * [ethcore-blockchain] fix compilation in tests * [ethstore] fix compilation in tests * [ethstore-accounts] fix compilation in tests * [parity-hash-fetch] fix compilation in tests * [parity-whisper] fix compilation in tests * [ethcore-miner] fix compilation in tests * [ethcore-network-devp2p] fix compilation in tests * [*] upgrade rand to 0.6 * [evm] get rid of num-bigint conversions * [ethcore] downgrade trie-standardmap and criterion * [ethcore] fix some warnings * [ethcore] fix compilation in tests * [evmbin] fix compilation in tests * [updater] fix compilation in tests * [ethash] fix compilation in tests * [ethcore-secretstore] fix compilation in tests * [ethcore-sync] fix compilation in tests * [parity-rpc] fix compilation in tests * [ethcore] finally fix compilation in tests FUCK YEAH!!! * [ethstore] lazy_static is unused * [ethcore] fix test * fix up bad merge * [Cargo.toml] remove unused patches * [*] replace some git dependencies with crates.io * [Cargo.toml] remove unused lazy_static * [*] clean up * [ethcore] fix transaction_filter_deprecated test * [private-tx] fix serialization tests * fix more serialization tests * [ethkey] fix smoky test * [rpc] fix tests, please? * [ethcore] remove commented out code * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * [ethstore] remove unused dev-dependency * [ethcore] remove resolved TODO * [*] resolve keccak-hash TODO * [*] s/Address::default()/Address::zero() * [rpc] remove Subscribers::new_test * [rpc] remove EthPubSubClient::new_test * [ethcore] use trie-standardmap from crates.io * [dir] fix db_root_path * [ethcore] simplify snapshot::tests::helpers::fill_storage * Apply suggestions from code review Co-Authored-By: David <dvdplm@gmail.com> * [ethcore-secretstore] resolve TODO in serialization * [ethcore-network-devp2p] resolve TODO in save_key * [Cargo.lock] update triehash * [*] use ethabi from crates.io * [ethkey] use secp256k1 from master branch * [Cargo.lock] update eth-secp256k1
2019-06-03 15:36:21 +02:00
trie.insert(addr.as_bytes(), &rand_acc()).unwrap();
2017-01-04 12:48:07 +01:00
}
let proof = {
let trie = SecTrieDB::new(&db, &root).unwrap();
2017-01-11 18:57:38 +01:00
let mut recorder = Recorder::new();
2017-01-04 12:48:07 +01:00
Upgrade ethereum types (#10670) * cargo upgrade "ethereum-types" --all --allow-prerelease * [ethash] fix compilation errors * [ethkey] fix compilation errors * [journaldb] fix compilation errors * [dir] fix compilation errors * [ethabi] update to 0.7 * wip * [eip-712] fix compilation errors * [ethjson] fix compilation errors * [Cargo.toml] add TODO to remove patches * [ethstore] fix compilation errors * use patched keccak-hash with new primitive-types * wip * [ethcore-network-devp2p] fix compilation errors * [vm] fix compilation errors * [common-types, evm, wasm] fix compilation errors * [ethcore-db] Require AsRef instead of Deref for keys * [ethcore-blockchain] fix some compilation errors * [blooms-db] fix compilation errors Thanks a lot @dvdplm :) * we don't need no rlp ethereum feature * [ethcore] fix some compilation errors * [parity-ipfs-api] fix compilation error * [ethcore-light] fix compilation errors * [Cargo.lock] update parity-common * [ethcore-private-tx] fix some compilation errors * wip * [ethcore-private-tx] fix compilation errors * [parity-updater] fix compilation errors * [parity-rpc] fix compilation errors * [parity-bin] fix other compilation errors * update to new ethereum-types * update keccak-hash * [fastmap] fix compilation in tests * [blooms-db] fix compilation in tests * [common-types] fix compilation in tests * [triehash-ethereum] fix compilation in tests * [ethkey] fix compilation in tests * [pwasm-run-test] fix compilation errors * [wasm] fix compilation errors * [ethjson] fix compilation in tests * [eip-712] fix compilation in tests * [ethcore-blockchain] fix compilation in tests * [ethstore] fix compilation in tests * [ethstore-accounts] fix compilation in tests * [parity-hash-fetch] fix compilation in tests * [parity-whisper] fix compilation in tests * [ethcore-miner] fix compilation in tests * [ethcore-network-devp2p] fix compilation in tests * [*] upgrade rand to 0.6 * [evm] get rid of num-bigint conversions * [ethcore] downgrade trie-standardmap and criterion * [ethcore] fix some warnings * [ethcore] fix compilation in tests * [evmbin] fix compilation in tests * [updater] fix compilation in tests * [ethash] fix compilation in tests * [ethcore-secretstore] fix compilation in tests * [ethcore-sync] fix compilation in tests * [parity-rpc] fix compilation in tests * [ethcore] finally fix compilation in tests FUCK YEAH!!! * [ethstore] lazy_static is unused * [ethcore] fix test * fix up bad merge * [Cargo.toml] remove unused patches * [*] replace some git dependencies with crates.io * [Cargo.toml] remove unused lazy_static * [*] clean up * [ethcore] fix transaction_filter_deprecated test * [private-tx] fix serialization tests * fix more serialization tests * [ethkey] fix smoky test * [rpc] fix tests, please? * [ethcore] remove commented out code * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * [ethstore] remove unused dev-dependency * [ethcore] remove resolved TODO * [*] resolve keccak-hash TODO * [*] s/Address::default()/Address::zero() * [rpc] remove Subscribers::new_test * [rpc] remove EthPubSubClient::new_test * [ethcore] use trie-standardmap from crates.io * [dir] fix db_root_path * [ethcore] simplify snapshot::tests::helpers::fill_storage * Apply suggestions from code review Co-Authored-By: David <dvdplm@gmail.com> * [ethcore-secretstore] resolve TODO in serialization * [ethcore-network-devp2p] resolve TODO in save_key * [Cargo.lock] update triehash * [*] use ethabi from crates.io * [ethkey] use secp256k1 from master branch * [Cargo.lock] update eth-secp256k1
2019-06-03 15:36:21 +02:00
trie.get_with(addr.as_bytes(), &mut recorder).unwrap().unwrap();
2017-01-04 12:48:07 +01:00
recorder.drain().into_iter().map(|r| r.data).collect::<Vec<_>>()
};
header.set_state_root(root.clone());
let req = Account {
header: encoded::Header::new(::rlp::encode(&header)).into(),
2017-01-04 12:48:07 +01:00
address: addr,
};
2017-04-06 17:22:05 +02:00
let cache = Mutex::new(make_cache());
assert!(req.check_response(&cache, &proof[..]).is_ok());
2017-01-04 12:48:07 +01:00
}
2017-02-07 15:29:38 +01:00
#[test]
fn check_code() {
let code = vec![1u8; 256];
2017-08-31 11:35:41 +02:00
let code_hash = keccak(&code);
let header = Header::new();
2017-02-07 15:29:38 +01:00
let req = Code {
header: encoded::Header::new(::rlp::encode(&header)).into(),
code_hash: code_hash.into(),
2017-02-07 15:29:38 +01:00
};
2017-04-06 17:22:05 +02:00
let cache = Mutex::new(make_cache());
assert!(req.check_response(&cache, &code_hash, &code).is_ok());
assert!(req.check_response(&cache, &code_hash, &[]).is_err());
2017-02-07 15:29:38 +01:00
}
2017-01-04 12:48:07 +01:00
}