prove_transaction function on state

This commit is contained in:
Robert Habermeier 2017-08-15 00:12:40 +02:00
parent 0abf2abc81
commit 1e269c94a6
3 changed files with 48 additions and 16 deletions

View File

@ -1884,27 +1884,23 @@ impl ProvingBlockChainClient for Client {
}
fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option<(Bytes, Vec<DBValue>)> {
let (state, mut env_info) = match (self.state_at(id), self.env_info(id)) {
let (header, mut env_info) = match (self.block_header(id), self.env_info(id)) {
(Some(s), Some(e)) => (s, e),
_ => return None,
};
env_info.gas_limit = transaction.gas.clone();
let mut jdb = self.state_db.lock().journal_db().boxed_clone();
let backend = state::backend::Proving::new(jdb.as_hashdb_mut());
let mut state = state.replace_backend(backend);
let options = TransactOptions { tracing: false, vm_tracing: false, check_nonce: false };
let res = Executive::new(&mut state, &env_info, &*self.engine).transact(&transaction, options);
match res {
Err(ExecutionError::Internal(_)) => None,
Err(e) => {
trace!(target: "client", "Proved call failed: {}", e);
Some((Vec::new(), state.drop().1.extract_proof()))
}
Ok(res) => Some((res.output, state.drop().1.extract_proof())),
}
state::prove_transaction(
jdb.as_hashdb_mut(),
header.state_root().clone(),
&transaction,
&*self.engine,
&env_info,
self.factories.clone(),
false,
)
}
}

View File

@ -32,7 +32,6 @@ use factory::Factories;
use header::{BlockNumber, Header};
use pod_state::*;
use rlp::{Rlp, RlpStream};
use state_db::StateDB;
use state::{Backend, State, Substate};
use state::backend::Basic as BasicBackend;
use trace::{NoopTracer, NoopVMTracer};
@ -421,7 +420,7 @@ impl Spec {
}
/// Ensure that the given state DB has the trie nodes in for the genesis state.
pub fn ensure_db_good(&self, db: StateDB, factories: &Factories) -> Result<StateDB, Error> {
pub fn ensure_db_good<T: Backend>(&self, db: T, factories: &Factories) -> Result<T, Error> {
if db.as_hashdb().contains(&self.state_root()) {
return Ok(db)
}

View File

@ -209,6 +209,43 @@ pub fn check_proof(
}
}
/// Prove a transaction on the given state.
/// Returns `None` when the transacion could not be proved,
/// and a proof otherwise.
pub fn prove_transaction<H: AsHashDB + Send + Sync>(
db: H,
root: H256,
transaction: &SignedTransaction,
engine: &Engine,
env_info: &EnvInfo,
factories: Factories,
virt: bool,
) -> Option<(Bytes, Vec<DBValue>)> {
use self::backend::Proving;
let backend = Proving::new(db);
let res = State::from_existing(
backend,
root,
engine.account_start_nonce(env_info.number),
factories,
);
let mut state = match res {
Ok(state) => state,
Err(_) => return None,
};
match state.execute(env_info, engine, transaction, false, virt) {
Err(ExecutionError::Internal(_)) => None,
Err(e) => {
trace!(target: "state", "Proved call failed: {}", e);
Some((Vec::new(), state.drop().1.extract_proof()))
}
Ok(res) => Some((res.output, state.drop().1.extract_proof())),
}
}
/// Representation of the entire state of all accounts in the system.
///
/// `State` can work together with `StateDB` to share account cache.