Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
[try-runtime-cli] Offchain worker support (#8966)
Browse files Browse the repository at this point in the history
* make remote-ext work with ws and safe RPCs

* Update docs.

* Update utils/frame/remote-externalities/Cargo.toml

Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>

* Fix test

* Update lock file

* Update utils/frame/remote-externalities/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Fix build again.

* checkpoint, merging the paged rpc now

* revert lifetime stuff

* WIP: remote client init not working

* Small cleanups

* use jsonrpsee alpha.7

* WIP

* Executiing without errors

* Reorg & cleanup

* Trivial cleaning

* Add txpool & keystore extension

* Small cleaning

* More :cleaning

* Flags: page-size, override-code

* WIP

* Apply suggestions from code review

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Remove heap_pages

* Dry code extraction from state

* Formatting

* More formatting

* Add issue todo

* Use jsonrpsee 0.2.0

* Try trigger gitlab

* Fix "block_import_works" test

* fix native_big_block_import_fails_on_fallback test

* fix commit should work

* Rewrite UI tests

* Revert "Rewrite UI tests"

This reverts commit ada7f67.

* try again with UI

* Use const for legacy heap pages val

* Move parse module to its own file

* Move rpc_api module to its own file

* Apply suggestions from code review

Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>

* trait names: Block, not B

* Corect HEAP_PAGES_TEST_LEGACY export

* Update utils/frame/remote-externalities/src/rpc_api.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Revert test_ext heap_page insert; adjust storage root instead

* Doc comments for try_runtime::cli::Command

* TryRuntime stub

* trailing comma

* Remove unused dev dep in frame-executive

* Improve parse::hash variable name & error index

* Use Result for rpc_api fns

* Richer err messagges

* Remove HEAP_PAGE_TEST_LEGACY

* Update bin/node/executor/tests/basic.rs

Co-authored-by: kianenigma <kian@parity.io>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>
  • Loading branch information
6 people authored Jun 9, 2021
1 parent 3e5b4a2 commit eb9033b
Show file tree
Hide file tree
Showing 12 changed files with 421 additions and 139 deletions.
6 changes: 6 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions bin/node/cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,14 @@ pub enum Subcommand {
#[structopt(name = "benchmark", about = "Benchmark runtime pallets.")]
Benchmark(frame_benchmarking_cli::BenchmarkCmd),

/// Try some experimental command on the runtime. This includes migration and runtime-upgrade
/// testing.
/// Try some command against runtime state.
#[cfg(feature = "try-runtime")]
TryRuntime(try_runtime_cli::TryRuntimeCmd),

/// Try some command against runtime state. Note: `try-runtime` feature must be enabled.
#[cfg(not(feature = "try-runtime"))]
TryRuntime,

/// Verify a signature for a message, provided on STDIN, with a given (public or secret) key.
Verify(VerifyCmd),

Expand Down
7 changes: 6 additions & 1 deletion bin/node/cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ pub fn run() -> Result<()> {

Ok((cmd.run::<Block, Executor>(config), task_manager))
})
}
},
#[cfg(not(feature = "try-runtime"))]
Some(Subcommand::TryRuntime) => {
Err("TryRuntime wasn't enabled when building the node. \
You can enable it with `--features try-runtime`.".into())
},
}
}
3 changes: 3 additions & 0 deletions bin/node/executor/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,9 @@ fn native_big_block_import_succeeds() {
fn native_big_block_import_fails_on_fallback() {
let mut t = new_test_ext(compact_code_unwrap(), false);

// We set the heap pages to 8 because we know that should give an OOM in WASM with the given block.
set_heap_pages(&mut t.ext(), 8);

assert!(
executor_call::<NeverNativeValue, fn() -> _>(
&mut t,
Expand Down
2 changes: 1 addition & 1 deletion frame/executive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ mod tests {
header: Header {
parent_hash: [69u8; 32].into(),
number: 1,
state_root: hex!("6e70de4fa07bac443dc7f8a812c8a0c941aacfa892bb373c5899f7d511d4c25b").into(),
state_root: hex!("ec6bb58b0e4bc7fdf0151a0f601eb825f529fbf90b5be5b2024deba30c5cbbcb").into(),
extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(),
digest: Digest { logs: vec![], },
},
Expand Down
7 changes: 3 additions & 4 deletions primitives/state-machine/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ use crate::{
},
};

use codec::{Decode, Encode};
use codec::Decode;
use hash_db::Hasher;
use sp_core::{
offchain::testing::TestPersistentOffchainDB,
storage::{
well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES, is_child_storage_key},
well_known_keys::{CHANGES_TRIE_CONFIG, CODE, is_child_storage_key},
Storage,
},
traits::TaskExecutorExt,
Expand Down Expand Up @@ -103,7 +103,6 @@ where
assert!(storage.top.keys().all(|key| !is_child_storage_key(key)));
assert!(storage.children_default.keys().all(|key| is_child_storage_key(key)));

storage.top.insert(HEAP_PAGES.to_vec(), 8u64.encode());
storage.top.insert(CODE.to_vec(), code.to_vec());

let mut extensions = Extensions::default();
Expand Down Expand Up @@ -308,7 +307,7 @@ mod tests {
ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec());
ext.set_storage(b"dog".to_vec(), b"puppy".to_vec());
ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec());
let root = H256::from(hex!("2a340d3dfd52f5992c6b117e9e45f479e6da5afffafeb26ab619cf137a95aeb8"));
let root = H256::from(hex!("ed4d8c799d996add422395a6abd7545491d40bd838d738afafa1b8a4de625489"));
assert_eq!(H256::from_slice(ext.storage_root().as_slice()), root);
}

Expand Down
2 changes: 1 addition & 1 deletion utils/frame/remote-externalities/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ hex = "0.4.0"
env_logger = "0.8.2"
log = "0.4.11"
codec = { package = "parity-scale-codec", version = "2.0.0" }

serde_json = "1.0"
serde = "1.0.0"

sp-io = { version = "3.0.0", path = "../../../primitives/io" }
sp-core = { version = "3.0.0", path = "../../../primitives/core" }
Expand Down
27 changes: 17 additions & 10 deletions utils/frame/remote-externalities/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ use sp_core::{
use codec::{Encode, Decode};
use sp_runtime::traits::Block as BlockT;
use jsonrpsee_ws_client::{
WsClientBuilder, WsClient, v2::params::JsonRpcParams, traits::Client,
WsClientBuilder, WsClient, v2::params::JsonRpcParams,
};

pub mod rpc_api;

type KeyPair = (StorageKey, StorageData);

const LOG_TARGET: &str = "remote-ext";
Expand Down Expand Up @@ -72,7 +74,7 @@ impl<B: BlockT> Default for Mode<B> {
}
}

/// configuration of the online execution.
/// Configuration of the offline execution.
///
/// A state snapshot config must be present.
#[derive(Clone)]
Expand All @@ -81,7 +83,7 @@ pub struct OfflineConfig {
pub state_snapshot: SnapshotConfig,
}

/// Description of the transport protocol.
/// Description of the transport protocol (for online execution).
#[derive(Debug)]
pub struct Transport {
uri: String,
Expand Down Expand Up @@ -115,23 +117,24 @@ pub struct OnlineConfig<B: BlockT> {
pub transport: Transport,
}

impl<B: BlockT> OnlineConfig<B> {
/// Return rpc (ws) client.
fn rpc_client(&self) -> &WsClient {
self.transport.client.as_ref().expect("ws client must have been initialized by now; qed.")
}
}

impl<B: BlockT> Default for OnlineConfig<B> {
fn default() -> Self {
Self {
transport: Transport { uri: DEFAULT_TARGET.to_string(), client: None },
transport: Transport { uri: DEFAULT_TARGET.to_owned(), client: None },
at: None,
state_snapshot: None,
modules: vec![],
}
}
}

impl<B: BlockT> OnlineConfig<B> {
/// Return rpc (ws) client.
fn rpc_client(&self) -> &WsClient {
self.transport.client.as_ref().expect("ws client must have been initialized by now; qed.")
}
}

/// Configuration of the state snapshot.
#[derive(Clone)]
Expand Down Expand Up @@ -189,6 +192,7 @@ impl<B: BlockT> Builder<B> {

// RPC methods
impl<B: BlockT> Builder<B> {
/// Get the latest finalized head.
async fn rpc_get_head(&self) -> Result<B::Hash, &'static str> {
trace!(target: LOG_TARGET, "rpc: finalized_head");
RpcApi::<B>::finalized_head(self.as_online().rpc_client()).await.map_err(|e| {
Expand Down Expand Up @@ -250,6 +254,7 @@ impl<B: BlockT> Builder<B> {
prefix: StorageKey,
at: B::Hash,
) -> Result<Vec<KeyPair>, &'static str> {
use jsonrpsee_ws_client::traits::Client;
use serde_json::to_value;
let keys = self.get_keys_paged(prefix, at).await?;
let keys_count = keys.len();
Expand Down Expand Up @@ -438,8 +443,10 @@ impl<B: BlockT> Builder<B> {
info!(target: LOG_TARGET, "injecting a total of {} keys", kv.len());
for (k, v) in kv {
let (k, v) = (k.0, v.0);
// Insert the key,value pair into the test trie backend
ext.insert(k, v);
}

Ok(ext)
}
}
Expand Down
53 changes: 53 additions & 0 deletions utils/frame/remote-externalities/src/rpc_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// This file is part of Substrate.

// Copyright (C) 2021 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! WS RPC API for one off RPC calls to a substrate node.
// TODO: Consolidate one off RPC calls https://github.com/paritytech/substrate/issues/8988

use super::*;

/// Get the header of the block identified by `at`
pub async fn get_header<B: BlockT, S: AsRef<str>>(from: S, at: B::Hash) -> Result<B::Header, String>
where
B::Header: serde::de::DeserializeOwned,
{
use jsonrpsee_ws_client::traits::Client;
let at = serde_json::to_value(at)
.map_err(|e| format!("Block hash could not be converted to JSON due to {:?}", e))?;
let params = vec![at];
let client = WsClientBuilder::default()
.max_request_body_size(u32::MAX)
.build(from.as_ref())
.await
.map_err(|e| format!("`WsClientBuilder` failed to build do to {:?}", e))?;
client.request::<B::Header>("chain_getHeader", JsonRpcParams::Array(params))
.await
.map_err(|e| format!("chain_getHeader request failed due to {:?}", e))
}

/// Get the finalized head
pub async fn get_finalized_head<B: BlockT, S: AsRef<str>>(from: S) -> Result<B::Hash, String> {
use jsonrpsee_ws_client::traits::Client;
let client = WsClientBuilder::default()
.max_request_body_size(u32::MAX)
.build(from.as_ref())
.await
.map_err(|e| format!("`WsClientBuilder` failed to build do to {:?}", e))?;
client.request::<B::Hash>("chain_getFinalizedHead", JsonRpcParams::NoParams)
.await
.map_err(|e| format!("chain_getFinalizedHead request failed due to {:?}", e))
}
5 changes: 4 additions & 1 deletion utils/frame/try-runtime/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,21 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
log = "0.4.8"
parity-scale-codec = { version = "2.0.0" }
serde = "1.0.0"
structopt = "0.3.8"

sc-service = { version = "0.9.0", default-features = false, path = "../../../../client/service" }
sc-cli = { version = "0.9.0", path = "../../../../client/cli" }
sc-executor = { version = "0.9.0", path = "../../../../client/executor" }
sc-client-api = { version = "3.0.0", path = "../../../../client/api" }
structopt = "0.3.8"
sc-chain-spec = { version = "3.0.0", path = "../../../../client/chain-spec" }
sp-state-machine = { version = "0.9.0", path = "../../../../primitives/state-machine" }
sp-api = { version = "3.0.0", path = "../../../../primitives/api" }
sp-blockchain = { version = "3.0.0", path = "../../../../primitives/blockchain" }
sp-runtime = { version = "3.0.0", path = "../../../../primitives/runtime" }
sp-externalities = { version = "0.9.0", path = "../../../../primitives/externalities" }
sp-core = { version = "3.0.0", path = "../../../../primitives/core" }
sp-keystore = { version = "0.9.0", path = "../../../../primitives/keystore" }
frame-try-runtime = { version = "0.9.0", path = "../../../../frame/try-runtime" }

remote-externalities = { version = "0.9.0", path = "../../remote-externalities" }
Loading

0 comments on commit eb9033b

Please sign in to comment.