most of proved_execution rpc

This commit is contained in:
Robert Habermeier 2017-02-26 13:48:56 +01:00
parent 69e82e15a3
commit 645011427a
3 changed files with 59 additions and 22 deletions

View File

@ -627,26 +627,28 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
self.send_raw_transaction(raw) self.send_raw_transaction(raw)
} }
fn call(&self, request: CallRequest, num: Trailing<BlockNumber>) -> Result<Bytes, Error> { fn call(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
let request = CallRequest::into(request); let request = CallRequest::into(request);
let signed = self.sign_call(request)?; let signed = self.sign_call(request)?;
let result = match num.0 { let result = match num.0 {
BlockNumber::Pending => take_weak!(self.miner).call(&*take_weak!(self.client), &signed, Default::default()), BlockNumber::Pending => take_weakf!(self.miner).call(&*take_weak!(self.client), &signed, Default::default()),
num => take_weak!(self.client).call(&signed, num.into(), Default::default()), num => take_weakf!(self.client).call(&signed, num.into(), Default::default()),
}; };
result future::done(result
.map(|b| b.output.into()) .map(|b| b.output.into())
.map_err(errors::from_call_error) .map_err(errors::from_call_error)
).boxed()
} }
fn estimate_gas(&self, request: CallRequest, num: Trailing<BlockNumber>) -> Result<RpcU256, Error> { fn estimate_gas(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
let request = CallRequest::into(request); let request = CallRequest::into(request);
let signed = self.sign_call(request)?; let signed = self.sign_call(request)?;
take_weak!(self.client).estimate_gas(&signed, num.0.into()) future::done(take_weakf!(self.client).estimate_gas(&signed, num.0.into())
.map(Into::into) .map(Into::into)
.map_err(errors::from_call_error) .map_err(errors::from_call_error)
).boxed()
} }
fn compile_lll(&self, _: String) -> Result<Bytes, Error> { fn compile_lll(&self, _: String) -> Result<Bytes, Error> {

View File

@ -38,7 +38,7 @@ use rlp::{UntrustedRlp, View};
use util::sha3::{SHA3_NULL_RLP, SHA3_EMPTY_LIST_RLP}; use util::sha3::{SHA3_NULL_RLP, SHA3_EMPTY_LIST_RLP};
use util::{RwLock, U256}; use util::{RwLock, U256};
use futures::{future, Future, BoxFuture}; use futures::{future, Future, BoxFuture, IntoFuture};
use futures::sync::oneshot; use futures::sync::oneshot;
use v1::helpers::{CallRequest as CRequest, errors, limit_logs}; use v1::helpers::{CallRequest as CRequest, errors, limit_logs};
@ -153,6 +153,27 @@ impl EthClient {
.unwrap_or_else(|| future::err(err_no_context()).boxed()) .unwrap_or_else(|| future::err(err_no_context()).boxed())
}).boxed() }).boxed()
} }
// helper for getting proved execution.
fn proved_execution(&self, req: CallRequest, num: Trailing<BlockNumber>) -> Result<Option<ProvedExecution>, Error> {
let (sync, on_demand) = (self.sync.clone(), self.on_demand.clone());
let req: CRequest = req.into();
let id = num.0.into();
let from = request.from.unwrap_or(Address::zero());
let action = request.to.map_or(Action::Create, Action::Call);
let gas: request.gas.unwrap_or(U256::from(10_000_000));
let value = request.value.unwrap_or_else(U256::zero);
let data = request.data.map_or_else(Vec::new, |d| d.to_vec());
sync.with_context(|ctx| {
let nonce_fut = req.nonce.map(Some).ok_or(err_no_context())
.or_else(|_| self.account(from, id).map(|acc| acc.map(|a| a.nonce)));
let gas_price_fut = req.gas_price.map(Some).ok_or(err_no_context())
.or_else(|_| unimplemented!())
})
}
} }
impl Eth for EthClient { impl Eth for EthClient {
@ -328,12 +349,25 @@ impl Eth for EthClient {
self.send_raw_transaction(raw) self.send_raw_transaction(raw)
} }
fn call(&self, req: CallRequest, num: Trailing<BlockNumber>) -> Result<Bytes, Error> { fn call(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
Err(errors::unimplemented(None)) self.proved_execution().and_then(|res| {
match res {
Ok(Some(exec)) => Ok(exec.output.into()),
Ok(None) => Err(errors::unknown_block()),
Err(e) => Err(errors::execution(e)),
}
}).boxed()
} }
fn estimate_gas(&self, req: CallRequest, num: Trailing<BlockNumber>) -> Result<RpcU256, Error> { fn estimate_gas(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
Err(errors::unimplemented(None)) // TODO: binary chop for more accurate estimates.
self.proved_execution().and_then(|res| {
match res {
Ok(Some(exec)) => Ok((exec.refunded + exec.gas_used).into()),
Ok(None) => Err(errors::unknown_block()),
Err(e) => Err(errors::execution(e)),
}
}).boxed()
} }
fn transaction_by_hash(&self, hash: RpcH256) -> Result<Option<Transaction>, Error> { fn transaction_by_hash(&self, hash: RpcH256) -> Result<Option<Transaction>, Error> {
@ -361,19 +395,20 @@ impl Eth for EthClient {
} }
fn compilers(&self) -> Result<Vec<String>, Error> { fn compilers(&self) -> Result<Vec<String>, Error> {
Err(errors::unimplemented(None)) Err(errors::deprecated("Compilation functionality is deprecated.".to_string()))
} }
fn compile_lll(&self, _code: String) -> Result<Bytes, Error> { fn compile_lll(&self, _: String) -> Result<Bytes, Error> {
Err(errors::unimplemented(None)) Err(errors::deprecated("Compilation of LLL via RPC is deprecated".to_string()))
} }
fn compile_solidity(&self, _code: String) -> Result<Bytes, Error> { fn compile_serpent(&self, _: String) -> Result<Bytes, Error> {
Err(errors::unimplemented(None)) Err(errors::deprecated("Compilation of Serpent via RPC is deprecated".to_string()))
} }
fn compile_serpent(&self, _code: String) -> Result<Bytes, Error> { fn compile_solidity(&self, _: String) -> Result<Bytes, Error> {
Err(errors::unimplemented(None)) Err(errors::deprecated("Compilation of Solidity via RPC is deprecated".to_string()))
} }
fn logs(&self, _filter: Filter) -> Result<Vec<Log>, Error> { fn logs(&self, _filter: Filter) -> Result<Vec<Log>, Error> {

View File

@ -110,12 +110,12 @@ build_rpc_trait! {
fn submit_transaction(&self, Bytes) -> Result<H256, Error>; fn submit_transaction(&self, Bytes) -> Result<H256, Error>;
/// Call contract, returning the output data. /// Call contract, returning the output data.
#[rpc(name = "eth_call")] #[rpc(async, name = "eth_call")]
fn call(&self, CallRequest, Trailing<BlockNumber>) -> Result<Bytes, Error>; fn call(&self, CallRequest, Trailing<BlockNumber>) -> BoxFuture<Bytes, Error>;
/// Estimate gas needed for execution of given contract. /// Estimate gas needed for execution of given contract.
#[rpc(name = "eth_estimateGas")] #[rpc(async, name = "eth_estimateGas")]
fn estimate_gas(&self, CallRequest, Trailing<BlockNumber>) -> Result<U256, Error>; fn estimate_gas(&self, CallRequest, Trailing<BlockNumber>) -> BoxFuture<U256, Error>;
/// Get transaction by its hash. /// Get transaction by its hash.
#[rpc(name = "eth_getTransactionByHash")] #[rpc(name = "eth_getTransactionByHash")]