Backports for beta 2.2.2 (#9976)
* version: bump beta to 2.2.2 * Add experimental RPCs flag (#9928) * WiP * Enable experimental RPCs. * Keep existing blocks when restoring a Snapshot (#8643) * Rename db_restore => client * First step: make it compile! * Second step: working implementation! * Refactoring * Fix tests * PR Grumbles * PR Grumbles WIP * Migrate ancient blocks interating backward * Early return in block migration if snapshot is aborted * Remove RwLock getter (PR Grumble I) * Remove dependency on `Client`: only used Traits * Add test for recovering aborted snapshot recovery * Add test for migrating old blocks * Fix build * PR Grumble I * PR Grumble II * PR Grumble III * PR Grumble IV * PR Grumble V * PR Grumble VI * Fix one test * Fix test * PR Grumble * PR Grumbles * PR Grumbles II * Fix tests * Release RwLock earlier * Revert Cargo.lock * Update _update ancient block_ logic: set local in `commit` * Update typo in ethcore/src/snapshot/service.rs Co-Authored-By: ngotchac <ngotchac@gmail.com> * Adjust requests costs for light client (#9925) * PIP Table Cost relative to average peers instead of max peers * Add tracing in PIP new_cost_table * Update stat peer_count * Use number of leeching peers for Light serve costs * Fix test::light_params_load_share_depends_on_max_peers (wrong type) * Remove (now) useless test * Remove `load_share` from LightParams.Config Prevent div. by 0 * Add LEECHER_COUNT_FACTOR * PR Grumble: u64 to u32 for f64 casting * Prevent u32 overflow for avg_peer_count * Add tests for LightSync::Statistics * Fix empty steps (#9939) * Don't send empty step twice or empty step then block. * Perform basic validation of locally sealed blocks. * Don't include empty step twice. * prevent silent errors in daemon mode, closes #9367 (#9946) * Fix a deadlock (#9952) * Update informant: - decimal in Mgas/s - print every 5s (not randomly between 5s and 10s) * Fix dead-lock in `blockchain.rs` * Update locks ordering * Fix light client informant while syncing (#9932) * Add `is_idle` to LightSync to check importing status * Use SyncStateWrapper to make sure is_idle gets updates * Update is_major_import to use verified queue size as well * Add comment for `is_idle` * Add Debug to `SyncStateWrapper` * `fn get` -> `fn into_inner` * ci: rearrange pipeline by logic (#9970) * ci: rearrange pipeline by logic * ci: rename docs script * fix docker build (#9971) * Deny unknown fields for chainspec (#9972) * Add deny_unknown_fields to chainspec * Add tests and fix existing one * Remove serde_ignored dependency for chainspec * Fix rpc test eth chain spec * Fix starting_nonce_test spec * Improve block and transaction propagation (#9954) * Refactor sync to add priority tasks. * Send priority tasks notifications. * Propagate blocks, optimize transactions. * Implement transaction propagation. Use sync_channel. * Tone down info. * Prevent deadlock by not waiting forever for sync lock. * Fix lock order. * Don't use sync_channel to prevent deadlocks. * Fix tests. * Fix unstable peers and slowness in sync (#9967) * Don't sync all peers after each response * Update formating * Fix tests: add `continue_sync` to `Sync_step` * Update ethcore/sync/src/chain/mod.rs Co-Authored-By: ngotchac <ngotchac@gmail.com> * fix rpc middlewares * fix Cargo.lock * json: resolve merge in spec * rpc: fix starting_nonce_test * ci: allow nightl job to fail
This commit is contained in:
@@ -218,9 +218,10 @@ impl<M: core::Middleware<Metadata>> WsDispatcher<M> {
|
||||
|
||||
impl<M: core::Middleware<Metadata>> core::Middleware<Metadata> for WsDispatcher<M> {
|
||||
type Future = Either<
|
||||
core::FutureRpcResult<M::Future>,
|
||||
core::FutureRpcResult<M::Future, M::CallFuture>,
|
||||
core::FutureResponse,
|
||||
>;
|
||||
type CallFuture = core::middleware::NoopCallFuture;
|
||||
|
||||
fn on_request<F, X>(&self, request: core::Request, meta: Metadata, process: F)
|
||||
-> Either<Self::Future, X>
|
||||
|
||||
@@ -53,6 +53,7 @@ mod codes {
|
||||
pub const FETCH_ERROR: i64 = -32060;
|
||||
pub const NO_LIGHT_PEERS: i64 = -32065;
|
||||
pub const DEPRECATED: i64 = -32070;
|
||||
pub const EXPERIMENTAL_RPC: i64 = -32071;
|
||||
}
|
||||
|
||||
pub fn unimplemented(details: Option<String>) -> Error {
|
||||
@@ -500,3 +501,15 @@ pub fn on_demand_others(err: &OnDemandError) -> Error {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a descriptive error in case experimental RPCs are not enabled.
|
||||
pub fn require_experimental(allow_experimental_rpcs: bool, eip: &str) -> Result<(), Error> {
|
||||
if allow_experimental_rpcs {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error {
|
||||
code: ErrorCode::ServerError(codes::EXPERIMENTAL_RPC),
|
||||
message: format!("This method is not part of the official RPC API yet (EIP-{}). Run with `--jsonrpc-experimental` to enable it.", eip),
|
||||
data: Some(Value::String(format!("See EIP: https://eips.ethereum.org/EIPS/eip-{}", eip))),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@ impl<C, M, U, S> Parity for ParityClient<C, M, U> where
|
||||
BlockNumber::Earliest => BlockId::Earliest,
|
||||
BlockNumber::Latest => BlockId::Latest,
|
||||
};
|
||||
let receipts = try_bf!(self.client.block_receipts(id).ok_or_else(errors::unknown_block));
|
||||
let receipts = try_bf!(self.client.localized_block_receipts(id).ok_or_else(errors::unknown_block));
|
||||
Box::new(future::ok(receipts.into_iter().map(Into::into).collect()))
|
||||
}
|
||||
|
||||
|
||||
@@ -47,15 +47,22 @@ pub struct PersonalClient<D: Dispatcher> {
|
||||
accounts: Arc<AccountProvider>,
|
||||
dispatcher: D,
|
||||
allow_perm_unlock: bool,
|
||||
allow_experimental_rpcs: bool,
|
||||
}
|
||||
|
||||
impl<D: Dispatcher> PersonalClient<D> {
|
||||
/// Creates new PersonalClient
|
||||
pub fn new(accounts: &Arc<AccountProvider>, dispatcher: D, allow_perm_unlock: bool) -> Self {
|
||||
pub fn new(
|
||||
accounts: &Arc<AccountProvider>,
|
||||
dispatcher: D,
|
||||
allow_perm_unlock: bool,
|
||||
allow_experimental_rpcs: bool,
|
||||
) -> Self {
|
||||
PersonalClient {
|
||||
accounts: accounts.clone(),
|
||||
dispatcher,
|
||||
allow_perm_unlock,
|
||||
allow_experimental_rpcs,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,6 +161,8 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
|
||||
}
|
||||
|
||||
fn sign_191(&self, version: EIP191Version, data: Value, account: RpcH160, password: String) -> BoxFuture<RpcH520> {
|
||||
try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "191"));
|
||||
|
||||
let data = try_bf!(eip191::hash_message(version, data));
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
let accounts = self.accounts.clone();
|
||||
@@ -174,6 +183,8 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
|
||||
}
|
||||
|
||||
fn sign_typed_data(&self, typed_data: EIP712, account: RpcH160, password: String) -> BoxFuture<RpcH520> {
|
||||
try_bf!(errors::require_experimental(self.allow_experimental_rpcs, "712"));
|
||||
|
||||
let data = match hash_structured_data(typed_data) {
|
||||
Ok(d) => d,
|
||||
Err(err) => return Box::new(future::err(errors::invalid_call_data(err.kind()))),
|
||||
|
||||
@@ -205,6 +205,7 @@ impl<T: ActivityNotifier> Middleware<T> {
|
||||
|
||||
impl<M: core::Metadata, T: ActivityNotifier> core::Middleware<M> for Middleware<T> {
|
||||
type Future = core::FutureResponse;
|
||||
type CallFuture = core::middleware::NoopCallFuture;
|
||||
|
||||
fn on_request<F, X>(&self, request: core::Request, meta: M, process: F) -> Either<Self::Future, X> where
|
||||
F: FnOnce(core::Request, M) -> X,
|
||||
|
||||
@@ -243,6 +243,7 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{
|
||||
"params": {
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"durationLimit": "0x0d",
|
||||
"homesteadTransition": "0xffffffffffffffff",
|
||||
"daoHardforkTransition": "0xffffffffffffffff",
|
||||
@@ -253,7 +254,6 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{
|
||||
},
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"accountStartNonce": "0x00",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
@@ -292,6 +292,7 @@ const POSITIVE_NONCE_SPEC: &'static [u8] = br#"{
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"homesteadTransition": "0xffffffffffffffff",
|
||||
"daoHardforkTransition": "0xffffffffffffffff",
|
||||
"daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000",
|
||||
@@ -301,7 +302,6 @@ const POSITIVE_NONCE_SPEC: &'static [u8] = br#"{
|
||||
},
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"accountStartNonce": "0x0100",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
|
||||
@@ -57,6 +57,16 @@ fn miner_service() -> Arc<TestMinerService> {
|
||||
}
|
||||
|
||||
fn setup() -> PersonalTester {
|
||||
setup_with(Config {
|
||||
allow_experimental_rpcs: true
|
||||
})
|
||||
}
|
||||
|
||||
struct Config {
|
||||
pub allow_experimental_rpcs: bool,
|
||||
}
|
||||
|
||||
fn setup_with(c: Config) -> PersonalTester {
|
||||
let runtime = Runtime::with_thread_count(1);
|
||||
let accounts = accounts_provider();
|
||||
let client = blockchain_client();
|
||||
@@ -64,7 +74,7 @@ fn setup() -> PersonalTester {
|
||||
let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor())));
|
||||
|
||||
let dispatcher = FullDispatcher::new(client, miner.clone(), reservations, 50);
|
||||
let personal = PersonalClient::new(&accounts, dispatcher, false);
|
||||
let personal = PersonalClient::new(&accounts, dispatcher, false, c.allow_experimental_rpcs);
|
||||
|
||||
let mut io = IoHandler::default();
|
||||
io.extend_with(personal.to_delegate());
|
||||
@@ -418,3 +428,109 @@ fn sign_eip191_structured_data() {
|
||||
let response = tester.io.handle_request_sync(&request).unwrap();
|
||||
assert_eq!(response, expected)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_structured_data() {
|
||||
let tester = setup();
|
||||
let secret: Secret = keccak("cow").into();
|
||||
let address = tester.accounts.insert_account(secret, &"lol".into()).unwrap();
|
||||
let request = r#"{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "personal_signTypedData",
|
||||
"params": [
|
||||
{
|
||||
"primaryType": "Mail",
|
||||
"domain": {
|
||||
"name": "Ether Mail",
|
||||
"version": "1",
|
||||
"chainId": "0x1",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
|
||||
},
|
||||
"message": {
|
||||
"from": {
|
||||
"name": "Cow",
|
||||
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
|
||||
},
|
||||
"to": {
|
||||
"name": "Bob",
|
||||
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
|
||||
},
|
||||
"contents": "Hello, Bob!"
|
||||
},
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "version", "type": "string" },
|
||||
{ "name": "chainId", "type": "uint256" },
|
||||
{ "name": "verifyingContract", "type": "address" }
|
||||
],
|
||||
"Person": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "wallet", "type": "address" }
|
||||
],
|
||||
"Mail": [
|
||||
{ "name": "from", "type": "Person" },
|
||||
{ "name": "to", "type": "Person" },
|
||||
{ "name": "contents", "type": "string" }
|
||||
]
|
||||
}
|
||||
},
|
||||
""#.to_owned() + &format!("0x{:x}", address) + r#"",
|
||||
"lol"
|
||||
],
|
||||
"id": 1
|
||||
}"#;
|
||||
let expected = r#"{"jsonrpc":"2.0","result":"0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c","id":1}"#;
|
||||
let response = tester.io.handle_request_sync(&request).unwrap();
|
||||
assert_eq!(response, expected)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_disable_experimental_apis() {
|
||||
// given
|
||||
let tester = setup_with(Config {
|
||||
allow_experimental_rpcs: false,
|
||||
});
|
||||
|
||||
// when
|
||||
let request = r#"{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "personal_sign191",
|
||||
"params": [
|
||||
"0x01",
|
||||
{},
|
||||
"0x1234567891234567891234567891234567891234",
|
||||
"lol"
|
||||
],
|
||||
"id": 1
|
||||
}"#;
|
||||
let r1 = tester.io.handle_request_sync(&request).unwrap();
|
||||
let request = r#"{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "personal_signTypedData",
|
||||
"params": [
|
||||
{
|
||||
"types": {},
|
||||
"message": {},
|
||||
"domain": {
|
||||
"name": "",
|
||||
"version": "1",
|
||||
"chainId": "0x1",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
|
||||
},
|
||||
"primaryType": ""
|
||||
},
|
||||
"0x1234567891234567891234567891234678912344",
|
||||
"lol"
|
||||
],
|
||||
"id": 1
|
||||
}"#;
|
||||
let r2 = tester.io.handle_request_sync(&request).unwrap();
|
||||
|
||||
// then
|
||||
let expected = r#"{"jsonrpc":"2.0","error":{"code":-32071,"message":"This method is not part of the official RPC API yet (EIP-191). Run with `--jsonrpc-experimental` to enable it.","data":"See EIP: https://eips.ethereum.org/EIPS/eip-191"},"id":1}"#;
|
||||
assert_eq!(r1, expected);
|
||||
|
||||
let expected = r#"{"jsonrpc":"2.0","error":{"code":-32071,"message":"This method is not part of the official RPC API yet (EIP-712). Run with `--jsonrpc-experimental` to enable it.","data":"See EIP: https://eips.ethereum.org/EIPS/eip-712"},"id":1}"#;
|
||||
assert_eq!(r2, expected);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user