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 COMPILATION_ERROR: i64 = -32050;
pub const ENCRYPTION_ERROR: i64 = -32055; pub const ENCRYPTION_ERROR: i64 = -32055;
pub const FETCH_ERROR: i64 = -32060; pub const FETCH_ERROR: i64 = -32060;
pub const ON_DEMAND_ERROR: i64 = -32065;
} }
pub fn unimplemented(details: Option<String>) -> Error { pub fn unimplemented(details: Option<String>) -> Error {
@ -308,3 +309,11 @@ pub fn unknown_block() -> Error {
data: None, 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::time::{Instant, Duration};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use futures::{self, BoxFuture, Future}; use futures::{self, future, BoxFuture, Future};
use rlp::{self, UntrustedRlp, View}; use rlp::{self, UntrustedRlp, View};
use time::get_time; use time::get_time;
use util::{H160, H256, Address, FixedHash, U256, H64, Uint}; 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> { fn balance(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
self.active()?;
let address = address.into(); 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())?; let inner = || {
match client.balance(&address, id.into()) { self.active()?;
Some(balance) => Ok(balance.into()), match num.0.clone() {
None => Err(errors::state_pruned()), 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> { fn storage_at(&self, address: RpcH160, pos: RpcU256, num: Trailing<BlockNumber>) -> BoxFuture<RpcH256, Error> {
self.active()?;
let address: Address = RpcH160::into(address); let address: Address = RpcH160::into(address);
let position: U256 = RpcU256::into(pos); 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())?; let inner = || {
match client.storage_at(&address, &H256::from(position), id.into()) { self.active()?;
Some(s) => Ok(s.into()), match num.0.clone() {
None => Err(errors::state_pruned()), 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> { fn transaction_count(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
self.active()?;
let address: Address = RpcH160::into(address); let address: Address = RpcH160::into(address);
match num.0 { let inner = move || {
BlockNumber::Pending => Ok(take_weak!(self.miner).nonce(&*take_weak!(self.client), &address).into()), self.active()?;
id => { match num.0.clone() {
let client = take_weak!(self.client); 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())?; check_known(&*client, id.clone())?;
match client.nonce(&address, id.into()) { match client.nonce(&address, id.into()) {
Some(nonce) => Ok(nonce.into()), Some(nonce) => Ok(nonce.into()),
None => Err(errors::state_pruned()), None => Err(errors::state_pruned()),
}
} }
} }
} };
future::done(inner()).boxed()
} }
fn block_transaction_count_by_hash(&self, hash: RpcH256) -> Result<Option<RpcU256>, Error> { fn block_transaction_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>, Error> {
self.active()?; let inner = || {
Ok( self.active()?;
take_weak!(self.client).block(BlockId::Hash(hash.into())) Ok(take_weak!(self.client).block(BlockId::Hash(hash.into()))
.map(|block| block.transactions_count().into()) .map(|block| block.transactions_count().into()))
) };
future::done(inner()).boxed()
} }
fn block_transaction_count_by_number(&self, num: BlockNumber) -> Result<Option<RpcU256>, Error> { fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>, Error> {
self.active()?; 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 { future::done(inner()).boxed()
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())
)
}
} }
fn block_uncles_count_by_hash(&self, hash: RpcH256) -> Result<Option<RpcU256>, Error> { fn block_uncles_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>, Error> {
self.active()?; let inner = || {
self.active()?;
Ok(take_weak!(self.client).block(BlockId::Hash(hash.into()))
.map(|block| block.uncles_count().into()))
};
Ok( future::done(inner()).boxed()
take_weak!(self.client).block(BlockId::Hash(hash.into()))
.map(|block| block.uncles_count().into())
)
} }
fn block_uncles_count_by_number(&self, num: BlockNumber) -> Result<Option<RpcU256>, Error> { fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>, Error> {
self.active()?; 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 { future::done(inner()).boxed()
BlockNumber::Pending => Ok(Some(0.into())),
_ => Ok(
take_weak!(self.client).block(num.into())
.map(|block| block.uncles_count().into())
),
}
} }
fn code_at(&self, address: RpcH160, num: Trailing<BlockNumber>) -> Result<Bytes, Error> { fn code_at(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
self.active()?;
let address: Address = RpcH160::into(address); 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())?; let inner = || {
match client.code(&address, id.into()) { self.active()?;
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)), match num.0.clone() {
None => Err(errors::state_pruned()), 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> { fn block_by_hash(&self, hash: RpcH256, include_txs: bool) -> BoxFuture<Option<RichBlock>, Error> {
self.active()?; 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> { fn block_by_number(&self, num: BlockNumber, include_txs: bool) -> BoxFuture<Option<RichBlock>, Error> {
self.active()?; 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> { 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::on_demand::{request, OnDemand};
use light::net::LightProtocol; use light::net::LightProtocol;
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::{AccountProvider, DappId};
use ethcore::encoded; use ethcore::encoded;
use ethcore::ids::BlockId; use ethcore::ids::BlockId;
use ethsync::LightSync; use ethsync::LightSync;
use futures::{future, BoxFuture}; use futures::{future, Future, BoxFuture};
use v1::helpers::{CallRequest as CRequest, errors, limit_logs}; use v1::helpers::{CallRequest as CRequest, errors, limit_logs};
use v1::helpers::dispatch::{dispatch_transaction, default_gas_price}; use v1::helpers::dispatch::{dispatch_transaction, default_gas_price};
@ -52,6 +52,11 @@ pub struct EthClient {
accounts: Arc<AccountProvider>, accounts: Arc<AccountProvider>,
} }
// helper for a specific kind of internal error.
fn err_no_context() -> Error {
errors::internal("network service detached", "")
}
impl EthClient { impl EthClient {
/// Create a new `EthClient` with a handle to the light sync instance, client, /// 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. /// 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 { let maybe_future = match id {
BlockId::Number(n) => { 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 { match cht_root {
None => return future::err(errors::unknown_block()).boxed(), None => return future::err(errors::unknown_block()).boxed(),
Some(root) => { Some(root) => {
@ -86,19 +91,19 @@ impl EthClient {
cht_root: root, 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) => { 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. _ => None, // latest, earliest, and pending will have all already returned.
}; };
match maybe_future { match maybe_future {
Some(recv) => recv.boxed(), Some(recv) => recv.map_err(errors::from_on_demand_error).boxed(),
None => future::err(errors::internal("network service detached", "")).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> { 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> { fn is_mining(&self) -> Result<bool, Error> {
@ -131,12 +136,13 @@ impl Eth for EthClient {
} }
fn accounts(&self, meta: Metadata) -> BoxFuture<Vec<RpcH160>, Error> { 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 let accounts = self.accounts
.note_dapp_used(dapp.clone()) .note_dapp_used(dapp.clone())
.and_then(|_| self.accounts.dapps_addresses(dapp)) .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() future::done(accounts).boxed()
} }
@ -151,11 +157,121 @@ impl Eth for EthClient {
let sync = self.sync.clone(); let sync = self.sync.clone();
let on_demand = self.on_demand.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 { sync.with_context(|ctx| on_demand.account(ctx, request::Account {
header: header, header: header,
address: address, 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>; fn block_number(&self) -> Result<U256, Error>;
/// Returns balance of the given account. /// Returns balance of the given account.
#[rpc(name = "eth_getBalance")] #[rpc(async, name = "eth_getBalance")]
fn balance(&self, H160, Trailing<BlockNumber>) -> BoxFuture<U256, Error>; fn balance(&self, H160, Trailing<BlockNumber>) -> BoxFuture<U256, Error>;
/// Returns content of the storage at given address. /// Returns content of the storage at given address.
#[rpc(name = "eth_getStorageAt")] #[rpc(async, name = "eth_getStorageAt")]
fn storage_at(&self, H160, U256, Trailing<BlockNumber>) -> Result<H256, Error>; fn storage_at(&self, H160, U256, Trailing<BlockNumber>) -> BoxFuture<H256, Error>;
/// Returns block with given hash. /// Returns block with given hash.
#[rpc(name = "eth_getBlockByHash")] #[rpc(async, name = "eth_getBlockByHash")]
fn block_by_hash(&self, H256, bool) -> Result<Option<RichBlock>, Error>; fn block_by_hash(&self, H256, bool) -> BoxFuture<Option<RichBlock>, Error>;
/// Returns block with given number. /// Returns block with given number.
#[rpc(name = "eth_getBlockByNumber")] #[rpc(async, name = "eth_getBlockByNumber")]
fn block_by_number(&self, BlockNumber, bool) -> Result<Option<RichBlock>, Error>; 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). /// Returns the number of transactions sent from given address at given time (block number).
#[rpc(name = "eth_getTransactionCount")] #[rpc(async, name = "eth_getTransactionCount")]
fn transaction_count(&self, H160, Trailing<BlockNumber>) -> Result<U256, Error>; fn transaction_count(&self, H160, Trailing<BlockNumber>) -> BoxFuture<U256, Error>;
/// Returns the number of transactions in a block with given hash. /// Returns the number of transactions in a block with given hash.
#[rpc(name = "eth_getBlockTransactionCountByHash")] #[rpc(async, name = "eth_getBlockTransactionCountByHash")]
fn block_transaction_count_by_hash(&self, H256) -> Result<Option<U256>, Error>; fn block_transaction_count_by_hash(&self, H256) -> BoxFuture<Option<U256>, Error>;
/// Returns the number of transactions in a block with given block number. /// Returns the number of transactions in a block with given block number.
#[rpc(name = "eth_getBlockTransactionCountByNumber")] #[rpc(async, name = "eth_getBlockTransactionCountByNumber")]
fn block_transaction_count_by_number(&self, BlockNumber) -> Result<Option<U256>, Error>; fn block_transaction_count_by_number(&self, BlockNumber) -> BoxFuture<Option<U256>, Error>;
/// Returns the number of uncles in a block with given hash. /// Returns the number of uncles in a block with given hash.
#[rpc(name = "eth_getUncleCountByBlockHash")] #[rpc(async, name = "eth_getUncleCountByBlockHash")]
fn block_uncles_count_by_hash(&self, H256) -> Result<Option<U256>, Error>; fn block_uncles_count_by_hash(&self, H256) -> BoxFuture<Option<U256>, Error>;
/// Returns the number of uncles in a block with given block number. /// Returns the number of uncles in a block with given block number.
#[rpc(name = "eth_getUncleCountByBlockNumber")] #[rpc(async, name = "eth_getUncleCountByBlockNumber")]
fn block_uncles_count_by_number(&self, BlockNumber) -> Result<Option<U256>, Error>; fn block_uncles_count_by_number(&self, BlockNumber) -> BoxFuture<Option<U256>, Error>;
/// Returns the code at given address at given time (block number). /// Returns the code at given address at given time (block number).
#[rpc(name = "eth_getCode")] #[rpc(async, name = "eth_getCode")]
fn code_at(&self, H160, Trailing<BlockNumber>) -> Result<Bytes, Error>; fn code_at(&self, H160, Trailing<BlockNumber>) -> BoxFuture<Bytes, Error>;
/// Sends signed transaction, returning its hash. /// Sends signed transaction, returning its hash.
#[rpc(name = "eth_sendRawTransaction")] #[rpc(name = "eth_sendRawTransaction")]