No block number in get work while in geth-compat mode. (#1821)
This commit is contained in:
parent
6ba1e66d32
commit
c5ffb5af79
@ -257,7 +257,7 @@ pub fn get_temp_journal_db() -> GuardedTempResult<Box<JournalDB>> {
|
||||
}
|
||||
|
||||
impl MiningBlockChainClient for TestBlockChainClient {
|
||||
fn prepare_open_block(&self, _author: Address, _gas_range_target: (U256, U256), _extra_data: Bytes) -> OpenBlock {
|
||||
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock {
|
||||
let engine = &self.spec.engine;
|
||||
let genesis_header = self.spec.genesis_header();
|
||||
let mut db_result = get_temp_journal_db();
|
||||
@ -265,7 +265,7 @@ impl MiningBlockChainClient for TestBlockChainClient {
|
||||
self.spec.ensure_db_good(db.as_hashdb_mut());
|
||||
|
||||
let last_hashes = vec![genesis_header.hash()];
|
||||
OpenBlock::new(
|
||||
let mut open_block = OpenBlock::new(
|
||||
engine.deref(),
|
||||
self.vm_factory(),
|
||||
Default::default(),
|
||||
@ -273,10 +273,13 @@ impl MiningBlockChainClient for TestBlockChainClient {
|
||||
db,
|
||||
&genesis_header,
|
||||
last_hashes,
|
||||
Address::zero(),
|
||||
(3141562.into(), 31415620.into()),
|
||||
vec![]
|
||||
).expect("Opening block for tests will not fail.")
|
||||
author,
|
||||
gas_range_target,
|
||||
extra_data
|
||||
).expect("Opening block for tests will not fail.");
|
||||
// TODO [todr] Override timestamp for predictability (set_timestamp_now kind of sucks)
|
||||
open_block.set_timestamp(10_000_000);
|
||||
open_block
|
||||
}
|
||||
|
||||
fn vm_factory(&self) -> &EvmFactory {
|
||||
|
@ -104,8 +104,8 @@ pub struct Dependencies {
|
||||
pub external_miner: Arc<ExternalMiner>,
|
||||
pub logger: Arc<RotatingLogger>,
|
||||
pub settings: Arc<NetworkSettings>,
|
||||
pub allow_pending_receipt_query: bool,
|
||||
pub net_service: Arc<ManageNetwork>,
|
||||
pub geth_compatibility: bool,
|
||||
}
|
||||
|
||||
fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {
|
||||
@ -163,7 +163,10 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
|
||||
&deps.secret_store,
|
||||
&deps.miner,
|
||||
&deps.external_miner,
|
||||
deps.allow_pending_receipt_query
|
||||
EthClientOptions {
|
||||
allow_pending_receipt_query: !deps.geth_compatibility,
|
||||
send_block_number_in_get_work: !deps.geth_compatibility,
|
||||
}
|
||||
);
|
||||
server.add_delegate(client.to_delegate());
|
||||
|
||||
|
@ -211,8 +211,8 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
||||
external_miner: external_miner.clone(),
|
||||
logger: logger.clone(),
|
||||
settings: Arc::new(cmd.net_settings.clone()),
|
||||
allow_pending_receipt_query: !cmd.geth_compatibility,
|
||||
net_service: manage_network.clone()
|
||||
net_service: manage_network.clone(),
|
||||
geth_compatibility: cmd.geth_compatibility,
|
||||
});
|
||||
|
||||
let dependencies = rpc::Dependencies {
|
||||
|
@ -47,6 +47,23 @@ use v1::helpers::CallRequest as CRequest;
|
||||
use v1::impls::{default_gas_price, dispatch_transaction, error_codes};
|
||||
use serde;
|
||||
|
||||
/// Eth RPC options
|
||||
pub struct EthClientOptions {
|
||||
/// Returns receipt from pending blocks
|
||||
pub allow_pending_receipt_query: bool,
|
||||
/// Send additional block number when asking for work
|
||||
pub send_block_number_in_get_work: bool,
|
||||
}
|
||||
|
||||
impl Default for EthClientOptions {
|
||||
fn default() -> Self {
|
||||
EthClientOptions {
|
||||
allow_pending_receipt_query: true,
|
||||
send_block_number_in_get_work: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Eth rpc implementation.
|
||||
pub struct EthClient<C, S: ?Sized, M, EM> where
|
||||
C: MiningBlockChainClient,
|
||||
@ -60,7 +77,7 @@ pub struct EthClient<C, S: ?Sized, M, EM> where
|
||||
miner: Weak<M>,
|
||||
external_miner: Arc<EM>,
|
||||
seed_compute: Mutex<SeedHashCompute>,
|
||||
allow_pending_receipt_query: bool,
|
||||
options: EthClientOptions,
|
||||
}
|
||||
|
||||
impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
|
||||
@ -70,7 +87,7 @@ impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
|
||||
EM: ExternalMinerService {
|
||||
|
||||
/// Creates new EthClient.
|
||||
pub fn new(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<AccountProvider>, miner: &Arc<M>, em: &Arc<EM>, allow_pending_receipt_query: bool)
|
||||
pub fn new(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<AccountProvider>, miner: &Arc<M>, em: &Arc<EM>, options: EthClientOptions)
|
||||
-> EthClient<C, S, M, EM> {
|
||||
EthClient {
|
||||
client: Arc::downgrade(client),
|
||||
@ -79,7 +96,7 @@ impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
|
||||
accounts: Arc::downgrade(accounts),
|
||||
external_miner: em.clone(),
|
||||
seed_compute: Mutex::new(SeedHashCompute::new()),
|
||||
allow_pending_receipt_query: allow_pending_receipt_query,
|
||||
options: options,
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,7 +513,7 @@ impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
let miner = take_weak!(self.miner);
|
||||
let hash: H256 = hash.into();
|
||||
match miner.pending_receipts().get(&hash) {
|
||||
Some(receipt) if self.allow_pending_receipt_query => to_value(&Receipt::from(receipt.clone())),
|
||||
Some(receipt) if self.options.allow_pending_receipt_query => to_value(&Receipt::from(receipt.clone())),
|
||||
_ => {
|
||||
let client = take_weak!(self.client);
|
||||
let receipt = client.transaction_receipt(TransactionID::Hash(hash));
|
||||
@ -582,8 +599,13 @@ impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
let pow_hash = b.hash();
|
||||
let target = Ethash::difficulty_to_boundary(b.block().header().difficulty());
|
||||
let seed_hash = self.seed_compute.lock().get_seedhash(b.block().header().number());
|
||||
|
||||
if self.options.send_block_number_in_get_work {
|
||||
let block_number = RpcU256::from(b.block().header().number());
|
||||
to_value(&(RpcH256::from(pow_hash), RpcH256::from(seed_hash), RpcH256::from(target), block_number))
|
||||
} else {
|
||||
to_value(&(RpcH256::from(pow_hash), RpcH256::from(seed_hash), RpcH256::from(target)))
|
||||
}
|
||||
}).unwrap_or(Err(Error::internal_error())) // no work found.
|
||||
},
|
||||
_ => Err(Error::invalid_params())
|
||||
|
@ -42,7 +42,7 @@ mod traces;
|
||||
mod rpc;
|
||||
|
||||
pub use self::web3::Web3Client;
|
||||
pub use self::eth::EthClient;
|
||||
pub use self::eth::{EthClient, EthClientOptions};
|
||||
pub use self::eth_filter::EthFilterClient;
|
||||
pub use self::eth_signing::{EthSigningUnsafeClient, EthSigningQueueClient};
|
||||
pub use self::net::NetClient;
|
||||
|
@ -121,7 +121,7 @@ impl EthTester {
|
||||
&account_provider,
|
||||
&miner_service,
|
||||
&external_miner,
|
||||
true
|
||||
Default::default(),
|
||||
);
|
||||
let eth_sign = EthSigningUnsafeClient::new(
|
||||
&client,
|
||||
|
@ -181,8 +181,9 @@ impl MinerService for TestMinerService {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn map_sealing_work<F, T>(&self, _chain: &MiningBlockChainClient, _f: F) -> Option<T> where F: FnOnce(&ClosedBlock) -> T {
|
||||
None
|
||||
fn map_sealing_work<F, T>(&self, chain: &MiningBlockChainClient, f: F) -> Option<T> where F: FnOnce(&ClosedBlock) -> T {
|
||||
let open_block = chain.prepare_open_block(self.author(), *self.gas_range_target.write(), self.extra_data());
|
||||
Some(f(&open_block.close()))
|
||||
}
|
||||
|
||||
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
|
||||
|
@ -29,7 +29,7 @@ use ethcore::receipt::LocalizedReceipt;
|
||||
use ethcore::transaction::{Transaction, Action};
|
||||
use ethcore::miner::{ExternalMiner, MinerService};
|
||||
use ethsync::SyncState;
|
||||
use v1::{Eth, EthClient, EthSigning, EthSigningUnsafeClient};
|
||||
use v1::{Eth, EthClient, EthClientOptions, EthSigning, EthSigningUnsafeClient};
|
||||
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService};
|
||||
use rustc_serialize::hex::ToHex;
|
||||
|
||||
@ -64,13 +64,19 @@ struct EthTester {
|
||||
|
||||
impl Default for EthTester {
|
||||
fn default() -> Self {
|
||||
Self::new_with_options(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl EthTester {
|
||||
pub fn new_with_options(options: EthClientOptions) -> Self {
|
||||
let client = blockchain_client();
|
||||
let sync = sync_provider();
|
||||
let ap = accounts_provider();
|
||||
let miner = miner_service();
|
||||
let hashrates = Arc::new(Mutex::new(HashMap::new()));
|
||||
let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
|
||||
let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner, true).to_delegate();
|
||||
let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner, options).to_delegate();
|
||||
let sign = EthSigningUnsafeClient::new(&client, &ap, &miner).to_delegate();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(eth);
|
||||
@ -790,15 +796,26 @@ fn returns_no_work_if_cant_mine() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn returns_error_if_can_mine_and_no_closed_block() {
|
||||
use ethsync::{SyncState};
|
||||
|
||||
fn returns_correct_work_package() {
|
||||
let eth_tester = EthTester::default();
|
||||
eth_tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap());
|
||||
eth_tester.sync.status.write().state = SyncState::Idle;
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":["0x3bbe93f74e7b97ae00784aeff8819c5cb600dd87e8b282a5d3446f3f871f0347","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x01"],"id":1}"#;
|
||||
|
||||
assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_return_block_number() {
|
||||
let eth_tester = EthTester::new_with_options(EthClientOptions {
|
||||
allow_pending_receipt_query: true,
|
||||
send_block_number_in_get_work: false,
|
||||
});
|
||||
eth_tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":["0x3bbe93f74e7b97ae00784aeff8819c5cb600dd87e8b282a5d3446f3f871f0347","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000"],"id":1}"#;
|
||||
|
||||
assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user