Substrate开发者中心

Substrate开发者中心

  • 教程
  • 知识库
  • 菜谱
  • 接口手册

›Build a permissioned network

Build a permissioned network

  • Introduction
  • Add node-authorization pallet
  • Launch our permissioned network
Edit

Add node-authorization pallet

You should already be familiar with the Node Template and how to add a new pallet after learning Build a PoE Decentralized Application Tutorial, if not, please complete that tutorial.

About node-authorization pallet

This pallet is a build-in pallet in Substrate FRAME, which manages a configurable set of nodes for a permissioned network. Each node is identified by a PeerId which is simply a wrapper on Vec<u8>. With this pallet, you have two ways to authorize a node which wants to join the network,

  • Join the set of well known nodes between which the connections are allowed. Such effort usually needs to be approved by the governance in the system.
  • Ask for the connection from a node which is already a member of the network. Such node can either be a well known node or a normal one.

A node must have one and only one owner. The owner of a well known node is specified when adding it. If it's a normal node, user can claim it as its owner. To eliminate false claim, the maintainer of the node should claim it before even starting the node (after getting the PeerId of course).

The owner can then change the additional connections for his (or her) node. To make it clear, you can't change the connections between well known nodes, they are always allowed to connect with each other. Instead, you can manipulate the connection between a well know node and a normal node or between two normal nodes.

It uses offchain worker to set authorized nodes in node-authorization pallet. Make sure to enable offchain worker with the right CLI flag as offchain worker is diabled by default for non-authority nodes. Your node can be lagged with the latest block, in this case you need to disable offchain worker and manually set reachable reserved nodes to sync up with the network.

Add our pallet

You should already have Node Template project at hand, otherwise, clone v2.0.0 of the project.

git clone -b v2.0.0 --depth 1 https://github.com/substrate-developer-hub/substrate-node-template

You should be able to compile the project without any error.

cd substrate-node-template/
cargo build --release

Now open the code with your favorite editor, can't wait to make some changes right?

In runtime/Cargo.toml, add the dependency of our pallet,

pallet-node-authorization = { default-features = false, version = '2.0.0' }

Don't forget the std feature pallet-node-authorization/std.

Let's import and use our pallet in runtime/src/lib.rs. Firstly Import the dependency with use frame_system::EnsureRoot, we need it to simulate the governance in our simple blockchain. Then implement the configure trait of our pallet. More description on the trait can be found in its reference doc.

parameter_types! {
    pub const MaxWellKnownNodes: u32 = 8;
    pub const MaxPeerIdLength: u32 = 128;
}

impl pallet_node_authorization::Trait for Runtime {
    type Event = Event;
    type MaxWellKnownNodes = MaxWellKnownNodes;
    type MaxPeerIdLength = MaxPeerIdLength;
    type AddOrigin = EnsureRoot<AccountId>;
    type RemoveOrigin = EnsureRoot<AccountId>;
    type SwapOrigin = EnsureRoot<AccountId>;
    type ResetOrigin = EnsureRoot<AccountId>;
    type WeightInfo = ();
}

Finally, we are ready to put our pallet in construct_runtime macro with following extra line of code.

NodeAuthorization: pallet_node_authorization::{Module, Call, Storage, Event<T>, Config<T>},

Add genesis storage for our pallet

PeerId is encoded in bs58 format, so we need a new library bs58 in node/cargo.toml to decode it to get its bytes.

bs58 = "0.3.1"

Let's see how to add proper genesis storage in node/src/chain_spec.rs. Similarly, import the necessary dependencies.

use sp_core::OpaquePeerId; // A struct wraps Vec<u8>, represents as our `PeerId`.
use node_template_runtime::NodeAuthorizationConfig; // The genesis config that serves for our pallet.

Adding our genesis config in the helper function testnet_genesis,

pallet_node_authorization: Some(NodeAuthorizationConfig {
    nodes: vec![
        (
            OpaquePeerId(bs58::decode("12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2").into_vec().unwrap()),
            endowed_accounts[0].clone()
        ),
        (
            OpaquePeerId(bs58::decode("12D3KooWQYV9dGMFoRzNStwpXztXaBUjtPqi6aU76ZgUriHhKust").into_vec().unwrap()),
            endowed_accounts[1].clone()
        ),
    ],
}),

NodeAuthorizationConfig contains a property named nodes, which is vector of tuple. The first element of the tuple is the OpaquePeerId and we use bs58::decode to convert the PeerId in human readable format to bytes. The second element of the tuple is AccountId and represents the owner of this node, here we are using one of the provided endowned accounts for demonstration. To make it clear, the owner of the first node is Alice, and Bob owns the seconde node.

You may wondering where the 12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 comes from. If you have missed reading the document P2P Networking, I highly recommend you finish it first. Then we can use subkey to generate the above human readable PeerId.

subkey generate-node-key

Notes: make sure to use the correct version which is 2.0.0.

The output of the command is like:

12D3KooWBmAwcd4PJNJvfV89HwE48nwkRmAgo8Vy3uQEyNNHBox2 // this is PeerId.
c12b6d18942f5ee8528c8e2baf4e147b5c5c18710926ea492d09cbd9f6c9f82a // This is node-key.

The overall changes can be found here.

Now all the code changes are finished, we are ready to launch our permissoned network. Go get yourself some water!

Last updated on 2020-9-28 by kaichao
← IntroductionLaunch our permissioned network →
  • About node-authorization pallet
  • Add our pallet
  • Add genesis storage for our pallet
Substrate开发者中心
开发者中心
教程知识库菜谱API 手册
社区
Community HomeStack OverflowTwitterEvents
更多
Substrate Builders ProgramBlogSubstrate GitHubDeveloper Hub GitHubPrivacy PolicyTerms of UseCookie Settings
本Substrate中文文档由登链社区翻译