get it compiling

This commit is contained in:
Robert Habermeier 2017-02-03 17:41:25 +01:00
parent 9328067eac
commit 024e69138a
4 changed files with 272 additions and 116 deletions

View File

@ -49,6 +49,7 @@ mod codes {
pub const COMPILATION_ERROR: i64 = -32050;
pub const ENCRYPTION_ERROR: i64 = -32055;
pub const FETCH_ERROR: i64 = -32060;
pub const ON_DEMAND_ERROR: i64 = -32065;
}
pub fn unimplemented(details: Option<String>) -> Error {
@ -308,3 +309,11 @@ pub fn unknown_block() -> Error {
data: None,
}
}
pub fn from_on_demand_error(error: ::light::on_demand::Error) -> Error {
Error {
code: ErrorCode::ServerError(codes::ON_DEMAND_ERROR),
message: "Failed to fetch on-demand data".into(),
data: Some(Value::String(format!("{:?}", error)))
}
}

View File

@ -22,7 +22,7 @@ use std::thread;
use std::time::{Instant, Duration};
use std::sync::{Arc, Weak};
use futures::{self, BoxFuture, Future};
use futures::{self, future, BoxFuture, Future};
use rlp::{self, UntrustedRlp, View};
use time::get_time;
use util::{H160, H256, Address, FixedHash, U256, H64, Uint};
@ -386,130 +386,161 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
}
fn balance(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
self.active()?;
let address = address.into();
match num.0 {
BlockNumber::Pending => Ok(take_weak!(self.miner).balance(&*take_weak!(self.client), &address).into()),
id => {
let client = take_weak!(self.client);
check_known(&*client, id.clone())?;
match client.balance(&address, id.into()) {
Some(balance) => Ok(balance.into()),
None => Err(errors::state_pruned()),
let inner = || {
self.active()?;
match num.0.clone() {
BlockNumber::Pending => Ok(take_weak!(self.miner).balance(&*take_weak!(self.client), &address).into()),
id => {
let client = take_weak!(self.client);
check_known(&*client, id.clone())?;
match client.balance(&address, id.into()) {
Some(balance) => Ok(balance.into()),
None => Err(errors::state_pruned()),
}
}
}
}
};
future::done(inner()).boxed()
}
fn storage_at(&self, address: RpcH160, pos: RpcU256, num: Trailing<BlockNumber>) -> Result<RpcH256, Error> {
self.active()?;
fn storage_at(&self, address: RpcH160, pos: RpcU256, num: Trailing<BlockNumber>) -> BoxFuture<RpcH256, Error> {
let address: Address = RpcH160::into(address);
let position: U256 = RpcU256::into(pos);
match num.0 {
BlockNumber::Pending => Ok(take_weak!(self.miner).storage_at(&*take_weak!(self.client), &address, &H256::from(position)).into()),
id => {
let client = take_weak!(self.client);
check_known(&*client, id.clone())?;
match client.storage_at(&address, &H256::from(position), id.into()) {
Some(s) => Ok(s.into()),
None => Err(errors::state_pruned()),
let inner = || {
self.active()?;
match num.0.clone() {
BlockNumber::Pending => Ok(take_weak!(self.miner).storage_at(&*take_weak!(self.client), &address, &H256::from(position)).into()),
id => {
let client = take_weak!(self.client);
check_known(&*client, id.clone())?;
match client.storage_at(&address, &H256::from(position), id.into()) {
Some(s) => Ok(s.into()),
None => Err(errors::state_pruned()),
}
}
}
}
};
future::done(inner()).boxed()
}
fn transaction_count(&self, address: RpcH160, num: Trailing<BlockNumber>) -> Result<RpcU256, Error> {
self.active()?;
fn transaction_count(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
let address: Address = RpcH160::into(address);
match num.0 {
BlockNumber::Pending => Ok(take_weak!(self.miner).nonce(&*take_weak!(self.client), &address).into()),
id => {
let client = take_weak!(self.client);
let inner = move || {
self.active()?;
match num.0.clone() {
BlockNumber::Pending => Ok(take_weak!(self.miner).nonce(&*take_weak!(self.client), &address).into()),
id => {
let client = take_weak!(self.client);
check_known(&*client, id.clone())?;
match client.nonce(&address, id.into()) {
Some(nonce) => Ok(nonce.into()),
None => Err(errors::state_pruned()),
check_known(&*client, id.clone())?;
match client.nonce(&address, id.into()) {
Some(nonce) => Ok(nonce.into()),
None => Err(errors::state_pruned()),
}
}
}
}
};
future::done(inner()).boxed()
}
fn block_transaction_count_by_hash(&self, hash: RpcH256) -> Result<Option<RpcU256>, Error> {
self.active()?;
Ok(
take_weak!(self.client).block(BlockId::Hash(hash.into()))
.map(|block| block.transactions_count().into())
)
fn block_transaction_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>, Error> {
let inner = || {
self.active()?;
Ok(take_weak!(self.client).block(BlockId::Hash(hash.into()))
.map(|block| block.transactions_count().into()))
};
future::done(inner()).boxed()
}
fn block_transaction_count_by_number(&self, num: BlockNumber) -> Result<Option<RpcU256>, Error> {
self.active()?;
fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>, Error> {
let inner = || {
self.active()?;
match num {
BlockNumber::Pending => Ok(Some(
take_weak!(self.miner).status().transactions_in_pending_block.into()
)),
_ => Ok(
take_weak!(self.client).block(num.into())
.map(|block| block.transactions_count().into())
)
}
};
match num {
BlockNumber::Pending => Ok(Some(
take_weak!(self.miner).status().transactions_in_pending_block.into()
)),
_ => Ok(
take_weak!(self.client).block(num.into())
.map(|block| block.transactions_count().into())
)
}
future::done(inner()).boxed()
}
fn block_uncles_count_by_hash(&self, hash: RpcH256) -> Result<Option<RpcU256>, Error> {
self.active()?;
fn block_uncles_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>, Error> {
let inner = || {
self.active()?;
Ok(take_weak!(self.client).block(BlockId::Hash(hash.into()))
.map(|block| block.uncles_count().into()))
};
Ok(
take_weak!(self.client).block(BlockId::Hash(hash.into()))
.map(|block| block.uncles_count().into())
)
future::done(inner()).boxed()
}
fn block_uncles_count_by_number(&self, num: BlockNumber) -> Result<Option<RpcU256>, Error> {
self.active()?;
fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>, Error> {
let inner = || {
self.active()?;
match num {
BlockNumber::Pending => Ok(Some(0.into())),
_ => Ok(
take_weak!(self.client).block(num.into())
.map(|block| block.uncles_count().into())
),
}
};
match num {
BlockNumber::Pending => Ok(Some(0.into())),
_ => Ok(
take_weak!(self.client).block(num.into())
.map(|block| block.uncles_count().into())
),
}
future::done(inner()).boxed()
}
fn code_at(&self, address: RpcH160, num: Trailing<BlockNumber>) -> Result<Bytes, Error> {
self.active()?;
fn code_at(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
let address: Address = RpcH160::into(address);
match num.0 {
BlockNumber::Pending => Ok(take_weak!(self.miner).code(&*take_weak!(self.client), &address).map_or_else(Bytes::default, Bytes::new)),
id => {
let client = take_weak!(self.client);
check_known(&*client, id.clone())?;
match client.code(&address, id.into()) {
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
None => Err(errors::state_pruned()),
let inner = || {
self.active()?;
match num.0.clone() {
BlockNumber::Pending => Ok(take_weak!(self.miner).code(&*take_weak!(self.client), &address).map_or_else(Bytes::default, Bytes::new)),
id => {
let client = take_weak!(self.client);
check_known(&*client, id.clone())?;
match client.code(&address, id.into()) {
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
None => Err(errors::state_pruned()),
}
}
}
}
};
future::done(inner()).boxed()
}
fn block_by_hash(&self, hash: RpcH256, include_txs: bool) -> Result<Option<RichBlock>, Error> {
self.active()?;
fn block_by_hash(&self, hash: RpcH256, include_txs: bool) -> BoxFuture<Option<RichBlock>, Error> {
let inner = || {
self.active()?;
self.block(BlockId::Hash(hash.into()), include_txs)
};
self.block(BlockId::Hash(hash.into()), include_txs)
future::done(inner()).boxed()
}
fn block_by_number(&self, num: BlockNumber, include_txs: bool) -> Result<Option<RichBlock>, Error> {
self.active()?;
fn block_by_number(&self, num: BlockNumber, include_txs: bool) -> BoxFuture<Option<RichBlock>, Error> {
let inner = || {
self.active()?;
self.block(num.into(), include_txs)
};
self.block(num.into(), include_txs)
future::done(inner()).boxed()
}
fn transaction_by_hash(&self, hash: RpcH256) -> Result<Option<Transaction>, Error> {

View File

@ -26,12 +26,12 @@ use light::cht;
use light::on_demand::{request, OnDemand};
use light::net::LightProtocol;
use ethcore::account_provider::AccountProvider;
use ethcore::account_provider::{AccountProvider, DappId};
use ethcore::encoded;
use ethcore::ids::BlockId;
use ethsync::LightSync;
use futures::{future, BoxFuture};
use futures::{future, Future, BoxFuture};
use v1::helpers::{CallRequest as CRequest, errors, limit_logs};
use v1::helpers::dispatch::{dispatch_transaction, default_gas_price};
@ -52,6 +52,11 @@ pub struct EthClient {
accounts: Arc<AccountProvider>,
}
// helper for a specific kind of internal error.
fn err_no_context() -> Error {
errors::internal("network service detached", "")
}
impl EthClient {
/// Create a new `EthClient` with a handle to the light sync instance, client,
/// and on-demand request service, which is assumed to be attached as a handler.
@ -77,7 +82,7 @@ impl EthClient {
let maybe_future = match id {
BlockId::Number(n) => {
let cht_root = cht::block_to_cht_number(n).and_then(|cn| self.client.cht_root(cn));
let cht_root = cht::block_to_cht_number(n).and_then(|cn| self.client.cht_root(cn as usize));
match cht_root {
None => return future::err(errors::unknown_block()).boxed(),
Some(root) => {
@ -86,19 +91,19 @@ impl EthClient {
cht_root: root,
};
self.sync.with_context(|ctx| self.on_demand.header_by_number(req))
self.sync.with_context(|ctx| self.on_demand.header_by_number(ctx, req))
}
}
}
BlockId::Hash(h) => {
self.sync.with_context(|ctx| self.on_demand.header_by_hash(request::HeaderByHash(h)))
self.sync.with_context(|ctx| self.on_demand.header_by_hash(ctx, request::HeaderByHash(h)))
}
_ => None, // latest, earliest, and pending will have all already returned.
};
match maybe_future {
Some(recv) => recv.boxed(),
None => future::err(errors::internal("network service detached", "")).boxed()
Some(recv) => recv.map_err(errors::from_on_demand_error).boxed(),
None => future::err(err_no_context()).boxed()
}
}
}
@ -115,7 +120,7 @@ impl Eth for EthClient {
}
fn author(&self, _meta: Self::Metadata) -> BoxFuture<RpcH160, Error> {
future::ok(Default::default())
future::ok(Default::default()).boxed()
}
fn is_mining(&self) -> Result<bool, Error> {
@ -131,12 +136,13 @@ impl Eth for EthClient {
}
fn accounts(&self, meta: Metadata) -> BoxFuture<Vec<RpcH160>, Error> {
let dapp = meta.dapp_id.unwrap_or_default();
let dapp: DappId = meta.dapp_id.unwrap_or_default().into();
let accounts = self.accounts
.note_dapp_used(dapp.clone())
.and_then(|_| self.accounts.dapps_addresses(dapp))
.map_err(|e| errors::internal("Could not fetch accounts.", e));
.map_err(|e| errors::internal("Could not fetch accounts.", e))
.map(|accs| accs.into_iter().map(Into::<RpcH160>::into).collect());
future::done(accounts).boxed()
}
@ -151,11 +157,121 @@ impl Eth for EthClient {
let sync = self.sync.clone();
let on_demand = self.on_demand.clone();
self.header(num.0.into()).then(move |header| {
self.header(num.0.into()).and_then(move |header| {
sync.with_context(|ctx| on_demand.account(ctx, request::Account {
header: header,
address: address,
}))
})
.map(|x| x.map_err(errors::from_on_demand_error).boxed())
.unwrap_or_else(|| future::err(err_no_context()).boxed())
}).map(|acc| acc.balance.into()).boxed()
}
fn storage_at(&self, address: RpcH160, key: RpcU256, num: Trailing<BlockNumber>) -> BoxFuture<RpcH256, Error> {
future::err(errors::unimplemented(None)).boxed()
}
fn block_by_hash(&self, hash: RpcH256, include_txs: bool) -> BoxFuture<Option<RichBlock>, Error> {
future::err(errors::unimplemented(None)).boxed()
}
fn block_by_number(&self, num: BlockNumber, include_txs: bool) -> BoxFuture<Option<RichBlock>, Error> {
future::err(errors::unimplemented(None)).boxed()
}
fn transaction_count(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
future::err(errors::unimplemented(None)).boxed()
}
fn block_transaction_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>, Error> {
future::err(errors::unimplemented(None)).boxed()
}
fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>, Error> {
future::err(errors::unimplemented(None)).boxed()
}
fn block_uncles_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>, Error> {
future::err(errors::unimplemented(None)).boxed()
}
fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>, Error> {
future::err(errors::unimplemented(None)).boxed()
}
fn code_at(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
future::err(errors::unimplemented(None)).boxed()
}
fn send_raw_transaction(&self, raw: Bytes) -> Result<RpcH256, Error> {
Err(errors::unimplemented(None))
}
fn submit_transaction(&self, raw: Bytes) -> Result<RpcH256, Error> {
Err(errors::unimplemented(None))
}
fn call(&self, req: CallRequest, num: Trailing<BlockNumber>) -> Result<Bytes, Error> {
Err(errors::unimplemented(None))
}
fn estimate_gas(&self, req: CallRequest, num: Trailing<BlockNumber>) -> Result<RpcU256, Error> {
Err(errors::unimplemented(None))
}
fn transaction_by_hash(&self, hash: RpcH256) -> Result<Option<Transaction>, Error> {
Err(errors::unimplemented(None))
}
fn transaction_by_block_hash_and_index(&self, hash: RpcH256, idx: Index) -> Result<Option<Transaction>, Error> {
Err(errors::unimplemented(None))
}
fn transaction_by_block_number_and_index(&self, num: BlockNumber, idx: Index) -> Result<Option<Transaction>, Error> {
Err(errors::unimplemented(None))
}
fn transaction_receipt(&self, hash: RpcH256) -> Result<Option<Receipt>, Error> {
Err(errors::unimplemented(None))
}
fn uncle_by_block_hash_and_index(&self, hash: RpcH256, idx: Index) -> Result<Option<RichBlock>, Error> {
Err(errors::unimplemented(None))
}
fn uncle_by_block_number_and_index(&self, num: BlockNumber, idx: Index) -> Result<Option<RichBlock>, Error> {
Err(errors::unimplemented(None))
}
fn compilers(&self) -> Result<Vec<String>, Error> {
Err(errors::unimplemented(None))
}
fn compile_lll(&self, _code: String) -> Result<Bytes, Error> {
Err(errors::unimplemented(None))
}
fn compile_solidity(&self, _code: String) -> Result<Bytes, Error> {
Err(errors::unimplemented(None))
}
fn compile_serpent(&self, _code: String) -> Result<Bytes, Error> {
Err(errors::unimplemented(None))
}
fn logs(&self, _filter: Filter) -> Result<Vec<Log>, Error> {
Err(errors::unimplemented(None))
}
fn work(&self, _timeout: Trailing<u64>) -> Result<Work, Error> {
Err(errors::unimplemented(None))
}
fn submit_work(&self, _nonce: RpcH64, _pow_hash: RpcH256, _mix_hash: RpcH256) -> Result<bool, Error> {
Err(errors::unimplemented(None))
}
fn submit_hashrate(&self, _rate: RpcU256, _id: RpcH256) -> Result<bool, Error> {
Err(errors::unimplemented(None))
}
}

View File

@ -62,44 +62,44 @@ build_rpc_trait! {
fn block_number(&self) -> Result<U256, Error>;
/// Returns balance of the given account.
#[rpc(name = "eth_getBalance")]
#[rpc(async, name = "eth_getBalance")]
fn balance(&self, H160, Trailing<BlockNumber>) -> BoxFuture<U256, Error>;
/// Returns content of the storage at given address.
#[rpc(name = "eth_getStorageAt")]
fn storage_at(&self, H160, U256, Trailing<BlockNumber>) -> Result<H256, Error>;
#[rpc(async, name = "eth_getStorageAt")]
fn storage_at(&self, H160, U256, Trailing<BlockNumber>) -> BoxFuture<H256, Error>;
/// Returns block with given hash.
#[rpc(name = "eth_getBlockByHash")]
fn block_by_hash(&self, H256, bool) -> Result<Option<RichBlock>, Error>;
#[rpc(async, name = "eth_getBlockByHash")]
fn block_by_hash(&self, H256, bool) -> BoxFuture<Option<RichBlock>, Error>;
/// Returns block with given number.
#[rpc(name = "eth_getBlockByNumber")]
fn block_by_number(&self, BlockNumber, bool) -> Result<Option<RichBlock>, Error>;
#[rpc(async, name = "eth_getBlockByNumber")]
fn block_by_number(&self, BlockNumber, bool) -> BoxFuture<Option<RichBlock>, Error>;
/// Returns the number of transactions sent from given address at given time (block number).
#[rpc(name = "eth_getTransactionCount")]
fn transaction_count(&self, H160, Trailing<BlockNumber>) -> Result<U256, Error>;
#[rpc(async, name = "eth_getTransactionCount")]
fn transaction_count(&self, H160, Trailing<BlockNumber>) -> BoxFuture<U256, Error>;
/// Returns the number of transactions in a block with given hash.
#[rpc(name = "eth_getBlockTransactionCountByHash")]
fn block_transaction_count_by_hash(&self, H256) -> Result<Option<U256>, Error>;
#[rpc(async, name = "eth_getBlockTransactionCountByHash")]
fn block_transaction_count_by_hash(&self, H256) -> BoxFuture<Option<U256>, Error>;
/// Returns the number of transactions in a block with given block number.
#[rpc(name = "eth_getBlockTransactionCountByNumber")]
fn block_transaction_count_by_number(&self, BlockNumber) -> Result<Option<U256>, Error>;
#[rpc(async, name = "eth_getBlockTransactionCountByNumber")]
fn block_transaction_count_by_number(&self, BlockNumber) -> BoxFuture<Option<U256>, Error>;
/// Returns the number of uncles in a block with given hash.
#[rpc(name = "eth_getUncleCountByBlockHash")]
fn block_uncles_count_by_hash(&self, H256) -> Result<Option<U256>, Error>;
#[rpc(async, name = "eth_getUncleCountByBlockHash")]
fn block_uncles_count_by_hash(&self, H256) -> BoxFuture<Option<U256>, Error>;
/// Returns the number of uncles in a block with given block number.
#[rpc(name = "eth_getUncleCountByBlockNumber")]
fn block_uncles_count_by_number(&self, BlockNumber) -> Result<Option<U256>, Error>;
#[rpc(async, name = "eth_getUncleCountByBlockNumber")]
fn block_uncles_count_by_number(&self, BlockNumber) -> BoxFuture<Option<U256>, Error>;
/// Returns the code at given address at given time (block number).
#[rpc(name = "eth_getCode")]
fn code_at(&self, H160, Trailing<BlockNumber>) -> Result<Bytes, Error>;
#[rpc(async, name = "eth_getCode")]
fn code_at(&self, H160, Trailing<BlockNumber>) -> BoxFuture<Bytes, Error>;
/// Sends signed transaction, returning its hash.
#[rpc(name = "eth_sendRawTransaction")]