fixed eth_call, eth_sendTransaction and eth_estimateGas
This commit is contained in:
@@ -24,17 +24,26 @@ use jsonrpc_core::*;
|
||||
use util::numbers::*;
|
||||
use util::sha3::*;
|
||||
use util::rlp::{encode, UntrustedRlp, View};
|
||||
use util::crypto::KeyPair;
|
||||
use ethcore::client::*;
|
||||
use ethcore::block::IsBlock;
|
||||
use ethcore::views::*;
|
||||
use ethcore::ethereum::Ethash;
|
||||
use ethcore::ethereum::denominations::shannon;
|
||||
use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction};
|
||||
use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action};
|
||||
use v1::traits::{Eth, EthFilter};
|
||||
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, OptionalValue, Index, Filter, Log, Receipt};
|
||||
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, CallRequest, OptionalValue, Index, Filter, Log, Receipt};
|
||||
use v1::helpers::{PollFilter, PollManager, ExternalMinerService, ExternalMiner};
|
||||
use util::keys::store::AccountProvider;
|
||||
|
||||
fn default_gas() -> U256 {
|
||||
U256::from(21_000)
|
||||
}
|
||||
|
||||
fn default_gas_price() -> U256 {
|
||||
shannon() * U256::from(50)
|
||||
}
|
||||
|
||||
/// Eth rpc implementation.
|
||||
pub struct EthClient<C, S, A, M, EM = ExternalMiner>
|
||||
where C: BlockChainClient,
|
||||
@@ -157,6 +166,35 @@ impl<C, S, A, M, EM> EthClient<C, S, A, M, EM>
|
||||
None => Ok(Value::Null)
|
||||
}
|
||||
}
|
||||
|
||||
fn sign_call(client: &Arc<C>, accounts: &Arc<A>, request: CallRequest) -> Option<SignedTransaction> {
|
||||
match request.from {
|
||||
Some(ref from) => {
|
||||
let transaction = EthTransaction {
|
||||
nonce: request.nonce.unwrap_or_else(|| client.nonce(from)),
|
||||
action: request.to.map_or(Action::Create, Action::Call),
|
||||
gas: request.gas.unwrap_or_else(default_gas),
|
||||
gas_price: request.gas_price.unwrap_or_else(default_gas_price),
|
||||
value: request.value.unwrap_or_else(U256::zero),
|
||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||
};
|
||||
|
||||
accounts.account_secret(from).ok().map(|secret| transaction.sign(&secret))
|
||||
},
|
||||
None => {
|
||||
let transaction = EthTransaction {
|
||||
nonce: request.nonce.unwrap_or_else(U256::zero),
|
||||
action: request.to.map_or(Action::Create, Action::Call),
|
||||
gas: request.gas.unwrap_or_else(default_gas),
|
||||
gas_price: request.gas_price.unwrap_or_else(default_gas_price),
|
||||
value: request.value.unwrap_or_else(U256::zero),
|
||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||
};
|
||||
|
||||
KeyPair::create().ok().map(|kp| transaction.sign(kp.secret()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
|
||||
@@ -217,7 +255,7 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
|
||||
|
||||
fn gas_price(&self, params: Params) -> Result<Value, Error> {
|
||||
match params {
|
||||
Params::None => to_value(&(shannon() * U256::from(50))),
|
||||
Params::None => to_value(&default_gas_price()),
|
||||
_ => Err(Error::invalid_params())
|
||||
}
|
||||
}
|
||||
@@ -405,14 +443,22 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
|
||||
|
||||
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||
from_params::<(TransactionRequest, )>(params)
|
||||
.and_then(|(transaction_request, )| {
|
||||
.and_then(|(request, )| {
|
||||
let accounts = take_weak!(self.accounts);
|
||||
match accounts.account_secret(&transaction_request.from) {
|
||||
match accounts.account_secret(&request.from) {
|
||||
Ok(secret) => {
|
||||
let miner = take_weak!(self.miner);
|
||||
let client = take_weak!(self.client);
|
||||
|
||||
let transaction: EthTransaction = transaction_request.into();
|
||||
let transaction = EthTransaction {
|
||||
nonce: request.nonce.unwrap_or_else(|| client.nonce(&request.from)),
|
||||
action: request.to.map_or(Action::Create, Action::Call),
|
||||
gas: request.gas.unwrap_or_else(default_gas),
|
||||
gas_price: request.gas_price.unwrap_or_else(default_gas_price),
|
||||
value: request.value.unwrap_or_else(U256::zero),
|
||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||
};
|
||||
|
||||
let signed_transaction = transaction.sign(&secret);
|
||||
let hash = signed_transaction.hash();
|
||||
|
||||
@@ -461,47 +507,30 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
|
||||
}
|
||||
|
||||
fn call(&self, params: Params) -> Result<Value, Error> {
|
||||
println!("params: {:?}", params);
|
||||
from_params::<(TransactionRequest, BlockNumber)>(params)
|
||||
.and_then(|(transaction_request, _block_number)| {
|
||||
from_params::<(CallRequest, BlockNumber)>(params)
|
||||
.and_then(|(request, _block_number)| {
|
||||
let client = take_weak!(self.client);
|
||||
let accounts = take_weak!(self.accounts);
|
||||
match accounts.account_secret(&transaction_request.from) {
|
||||
Ok(secret) => {
|
||||
let client = take_weak!(self.client);
|
||||
let signed = Self::sign_call(&client, &accounts, request);
|
||||
let output = signed.map(|tx| client.call(&tx)
|
||||
.map(|e| Bytes::new(e.output))
|
||||
.unwrap_or(Bytes::default()));
|
||||
|
||||
let transaction: EthTransaction = transaction_request.into();
|
||||
let signed_transaction = transaction.sign(&secret);
|
||||
|
||||
let output = client.call(&signed_transaction)
|
||||
.map(|e| Bytes::new(e.output))
|
||||
.unwrap_or(Bytes::default());
|
||||
|
||||
to_value(&output)
|
||||
},
|
||||
Err(_) => { to_value(&Bytes::default()) }
|
||||
}
|
||||
to_value(&output)
|
||||
})
|
||||
}
|
||||
|
||||
fn estimate_gas(&self, params: Params) -> Result<Value, Error> {
|
||||
from_params::<(TransactionRequest, BlockNumber)>(params)
|
||||
.and_then(|(transaction_request, _block_number)| {
|
||||
from_params::<(CallRequest, BlockNumber)>(params)
|
||||
.and_then(|(request, _block_number)| {
|
||||
let client = take_weak!(self.client);
|
||||
let accounts = take_weak!(self.accounts);
|
||||
match accounts.account_secret(&transaction_request.from) {
|
||||
Ok(secret) => {
|
||||
let client = take_weak!(self.client);
|
||||
let signed = Self::sign_call(&client, &accounts, request);
|
||||
let output = signed.map(|tx| client.call(&tx)
|
||||
.map(|e| e.gas_used + e.refunded)
|
||||
.unwrap_or(U256::zero()));
|
||||
|
||||
let transaction: EthTransaction = transaction_request.into();
|
||||
let signed_transaction = transaction.sign(&secret);
|
||||
|
||||
let gas_used = client.call(&signed_transaction)
|
||||
.map(|e| e.gas_used + e.refunded)
|
||||
.unwrap_or(U256::zero());
|
||||
|
||||
to_value(&gas_used)
|
||||
},
|
||||
Err(_) => { to_value(&U256::zero()) }
|
||||
}
|
||||
to_value(&output)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user