prove_transaction function on state
This commit is contained in:
parent
0abf2abc81
commit
1e269c94a6
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user