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 {
|
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 engine = &self.spec.engine;
|
||||||
let genesis_header = self.spec.genesis_header();
|
let genesis_header = self.spec.genesis_header();
|
||||||
let mut db_result = get_temp_journal_db();
|
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());
|
self.spec.ensure_db_good(db.as_hashdb_mut());
|
||||||
|
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
OpenBlock::new(
|
let mut open_block = OpenBlock::new(
|
||||||
engine.deref(),
|
engine.deref(),
|
||||||
self.vm_factory(),
|
self.vm_factory(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
@ -273,10 +273,13 @@ impl MiningBlockChainClient for TestBlockChainClient {
|
|||||||
db,
|
db,
|
||||||
&genesis_header,
|
&genesis_header,
|
||||||
last_hashes,
|
last_hashes,
|
||||||
Address::zero(),
|
author,
|
||||||
(3141562.into(), 31415620.into()),
|
gas_range_target,
|
||||||
vec![]
|
extra_data
|
||||||
).expect("Opening block for tests will not fail.")
|
).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 {
|
fn vm_factory(&self) -> &EvmFactory {
|
||||||
|
@ -104,8 +104,8 @@ pub struct Dependencies {
|
|||||||
pub external_miner: Arc<ExternalMiner>,
|
pub external_miner: Arc<ExternalMiner>,
|
||||||
pub logger: Arc<RotatingLogger>,
|
pub logger: Arc<RotatingLogger>,
|
||||||
pub settings: Arc<NetworkSettings>,
|
pub settings: Arc<NetworkSettings>,
|
||||||
pub allow_pending_receipt_query: bool,
|
|
||||||
pub net_service: Arc<ManageNetwork>,
|
pub net_service: Arc<ManageNetwork>,
|
||||||
|
pub geth_compatibility: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {
|
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.secret_store,
|
||||||
&deps.miner,
|
&deps.miner,
|
||||||
&deps.external_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());
|
server.add_delegate(client.to_delegate());
|
||||||
|
|
||||||
|
@ -211,8 +211,8 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
|
|||||||
external_miner: external_miner.clone(),
|
external_miner: external_miner.clone(),
|
||||||
logger: logger.clone(),
|
logger: logger.clone(),
|
||||||
settings: Arc::new(cmd.net_settings.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 {
|
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 v1::impls::{default_gas_price, dispatch_transaction, error_codes};
|
||||||
use serde;
|
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.
|
/// Eth rpc implementation.
|
||||||
pub struct EthClient<C, S: ?Sized, M, EM> where
|
pub struct EthClient<C, S: ?Sized, M, EM> where
|
||||||
C: MiningBlockChainClient,
|
C: MiningBlockChainClient,
|
||||||
@ -60,7 +77,7 @@ pub struct EthClient<C, S: ?Sized, M, EM> where
|
|||||||
miner: Weak<M>,
|
miner: Weak<M>,
|
||||||
external_miner: Arc<EM>,
|
external_miner: Arc<EM>,
|
||||||
seed_compute: Mutex<SeedHashCompute>,
|
seed_compute: Mutex<SeedHashCompute>,
|
||||||
allow_pending_receipt_query: bool,
|
options: EthClientOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
|
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 {
|
EM: ExternalMinerService {
|
||||||
|
|
||||||
/// Creates new EthClient.
|
/// 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<C, S, M, EM> {
|
||||||
EthClient {
|
EthClient {
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
@ -79,7 +96,7 @@ impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
|
|||||||
accounts: Arc::downgrade(accounts),
|
accounts: Arc::downgrade(accounts),
|
||||||
external_miner: em.clone(),
|
external_miner: em.clone(),
|
||||||
seed_compute: Mutex::new(SeedHashCompute::new()),
|
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 miner = take_weak!(self.miner);
|
||||||
let hash: H256 = hash.into();
|
let hash: H256 = hash.into();
|
||||||
match miner.pending_receipts().get(&hash) {
|
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 client = take_weak!(self.client);
|
||||||
let receipt = client.transaction_receipt(TransactionID::Hash(hash));
|
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 pow_hash = b.hash();
|
||||||
let target = Ethash::difficulty_to_boundary(b.block().header().difficulty());
|
let target = Ethash::difficulty_to_boundary(b.block().header().difficulty());
|
||||||
let seed_hash = self.seed_compute.lock().get_seedhash(b.block().header().number());
|
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());
|
let block_number = RpcU256::from(b.block().header().number());
|
||||||
to_value(&(RpcH256::from(pow_hash), RpcH256::from(seed_hash), RpcH256::from(target), block_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.
|
}).unwrap_or(Err(Error::internal_error())) // no work found.
|
||||||
},
|
},
|
||||||
_ => Err(Error::invalid_params())
|
_ => Err(Error::invalid_params())
|
||||||
|
@ -42,7 +42,7 @@ mod traces;
|
|||||||
mod rpc;
|
mod rpc;
|
||||||
|
|
||||||
pub use self::web3::Web3Client;
|
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_filter::EthFilterClient;
|
||||||
pub use self::eth_signing::{EthSigningUnsafeClient, EthSigningQueueClient};
|
pub use self::eth_signing::{EthSigningUnsafeClient, EthSigningQueueClient};
|
||||||
pub use self::net::NetClient;
|
pub use self::net::NetClient;
|
||||||
|
@ -121,7 +121,7 @@ impl EthTester {
|
|||||||
&account_provider,
|
&account_provider,
|
||||||
&miner_service,
|
&miner_service,
|
||||||
&external_miner,
|
&external_miner,
|
||||||
true
|
Default::default(),
|
||||||
);
|
);
|
||||||
let eth_sign = EthSigningUnsafeClient::new(
|
let eth_sign = EthSigningUnsafeClient::new(
|
||||||
&client,
|
&client,
|
||||||
|
@ -181,8 +181,9 @@ impl MinerService for TestMinerService {
|
|||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_sealing_work<F, T>(&self, _chain: &MiningBlockChainClient, _f: F) -> Option<T> where F: FnOnce(&ClosedBlock) -> T {
|
fn map_sealing_work<F, T>(&self, chain: &MiningBlockChainClient, f: F) -> Option<T> where F: FnOnce(&ClosedBlock) -> T {
|
||||||
None
|
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> {
|
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
|
||||||
|
@ -29,7 +29,7 @@ use ethcore::receipt::LocalizedReceipt;
|
|||||||
use ethcore::transaction::{Transaction, Action};
|
use ethcore::transaction::{Transaction, Action};
|
||||||
use ethcore::miner::{ExternalMiner, MinerService};
|
use ethcore::miner::{ExternalMiner, MinerService};
|
||||||
use ethsync::SyncState;
|
use ethsync::SyncState;
|
||||||
use v1::{Eth, EthClient, EthSigning, EthSigningUnsafeClient};
|
use v1::{Eth, EthClient, EthClientOptions, EthSigning, EthSigningUnsafeClient};
|
||||||
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService};
|
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService};
|
||||||
use rustc_serialize::hex::ToHex;
|
use rustc_serialize::hex::ToHex;
|
||||||
|
|
||||||
@ -64,13 +64,19 @@ struct EthTester {
|
|||||||
|
|
||||||
impl Default for EthTester {
|
impl Default for EthTester {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
Self::new_with_options(Default::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EthTester {
|
||||||
|
pub fn new_with_options(options: EthClientOptions) -> Self {
|
||||||
let client = blockchain_client();
|
let client = blockchain_client();
|
||||||
let sync = sync_provider();
|
let sync = sync_provider();
|
||||||
let ap = accounts_provider();
|
let ap = accounts_provider();
|
||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let hashrates = Arc::new(Mutex::new(HashMap::new()));
|
let hashrates = Arc::new(Mutex::new(HashMap::new()));
|
||||||
let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
|
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 sign = EthSigningUnsafeClient::new(&client, &ap, &miner).to_delegate();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(eth);
|
io.add_delegate(eth);
|
||||||
@ -790,15 +796,26 @@ fn returns_no_work_if_cant_mine() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn returns_error_if_can_mine_and_no_closed_block() {
|
fn returns_correct_work_package() {
|
||||||
use ethsync::{SyncState};
|
|
||||||
|
|
||||||
let eth_tester = EthTester::default();
|
let eth_tester = EthTester::default();
|
||||||
eth_tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap());
|
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 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()));
|
assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user