-
Notifications
You must be signed in to change notification settings - Fork 699
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New reference doc for Custom RPC V2 (#4654)
Thanks for @xlc for the original seed info, I've just fixed it up a bit and added example links. I've moved the comparison between eth-rpc-api and frontier outside, as it is opinionation. I think the content there was good but should live in the README of the corresponding repos. No strong opinion, happy either way. --------- Co-authored-by: Bryan Chen <xlchen1291@gmail.com> Co-authored-by: Bastian Köcher <git@kchr.de> Co-authored-by: Gonçalo Pestana <g6pestana@gmail.com> Co-authored-by: command-bot <>
- Loading branch information
1 parent
9bb1f3f
commit d783ca9
Showing
9 changed files
with
96 additions
and
3 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
//! # Custom RPC do's and don'ts | ||
//! | ||
//! **TLDR:** don't create new custom RPCs. Instead, rely on custom Runtime APIs, combined with | ||
//! `state_call` | ||
//! | ||
//! ## Background | ||
//! | ||
//! Polkadot-SDK offers the ability to query and subscribe storages directly. However what it does | ||
//! not have is [view functions](https://github.com/paritytech/polkadot-sdk/issues/216). This is an | ||
//! essential feature to avoid duplicated logic between runtime and the client SDK. Custom RPC was | ||
//! used as a solution. It allow the RPC node to expose new RPCs that clients can be used to query | ||
//! computed properties. | ||
//! | ||
//! ## Problems with Custom RPC | ||
//! | ||
//! Unfortunately, custom RPC comes with many problems. To list a few: | ||
//! | ||
//! - It is offchain logic executed by the RPC node and therefore the client has to trust the RPC | ||
//! node. | ||
//! - To upgrade or add a new RPC logic, the RPC node has to be upgraded. This can cause significant | ||
//! trouble when the RPC infrastructure is decentralized as we will need to coordinate multiple | ||
//! parties to upgrade the RPC nodes. | ||
//! - A lot of boilerplate code are required to add custom RPC. | ||
//! - It prevents the dApp to use a light client or alternative client. | ||
//! - It makes ecosystem tooling integration much more complicated. For example, the dApp will not | ||
//! be able to use [Chopsticks](https://github.com/AcalaNetwork/chopsticks) for testing as | ||
//! Chopsticks will not have the custom RPC implementation. | ||
//! - Poorly implemented custom RPC can be a DoS vector. | ||
//! | ||
//! Hence, we should avoid custom RPC. | ||
//! | ||
//! ## Alternatives | ||
//! | ||
//! Generally, [`sc_rpc::state::StateBackend::call`] aka. `state_call` should be used instead of | ||
//! custom RPC. | ||
//! | ||
//! Usually, each custom RPC comes with a corresponding runtime API which implements the business | ||
//! logic. So instead of invoke the custom RPC, we can use `state_call` to invoke the runtime API | ||
//! directly. This is a trivial change on the dApp and no change on the runtime side. We may remove | ||
//! the custom RPC from the node side if wanted. | ||
//! | ||
//! There are some other cases that a simple runtime API is not enough. For example, implementation | ||
//! of Ethereum RPC requires an additional offchain database to index transactions. In this | ||
//! particular case, we can have the RPC implemented on another client. | ||
//! | ||
//! For example, the Acala EVM+ RPC are implemented by | ||
//! [eth-rpc-adapter](https://github.com/AcalaNetwork/bodhi.js/tree/master/packages/eth-rpc-adapter). | ||
//! Alternatively, the [Frontier](https://github.com/polkadot-evm/frontier) project also provided | ||
//! Ethereum RPC compatibility directly in the node-side software. | ||
//! | ||
//! ## Create a new Runtime API | ||
//! | ||
//! For example, let's take a look a the process through which the account nonce can be queried | ||
//! through an RPC. First, a new runtime-api needs to be declared: | ||
#![doc = docify::embed!("../../substrate/frame/system/rpc/runtime-api/src/lib.rs", AccountNonceApi)] | ||
//! | ||
//! This API is implemented at the runtime level, always inside [`sp_api::impl_runtime_apis!`]. | ||
//! | ||
//! As noted, this is already enough to make this API usable via `state_call`. | ||
//! | ||
//! ## Create a new custom RPC (Legacy) | ||
//! | ||
//! Should you wish to implement the legacy approach of exposing this runtime-api as a custom | ||
//! RPC-api, then a custom RPC server has to be defined. | ||
#![doc = docify::embed!("../../substrate/utils/frame/rpc/system/src/lib.rs", SystemApi)] | ||
//! | ||
//! ## Add a new RPC to the node (Legacy) | ||
//! | ||
//! Finally, this custom RPC needs to be integrated into the node side. This is usually done in a | ||
//! `rpc.rs` in a typical template, as follows: | ||
#![doc = docify::embed!("../../templates/minimal/node/src/rpc.rs", create_full)] | ||
//! | ||
//! ## Future | ||
//! | ||
//! - [XCQ](https://forum.polkadot.network/t/cross-consensus-query-language-xcq/7583) will be a good | ||
//! solution for most of the query needs. | ||
//! - [New JSON-RPC Specification](https://github.com/paritytech/json-rpc-interface-spec) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters