From 3c786938c9221ea5d3fb510521dbe53a2f5c61d0 Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Tue, 1 Nov 2022 18:02:56 +1300 Subject: [PATCH] support relaychain (#35) --- e2e/__snapshots__/author.test.ts.snap | 28 ++++++++-------- e2e/__snapshots__/chain.test.ts.snap | 14 ++++---- e2e/storage.test.ts | 4 +-- executor/Cargo.lock | 46 +++++++++++---------------- executor/src/lib.rs | 4 ++- executor/src/main.rs | 4 +-- executor/src/runner_api.rs | 2 +- executor/src/task.rs | 6 ++-- src/blockchain/inherents.ts | 11 +++++-- src/blockchain/txpool.ts | 41 ++++++++++++++++++++---- vendor/smoldot | 2 +- 11 files changed, 94 insertions(+), 68 deletions(-) diff --git a/e2e/__snapshots__/author.test.ts.snap b/e2e/__snapshots__/author.test.ts.snap index 464bed18..e1f702aa 100644 --- a/e2e/__snapshots__/author.test.ts.snap +++ b/e2e/__snapshots__/author.test.ts.snap @@ -22,7 +22,7 @@ exports[`author rpc > works 1`] = ` "events": [], "internalError": undefined, "status": { - "finalized": "0x81a904a5358a1f36535e91fa1a386f333ec6d5e73840585a48111c1f276ce861", + "finalized": "0xeefde1ec4bb9834c9282bdaa2034a1f603ef931b70c25caaa5a97f1fb2720fd5", }, "txHash": "0x379a84a326f2abe840fc3b54db762da86f60c31b20f7d81d15cc5ffb7dc995be", "txIndex": 1, @@ -44,7 +44,7 @@ exports[`author rpc > works 2`] = ` { "preRuntime": [ "0x61757261", - "0x", + "0xe1cf470800000000", ], }, { @@ -106,7 +106,7 @@ exports[`author rpc > works 5`] = ` "status": { "ready": null, }, - "txHash": "0xa35243e8a3b5950431848f6809a6ddb36611f6a10d9fe44a4a984f9925a086c1", + "txHash": "0x7a50dcf54f3f69a233ef03fd835b26b414c2892ccc0aad4f5b1a7b7407dbb16b", "txIndex": undefined, }, ], @@ -117,9 +117,9 @@ exports[`author rpc > works 5`] = ` "events": [], "internalError": undefined, "status": { - "finalized": "0xbc271d06d6f55f5bcbcb3be21fa162901e7d5fd7c8c8fe14bb9a3a9c36e6e1ee", + "finalized": "0x0a88e86168da4aa27a33f9273b34bba3dbef86bd7b246e831333c83a8d38f975", }, - "txHash": "0xa35243e8a3b5950431848f6809a6ddb36611f6a10d9fe44a4a984f9925a086c1", + "txHash": "0x7a50dcf54f3f69a233ef03fd835b26b414c2892ccc0aad4f5b1a7b7407dbb16b", "txIndex": 1, }, ], @@ -131,7 +131,7 @@ exports[`author rpc > works 6`] = ` "block": { "extrinsics": [ "0x280401000b40c030268401", - "0x3102840088dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee00c836c58f39683b5add00e3f1de76f90cc90e0e13fc07e4b6e4125570c8a5c7ac53a2a0ce11cc83afe966525cb1ebc81d2dd6d2f6f8517ad4fb712f706f1fc40c140104000a0000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae692103", + "0x3102840088dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee00ac0122165c15db54e67d09a8f7aa0651c39c80bc775483f15a06dab12f7214019d6ae60ef92f4218819d4ddd2e2726bf500e82e405de7306aecbd6959701ef08140104000a0000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae692103", ], "header": { "digest": { @@ -139,7 +139,7 @@ exports[`author rpc > works 6`] = ` { "preRuntime": [ "0x61757261", - "0x", + "0xe3cf470800000000", ], }, { @@ -152,7 +152,7 @@ exports[`author rpc > works 6`] = ` }, "extrinsicsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "number": 189522, - "parentHash": "0x81a904a5358a1f36535e91fa1a386f333ec6d5e73840585a48111c1f276ce861", + "parentHash": "0xeefde1ec4bb9834c9282bdaa2034a1f603ef931b70c25caaa5a97f1fb2720fd5", "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", }, }, @@ -201,7 +201,7 @@ exports[`author rpc > works 9`] = ` "status": { "ready": null, }, - "txHash": "0x8a9822cf31018457f8a6d8ac5c641f433dcdf250c97955d1ef761500019ee4d7", + "txHash": "0xd56f14739289e8b4e93b208fbb16076d682139e4b09304a811d7d065318412d1", "txIndex": undefined, }, ], @@ -212,9 +212,9 @@ exports[`author rpc > works 9`] = ` "events": [], "internalError": undefined, "status": { - "finalized": "0xe9256f36e500bd6569a4a57a276aeb8db824372e90766bae513c17923c858b30", + "finalized": "0xeaf40e1042a99e9c20fa0b03d0806ce738885597e5ef204dbdf6f325ad905c9e", }, - "txHash": "0x8a9822cf31018457f8a6d8ac5c641f433dcdf250c97955d1ef761500019ee4d7", + "txHash": "0xd56f14739289e8b4e93b208fbb16076d682139e4b09304a811d7d065318412d1", "txIndex": 1, }, ], @@ -226,7 +226,7 @@ exports[`author rpc > works 10`] = ` "block": { "extrinsics": [ "0x280401000b600e31268401", - "0x3102840088dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0053c7d8fa717ad584e223ef83f062ce6ff59de7df0e9f9c09298887fcb5c64f45ca8a1cd7165610b6a15ecbee55777e9f067dd6762b0936eb6d6b3bee3e242604240104000a0000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae69b104", + "0x3102840088dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee00382223470912adf1cd1cdeb094097acc7fc4a8688ae9e1f251efefa6ba671314c85561f4cfe45e329ae4a3979f1a9b9ef21473757945fa471edbdc75865eb40b240104000a0000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae69b104", ], "header": { "digest": { @@ -234,7 +234,7 @@ exports[`author rpc > works 10`] = ` { "preRuntime": [ "0x61757261", - "0x", + "0xe5cf470800000000", ], }, { @@ -247,7 +247,7 @@ exports[`author rpc > works 10`] = ` }, "extrinsicsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "number": 189523, - "parentHash": "0xbc271d06d6f55f5bcbcb3be21fa162901e7d5fd7c8c8fe14bb9a3a9c36e6e1ee", + "parentHash": "0x0a88e86168da4aa27a33f9273b34bba3dbef86bd7b246e831333c83a8d38f975", "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", }, }, diff --git a/e2e/__snapshots__/chain.test.ts.snap b/e2e/__snapshots__/chain.test.ts.snap index 518f58c8..9eff12a7 100644 --- a/e2e/__snapshots__/chain.test.ts.snap +++ b/e2e/__snapshots__/chain.test.ts.snap @@ -207,9 +207,9 @@ exports[`chain rpc > getXXX 8`] = ` } `; -exports[`chain rpc > getXXX 9`] = `"0x81a904a5358a1f36535e91fa1a386f333ec6d5e73840585a48111c1f276ce861"`; +exports[`chain rpc > getXXX 9`] = `"0xeefde1ec4bb9834c9282bdaa2034a1f603ef931b70c25caaa5a97f1fb2720fd5"`; -exports[`chain rpc > getXXX 10`] = `"0x81a904a5358a1f36535e91fa1a386f333ec6d5e73840585a48111c1f276ce861"`; +exports[`chain rpc > getXXX 10`] = `"0xeefde1ec4bb9834c9282bdaa2034a1f603ef931b70c25caaa5a97f1fb2720fd5"`; exports[`chain rpc > getXXX 11`] = ` { @@ -218,7 +218,7 @@ exports[`chain rpc > getXXX 11`] = ` { "preRuntime": [ "0x61757261", - "0x", + "0xe1cf470800000000", ], }, { @@ -248,7 +248,7 @@ exports[`chain rpc > getXXX 12`] = ` { "preRuntime": [ "0x61757261", - "0x", + "0xe1cf470800000000", ], }, { @@ -298,7 +298,7 @@ exports[`chain rpc > subscribeNewHeads 1`] = ` ] `; -exports[`chain rpc > subscribeNewHeads 2`] = `"0x81a904a5358a1f36535e91fa1a386f333ec6d5e73840585a48111c1f276ce861"`; +exports[`chain rpc > subscribeNewHeads 2`] = `"0xeefde1ec4bb9834c9282bdaa2034a1f603ef931b70c25caaa5a97f1fb2720fd5"`; exports[`chain rpc > subscribeNewHeads 3`] = ` [ @@ -309,7 +309,7 @@ exports[`chain rpc > subscribeNewHeads 3`] = ` { "preRuntime": [ "0x61757261", - "0x", + "0xe1cf470800000000", ], }, { @@ -329,4 +329,4 @@ exports[`chain rpc > subscribeNewHeads 3`] = ` ] `; -exports[`chain rpc > subscribeNewHeads 4`] = `"0xbc271d06d6f55f5bcbcb3be21fa162901e7d5fd7c8c8fe14bb9a3a9c36e6e1ee"`; +exports[`chain rpc > subscribeNewHeads 4`] = `"0x0a88e86168da4aa27a33f9273b34bba3dbef86bd7b246e831333c83a8d38f975"`; diff --git a/e2e/storage.test.ts b/e2e/storage.test.ts index fb2d0a51..ef2cb69e 100644 --- a/e2e/storage.test.ts +++ b/e2e/storage.test.ts @@ -70,7 +70,7 @@ describe('storage', () => { callback.mockClear() expect(await dev.newBlock()).toMatchInlineSnapshot( - '"0x81a904a5358a1f36535e91fa1a386f333ec6d5e73840585a48111c1f276ce861"' + '"0xeefde1ec4bb9834c9282bdaa2034a1f603ef931b70c25caaa5a97f1fb2720fd5"' ) await next() @@ -81,7 +81,7 @@ describe('storage', () => { unsub() expect(await dev.newBlock()).toMatchInlineSnapshot( - '"0xbc271d06d6f55f5bcbcb3be21fa162901e7d5fd7c8c8fe14bb9a3a9c36e6e1ee"' + '"0x0a88e86168da4aa27a33f9273b34bba3dbef86bd7b246e831333c83a8d38f975"' ) await delay(100) diff --git a/executor/Cargo.lock b/executor/Cargo.lock index 23940e83..bb7a92ce 100644 --- a/executor/Cargo.lock +++ b/executor/Cargo.lock @@ -37,6 +37,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "anyhow" version = "1.0.65" @@ -488,15 +499,15 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "ed25519-zebra" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" dependencies = [ "curve25519-dalek 3.2.0", + "hashbrown", "hex", "rand_core 0.6.4", "sha2 0.9.9", - "thiserror", "zeroize", ] @@ -520,7 +531,7 @@ dependencies = [ "console_error_panic_hook", "console_log", "futures", - "getrandom 0.2.7", + "getrandom", "hex", "hex-literal", "jsonrpsee", @@ -648,17 +659,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.7" @@ -668,7 +668,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -733,6 +733,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ + "ahash", "serde", ] @@ -1086,7 +1087,7 @@ checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.42.0", ] @@ -1407,9 +1408,6 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] [[package]] name = "rand_core" @@ -1417,7 +1415,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.7", + "getrandom", ] [[package]] @@ -2019,12 +2017,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/executor/src/lib.rs b/executor/src/lib.rs index 50e766c6..4c375be0 100644 --- a/executor/src/lib.rs +++ b/executor/src/lib.rs @@ -28,5 +28,7 @@ pub async fn start(task_id: u32, ws_url: &str) -> Result<(), JsValue> { async fn run_task(client: &Client, task_id: u32) -> Result<(), jsonrpsee::core::Error> { let task = client.get_task(task_id).await?; - task.run(task_id, &client).await + task.run(task_id, &client).await?; + + Ok(()) } diff --git a/executor/src/main.rs b/executor/src/main.rs index 685856b2..c835f0fd 100644 --- a/executor/src/main.rs +++ b/executor/src/main.rs @@ -27,9 +27,9 @@ async fn real_main() -> Result<(), jsonrpsee::core::Error> { let task = client.get_task(task_id).await?; - task.run(task_id, &client).await?; + let res = task.run(task_id, &client).await?; - println!("Done"); + println!("Done {:?}", res); Ok(()) } diff --git a/executor/src/runner_api.rs b/executor/src/runner_api.rs index 353f54a6..8308a246 100644 --- a/executor/src/runner_api.rs +++ b/executor/src/runner_api.rs @@ -44,7 +44,7 @@ pub trait RpcApi { fn get_task(&self, task_id: u32) -> Result; #[method(name = "exec_taskResult")] - fn task_result(&self, task_id: u32, resp: TaskResponse) -> Result<(), RpcError>; + fn task_result(&self, task_id: u32, resp: &TaskResponse) -> Result<(), RpcError>; } pub async fn client(url: &str) -> Result { diff --git a/executor/src/task.rs b/executor/src/task.rs index d6f76876..480b6479 100644 --- a/executor/src/task.rs +++ b/executor/src/task.rs @@ -42,15 +42,15 @@ pub enum TaskResponse { } impl Task { - pub async fn run(&self, task_id: u32, client: &Client) -> Result<(), jsonrpsee::core::Error> { + pub async fn run(&self, task_id: u32, client: &Client) -> Result { let resp = match self.kind { TaskKind::Call => self.call(task_id, client).await, TaskKind::RuntimeVersion => self.runtime_version(task_id, client).await, }?; - client.task_result(task_id, resp).await?; + client.task_result(task_id, &resp).await?; - Ok(()) + Ok(resp) } async fn call( diff --git a/src/blockchain/inherents.ts b/src/blockchain/inherents.ts index 20a2b148..e9ae8b83 100644 --- a/src/blockchain/inherents.ts +++ b/src/blockchain/inherents.ts @@ -3,7 +3,8 @@ import { ApiPromise } from '@polkadot/api' import { Block } from './block' export interface InherentProvider { - createInherents(api: ApiPromise, parent: Block): Promise + createInherents(api: ApiPromise, timestamp: number, parent: Block): Promise + getTimestamp(): number } export class SetTimestamp implements InherentProvider { @@ -13,7 +14,11 @@ export class SetTimestamp implements InherentProvider { this.#getTimestamp = getTimestamp } - async createInherents(api: ApiPromise, _parent: Block): Promise { - return [api.tx.timestamp.set(this.#getTimestamp()).toHex()] + async createInherents(api: ApiPromise, timestamp: number, _parent: Block): Promise { + return [api.tx.timestamp.set(timestamp).toHex()] + } + + getTimestamp(): number { + return this.#getTimestamp() } } diff --git a/src/blockchain/txpool.ts b/src/blockchain/txpool.ts index fba234d1..e7c0ac1c 100644 --- a/src/blockchain/txpool.ts +++ b/src/blockchain/txpool.ts @@ -1,6 +1,6 @@ import { ApiPromise } from '@polkadot/api' import { Header } from '@polkadot/types/interfaces' -import { bnToU8a, u8aToBn } from '@polkadot/util' +import { bnToHex, bnToU8a, compactAddLength, u8aConcat } from '@polkadot/util' import _ from 'lodash' import { Block } from './block' @@ -63,7 +63,7 @@ export class TxPool { } async #buildBlock(wait: Promise) { - await wait + await wait.catch(() => {}) // ignore error const head = this.#chain.head @@ -71,17 +71,29 @@ export class TxPool { const parentHeader = await head.header + const time = this.#inherentProvider.getTimestamp() + const preRuntime = parentHeader.digest.logs[0].asPreRuntime - const [consensusEngine, auraSlot] = preRuntime - const newAuraSlot = bnToU8a(u8aToBn(auraSlot, { isLe: false }).addn(1), { isLe: true, bitLength: 64 }) - const seal = parentHeader.digest.logs[1] + const [consensusEngine] = preRuntime + const rest = parentHeader.digest.logs.slice(1) + let newLogs = parentHeader.digest.logs as any + const expectedSlot = Math.floor(time / ((this.#api.consts.timestamp.minimumPeriod as any).toNumber() * 2)) + if (consensusEngine.isAura) { + const newSlot = compactAddLength(bnToU8a(expectedSlot, { isLe: true, bitLength: 64 })) + newLogs = [{ PreRuntime: [consensusEngine, newSlot] }, ...rest] + } else if (consensusEngine.isBabe) { + // trying to make a SecondaryPlainPreDigest + const newSlot = compactAddLength(u8aConcat('0x02000000', bnToU8a(expectedSlot, { isLe: true, bitLength: 64 }))) + newLogs = [{ PreRuntime: [consensusEngine, newSlot] }, ...rest] + } + const header = this.#api.createType('Header', { parentHash: head.hash, number: head.number + 1, stateRoot: '0x0000000000000000000000000000000000000000000000000000000000000000', extrinsicsRoot: '0x0000000000000000000000000000000000000000000000000000000000000000', digest: { - logs: [{ PreRuntime: [consensusEngine, newAuraSlot] }, seal], + logs: newLogs, }, }) as Header @@ -102,7 +114,14 @@ export class TxPool { newBlock.pushStorageLayer().setAll(resp.storageDiff) - const inherents = await this.#inherentProvider.createInherents(this.#api, newBlock) + if ((this.#api.query as any).babe?.currentSlot) { + // TODO: figure out how to generate a valid babe slot digest instead of just modify the data + // but hey, we can get it working without a valid digest + const key = this.#api.query.babe.currentSlot.key() + newBlock.pushStorageLayer().set(key, bnToHex(expectedSlot, { isLe: true, bitLength: 64 })) + } + + const inherents = await this.#inherentProvider.createInherents(this.#api, time, newBlock) for (const extrinsic of inherents) { try { @@ -138,6 +157,14 @@ export class TxPool { } } + if (this.#api.query.paraInherent?.included) { + // TODO: remvoe this once paraInherent.enter is implemented + // we are relaychain, however as we have not yet implemented the paraInherent.enter + // so need to do some trick to make the on_finalize check happy + const paraInherentIncludedKey = this.#api.query.paraInherent.included.key() + newBlock.pushStorageLayer().set(paraInherentIncludedKey, '0x01') + } + const resp2 = await newBlock.call('BlockBuilder_finalize_block', '0x') newBlock.pushStorageLayer().setAll(resp2.storageDiff) diff --git a/vendor/smoldot b/vendor/smoldot index 37697c41..6df249ea 160000 --- a/vendor/smoldot +++ b/vendor/smoldot @@ -1 +1 @@ -Subproject commit 37697c41dfc0f504f2d5ca23876220d264e981ae +Subproject commit 6df249ea1835b6118df364c5fc7f39991acf778f