From 2de7ba7a485547eaef6e5a79ac97d3b9953ba6b6 Mon Sep 17 00:00:00 2001 From: librelois <c@elo.tf> Date: Thu, 26 May 2022 08:22:06 +0200 Subject: [PATCH] Add rml16 presentation --- README.md | 4 + public/images/Duniter-v2.png | Bin 0 -> 14337 bytes public/images/Substrate.png | Bin 0 -> 9134 bytes public/images/patricia-trie.png | Bin 0 -> 19994 bytes public/rml16/duniter-v2s/index.html | 38 ++ public/rml16/duniter-v2s/slideshow.md | 584 ++++++++++++++++++++++++++ public/rml16/event.md | 1 + 7 files changed, 627 insertions(+) create mode 100644 public/images/Duniter-v2.png create mode 100644 public/images/Substrate.png create mode 100644 public/images/patricia-trie.png create mode 100644 public/rml16/duniter-v2s/index.html create mode 100644 public/rml16/duniter-v2s/slideshow.md create mode 100644 public/rml16/event.md diff --git a/README.md b/README.md index 3da88df..26f6759 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,10 @@ sh launch-me-once-after-git-clone-to-auto-update-readme.sh - [Dunitrust (Duniter-Rust)](https://librelois.duniter.io/slides/rml14/dunitrust/) - [Public Key Secure Transport Layer](https://librelois.duniter.io/slides/rml14/pkstl/) +### RML 16 (mai 2022) + +- [Duniter-v2s (substrate)](https://librelois.duniter.io/slides/rml16/duniter-v2s/) + ### Rustkathon 1 (mars 2019) - [Le protocole DUP](https://librelois.duniter.io/slides/rustkathon2019_1/dup-protocol/) diff --git a/public/images/Duniter-v2.png b/public/images/Duniter-v2.png new file mode 100644 index 0000000000000000000000000000000000000000..552b6965badae2abf93f97dfaee3306fbfe32f17 GIT binary patch literal 14337 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 literal 0 HcmV?d00001 diff --git a/public/images/Substrate.png b/public/images/Substrate.png new file mode 100644 index 0000000000000000000000000000000000000000..8993dacf54f4747ec26872de5a58e317a31ae849 GIT binary patch literal 9134 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 Y#ml<vyp^9A7#J8lUHx3vIVCg!0HR3qzyJUM literal 0 HcmV?d00001 diff --git a/public/images/patricia-trie.png b/public/images/patricia-trie.png new file mode 100644 index 0000000000000000000000000000000000000000..48bc9883f52f9059a617b6c6a8bb7d454bdde948 GIT binary patch literal 19994 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 literal 0 HcmV?d00001 diff --git a/public/rml16/duniter-v2s/index.html b/public/rml16/duniter-v2s/index.html new file mode 100644 index 0000000..11bcd3f --- /dev/null +++ b/public/rml16/duniter-v2s/index.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> + +<head> + <title>RML16: Duniter-v2s</title> + <meta charset="utf-8"> + <link rel="stylesheet" href="../../common.css"> + <link rel="stylesheet" href="../../lib/mermaid.dark.css"> + <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/tonsky/FiraCode@1.206/distr/fira_code.css"> +</head> + +<body> + <textarea id="source"></textarea> + <script src="../../lib/mermaid.min.js"></script> + <script src="../../lib/remark-latest.min.js"></script> + <script> + var slideshow = remark.create({ + sourceUrl: 'slideshow.md', + highlightStyle: 'tomorrow-night', + countIncrementalSlides: false + }); + // don't let mermaid automatically load on start + mermaid.initialize({ + startOnLoad: false, + cloneCssStyles: false + }); + + slideshow.on("afterShowSlide", s => { + const [slide] = document.getElementsByClassName("remark-visible"); + mermaid.sequenceConfig = { + diagramMarginY: 0 + }; + mermaid.init(Array.from(slide.getElementsByClassName("mermaid"))); + }); + </script> +</body> + +</html> \ No newline at end of file diff --git a/public/rml16/duniter-v2s/slideshow.md b/public/rml16/duniter-v2s/slideshow.md new file mode 100644 index 0000000..19d5b5b --- /dev/null +++ b/public/rml16/duniter-v2s/slideshow.md @@ -0,0 +1,584 @@ +class: dark, middle, center + +## Duniter-v2s (substrate) + + + +<!----> + +_21 mai 2022_ +_RML #16_ +_Librelois <c@elo.tf>_ + +Follow the presentation on your screen : + +`librelois.duniter.io/slides/rml16/duniter-v2s` + +--- + +layout: true +class: dark + +.center[Duniter-v2s (substrate)] + +--- + +## Sommaire + +* [Project history](#history) +* [Codebase & Contributors](#codebase) +* [Implemented features](#features) +* [Missing features](#missing-features) +* [Ğ1 migration plan](#g1-migration) +* [Substrate concepts](#substrate) + * [State Transition Function](#stf) + * [Wasm runtime](#wasm) + * [Forkless runtime upgrades](#forkless) + * [Onchain storage](#storage) + * [FRAME and Pallets](#frame) + * [Calls](#calls) + * [Runtime metadata](#metadata) + * [Extrinsic](#extrinsic) + * [SignedExtra](#extra) + * [SCALE](#scale) + * [RPC](#rpc) +* [Recommended libs](#libs) + +--- + +name: history + +## .center[Project history] + +- **July 2021:** Creation of the first PoC + +- **mid July 2021:** video presentation with basic wot and UT creation + +- **January 30, 2022:** video presentation with smiths sub-wot and wire transfers + +- **Feb-May, 2022:** No big step, but a lot of small work on a wide range + +- **May 27, 2022:** launch of the first test currency called `ĞDev` + +--- + +name: codebase + +## .center[Codebase & Contributors] + +### Codebase stats + +- 120 files +- 20 crates (18 lib + 2 bin) +- 43 Merge requests merged +- 13_918 rust lines code (including tests) +- 3_693 comments lines +- ~200h hours of work over 4 months + +### Contributors + +- librelois: 231 commits +- Tuxmain: 8 commits +- Pini: 4 commits +- Vit: 1 commit +- Hugo: 1 commit +- Poka: 1 commit + +--- + +name: features + +## .center[Implemented features] + +* p2p network (provided by substrate) +* forkless protocol upgrade (provided by substrate) +* UD creation and revalution according to the RTM +* Currency transfers (in unit and in UD) +* User actions can be scheduled, which allows for instance automatic transfers (substrate pallet). +* Multisig accounts: shared account requiring the signature of several private keys (substrate pallet). +* Atomic swap (substrate pallet). +* A ğ1-like web of trust (without distance) +* Smiths sub-wot +* On-chain governance for protocol upgrades (2/3 of smiths) +* The possibility to delegate rights on your account to another account (substrate pallet) +* A common treasury managed by on-chain governance (substrate pallet) +* And some other features + +--- + +name: missing-features + +## .center[Missing features] + +* Weighs benchmarking: essential to correctly estimate the cost of execution of each transaction. At the moment, weights are entered manually at overvalued values. +* The management of "offences": i.e. how to sanction the authorities that act badly. The BABE/GRANDPA consensus manages the system of automatic reporting of "offences" and verification of their validity, which allows to prove that an authority has acted badly, but it does not manage the sanctions +* Evaluation of the distance rule: due to the way substrate is designed, and the constraints of the BABE/GRANDPA consensus, we cannot directly compute the distance on-chain. So we will have to develop an oracle system to submit the computation result. +* Automatic renewal of membership +* À better on-chain governance (modalities to be decided with the community) +* Lots of other small features and improvements +* And more tests and documentation + +--- + +name: g1-migration + +## .center[Ğ1 migration plan] + +* Deploy a first test currency without migration (ĞDev) +-- + +* Development of the new technical ecosystem around the ĞDev (indexers, wallets, tools, etc) +-- + +* Fake migration of the ğ1-test + * Convert ğ1-test state to duniter-v2s genesis config + * launch a ğtest whose genesis takes the state of the Ğ1-test, but keep the ğ1-test in parallel + * massively test this ĞTest and fix bugs + * Eventual shutdown of ĞDev to not have too many different networks to manage. + * Redo this fake migration until it's perfectly mastered +-- + +* Fake migration of Ğ1 +-- + +* Official communication to users about the upcoming changes and calls to test the new wallets on this "fake Ğ1" +-- + +* Redo the fake ğ1 migration until it's perfectly mastered +-- + +* Choose dates for the definitive migration of ğ1-test and Ğ1 +-- + +* New duniter-v1 release that will stop producing blocks at the chosen dates +-- + +* Real ğ1-test migration then real Ğ1 migration + +--- + +name: substrate + +## .center[Substrate concepts] + +very generic & customisable blockchain framework with many concepts + +* State Transition Function & storage by block +* WASM runtime +* Forkless runtime upgrades +* Storage trie and proofs +* pallets and FRAME (a framework in the framework) +* + +--- + +name: stf + +## .center[State Transition Function] + +<div class="mermaid"> +graph LR + B[Block_n]-->F + State_n-1-->F("STF (Bn, Sn-1)") + F-->State_n +</div> + +* The STF check all rules and produce the new state. +* The STF shoud be a "pure" function (perfectly reproducible). +* Verifying a block is the same as executing the STF with this block as input + + +--- + +name: wasm + +## .center[Wasm runtime] + +<div class="mermaid"> +graph LR + B["Substrate Node (Host)"]-->|runtime APIs| R(Wasm runtime) + R-->|"Externalities (Host functions)"| B +</div> + +* The host (also called node/binary/client) use runtime APis to call the runtime. +-- + + * Examples of runtime APIs: + * execute_block(block) + * validate_transaction(source, tx, block_hash) + * generate_session_keys(seed) +-- +* The runtime use externalities to call host functions. +-- + + * Examples of externalities: + * get(key) + * set(key, value) + * ed25519_verify(sig, msg, pub_key) + * sr25519_verify(sig, msg, pub_key) + * blake2_256(data) + * twox_128(data) + +--- + +name: forkless + +## .center[Forkless runtime upgrades] + +* The runtime wasm bytecode is written in the onchain storage +* => so the runtime can modify its own code (with externality `set(key, value)`)! +-- + +* And this is necessarily the case, because any change of onchain storage can only be done by the State Transiton Function (the block execution) +-- + + + +=> This implies that any blockchain substrate must define an on-chain governance mechanism for the update of the runtime. + + +--- + +name: storage + +## .center[Onchain storage] + +Each block have an onchain storage. + +The onchain storage should contains only the data that are needed to verify *efficiently* all protocol rules. + +<div class="mermaid"> +graph LR + B[Block_n+1]-->F + State_n-->F("STF (Bn+1, Sn)") + F-->State_n+1 +</div> + +The block itself does not contain the storage, only its merkle root. + +--- + +name: storage2 + +## .center[Onchain storage (2)] + +.center[<div class="mermaid"> +graph TD + E["Storage Externalities"]-->O[Overlay Change Set] + O-->M[Patricia Merkle trie] + M-->D["Key value Database (ParityDB)"] +</div>] + +--- + +name: storage3 + +## .center[Onchain storage (3)] + +### .center[Patricia Trie] + +* Position in the tree defines the associated key. + +* space optimized for elements which share a prefix + +.center[] + +--- + +name: storage4 + +## .center[Onchain storage (4)] + +### .center[Patricia Merkle Trie] + +More detailed presentation here: [Substrate Storage Deep Dive](https://www.shawntabrizi.com/substrate/substrate-storage-deep-dive/) + +To resume: + +* The performance of the storage (and thus the execution time of the blocks), depends strongly on the number of keys, but especially on the good distribution of these. + +* The access time to a key in the tree evolves according to log(N), where N is the number of keys, but only if the keys are well distributed. + +=> All storage keys should be prefixed by a hash ! + +--- + +name: frame + +## .center[FRAME and Pallets] + +FRAME: Framework for Runtime Aggregation of Modularized Entities + +FRAME is divided in "pallets". A pallet looks like a module. Each pallet contains its own call, storage entries, events. + +All storage keys in a pallet are prefixed by the hash `twox128(palletInstanceName)`. +-- + + +Some pallets are instantiable, this means that it is possible to use several instances of this pallet in the same runtime (max 16), most pallets are not instantiable (max 1 instance per runtime). + +For instance, substrate pallets "collective" and "treasury" are instantiable. + +??? + +FRAME is optional, but provides a framework that helps a lot to code our runtime cleanly, and already provides a lot of features that can be reused directly (because coded in a very generic way). In practice, all substrate based projects use FRAME + +--- + +name: calls + +## .center[Calls] + +Each pallet can define a list of calls. + +Calls are "dispachable" functions, that can be called by a user with an extrinsic or by the runtime itself. + +Each user transaction contain one call (and some metadata). + +<div class="mermaid"> +graph LR + U["User app"]-->|"Transaction (1 call)"| N[Substrate node] + N-->|"Extrinsic (1 call)"| R[Runtime] +</div> + +From runtime point of view, transaction are called extrinsics, because they come from the external world. + +Each call expects an exact number of parameters, each of a precise type, indicated in the call definition and in the runtime metadata. + +--- + +name: origin + +## .center[Origin] + +Each Call is dispatched by an origin, it's looks like the "caller". + +<div class="mermaid"> +graph LR + S["Signed extrinsic"]-->|"Origin::Signed(pubkey)"| C("call()") + U["Unsigned extrinsic (aka. Inherent)"]-->|"Origin::None"| C + R[Runtime]-->|"Any origin"| C +</div> + +Every FRAME runtime has at least 3 kind of origin: Signed, None and Root. Each pallet can define additional Origin types. + +--- + +name: origin + +## .center[Origin (2)] + +Origin are very usefull to manage permnissions easily. + +Example: In ĞDev 2/3 of smiths members can act as Root. + +Substrate pallet collective define Origin `Members(p, n)`, where `p` is a number of members of the group and `n` the size of the group. + +In ĞDev runtime, we have an instance of pallet collective named `SmithsCollective`, so we just need to declare that origin `SmithsCollective::Members(x, y)` can act as root if x/y >= 2/3. +-- + + +Thanks to FRAME and Rust declarative style, we can configure this permission behavior in one line of code! + +```rust +UpgradableOrigin = EnsureProportionAtLeast<2, 3, AccountId, SmithsInstance>; +``` + +--- + +name: events + +## .center[Events] + +Substrate events are for external world, and mainly for indexers. +It's the way to say from the runtime "Something happened". + +Each pallet can defined it's how events. Events are emitted by calls execution or by hooks execution. + +The code of a typical call consists of 4 steps: + +```rust +fn call_name(origin, param1, param2) { + // 1. Verify origin and params + // 2. Read storage to ensure all protocol rules are + // 3. Write storage changes + // 4. Emit events +} +``` + +--- + +name: events2 + +## .center[Events (2)] + +Example: events of identity pallet: + +```rust +pub enum Event<T: Config> { + /// A new identity has been created + IdtyCreated { + idty_index: IdtyIndex, + owner_key: AccountId, + }, + /// An identity has been validated + IdtyValidated { idty_index: IdtyIndex }, + /// An identity has been removed + IdtyRemoved { idty_index: IdtyIndex }, +} +``` + +--- + +name: metadata + +## .center[Runtime metadata] + +The runtime metadata define: + +- Extrinsic format +- All calls definition (pallet, callName, params nams and types) +- All events definition (pallet, eventName, params nams and types) +- All storage entries definitions +- All constants definitions +- All errors definitions +- SCALE definition of all types + +Theses metadata can be obtained with the RPC method `state_getMetadata`. + +--- + +name: extrinsic + +## .center[Extrinsic] + +The runtime define also the format of extrinsics, for now duniter-v2s use the defaut format, already very generic: + +```rust +struct UncheckedExtrinsic<Address, Call, Signature, SignedExtra> +{ + /// The signature, address, and signed extra + signature: Option<(Address, Signature, SignedExtra)>, + /// The function that should be called. + function: Call, +} +``` + +`SignedExtra`, define extra metadata that we should append to the signed message. + +All theses data shoud be SCALE encoded. + +--- + +name: extra + +## .center[SignedExtra] + +```rust +pub type SignedExtra = ( + frame_system::CheckSpecVersion<Runtime>, + frame_system::CheckTxVersion<Runtime>, + frame_system::CheckGenesis<Runtime>, + frame_system::CheckEra<Runtime>, + frame_system::CheckNonce<Runtime>, + transaction_payment::ChargeTransactionPayment<Runtime>, +); +``` + +Our SignedExtra contains: + +* Runtime spec version +* Transaction format version +* Genesis hash (to avoid replay attack on another network) +* Mortality +* User nonce +* an optional tip for block author (can be zero) + +--- + +name: scale + +## .center[SCALE] + +The SCALE (Simple Concatenated Aggregate Little-Endian) Codec is a lightweight, efficient, binary serialization and deserialization codec. +In substrate, SCALE is used everywhere: + +- All RPC method parameters must be SCALE encoded +- Extrinsics must be SCALE encoded +- RPC responses payloads are SCALE encoded +- Blocks contents is SCALE encoded +- … + +--- + +name: rpc + +## .center[RPC] + +Substrate RPC API is the way to interact with a substrate chain. +It's a generic API that work with all substrate chains. +This API follow the [JSON-RPC 2.0 specification](https://www.jsonrpc.org/specification). + +Essentials: + +* `state_getMetadata()`: get runtime metadata +* `system_accountNextIndex(accountId)`: get next user nonce +* `author_submitExtrinsic(extrinsic)`: submit an extrinsic +* `chain_getFinalizedHead()`: get head of last finalized block header +* `state_getStorage(key, at?)`: get a value in onchain storage at specified block hash (or best block) +* `state_subscribeStorage(keys?)`: subcribe to storage changes at given keys prefix + + +The method `rpc_methods()` return the list of available RPC methods. + +--- + +name: rpc2 + +## .center[RPC (2)] + +### .center[RPC query example] + +* Get runtime metadata + +``` +curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "state_getMetadata"}' http://localhost:9933 +``` + +* Get current universal dividend amount + +``` +curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "state_getStorage", "params": ["0x235cdca73b1fc4b26dd60639fe5bf213e693e94477a5a91aed0757f3de0b8168"]}' http://localhost:9933 +``` +-- + +=> twox128("UniversalDividend") ++ twox128("CurrentUd") + +--- + +name: libs + +## .center[Recommended libs] + +In practices, it's recommended to use libs that provide more convenient interface for your language in front of RPC API. + +It's not magic, all theses libs use the runtime metadata (queried at startup or provided at compile time) to generate a convenient API for a specific runtime. + +* Javascript: [Polkadot-JS API](https://github.com/polkadot-js/api/) +* Python: [Python Interface](https://github.com/polkascan/py-substrate-interface) +* Rust: [subxt](https://github.com/paritytech/substrate-subxt) +* Go: [Go RPC Client](https://github.com/centrifuge/go-substrate-rpc-client/) + +Find more on [awesome-substrate repo](https://github.com/substrate-developer-hub/awesome-substrate). + + +--- + +## .center[Thanks for your attention] + +Slides made with [remark](https://github.com/gnab/remark). +Graphes created with [mermaid](https://github.com/knsv/mermaid). + +See the sources of this presentation on duniter gitlab: + +.center[[https://git.duniter.org/librelois/slides](https://git.duniter.org/librelois/slides)] diff --git a/public/rml16/event.md b/public/rml16/event.md new file mode 100644 index 0000000..430f44c --- /dev/null +++ b/public/rml16/event.md @@ -0,0 +1 @@ +RML 16 (mai 2022) \ No newline at end of file -- GitLab