Rebrand: polkadot → pezkuwi build fixes

- Fixed TypeScript type assertion issues
- Updated imports from api-augment/substrate to api-augment/bizinikiwi
- Fixed imgConvert.mjs header and imports
- Added @ts-expect-error for runtime-converted types
- Fixed all @polkadot copyright headers to @pezkuwi
This commit is contained in:
2026-01-07 02:32:54 +03:00
parent fe2cd390f6
commit 1295c36241
4678 changed files with 26389 additions and 63316 deletions
+139
View File
@@ -0,0 +1,139 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.*
!.env.example
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Sveltekit cache directory
.svelte-kit/
# vitepress build output
**/.vitepress/dist
# vitepress cache directory
**/.vitepress/cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# Firebase cache directory
.firebase/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v3
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Vite logs files
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
+2
View File
@@ -0,0 +1,2 @@
# docs.pezkuwichain.io
A sovereign blockchain parachain built for the Kurdish Nation and Culturel Nations of the world, on blockchain
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 666 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 632 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 670 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 725 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

+1 -1
View File
@@ -6,7 +6,7 @@ flowchart TD
devhub --> guides
devhub --> external_resources
pezkuwi_sdk --> substrate
pezkuwi_sdk --> bizinikiwi
pezkuwi_sdk --> frame
pezkuwi_sdk --> xcm
pezkuwi_sdk --> templates
@@ -1,5 +1,5 @@
graph TB
subgraph Substrate
subgraph Bizinikiwi
direction LR
subgraph Node
end
@@ -1,5 +1,5 @@
graph TB
subgraph Substrate
subgraph Bizinikiwi
direction LR
subgraph Node
end
@@ -1,5 +1,5 @@
graph TB
subgraph Substrate
subgraph Bizinikiwi
direction LR
subgraph Node
Database
@@ -7,5 +7,5 @@ flowchart LR
FRAME -.-> TeyrChainRuntime
PezkuwiSDK[Pezkuwi SDK Node Libraries] -.-> TeyrChainNode
CumulusC[Cumulus Node Libraries] -.-> TeyrChainNode
CumulusR[Cumulus Runtime Libraries] -.-> TeyrChainRuntime
CumulusC[Pezcumulus Node Libraries] -.-> TeyrChainNode
CumulusR[Pezcumulus Runtime Libraries] -.-> TeyrChainRuntime
+107
View File
@@ -0,0 +1,107 @@
#!/usr/bin/env python3
"""
Slow Crate Publisher - 6 dakikada bir 1 crate publish eder
Rate limit'e takilmamak icin yavas yavas publish yapar.
Kullanim:
nohup python3 publish_crates_slow.py > publish_log.txt 2>&1 &
"""
import subprocess
import os
import time
from datetime import datetime
PLACEHOLDER_DIR = '/home/mamostehp/kurdistan-sdk/crate_placeholders'
LOG_FILE = '/home/mamostehp/kurdistan-sdk/publish_log.txt'
INTERVAL_SECONDS = 360 # 6 dakika
def log(msg):
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
line = f"[{timestamp}] {msg}"
print(line, flush=True)
with open(LOG_FILE, 'a') as f:
f.write(line + '\n')
def is_published(name):
"""crates.io'da mevcut mu kontrol et"""
result = subprocess.run(
['cargo', 'search', name, '--limit', '1'],
capture_output=True, text=True, timeout=30
)
return f'{name} = ' in result.stdout
def publish_crate(name):
"""Tek bir crate publish et"""
crate_dir = os.path.join(PLACEHOLDER_DIR, name)
manifest = os.path.join(crate_dir, 'Cargo.toml')
if not os.path.exists(manifest):
return False, "Cargo.toml not found"
result = subprocess.run(
['cargo', 'publish', '--manifest-path', manifest],
capture_output=True, text=True, cwd=crate_dir, timeout=180
)
if result.returncode == 0:
return True, "Success"
elif 'already uploaded' in result.stderr or 'already exists' in result.stderr:
return True, "Already exists"
elif '429' in result.stderr or 'Too Many Requests' in result.stderr:
return False, "Rate limited"
else:
return False, result.stderr[:200]
def get_unpublished_crates():
"""Henuz publish edilmemis crate'leri bul"""
crates = sorted([d for d in os.listdir(PLACEHOLDER_DIR)
if os.path.isdir(os.path.join(PLACEHOLDER_DIR, d))])
unpublished = []
for crate in crates:
if not is_published(crate):
unpublished.append(crate)
return unpublished
def main():
log("=" * 60)
log("Slow Crate Publisher baslatildi")
log(f"Interval: {INTERVAL_SECONDS} saniye (6 dakika)")
log("=" * 60)
unpublished = get_unpublished_crates()
total = len(unpublished)
log(f"Toplam {total} crate publish edilecek")
success_count = 0
fail_count = 0
for i, crate in enumerate(unpublished, 1):
log(f"[{i}/{total}] Publishing: {crate}")
success, msg = publish_crate(crate)
if success:
log(f"{msg}")
success_count += 1
else:
log(f"{msg}")
fail_count += 1
# Rate limit durumunda ekstra bekle
if "Rate limited" in msg:
log(" Rate limited! 10 dakika bekleniyor...")
time.sleep(600)
# Sonraki crate icin bekle
if i < total:
log(f" Sonraki crate icin {INTERVAL_SECONDS}s bekleniyor...")
time.sleep(INTERVAL_SECONDS)
log("=" * 60)
log(f"Tamamlandi! Basarili: {success_count}, Basarisiz: {fail_count}")
log("=" * 60)
if __name__ == "__main__":
main()
+214
View File
@@ -0,0 +1,214 @@
import os
import sys
# Rebranding haritası
REBRAND_MAP = [
("asset-test-utils", "asset-test-pezutils"),
("chain-spec-guide-runtime", "pez-chain-spec-guide-runtime"),
("equivocation-detector", "pez-equivocation-detector"),
("erasure-coding-fuzzer", "pez-erasure-coding-fuzzer"),
("ethereum-standards", "pez-ethereum-standards"),
("finality-relay", "pez-finality-relay"),
("fork-tree", "pez-fork-tree"),
("generate-bags", "pez-generate-bags"),
("kitchensink-runtime", "pez-kitchensink-runtime"),
("messages-relay", "pez-messages-relay"),
("minimal-template-node", "pez-minimal-template-node"),
("minimal-template-runtime", "pez-minimal-template-runtime"),
("node-bench", "pez-node-bench"),
("node-primitives", "pez-node-primitives"),
("node-rpc", "pez-node-rpc"),
("node-runtime-generate-bags", "pez-node-runtime-generate-bags"),
("node-template-release", "pez-node-template-release"),
("node-testing", "pez-node-testing"),
("penpal-emulated-chain", "pez-penpal-emulated-chain"),
("penpal-runtime", "pez-penpal-runtime"),
("remote-ext-tests-bags-list", "pez-remote-ext-tests-bags-list"),
("revive-dev-node", "pez-revive-dev-node"),
("revive-dev-runtime", "pez-revive-dev-runtime"),
("slot-range-helper", "pez-slot-range-helper"),
("solochain-template-node", "pez-solochain-template-node"),
("solochain-template-runtime", "pez-solochain-template-runtime"),
("subkey", "pez-subkey"),
("template-zombienet-tests", "pez-template-zombienet-tests"),
("test-runtime-constants", "peztest-runtime-constants"),
("tracing-gum", "pez-tracing-gum"),
("tracing-gum-proc-macro", "pez-tracing-gum-proc-macro"),
("bp-header-chain", "bp-header-pez-chain"),
("bp-runtime", "pezbp-runtime"),
("bridge-hub-pezkuwichain-emulated-chain", "pezbridge-hub-pezkuwichain-emulated-chain"),
("bridge-hub-pezkuwichain-integration-tests", "pezbridge-hub-pezkuwichain-integration-tests"),
("bridge-hub-pezkuwichain-runtime", "pezbridge-hub-pezkuwichain-runtime"),
("bridge-hub-test-utils", "pezbridge-hub-test-utils"),
("bridge-hub-zagros-emulated-chain", "pezbridge-hub-zagros-emulated-chain"),
("bridge-hub-zagros-integration-tests", "pezbridge-hub-zagros-integration-tests"),
("bridge-hub-zagros-runtime", "pezbridge-hub-zagros-runtime"),
("bridge-runtime-common", "pezbridge-runtime-common"),
("mmr-gadget", "pezmmr-gadget"),
("mmr-rpc", "pezmmr-rpc"),
("snowbridge-beacon-primitives", "pezsnowbridge-beacon-primitives"),
("snowbridge-core", "pezsnowbridge-core"),
("snowbridge-ethereum", "pezsnowbridge-ethereum"),
("snowbridge-inbound-queue-primitives", "pezsnowbridge-inbound-queue-primitives"),
("snowbridge-merkle-tree", "pezsnowbridge-merkle-tree"),
("snowbridge-outbound-queue-primitives", "pezsnowbridge-outbound-queue-primitives"),
("snowbridge-outbound-queue-runtime-api", "pezsnowbridge-outbound-queue-runtime-api"),
("snowbridge-outbound-queue-v2-runtime-api", "pezsnowbridge-outbound-queue-v2-runtime-api"),
("snowbridge-pezpallet-ethereum-client", "snowbridge-pezpallet-ethereum-client"),
("snowbridge-pezpallet-ethereum-client-fixtures", "snowbridge-pezpallet-ethereum-client-fixtures"),
("snowbridge-pezpallet-inbound-queue", "snowbridge-pezpallet-inbound-queue"),
("snowbridge-pezpallet-inbound-queue-fixtures", "snowbridge-pezpallet-inbound-queue-fixtures"),
("snowbridge-pezpallet-inbound-queue-v2", "snowbridge-pezpallet-inbound-queue-v2"),
("snowbridge-pezpallet-inbound-queue-v2-fixtures", "snowbridge-pezpallet-inbound-queue-v2-fixtures"),
("snowbridge-pezpallet-outbound-queue", "snowbridge-pezpallet-outbound-queue"),
("snowbridge-pezpallet-outbound-queue-v2", "snowbridge-pezpallet-outbound-queue-v2"),
("snowbridge-pezpallet-system", "snowbridge-pezpallet-system"),
("snowbridge-pezpallet-system-frontend", "snowbridge-pezpallet-system-frontend"),
("snowbridge-pezpallet-system-v2", "snowbridge-pezpallet-system-v2"),
("snowbridge-runtime-common", "pezsnowbridge-runtime-common"),
("snowbridge-runtime-test-common", "pezsnowbridge-runtime-test-common"),
("snowbridge-system-runtime-api", "pezsnowbridge-system-runtime-api"),
("snowbridge-system-v2-runtime-api", "pezsnowbridge-system-v2-runtime-api"),
("snowbridge-test-utils", "pezsnowbridge-test-utils"),
("snowbridge-verification-primitives", "pezsnowbridge-verification-primitives"),
("xcm-docs", "xcm-pez-docs"),
("xcm-emulator", "xcm-pez-emulator"),
("xcm-executor-integration-tests", "xcm-pez-executor-integration-tests"),
("xcm-procedural", "xcm-pez-procedural"),
("xcm-runtime-apis", "xcm-runtime-pezapis"),
("xcm-simulator", "xcm-pez-simulator"),
("xcm-simulator-example", "xcm-pez-simulator-example"),
("xcm-simulator-fuzzer", "xcm-pez-simulator-fuzzer"),
]
# Hedef dosya uzantıları
TARGET_EXTENSIONS = ('.rs', '.toml', '.md', '.txt', '.yml', '.yaml', '.json', '.py')
# HARİÇ TUTULACAK KLASÖRLER (KESİN LİSTE)
EXCLUDE_DIRS = {'crate_placeholders', '.git', 'target', 'node_modules', '__pycache__'}
def is_path_excluded(path):
"""Verilen yolun yasaklı bir klasörün içinde olup olmadığını kontrol eder."""
parts = path.split(os.sep)
# Eğer path'in herhangi bir parçası EXCLUDE_DIRS içindeyse True döner
return any(excluded in parts for excluded in EXCLUDE_DIRS)
def replace_in_file(filepath):
# Kendi kendimizi değiştirmeyelim
if os.path.basename(filepath) == os.path.basename(__file__):
return
try:
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
original_content = content
for old_name, new_name in REBRAND_MAP:
# 1. Normal (tireli)
content = content.replace(old_name, new_name)
# 2. Snake case (alt çizgili)
old_snake = old_name.replace('-', '_')
new_snake = new_name.replace('-', '_')
content = content.replace(old_snake, new_snake)
if content != original_content:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
print(f" [GÜNCELLENDİ] Dosya içeriği: {filepath}")
except Exception as e:
print(f" [HATA] Dosya okunamadı: {filepath} -> {e}")
def rename_directories_and_files(root_dir):
# topdown=True kullanarak yukarıdan aşağıya iniyoruz, böylece dirs listesini modifiye edebiliriz
for dirpath, dirnames, filenames in os.walk(root_dir, topdown=True):
# GÜVENLİK: Yasaklı klasörleri yerinde (in-place) listeden silerek os.walk'un oraya girmesini engelle
# Bu en güvenli yöntemdir.
dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS]
# Eğer şu anki dizin zaten yasaklı bir yolun altındaysa (üstteki koruma kaçırdıysa) atla
if is_path_excluded(dirpath):
continue
# 1. Dosya isimlerini değiştir
for filename in filenames:
if filename == os.path.basename(__file__):
continue
for old_name, new_name in REBRAND_MAP:
if old_name in filename:
old_file_path = os.path.join(dirpath, filename)
new_filename = filename.replace(old_name, new_name)
new_file_path = os.path.join(dirpath, new_filename)
if os.path.exists(old_file_path):
try:
os.rename(old_file_path, new_file_path)
print(f" [RENAME] Dosya: {filename} -> {new_filename}")
except OSError as e:
print(f" [HATA] Dosya adlandırılamadı {filename}: {e}")
# 2. Klasör isimlerini değiştir
# Not: dirnames listesi üzerinde iterasyon yapıyoruz ama rename işlemi riskli olabilir
# O yüzden sadece şu anki seviyedeki klasörleri kontrol ediyoruz
# Ancak os.walk çalışırken klasör adı değişirse alt dizin taraması sapıtabilir.
# Bu yüzden klasör yeniden adlandırmayı en sona, ayrı bir "bottom-up" geçişe bırakmak daha iyidir
# ama basitlik adına burada dikkatli yapıyoruz.
# İkinci Geçiş: Sadece Klasör İsimleri (Bottom-Up)
# Klasör isimlerini değiştirirken path bozulmasın diye en alttan başlıyoruz
for dirpath, dirnames, filenames in os.walk(root_dir, topdown=False):
if is_path_excluded(dirpath):
continue
for dirname in dirnames:
if dirname in EXCLUDE_DIRS:
continue
for old_name, new_name in REBRAND_MAP:
if old_name == dirname:
old_dir_path = os.path.join(dirpath, dirname)
new_dir_path = os.path.join(dirpath, new_name)
if os.path.exists(old_dir_path):
try:
os.rename(old_dir_path, new_dir_path)
print(f" [RENAME] Klasör: {dirname} -> {new_name}")
except OSError as e:
print(f" [HATA] Klasör adlandırılamadı {dirname}: {e}")
def process_content_updates(root_dir):
for dirpath, dirnames, filenames in os.walk(root_dir, topdown=True):
# Yasaklı klasörlere girme
dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS]
if is_path_excluded(dirpath):
continue
for filename in filenames:
if filename.endswith(TARGET_EXTENSIONS) or filename == 'Cargo.lock':
filepath = os.path.join(dirpath, filename)
replace_in_file(filepath)
def main():
root_dir = os.getcwd()
print("==================================================")
print(f"⚠️ DİKKAT: Çalışma dizini: {root_dir}")
print(f"⚠️ HARİÇ TUTULANLAR: {EXCLUDE_DIRS}")
print("==================================================")
# Otomatik onay veya soru
# confirm = input("Emin misin? (evet/hayir): ")
# if confirm.lower() != "evet": return
print("İşlem başlatılıyor...")
print("\n--- Adım 1: Dosya İçeriklerinin Güncellenmesi ---")
process_content_updates(root_dir)
print("\n--- Adım 2: Klasör ve Dosya İsimlerinin Değiştirilmesi ---")
rename_directories_and_files(root_dir)
print("\n✅ Rebranding işlemi tamamlandı.")
if __name__ == "__main__":
main()
@@ -0,0 +1,127 @@
import os
import sys
# HARİÇ TUTULACAK KLASÖRLER
EXCLUDE_DIRS = {'crate_placeholders', '.git', 'target', 'node_modules', '__pycache__'}
# Düzeltilecek Kalıplar ve Yerine Geçecek Değerler
# Tekrar eden önekleri temizler.
REPLACEMENT_MAP = {
"pezpez": "pez",
"Pezpez": "Pez",
"PEZPEZ": "PEZ",
"PeZPeZ": "PeZ",
"pezPez": "pez",
"PEZpez": "PEZ",
}
def is_path_excluded(path):
"""Verilen yolun yasaklı bir klasörün içinde olup olmadığını kontrol eder."""
parts = path.split(os.sep)
return any(excluded in parts for excluded in EXCLUDE_DIRS)
def fix_double_prefix(text):
"""Metin içindeki çift PEZ öneklerini tek PEZ önekiyle değiştirir."""
for old_prefix, new_prefix in REPLACEMENT_MAP.items():
text = text.replace(old_prefix, new_prefix)
return text
def process_content_updates(root_dir):
"""Belirtilen dizin altındaki tüm hedef dosyaların içeriğini günceller."""
# Sadece .rs ve .toml gibi kod dosyalarını hedefleyelim.
TARGET_EXTENSIONS = ('.rs', '.toml', '.md', '.txt', '.yml', '.yaml', '.json', '.py')
print("--- Adım 1: Dosya İçeriklerinde Çift Önek Düzeltme ---")
for dirpath, dirnames, filenames in os.walk(root_dir, topdown=True):
dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS]
if is_path_excluded(dirpath):
continue
for filename in filenames:
if filename.endswith(TARGET_EXTENSIONS) or filename == 'Cargo.lock':
filepath = os.path.join(dirpath, filename)
if os.path.basename(filepath) == os.path.basename(sys.argv[0]):
continue
try:
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
original_content = content
content = fix_double_prefix(content)
if content != original_content:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
print(f" [İÇERİK DÜZELTİLDİ] Dosya içeriği: {filepath}")
except Exception as e:
print(f" [HATA] İçerik düzeltilirken: {filepath} -> {e}")
def rename_pezpez_paths(root_dir):
"""Dosya ve klasör adlarında geçen 'pezpez' önekini 'pez' olarak düzeltir (bottom-up)."""
# 2. Klasör İsimlerini Düzelt (topdown=False, en alttan yukarı güvenli işlem)
print("\n--- Adım 2: Klasör İsimlerinin Düzeltilmesi (pezpez -> pez) ---")
for dirpath, dirnames, filenames in os.walk(root_dir, topdown=False):
if any(excluded in dirpath.split(os.sep) for excluded in EXCLUDE_DIRS):
continue
dirname = os.path.basename(dirpath)
original_dirname = dirname
new_dirname = fix_double_prefix(dirname)
if new_dirname != original_dirname:
old_path = dirpath
new_path = os.path.join(os.path.dirname(dirpath), new_dirname)
if os.path.exists(old_path) and not os.path.exists(new_path):
try:
os.rename(old_path, new_path)
print(f" [RENAME-DIR] {original_dirname} -> {new_dirname}")
except OSError as e:
print(f" [HATA] Klasör adlandırılamadı {original_dirname}: {e}")
# 3. Dosya İsimlerini Düzelt (topdown=True, kökten aşağı)
print("\n--- Adım 3: Dosya İsimlerinin Düzeltilmesi (pezpez -> pez) ---")
for dirpath, dirnames, filenames in os.walk(root_dir, topdown=True):
dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS]
if is_path_excluded(dirpath):
continue
for filename in filenames:
original_filename = filename
new_filename = fix_double_prefix(filename)
if new_filename != original_filename:
old_path = os.path.join(dirpath, original_filename)
new_path = os.path.join(dirpath, new_filename)
if os.path.exists(old_path) and not os.path.exists(new_path):
try:
os.rename(old_path, new_path)
print(f" [RENAME-FILE] {original_filename} -> {new_filename}")
except OSError as e:
print(f" [HATA] Dosya adlandırılamadı {original_filename}: {e}")
def main():
root_dir = os.getcwd()
print("==================================================")
print(f"🔧 PEZPEZ DÜZELTME (İçerik ve Ad) İşlemi Başlatılıyor...")
print(f"⚠️ Çalışma Dizini: {root_dir}")
print("==================================================")
# Önce içerikleri düzelt (dosya yolları değişmeden)
process_content_updates(root_dir)
# Ardından dosya ve klasör adlarını düzelt
rename_pezpez_paths(root_dir)
print("\n✅ PEZPEZ Düzeltme işlemi tamamlandı.")
if __name__ == "__main__":
main()
@@ -0,0 +1,96 @@
import os
import sys
# HARİÇ TUTULACAK KLASÖRLER
EXCLUDE_DIRS = {'crate_placeholders', '.git', 'target', 'node_modules', '__pycache__'}
# Yeniden adlandırma haritası (Basit: sadece 'pallet'in önüne 'pez' ekle)
RENAME_MAP = {
# Tireli (kebab-case) isimlendirmeler için
"pallet-": "pezpallet-",
# Alt çizgili (snake_case) isimlendirmeler için
"pallet_": "pezpallet_",
}
# Not: Bu betik, 'Pallet-' veya 'PALLET-' gibi büyük harf varyasyonlarını dosya sisteminde
# (çoğunlukla küçük harf veya tireli kullanılan) adreslemeyebilir, ancak en yaygın olanları hedefler.
def is_path_excluded(path):
"""Verilen yolun yasaklı bir klasörün içinde olup olmadığını kontrol eder."""
parts = path.split(os.sep)
return any(excluded in parts for excluded in EXCLUDE_DIRS)
def rename_paths(root_dir):
"""
Dosya ve klasör adlarında geçen 'pallet' önekini 'pezpallet' olarak değiştirir.
Bottom-up (en alttan yukarı) yaklaşımıyla klasör adlarını güvenli bir şekilde değiştirir.
"""
# Adım 1: Dosya İsimlerini Düzelt (topdown=True, kökten aşağı)
print("--- Adım 1: Dosya İsimlerinin Güncellenmesi (pallet -> pezpallet) ---")
for dirpath, dirnames, filenames in os.walk(root_dir, topdown=True):
# Yasaklı klasörleri atla
dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS]
if any(excluded in dirpath.split(os.sep) for excluded in EXCLUDE_DIRS):
continue
for filename in filenames:
original_filename = filename
new_filename = filename
for old_prefix, new_prefix in RENAME_MAP.items():
if old_prefix in new_filename:
# Basit string değiştirme, pez yaratma riskini taşıyoruz.
new_filename = new_filename.replace(old_prefix, new_prefix)
if new_filename != original_filename:
old_path = os.path.join(dirpath, original_filename)
new_path = os.path.join(dirpath, new_filename)
if os.path.exists(old_path) and not os.path.exists(new_path):
try:
os.rename(old_path, new_path)
print(f" [RENAME-FILE] {original_filename} -> {new_filename}")
except OSError as e:
print(f" [HATA] Dosya adlandırılamadı {original_filename}: {e}")
# Adım 2: Klasör İsimlerini Düzelt (topdown=False, en alttan yukarı güvenli işlem)
print("\n--- Adım 2: Klasör İsimlerinin Güncellenmesi (pallet -> pezpallet) ---")
for dirpath, dirnames, filenames in os.walk(root_dir, topdown=False):
if any(excluded in dirpath.split(os.sep) for excluded in EXCLUDE_DIRS):
continue
dirname = os.path.basename(dirpath)
original_dirname = dirname
new_dirname = dirname
for old_prefix, new_prefix in RENAME_MAP.items():
if old_prefix in new_dirname:
new_dirname = new_dirname.replace(old_prefix, new_prefix)
if new_dirname != original_dirname:
old_path = dirpath
new_path = os.path.join(os.path.dirname(dirpath), new_dirname)
if os.path.exists(old_path) and not os.path.exists(new_path):
try:
os.rename(old_path, new_path)
print(f" [RENAME-DIR] {original_dirname} -> {new_dirname}")
except OSError as e:
print(f" [HATA] Klasör adlandırılamadı {original_dirname}: {e}")
def main():
root_dir = os.getcwd()
print("==================================================")
print(f"🗂️ Dosya Adı Düzeltme İşlemi Başlatılıyor (pallet -> pezpallet)...")
print(f"⚠️ Çalışma Dizini: {root_dir}")
print("==================================================")
rename_paths(root_dir)
print("\n✅ Dosya Adları Düzeltme işlemi tamamlandı.")
if __name__ == "__main__":
main()
+320
View File
@@ -0,0 +1,320 @@
#!/usr/bin/env python3
"""
crates.io İsim Rezervasyon Script'i (Gelişmiş Versiyon)
Özellikler:
- Kaldığı yerden devam etme (--start-from)
- Ayarlanabilir bekleme süresi (--interval)
- Workspace izolasyonu (üst dizindeki Cargo.toml ile çakışmaz)
- "Already exists" durumunu akıllıca yönetir (bekleme yapmaz)
"""
import subprocess
import os
import sys
import json
import time
from pathlib import Path
import argparse
WORKSPACE_ROOT = Path(__file__).parent.resolve()
PLACEHOLDER_DIR = WORKSPACE_ROOT / "crate_placeholders"
# Yeni isim listesi
NEW_CRATE_NAMES = [
"asset-hub-pezkuwichain-emulated-chain",
"asset-hub-pezkuwichain-integration-tests",
"asset-hub-pezkuwichain-runtime",
"asset-hub-zagros-emulated-chain",
"asset-hub-zagros-integration-tests",
"asset-hub-zagros-runtime",
"asset-test-pezutils",
"pez-binary-merkle-tree",
"pez-chain-spec-guide-runtime",
"collectives-zagros-emulated-chain",
"collectives-zagros-integration-tests",
"collectives-zagros-runtime",
"coretime-pezkuwichain-emulated-chain",
"coretime-pezkuwichain-integration-tests",
"coretime-pezkuwichain-runtime",
"coretime-zagros-emulated-chain",
"coretime-zagros-integration-tests",
"coretime-zagros-runtime",
"emulated-integration-tests-common",
"pez-equivocation-detector",
"pez-erasure-coding-fuzzer",
"pez-ethereum-standards",
"pez-finality-relay",
"pez-fork-tree",
"pezframe-election-solution-type-fuzzer",
"pezframe-omni-bencher",
"pezframe-remote-externalities",
"pezframe-storage-access-test-runtime",
"pez-generate-bags",
"glutton-zagros-runtime",
"governance-zagros-integration-tests",
"pez-kitchensink-runtime",
"pez-messages-relay",
"pez-minimal-template-node",
"pez-minimal-template-runtime",
"pez-node-bench",
"pez-node-primitives",
"pez-node-rpc",
"pez-node-runtime-pez-generate-bags",
"pez-node-template-release",
"pez-node-testing",
"pez-penpal-emulated-chain",
"pez-penpal-runtime",
"people-pezkuwichain-emulated-chain",
"people-pezkuwichain-integration-tests",
"people-pezkuwichain-runtime",
"people-zagros-emulated-chain",
"people-zagros-integration-tests",
"people-zagros-runtime",
"pezkuwi",
"pezkuwichain-emulated-chain",
"pezkuwichain-runtime",
"pezkuwichain-runtime-constants",
"pezkuwichain-system-emulated-network",
"pezkuwichain-teyrchain-runtime",
"pezkuwichain-zagros-system-emulated-network",
"relay-bizinikiwi-client",
"relay-pezutils",
"pez-remote-ext-tests-bags-list",
"pez-revive-dev-node",
"pez-revive-dev-runtime",
"pez-slot-range-helper",
"pez-solochain-template-node",
"pez-solochain-template-runtime",
"pez-pez_subkey",
"pez-template-zombienet-tests",
"peztest-runtime-constants",
"test-teyrchain-adder",
"test-teyrchain-adder-collator",
"test-teyrchain-halt",
"test-teyrchain-undying",
"test-teyrchain-undying-collator",
"testnet-teyrchains-constants",
"teyrchain-template",
"teyrchain-template-node",
"teyrchain-template-runtime",
"teyrchains-common",
"teyrchains-relay",
"teyrchains-runtimes-test-utils",
"pez-tracing-gum",
"pez-pez-tracing-gum-proc-macro",
"yet-another-teyrchain-runtime",
"zagros-emulated-chain",
"zagros-runtime",
"zagros-runtime-constants",
"zagros-system-emulated-network",
"pez-zombienet-backchannel",
"pezassets-common",
"bp-asset-hub-pezkuwichain",
"bp-asset-hub-zagros",
"bp-pezbeefy",
"bp-bridge-hub-pezcumulus",
"bp-bridge-hub-pezkuwichain",
"bp-bridge-hub-zagros",
"bp-header-pez-chain",
"bp-pez-messages",
"bp-pezkuwi-bulletin",
"bp-pezkuwi-core",
"bp-pezkuwichain",
"bp-pez-relayers",
"pezbp-runtime",
"bp-test-pezutils",
"bp-teyrchains",
"bp-xcm-pezbridge-hub",
"bp-xcm-pezbridge-hub-router",
"bp-zagros",
"pezbridge-hub-common",
"pezbridge-hub-pezkuwichain-emulated-chain",
"pezbridge-hub-pezkuwichain-integration-tests",
"pezbridge-hub-pezkuwichain-runtime",
"pezbridge-hub-test-utils",
"pezbridge-hub-zagros-emulated-chain",
"pezbridge-hub-zagros-integration-tests",
"pezbridge-hub-zagros-runtime",
"pezbridge-runtime-common",
"pezmmr-gadget",
"pezmmr-rpc",
"pezsnowbridge-beacon-primitives",
"pezsnowbridge-core",
"pezsnowbridge-ethereum",
"pezsnowbridge-inbound-queue-primitives",
"pezsnowbridge-merkle-tree",
"pezsnowbridge-outbound-queue-primitives",
"pezsnowbridge-outbound-queue-runtime-api",
"pezsnowbridge-outbound-queue-v2-runtime-api",
"pezsnowbridge-pezpallet-ethereum-client",
"pezsnowbridge-pezpallet-ethereum-client-fixtures",
"pezsnowbridge-pezpallet-inbound-queue",
"pezsnowbridge-pezpallet-inbound-queue-fixtures",
"pezsnowbridge-pezpallet-inbound-queue-v2",
"pezsnowbridge-pezpallet-inbound-queue-v2-fixtures",
"pezsnowbridge-pezpallet-outbound-queue",
"pezsnowbridge-pezpallet-outbound-queue-v2",
"pezsnowbridge-pezpallet-system",
"pezsnowbridge-pezpallet-system-frontend",
"pezsnowbridge-pezpallet-system-v2",
"pezsnowpezbridge-runtime-common",
"pezsnowbridge-runtime-test-common",
"pezsnowbridge-system-runtime-api",
"pezsnowbridge-system-v2-runtime-api",
"pezsnowbridge-test-utils",
"pezsnowbridge-verification-primitives",
"xcm-pez-docs",
"xcm-pez-emulator",
"xcm-pez-executor-integration-tests",
"xcm-pez-procedural",
"xcm-runtime-pezapis",
"xcm-pez-simulator",
"xcm-pez-simulator-example",
"xcm-pez-simulator-fuzzer",
]
def check_crate_available(name: str) -> bool:
"""crates.io'da isim müsait mi kontrol et"""
result = subprocess.run(
["cargo", "search", name, "--limit", "1"],
capture_output=True, text=True
)
return f'{name} = "' not in result.stdout
def create_placeholder(name: str) -> Path:
"""Placeholder crate oluştur"""
crate_dir = PLACEHOLDER_DIR / name
crate_dir.mkdir(parents=True, exist_ok=True)
# [workspace] ekleyerek parent workspace ile ilişkisini kesiyoruz
cargo_toml = f'''[package]
name = "{name}"
version = "0.1.0"
edition = "2021"
description = "PezkuwiChain SDK component - placeholder for name reservation"
license = "Apache-2.0"
repository = "https://github.com/pezkuwichain/pezkuwi-sdk"
homepage = "https://pezkuwichain.io"
documentation = "https://docs.pezkuwichain.io/sdk/"
authors = ["Kurdistan Tech Institute <info@pezkuwichain.io>"]
keywords = ["pezkuwichain", "blockchain", "sdk"]
categories = ["cryptography::cryptocurrencies"]
[workspace]
[dependencies]
'''
(crate_dir / "Cargo.toml").write_text(cargo_toml)
src_dir = crate_dir / "src"
src_dir.mkdir(exist_ok=True)
lib_rs = f'''//! {name}
//! This crate is part of the PezkuwiChain SDK.
//! Full implementation coming soon.
#![doc = include_str!("../README.md")]
'''
(src_dir / "lib.rs").write_text(lib_rs)
readme = f'''# {name}
Part of [PezkuwiChain SDK](https://github.com/pezkuwichain/pezkuwi-sdk).
## About
This crate is a component of the PezkuwiChain blockchain SDK.
'''
(crate_dir / "README.md").write_text(readme)
return crate_dir
def publish_placeholder(crate_dir: Path, dry_run: bool = True):
"""Placeholder'ı crates.io'ya publish et.
Dönüş: (başarılı_mı, bekleme_gerekli_mi)
"""
args = ["cargo", "publish"]
if dry_run:
args.append("--dry-run")
args.extend(["--manifest-path", str(crate_dir / "Cargo.toml")])
result = subprocess.run(args, capture_output=True, text=True, cwd=crate_dir)
if result.returncode == 0:
return True, True # Başarılı, bekleme yap
# "already exists" hatasını kontrol et
if "already exists" in result.stderr:
return True, False # Zaten var, bekleme yapma
print(f"\n[HATA] {crate_dir.name} publish edilemedi:\n{result.stderr}")
return False, False
def main():
parser = argparse.ArgumentParser(description="crates.io isim rezervasyonu")
parser.add_argument("--list", action="store_true", help="İsimleri listele")
parser.add_argument("--check", action="store_true", help="crates.io'da müsaitlik kontrol et")
parser.add_argument("--create", action="store_true", help="Placeholder crate'leri oluştur")
parser.add_argument("--publish", action="store_true", help="crates.io'ya publish et")
parser.add_argument("--dry-run", action="store_true", help="Publish dry-run")
parser.add_argument("--start-from", type=str, help="İşleme bu crate isminden başla (öncekileri atlar)")
parser.add_argument("--interval", type=int, default=360, help="Publish arası bekleme süresi (saniye). Varsayılan: 360")
args = parser.parse_args()
if args.list:
for name in sorted(NEW_CRATE_NAMES):
print(f" {name}")
return
# Create/Publish işlemleri
if args.create or args.publish:
# Placeholder klasörünü oluştur
PLACEHOLDER_DIR.mkdir(exist_ok=True)
start_processing = False
if not args.start_from:
start_processing = True
print(f"Toplam Crate Sayısı: {len(NEW_CRATE_NAMES)}")
print(f"Bekleme Süresi: {args.interval} saniye")
if args.start_from:
print(f"Başlangıç: {args.start_from} (Öncekiler atlanacak)")
success = 0
failed = 0
skipped = 0
for i, name in enumerate(NEW_CRATE_NAMES, 1):
# Resume mantığı
if not start_processing:
if name == args.start_from:
start_processing = True
else:
skipped += 1
continue
print(f"[{i}/{len(NEW_CRATE_NAMES)}] {name}...", end=" ", flush=True)
# 1. Create
crate_dir = create_placeholder(name)
# 2. Publish (Eğer istenmişse)
if args.publish:
success_status, needs_wait = publish_placeholder(crate_dir, args.dry_run)
if success_status:
if needs_wait:
print("✓ PUBLISHED")
success += 1
if not args.dry_run:
print(f" -> Bekleniyor {args.interval}sn...")
time.sleep(args.interval)
else:
print("✓ ZATEN VAR (Atlandı)")
success += 1
else:
print("✗ FAILED")
failed += 1
else:
print("✓ CREATED")
print(f"\nSonuç: {success} başarılı, {failed} başarısız, {skipped} atlandı.")
if __name__ == "__main__":
main()
+192
View File
@@ -0,0 +1,192 @@
#!/usr/bin/env python3
"""
Eski (rebrand edilmemiş) kelimeleri tarayan script.
Her crate için çalıştırılır ve kalan eski kelimeleri tespit eder.
Kullanım:
python3 scan_old_words.py <crate_path>
python3 scan_old_words.py /home/mamostehp/kurdistan-sdk/bizinikiwi/primitives/core
"""
import os
import sys
import re
from pathlib import Path
# Rebrand kuralları: (eski_pattern, yeni_kelime, açıklama)
# Sıralama önemli - daha spesifik olanlar önce
REBRAND_RULES = [
# Terminoloji
(r'\bparachain\b', 'teyrchain', 'parachain → teyrchain'),
(r'\bParachain\b', 'Teyrchain', 'Parachain → Teyrchain'),
(r'\bPARACHAIN\b', 'TEYRCHAIN', 'PARACHAIN → TEYRCHAIN'),
(r'\brococo\b', 'pezkuwichain', 'rococo → pezkuwichain'),
(r'\bRococo\b', 'Pezkuwichain', 'Rococo → Pezkuwichain'),
(r'\bROCOCO\b', 'PEZKUWICHAIN', 'ROCOCO → PEZKUWICHAIN'),
(r'\bwestend\b', 'zagros', 'westend → zagros'),
(r'\bWestend\b', 'Zagros', 'Westend → Zagros'),
(r'\bWESTEND\b', 'ZAGROS', 'WESTEND → ZAGROS'),
(r'\bkusama\b', 'zagros', 'kusama → zagros'),
(r'\bKusama\b', 'Zagros', 'Kusama → Zagros'),
(r'\bKUSAMA\b', 'ZAGROS', 'KUSAMA → ZAGROS'),
# Crate prefix'leri (Cargo.toml name ve use statement'larda)
# Dikkat: Bunlar sadece crate isimlerinde geçerli, rastgele "sp_" değil
(r'\bsp-core\b', 'pezsp-core', 'sp-core → pezsp-core'),
(r'\bsp-runtime\b', 'pezsp-runtime', 'sp-runtime → pezsp-runtime'),
(r'\bsp-io\b', 'pezsp-io', 'sp-io → pezsp-io'),
(r'\bsp-std\b', 'pezsp-std', 'sp-std → pezsp-std'),
(r'\bsp-api\b', 'pezsp-api', 'sp-api → pezsp-api'),
(r'\bsc-client\b', 'pezsc-client', 'sc-client → pezsc-client'),
(r'\bsc-service\b', 'pezsc-service', 'sc-service → pezsc-service'),
(r'\bframe-support\b', 'pezframe-support', 'frame-support → pezframe-support'),
(r'\bframe-system\b', 'pezframe-system', 'frame-system → pezframe-system'),
(r'\bpallet-balances\b', 'pezpallet-balances', 'pallet-balances → pezpallet-balances'),
(r'\bcumulus-client\b', 'pezcumulus-client', 'cumulus-client → pezcumulus-client'),
(r'\bcumulus-primitives\b', 'pezcumulus-primitives', 'cumulus-primitives → pezcumulus-primitives'),
# Snowbridge (pezsnowbridge-pezpallet önce, sonra genel snowbridge)
(r'\bsnowbridge-pezpallet-', 'pezsnowbridge-pezpallet-', 'snowbridge-pezpallet- → pezsnowbridge-pezpallet-'),
(r'\bsnowbridge-pallet-', 'pezsnowbridge-pezpallet-', 'snowbridge-pallet- → pezsnowbridge-pezpallet-'),
(r'\bsnowbridge-', 'pezsnowbridge-', 'snowbridge- → pezsnowbridge-'),
(r'\bsnowbridge_pallet_', 'pezsnowbridge_pezpallet_', 'snowbridge_pallet_ → pezsnowbridge_pezpallet_'),
(r'\bsnowbridge_pezpallet_', 'pezsnowbridge_pezpallet_', 'snowbridge_pezpallet_ → pezsnowbridge_pezpallet_'),
# Bridge
(r'\bbridge-hub-rococo\b', 'pezbridge-hub-pezkuwichain', 'bridge-hub-rococo → pezbridge-hub-pezkuwichain'),
(r'\bbridge-hub-westend\b', 'pezbridge-hub-zagros', 'bridge-hub-westend → pezbridge-hub-zagros'),
(r'\bbridge-runtime-common\b', 'pezbridge-runtime-common', 'bridge-runtime-common → pezbridge-runtime-common'),
# MMR
(r'\bmmr-gadget\b', 'pezmmr-gadget', 'mmr-gadget → pezmmr-gadget'),
(r'\bmmr-rpc\b', 'pezmmr-rpc', 'mmr-rpc → pezmmr-rpc'),
# Substrate (dikkatli - sadece proje referanslarında)
(r'\bsubstrate-wasm-builder\b', 'bizinikiwi-wasm-builder', 'substrate-wasm-builder → bizinikiwi-wasm-builder'),
(r'\bsubstrate-build-script-utils\b', 'bizinikiwi-build-script-utils', 'substrate-build-script-utils → bizinikiwi-build-script-utils'),
# Polkadot referansları
(r'\bpolkadot-sdk\b', 'pezkuwi-sdk', 'polkadot-sdk → pezkuwi-sdk'),
(r'\bpolkadot-runtime\b', 'pezkuwichain-runtime', 'polkadot-runtime → pezkuwichain-runtime'),
(r'\bpolkadot-primitives\b', 'pezkuwi-primitives', 'polkadot-primitives → pezkuwi-primitives'),
# Rust module isimleri (underscore versiyonları)
(r'\bsp_core\b', 'pezsp_core', 'sp_core → pezsp_core'),
(r'\bsp_runtime\b', 'pezsp_runtime', 'sp_runtime → pezsp_runtime'),
(r'\bsp_io\b', 'pezsp_io', 'sp_io → pezsp_io'),
(r'\bsc_client\b', 'pezsc_client', 'sc_client → pezsc_client'),
(r'\bframe_support\b', 'pezframe_support', 'frame_support → pezframe_support'),
(r'\bframe_system\b', 'pezframe_system', 'frame_system → pezframe_system'),
(r'\bpallet_balances\b', 'pezpallet_balances', 'pallet_balances → pezpallet_balances'),
(r'\bcumulus_client\b', 'pezcumulus_client', 'cumulus_client → pezcumulus_client'),
(r'\bcumulus_primitives\b', 'pezcumulus_primitives', 'cumulus_primitives → pezcumulus_primitives'),
]
# Taranacak dosya uzantıları
SCAN_EXTENSIONS = {'.rs', '.toml', '.md', '.json', '.yaml', '.yml'}
# Atlanacak dizinler
SKIP_DIRS = {'target', '.git', 'node_modules', 'crate_placeholders'}
def scan_file(file_path: Path) -> list:
"""Tek bir dosyayı tarar ve bulunan eski kelimeleri döndürür."""
findings = []
try:
content = file_path.read_text(encoding='utf-8', errors='ignore')
except Exception as e:
return [(str(file_path), 0, f"OKUMA HATASI: {e}", "", "")]
lines = content.split('\n')
for line_num, line in enumerate(lines, 1):
for pattern, replacement, description in REBRAND_RULES:
matches = re.finditer(pattern, line)
for match in matches:
findings.append({
'file': str(file_path),
'line': line_num,
'column': match.start() + 1,
'found': match.group(),
'replacement': replacement,
'description': description,
'context': line.strip()[:100]
})
return findings
def scan_crate(crate_path: str) -> list:
"""Bir crate dizinini tarar."""
crate_dir = Path(crate_path)
if not crate_dir.exists():
print(f"HATA: Dizin bulunamadı: {crate_path}")
return []
all_findings = []
for root, dirs, files in os.walk(crate_dir):
# Skip directories
dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
for file in files:
file_path = Path(root) / file
if file_path.suffix not in SCAN_EXTENSIONS:
continue
findings = scan_file(file_path)
all_findings.extend(findings)
return all_findings
def print_report(findings: list, crate_path: str):
"""Bulunan eski kelimelerin raporunu yazdırır."""
print(f"\n{'='*60}")
print(f"TARAMA RAPORU: {crate_path}")
print(f"{'='*60}\n")
if not findings:
print("✅ ESKİ KELİME BULUNAMADI - Crate temiz!")
return
print(f"{len(findings)} adet eski kelime bulundu:\n")
# Dosyaya göre grupla
by_file = {}
for f in findings:
if f['file'] not in by_file:
by_file[f['file']] = []
by_file[f['file']].append(f)
for file_path, file_findings in sorted(by_file.items()):
rel_path = file_path.replace(crate_path, '.')
print(f"\n📄 {rel_path}")
print(f" {'-'*50}")
for finding in file_findings:
print(f" Satır {finding['line']}: {finding['found']}{finding['replacement']}")
print(f" Bağlam: {finding['context']}")
print()
def main():
if len(sys.argv) < 2:
print("Kullanım: python3 scan_old_words.py <crate_path>")
print("Örnek: python3 scan_old_words.py ./bizinikiwi/primitives/core")
sys.exit(1)
crate_path = sys.argv[1]
findings = scan_crate(crate_path)
print_report(findings, crate_path)
# Çıkış kodu: bulgu varsa 1, yoksa 0
sys.exit(1 if findings else 0)
if __name__ == "__main__":
main()
+246 -137
View File
@@ -8,7 +8,8 @@ authors.workspace = true
edition.workspace = true
# This crate is not publish-able to crates.io for now because of docify.
publish = false
version = "0.0.1"
version = "0.0.2"
documentation.workspace = true
[lints]
workspace = true
@@ -16,14 +17,14 @@ workspace = true
[dependencies]
# Needed for all FRAME-based code
codec = { workspace = true }
frame = { features = [
pezframe = { features = [
"experimental",
"runtime",
], workspace = true, default-features = true }
pallet-contracts = { workspace = true }
pallet-default-config-example = { workspace = true, default-features = true }
pallet-example-offchain-worker = { workspace = true, default-features = true }
pallet-examples = { workspace = true }
pezpallet-contracts = { workspace = true }
pezpallet-default-config-example = { workspace = true, default-features = true }
pezpallet-example-offchain-worker = { workspace = true, default-features = true }
pezpallet-examples = { workspace = true }
scale-info = { workspace = true }
# How we build docs in rust-docs
@@ -33,98 +34,98 @@ simple-mermaid = { workspace = true }
# Pezkuwi SDK deps, typically all should only be in scope such that we can link to their doc item.
chain-spec-builder = { workspace = true, default-features = true }
frame-benchmarking = { workspace = true }
frame-executive = { workspace = true }
frame-metadata-hash-extension = { workspace = true, default-features = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
kitchensink-runtime = { workspace = true }
log = { workspace = true, default-features = true }
node-cli = { workspace = true }
pallet-example-authorization-tx-extension = { workspace = true, default-features = true }
pallet-example-single-block-migrations = { workspace = true, default-features = true }
pez-kitchensink-runtime = { workspace = true }
pez-subkey = { workspace = true, default-features = true }
pezframe-benchmarking = { workspace = true }
pezframe-executive = { workspace = true }
pezframe-metadata-hash-extension = { workspace = true, default-features = true }
pezframe-support = { workspace = true }
pezframe-system = { workspace = true }
pezkuwi-sdk = { features = [
"runtime-full",
], workspace = true, default-features = true }
subkey = { workspace = true, default-features = true }
pezpallet-example-authorization-tx-extension = { workspace = true, default-features = true }
pezpallet-example-single-block-migrations = { workspace = true, default-features = true }
# Substrate Client
sc-chain-spec = { workspace = true, default-features = true }
sc-cli = { workspace = true, default-features = true }
sc-client-db = { workspace = true, default-features = true }
sc-consensus-aura = { workspace = true, default-features = true }
sc-consensus-babe = { workspace = true, default-features = true }
sc-consensus-beefy = { workspace = true, default-features = true }
sc-consensus-grandpa = { workspace = true, default-features = true }
sc-consensus-manual-seal = { workspace = true, default-features = true }
sc-consensus-pow = { workspace = true, default-features = true }
sc-executor = { workspace = true, default-features = true }
sc-network = { workspace = true, default-features = true }
sc-rpc = { workspace = true, default-features = true }
sc-rpc-api = { workspace = true, default-features = true }
sc-service = { workspace = true, default-features = true }
# Bizinikiwi Client
pezsc-chain-spec = { workspace = true, default-features = true }
pezsc-cli = { workspace = true, default-features = true }
pezsc-client-db = { workspace = true, default-features = true }
pezsc-consensus-aura = { workspace = true, default-features = true }
pezsc-consensus-babe = { workspace = true, default-features = true }
pezsc-consensus-beefy = { workspace = true, default-features = true }
pezsc-consensus-grandpa = { workspace = true, default-features = true }
pezsc-consensus-manual-seal = { workspace = true, default-features = true }
pezsc-consensus-pow = { workspace = true, default-features = true }
pezsc-executor = { workspace = true, default-features = true }
pezsc-network = { workspace = true, default-features = true }
pezsc-rpc = { workspace = true, default-features = true }
pezsc-rpc-api = { workspace = true, default-features = true }
pezsc-service = { workspace = true, default-features = true }
substrate-wasm-builder = { workspace = true, default-features = true }
bizinikiwi-wasm-builder = { workspace = true, default-features = true }
# Cumulus
cumulus-client-service = { workspace = true, default-features = true }
cumulus-pallet-aura-ext = { workspace = true, default-features = true }
cumulus-pallet-teyrchain-system = { workspace = true, default-features = true }
cumulus-pallet-weight-reclaim = { workspace = true, default-features = true }
cumulus-primitives-proof-size-hostfunction = { workspace = true, default-features = true }
# Pezcumulus
pezcumulus-client-service = { workspace = true, default-features = true }
pezcumulus-pezpallet-aura-ext = { workspace = true, default-features = true }
pezcumulus-pezpallet-teyrchain-system = { workspace = true, default-features = true }
pezcumulus-pezpallet-weight-reclaim = { workspace = true, default-features = true }
pezcumulus-primitives-proof-size-hostfunction = { workspace = true, default-features = true }
teyrchain-info = { workspace = true, default-features = true }
# Omni Node
pezkuwi-omni-node-lib = { workspace = true, default-features = true }
# Pallets and FRAME internals
pallet-asset-conversion-tx-payment = { workspace = true, default-features = true }
pallet-asset-tx-payment = { workspace = true, default-features = true }
pallet-assets = { workspace = true, default-features = true }
pallet-aura = { workspace = true, default-features = true }
pallet-babe = { workspace = true, default-features = true }
pallet-balances = { workspace = true, default-features = true }
pallet-collective = { workspace = true, default-features = true }
pallet-democracy = { workspace = true, default-features = true }
pallet-grandpa = { workspace = true, default-features = true }
pallet-nfts = { workspace = true, default-features = true }
pallet-preimage = { workspace = true, default-features = true }
pallet-scheduler = { workspace = true, default-features = true }
pallet-skip-feeless-payment = { workspace = true, default-features = true }
pallet-timestamp = { workspace = true, default-features = true }
pallet-transaction-payment = { workspace = true, default-features = true }
pallet-uniques = { workspace = true, default-features = true }
pezpallet-asset-conversion-tx-payment = { workspace = true, default-features = true }
pezpallet-asset-tx-payment = { workspace = true, default-features = true }
pezpallet-assets = { workspace = true, default-features = true }
pezpallet-aura = { workspace = true, default-features = true }
pezpallet-babe = { workspace = true, default-features = true }
pezpallet-balances = { workspace = true, default-features = true }
pezpallet-collective = { workspace = true, default-features = true }
pezpallet-democracy = { workspace = true, default-features = true }
pezpallet-grandpa = { workspace = true, default-features = true }
pezpallet-nfts = { workspace = true, default-features = true }
pezpallet-preimage = { workspace = true, default-features = true }
pezpallet-scheduler = { workspace = true, default-features = true }
pezpallet-skip-feeless-payment = { workspace = true, default-features = true }
pezpallet-timestamp = { workspace = true, default-features = true }
pezpallet-transaction-payment = { workspace = true, default-features = true }
pezpallet-uniques = { workspace = true, default-features = true }
# Primitives
sp-api = { workspace = true, default-features = true }
sp-arithmetic = { workspace = true, default-features = true }
sp-core = { workspace = true, default-features = true }
sp-genesis-builder = { workspace = true, default-features = true }
sp-io = { workspace = true, default-features = true }
sp-keyring = { workspace = true, default-features = true }
sp-offchain = { workspace = true, default-features = true }
sp-runtime = { workspace = true, default-features = true }
sp-runtime-interface = { workspace = true, default-features = true }
sp-std = { workspace = true, default-features = true }
sp-storage = { workspace = true, default-features = true }
sp-tracing = { workspace = true, default-features = true }
sp-version = { workspace = true, default-features = true }
sp-weights = { workspace = true, default-features = true }
pezsp-api = { workspace = true, default-features = true }
pezsp-arithmetic = { workspace = true, default-features = true }
pezsp-core = { workspace = true, default-features = true }
pezsp-genesis-builder = { workspace = true, default-features = true }
pezsp-io = { workspace = true, default-features = true }
pezsp-keyring = { workspace = true, default-features = true }
pezsp-offchain = { workspace = true, default-features = true }
pezsp-runtime = { workspace = true, default-features = true }
pezsp-runtime-interface = { workspace = true, default-features = true }
pezsp-std = { workspace = true, default-features = true }
pezsp-storage = { workspace = true, default-features = true }
pezsp-tracing = { workspace = true, default-features = true }
pezsp-version = { workspace = true, default-features = true }
pezsp-weights = { workspace = true, default-features = true }
# XCM
pallet-xcm = { workspace = true }
pezpallet-xcm = { workspace = true }
xcm = { workspace = true, default-features = true }
xcm-builder = { workspace = true }
xcm-docs = { workspace = true }
xcm-executor = { workspace = true }
xcm-simulator = { workspace = true }
xcm-pez-docs = { workspace = true }
xcm-pez-simulator = { workspace = true }
# Runtime guides
chain-spec-guide-runtime = { workspace = true, default-features = true }
pez-chain-spec-guide-runtime = { workspace = true, default-features = true }
# Templates
minimal-template-runtime = { workspace = true, default-features = true }
solochain-template-runtime = { workspace = true, default-features = true }
pez-minimal-template-runtime = { workspace = true, default-features = true }
pez-solochain-template-runtime = { workspace = true, default-features = true }
# local packages
first-runtime = { workspace = true, default-features = true }
@@ -137,77 +138,185 @@ tokio = { workspace = true }
[features]
runtime-benchmarks = [
"bizinikiwi-wasm-builder/runtime-benchmarks",
"chain-spec-builder/runtime-benchmarks",
"chain-spec-guide-runtime/runtime-benchmarks",
"cumulus-client-service/runtime-benchmarks",
"cumulus-pallet-aura-ext/runtime-benchmarks",
"cumulus-pallet-teyrchain-system/runtime-benchmarks",
"cumulus-pallet-weight-reclaim/runtime-benchmarks",
"cumulus-primitives-proof-size-hostfunction/runtime-benchmarks",
"first-runtime/runtime-benchmarks",
"frame-benchmarking/runtime-benchmarks",
"frame-executive/runtime-benchmarks",
"frame-metadata-hash-extension/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"frame/runtime-benchmarks",
"kitchensink-runtime/runtime-benchmarks",
"minimal-template-runtime/runtime-benchmarks",
"node-cli/runtime-benchmarks",
"pallet-asset-conversion-tx-payment/runtime-benchmarks",
"pallet-asset-tx-payment/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-aura/runtime-benchmarks",
"pallet-babe/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-collective/runtime-benchmarks",
"pallet-contracts/runtime-benchmarks",
"pallet-default-config-example/runtime-benchmarks",
"pallet-democracy/runtime-benchmarks",
"pallet-example-authorization-tx-extension/runtime-benchmarks",
"pallet-example-offchain-worker/runtime-benchmarks",
"pallet-example-single-block-migrations/runtime-benchmarks",
"pallet-examples/runtime-benchmarks",
"pallet-grandpa/runtime-benchmarks",
"pallet-nfts/runtime-benchmarks",
"pallet-preimage/runtime-benchmarks",
"pallet-scheduler/runtime-benchmarks",
"pallet-skip-feeless-payment/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"pallet-transaction-payment/runtime-benchmarks",
"pallet-uniques/runtime-benchmarks",
"pallet-xcm/runtime-benchmarks",
"pez-chain-spec-guide-runtime/runtime-benchmarks",
"pez-kitchensink-runtime/runtime-benchmarks",
"pez-minimal-template-runtime/runtime-benchmarks",
"pez-solochain-template-runtime/runtime-benchmarks",
"pez-subkey/runtime-benchmarks",
"pezcumulus-client-service/runtime-benchmarks",
"pezcumulus-pezpallet-aura-ext/runtime-benchmarks",
"pezcumulus-pezpallet-teyrchain-system/runtime-benchmarks",
"pezcumulus-pezpallet-weight-reclaim/runtime-benchmarks",
"pezcumulus-primitives-proof-size-hostfunction/runtime-benchmarks",
"pezframe-benchmarking/runtime-benchmarks",
"pezframe-executive/runtime-benchmarks",
"pezframe-metadata-hash-extension/runtime-benchmarks",
"pezframe-support/runtime-benchmarks",
"pezframe-system/runtime-benchmarks",
"pezframe/runtime-benchmarks",
"pezkuwi-omni-node-lib/runtime-benchmarks",
"pezkuwi-sdk/runtime-benchmarks",
"sc-chain-spec/runtime-benchmarks",
"sc-cli/runtime-benchmarks",
"sc-client-db/runtime-benchmarks",
"sc-consensus-aura/runtime-benchmarks",
"sc-consensus-babe/runtime-benchmarks",
"sc-consensus-beefy/runtime-benchmarks",
"sc-consensus-grandpa/runtime-benchmarks",
"sc-consensus-manual-seal/runtime-benchmarks",
"sc-consensus-pow/runtime-benchmarks",
"sc-executor/runtime-benchmarks",
"sc-network/runtime-benchmarks",
"sc-rpc-api/runtime-benchmarks",
"sc-rpc/runtime-benchmarks",
"sc-service/runtime-benchmarks",
"solochain-template-runtime/runtime-benchmarks",
"sp-api/runtime-benchmarks",
"sp-genesis-builder/runtime-benchmarks",
"sp-io/runtime-benchmarks",
"sp-keyring/runtime-benchmarks",
"sp-offchain/runtime-benchmarks",
"sp-runtime-interface/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"sp-version/runtime-benchmarks",
"subkey/runtime-benchmarks",
"substrate-wasm-builder/runtime-benchmarks",
"pezpallet-asset-conversion-tx-payment/runtime-benchmarks",
"pezpallet-asset-tx-payment/runtime-benchmarks",
"pezpallet-assets/runtime-benchmarks",
"pezpallet-aura/runtime-benchmarks",
"pezpallet-babe/runtime-benchmarks",
"pezpallet-balances/runtime-benchmarks",
"pezpallet-collective/runtime-benchmarks",
"pezpallet-contracts/runtime-benchmarks",
"pezpallet-default-config-example/runtime-benchmarks",
"pezpallet-democracy/runtime-benchmarks",
"pezpallet-example-authorization-tx-extension/runtime-benchmarks",
"pezpallet-example-offchain-worker/runtime-benchmarks",
"pezpallet-example-single-block-migrations/runtime-benchmarks",
"pezpallet-examples/runtime-benchmarks",
"pezpallet-grandpa/runtime-benchmarks",
"pezpallet-nfts/runtime-benchmarks",
"pezpallet-preimage/runtime-benchmarks",
"pezpallet-scheduler/runtime-benchmarks",
"pezpallet-skip-feeless-payment/runtime-benchmarks",
"pezpallet-timestamp/runtime-benchmarks",
"pezpallet-transaction-payment/runtime-benchmarks",
"pezpallet-uniques/runtime-benchmarks",
"pezpallet-xcm/runtime-benchmarks",
"pezsc-chain-spec/runtime-benchmarks",
"pezsc-cli/runtime-benchmarks",
"pezsc-client-db/runtime-benchmarks",
"pezsc-consensus-aura/runtime-benchmarks",
"pezsc-consensus-babe/runtime-benchmarks",
"pezsc-consensus-beefy/runtime-benchmarks",
"pezsc-consensus-grandpa/runtime-benchmarks",
"pezsc-consensus-manual-seal/runtime-benchmarks",
"pezsc-consensus-pow/runtime-benchmarks",
"pezsc-executor/runtime-benchmarks",
"pezsc-network/runtime-benchmarks",
"pezsc-rpc-api/runtime-benchmarks",
"pezsc-rpc/runtime-benchmarks",
"pezsc-service/runtime-benchmarks",
"pezsp-api/runtime-benchmarks",
"pezsp-genesis-builder/runtime-benchmarks",
"pezsp-io/runtime-benchmarks",
"pezsp-keyring/runtime-benchmarks",
"pezsp-offchain/runtime-benchmarks",
"pezsp-runtime-interface/runtime-benchmarks",
"pezsp-runtime/runtime-benchmarks",
"pezsp-version/runtime-benchmarks",
"teyrchain-info/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-docs/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
"xcm-simulator/runtime-benchmarks",
"xcm-pez-docs/runtime-benchmarks",
"xcm-pez-simulator/runtime-benchmarks",
"xcm/runtime-benchmarks",
]
std = [
"bizinikiwi-wasm-builder/std",
"chain-spec-builder/std",
"codec/std",
"log/std",
"node-cli/std",
"pez-subkey/std",
"pezcumulus-client-service/std",
"pezframe-benchmarking/std",
"pezframe-executive/std",
"pezframe-support/std",
"pezframe-system/std",
"pezkuwi-omni-node-lib/std",
"pezpallet-contracts/std",
"pezpallet-xcm/std",
"pezsc-chain-spec/std",
"pezsc-cli/std",
"pezsc-client-db/std",
"pezsc-consensus-aura/std",
"pezsc-consensus-babe/std",
"pezsc-consensus-beefy/std",
"pezsc-consensus-grandpa/std",
"pezsc-consensus-manual-seal/std",
"pezsc-consensus-pow/std",
"pezsc-network/std",
"pezsc-rpc-api/std",
"pezsc-rpc/std",
"pezsc-service/std",
"scale-info/std",
"serde_json/std",
"xcm-builder/std",
"xcm-executor/std",
"xcm-pez-docs/std",
"xcm-pez-simulator/std",
]
try-runtime = [
"first-runtime/try-runtime",
"node-cli/try-runtime",
"pez-chain-spec-guide-runtime/try-runtime",
"pez-kitchensink-runtime/try-runtime",
"pez-minimal-template-runtime/try-runtime",
"pez-solochain-template-runtime/try-runtime",
"pezcumulus-client-service/try-runtime",
"pezcumulus-pezpallet-aura-ext/try-runtime",
"pezcumulus-pezpallet-teyrchain-system/try-runtime",
"pezcumulus-pezpallet-weight-reclaim/try-runtime",
"pezframe-benchmarking/try-runtime",
"pezframe-executive/try-runtime",
"pezframe-metadata-hash-extension/try-runtime",
"pezframe-support/try-runtime",
"pezframe-system/try-runtime",
"pezframe/try-runtime",
"pezkuwi-omni-node-lib/try-runtime",
"pezkuwi-sdk/try-runtime",
"pezpallet-asset-conversion-tx-payment/try-runtime",
"pezpallet-asset-tx-payment/try-runtime",
"pezpallet-assets/try-runtime",
"pezpallet-aura/try-runtime",
"pezpallet-babe/try-runtime",
"pezpallet-balances/try-runtime",
"pezpallet-collective/try-runtime",
"pezpallet-contracts/try-runtime",
"pezpallet-default-config-example/try-runtime",
"pezpallet-democracy/try-runtime",
"pezpallet-example-authorization-tx-extension/try-runtime",
"pezpallet-example-offchain-worker/try-runtime",
"pezpallet-example-single-block-migrations/try-runtime",
"pezpallet-examples/try-runtime",
"pezpallet-grandpa/try-runtime",
"pezpallet-nfts/try-runtime",
"pezpallet-preimage/try-runtime",
"pezpallet-scheduler/try-runtime",
"pezpallet-skip-feeless-payment/try-runtime",
"pezpallet-timestamp/try-runtime",
"pezpallet-transaction-payment/try-runtime",
"pezpallet-uniques/try-runtime",
"pezpallet-xcm/try-runtime",
"pezsc-chain-spec/try-runtime",
"pezsc-cli/try-runtime",
"pezsc-client-db/try-runtime",
"pezsc-consensus-aura/try-runtime",
"pezsc-consensus-babe/try-runtime",
"pezsc-consensus-beefy/try-runtime",
"pezsc-consensus-grandpa/try-runtime",
"pezsc-consensus-manual-seal/try-runtime",
"pezsc-consensus-pow/try-runtime",
"pezsc-executor/try-runtime",
"pezsc-network/try-runtime",
"pezsc-rpc-api/try-runtime",
"pezsc-rpc/try-runtime",
"pezsc-service/try-runtime",
"pezsp-api/try-runtime",
"pezsp-genesis-builder/try-runtime",
"pezsp-keyring/try-runtime",
"pezsp-offchain/try-runtime",
"pezsp-runtime/try-runtime",
"pezsp-version/try-runtime",
"teyrchain-info/try-runtime",
"xcm-builder/try-runtime",
"xcm-executor/try-runtime",
"xcm-pez-docs/try-runtime",
"xcm-pez-simulator/try-runtime",
"xcm/try-runtime",
]
serde = []
experimental = []
with-tracing = []
tuples-96 = []
@@ -1,27 +0,0 @@
[package]
name = "pezkuwi-sdk-docs-first-pallet"
description = "A simple pallet created for the pezkuwi-sdk-docs guides"
version = "0.0.0"
license = "MIT-0"
authors.workspace = true
homepage.workspace = true
repository.workspace = true
edition.workspace = true
publish = false
[lints]
workspace = true
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { workspace = true }
docify = { workspace = true }
frame = { workspace = true, features = ["runtime"] }
scale-info = { workspace = true }
[features]
default = ["std"]
std = ["codec/std", "frame/std", "scale-info/std"]
runtime-benchmarks = ["frame/runtime-benchmarks"]
@@ -0,0 +1,48 @@
[package]
name = "pezkuwi-sdk-docs-first-pezpallet"
description = "A simple pezpallet created for the pezkuwi-sdk-docs guides"
version = "0.0.0"
license = "MIT-0"
authors.workspace = true
homepage.workspace = true
repository.workspace = true
edition.workspace = true
publish = false
documentation.workspace = true
[lints]
workspace = true
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { workspace = true }
docify = { workspace = true }
pezframe = { workspace = true, features = ["runtime"] }
pezframe-support = { workspace = true }
pezframe-system = { workspace = true }
scale-info = { workspace = true }
[features]
default = ["std"]
std = [
"codec/std",
"pezframe-support/std",
"pezframe-system/std",
"pezframe/std",
"scale-info/std",
]
runtime-benchmarks = [
"pezframe-support/runtime-benchmarks",
"pezframe-system/runtime-benchmarks",
"pezframe/runtime-benchmarks",
]
try-runtime = [
"pezframe-support/try-runtime",
"pezframe-system/try-runtime",
"pezframe/try-runtime",
]
serde = []
experimental = []
tuples-96 = []
@@ -1,6 +1,6 @@
// This file is part of Substrate.
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,43 +20,43 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[docify::export]
#[frame::pallet(dev_mode)]
#[pezframe::pezpallet(dev_mode)]
pub mod shell_pallet {
use frame::prelude::*;
use pezframe::prelude::*;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
}
#[frame::pallet(dev_mode)]
pub mod pallet {
use frame::prelude::*;
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet {
use pezframe::prelude::*;
#[docify::export]
pub type Balance = u128;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[docify::export]
/// Single storage item, of type `Balance`.
#[pallet::storage]
#[pezpallet::storage]
pub type TotalIssuance<T: Config> = StorageValue<_, Balance>;
#[docify::export]
/// A mapping from `T::AccountId` to `Balance`
#[pallet::storage]
#[pezpallet::storage]
pub type Balances<T: Config> = StorageMap<_, _, T::AccountId, Balance>;
#[docify::export(impl_pallet)]
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
/// An unsafe mint that can be called by anyone. Not a great idea.
pub fn mint_unsafe(
origin: T::RuntimeOrigin,
@@ -98,7 +98,7 @@ pub mod pallet {
}
#[allow(unused)]
impl<T: Config> Pallet<T> {
impl<T: Config> Pezpallet<T> {
#[docify::export]
pub fn transfer_better(
origin: T::RuntimeOrigin,
@@ -134,10 +134,10 @@ pub mod pallet {
#[cfg(any(test, doc))]
pub(crate) mod tests {
use crate::pallet::*;
use crate::pezpallet::*;
#[docify::export(testing_prelude)]
use frame::testing_prelude::*;
use pezframe::testing_prelude::*;
pub(crate) const ALICE: u64 = 1;
pub(crate) const BOB: u64 = 2;
@@ -148,29 +148,29 @@ pub mod pallet {
// tests { .. }`
mod runtime {
use super::*;
// we need to reference our `mod pallet` as an identifier to pass to
// we need to reference our `mod pezpallet` as an identifier to pass to
// `construct_runtime`.
// YOU HAVE TO CHANGE THIS LINE BASED ON YOUR TEMPLATE
use crate::pallet as pallet_currency;
use crate::pezpallet as pezpallet_currency;
construct_runtime!(
pub enum Runtime {
// ---^^^^^^ This is where `enum Runtime` is defined.
System: frame_system,
Currency: pallet_currency,
System: pezframe_system,
Currency: pezpallet_currency,
}
);
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Runtime>;
// within pallet we just said `<T as frame_system::Config>::AccountId`, now we
// within pezpallet we just said `<T as pezframe_system::Config>::AccountId`, now we
// finally specified it.
type AccountId = u64;
}
// our simple pallet has nothing to be configured.
impl pallet_currency::Config for Runtime {}
// our simple pezpallet has nothing to be configured.
impl pezpallet_currency::Config for Runtime {}
}
pub(crate) use runtime::*;
@@ -192,7 +192,7 @@ pub mod pallet {
#[docify::export]
pub(crate) struct StateBuilder {
balances: Vec<(<Runtime as frame_system::Config>::AccountId, Balance)>,
balances: Vec<(<Runtime as pezframe_system::Config>::AccountId, Balance)>,
}
#[docify::export(default_state_builder)]
@@ -206,7 +206,7 @@ pub mod pallet {
impl StateBuilder {
fn add_balance(
mut self,
who: <Runtime as frame_system::Config>::AccountId,
who: <Runtime as pezframe_system::Config>::AccountId,
amount: Balance,
) -> Self {
self.balances.push((who, amount));
@@ -246,7 +246,7 @@ pub mod pallet {
assert_eq!(TotalIssuance::<Runtime>::get(), None);
// mint some funds into Alice's account.
assert_ok!(Pallet::<Runtime>::mint_unsafe(
assert_ok!(Pezpallet::<Runtime>::mint_unsafe(
RuntimeOrigin::signed(ALICE),
ALICE,
100
@@ -295,14 +295,18 @@ pub mod pallet {
fn mint_works() {
StateBuilder::default().build_and_execute(|| {
// given the initial state, when:
assert_ok!(Pallet::<Runtime>::mint_unsafe(RuntimeOrigin::signed(ALICE), BOB, 100));
assert_ok!(Pezpallet::<Runtime>::mint_unsafe(
RuntimeOrigin::signed(ALICE),
BOB,
100
));
// then:
assert_eq!(Balances::<Runtime>::get(&BOB), Some(200));
assert_eq!(TotalIssuance::<Runtime>::get(), Some(300));
// given:
assert_ok!(Pallet::<Runtime>::mint_unsafe(
assert_ok!(Pezpallet::<Runtime>::mint_unsafe(
RuntimeOrigin::signed(ALICE),
CHARLIE,
100
@@ -319,7 +323,7 @@ pub mod pallet {
fn transfer_works() {
StateBuilder::default().build_and_execute(|| {
// given the initial state, when:
assert_ok!(Pallet::<Runtime>::transfer(RuntimeOrigin::signed(ALICE), BOB, 50));
assert_ok!(Pezpallet::<Runtime>::transfer(RuntimeOrigin::signed(ALICE), BOB, 50));
// then:
assert_eq!(Balances::<Runtime>::get(&ALICE), Some(50));
@@ -327,7 +331,7 @@ pub mod pallet {
assert_eq!(TotalIssuance::<Runtime>::get(), Some(200));
// when:
assert_ok!(Pallet::<Runtime>::transfer(RuntimeOrigin::signed(BOB), ALICE, 50));
assert_ok!(Pezpallet::<Runtime>::transfer(RuntimeOrigin::signed(BOB), ALICE, 50));
// then:
assert_eq!(Balances::<Runtime>::get(&ALICE), Some(100));
@@ -342,7 +346,7 @@ pub mod pallet {
StateBuilder::default().build_and_execute(|| {
// given the initial state, when:
assert_err!(
Pallet::<Runtime>::transfer(RuntimeOrigin::signed(CHARLIE), ALICE, 10),
Pezpallet::<Runtime>::transfer(RuntimeOrigin::signed(CHARLIE), ALICE, 10),
"NonExistentAccount"
);
@@ -356,32 +360,32 @@ pub mod pallet {
}
}
#[frame::pallet(dev_mode)]
pub mod pallet_v2 {
use super::pallet::Balance;
use frame::prelude::*;
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet_v2 {
use super::pezpallet::Balance;
use pezframe::prelude::*;
#[docify::export(config_v2)]
#[pallet::config]
pub trait Config: frame_system::Config {
#[pezpallet::config]
pub trait Config: pezframe_system::Config {
/// The overarching event type of the runtime.
#[allow(deprecated)]
type RuntimeEvent: From<Event<Self>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>
+ IsType<<Self as pezframe_system::Config>::RuntimeEvent>
+ TryInto<Event<Self>>;
}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[pallet::storage]
#[pezpallet::storage]
pub type Balances<T: Config> = StorageMap<_, _, T::AccountId, Balance>;
#[pallet::storage]
#[pezpallet::storage]
pub type TotalIssuance<T: Config> = StorageValue<_, Balance>;
#[docify::export]
#[pallet::error]
#[pezpallet::error]
pub enum Error<T> {
/// Account does not exist.
NonExistentAccount,
@@ -390,15 +394,15 @@ pub mod pallet_v2 {
}
#[docify::export]
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
#[pezpallet::event]
#[pezpallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// A transfer succeeded.
Transferred { from: T::AccountId, to: T::AccountId, amount: Balance },
}
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
#[docify::export(transfer_v2)]
pub fn transfer(
origin: T::RuntimeOrigin,
@@ -424,30 +428,30 @@ pub mod pallet_v2 {
#[cfg(any(test, doc))]
pub mod tests {
use super::{super::pallet::tests::StateBuilder, *};
use frame::testing_prelude::*;
use super::{super::pezpallet::tests::StateBuilder, *};
use pezframe::testing_prelude::*;
const ALICE: u64 = 1;
const BOB: u64 = 2;
#[docify::export]
pub mod runtime_v2 {
use super::*;
use crate::pallet_v2 as pallet_currency;
use crate::pezpallet_v2 as pezpallet_currency;
construct_runtime!(
pub enum Runtime {
System: frame_system,
Currency: pallet_currency,
System: pezframe_system,
Currency: pezpallet_currency,
}
);
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Runtime>;
type AccountId = u64;
}
impl pallet_currency::Config for Runtime {
impl pezpallet_currency::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}
}
@@ -463,7 +467,7 @@ pub mod pallet_v2 {
System::set_block_number(ALICE);
// given the initial state, when:
assert_ok!(Pallet::<Runtime>::transfer(RuntimeOrigin::signed(ALICE), BOB, 50));
assert_ok!(Pezpallet::<Runtime>::transfer(RuntimeOrigin::signed(ALICE), BOB, 50));
// then:
assert_eq!(Balances::<Runtime>::get(&ALICE), Some(50));
@@ -8,6 +8,7 @@ homepage.workspace = true
repository.workspace = true
edition.workspace = true
publish = false
documentation.workspace = true
[lints]
workspace = true
@@ -18,54 +19,105 @@ scale-info = { workspace = true }
serde_json = { workspace = true }
# this is a frame-based runtime, thus importing `frame` with runtime feature enabled.
frame = { workspace = true, features = ["runtime"] }
pezframe = { workspace = true, features = ["runtime"] }
pezframe-support = { workspace = true }
pezframe-system = { workspace = true }
# pallets that we want to use
pallet-balances = { workspace = true }
pallet-sudo = { workspace = true }
pallet-timestamp = { workspace = true }
pallet-transaction-payment = { workspace = true }
pallet-transaction-payment-rpc-runtime-api = { workspace = true }
pezpallet-balances = { workspace = true }
pezpallet-sudo = { workspace = true }
pezpallet-timestamp = { workspace = true }
pezpallet-transaction-payment = { workspace = true }
pezpallet-transaction-payment-rpc-runtime-api = { workspace = true }
# other pezkuwi-sdk-deps
sp-keyring = { workspace = true }
pezframe-system-rpc-runtime-api = { workspace = true }
pezsp-api = { workspace = true }
pezsp-block-builder = { workspace = true }
pezsp-core = { workspace = true }
pezsp-genesis-builder = { workspace = true }
pezsp-keyring = { workspace = true }
pezsp-offchain = { workspace = true }
pezsp-runtime = { workspace = true }
pezsp-session = { workspace = true }
pezsp-transaction-pool = { workspace = true }
# local pallet templates
first-pallet = { workspace = true }
# local pezpallet templates
first-pezpallet = { workspace = true }
docify = { workspace = true }
[build-dependencies]
substrate-wasm-builder = { workspace = true, optional = true }
bizinikiwi-wasm-builder = { workspace = true, optional = true }
[features]
default = ["std"]
std = [
"bizinikiwi-wasm-builder",
"bizinikiwi-wasm-builder?/std",
"codec/std",
"first-pezpallet/std",
"pezframe-support/std",
"pezframe-system-rpc-runtime-api/std",
"pezframe-system/std",
"pezframe/std",
"pezpallet-balances/std",
"pezpallet-sudo/std",
"pezpallet-timestamp/std",
"pezpallet-transaction-payment-rpc-runtime-api/std",
"pezpallet-transaction-payment/std",
"pezsp-api/std",
"pezsp-block-builder/std",
"pezsp-core/std",
"pezsp-genesis-builder/std",
"pezsp-keyring/std",
"pezsp-offchain/std",
"pezsp-runtime/std",
"pezsp-session/std",
"pezsp-transaction-pool/std",
"scale-info/std",
"serde_json/std",
"frame/std",
"pallet-balances/std",
"pallet-sudo/std",
"pallet-timestamp/std",
"pallet-transaction-payment-rpc-runtime-api/std",
"pallet-transaction-payment/std",
"first-pallet/std",
"sp-keyring/std",
"substrate-wasm-builder",
]
runtime-benchmarks = [
"first-pallet/runtime-benchmarks",
"frame/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-sudo/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"pallet-transaction-payment-rpc-runtime-api/runtime-benchmarks",
"pallet-transaction-payment/runtime-benchmarks",
"sp-keyring/runtime-benchmarks",
"substrate-wasm-builder?/runtime-benchmarks",
"bizinikiwi-wasm-builder?/runtime-benchmarks",
"first-pezpallet/runtime-benchmarks",
"pezframe-support/runtime-benchmarks",
"pezframe-system-rpc-runtime-api/runtime-benchmarks",
"pezframe-system/runtime-benchmarks",
"pezframe/runtime-benchmarks",
"pezpallet-balances/runtime-benchmarks",
"pezpallet-sudo/runtime-benchmarks",
"pezpallet-timestamp/runtime-benchmarks",
"pezpallet-transaction-payment-rpc-runtime-api/runtime-benchmarks",
"pezpallet-transaction-payment/runtime-benchmarks",
"pezsp-api/runtime-benchmarks",
"pezsp-block-builder/runtime-benchmarks",
"pezsp-genesis-builder/runtime-benchmarks",
"pezsp-keyring/runtime-benchmarks",
"pezsp-offchain/runtime-benchmarks",
"pezsp-runtime/runtime-benchmarks",
"pezsp-session/runtime-benchmarks",
"pezsp-transaction-pool/runtime-benchmarks",
]
try-runtime = [
"first-pezpallet/try-runtime",
"pezframe-support/try-runtime",
"pezframe-system/try-runtime",
"pezframe/try-runtime",
"pezpallet-balances/try-runtime",
"pezpallet-sudo/try-runtime",
"pezpallet-timestamp/try-runtime",
"pezpallet-transaction-payment-rpc-runtime-api/try-runtime",
"pezpallet-transaction-payment/try-runtime",
"pezsp-api/try-runtime",
"pezsp-block-builder/try-runtime",
"pezsp-genesis-builder/try-runtime",
"pezsp-keyring/try-runtime",
"pezsp-offchain/try-runtime",
"pezsp-runtime/try-runtime",
"pezsp-session/try-runtime",
"pezsp-transaction-pool/try-runtime",
]
serde = []
experimental = []
tuples-96 = []
@@ -1,6 +1,6 @@
// This file is part of Substrate.
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +18,7 @@
fn main() {
#[cfg(feature = "std")]
{
substrate_wasm_builder::WasmBuilder::new()
bizinikiwi_wasm_builder::WasmBuilder::new()
.with_current_project()
.export_heap_base()
.import_memory()
@@ -1,6 +1,6 @@
// This file is part of Substrate.
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,12 +21,15 @@
extern crate alloc;
use alloc::{vec, vec::Vec};
use first_pallet::pallet_v2 as our_first_pallet;
use frame::{
prelude::*,
runtime::{apis, prelude::*},
use first_pezpallet::pezpallet_v2 as our_first_pallet;
use pezframe::{deps::pezsp_genesis_builder::DEV_RUNTIME_PRESET, prelude::*, runtime::prelude::*};
use pezpallet_transaction_payment_rpc_runtime_api::{FeeDetails, RuntimeDispatchInfo};
use pezsp_keyring::Sr25519Keyring;
use pezsp_runtime::{
traits::Block as BlockT,
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult,
};
use pallet_transaction_payment_rpc_runtime_api::{FeeDetails, RuntimeDispatchInfo};
#[docify::export]
#[runtime_version]
@@ -45,15 +48,15 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
construct_runtime!(
pub struct Runtime {
// Mandatory for all runtimes
System: frame_system,
System: pezframe_system,
// A number of other pallets from FRAME.
Timestamp: pallet_timestamp,
Balances: pallet_balances,
Sudo: pallet_sudo,
TransactionPayment: pallet_transaction_payment,
Timestamp: pezpallet_timestamp,
Balances: pezpallet_balances,
Sudo: pezpallet_sudo,
TransactionPayment: pezpallet_transaction_payment,
// Our local pallet
// Our local pezpallet
FirstPallet: our_first_pallet,
}
);
@@ -62,19 +65,19 @@ construct_runtime!(
mod runtime_types {
use super::*;
pub(super) type SignedExtra = (
// `frame` already provides all the signed extensions from `frame-system`. We just add the
// one related to tx-payment here.
frame::runtime::types_common::SystemTransactionExtensionsOf<Runtime>,
pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
// `frame` already provides all the signed extensions from `pezframe-system`. We just add
// the one related to tx-payment here.
pezframe::runtime::types_common::SystemTransactionExtensionsOf<Runtime>,
pezpallet_transaction_payment::ChargeTransactionPayment<Runtime>,
);
pub(super) type Block = frame::runtime::types_common::BlockOf<Runtime, SignedExtra>;
pub(super) type Header = HeaderFor<Runtime>;
pub(super) type Block = pezframe::runtime::types_common::BlockOf<Runtime, SignedExtra>;
pub(super) type _Header = HeaderFor<Runtime>;
pub(super) type RuntimeExecutive = Executive<
Runtime,
Block,
frame_system::ChainContext<Runtime>,
pezframe_system::ChainContext<Runtime>,
Runtime,
AllPalletsWithSystem,
>;
@@ -89,32 +92,32 @@ mod config_impls {
pub const Version: RuntimeVersion = VERSION;
}
#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
impl frame_system::Config for Runtime {
#[derive_impl(pezframe_system::config_preludes::SolochainDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = Block;
type Version = Version;
type AccountData =
pallet_balances::AccountData<<Runtime as pallet_balances::Config>::Balance>;
pezpallet_balances::AccountData<<Runtime as pezpallet_balances::Config>::Balance>;
}
#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
impl pallet_balances::Config for Runtime {
#[derive_impl(pezpallet_balances::config_preludes::TestDefaultConfig)]
impl pezpallet_balances::Config for Runtime {
type AccountStore = System;
}
#[derive_impl(pallet_sudo::config_preludes::TestDefaultConfig)]
impl pallet_sudo::Config for Runtime {}
#[derive_impl(pezpallet_sudo::config_preludes::TestDefaultConfig)]
impl pezpallet_sudo::Config for Runtime {}
#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)]
impl pallet_timestamp::Config for Runtime {}
#[derive_impl(pezpallet_timestamp::config_preludes::TestDefaultConfig)]
impl pezpallet_timestamp::Config for Runtime {}
#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig)]
impl pallet_transaction_payment::Config for Runtime {
type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter<Balances, ()>;
#[derive_impl(pezpallet_transaction_payment::config_preludes::TestDefaultConfig)]
impl pezpallet_transaction_payment::Config for Runtime {
type OnChargeTransaction = pezpallet_transaction_payment::FungibleAdapter<Balances, ()>;
// We specify a fixed length to fee here, which essentially means all transactions charge
// exactly 1 unit of fee.
type LengthToFee = FixedFee<1, <Self as pallet_balances::Config>::Balance>;
type WeightToFee = NoFee<<Self as pallet_balances::Config>::Balance>;
type LengthToFee = FixedFee<1, <Self as pezpallet_balances::Config>::Balance>;
type WeightToFee = NoFee<<Self as pezpallet_balances::Config>::Balance>;
}
}
@@ -130,7 +133,7 @@ pub mod genesis_config_presets {
interface::{Balance, MinimumBalance},
BalancesConfig, RuntimeGenesisConfig, SudoConfig,
};
use frame::deps::frame_support::build_struct_json_patch;
use pezframe::deps::pezframe_support::build_struct_json_patch;
use serde_json::Value;
/// Returns a development genesis config preset.
@@ -169,21 +172,21 @@ pub mod genesis_config_presets {
}
impl_runtime_apis! {
impl apis::Core<Block> for Runtime {
impl pezsp_api::Core<Block> for Runtime {
fn version() -> RuntimeVersion {
VERSION
}
fn execute_block(block: <Block as frame::traits::Block>::LazyBlock) {
fn execute_block(block: <Block as BlockT>::LazyBlock) {
RuntimeExecutive::execute_block(block)
}
fn initialize_block(header: &Header) -> ExtrinsicInclusionMode {
fn initialize_block(header: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode {
RuntimeExecutive::initialize_block(header)
}
}
impl apis::Metadata<Block> for Runtime {
impl pezsp_api::Metadata<Block> for Runtime {
fn metadata() -> OpaqueMetadata {
OpaqueMetadata::new(Runtime::metadata().into())
}
@@ -197,62 +200,62 @@ impl_runtime_apis! {
}
}
impl apis::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(extrinsic: ExtrinsicFor<Runtime>) -> ApplyExtrinsicResult {
impl pezsp_block_builder::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
RuntimeExecutive::apply_extrinsic(extrinsic)
}
fn finalize_block() -> HeaderFor<Runtime> {
fn finalize_block() -> <Block as BlockT>::Header {
RuntimeExecutive::finalize_block()
}
fn inherent_extrinsics(data: InherentData) -> Vec<ExtrinsicFor<Runtime>> {
fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
data.create_extrinsics()
}
fn check_inherents(
block: <Block as frame::traits::Block>::LazyBlock,
block: <Block as BlockT>::LazyBlock,
data: InherentData,
) -> CheckInherentsResult {
data.check_extrinsics(&block)
}
}
impl apis::TaggedTransactionQueue<Block> for Runtime {
impl pezsp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(
source: TransactionSource,
tx: ExtrinsicFor<Runtime>,
block_hash: <Runtime as frame_system::Config>::Hash,
tx: <Block as BlockT>::Extrinsic,
block_hash: <Block as BlockT>::Hash,
) -> TransactionValidity {
RuntimeExecutive::validate_transaction(source, tx, block_hash)
}
}
impl apis::OffchainWorkerApi<Block> for Runtime {
fn offchain_worker(header: &HeaderFor<Runtime>) {
impl pezsp_offchain::OffchainWorkerApi<Block> for Runtime {
fn offchain_worker(header: &<Block as BlockT>::Header) {
RuntimeExecutive::offchain_worker(header)
}
}
impl apis::SessionKeys<Block> for Runtime {
impl pezsp_session::SessionKeys<Block> for Runtime {
fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
Default::default()
}
fn decode_session_keys(
_encoded: Vec<u8>,
) -> Option<Vec<(Vec<u8>, apis::KeyTypeId)>> {
) -> Option<Vec<(Vec<u8>, pezsp_core::crypto::KeyTypeId)>> {
Default::default()
}
}
impl apis::AccountNonceApi<Block, interface::AccountId, interface::Nonce> for Runtime {
impl pezframe_system_rpc_runtime_api::AccountNonceApi<Block, interface::AccountId, interface::Nonce> for Runtime {
fn account_nonce(account: interface::AccountId) -> interface::Nonce {
System::account_nonce(account)
}
}
impl apis::GenesisBuilder<Block> for Runtime {
impl pezsp_genesis_builder::GenesisBuilder<Block> for Runtime {
fn build_state(config: Vec<u8>) -> GenesisBuilderResult {
build_state::<RuntimeGenesisConfig>(config)
}
@@ -266,14 +269,14 @@ impl_runtime_apis! {
}
}
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
impl pezpallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
Block,
interface::Balance,
> for Runtime {
fn query_info(uxt: ExtrinsicFor<Runtime>, len: u32) -> RuntimeDispatchInfo<interface::Balance> {
fn query_info(uxt: <Block as BlockT>::Extrinsic, len: u32) -> RuntimeDispatchInfo<interface::Balance> {
TransactionPayment::query_info(uxt, len)
}
fn query_fee_details(uxt: ExtrinsicFor<Runtime>, len: u32) -> FeeDetails<interface::Balance> {
fn query_fee_details(uxt: <Block as BlockT>::Extrinsic, len: u32) -> FeeDetails<interface::Balance> {
TransactionPayment::query_fee_details(uxt, len)
}
fn query_weight_to_fee(weight: Weight) -> interface::Balance {
@@ -285,15 +288,15 @@ impl_runtime_apis! {
}
}
/// Just a handy re-definition of some types based on what is already provided to the pallet
/// Just a handy re-definition of some types based on what is already provided to the pezpallet
/// configs.
pub mod interface {
use super::Runtime;
use frame::prelude::frame_system;
use pezframe::prelude::pezframe_system;
pub type AccountId = <Runtime as frame_system::Config>::AccountId;
pub type Nonce = <Runtime as frame_system::Config>::Nonce;
pub type Hash = <Runtime as frame_system::Config>::Hash;
pub type Balance = <Runtime as pallet_balances::Config>::Balance;
pub type MinimumBalance = <Runtime as pallet_balances::Config>::ExistentialDeposit;
pub type AccountId = <Runtime as pezframe_system::Config>::AccountId;
pub type Nonce = <Runtime as pezframe_system::Config>::Nonce;
pub type Hash = <Runtime as pezframe_system::Config>::Hash;
pub type Balance = <Runtime as pezpallet_balances::Config>::Balance;
pub type MinimumBalance = <Runtime as pezpallet_balances::Config>::ExistentialDeposit;
}
@@ -8,7 +8,7 @@
//! by opening a pull request to the `pezkuwi-sdk` repository.
//!
//! - [Pezkuwi NFT Marketplace Tutorial by Pezkuwi Fellow Shawn Tabrizi](https://www.shawntabrizi.com/substrate-collectables-workshop/)
//! - [HEZ Code School](https://dotcodeschool.com/)
//! - [HEZ Code School](https://pezkuwichain.io/docs/introduction)
//! - [Pezkuwi Developers Github Organization](https://github.com/polkadot-developers/)
//! - [Pezkuwi Blockchain Academy](https://github.com/pezkuwichain/kurdistan_blockchain-akademy)
//! - [Pezkuwi Wiki](https://wiki.network.pezkuwichain.io/)
@@ -1,6 +1,6 @@
//! # Upgrade Teyrchain for Asynchronous Backing Compatibility
//!
//! This guide is relevant for cumulus based teyrchain projects started in 2023 or before, whose
//! This guide is relevant for pezcumulus based teyrchain projects started in 2023 or before, whose
//! backing process is synchronous where parablocks can only be built on the latest Relay Chain
//! block. Async Backing allows collators to build parablocks on older Relay Chain blocks and create
//! pipelines of multiple pending parablocks. This parallel block generation increases efficiency
@@ -53,21 +53,21 @@
//! 3. Establish constants `MILLISECS_PER_BLOCK` and `SLOT_DURATION` if not already present in the
//! runtime.
//! ```ignore
//! // `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked
//! // up by `pallet_aura` to implement `fn slot_duration()`.
//! // `SLOT_DURATION` is picked up by `pezpallet_timestamp` which is in turn picked
//! // up by `pezpallet_aura` to implement `fn slot_duration()`.
//! //
//! // Change this to adjust the block time.
//! pub const MILLISECS_PER_BLOCK: u64 = 12000;
//! pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
//! ```
//!
//! 4. Configure `cumulus_pallet_teyrchain_system` in the runtime.
//! 4. Configure `pezcumulus_pezpallet_teyrchain_system` in the runtime.
//!
//! - Define a `FixedVelocityConsensusHook` using our capacity, velocity, and relay slot duration
//! constants. Use this to set the teyrchain system `ConsensusHook` property.
#![doc = docify::embed!("../../templates/teyrchain/runtime/src/lib.rs", ConsensusHook)]
//! ```ignore
//! impl cumulus_pallet_teyrchain_system::Config for Runtime {
//! impl pezcumulus_pezpallet_teyrchain_system::Config for Runtime {
//! ..
//! type ConsensusHook = ConsensusHook;
//! ..
@@ -76,21 +76,21 @@
//! - Set the teyrchain system property `CheckAssociatedRelayNumber` to
//! `RelayNumberMonotonicallyIncreases`
//! ```ignore
//! impl cumulus_pallet_teyrchain_system::Config for Runtime {
//! impl pezcumulus_pezpallet_teyrchain_system::Config for Runtime {
//! ..
//! type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases;
//! ..
//! }
//! ```
//!
//! 5. Configure `pallet_aura` in the runtime.
//! 5. Configure `pezpallet_aura` in the runtime.
//!
//! - Set `AllowMultipleBlocksPerSlot` to `false` (don't worry, we will set it to `true` when we
//! activate async backing in phase 3).
//!
//! - Define `pallet_aura::SlotDuration` using our constant `SLOT_DURATION`
//! - Define `pezpallet_aura::SlotDuration` using our constant `SLOT_DURATION`
//! ```ignore
//! impl pallet_aura::Config for Runtime {
//! impl pezpallet_aura::Config for Runtime {
//! ..
//! type AllowMultipleBlocksPerSlot = ConstBool<false>;
//! #[cfg(feature = "experimental")]
@@ -99,25 +99,25 @@
//! }
//! ```
//!
//! 6. Update `sp_consensus_aura::AuraApi::slot_duration` in `sp_api::impl_runtime_apis` to match
//! the constant `SLOT_DURATION`
//! 6. Update `pezsp_consensus_aura::AuraApi::slot_duration` in `pezsp_api::impl_runtime_apis` to
//! match the constant `SLOT_DURATION`
#![doc = docify::embed!("../../templates/teyrchain/runtime/src/apis.rs", impl_slot_duration)]
//!
//! 7. Implement the `AuraUnincludedSegmentApi`, which allows the collator client to query its
//! runtime to determine whether it should author a block.
//!
//! - Add the dependency `cumulus-primitives-aura` to the `runtime/Cargo.toml` file for your
//! - Add the dependency `pezcumulus-primitives-aura` to the `runtime/Cargo.toml` file for your
//! runtime
//! ```ignore
//! ..
//! cumulus-primitives-aura = { path = "../../../../primitives/aura", default-features = false }
//! pezcumulus-primitives-aura = { path = "../../../../primitives/aura", default-features = false }
//! ..
//! ```
//!
//! - In the same file, add `"cumulus-primitives-aura/std",` to the `std` feature.
//! - In the same file, add `"pezcumulus-primitives-aura/std",` to the `std` feature.
//!
//! - Inside the `impl_runtime_apis!` block for your runtime, implement the
//! `cumulus_primitives_aura::AuraUnincludedSegmentApi` as shown below.
//! `pezcumulus_primitives_aura::AuraUnincludedSegmentApi` as shown below.
#![doc = docify::embed!("../../templates/teyrchain/runtime/src/apis.rs", impl_can_build_upon)]
//!
//! **Note:** With a capacity of 1 we have an effective velocity of ½ even when velocity is
@@ -136,13 +136,13 @@
//!
//! This phase consists of plugging in the new lookahead collator node.
//!
//! 1. Import `cumulus_primitives_core::ValidationCode` to `node/src/service.rs`.
#![doc = docify::embed!("../../templates/teyrchain/node/src/service.rs", cumulus_primitives)]
//! 1. Import `pezcumulus_primitives_core::ValidationCode` to `node/src/service.rs`.
#![doc = docify::embed!("../../templates/teyrchain/node/src/service.rs", pezcumulus_primitives)]
//!
//! 2. In `node/src/service.rs`, modify `sc_service::spawn_tasks` to use a clone of `Backend` rather
//! than the original
//! 2. In `node/src/service.rs`, modify `pezsc_service::spawn_tasks` to use a clone of `Backend`
//! rather than the original
//! ```ignore
//! sc_service::spawn_tasks(sc_service::SpawnTasksParams {
//! pezsc_service::spawn_tasks(pezsc_service::SpawnTasksParams {
//! ..
//! backend: backend.clone(),
//! ..
@@ -197,7 +197,7 @@
//! 6. In `start_consensus()` replace `basic_aura::run` with `aura::run`
//! ```ignore
//! let fut =
//! aura::run::<Block, sp_consensus_aura::sr25519::AuthorityPair, _, _, _, _, _, _, _, _, _>(
//! aura::run::<Block, pezsp_consensus_aura::sr25519::AuthorityPair, _, _, _, _, _, _, _, _, _>(
//! params,
//! );
//! task_manager.spawn_essential_handle().spawn("aura", None, fut);
@@ -207,7 +207,7 @@
//!
//! This phase consists of changes to your teyrchains runtime that activate async backing feature.
//!
//! 1. Configure `pallet_aura`, setting `AllowMultipleBlocksPerSlot` to true in
//! 1. Configure `pezpallet_aura`, setting `AllowMultipleBlocksPerSlot` to true in
//! `runtime/src/lib.rs`.
#![doc = docify::embed!("../../templates/teyrchain/runtime/src/configs/mod.rs", aura_config)]
//!
@@ -224,11 +224,11 @@
//! 4. Update `MAXIMUM_BLOCK_WEIGHT` to reflect the increased time available for block production.
#![doc = docify::embed!("../../templates/teyrchain/runtime/src/lib.rs", max_block_weight)]
//!
//! 5. Add a feature flagged alternative for `MinimumPeriod` in `pallet_timestamp`. The type should
//! be `ConstU64<0>` with the feature flag experimental, and `ConstU64<{SLOT_DURATION / 2}>`
//! without.
//! 5. Add a feature flagged alternative for `MinimumPeriod` in `pezpallet_timestamp`. The type
//! should be `ConstU64<0>` with the feature flag experimental, and `ConstU64<{SLOT_DURATION /
//! 2}>` without.
//! ```ignore
//! impl pallet_timestamp::Config for Runtime {
//! impl pezpallet_timestamp::Config for Runtime {
//! ..
//! #[cfg(feature = "experimental")]
//! type MinimumPeriod = ConstU64<0>;
@@ -246,7 +246,7 @@
//! actual time not matching up, stalling the teyrchain.
//!
//! One strategy to deal with this issue is to instead rely on relay chain block numbers for timing.
//! Relay block number is kept track of by each teyrchain in `pallet-teyrchain-system` with the
//! Relay block number is kept track of by each teyrchain in `pezpallet-teyrchain-system` with the
//! storage value `LastRelayChainBlockNumber`. This value can be obtained and used wherever timing
//! based on block number is needed.
@@ -1 +0,0 @@
//! # Cumulus Enabled Teyrchain
@@ -66,7 +66,7 @@
//!
//! ### UMP signals
//!
//! UMP signals are now enabled by default in the `teyrchain-system` pallet and are used for
//! UMP signals are now enabled by default in the `teyrchain-system` pezpallet and are used for
//! elastic scaling. You can find more technical details about UMP signals and their usage for
//! elastic scaling
//! [here](https://github.com/polkadot-fellows/RFCs/blob/main/text/0103-introduce-core-index-commitment.md).
@@ -81,7 +81,7 @@
//! /// Build with an offset of 1 behind the relay chain best block.
//! const RELAY_PARENT_OFFSET: u32 = 1;
//!
//! impl cumulus_pallet_teyrchain_system::Config for Runtime {
//! impl pezcumulus_pezpallet_teyrchain_system::Config for Runtime {
//! // ...
//! type RelayParentOffset = ConstU32<RELAY_PARENT_OFFSET>;
//! }
@@ -89,7 +89,7 @@
//!
//! Implement the runtime API to retrieve the offset on the client side.
//! ```ignore
//! impl cumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
//! impl pezcumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
//! fn relay_parent_offset() -> u32 {
//! RELAY_PARENT_OFFSET
//! }
@@ -117,7 +117,7 @@
//! /// Relay chain slot duration, in milliseconds.
//! const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
//!
//! type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
//! type ConsensusHook = pezcumulus_pezpallet_aura_ext::FixedVelocityConsensusHook<
//! Runtime,
//! RELAY_CHAIN_SLOT_DURATION_MILLIS,
//! BLOCK_PROCESSING_VELOCITY,
@@ -129,9 +129,9 @@
//! ### Teyrchain Slot Duration
//!
//! A common source of confusion is the correct configuration of the `SlotDuration` that is passed
//! to `pallet-aura`.
//! to `pezpallet-aura`.
//! ```ignore
//! impl pallet_aura::Config for Runtime {
//! impl pezpallet_aura::Config for Runtime {
//! // ...
//! type SlotDuration = ConstU64<SLOT_DURATION>;
//! }
@@ -44,8 +44,8 @@
//! ### Runtime integration
//!
//! From the runtime side only the
//! [`CheckMetadataHash`](frame_metadata_hash_extension::CheckMetadataHash) needs to be added to the
//! list of signed extension:
//! [`CheckMetadataHash`](pezframe_metadata_hash_extension::CheckMetadataHash) needs to be added to
//! the list of signed extension:
#![doc = docify::embed!("../../templates/teyrchain/runtime/src/lib.rs", template_signed_extra)]
//!
//! > **Note:**
@@ -64,19 +64,20 @@
//!
//! The extension does not work with the native runtime, because the
//! `RUNTIME_METADATA_HASH` environment variable is not set when building the
//! `frame-metadata-hash-extension` crate.
//! `pezframe-metadata-hash-extension` crate.
//!
//! </div>
//!
//! ### Enable metadata hash generation
//!
//! The metadata hash generation needs to be enabled when building the wasm binary. The
//! `substrate-wasm-builder` supports this out of the box:
//! `bizinikiwi-wasm-builder` supports this out of the box:
#![doc = docify::embed!("../../templates/teyrchain/runtime/build.rs", template_enable_metadata_hash)]
//!
//! > **Note:**
//! >
//! > The `metadata-hash` feature needs to be enabled for the `substrate-wasm-builder` to enable the
//! > The `metadata-hash` feature needs to be enabled for the `bizinikiwi-wasm-builder` to enable
//! > the
//! > code for being able to generate the metadata hash. It is also recommended to put the metadata
//! > hash generation behind a feature in the runtime as shown above. The reason behind is that it
//! > adds a lot of code which increases the compile time and the generation itself also increases
@@ -2,8 +2,8 @@
//!
//! This guide will teach you how to enable storage weight reclaiming for a teyrchain. The
//! explanations in this guide assume a project structure similar to the one detailed in
//! the [substrate documentation](crate::pezkuwi_sdk::substrate#anatomy-of-a-binary-crate). Full
//! technical details are available in the original [pull request](https://github.com/paritytech/polkadot-sdk/pull/3002).
//! the [bizinikiwi documentation](crate::pezkuwi_sdk::bizinikiwi#anatomy-of-a-binary-crate). Full
//! technical details are available in the original [pull request](https://github.com/pezkuwichain/pezkuwi-sdk/issues/257).
//!
//! # What is PoV reclaim?
//! When a teyrchain submits a block to a relay chain like Pezkuwi or Kusama, it sends the block
@@ -12,7 +12,7 @@
//! validators distribute this PoV among themselves over the network. This distribution is costly
//! and limits the size of the storage proof. The storage weight dimension of FRAME weights reflects
//! this cost and limits the size of the storage proof. However, the storage weight determined
//! during [benchmarking](crate::reference_docs::frame_benchmarking_weight) represents the worst
//! during [benchmarking](crate::reference_docs::pezframe_benchmarking_weight) represents the worst
//! case. In reality, runtime operations often consume less space in the storage proof. PoV reclaim
//! offers a mechanism to reclaim the difference between the benchmarked worst-case and the real
//! proof-size consumption.
@@ -24,12 +24,12 @@
//! To reclaim excess storage weight, a teyrchain runtime needs the
//! ability to fetch the size of the storage proof from the node. The reclaim
//! mechanism uses the
//! [`storage_proof_size`](cumulus_primitives_proof_size_hostfunction::storage_proof_size)
//! host function for this purpose. For convenience, cumulus provides
//! [`TeyrchainHostFunctions`](cumulus_client_service::TeyrchainHostFunctions), a set of
//! host functions typically used by cumulus-based teyrchains. In the binary crate of your
//! teyrchain, find the instantiation of the [`WasmExecutor`](sc_executor::WasmExecutor) and set the
//! correct generic type.
//! [`storage_proof_size`](pezcumulus_primitives_proof_size_hostfunction::storage_proof_size)
//! host function for this purpose. For convenience, pezcumulus provides
//! [`TeyrchainHostFunctions`](pezcumulus_client_service::TeyrchainHostFunctions), a set of
//! host functions typically used by pezcumulus-based teyrchains. In the binary crate of your
//! teyrchain, find the instantiation of the [`WasmExecutor`](pezsc_executor::WasmExecutor) and set
//! the correct generic type.
//!
//! This example from the teyrchain-template shows a type definition that includes the correct
//! host functions.
@@ -46,9 +46,9 @@
//! The reclaim mechanism reads the size of the currently recorded storage proof multiple times
//! during block authoring and block import. Proof recording during authoring is already enabled on
//! teyrchains. You must also ensure that storage proof recording is enabled during block import.
//! Find where your node builds the fundamental substrate components by calling
//! [`new_full_parts`](sc_service::new_full_parts). Replace this
//! with [`new_full_parts_record_import`](sc_service::new_full_parts_record_import) and
//! Find where your node builds the fundamental bizinikiwi components by calling
//! [`new_full_parts`](pezsc_service::new_full_parts). Replace this
//! with [`new_full_parts_record_import`](pezsc_service::new_full_parts_record_import) and
//! pass `true` as the last parameter to enable import recording.
#![doc = docify::embed!("../../templates/teyrchain/node/src/service.rs", component_instantiation)]
//!
@@ -62,7 +62,7 @@
//!
//! In your runtime, you will find a list of TransactionExtensions.
//! To enable the reclaiming,
//! set [`StorageWeightReclaim`](cumulus_pallet_weight_reclaim::StorageWeightReclaim)
//! set [`StorageWeightReclaim`](pezcumulus_pezpallet_weight_reclaim::StorageWeightReclaim)
//! as a warpper of that list.
//! It is necessary that this extension wraps all the other transaction extensions in order to catch
//! the whole PoV size of the transactions.
@@ -28,10 +28,10 @@
//! latency and reduces throughput, affecting the overall performance of the teyrchain.
//!
//! # Building on Older Pelay Parents
//! Cumulus offers a way to mitigate the occurence of forks. Instead of picking a block at the tip
//! of the relay chain to build blocks, the node side can pick a relay chain block that is older. By
//! building on 12s old relay chain blocks, forks will already have settled and the teyrchain can
//! build fork-free.
//! Pezcumulus offers a way to mitigate the occurence of forks. Instead of picking a block at the
//! tip of the relay chain to build blocks, the node side can pick a relay chain block that is
//! older. By building on 12s old relay chain blocks, forks will already have settled and the
//! teyrchain can build fork-free.
//!
//! ```text
//! Without offset:
@@ -68,10 +68,10 @@
//! ```ignore
//! const RELAY_PARENT_OFFSET = 2;
//! ```
//! 2. Pass this constant to the `teyrchain-system` pallet.
//! 2. Pass this constant to the `teyrchain-system` pezpallet.
//!
//! ```ignore
//! impl cumulus_pallet_teyrchain_system::Config for Runtime {
//! impl pezcumulus_pezpallet_teyrchain_system::Config for Runtime {
//! // Other config items here
//! ...
//! type RelayParentOffset = ConstU32<RELAY_PARENT_OFFSET>;
@@ -80,7 +80,7 @@
//! 3. Implement the `RelayParentOffsetApi` runtime API for your runtime.
//!
//! ```ignore
//! impl cumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
//! impl pezcumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
//! fn relay_parent_offset() -> u32 {
//! RELAY_PARENT_OFFSET
//! }
+4 -4
View File
@@ -5,7 +5,7 @@
//!
//! The main user-journey covered by these guides is:
//!
//! * [`your_first_pallet`], where you learn what a FRAME pallet is, and write your first
//! * [`your_first_pallet`], where you learn what a FRAME pezpallet is, and write your first
//! application logic.
//! * [`your_first_runtime`], where you learn how to compile your pallets into a WASM runtime.
//! * [`your_first_node`], where you learn how to run the said runtime in a node.
@@ -20,17 +20,17 @@
//!
//! Other guides are related to other miscellaneous topics and are listed as modules below.
/// Write your first simple pallet, learning the most most basic features of FRAME along the way.
/// Write your first simple pezpallet, learning the most most basic features of FRAME along the way.
pub mod your_first_pallet;
/// Write your first real [runtime](`crate::reference_docs::wasm_meta_protocol`),
/// compiling it to [WASM](crate::pezkuwi_sdk::substrate#wasm-build).
/// compiling it to [WASM](crate::pezkuwi_sdk::bizinikiwi#wasm-build).
pub mod your_first_runtime;
/// Running the given runtime with a node. No specific consensus mechanism is used at this stage.
pub mod your_first_node;
/// How to enhance a given runtime and node to be cumulus-enabled, run it as a teyrchain
/// How to enhance a given runtime and node to be pezcumulus-enabled, run it as a teyrchain
/// and connect it to a relay-chain.
// pub mod your_first_teyrchain;
@@ -0,0 +1 @@
//! # Pezcumulus Enabled Teyrchain
@@ -6,7 +6,7 @@
//! other options when it comes to running a node.
//!
//! [`your_first_runtime`] is a runtime with no consensus related code, and therefore can only be
//! executed with a node that also expects no consensus ([`sc_consensus_manual_seal`]).
//! executed with a node that also expects no consensus ([`pezsc_consensus_manual_seal`]).
//! `pezkuwi-omni-node`'s [`--dev-block-time`] precisely does this.
//!
//! > All of the following steps are coded as unit tests of this module. Please see `Source` of the
@@ -28,7 +28,7 @@
//! described in [`crate::guides::your_first_runtime#genesis-configuration`].
//!
//! ```text
//! cargo install staging-chain-spec-builder
//! cargo install pezstaging-chain-spec-builder
//! ```
//!
//! > The name of the crate is prefixed with `staging` as the crate name `chain-spec-builder` on
@@ -49,7 +49,7 @@
//! ### Building Chain Spec
//!
//! Next, we can generate the corresponding chain-spec file. For this example, we will use the
//! `development` (`sp_genesis_config::DEVELOPMENT`) preset.
//! `development` (`pezsp_genesis_config::DEVELOPMENT`) preset.
//!
//! Note that we intend to run this chain-spec with `pezkuwi-omni-node`, which is tailored for
//! running teyrchains. This requires the chain-spec to always contain the `para_id` and a
@@ -82,7 +82,7 @@
//!
//! > Note that we always prefer to use `--tmp` for testing, as it will save the chain state to a
//! > temporary folder, allowing the chain-to be easily restarted without `purge-chain`. See
//! > [`sc_cli::commands::PurgeChainCmd`] and [`sc_cli::commands::RunCmd::tmp`] for more info.
//! > [`pezsc_cli::commands::PurgeChainCmd`] and [`pezsc_cli::commands::RunCmd::tmp`] for more info.
//!
//! This will start the node and import the blocks. Note while using `--dev-block-time`, the node
//! will use the testing-specific manual-seal consensus. This is an efficient way to test the
@@ -103,9 +103,9 @@
mod tests {
use assert_cmd::assert::OutputAssertExt;
use cmd_lib::*;
use pezsc_chain_spec::{DEV_RUNTIME_PRESET, LOCAL_TESTNET_RUNTIME_PRESET};
use pezsp_genesis_builder::PresetId;
use rand::Rng;
use sc_chain_spec::{DEV_RUNTIME_PRESET, LOCAL_TESTNET_RUNTIME_PRESET};
use sp_genesis_builder::PresetId;
use std::{
io::{BufRead, BufReader},
path::PathBuf,
@@ -182,7 +182,7 @@ mod tests {
.arg("build")
.arg("--release")
.arg("-p")
.arg("staging-chain-spec-builder")
.arg("pezstaging-chain-spec-builder")
.assert()
.success();
}
@@ -224,7 +224,7 @@ mod tests {
block_time: u64,
maybe_preset: Option<PresetId>,
) {
sp_tracing::try_init_simple();
pezsp_tracing::try_init_simple();
maybe_build_runtimes();
maybe_build_chain_spec_builder();
maybe_build_omni_node();
@@ -332,7 +332,7 @@ mod tests {
#[tokio::test]
// This is a regresion test so that we still remain compatible with runtimes that use
// `para-id` in chain specs, instead of implementing the
// `cumulus_primitives_core::GetTeyrchainInfo`.
// `pezcumulus_primitives_core::GetTeyrchainInfo`.
async fn omni_node_dev_mode_works_without_getteyrchaininfo() {
let dev_chain_spec = std::env::current_dir()
.unwrap()
@@ -1,20 +1,20 @@
//! # Currency Pallet
//! # Currency Pezpallet
//!
//! By the end of this guide, you will have written a small FRAME pallet (see
//! By the end of this guide, you will have written a small FRAME pezpallet (see
//! [`crate::pezkuwi_sdk::frame_runtime`]) that is capable of handling a simple crypto-currency.
//! This pallet will:
//! This pezpallet will:
//!
//! 1. Allow anyone to mint new tokens into accounts (which is obviously not a great idea for a real
//! system).
//! 2. Allow any user that owns tokens to transfer them to others.
//! 3. Track the total issuance of all tokens at all times.
//!
//! > This guide will build a currency pallet from scratch using only the lowest primitives of
//! > This guide will build a currency pezpallet from scratch using only the lowest primitives of
//! > FRAME, and is mainly intended for education, not *applicability*. For example, almost all
//! > FRAME-based runtimes use various techniques to re-use a currency pallet instead of writing
//! > FRAME-based runtimes use various techniques to re-use a currency pezpallet instead of writing
//! > one. Further advanced FRAME related topics are discussed in [`crate::reference_docs`].
//!
//! ## Writing Your First Pallet
//! ## Writing Your First Pezpallet
//!
//! To get started, clone one of the templates mentioned in [`crate::pezkuwi_sdk::templates`]. We
//! recommend using the `pezkuwi-sdk-minimal-template`. You might need to change small parts of
@@ -33,23 +33,23 @@
//!
//! The following FRAME topics are covered in this guide:
//!
//! - [`pallet::storage`]
//! - [`pallet::call`]
//! - [`pallet::event`]
//! - [`pallet::error`]
//! - Basics of testing a pallet
//! - [Constructing a runtime](frame::runtime::prelude::construct_runtime)
//! - [`pezpallet::storage`]
//! - [`pezpallet::call`]
//! - [`pezpallet::event`]
//! - [`pezpallet::error`]
//! - Basics of testing a pezpallet
//! - [Constructing a runtime](pezframe::runtime::prelude::construct_runtime)
//!
//! ### Shell Pallet
//! ### Shell Pezpallet
//!
//! Consider the following as a "shell pallet". We continue building the rest of this pallet based
//! on this template.
//! Consider the following as a "shell pezpallet". We continue building the rest of this pezpallet
//! based on this template.
//!
//! [`pallet::config`] and [`pallet::pallet`] are both mandatory parts of any
//! pallet. Refer to the documentation of each to get an overview of what they do.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", shell_pallet)]
//! [`pezpallet::config`] and [`pezpallet::pezpallet`] are both mandatory parts of any
//! pezpallet. Refer to the documentation of each to get an overview of what they do.
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", shell_pallet)]
//!
//! All of the code that follows in this guide should live inside of the `mod pallet`.
//! All of the code that follows in this guide should live inside of the `mod pezpallet`.
//!
//! ### Storage
//!
@@ -59,117 +59,120 @@
//! issuance.
//!
//! > For the rest of this guide, we will opt for a balance type of `u128`. For the sake of
//! > simplicity, we are hardcoding this type. In a real pallet is best practice to define it as a
//! > simplicity, we are hardcoding this type. In a real pezpallet is best practice to define it as
//! > a
//! > generic bounded type in the `Config` trait, and then specify it in the implementation.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", Balance)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", Balance)]
//!
//! The definition of these two storage items, based on [`pallet::storage`] details, is as follows:
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", TotalIssuance)]
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", Balances)]
//! The definition of these two storage items, based on [`pezpallet::storage`] details, is as
//! follows:
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", TotalIssuance)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", Balances)]
//!
//! ### Dispatchables
//!
//! Next, we will define the dispatchable functions. As per [`pallet::call`], these will be defined
//! as normal `fn`s attached to `struct Pallet`.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", impl_pallet)]
//! Next, we will define the dispatchable functions. As per [`pezpallet::call`], these will be
//! defined as normal `fn`s attached to `struct Pezpallet`.
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", impl_pallet)]
//!
//! The logic of these functions is self-explanatory. Instead, we will focus on the FRAME-related
//! details:
//!
//! - Where do `T::AccountId` and `T::RuntimeOrigin` come from? These are both defined in
//! [`frame::prelude::frame_system::Config`], therefore we can access them in `T`.
//! [`pezframe::prelude::pezframe_system::Config`], therefore we can access them in `T`.
//! - What is `ensure_signed`, and what does it do with the aforementioned `T::RuntimeOrigin`? This
//! is outside the scope of this guide, and you can learn more about it in the origin reference
//! document ([`crate::reference_docs::frame_origin`]). For now, you should only know the
//! signature of the function: it takes a generic `T::RuntimeOrigin` and returns a
//! `Result<T::AccountId, _>`. So by the end of this function call, we know that this dispatchable
//! was signed by `sender`.
#![doc = docify::embed!("../../substrate/frame/system/src/lib.rs", ensure_signed)]
#![doc = docify::embed!("../../bizinikiwi/pezframe/system/src/lib.rs", ensure_signed)]
//!
//! - Where does `mutate`, `get` and `insert` and other storage APIs come from? All of them are
//! explained in the corresponding `type`, for example, for `Balances::<T>::insert`, you can look
//! into [`frame::prelude::StorageMap::insert`].
//! into [`pezframe::prelude::StorageMap::insert`].
//!
//! - The return type of all dispatchable functions is [`frame::prelude::DispatchResult`]:
#![doc = docify::embed!("../../substrate/frame/support/src/dispatch.rs", DispatchResult)]
//! - The return type of all dispatchable functions is [`pezframe::prelude::DispatchResult`]:
#![doc = docify::embed!("../../bizinikiwi/pezframe/support/src/dispatch.rs", DispatchResult)]
//!
//! Which is more or less a normal Rust `Result`, with a custom [`frame::prelude::DispatchError`] as
//! Which is more or less a normal Rust `Result`, with a custom [`pezframe::prelude::DispatchError`] as
//! the `Err` variant. We won't cover this error in detail here, but importantly you should know
//! that there is an `impl From<&'static string> for DispatchError` provided (see
//! [here](`frame::prelude::DispatchError#impl-From<%26str>-for-DispatchError`)). Therefore,
//! [here](`pezframe::prelude::DispatchError#impl-From<%26str>-for-DispatchError`)). Therefore,
//! we can use basic string literals as our error type and `.into()` them into `DispatchError`.
//!
//! - Why are all `get` and `mutate` functions returning an `Option`? This is the default behavior
//! of FRAME storage APIs. You can learn more about how to override this by looking into
//! [`pallet::storage`], and [`frame::prelude::ValueQuery`]/[`frame::prelude::OptionQuery`]
//! [`pezpallet::storage`], and [`pezframe::prelude::ValueQuery`]/[`pezframe::prelude::OptionQuery`]
//!
//! ### Improving Errors
//!
//! How we handle error in the above snippets is fairly rudimentary. Let's look at how this can be
//! improved. First, we can use [`frame::prelude::ensure`] to express the error slightly better.
//! improved. First, we can use [`pezframe::prelude::ensure`] to express the error slightly better.
//! This macro will call `.into()` under the hood.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", transfer_better)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", transfer_better)]
//!
//! Moreover, you will learn in the [Defensive Programming
//! section](crate::reference_docs::defensive_programming) that it is always recommended to use
//! safe arithmetic operations in your runtime. By using [`frame::traits::CheckedSub`], we can not
//! safe arithmetic operations in your runtime. By using [`pezframe::traits::CheckedSub`], we can not
//! only take a step in that direction, but also improve the error handing and make it slightly more
//! ergonomic.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", transfer_better_checked)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", transfer_better_checked)]
//!
//! This is more or less all the logic that there is in this basic currency pallet!
//! This is more or less all the logic that there is in this basic currency pezpallet!
//!
//! ### Your First (Test) Runtime
//!
//! The typical testing code of a pallet lives in a module that imports some preludes useful for
//! The typical testing code of a pezpallet lives in a module that imports some preludes useful for
//! testing, similar to:
//!
//! ```
//! pub mod pallet {
//! // snip -- actually pallet code.
//! pub mod pezpallet {
//! // snip -- actually pezpallet code.
//! }
//!
//! #[cfg(test)]
//! mod tests {
//! // bring in the testing prelude of frame
//! use frame::testing_prelude::*;
//! // bring in all pallet items
//! use super::pallet::*;
//! use pezframe::testing_prelude::*;
//! // bring in all pezpallet items
//! use super::pezpallet::*;
//!
//! // snip -- rest of the testing code.
//! }
//! ```
//!
//! Next, we create a "test runtime" in order to test our pallet. Recall from
//! Next, we create a "test runtime" in order to test our pezpallet. Recall from
//! [`crate::pezkuwi_sdk::frame_runtime`] that a runtime is a collection of pallets, expressed
//! through [`frame::runtime::prelude::construct_runtime`]. All runtimes also have to include
//! [`frame::prelude::frame_system`]. So we expect to see a runtime with two pallet, `frame_system`
//! and the one we just wrote.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", runtime)]
//! through [`pezframe::runtime::prelude::construct_runtime`]. All runtimes also have to include
//! [`pezframe::prelude::pezframe_system`]. So we expect to see a runtime with two pezpallet,
//! `pezframe_system` and the one we just wrote.
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", runtime)]
//!
//! > [`frame::pallet_macros::derive_impl`] is a FRAME feature that enables developers to have
//! > [`pezframe::pezpallet_macros::derive_impl`] is a FRAME feature that enables developers to have
//! > defaults for associated types.
//!
//! Recall that within our pallet, (almost) all blocks of code are generic over `<T: Config>`. And,
//! because `trait Config: frame_system::Config`, we can get access to all items in `Config` (or
//! `frame_system::Config`) using `T::NameOfItem`. This is all within the boundaries of how
//! Recall that within our pezpallet, (almost) all blocks of code are generic over `<T: Config>`.
//! And, because `trait Config: pezframe_system::Config`, we can get access to all items in `Config`
//! (or `pezframe_system::Config`) using `T::NameOfItem`. This is all within the boundaries of how
//! Rust traits and generics work. If unfamiliar with this pattern, read
//! [`crate::reference_docs::trait_based_programming`] before going further.
//!
//! Crucially, a typical FRAME runtime contains a `struct Runtime`. The main role of this `struct`
//! is to implement the `trait Config` of all pallets. That is, anywhere within your pallet code
//! is to implement the `trait Config` of all pallets. That is, anywhere within your pezpallet code
//! where you see `<T: Config>` (read: *"some type `T` that implements `Config`"*), in the runtime,
//! it can be replaced with `<Runtime>`, because `Runtime` implements `Config` of all pallets, as we
//! see above.
//!
//! Another way to think about this is that within a pallet, a lot of types are "unknown" and, we
//! Another way to think about this is that within a pezpallet, a lot of types are "unknown" and, we
//! only know that they will be provided at some later point. For example, when you write
//! `T::AccountId` (which is short for `<T as frame_system::Config>::AccountId`) in your pallet,
//! you are in fact saying "*Some type `AccountId` that will be known later*". That "later" is in
//! fact when you specify these types when you implement all `Config` traits for `Runtime`.
//! `T::AccountId` (which is short for `<T as pezframe_system::Config>::AccountId`) in your
//! pezpallet, you are in fact saying "*Some type `AccountId` that will be known later*". That
//! "later" is in fact when you specify these types when you implement all `Config` traits for
//! `Runtime`.
//!
//! As you see above, `frame_system::Config` is setting the `AccountId` to `u64`. Of course, a real
//! runtime will not use this type, and instead reside to a proper type like a 32-byte standard
//! As you see above, `pezframe_system::Config` is setting the `AccountId` to `u64`. Of course, a
//! real runtime will not use this type, and instead reside to a proper type like a 32-byte standard
//! public key. This is a HUGE benefit that FRAME developers can tap into: through the framework
//! being so generic, different types can always be customized to simple things when needed.
//!
@@ -178,23 +181,23 @@
//!
//! ### Your First Test
//!
//! The above is all you need to execute the dispatchables of your pallet. The last thing you need
//! to learn is that all of your pallet testing code should be wrapped in
//! [`frame::testing_prelude::TestState`]. This is a type that provides access to an in-memory state
//! The above is all you need to execute the dispatchables of your pezpallet. The last thing you
//! need to learn is that all of your pezpallet testing code should be wrapped in
//! [`pezframe::testing_prelude::TestState`]. This is a type that provides access to an in-memory state
//! to be used in our tests.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", first_test)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", first_test)]
//!
//! In the first test, we simply assert that there is no total issuance, and no balance associated
//! with Alice's account. Then, we mint some balance into Alice's, and re-check.
//!
//! As noted above, the `T::AccountId` is now `u64`. Moreover, `Runtime` is replacing `<T: Config>`.
//! This is why for example you see `Balances::<Runtime>::get(..)`. Finally, notice that the
//! dispatchables are simply functions that can be called on top of the `Pallet` struct.
//! dispatchables are simply functions that can be called on top of the `Pezpallet` struct.
//!
//! Congratulations! You have written your first pallet and tested it! Next, we learn a few optional
//! steps to improve our pallet.
//! Congratulations! You have written your first pezpallet and tested it! Next, we learn a few
//! optional steps to improve our pezpallet.
//!
//! ## Improving the Currency Pallet
//! ## Improving the Currency Pezpallet
//!
//! ### Better Test Setup
//!
@@ -206,16 +209,16 @@
//!
//! Let's see how we can implement a better test setup using this pattern. First, we define a
//! `struct StateBuilder`.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", StateBuilder)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", StateBuilder)]
//!
//! This struct is meant to contain the same list of accounts and balances that we want to have at
//! the beginning of each block. We hardcoded this to `let accounts = vec![(ALICE, 100), (2, 100)];`
//! so far. Then, if desired, we attach a default value for this struct.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", default_state_builder)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", default_state_builder)]
//!
//! Like any other builder pattern, we attach functions to the type to mutate its internal
//! properties.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", impl_state_builder_add)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", impl_state_builder_add)]
//!
//! Finally --the useful part-- we write our own custom `build_and_execute` function on
//! this type. This function will do multiple things:
@@ -227,29 +230,29 @@
//! after each test. For example, in this test, we do some additional checking about the
//! correctness of the `TotalIssuance`. We leave it up to you as an exercise to learn why the
//! assertion should always hold, and how it is checked.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", impl_state_builder_build)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", impl_state_builder_build)]
//!
//! We can write tests that specifically check the initial state, and making sure our `StateBuilder`
//! is working exactly as intended.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", state_builder_works)]
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", state_builder_add_balance)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", state_builder_works)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", state_builder_add_balance)]
//!
//! ### More Tests
//!
//! Now that we have a more ergonomic test setup, let's see how a well written test for transfer and
//! mint would look like.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", transfer_works)]
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", mint_works)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", transfer_works)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", mint_works)]
//!
//! It is always a good idea to build a mental model where you write *at least* one test for each
//! "success path" of a dispatchable, and one test for each "failure path", such as:
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", transfer_from_non_existent_fails)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", transfer_from_non_existent_fails)]
//!
//! We leave it up to you to write a test that triggers the `InsufficientBalance` error.
//!
//! ### Event and Error
//!
//! Our pallet is mainly missing two parts that are common in most FRAME pallets: Events, and
//! Our pezpallet is mainly missing two parts that are common in most FRAME pallets: Events, and
//! Errors. First, let's understand what each is.
//!
//! - **Error**: The static string-based error scheme we used so far is good for readability, but it
@@ -259,10 +262,10 @@
//! by one character. FRAME errors are exactly a solution to maintain readability, whilst fixing
//! the drawbacks mentioned. In short, we use an enum to represent different variants of our
//! error. These variants are then mapped in an efficient way (using only `u8` indices) to
//! [`sp_runtime::DispatchError::Module`]. Read more about this in [`pallet::error`].
//! [`pezsp_runtime::DispatchError::Module`]. Read more about this in [`pezpallet::error`].
//!
//! - **Event**: Events are akin to the return type of dispatchables. They are mostly data blobs
//! emitted by the runtime to let outside world know what is happening inside the pallet. Since
//! emitted by the runtime to let outside world know what is happening inside the pezpallet. Since
//! otherwise, the outside world does not have an easy access to the state changes. They should
//! represent what happened at the end of a dispatch operation. Therefore, the convention is to
//! use passive tense for event names (eg. `SomethingHappened`). This allows other sub-systems or
@@ -270,41 +273,41 @@
//! needing to re-execute the whole state transition function.
//!
//! With the explanation out of the way, let's see how these components can be added. Both follow a
//! fairly familiar syntax: normal Rust enums, with extra [`pallet::event`] and [`pallet::error`]
//! attributes attached.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", Event)]
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", Error)]
//! fairly familiar syntax: normal Rust enums, with extra [`pezpallet::event`] and
//! [`pezpallet::error`] attributes attached.
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", Event)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", Error)]
//!
//! One slightly custom part of this is the [`pallet::generate_deposit`] part. Without going into
//! too much detail, in order for a pallet to emit events to the rest of the system, it needs to do
//! two things:
//! One slightly custom part of this is the [`pezpallet::generate_deposit`] part. Without going into
//! too much detail, in order for a pezpallet to emit events to the rest of the system, it needs to
//! do two things:
//!
//! 1. Declare a type in its `Config` that refers to the overarching event type of the runtime. In
//! short, by doing this, the pallet is expressing an important bound: `type RuntimeEvent:
//! short, by doing this, the pezpallet is expressing an important bound: `type RuntimeEvent:
//! From<Event<Self>>`. Read: a `RuntimeEvent` exists, and it can be created from the local `enum
//! Event` of this pallet. This enables the pallet to convert its `Event` into `RuntimeEvent`, and
//! store it where needed.
//! Event` of this pezpallet. This enables the pezpallet to convert its `Event` into `RuntimeEvent`,
//! and store it where needed.
//!
//! 2. But, doing this conversion and storing is too much to expect each pallet to define. FRAME
//! provides a default way of storing events, and this is what [`pallet::generate_deposit`] is
//! 2. But, doing this conversion and storing is too much to expect each pezpallet to define. FRAME
//! provides a default way of storing events, and this is what [`pezpallet::generate_deposit`] is
//! doing.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", config_v2)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", config_v2)]
//!
//! > These `Runtime*` types are better explained in
//! > [`crate::reference_docs::frame_runtime_types`].
//!
//! Then, we can rewrite the `transfer` dispatchable as such:
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", transfer_v2)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", transfer_v2)]
//!
//! Then, notice how now we would need to provide this `type RuntimeEvent` in our test runtime
//! setup.
#![doc = docify::embed!("./packages/guides/first-pallet/src/lib.rs", runtime_v2)]
#![doc = docify::embed!("./packages/guides/first-pezpallet/src/lib.rs", runtime_v2)]
//!
//! In this snippet, the actual `RuntimeEvent` type (right hand side of `type RuntimeEvent =
//! RuntimeEvent`) is generated by
//! [`construct_runtime`](frame::runtime::prelude::construct_runtime). An interesting way to inspect
//! [`construct_runtime`](pezframe::runtime::prelude::construct_runtime). An interesting way to inspect
//! this type is to see its definition in rust-docs:
//! [`crate::guides::your_first_pallet::pallet_v2::tests::runtime_v2::RuntimeEvent`].
//! [`crate::guides::your_first_pallet::pezpallet_v2::tests::runtime_v2::RuntimeEvent`].
//!
//!
//! ## What Next?
@@ -315,56 +318,57 @@
//! - [`crate::reference_docs::defensive_programming`].
//! - [`crate::reference_docs::frame_origin`].
//! - [`crate::reference_docs::frame_runtime_types`].
//! - The pallet we wrote in this guide was using `dev_mode`, learn more in [`pallet::config`].
//! - Learn more about the individual pallet items/macros, such as event and errors and call, in
//! [`frame::pallet_macros`].
//! - The pezpallet we wrote in this guide was using `dev_mode`, learn more in
//! [`pezpallet::config`].
//! - Learn more about the individual pezpallet items/macros, such as event and errors and call, in
//! [`pezframe::pezpallet_macros`].
//!
//! [`pallet::storage`]: frame_support::pallet_macros::storage
//! [`pallet::call`]: frame_support::pallet_macros::call
//! [`pallet::event`]: frame_support::pallet_macros::event
//! [`pallet::error`]: frame_support::pallet_macros::error
//! [`pallet::pallet`]: frame_support::pallet
//! [`pallet::config`]: frame_support::pallet_macros::config
//! [`pallet::generate_deposit`]: frame_support::pallet_macros::generate_deposit
//! [`pezpallet::storage`]: pezframe_support::pezpallet_macros::storage
//! [`pezpallet::call`]: pezframe_support::pezpallet_macros::call
//! [`pezpallet::event`]: pezframe_support::pezpallet_macros::event
//! [`pezpallet::error`]: pezframe_support::pezpallet_macros::error
//! [`pezpallet::pezpallet`]: pezframe_support::pezpallet
//! [`pezpallet::config`]: pezframe_support::pezpallet_macros::config
//! [`pezpallet::generate_deposit`]: pezframe_support::pezpallet_macros::generate_deposit
#[docify::export]
#[frame::pallet(dev_mode)]
#[pezframe::pezpallet(dev_mode)]
pub mod shell_pallet {
use frame::prelude::*;
use pezframe::prelude::*;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
}
#[frame::pallet(dev_mode)]
pub mod pallet {
use frame::prelude::*;
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet {
use pezframe::prelude::*;
#[docify::export]
pub type Balance = u128;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[docify::export]
/// Single storage item, of type `Balance`.
#[pallet::storage]
#[pezpallet::storage]
pub type TotalIssuance<T: Config> = StorageValue<_, Balance>;
#[docify::export]
/// A mapping from `T::AccountId` to `Balance`
#[pallet::storage]
#[pezpallet::storage]
pub type Balances<T: Config> = StorageMap<_, _, T::AccountId, Balance>;
#[docify::export(impl_pallet)]
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
/// An unsafe mint that can be called by anyone. Not a great idea.
pub fn mint_unsafe(
origin: T::RuntimeOrigin,
@@ -406,7 +410,7 @@ pub mod pallet {
}
#[allow(unused)]
impl<T: Config> Pallet<T> {
impl<T: Config> Pezpallet<T> {
#[docify::export]
pub fn transfer_better(
origin: T::RuntimeOrigin,
@@ -442,10 +446,10 @@ pub mod pallet {
#[cfg(any(test, doc))]
pub(crate) mod tests {
use crate::guides::your_first_pallet::pallet::*;
use crate::guides::your_first_pallet::pezpallet::*;
#[docify::export(testing_prelude)]
use frame::testing_prelude::*;
use pezframe::testing_prelude::*;
pub(crate) const ALICE: u64 = 1;
pub(crate) const BOB: u64 = 2;
@@ -456,29 +460,29 @@ pub mod pallet {
// tests { .. }`
mod runtime {
use super::*;
// we need to reference our `mod pallet` as an identifier to pass to
// we need to reference our `mod pezpallet` as an identifier to pass to
// `construct_runtime`.
// YOU HAVE TO CHANGE THIS LINE BASED ON YOUR TEMPLATE
use crate::guides::your_first_pallet::pallet as pallet_currency;
use crate::guides::your_first_pallet::pezpallet as pezpallet_currency;
construct_runtime!(
pub enum Runtime {
// ---^^^^^^ This is where `enum Runtime` is defined.
System: frame_system,
Currency: pallet_currency,
System: pezframe_system,
Currency: pezpallet_currency,
}
);
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Runtime>;
// within pallet we just said `<T as frame_system::Config>::AccountId`, now we
// within pezpallet we just said `<T as pezframe_system::Config>::AccountId`, now we
// finally specified it.
type AccountId = u64;
}
// our simple pallet has nothing to be configured.
impl pallet_currency::Config for Runtime {}
// our simple pezpallet has nothing to be configured.
impl pezpallet_currency::Config for Runtime {}
}
pub(crate) use runtime::*;
@@ -500,7 +504,7 @@ pub mod pallet {
#[docify::export]
pub(crate) struct StateBuilder {
balances: Vec<(<Runtime as frame_system::Config>::AccountId, Balance)>,
balances: Vec<(<Runtime as pezframe_system::Config>::AccountId, Balance)>,
}
#[docify::export(default_state_builder)]
@@ -514,7 +518,7 @@ pub mod pallet {
impl StateBuilder {
fn add_balance(
mut self,
who: <Runtime as frame_system::Config>::AccountId,
who: <Runtime as pezframe_system::Config>::AccountId,
amount: Balance,
) -> Self {
self.balances.push((who, amount));
@@ -554,7 +558,7 @@ pub mod pallet {
assert_eq!(TotalIssuance::<Runtime>::get(), None);
// mint some funds into Alice's account.
assert_ok!(Pallet::<Runtime>::mint_unsafe(
assert_ok!(Pezpallet::<Runtime>::mint_unsafe(
RuntimeOrigin::signed(ALICE),
ALICE,
100
@@ -603,14 +607,18 @@ pub mod pallet {
fn mint_works() {
StateBuilder::default().build_and_execute(|| {
// given the initial state, when:
assert_ok!(Pallet::<Runtime>::mint_unsafe(RuntimeOrigin::signed(ALICE), BOB, 100));
assert_ok!(Pezpallet::<Runtime>::mint_unsafe(
RuntimeOrigin::signed(ALICE),
BOB,
100
));
// then:
assert_eq!(Balances::<Runtime>::get(&BOB), Some(200));
assert_eq!(TotalIssuance::<Runtime>::get(), Some(300));
// given:
assert_ok!(Pallet::<Runtime>::mint_unsafe(
assert_ok!(Pezpallet::<Runtime>::mint_unsafe(
RuntimeOrigin::signed(ALICE),
CHARLIE,
100
@@ -627,7 +635,7 @@ pub mod pallet {
fn transfer_works() {
StateBuilder::default().build_and_execute(|| {
// given the initial state, when:
assert_ok!(Pallet::<Runtime>::transfer(RuntimeOrigin::signed(ALICE), BOB, 50));
assert_ok!(Pezpallet::<Runtime>::transfer(RuntimeOrigin::signed(ALICE), BOB, 50));
// then:
assert_eq!(Balances::<Runtime>::get(&ALICE), Some(50));
@@ -635,7 +643,7 @@ pub mod pallet {
assert_eq!(TotalIssuance::<Runtime>::get(), Some(200));
// when:
assert_ok!(Pallet::<Runtime>::transfer(RuntimeOrigin::signed(BOB), ALICE, 50));
assert_ok!(Pezpallet::<Runtime>::transfer(RuntimeOrigin::signed(BOB), ALICE, 50));
// then:
assert_eq!(Balances::<Runtime>::get(&ALICE), Some(100));
@@ -650,7 +658,7 @@ pub mod pallet {
StateBuilder::default().build_and_execute(|| {
// given the initial state, when:
assert_err!(
Pallet::<Runtime>::transfer(RuntimeOrigin::signed(CHARLIE), ALICE, 10),
Pezpallet::<Runtime>::transfer(RuntimeOrigin::signed(CHARLIE), ALICE, 10),
"NonExistentAccount"
);
@@ -664,32 +672,32 @@ pub mod pallet {
}
}
#[frame::pallet(dev_mode)]
pub mod pallet_v2 {
use super::pallet::Balance;
use frame::prelude::*;
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet_v2 {
use super::pezpallet::Balance;
use pezframe::prelude::*;
#[docify::export(config_v2)]
#[pallet::config]
pub trait Config: frame_system::Config {
#[pezpallet::config]
pub trait Config: pezframe_system::Config {
/// The overarching event type of the runtime.
#[allow(deprecated)]
type RuntimeEvent: From<Event<Self>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>
+ IsType<<Self as pezframe_system::Config>::RuntimeEvent>
+ TryInto<Event<Self>>;
}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[pallet::storage]
#[pezpallet::storage]
pub type Balances<T: Config> = StorageMap<_, _, T::AccountId, Balance>;
#[pallet::storage]
#[pezpallet::storage]
pub type TotalIssuance<T: Config> = StorageValue<_, Balance>;
#[docify::export]
#[pallet::error]
#[pezpallet::error]
pub enum Error<T> {
/// Account does not exist.
NonExistentAccount,
@@ -698,15 +706,15 @@ pub mod pallet_v2 {
}
#[docify::export]
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
#[pezpallet::event]
#[pezpallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// A transfer succeeded.
Transferred { from: T::AccountId, to: T::AccountId, amount: Balance },
}
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
#[docify::export(transfer_v2)]
pub fn transfer(
origin: T::RuntimeOrigin,
@@ -732,30 +740,30 @@ pub mod pallet_v2 {
#[cfg(any(test, doc))]
pub mod tests {
use super::{super::pallet::tests::StateBuilder, *};
use frame::testing_prelude::*;
use super::{super::pezpallet::tests::StateBuilder, *};
use pezframe::testing_prelude::*;
const ALICE: u64 = 1;
const BOB: u64 = 2;
#[docify::export]
pub mod runtime_v2 {
use super::*;
use crate::guides::your_first_pallet::pallet_v2 as pallet_currency;
use crate::guides::your_first_pallet::pezpallet_v2 as pezpallet_currency;
construct_runtime!(
pub enum Runtime {
System: frame_system,
Currency: pallet_currency,
System: pezframe_system,
Currency: pezpallet_currency,
}
);
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Runtime>;
type AccountId = u64;
}
impl pallet_currency::Config for Runtime {
impl pezpallet_currency::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}
}
@@ -771,7 +779,7 @@ pub mod pallet_v2 {
System::set_block_number(ALICE);
// given the initial state, when:
assert_ok!(Pallet::<Runtime>::transfer(RuntimeOrigin::signed(ALICE), BOB, 50));
assert_ok!(Pezpallet::<Runtime>::transfer(RuntimeOrigin::signed(ALICE), BOB, 50));
// then:
assert_eq!(Balances::<Runtime>::get(&ALICE), Some(50));
@@ -1,25 +1,25 @@
//! # Your first Runtime
//!
//! This guide will walk you through the steps to add your pallet to a runtime.
//! This guide will walk you through the steps to add your pezpallet to a runtime.
//!
//! The good news is, in [`crate::guides::your_first_pallet`], we have already created a _test_
//! runtime that was used for testing, and a real runtime is not that much different!
//!
//! ## Setup
//!
//! A runtime shares a few similar setup requirements as with a pallet:
//! A runtime shares a few similar setup requirements as with a pezpallet:
//!
//! * importing [`frame`], [`codec`], and [`scale_info`] crates.
//! * following the [`std` feature-gating](crate::pezkuwi_sdk::substrate#wasm-build) pattern.
//! * following the [`std` feature-gating](crate::pezkuwi_sdk::bizinikiwi#wasm-build) pattern.
//!
//! But, more specifically, it also contains:
//!
//! * a `build.rs` that uses [`substrate_wasm_builder`]. This entails declaring
//! * a `build.rs` that uses [`bizinikiwi_wasm_builder`]. This entails declaring
//! `[build-dependencies]` in the Cargo manifest file:
//!
//! ```ignore
//! [build-dependencies]
//! substrate-wasm-builder = { ... }
//! bizinikiwi-wasm-builder = { ... }
//! ```
//!
//! >Note that a runtime must always be one-runtime-per-crate. You cannot define multiple runtimes
@@ -30,7 +30,7 @@
//! ## Your First Runtime
//!
//! The first new property of a real runtime that it must define its
//! [`frame::runtime::prelude::RuntimeVersion`]:
//! [`pezframe::runtime::prelude::RuntimeVersion`]:
#![doc = docify::embed!("./packages/guides/first-runtime/src/lib.rs", VERSION)]
//!
//! The version contains a number of very important fields, such as `spec_version` and `spec_name`
@@ -39,7 +39,7 @@
//! [`crate::reference_docs::frame_runtime_upgrades_and_migrations`].
//!
//! Then, a real runtime also contains the `impl` of all individual pallets' `trait Config` for
//! `struct Runtime`, and a [`frame::runtime::prelude::construct_runtime`] macro that amalgamates
//! `struct Runtime`, and a [`pezframe::runtime::prelude::construct_runtime`] macro that amalgamates
//! them all.
//!
//! In the case of our example:
@@ -49,13 +49,13 @@
//! their `Config` need to be implemented for `struct Runtime`:
#![doc = docify::embed!("./packages/guides/first-runtime/src/lib.rs", config_impls)]
//!
//! Notice how we use [`frame::pallet_macros::derive_impl`] to provide "default" configuration items
//! for each pallet. Feel free to dive into the definition of each default prelude (eg.
//! [`frame::prelude::frame_system::pallet::config_preludes`]) to learn more which types are exactly
//! used.
//! Notice how we use [`pezframe::pezpallet_macros::derive_impl`] to provide "default" configuration
//! items for each pezpallet. Feel free to dive into the definition of each default prelude (eg.
//! [`pezframe::prelude::pezframe_system::pezpallet::config_preludes`]) to learn more which types are
//! exactly used.
//!
//! Recall that in test runtime in [`crate::guides::your_first_pallet`], we provided `type AccountId
//! = u64` to `frame_system`, while in this case we rely on whatever is provided by
//! = u64` to `pezframe_system`, while in this case we rely on whatever is provided by
//! [`SolochainDefaultConfig`], which is indeed a "real" 32 byte account id.
//!
//! Then, a familiar instance of `construct_runtime` amalgamates all of the pallets:
@@ -66,12 +66,12 @@
//! steps of crafting a runtime are related to achieving exactly this.
//!
//! First, we define a number of types that eventually lead to the creation of an instance of
//! [`frame::runtime::prelude::Executive`]. The executive is a handy FRAME utility that, through
//! [`pezframe::runtime::prelude::Executive`]. The executive is a handy FRAME utility that, through
//! amalgamating all pallets and further types, implements some of the very very core pieces of the
//! runtime logic, such as how blocks are executed and other runtime-api implementations.
#![doc = docify::embed!("./packages/guides/first-runtime/src/lib.rs", runtime_types)]
//!
//! Finally, we use [`frame::runtime::prelude::impl_runtime_apis`] to implement all of the runtime
//! Finally, we use [`pezframe::runtime::prelude::impl_runtime_apis`] to implement all of the runtime
//! APIs that the runtime wishes to expose. As you will see in the code, most of these runtime API
//! implementations are merely forwarding calls to `RuntimeExecutive` which handles the actual
//! logic. Given that the implementation block is somewhat large, we won't repeat it here. You can
@@ -101,7 +101,7 @@
//!
//! Once you compile a crate that contains a runtime as above, simply running `cargo build` will
//! generate the wasm blobs and place them under `./target/release/wbuild`, as explained
//! [here](crate::pezkuwi_sdk::substrate#wasm-build).
//! [here](crate::pezkuwi_sdk::bizinikiwi#wasm-build).
//!
//! ## Genesis Configuration
//!
@@ -110,8 +110,8 @@
//! what is known as a **Chain Specification, or chain spec for short**. A chain spec is the
//! primary way to run a new chain.
//!
//! These APIs are defined in [`sp_genesis_builder`], and are re-exposed as a part of
//! [`frame::runtime::apis`]. Therefore, the implementation blocks can be found inside of
//! These APIs are defined in [`pezsp_genesis_builder`], and are re-exposed as a part of
//! [`pezframe::runtime::apis`]. Therefore, the implementation blocks can be found inside of
//! `impl_runtime_apis!` similar to:
//!
//! ```ignore
@@ -136,13 +136,14 @@
//! The implementation of these function can naturally vary from one runtime to the other, but the
//! overall pattern is common. For the case of this runtime, we do the following:
//!
//! 1. Expose one non-default preset, namely [`sp_genesis_builder::DEV_RUNTIME_PRESET`]. This means
//! our runtime has two "presets" of genesis state in total: `DEV_RUNTIME_PRESET` and `None`.
//! 1. Expose one non-default preset, namely [`pezsp_genesis_builder::DEV_RUNTIME_PRESET`]. This
//! means our runtime has two "presets" of genesis state in total: `DEV_RUNTIME_PRESET` and
//! `None`.
#![doc = docify::embed!("./packages/guides/first-runtime/src/lib.rs", preset_names)]
//!
//! For `build_state` and `get_preset`, we use the helper functions provide by frame:
//!
//! * [`frame::runtime::prelude::build_state`] and [`frame::runtime::prelude::get_preset`].
//! * [`pezframe::runtime::prelude::build_state`] and [`pezframe::runtime::prelude::get_preset`].
//!
//! Indeed, our runtime needs to specify what its `DEV_RUNTIME_PRESET` genesis state should be like:
#![doc = docify::embed!("./packages/guides/first-runtime/src/lib.rs", development_config_genesis)]
@@ -164,10 +165,10 @@
//! [`crate::reference_docs::frame_runtime_upgrades_and_migrations`].
//! 4. Learn more about adding and implementing runtime apis in
//! [`crate::reference_docs::custom_runtime_api_rpc`].
//! 5. To see a complete example of a runtime+pallet that is similar to this guide, please see
//! 5. To see a complete example of a runtime+pezpallet that is similar to this guide, please see
//! [`crate::pezkuwi_sdk::templates`].
//!
//! [`SolochainDefaultConfig`]: struct@frame_system::pallet::config_preludes::SolochainDefaultConfig
//! [`SolochainDefaultConfig`]: struct@pezframe_system::pezpallet::config_preludes::SolochainDefaultConfig
#[cfg(test)]
mod tests {
+17 -17
View File
@@ -29,7 +29,7 @@
//! > To achieve this, we often use [`docify`](https://github.com/sam0x17/docify), a nifty invention
//! > of `@sam0x17`.
//!
//! Also see: <https://github.com/pezkuwichain/pezkuwi-sdk/issues/109>.
//! Also see: <https://github.com/pezkuwichain/pezkuwi-sdk/issues/255>.
//!
//! ## Scope
//!
@@ -63,7 +63,7 @@
//!
//! > A prime example of this, the list of CLI arguments of a particular binary should not be
//! > documented in multiple places across this crate. It should be only be documented in the
//! > corresponding crate (e.g. `sc_cli`).
//! > corresponding crate (e.g. `pezsc_cli`).
//!
//! > Moreover, this means that as a contributor, **it is your responsibility to have a grasp over
//! > what topics are already covered in this crate, and how you can build on top of the information
@@ -72,7 +72,7 @@
//! For more details see the [latest documenting
//! guidelines](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/docs/contributor/DOCUMENTATION_GUIDELINES.md).
//!
//! #### Example: Explaining `#[pallet::call]`
//! #### Example: Explaining `#[pezpallet::call]`
//!
//! <details>
//! <summary>
@@ -82,15 +82,15 @@
//!
//!
//! ```
//! #[frame::pallet(dev_mode)]
//! pub mod pallet {
//! # use frame::prelude::*;
//! # #[pallet::config]
//! # pub trait Config: frame_system::Config {}
//! # #[pallet::pallet]
//! # pub struct Pallet<T>(_);
//! #[pallet::call]
//! impl<T: Config> Pallet<T> {
//! #[pezframe::pezpallet(dev_mode)]
//! pub mod pezpallet {
//! # use pezframe::prelude::*;
//! # #[pezpallet::config]
//! # pub trait Config: pezframe_system::Config {}
//! # #[pezpallet::pezpallet]
//! # pub struct Pezpallet<T>(_);
//! #[pezpallet::call]
//! impl<T: Config> Pezpallet<T> {
//! pub fn a_simple_call(origin: OriginFor<T>, data: u32) -> DispatchResult {
//! ensure!(data > 10, "SomeStaticString");
//! todo!();
@@ -101,13 +101,13 @@
//!
//! * Before even getting started, what is with all of this `<T: Config>`? We link to
//! [`crate::reference_docs::trait_based_programming`].
//! * First, the name. Why is this called `pallet::call`? This goes back to `enum Call`, which is
//! * First, the name. Why is this called `pezpallet::call`? This goes back to `enum Call`, which is
//! explained in [`crate::reference_docs::frame_runtime_types`]. Build on top of this!
//! * Then, what is `origin`? Just an account id? [`crate::reference_docs::frame_origin`].
//! * Then, what is `DispatchResult`? Why is this called *dispatch*? Probably something that can be
//! explained in the documentation of [`frame::prelude::DispatchResult`].
//! explained in the documentation of [`pezframe::prelude::DispatchResult`].
//! * Why is `"SomeStaticString"` a valid error? Because there is implementation for it that you can
//! see [here](frame::prelude::DispatchError#impl-From<%26'static+str>-for-DispatchError).
//! see [here](pezframe::prelude::DispatchError#impl-From<%26'static+str>-for-DispatchError).
//!
//!
//! All of these are examples of underlying information that a contributor should:
@@ -132,7 +132,7 @@
//! So long as not deployed in `crates.io`, please notice that all of the information in this crate,
//! namely in [`crate::guides`] and such are compatible with the master branch of `pezkuwi-sdk`. A
//! few solutions have been proposed to improve this, please see
//! [here](https://github.com/pezkuwichain/pezkuwi-sdk/issues/146).
//! [here](https://github.com/pezkuwichain/pezkuwi-sdk/issues/289).
//!
//! ## How to Develop Locally
//!
@@ -146,6 +146,6 @@
//! ```
//!
//! If even faster build time for docs is needed, you can temporarily remove most of the
//! substrate/cumulus dependencies that are only used for linking purposes.
//! bizinikiwi/pezcumulus dependencies that are only used for linking purposes.
//!
//! For more on local development, see [`crate::reference_docs::development_environment_advice`].
@@ -0,0 +1,138 @@
//! # Bizinikiwi
//!
//! Bizinikiwi is a Rust framework for building blockchains in a modular and extensible way. While
//! in itself un-opinionated, it is the main engine behind the Pezkuwi ecosystem.
//!
//! ## Overview, Philosophy
//!
//! Bizinikiwi approaches blockchain development with an acknowledgement of a few self-evident
//! truths:
//!
//! 1. Society and technology evolves.
//! 2. Humans are fallible.
//!
//! This makes the task of designing a correct, safe and long-lasting blockchain system hard.
//!
//! Nonetheless, in strive towards achieving this goal, Bizinikiwi embraces the following:
//!
//! 1. Use of **Rust** as a modern and safe programming language, which limits human error through
//! various means, most notably memory and type safety.
//! 2. Bizinikiwi is written from the ground-up with a *generic, modular and extensible* design.
//! This ensures that software components can be easily swapped and upgraded. Examples of this is
//! multiple consensus mechanisms provided by Bizinikiwi, as listed below.
//! 3. Lastly, the final blockchain system created with the above properties needs to be
//! upgradeable. In order to achieve this, Bizinikiwi is designed as a meta-protocol, whereby the
//! application logic of the blockchain (called "Runtime") is encoded as a WASM blob, and is
//! stored in the state. The rest of the system (called "node") acts as the executor of the WASM
//! blob.
//!
//! In essence, the meta-protocol of all Bizinikiwi based chains is the "Runtime as WASM blob"
//! accord. This enables the Runtime to become inherently upgradeable, crucially without [forks](https://en.wikipedia.org/wiki/Fork_(blockchain)). The
//! upgrade is merely a matter of the WASM blob being changed in the state, which is, in principle,
//! same as updating an account's balance. Learn more about this in detail in
//! [`crate::reference_docs::wasm_meta_protocol`].
//!
//! > A great analogy for bizinikiwi is the following: Bizinikiwi node is a gaming console, and a
//! > WASM
//! > runtime, possibly created with FRAME is the game being inserted into the console.
//!
//! [`frame`], Bizinikiwi's default runtime development library, takes the above safety practices
//! even further by embracing a declarative programming model whereby correctness is enhanced and
//! the system is highly configurable through parameterization. Learn more about this in
//! [`crate::reference_docs::trait_based_programming`].
//!
//! ## How to Get Started
//!
//! Bizinikiwi offers different options at the spectrum of technical freedom <-> development ease.
//!
//! * The easiest way to use Bizinikiwi is to use one of the templates (some of which listed at
//! [`crate::pezkuwi_sdk::templates`]) and only tweak the parameters of the runtime or node. This
//! allows you to launch a blockchain in minutes, but is limited in technical freedom.
//! * Next, most developers wish to develop their custom runtime modules, for which the de-facto way
//! is [`frame`](crate::pezkuwi_sdk::frame_runtime).
//! * Finally, Bizinikiwi is highly configurable at the node side as well, but this is the most
//! technically demanding.
//!
//! > A notable Bizinikiwi-based blockchain that has built both custom FRAME pallets and custom
//! > node-side components is <https://github.com/Cardinal-Cryptography/aleph-node>.
#![doc = simple_mermaid::mermaid!("../../../mermaid/bizinikiwi_dev.mmd")]
//!
//! ## Structure
//!
//! Bizinikiwi contains a large number of crates, therefore it is useful to have an overview of what
//! they are, and how they are organized. In broad terms, these crates are divided into three
//! categories:
//!
//! * `sc-*` (short for *Bizinikiwi-client*) crates, located under `./client` folder. These are all
//! the crates that lead to the node software. Notable examples are [`pezsc_network`], various
//! consensus crates, RPC ([`pezsc_rpc_api`]) and database ([`pezsc_client_db`]), all of which are
//! expected to reside in the node side.
//! * `sp-*` (short for *bizinikiwi-primitives*) crates, located under `./primitives` folder. These
//! are crates that facilitate both the node and the runtime, but are not opinionated about what
//! framework is using for building the runtime. Notable examples are [`pezsp_api`] and
//! [`pezsp_io`], which form the communication bridge between the node and runtime.
//! * `pezpallet-*` and `frame-*` crates, located under `./frame` folder. These are the crates
//! related to FRAME. See [`frame`] for more information.
//!
//! ### WASM Build
//!
//! Many of the Bizinikiwi crates, such as entire `sp-*`, need to compile to both WASM (when a WASM
//! runtime is being generated) and native (for example, when testing). To achieve this, Bizinikiwi
//! follows the convention of the Rust community, and uses a `feature = "std"` to signify that a
//! crate is being built with the standard library, and is built for native. Otherwise, it is built
//! for `no_std`.
//!
//! This can be summarized in `#![cfg_attr(not(feature = "std"), no_std)]`, which you can often find
//! in any Bizinikiwi-based runtime.
//!
//! Bizinikiwi-based runtimes use [`bizinikiwi_wasm_builder`] in their `build.rs` to automatically
//! build their WASM files as a part of normal build command (e.g. `cargo build`). Once built, the
//! wasm file is placed in `./target/{debug|release}/wbuild/{runtime_name}/{runtime_name}.wasm`.
//!
//! In order to ensure that the WASM build is **deterministic**, the [Bizinikiwi Runtime Toolbox (srtool)](https://github.com/paritytech/srtool) can be used.
//!
//! ### Anatomy of a Binary Crate
//!
//! From the above, [`node_cli`]/[`pez_kitchensink_runtime`] and `node-template` are essentially
//! blueprints of a Bizinikiwi-based project, as the name of the latter is implying. Each
//! Bizinikiwi-based project typically contains the following:
//!
//! * Under `./runtime`, a `./runtime/src/lib.rs` which is the top level runtime amalgamator file.
//! This file typically contains the [`pezframe::runtime::prelude::construct_runtime`] and
//! [`pezframe::runtime::prelude::impl_runtime_apis`] macro calls, which is the final definition of a
//! runtime.
//!
//! * Under `./node`, a `main.rs`, which is the starting point, and a `./service.rs`, which contains
//! all the node side components. Skimming this file yields an overview of the networking,
//! database, consensus and similar node side components.
//!
//! > The above two are conventions, not rules.
//!
//! > See <https://github.com/pezkuwichain/pezkuwi-sdk/issues/241> for an update on how the node side
//! > components are being amalgamated.
//!
//! ## Teyrchain?
//!
//! As noted above, Bizinikiwi is the main engine behind the Pezkuwi ecosystem. One of the ways
//! through which Pezkuwi can be utilized is by building "teyrchains", blockchains that are
//! connected to Pezkuwi's shared security.
//!
//! To build a teyrchain, one could use [Pezcumulus](crate::pezkuwi_sdk::pezcumulus), the library on
//! top of Bizinikiwi, empowering any bizinikiwi-based chain to be a Pezkuwi teyrchain.
//!
//! ## Where To Go Next?
//!
//! Additional noteworthy crates within bizinikiwi:
//!
//! - RPC APIs of a Bizinikiwi node: [`pezsc_rpc_api`]/[`pezsc_rpc`]
//! - CLI Options of a Bizinikiwi node: [`pezsc_cli`]
//! - All of the consensus related crates provided by Bizinikiwi:
//! - [`pezsc_consensus_aura`]
//! - [`pezsc_consensus_babe`]
//! - [`pezsc_consensus_grandpa`]
//! - [`pezsc_consensus_beefy`] (TODO: @adrian, add some high level docs <https://github.com/pezkuwichain/pezkuwi-sdk/issues/305>)
//! - [`pezsc_consensus_manual_seal`]
//! - [`pezsc_consensus_pow`]
#[doc(hidden)]
pub use crate::pezkuwi_sdk;
@@ -1,130 +0,0 @@
//! # Cumulus
//!
//! Substrate provides a framework ([FRAME]) through which a blockchain node and runtime can easily
//! be created. Cumulus aims to extend the same approach to creation of Pezkuwi teyrchains.
//!
//! > Cumulus clouds are shaped sort of like dots; together they form a system that is intricate,
//! > beautiful and functional.
//!
//! ## Example: Runtime
//!
//! A Cumulus-based runtime is fairly similar to other [FRAME]-based runtimes. Most notably, the
//! following changes are applied to a normal FRAME-based runtime to make it a Cumulus-based
//! runtime:
//!
//! #### Cumulus Pallets
//!
//! A teyrchain runtime should use a number of pallets that are provided by Cumulus and Substrate.
//! Notably:
//!
//! - [`frame-system`](frame::prelude::frame_system), like all FRAME-based runtimes.
//! - [`cumulus_pallet_teyrchain_system`]
//! - [`teyrchain_info`]
#![doc = docify::embed!("./src/pezkuwi_sdk/cumulus.rs", system_pallets)]
//!
//! Given that all Cumulus-based runtimes use a simple Aura-based consensus mechanism, the following
//! pallets also need to be added:
//!
//! - [`pallet_timestamp`]
//! - [`pallet_aura`]
//! - [`cumulus_pallet_aura_ext`]
#![doc = docify::embed!("./src/pezkuwi_sdk/cumulus.rs", consensus_pallets)]
//!
//!
//! Finally, a separate macro, similar to
//! [`impl_runtime_api`](frame::runtime::prelude::impl_runtime_apis), which creates the default set
//! of runtime APIs, will generate the teyrchain runtime's validation runtime API, also known as
//! teyrchain validation function (PVF). Without this API, the relay chain is unable to validate
//! blocks produced by our teyrchain.
#![doc = docify::embed!("./src/pezkuwi_sdk/cumulus.rs", validate_block)]
//!
//! ---
//!
//! [FRAME]: crate::pezkuwi_sdk::frame_runtime
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(rustdoc::private_intra_doc_links)]
#[cfg(test)]
mod tests {
mod runtime {
pub use frame::{
deps::sp_consensus_aura::sr25519::AuthorityId as AuraId, prelude::*,
runtime::prelude::*, testing_prelude::*,
};
#[docify::export(CR)]
construct_runtime!(
pub enum Runtime {
// system-level pallets.
System: frame_system,
Timestamp: pallet_timestamp,
TeyrchainSystem: cumulus_pallet_teyrchain_system,
TeyrchainInfo: teyrchain_info,
// teyrchain consensus support -- mandatory.
Aura: pallet_aura,
AuraExt: cumulus_pallet_aura_ext,
}
);
#[docify::export]
mod system_pallets {
use super::*;
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
type Block = MockBlock<Self>;
type OnSetCode = cumulus_pallet_teyrchain_system::TeyrchainSetCode<Self>;
}
impl cumulus_pallet_teyrchain_system::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type OnSystemEvent = ();
type SelfParaId = teyrchain_info::Pallet<Runtime>;
type OutboundXcmpMessageSource = ();
type XcmpMessageHandler = ();
type ReservedDmpWeight = ();
type ReservedXcmpWeight = ();
type CheckAssociatedRelayNumber =
cumulus_pallet_teyrchain_system::RelayNumberMonotonicallyIncreases;
type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
Runtime,
6000, // relay chain block time
1,
1,
>;
type WeightInfo = ();
type DmpQueue = frame::traits::EnqueueWithOrigin<(), sp_core::ConstU8<0>>;
type RelayParentOffset = ConstU32<0>;
}
impl teyrchain_info::Config for Runtime {}
}
#[docify::export]
mod consensus_pallets {
use super::*;
impl pallet_aura::Config for Runtime {
type AuthorityId = AuraId;
type DisabledValidators = ();
type MaxAuthorities = ConstU32<100_000>;
type AllowMultipleBlocksPerSlot = ConstBool<false>;
type SlotDuration = pallet_aura::MinimumPeriodTimesTwo<Self>;
}
#[docify::export(timestamp)]
#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)]
impl pallet_timestamp::Config for Runtime {}
impl cumulus_pallet_aura_ext::Config for Runtime {}
}
#[docify::export(validate_block)]
cumulus_pallet_teyrchain_system::register_validate_block! {
Runtime = Runtime,
BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
}
}
}
@@ -10,102 +10,104 @@
//! \_\/ \_\/ \_\/ \__\/\__\/ \__\/ \__\/ \_____\/
//! ```
//!
//! > **F**ramework for **R**untime **A**ggregation of **M**odularized **E**ntities: Substrate's
//! > **F**ramework for **R**untime **A**ggregation of **M**odularized **E**ntities: Bizinikiwi's
//! > State Transition Function (Runtime) Framework.
//!
//! ## Introduction
//!
//! As described in [`crate::reference_docs::wasm_meta_protocol`], at a high-level Substrate-based
//! As described in [`crate::reference_docs::wasm_meta_protocol`], at a high-level Bizinikiwi-based
//! blockchains are composed of two parts:
//!
//! 1. A *runtime* which represents the state transition function (i.e. "Business Logic") of a
//! blockchain, and is encoded as a WASM blob.
//! 2. A node whose primary purpose is to execute the given runtime.
#![doc = simple_mermaid::mermaid!("../../../mermaid/substrate_simple.mmd")]
#![doc = simple_mermaid::mermaid!("../../../mermaid/bizinikiwi_simple.mmd")]
//!
//! *FRAME is the Substrate's framework of choice to build a runtime.*
//! *FRAME is the Bizinikiwi's framework of choice to build a runtime.*
//!
//! FRAME is composed of two major components, **pallets** and a **runtime**.
//!
//! ## Pallets
//!
//! A pallet is a unit of encapsulated logic. It has a clearly defined responsibility and can be
//! A pezpallet is a unit of encapsulated logic. It has a clearly defined responsibility and can be
//! linked to other pallets. In order to be reusable, pallets shipped with FRAME strive to only care
//! about its own responsibilities and make as few assumptions about the general runtime as
//! possible. A pallet is analogous to a _module_ in the runtime.
//! possible. A pezpallet is analogous to a _module_ in the runtime.
//!
//! A pallet is defined as a `mod pallet` wrapped by the [`frame::pallet`] macro. Within this macro,
//! pallet components/parts can be defined. Most notable of these parts are:
//! A pezpallet is defined as a `mod pezpallet` wrapped by the [`pezframe::pezpallet`] macro. Within
//! this macro, pezpallet components/parts can be defined. Most notable of these parts are:
//!
//! - [Config](frame::pallet_macros::config), allowing a pallet to make itself configurable and
//! generic over types, values and such.
//! - [Storage](frame::pallet_macros::storage), allowing a pallet to define onchain storage.
//! - [Dispatchable function](frame::pallet_macros::call), allowing a pallet to define extrinsics
//! that are callable by end users, from the outer world.
//! - [Events](frame::pallet_macros::event), allowing a pallet to emit events.
//! - [Errors](frame::pallet_macros::error), allowing a pallet to emit well-formed errors.
//! - [Config](pezframe::pezpallet_macros::config), allowing a pezpallet to make itself configurable
//! and generic over types, values and such.
//! - [Storage](pezframe::pezpallet_macros::storage), allowing a pezpallet to define onchain storage.
//! - [Dispatchable function](pezframe::pezpallet_macros::call), allowing a pezpallet to define
//! extrinsics that are callable by end users, from the outer world.
//! - [Events](pezframe::pezpallet_macros::event), allowing a pezpallet to emit events.
//! - [Errors](pezframe::pezpallet_macros::error), allowing a pezpallet to emit well-formed errors.
//!
//! Some of these pallet components resemble the building blocks of a smart contract. While both
//! Some of these pezpallet components resemble the building blocks of a smart contract. While both
//! models are programming state transition functions of blockchains, there are crucial differences
//! between the two. See [`crate::reference_docs::runtime_vs_smart_contract`] for more.
//!
//! Most of these components are defined using macros, the full list of which can be found in
//! [`frame::pallet_macros`].
//! [`pezframe::pezpallet_macros`].
//!
//! ### Example
//!
//! The following example showcases a minimal pallet.
#![doc = docify::embed!("src/pezkuwi_sdk/frame_runtime.rs", pallet)]
//! The following example showcases a minimal pezpallet.
#![doc = docify::embed!("src/pezkuwi_sdk/frame_runtime.rs", pezpallet)]
//!
//! ## Runtime
//!
//! A runtime is a collection of pallets that are amalgamated together. Each pallet typically has
//! A runtime is a collection of pallets that are amalgamated together. Each pezpallet typically has
//! some configurations (exposed as a `trait Config`) that needs to be *specified* in the runtime.
//! This is done with [`frame::runtime::prelude::construct_runtime`].
//! This is done with [`pezframe::runtime::prelude::construct_runtime`].
//!
//! A (real) runtime that actually wishes to compile to WASM needs to also implement a set of
//! runtime-apis. These implementation can be specified using the
//! [`frame::runtime::prelude::impl_runtime_apis`] macro.
//! [`pezframe::runtime::prelude::impl_runtime_apis`] macro.
//!
//! ### Example
//!
//! The following example shows a (test) runtime that is composing the pallet demonstrated above,
//! next to the [`frame::prelude::frame_system`] pallet, into a runtime.
//! The following example shows a (test) runtime that is composing the pezpallet demonstrated above,
//! next to the [`pezframe::prelude::pezframe_system`] pezpallet, into a runtime.
#![doc = docify::embed!("src/pezkuwi_sdk/frame_runtime.rs", runtime)]
//!
//! ## More Examples
//!
//! You can find more FRAME examples that revolve around specific features at [`pallet_examples`].
//! You can find more FRAME examples that revolve around specific features at
//! [`pezpallet_examples`].
//!
//! ## Alternatives 🌈
//!
//! There is nothing in the Substrate's node side code-base that mandates the use of FRAME. While
//! FRAME makes it very simple to write Substrate-based runtimes, it is by no means intended to be
//! There is nothing in the Bizinikiwi's node side code-base that mandates the use of FRAME. While
//! FRAME makes it very simple to write Bizinikiwi-based runtimes, it is by no means intended to be
//! the only one. At the end of the day, any WASM blob that exposes the right set of runtime APIs is
//! a valid Runtime form the point of view of a Substrate client (see
//! a valid Runtime form the point of view of a Bizinikiwi client (see
//! [`crate::reference_docs::wasm_meta_protocol`]). Notable examples are:
//!
//! * writing a runtime in pure Rust, as done in [this template](https://github.com/JoshOrndorff/frameless-node-template).
//! * writing a runtime in AssemblyScript, as explored in [this project](https://github.com/LimeChain/subsembly).
/// A FRAME based pallet. This `mod` is the entry point for everything else. All
/// `#[pallet::xxx]` macros must be defined in this `mod`. Although, frame also provides an
/// experimental feature to break these parts into different `mod`s. See [`pallet_examples`] for
/// A FRAME based pezpallet. This `mod` is the entry point for everything else. All
/// `#[pezpallet::xxx]` macros must be defined in this `mod`. Although, frame also provides an
/// experimental feature to break these parts into different `mod`s. See [`pezpallet_examples`] for
/// more.
#[docify::export]
#[frame::pallet(dev_mode)]
pub mod pallet {
use frame::prelude::*;
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet {
use pezframe::prelude::*;
/// The configuration trait of a pallet. Mandatory. Allows a pallet to receive types at a
/// later point from the runtime that wishes to contain it. It allows the pallet to be
/// The configuration trait of a pezpallet. Mandatory. Allows a pezpallet to receive types at a
/// later point from the runtime that wishes to contain it. It allows the pezpallet to be
/// parameterized over both types and values.
#[pallet::config]
pub trait Config: frame_system::Config {
/// A type that is not known now, but the runtime that will contain this pallet will
#[pezpallet::config]
pub trait Config: pezframe_system::Config {
/// A type that is not known now, but the runtime that will contain this pezpallet will
/// know it later, therefore we define it here as an associated type.
#[allow(deprecated)]
type RuntimeEvent: IsType<<Self as frame_system::Config>::RuntimeEvent> + From<Event<Self>>;
type RuntimeEvent: IsType<<Self as pezframe_system::Config>::RuntimeEvent>
+ From<Event<Self>>;
/// A parameterize-able value that we receive later via the `Get<_>` trait.
type ValueParameter: Get<u32>;
@@ -115,25 +117,25 @@ pub mod pallet {
const ANOTHER_VALUE_PARAMETER: u32;
}
/// A mandatory struct in each pallet. All functions callable by external users (aka.
/// transactions) must be attached to this type (see [`frame::pallet_macros::call`]). For
/// A mandatory struct in each pezpallet. All functions callable by external users (aka.
/// transactions) must be attached to this type (see [`pezframe::pezpallet_macros::call`]). For
/// convenience, internal (private) functions can also be attached to this type.
#[pallet::pallet]
pub struct Pallet<T>(PhantomData<T>);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(PhantomData<T>);
/// The events that this pallet can emit.
#[pallet::event]
/// The events that this pezpallet can emit.
#[pezpallet::event]
pub enum Event<T: Config> {}
/// A storage item that this pallet contains. This will be part of the state root trie
/// A storage item that this pezpallet contains. This will be part of the state root trie
/// of the blockchain.
#[pallet::storage]
#[pezpallet::storage]
pub type Value<T> = StorageValue<Value = u32>;
/// All *dispatchable* call functions (aka. transactions) are attached to `Pallet` in a
/// All *dispatchable* call functions (aka. transactions) are attached to `Pezpallet` in a
/// `impl` block.
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
/// This will be callable by external users, and has two u32s as a parameter.
pub fn some_dispatchable(
_origin: OriginFor<T>,
@@ -145,29 +147,29 @@ pub mod pallet {
}
}
/// A simple runtime that contains the above pallet and `frame_system`, the mandatory pallet of
/// all runtimes. This runtime is for testing, but it shares a lot of similarities with a *real*
/// runtime.
/// A simple runtime that contains the above pezpallet and `pezframe_system`, the mandatory
/// pezpallet of all runtimes. This runtime is for testing, but it shares a lot of similarities with
/// a *real* runtime.
#[docify::export]
pub mod runtime {
use super::pallet as pallet_example;
use frame::{prelude::*, testing_prelude::*};
use super::pezpallet as pezpallet_example;
use pezframe::{prelude::*, testing_prelude::*};
// The major macro that amalgamates pallets into `enum Runtime`
construct_runtime!(
pub enum Runtime {
System: frame_system,
Example: pallet_example,
System: pezframe_system,
Example: pezpallet_example,
}
);
// These `impl` blocks specify the parameters of each pallet's `trait Config`.
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
// These `impl` blocks specify the parameters of each pezpallet's `trait Config`.
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Self>;
}
impl pallet_example::Config for Runtime {
impl pezpallet_example::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type ValueParameter = ConstU32<42>;
const ANOTHER_VALUE_PARAMETER: u32 = 42;
+41 -41
View File
@@ -4,7 +4,7 @@
//! start building on the [Pezkuwi network](https://pezkuwichain.io/), a scalable, multi-chain
//! blockchain platform that enables different blockchains to securely interoperate.
//!
//! [![StackExchange](https://img.shields.io/badge/StackExchange-Polkadot%20and%20Substrate-222222?logo=stackexchange)](https://exchange.pezkuwichain.app/)
//! [![StackExchange](https://img.shields.io/badge/StackExchange-Polkadot%20and%20Bizinikiwi-222222?logo=stackexchange)](https://exchange.pezkuwichain.app/)
//!
//! [![awesomeDot](https://img.shields.io/badge/polkadot-awesome-e6007a?logo=polkadot)](https://github.com/Awsmdot/awesome-dot)
//! [![wiki](https://img.shields.io/badge/polkadot-wiki-e6007a?logo=polkadot)](https://wiki.network.pezkuwichain.io/)
@@ -20,56 +20,56 @@
//! See:
//!
//! * [`pezkuwi`], to understand what is Pezkuwi as a development platform.
//! * [`substrate`], for an overview of what Substrate as the main blockchain framework of Pezkuwi
//! * [`bizinikiwi`], for an overview of what Bizinikiwi as the main blockchain framework of Pezkuwi
//! SDK.
//! * [`frame`], to learn about how to write blockchain applications aka. "App Chains".
//! * Continue with the [`pezkuwi_sdk_docs`'s "getting started"](crate#getting-started).
//!
//! ## Components
//!
//! #### Substrate
//! #### Bizinikiwi
//!
//! [![Substrate-license](https://img.shields.io/badge/License-GPL3%2FApache2.0-blue)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/substrate/LICENSE-APACHE2)
//! [![Bizinikiwi-license](https://img.shields.io/badge/License-GPL3%2FApache2.0-blue)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/bizinikiwi/LICENSE-APACHE2)
//! [![GitHub
//! Repo](https://img.shields.io/badge/github-substrate-2324CC85)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/substrate)
//! Repo](https://img.shields.io/badge/github-bizinikiwi-2324CC85)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/bizinikiwi)
//!
//! [`substrate`] is the base blockchain framework used to power the Pezkuwi SDK. It is a full
//! [`bizinikiwi`] is the base blockchain framework used to power the Pezkuwi SDK. It is a full
//! toolkit to create sovereign blockchains, including but not limited to those which connect to
//! Pezkuwi as teyrchains.
//!
//! #### FRAME
//!
//! [![Substrate-license](https://img.shields.io/badge/License-Apache2.0-blue)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/substrate/LICENSE-APACHE2)
//! [![Bizinikiwi-license](https://img.shields.io/badge/License-Apache2.0-blue)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/bizinikiwi/LICENSE-APACHE2)
//! [![GitHub
//! Repo](https://img.shields.io/badge/github-frame-2324CC85)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/substrate/frame)
//! Repo](https://img.shields.io/badge/github-frame-2324CC85)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/bizinikiwi/pezframe)
//!
//! [`frame`] is the framework used to create Substrate-based application logic, aka. runtimes.
//! [`frame`] is the framework used to create Bizinikiwi-based application logic, aka. runtimes.
//! Learn more about the distinction of a runtime and node in
//! [`reference_docs::wasm_meta_protocol`].
//!
//! #### Cumulus
//! #### Pezcumulus
//!
//! [![Cumulus-license](https://img.shields.io/badge/License-GPL3-blue)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/cumulus/LICENSE)
//! [![Pezcumulus-license](https://img.shields.io/badge/License-GPL3-blue)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/pezcumulus/LICENSE)
//! [![GitHub
//! Repo](https://img.shields.io/badge/github-cumulus-white)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/cumulus)
//! Repo](https://img.shields.io/badge/github-pezcumulus-white)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/pezcumulus)
//!
//! [`cumulus`] transforms FRAME-based runtimes into Pezkuwi-compatible teyrchain runtimes, and
//! Substrate-based nodes into Pezkuwi/Teyrchain-compatible nodes.
//! [`pezcumulus`] transforms FRAME-based runtimes into Pezkuwi-compatible teyrchain runtimes, and
//! Bizinikiwi-based nodes into Pezkuwi/Teyrchain-compatible nodes.
//!
//! #### XCM
//!
//! [![XCM-license](https://img.shields.io/badge/License-GPL3-blue)](https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/LICENSE)
//! [![XCM-license](https://img.shields.io/badge/License-GPL3-blue)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/pezkuwi/LICENSE)
//! [![GitHub
//! Repo](https://img.shields.io/badge/github-XCM-e6007a?logo=polkadot)](https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/xcm)
//! Repo](https://img.shields.io/badge/github-XCM-e6007a?logo=polkadot)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/pezkuwi/xcm)
//!
//! [`xcm`], short for "cross consensus message", is the primary format that is used for
//! communication between teyrchains, but is intended to be extensible to other use cases as well.
//!
//! #### Pezkuwi
//!
//! [![Pezkuwi-license](https://img.shields.io/badge/License-GPL3-blue)](https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/LICENSE)
//! [![Pezkuwi-license](https://img.shields.io/badge/License-GPL3-blue)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/pezkuwi/LICENSE)
//! [![GitHub
//! Repo](https://img.shields.io/badge/github-polkadot-e6007a?logo=polkadot)](https://github.com/paritytech/polkadot-sdk/blob/master/polkadot)
//! Repo](https://img.shields.io/badge/github-polkadot-e6007a?logo=polkadot)](https://github.com/pezkuwichain/pezkuwi-sdk/blob/master/pezkuwi)
//!
//! [`pezkuwi`] is an implementation of a Pezkuwi node in Rust, by `@paritytech`. The Pezkuwi
//! runtimes are located under the
@@ -89,35 +89,35 @@
//! `benchmark` subcommand that does the same.
//! * [`chain_spec_builder`]: Utility to build chain-specs Nodes typically contain a `build-spec`
//! subcommand that does the same.
//! * [`subkey`]: Substrate's key management utility.
//! * [`substrate-node`](node_cli) is an extensive substrate node that contains the superset of all
//! runtime and node side features. The corresponding runtime, called [`kitchensink_runtime`]
//! contains all of the modules that are provided with `FRAME`. This node and runtime is only used
//! for testing and demonstration.
//! * [`pez_subkey`]: Bizinikiwi's key management utility.
//! * [`bizinikiwi-node`](node_cli) is an extensive bizinikiwi node that contains the superset of
//! all runtime and node side features. The corresponding runtime, called
//! [`pez_kitchensink_runtime`] contains all of the modules that are provided with `FRAME`. This
//! node and runtime is only used for testing and demonstration.
//!
//! ### Summary
//!
//! The following diagram summarizes how some of the components of Pezkuwi SDK work together:
#![doc = simple_mermaid::mermaid!("../../../mermaid/pezkuwi_sdk_substrate.mmd")]
#![doc = simple_mermaid::mermaid!("../../../mermaid/pezkuwi_sdk_bizinikiwi.mmd")]
//!
//! A Substrate-based chain is a blockchain composed of a runtime and a node. As noted above, the
//! A Bizinikiwi-based chain is a blockchain composed of a runtime and a node. As noted above, the
//! runtime is the application logic of the blockchain, and the node is everything else.
//! See [`reference_docs::wasm_meta_protocol`] for an in-depth explanation of this. The
//! former is built with [`frame`], and the latter is built with rest of Substrate.
//! former is built with [`frame`], and the latter is built with rest of Bizinikiwi.
//!
//! > You can think of a Substrate-based chain as a white-labeled blockchain.
//! > You can think of a Bizinikiwi-based chain as a white-labeled blockchain.
#![doc = simple_mermaid::mermaid!("../../../mermaid/pezkuwi_sdk_pezkuwi.mmd")]
//! Pezkuwi is itself a Substrate-based chain, composed of the exact same two components. It has
//! Pezkuwi is itself a Bizinikiwi-based chain, composed of the exact same two components. It has
//! specialized logic in both the node and the runtime side, but it is not "special" in any way.
//!
//! A teyrchain is a "special" Substrate-based chain, whereby both the node and the runtime
//! components have became "Pezkuwi-aware" using Cumulus.
//! A teyrchain is a "special" Bizinikiwi-based chain, whereby both the node and the runtime
//! components have became "Pezkuwi-aware" using Pezcumulus.
#![doc = simple_mermaid::mermaid!("../../../mermaid/pezkuwi_sdk_teyrchain.mmd")]
//!
//! ## Notable Upstream Crates
//!
//! - [`parity-scale-codec`](https://github.com/paritytech/parity-scale-codec)
//! - [`parity-db`](https://github.com/paritytech/parity-db)
//! - [`parity-scale-codec`](https://github.com/pezkuwichain/parity-scale-codec)
//! - [`parity-db`](https://github.com/pezkuwichain/parity-db)
//! - [`trie`](https://github.com/paritytech/trie)
//! - [`parity-common`](https://github.com/paritytech/parity-common)
//!
@@ -131,27 +131,27 @@
//! * [Starknet's Madara Sequencer](https://github.com/keep-starknet-strange/madara)
//! * [Polymesh](https://polymesh.network/)
//!
//! [`substrate`]: crate::pezkuwi_sdk::substrate
//! [`bizinikiwi`]: crate::pezkuwi_sdk::bizinikiwi
//! [`frame`]: crate::pezkuwi_sdk::frame_runtime
//! [`cumulus`]: crate::pezkuwi_sdk::cumulus
//! [`pezcumulus`]: crate::pezkuwi_sdk::pezcumulus
//! [`pezkuwi`]: crate::pezkuwi_sdk::pezkuwi
//! [`xcm`]: crate::pezkuwi_sdk::xcm
//! [`frame-omni-bencher`]: https://crates.io/crates/frame-omni-bencher
//! [`pezkuwi-teyrchain-bin`]: https://crates.io/crates/polkadot-parachain-bin
//! [`pezkuwi-omni-node`]: https://crates.io/crates/polkadot-omni-node
/// Learn about Cumulus, the framework that transforms [`substrate`]-based chains into
/// [`pezkuwi`]-enabled teyrchains.
pub mod cumulus;
/// Learn about FRAME, the framework used to build Substrate runtimes.
/// Learn about Bizinikiwi, the main blockchain framework used in the Pezkuwi ecosystem.
pub mod bizinikiwi;
/// Learn about FRAME, the framework used to build Bizinikiwi runtimes.
pub mod frame_runtime;
/// Learn about Pezcumulus, the framework that transforms [`bizinikiwi`]-based chains into
/// [`pezkuwi`]-enabled teyrchains.
pub mod pezcumulus;
/// Learn about Pezkuwi as a platform.
pub mod pezkuwi;
/// Learn about different ways through which smart contracts can be utilized on top of Substrate,
/// Learn about different ways through which smart contracts can be utilized on top of Bizinikiwi,
/// and in the Pezkuwi ecosystem.
pub mod smart_contracts;
/// Learn about Substrate, the main blockchain framework used in the Pezkuwi ecosystem.
pub mod substrate;
/// Index of all the templates that can act as first scaffold for a new project.
pub mod templates;
/// Learn about XCM, the de-facto communication language between different consensus systems.
@@ -0,0 +1,130 @@
//! # Pezcumulus
//!
//! Bizinikiwi provides a framework ([FRAME]) through which a blockchain node and runtime can easily
//! be created. Pezcumulus aims to extend the same approach to creation of Pezkuwi teyrchains.
//!
//! > Pezcumulus clouds are shaped sort of like dots; together they form a system that is intricate,
//! > beautiful and functional.
//!
//! ## Example: Runtime
//!
//! A Pezcumulus-based runtime is fairly similar to other [FRAME]-based runtimes. Most notably, the
//! following changes are applied to a normal FRAME-based runtime to make it a Pezcumulus-based
//! runtime:
//!
//! #### Pezcumulus Pallets
//!
//! A teyrchain runtime should use a number of pallets that are provided by Pezcumulus and
//! Bizinikiwi. Notably:
//!
//! - [`pezframe-system`](pezframe::prelude::pezframe_system), like all FRAME-based runtimes.
//! - [`pezcumulus_pezpallet_teyrchain_system`]
//! - [`teyrchain_info`]
#![doc = docify::embed!("./src/pezkuwi_sdk/pezcumulus.rs", system_pallets)]
//!
//! Given that all Pezcumulus-based runtimes use a simple Aura-based consensus mechanism, the
//! following pallets also need to be added:
//!
//! - [`pezpallet_timestamp`]
//! - [`pezpallet_aura`]
//! - [`pezcumulus_pezpallet_aura_ext`]
#![doc = docify::embed!("./src/pezkuwi_sdk/pezcumulus.rs", consensus_pallets)]
//!
//!
//! Finally, a separate macro, similar to
//! [`impl_runtime_api`](pezframe::runtime::prelude::impl_runtime_apis), which creates the default set
//! of runtime APIs, will generate the teyrchain runtime's validation runtime API, also known as
//! teyrchain validation function (PVF). Without this API, the relay chain is unable to validate
//! blocks produced by our teyrchain.
#![doc = docify::embed!("./src/pezkuwi_sdk/pezcumulus.rs", validate_block)]
//!
//! ---
//!
//! [FRAME]: crate::pezkuwi_sdk::frame_runtime
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(rustdoc::private_intra_doc_links)]
#[cfg(test)]
mod tests {
mod runtime {
pub use pezframe::{
deps::pezsp_consensus_aura::sr25519::AuthorityId as AuraId, prelude::*,
runtime::prelude::*, testing_prelude::*,
};
#[docify::export(CR)]
construct_runtime!(
pub enum Runtime {
// system-level pallets.
System: pezframe_system,
Timestamp: pezpallet_timestamp,
TeyrchainSystem: pezcumulus_pezpallet_teyrchain_system,
TeyrchainInfo: teyrchain_info,
// teyrchain consensus support -- mandatory.
Aura: pezpallet_aura,
AuraExt: pezcumulus_pezpallet_aura_ext,
}
);
#[docify::export]
mod system_pallets {
use super::*;
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Self>;
type OnSetCode = pezcumulus_pezpallet_teyrchain_system::TeyrchainSetCode<Self>;
}
impl pezcumulus_pezpallet_teyrchain_system::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type OnSystemEvent = ();
type SelfParaId = teyrchain_info::Pezpallet<Runtime>;
type OutboundXcmpMessageSource = ();
type XcmpMessageHandler = ();
type ReservedDmpWeight = ();
type ReservedXcmpWeight = ();
type CheckAssociatedRelayNumber =
pezcumulus_pezpallet_teyrchain_system::RelayNumberMonotonicallyIncreases;
type ConsensusHook = pezcumulus_pezpallet_aura_ext::FixedVelocityConsensusHook<
Runtime,
6000, // relay chain block time
1,
1,
>;
type WeightInfo = ();
type DmpQueue = pezframe::traits::EnqueueWithOrigin<(), pezsp_core::ConstU8<0>>;
type RelayParentOffset = ConstU32<0>;
}
impl teyrchain_info::Config for Runtime {}
}
#[docify::export]
mod consensus_pallets {
use super::*;
impl pezpallet_aura::Config for Runtime {
type AuthorityId = AuraId;
type DisabledValidators = ();
type MaxAuthorities = ConstU32<100_000>;
type AllowMultipleBlocksPerSlot = ConstBool<false>;
type SlotDuration = pezpallet_aura::MinimumPeriodTimesTwo<Self>;
}
#[docify::export(timestamp)]
#[derive_impl(pezpallet_timestamp::config_preludes::TestDefaultConfig)]
impl pezpallet_timestamp::Config for Runtime {}
impl pezcumulus_pezpallet_aura_ext::Config for Runtime {}
}
#[docify::export(validate_block)]
pezcumulus_pezpallet_teyrchain_system::register_validate_block! {
Runtime = Runtime,
BlockExecutor = pezcumulus_pezpallet_aura_ext::BlockExecutor::<Runtime, Executive>,
}
}
}
@@ -56,8 +56,8 @@
//! security as the Relay Chain.
//! Learn about this process called [Approval Checking](https://pezkuwichain.io/blog/polkadot-v1-0-sharding-and-economic-security#approval-checking-and-finality).
//! * A framework to build blockchains: In order to materialize the ecosystem of teyrchains, an easy
//! blockchain framework must exist. This is [Substrate](crate::pezkuwi_sdk::substrate),
//! [FRAME](crate::pezkuwi_sdk::frame_runtime) and [Cumulus](crate::pezkuwi_sdk::cumulus).
//! blockchain framework must exist. This is [Bizinikiwi](crate::pezkuwi_sdk::bizinikiwi),
//! [FRAME](crate::pezkuwi_sdk::frame_runtime) and [Pezcumulus](crate::pezkuwi_sdk::pezcumulus).
//! * A communication language between blockchains: In order for these blockchains to communicate,
//! they need a shared language. [XCM](crate::pezkuwi_sdk::xcm) is one such language, and the one
//! that is most endorsed in the Pezkuwi ecosystem.
@@ -1,8 +1,8 @@
//! # Smart Contracts
//!
//! TODO: @cmichi <https://github.com/pezkuwichain/pezkuwi-sdk/issues/161>
//! TODO: @cmichi <https://github.com/pezkuwichain/pezkuwi-sdk/issues/304>
//!
//! - WASM and EVM based, pallet-contracts and pallet-evm.
//! - WASM and EVM based, pezpallet-contracts and pezpallet-evm.
//! - single-daap-chain, transition from ink! to FRAME.
//! - Link to `use.ink`
//! - Link to [`crate::reference_docs::runtime_vs_smart_contract`].
@@ -1,137 +0,0 @@
//! # Substrate
//!
//! Substrate is a Rust framework for building blockchains in a modular and extensible way. While in
//! itself un-opinionated, it is the main engine behind the Pezkuwi ecosystem.
//!
//! ## Overview, Philosophy
//!
//! Substrate approaches blockchain development with an acknowledgement of a few self-evident
//! truths:
//!
//! 1. Society and technology evolves.
//! 2. Humans are fallible.
//!
//! This makes the task of designing a correct, safe and long-lasting blockchain system hard.
//!
//! Nonetheless, in strive towards achieving this goal, Substrate embraces the following:
//!
//! 1. Use of **Rust** as a modern and safe programming language, which limits human error through
//! various means, most notably memory and type safety.
//! 2. Substrate is written from the ground-up with a *generic, modular and extensible* design. This
//! ensures that software components can be easily swapped and upgraded. Examples of this is
//! multiple consensus mechanisms provided by Substrate, as listed below.
//! 3. Lastly, the final blockchain system created with the above properties needs to be
//! upgradeable. In order to achieve this, Substrate is designed as a meta-protocol, whereby the
//! application logic of the blockchain (called "Runtime") is encoded as a WASM blob, and is
//! stored in the state. The rest of the system (called "node") acts as the executor of the WASM
//! blob.
//!
//! In essence, the meta-protocol of all Substrate based chains is the "Runtime as WASM blob"
//! accord. This enables the Runtime to become inherently upgradeable, crucially without [forks](https://en.wikipedia.org/wiki/Fork_(blockchain)). The
//! upgrade is merely a matter of the WASM blob being changed in the state, which is, in principle,
//! same as updating an account's balance. Learn more about this in detail in
//! [`crate::reference_docs::wasm_meta_protocol`].
//!
//! > A great analogy for substrate is the following: Substrate node is a gaming console, and a WASM
//! > runtime, possibly created with FRAME is the game being inserted into the console.
//!
//! [`frame`], Substrate's default runtime development library, takes the above safety practices
//! even further by embracing a declarative programming model whereby correctness is enhanced and
//! the system is highly configurable through parameterization. Learn more about this in
//! [`crate::reference_docs::trait_based_programming`].
//!
//! ## How to Get Started
//!
//! Substrate offers different options at the spectrum of technical freedom <-> development ease.
//!
//! * The easiest way to use Substrate is to use one of the templates (some of which listed at
//! [`crate::pezkuwi_sdk::templates`]) and only tweak the parameters of the runtime or node. This
//! allows you to launch a blockchain in minutes, but is limited in technical freedom.
//! * Next, most developers wish to develop their custom runtime modules, for which the de-facto way
//! is [`frame`](crate::pezkuwi_sdk::frame_runtime).
//! * Finally, Substrate is highly configurable at the node side as well, but this is the most
//! technically demanding.
//!
//! > A notable Substrate-based blockchain that has built both custom FRAME pallets and custom
//! > node-side components is <https://github.com/Cardinal-Cryptography/aleph-node>.
#![doc = simple_mermaid::mermaid!("../../../mermaid/substrate_dev.mmd")]
//!
//! ## Structure
//!
//! Substrate contains a large number of crates, therefore it is useful to have an overview of what
//! they are, and how they are organized. In broad terms, these crates are divided into three
//! categories:
//!
//! * `sc-*` (short for *Substrate-client*) crates, located under `./client` folder. These are all
//! the crates that lead to the node software. Notable examples are [`sc_network`], various
//! consensus crates, RPC ([`sc_rpc_api`]) and database ([`sc_client_db`]), all of which are
//! expected to reside in the node side.
//! * `sp-*` (short for *substrate-primitives*) crates, located under `./primitives` folder. These
//! are crates that facilitate both the node and the runtime, but are not opinionated about what
//! framework is using for building the runtime. Notable examples are [`sp_api`] and [`sp_io`],
//! which form the communication bridge between the node and runtime.
//! * `pallet-*` and `frame-*` crates, located under `./frame` folder. These are the crates related
//! to FRAME. See [`frame`] for more information.
//!
//! ### WASM Build
//!
//! Many of the Substrate crates, such as entire `sp-*`, need to compile to both WASM (when a WASM
//! runtime is being generated) and native (for example, when testing). To achieve this, Substrate
//! follows the convention of the Rust community, and uses a `feature = "std"` to signify that a
//! crate is being built with the standard library, and is built for native. Otherwise, it is built
//! for `no_std`.
//!
//! This can be summarized in `#![cfg_attr(not(feature = "std"), no_std)]`, which you can often find
//! in any Substrate-based runtime.
//!
//! Substrate-based runtimes use [`substrate_wasm_builder`] in their `build.rs` to automatically
//! build their WASM files as a part of normal build command (e.g. `cargo build`). Once built, the
//! wasm file is placed in `./target/{debug|release}/wbuild/{runtime_name}/{runtime_name}.wasm`.
//!
//! In order to ensure that the WASM build is **deterministic**, the [Substrate Runtime Toolbox (srtool)](https://github.com/paritytech/srtool) can be used.
//!
//! ### Anatomy of a Binary Crate
//!
//! From the above, [`node_cli`]/[`kitchensink_runtime`] and `node-template` are essentially
//! blueprints of a Substrate-based project, as the name of the latter is implying. Each
//! Substrate-based project typically contains the following:
//!
//! * Under `./runtime`, a `./runtime/src/lib.rs` which is the top level runtime amalgamator file.
//! This file typically contains the [`frame::runtime::prelude::construct_runtime`] and
//! [`frame::runtime::prelude::impl_runtime_apis`] macro calls, which is the final definition of a
//! runtime.
//!
//! * Under `./node`, a `main.rs`, which is the starting point, and a `./service.rs`, which contains
//! all the node side components. Skimming this file yields an overview of the networking,
//! database, consensus and similar node side components.
//!
//! > The above two are conventions, not rules.
//!
//! > See <https://github.com/pezkuwichain/pezkuwi-sdk/issues/94> for an update on how the node side
//! > components are being amalgamated.
//!
//! ## Teyrchain?
//!
//! As noted above, Substrate is the main engine behind the Pezkuwi ecosystem. One of the ways
//! through which Pezkuwi can be utilized is by building "teyrchains", blockchains that are
//! connected to Pezkuwi's shared security.
//!
//! To build a teyrchain, one could use [Cumulus](crate::pezkuwi_sdk::cumulus), the library on
//! top of Substrate, empowering any substrate-based chain to be a Pezkuwi teyrchain.
//!
//! ## Where To Go Next?
//!
//! Additional noteworthy crates within substrate:
//!
//! - RPC APIs of a Substrate node: [`sc_rpc_api`]/[`sc_rpc`]
//! - CLI Options of a Substrate node: [`sc_cli`]
//! - All of the consensus related crates provided by Substrate:
//! - [`sc_consensus_aura`]
//! - [`sc_consensus_babe`]
//! - [`sc_consensus_grandpa`]
//! - [`sc_consensus_beefy`] (TODO: @adrian, add some high level docs <https://github.com/pezkuwichain/pezkuwi-sdk/issues/162>)
//! - [`sc_consensus_manual_seal`]
//! - [`sc_consensus_pow`]
#[doc(hidden)]
pub use crate::pezkuwi_sdk;
@@ -9,11 +9,11 @@
//!
//! The following templates are maintained as a part of the `pezkuwi-sdk` repository:
//!
//! - [`minimal-template`](https://github.com/pezkuwichain/pezkuwi-sdk/issues/25): A minimal
//! - [`minimal-template`](https://github.com/pezkuwichain/pezkuwi-sdk/issues/195): A minimal
//! template that contains the least amount of features to be a functioning blockchain. Suitable
//! for learning and testing.
//! - [`solochain-template`](https://github.com/pezkuwichain/pezkuwi-sdk/issues/25): Formerly known
//! as "substrate-node-template", is a white-labeled substrate-based blockchain (aka. solochain)
//! - [`solochain-template`](https://github.com/pezkuwichain/pezkuwi-sdk/issues/195): Formerly known
//! as "bizinikiwi-node-template", is a white-labeled bizinikiwi-based blockchain (aka. solochain)
//! that contains moderate features, such as a basic consensus engine and some FRAME pallets. This
//! template can act as a good starting point for those who want to launch a solochain.
//! - [`teyrchain-template`](https://github.com/pezkuwichain/pezkuwi-sdk-teyrchain-template):
+5 -5
View File
@@ -5,7 +5,7 @@
//!
//! ## Overview
//!
//! XCM is a standard, specification of which lives in the [xcm format repo](https://github.com/paritytech/xcm-format).
//! XCM is a standard, specification of which lives in the [xcm format repo](https://github.com/polkadot-fellows/xcm-format).
//! It's agnostic both in programming language and blockchain platform, which means it could be used
//! in Rust in Pezkuwi, or in Go or C++ in any other platform like Cosmos or Ethereum.
//!
@@ -30,15 +30,15 @@
//!
//! ## Implementation
//!
//! A ready-to-use Rust implementation lives in the [pezkuwi-sdk repo](https://github.com/paritytech/polkadot-sdk/tree/master/polkadot/xcm),
//! A ready-to-use Rust implementation lives in the [pezkuwi-sdk repo](https://github.com/pezkuwichain/pezkuwi-sdk/tree/main/pezkuwi/xcm),
//! but will be moved to its own repo in the future.
//!
//! Its main components are:
//! - [`xcm`](::xcm): The definition of the basic types and instructions.
//! - [`xcm_executor`]: An implementation of the virtual machine to execute instructions.
//! - [`pallet_xcm`]: A FRAME pallet for interacting with the executor.
//! - [`pezpallet_xcm`]: A FRAME pezpallet for interacting with the executor.
//! - [`xcm_builder`]: A collection of types to configure the executor.
//! - [`xcm_simulator`]: A playground for trying out different XCM programs and executor
//! - [`xcm_pez_simulator`]: A playground for trying out different XCM programs and executor
//! configurations.
//!
//! ## Example
@@ -49,7 +49,7 @@
//!
//! ## Get started
//!
//! To learn how it works and to get started, go to the [XCM docs](xcm_docs).
//! To learn how it works and to get started, go to the [XCM docs](xcm_pez_docs).
#[cfg(test)]
mod tests {
@@ -1,6 +1,6 @@
//! # State Transition Function
//!
//! This document briefly explains how in the context of Substrate-based blockchains, we view the
//! This document briefly explains how in the context of Bizinikiwi-based blockchains, we view the
//! blockchain as a **decentralized state transition function**.
//!
//! Recall that a blockchain's main purpose is to help a permissionless set of entities to agree on
@@ -14,7 +14,7 @@
//! function*.
#![doc = simple_mermaid::mermaid!("../../../mermaid/stf_simple.mmd")]
//!
//! In Substrate-based blockchains, the state transition function is called the *Runtime*. This is
//! In Bizinikiwi-based blockchains, the state transition function is called the *Runtime*. This is
//! explained further in [`crate::reference_docs::wasm_meta_protocol`].
//!
//! With this in mind, we can paint a complete picture of a blockchain as a state machine:
@@ -10,52 +10,54 @@
//! interact with the runtime in order to build the genesis state.
//!
//! For more information on chain specification and its properties, refer to
//! [`sc_chain_spec#from-initial-state-to-raw-genesis`].
//! [`pezsc_chain_spec#from-initial-state-to-raw-genesis`].
//!
//! The initial genesis state can be provided in the following formats:
//! - full
//! - patch
//! - raw
//!
//! Each of the formats is explained in [_chain-spec-format_][`sc_chain_spec#chain-spec-formats`].
//! Each of the formats is explained in
//! [_chain-spec-format_][`pezsc_chain_spec#chain-spec-formats`].
//!
//!
//! # `GenesisConfig` for `pallet`
//! # `GenesisConfig` for `pezpallet`
//!
//! Every frame pallet may have its initial state which is defined by the `GenesisConfig` internal
//! struct. It is a regular Rust struct, annotated with the [`pallet::genesis_config`] attribute.
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pallet_bar_GenesisConfig)]
//! Every frame pezpallet may have its initial state which is defined by the `GenesisConfig`
//! internal struct. It is a regular Rust struct, annotated with the [`pezpallet::genesis_config`]
//! attribute.
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pezpallet_bar_GenesisConfig)]
//!
//! The struct shall be defined within the pallet `mod`, as in the following code:
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pallet_bar)]
//! The struct shall be defined within the pezpallet `mod`, as in the following code:
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pezpallet_bar)]
//!
//! The initial state conveyed in the `GenesisConfig` struct is transformed into state storage
//! items by means of the [`BuildGenesisConfig`] trait, which shall be implemented for the pallet's
//! `GenesisConfig` struct. The [`pallet::genesis_build`] attribute shall be attached to the `impl`
//! block:
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pallet_bar_build)]
//! items by means of the [`BuildGenesisConfig`] trait, which shall be implemented for the
//! pezpallet's `GenesisConfig` struct. The [`pezpallet::genesis_build`] attribute shall be attached
//! to the `impl` block:
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pezpallet_bar_build)]
//!
//! `GenesisConfig` may also contain more complicated types, including nested structs or enums, as
//! in the example for `pallet_foo`:
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pallet_foo_GenesisConfig)]
//! in the example for `pezpallet_foo`:
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pezpallet_foo_GenesisConfig)]
//!
//! Note that [`serde`] attributes can be used to control how the data
//! structures are stored into JSON. In the following example, the [`sp_core::bytes`] function is
//! structures are stored into JSON. In the following example, the [`pezsp_core::bytes`] function is
//! used to serialize the `values` field.
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", SomeFooData2)]
//!
//! Please note that fields of `GenesisConfig` may not be directly mapped to storage items. In the
//! following example, the initial struct fields are used to compute (sum) the value that will be
//! stored in the state as `ProcessedEnumValue`:
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pallet_foo_build)]
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/pallets.rs", pezpallet_foo_build)]
//!
//! # `GenesisConfig` for `runtimes`
//!
//! The runtime genesis config struct consists of configs for every pallet. For the [_demonstration
//! runtime_][`chain_spec_guide_runtime`] used in this guide, it consists of `SystemConfig`,
//! `BarConfig`, and `FooConfig`. This structure was automatically generated by a macro and it can
//! be sneak-peeked here: [`RuntimeGenesisConfig`]. For further reading on generated runtime
//! types, refer to [`frame_runtime_types`].
//! The runtime genesis config struct consists of configs for every pezpallet. For the
//! [_demonstration runtime_][`pez_chain_spec_guide_runtime`] used in this guide, it consists of
//! `SystemConfig`, `BarConfig`, and `FooConfig`. This structure was automatically generated by a
//! macro and it can be sneak-peeked here: [`RuntimeGenesisConfig`]. For further reading on
//! generated runtime types, refer to [`frame_runtime_types`].
//!
//! The macro automatically adds an attribute that renames all the fields to [`camelCase`]. It is a
//! good practice to add it to nested structures too, to have the naming of the JSON keys consistent
@@ -80,16 +82,16 @@
//! ## Implementing `GenesisBuilder` for runtime
//!
//! The runtime exposes a dedicated runtime API for interacting with its genesis config:
//! [`sp_genesis_builder::GenesisBuilder`]. The implementation shall be provided within
//! the [`sp_api::impl_runtime_apis`] macro, typically making use of some helpers provided:
//! [`pezsp_genesis_builder::GenesisBuilder`]. The implementation shall be provided within
//! the [`pezsp_api::impl_runtime_apis`] macro, typically making use of some helpers provided:
//! [`build_state`], [`get_preset`].
//! A typical implementation of [`sp_genesis_builder::GenesisBuilder`] looks as follows:
//! A typical implementation of [`pezsp_genesis_builder::GenesisBuilder`] looks as follows:
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/runtime.rs", runtime_impl)]
//!
//! Please note that two functions are customized: `preset_names` and `get_preset`. The first one
//! just provides a `Vec` of the names of supported presets, while the latter delegates the call
//! to a function that maps the name to an actual preset:
//! [`chain_spec_guide_runtime::presets::get_builtin_preset`]
//! [`pez_chain_spec_guide_runtime::presets::get_builtin_preset`]
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/src/presets.rs", get_builtin_preset)]
//!
//! ## Genesis state presets for runtime
@@ -150,27 +152,27 @@
//! recommended for production chains.
//!
//! For a detailed description of how the raw format is built, please refer to
//! [_chain-spec-raw-genesis_][`sc_chain_spec#from-initial-state-to-raw-genesis`]. Plain and
//! [_chain-spec-raw-genesis_][`pezsc_chain_spec#from-initial-state-to-raw-genesis`]. Plain and
//! corresponding raw examples of chain-spec are given in
//! [_chain-spec-examples_][`sc_chain_spec#json-chain-specification-example`].
//! [_chain-spec-examples_][`pezsc_chain_spec#json-chain-specification-example`].
//! The [`chain_spec_builder`] util supports building the raw storage.
//!
//! # Interacting with the tool
//!
//! The [`chain_spec_builder`] util allows interaction with the runtime in order to list or display
//! presets and build the chain specification file. It is possible to use the tool with the
//! [_demonstration runtime_][`chain_spec_guide_runtime`]. To build the required packages, just run
//! the following command:
//! [_demonstration runtime_][`pez_chain_spec_guide_runtime`]. To build the required packages, just
//! run the following command:
//!
//! ```ignore
//! cargo build -p staging-chain-spec-builder -p chain-spec-guide-runtime --release
//! cargo build -p pezstaging-chain-spec-builder -p pez-chain-spec-guide-runtime --release
//! ```
//!
//! The `chain-spec-builder` util can also be installed with `cargo install`:
//!
//! ```ignore
//! cargo install staging-chain-spec-builder
//! cargo build -p chain-spec-guide-runtime --release
//! cargo install pezstaging-chain-spec-builder
//! cargo build -p pez-chain-spec-guide-runtime --release
//! ```
//! Here are some examples in the form of rust tests:
//! ## Listing available preset names:
@@ -183,18 +185,18 @@
#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", cmd_generate_para_chain_spec)]
//!
//! [`RuntimeGenesisConfig`]:
//! chain_spec_guide_runtime::runtime::RuntimeGenesisConfig
//! pez_chain_spec_guide_runtime::runtime::RuntimeGenesisConfig
//! [`FooStruct`]:
//! chain_spec_guide_runtime::pallets::FooStruct
//! [`impl_runtime_apis`]: frame::runtime::prelude::impl_runtime_apis
//! [`build_state`]: frame_support::genesis_builder_helper::build_state
//! [`get_preset`]: frame_support::genesis_builder_helper::get_preset
//! [`pallet::genesis_build`]: frame_support::pallet_macros::genesis_build
//! [`pallet::genesis_config`]: frame_support::pallet_macros::genesis_config
//! [`build_struct_json_patch`]: frame_support::build_struct_json_patch
//! [`BuildGenesisConfig`]: frame_support::traits::BuildGenesisConfig
//! pez_chain_spec_guide_runtime::pallets::FooStruct
//! [`impl_runtime_apis`]: pezframe::runtime::prelude::impl_runtime_apis
//! [`build_state`]: pezframe_support::genesis_builder_helper::build_state
//! [`get_preset`]: pezframe_support::genesis_builder_helper::get_preset
//! [`pezpallet::genesis_build`]: pezframe_support::pezpallet_macros::genesis_build
//! [`pezpallet::genesis_config`]: pezframe_support::pezpallet_macros::genesis_config
//! [`build_struct_json_patch`]: pezframe_support::build_struct_json_patch
//! [`BuildGenesisConfig`]: pezframe_support::traits::BuildGenesisConfig
//! [`serde`]: https://serde.rs/field-attrs.html
//! [`get_storage_for_patch`]: sc_chain_spec::GenesisConfigBuilderRuntimeCaller::get_storage_for_patch
//! [`GenesisBuilder::get_preset`]: sp_genesis_builder::GenesisBuilder::get_preset
//! [`get_storage_for_patch`]: pezsc_chain_spec::GenesisConfigBuilderRuntimeCaller::get_storage_for_patch
//! [`GenesisBuilder::get_preset`]: pezsp_genesis_builder::GenesisBuilder::get_preset
//! [`deny_unknown_fields`]: https://serde.rs/container-attrs.html#deny_unknown_fields
//! [`camelCase`]: https://serde.rs/container-attrs.html#rename_all
@@ -1,5 +1,5 @@
[package]
name = "chain-spec-guide-runtime"
name = "pez-chain-spec-guide-runtime"
description = "A minimal runtime for chain spec guide"
version = "0.0.0"
license = "MIT-0"
@@ -8,57 +8,77 @@ homepage.workspace = true
repository.workspace = true
edition.workspace = true
publish = false
documentation.workspace = true
[dependencies]
codec = { workspace = true }
docify = { workspace = true }
frame-support = { workspace = true }
pezframe-support = { workspace = true }
pezframe-system = { workspace = true }
scale-info = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
# this is a frame-based runtime, thus importing `frame` with runtime feature enabled.
frame = { features = ["experimental", "runtime"], workspace = true }
pezframe = { features = ["experimental", "runtime"], workspace = true }
# genesis builder that allows us to interact with runtime genesis config
sp-application-crypto = { features = ["serde"], workspace = true }
sp-core = { workspace = true }
sp-genesis-builder = { workspace = true }
sp-keyring = { workspace = true }
sp-runtime = { features = ["serde"], workspace = true }
pezsp-api = { workspace = true }
pezsp-application-crypto = { features = ["serde"], workspace = true }
pezsp-core = { workspace = true }
pezsp-genesis-builder = { workspace = true }
pezsp-keyring = { workspace = true }
pezsp-runtime = { features = ["serde"], workspace = true }
[dev-dependencies]
cmd_lib = { workspace = true }
sc-chain-spec = { workspace = true, default-features = true }
pezsc-chain-spec = { workspace = true, default-features = true }
[build-dependencies]
substrate-wasm-builder = { optional = true, workspace = true, default-features = true }
bizinikiwi-wasm-builder = { optional = true, workspace = true, default-features = true }
[features]
default = ["std"]
std = [
"bizinikiwi-wasm-builder",
"bizinikiwi-wasm-builder?/std",
"codec/std",
"pezframe-support/std",
"pezframe-system/std",
"pezframe/std",
"pezsc-chain-spec/std",
"pezsp-api/std",
"pezsp-application-crypto/std",
"pezsp-core/std",
"pezsp-genesis-builder/std",
"pezsp-keyring/std",
"pezsp-runtime/std",
"scale-info/std",
"frame-support/std",
"frame/std",
"sp-application-crypto/std",
"sp-core/std",
"sp-genesis-builder/std",
"sp-keyring/std",
"sp-runtime/std",
"serde/std",
"serde_json/std",
"substrate-wasm-builder",
]
runtime-benchmarks = [
"frame-support/runtime-benchmarks",
"frame/runtime-benchmarks",
"sc-chain-spec/runtime-benchmarks",
"sp-genesis-builder/runtime-benchmarks",
"sp-keyring/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"substrate-wasm-builder?/runtime-benchmarks",
"bizinikiwi-wasm-builder?/runtime-benchmarks",
"pezframe-support/runtime-benchmarks",
"pezframe-system/runtime-benchmarks",
"pezframe/runtime-benchmarks",
"pezsc-chain-spec/runtime-benchmarks",
"pezsp-api/runtime-benchmarks",
"pezsp-application-crypto/runtime-benchmarks",
"pezsp-genesis-builder/runtime-benchmarks",
"pezsp-keyring/runtime-benchmarks",
"pezsp-runtime/runtime-benchmarks",
]
try-runtime = [
"pezframe-support/try-runtime",
"pezframe-system/try-runtime",
"pezframe/try-runtime",
"pezsc-chain-spec/try-runtime",
"pezsp-api/try-runtime",
"pezsp-genesis-builder/try-runtime",
"pezsp-keyring/try-runtime",
"pezsp-runtime/try-runtime",
]
serde = []
experimental = []
tuples-96 = []
@@ -1,6 +1,6 @@
// This file is part of Substrate.
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,6 +18,6 @@
fn main() {
#[cfg(feature = "std")]
{
substrate_wasm_builder::WasmBuilder::build_using_defaults();
bizinikiwi_wasm_builder::WasmBuilder::build_using_defaults();
}
}
@@ -1,6 +1,6 @@
// This file is part of Substrate.
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,6 +1,6 @@
// This file is part of Substrate.
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,32 +18,32 @@
//! Pallets for the chain-spec demo runtime.
use alloc::vec::Vec;
use frame::prelude::*;
use pezframe::prelude::*;
#[docify::export]
#[frame::pallet(dev_mode)]
pub mod pallet_bar {
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet_bar {
use super::*;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[pallet::storage]
#[pezpallet::storage]
pub(super) type InitialAccount<T: Config> = StorageValue<Value = T::AccountId>;
/// Simple `GenesisConfig`.
#[pallet::genesis_config]
#[pezpallet::genesis_config]
#[derive(DefaultNoBound)]
#[docify::export(pallet_bar_GenesisConfig)]
#[docify::export(pezpallet_bar_GenesisConfig)]
pub struct GenesisConfig<T: Config> {
pub initial_account: Option<T::AccountId>,
}
#[pallet::genesis_build]
#[docify::export(pallet_bar_build)]
#[pezpallet::genesis_build]
#[docify::export(pezpallet_bar_build)]
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
/// The storage building function that presents a direct mapping of the initial config
/// values to the storage items.
@@ -80,7 +80,7 @@ pub struct SomeFooData1 {
#[docify::export]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct SomeFooData2 {
#[serde(default, with = "sp_core::bytes")]
#[serde(default, with = "pezsp_core::bytes")]
pub values: Vec<u8>,
}
@@ -94,24 +94,24 @@ pub enum FooEnum {
}
#[docify::export]
#[frame::pallet(dev_mode)]
pub mod pallet_foo {
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet_foo {
use super::*;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[pallet::storage]
#[pezpallet::storage]
pub type ProcessedEnumValue<T> = StorageValue<Value = u64>;
#[pallet::storage]
#[pezpallet::storage]
pub type SomeInteger<T> = StorageValue<Value = u32>;
/// The more sophisticated structure for conveying initial state.
#[docify::export(pallet_foo_GenesisConfig)]
#[pallet::genesis_config]
#[docify::export(pezpallet_foo_GenesisConfig)]
#[pezpallet::genesis_config]
#[derive(DefaultNoBound)]
pub struct GenesisConfig<T: Config> {
pub some_integer: u32,
@@ -121,8 +121,8 @@ pub mod pallet_foo {
pub _phantom: PhantomData<T>,
}
#[pallet::genesis_build]
#[docify::export(pallet_foo_build)]
#[pezpallet::genesis_build]
#[docify::export(pezpallet_foo_build)]
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
/// The build method that indirectly maps an initial config values into the storage items.
fn build(&self) {
@@ -1,6 +1,6 @@
// This file is part of Substrate.
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,10 +22,10 @@ use crate::{
runtime::{BarConfig, FooConfig, RuntimeGenesisConfig},
};
use alloc::vec;
use frame_support::build_struct_json_patch;
use pezframe_support::build_struct_json_patch;
use pezsp_application_crypto::Ss58Codec;
use pezsp_keyring::Sr25519Keyring;
use serde_json::{json, to_string, Value};
use sp_application_crypto::Ss58Codec;
use sp_keyring::Sr25519Keyring;
/// A demo preset with strings only.
pub const PRESET_1: &str = "preset_1";
@@ -120,7 +120,7 @@ fn preset_invalid() -> Value {
///
/// If no preset with given `id` exits `None` is returned.
#[docify::export]
pub fn get_builtin_preset(id: &sp_genesis_builder::PresetId) -> Option<alloc::vec::Vec<u8>> {
pub fn get_builtin_preset(id: &pezsp_genesis_builder::PresetId) -> Option<alloc::vec::Vec<u8>> {
let preset = match id.as_ref() {
PRESET_1 => preset_1(),
PRESET_2 => preset_2(),
@@ -140,7 +140,7 @@ pub fn get_builtin_preset(id: &sp_genesis_builder::PresetId) -> Option<alloc::ve
#[test]
#[docify::export]
fn check_presets() {
let builder = sc_chain_spec::GenesisConfigBuilderRuntimeCaller::<()>::new(
let builder = pezsc_chain_spec::GenesisConfigBuilderRuntimeCaller::<()>::new(
crate::WASM_BINARY.expect("wasm binary shall exists"),
);
assert!(builder.get_storage_for_named_preset(Some(&PRESET_1.to_string())).is_ok());
@@ -152,7 +152,7 @@ fn check_presets() {
#[test]
#[docify::export]
fn invalid_preset_works() {
let builder = sc_chain_spec::GenesisConfigBuilderRuntimeCaller::<()>::new(
let builder = pezsc_chain_spec::GenesisConfigBuilderRuntimeCaller::<()>::new(
crate::WASM_BINARY.expect("wasm binary shall exists"),
);
// Even though a preset contains invalid_key, conversion to raw storage does not fail. This is
@@ -1,6 +1,6 @@
// This file is part of Substrate.
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,25 +22,24 @@
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
use crate::{
pallets::{pallet_bar, pallet_foo},
pallets::{pezpallet_bar, pezpallet_foo},
presets::*,
};
use alloc::{vec, vec::Vec};
use frame::{
deps::frame_support::{
genesis_builder_helper::{build_state, get_preset},
runtime,
},
use pezframe::{
deps::pezframe_support::genesis_builder_helper::{build_state, get_preset},
prelude::*,
runtime::{apis, prelude::*},
runtime::prelude::*,
};
use sp_genesis_builder::PresetId;
use pezsp_api::impl_runtime_apis;
use pezsp_genesis_builder::PresetId;
use pezsp_runtime::traits::Block as BlockT;
/// The runtime version.
#[runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: alloc::borrow::Cow::Borrowed("minimal-template-runtime"),
impl_name: alloc::borrow::Cow::Borrowed("minimal-template-runtime"),
spec_name: alloc::borrow::Cow::Borrowed("pez-minimal-template-runtime"),
impl_name: alloc::borrow::Cow::Borrowed("pez-minimal-template-runtime"),
authoring_version: 1,
spec_version: 0,
impl_version: 1,
@@ -53,7 +52,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
type SignedExtra = ();
// Composes the runtime by adding all the used pallets and deriving necessary types.
#[runtime]
#[frame_construct_runtime]
mod runtime {
/// The main runtime type.
#[runtime::runtime]
@@ -67,48 +66,48 @@ mod runtime {
)]
pub struct Runtime;
/// Mandatory system pallet that should always be included in a FRAME runtime.
#[runtime::pallet_index(0)]
pub type System = frame_system;
/// Mandatory system pezpallet that should always be included in a FRAME runtime.
#[runtime::pezpallet_index(0)]
pub type System = pezframe_system::Pezpallet<Runtime>;
/// Sample pallet 1
#[runtime::pallet_index(1)]
pub type Bar = pallet_bar;
/// Sample pezpallet 1
#[runtime::pezpallet_index(1)]
pub type Bar = pezpallet_bar::Pezpallet<Runtime>;
/// Sample pallet 2
#[runtime::pallet_index(2)]
pub type Foo = pallet_foo;
/// Sample pezpallet 2
#[runtime::pezpallet_index(2)]
pub type Foo = pezpallet_foo::Pezpallet<Runtime>;
}
parameter_types! {
pub const Version: RuntimeVersion = VERSION;
}
/// Implements the types required for the system pallet.
#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
impl frame_system::Config for Runtime {
/// Implements the types required for the system pezpallet.
#[derive_impl(pezframe_system::config_preludes::SolochainDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = Block;
type Version = Version;
}
impl pallet_bar::Config for Runtime {}
impl pallet_foo::Config for Runtime {}
impl pezpallet_bar::Config for Runtime {}
impl pezpallet_foo::Config for Runtime {}
type Block = frame::runtime::types_common::BlockOf<Runtime, SignedExtra>;
type Header = HeaderFor<Runtime>;
type Block = pezframe::runtime::types_common::BlockOf<Runtime, SignedExtra>;
type _Header = HeaderFor<Runtime>;
#[docify::export(runtime_impl)]
impl_runtime_apis! {
impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
impl pezsp_genesis_builder::GenesisBuilder<Block> for Runtime {
fn build_state(config: Vec<u8>) -> pezsp_genesis_builder::Result {
build_state::<RuntimeGenesisConfig>(config)
}
fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
fn get_preset(id: &Option<pezsp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
get_preset::<RuntimeGenesisConfig>(id, get_builtin_preset)
}
fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
fn preset_names() -> Vec<pezsp_genesis_builder::PresetId> {
vec![
PresetId::from(PRESET_1),
PresetId::from(PRESET_2),
@@ -119,9 +118,9 @@ impl_runtime_apis! {
}
}
impl apis::Core<Block> for Runtime {
impl pezsp_api::Core<Block> for Runtime {
fn version() -> RuntimeVersion { VERSION }
fn execute_block(_: <Block as frame::traits::Block>::LazyBlock) { }
fn initialize_block(_: &Header) -> ExtrinsicInclusionMode { ExtrinsicInclusionMode::default() }
fn execute_block(_: <Block as BlockT>::LazyBlock) { }
fn initialize_block(_: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode { ExtrinsicInclusionMode::default() }
}
}
@@ -3,8 +3,8 @@ use serde_json::{json, Value};
use std::str;
fn wasm_file_path() -> &'static str {
chain_spec_guide_runtime::runtime::WASM_BINARY_PATH
.expect("chain_spec_guide_runtime wasm should exist. qed")
pez_chain_spec_guide_runtime::runtime::WASM_BINARY_PATH
.expect("pez_chain_spec_guide_runtime wasm should exist. qed")
}
const CHAIN_SPEC_BUILDER_PATH: &str = "../../../../../target/release/chain-spec-builder";
@@ -24,7 +24,7 @@ macro_rules! bash(
fn get_chain_spec_builder_path() -> &'static str {
run_cmd!(
cargo build --release -p staging-chain-spec-builder --bin chain-spec-builder
cargo build --release -p pezstaging-chain-spec-builder --bin chain-spec-builder
)
.expect("Failed to execute command");
CHAIN_SPEC_BUILDER_PATH
@@ -189,7 +189,7 @@ fn generate_para_chain_spec() {
#[docify::export_content]
fn preset_4_json() {
assert_eq!(
chain_spec_guide_runtime::presets::preset_4(),
pez_chain_spec_guide_runtime::presets::preset_4(),
json!({
"foo": {
"someEnum": {
@@ -1,7 +1,7 @@
//! # Substrate CLI
//! # Bizinikiwi CLI
//!
//! Let's see some examples of typical CLI arguments used when setting up and running a
//! Substrate-based blockchain. We use the [`solochain-template`](https://github.com/pezkuwichain/pezkuwi-sdk/issues/25)
//! Bizinikiwi-based blockchain. We use the [`solochain-template`](https://github.com/pezkuwichain/pezkuwi-sdk/issues/195)
//! on these examples.
//!
//! #### Checking the available CLI arguments
@@ -10,7 +10,7 @@
//! ```
//! - `--help`: Displays the available CLI arguments.
//!
//! #### Starting a Local Substrate Node in Development Mode
//! #### Starting a Local Bizinikiwi Node in Development Mode
//! ```bash
//! ./target/release/node-template \
//! --dev
@@ -97,8 +97,8 @@
//! ---
//!
//! > If you are interested in learning how to extend the CLI with your custom arguments, you can
//! > check out the [Customize your Substrate chain CLI](https://www.youtube.com/watch?v=IVifko1fqjw)
//! > check out the [Customize your Bizinikiwi chain CLI](https://www.youtube.com/watch?v=IVifko1fqjw)
//! > seminar.
//! > Please note that the seminar is based on an older version of Substrate, and [Clap](https://docs.rs/clap/latest/clap/)
//! > Please note that the seminar is based on an older version of Bizinikiwi, and [Clap](https://docs.rs/clap/latest/clap/)
//! > is now used instead of [StructOpt](https://docs.rs/structopt/latest/structopt/) for parsing
//! > CLI arguments.
@@ -6,9 +6,9 @@
//! ## Finding Host Functions
//!
//! To declare a set of functions as host functions, you need to use the `#[runtime_interface]`
//! ([`sp_runtime_interface`]) attribute macro. The most notable set of host functions are those
//! that allow the runtime to access the chain state, namely [`sp_io::storage`]. Some other notable
//! host functions are also defined in [`sp_io`].
//! ([`pezsp_runtime_interface`]) attribute macro. The most notable set of host functions are those
//! that allow the runtime to access the chain state, namely [`pezsp_io::storage`]. Some other
//! notable host functions are also defined in [`pezsp_io`].
//!
//! ## Adding New Host Functions
//!
@@ -20,8 +20,8 @@
//! access to the boilerplate of building your node.
//!
//! A group of host functions can always be grouped to gether as a tuple:
#![doc = docify::embed!("../../substrate/primitives/io/src/lib.rs", SubstrateHostFunctions)]
#![doc = docify::embed!("../../bizinikiwi/primitives/io/src/lib.rs", BizinikiwiHostFunctions)]
//!
//! The host functions are attached to the node side's [`sc_executor::WasmExecutor`]. For example in
//! the minimal template, the setup looks as follows:
//! The host functions are attached to the node side's [`pezsc_executor::WasmExecutor`]. For example
//! in the minimal template, the setup looks as follows:
#![doc = docify::embed!("../../templates/minimal/node/src/service.rs", FullClient)]
@@ -6,7 +6,7 @@
//! ## Background
//!
//! Pezkuwi-SDK offers the ability to query and subscribe storages directly. However what it does
//! not have is [view functions](https://github.com/pezkuwichain/pezkuwi-sdk/issues/101). This is an
//! not have is [view functions](https://github.com/pezkuwichain/pezkuwi-sdk/issues/247). 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.
@@ -31,7 +31,7 @@
//!
//! ## Alternatives
//!
//! Generally, [`sc_rpc::state::StateBackend::call`] aka. `state_call` should be used instead of
//! Generally, [`pezsc_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
@@ -52,9 +52,9 @@
//!
//! For example, let's take a look at 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)]
#![doc = docify::embed!("../../bizinikiwi/pezframe/system/rpc/runtime-api/src/lib.rs", AccountNonceApi)]
//!
//! This API is implemented at the runtime level, always inside [`sp_api::impl_runtime_apis!`].
//! This API is implemented at the runtime level, always inside [`pezsp_api::impl_runtime_apis!`].
//!
//! As noted, this is already enough to make this API usable via `state_call`.
//!
@@ -62,7 +62,7 @@
//!
//! 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)]
#![doc = docify::embed!("../../bizinikiwi/utils/pezframe/rpc/system/src/lib.rs", SystemApi)]
//!
//! ## Add a new RPC to the node (Legacy)
//!
@@ -1,4 +1,4 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,14 +24,14 @@
//!
//! ## General Overview
//!
//! When developing within the context of the Substrate runtime, there is one golden rule:
//! When developing within the context of the Bizinikiwi runtime, there is one golden rule:
//!
//! ***DO NOT PANIC***. There are some exceptions, but generally, this is the default precedent.
//!
//! > Its important to differentiate between the runtime and node. The runtime refers to the core
//! > business logic of a Substrate-based chain, whereas the node refers to the outer client, which
//! > business logic of a Bizinikiwi-based chain, whereas the node refers to the outer client, which
//! > deals with telemetry and gossip from other nodes. For more information, read about
//! > [Substrate's node
//! > [Bizinikiwi's node
//! > architecture](crate::reference_docs::wasm_meta_protocol#node-vs-runtime). Its also important
//! > to note that the criticality of the node is slightly lesser
//! > than that of the runtime, which is why you may see `unwrap()` or other “non-defensive”
@@ -70,18 +70,18 @@
//!
//! ### Defensive Traits
//!
//! The [`Defensive`](frame::traits::Defensive) trait provides a number of functions, all of which
//! The [`Defensive`](pezframe::traits::Defensive) trait provides a number of functions, all of which
//! provide an alternative to 'vanilla' Rust functions, e.g.:
//!
//! - [`defensive_unwrap_or()`](frame::traits::Defensive::defensive_unwrap_or) instead of
//! - [`defensive_unwrap_or()`](pezframe::traits::Defensive::defensive_unwrap_or) instead of
//! `unwrap_or()`
//! - [`defensive_ok_or()`](frame::traits::DefensiveOption::defensive_ok_or) instead of `ok_or()`
//! - [`defensive_ok_or()`](pezframe::traits::DefensiveOption::defensive_ok_or) instead of `ok_or()`
//!
//! Defensive methods use [`debug_assertions`](https://doc.rust-lang.org/reference/conditional-compilation.html#debug_assertions), which panic in development, but in
//! production/release, they will merely log an error (i.e., `log::error`).
//!
//! The [`Defensive`](frame::traits::Defensive) trait and its various implementations can be found
//! [here](frame::traits::Defensive).
//! The [`Defensive`](pezframe::traits::Defensive) trait and its various implementations can be found
//! [here](pezframe::traits::Defensive).
//!
//! ## Integer Overflow
//!
@@ -110,11 +110,11 @@
//! unexpected consequences like a user balance over or underflowing.
//!
//! Fortunately, there are ways to both represent and handle these scenarios depending on our
//! specific use case natively built into Rust and libraries like [`sp_arithmetic`].
//! specific use case natively built into Rust and libraries like [`pezsp_arithmetic`].
//!
//! ## Infallible Arithmetic
//!
//! Both Rust and Substrate provide safe ways to deal with numbers and alternatives to floating
//! Both Rust and Bizinikiwi provide safe ways to deal with numbers and alternatives to floating
//! point arithmetic.
//!
//! Known scenarios that could be fallible should be avoided: i.e., avoiding the possibility of
@@ -124,8 +124,9 @@
//! A developer should use fixed-point instead of floating-point arithmetic to mitigate the
//! potential for inaccuracy, rounding errors, or other unexpected behavior.
//!
//! - [Fixed point types](sp_arithmetic::fixed_point) and their associated usage can be found here.
//! - [PerThing](sp_arithmetic::per_things) and its associated types can be found here.
//! - [Fixed point types](pezsp_arithmetic::fixed_point) and their associated usage can be found
//! here.
//! - [PerThing](pezsp_arithmetic::per_things) and its associated types can be found here.
//!
//! Using floating point number types (i.e. f32, f64) in the runtime should be avoided, as a single non-deterministic result could cause chaos for blockchain consensus along with the issues above. For more on the specifics of the peculiarities of floating point calculations, [watch this video by the Computerphile](https://www.youtube.com/watch?v=PZRI1IfStY0).
//!
@@ -187,15 +188,15 @@
//! to avoid introducing the notion of any potential-panic or wrapping behavior.
//!
//! There is also a series of defensive alternatives via
//! [`DefensiveSaturating`](frame::traits::DefensiveSaturating), which introduces the same behavior
//! of the [`Defensive`](frame::traits::Defensive) trait, only with saturating, mathematical
//! [`DefensiveSaturating`](pezframe::traits::DefensiveSaturating), which introduces the same behavior
//! of the [`Defensive`](pezframe::traits::Defensive) trait, only with saturating, mathematical
//! operations:
#![doc = docify::embed!(
"./src/reference_docs/defensive_programming.rs",
saturated_defensive_example
)]
//!
//! ### Mathematical Operations in Substrate Development - Further Context
//! ### Mathematical Operations in Bizinikiwi Development - Further Context
//!
//! As a recap, we covered the following concepts:
//!
@@ -214,9 +215,9 @@
//!
//! #### Bob's Overflowed Balance
//!
//! **Bob's** balance exceeds the `Balance` type on the `EduChain`. Because the pallet developer did
//! not handle the calculation to add to Bob's balance with any regard to this overflow, **Bob's**
//! balance is now essentially `0`, the operation **wrapped**.
//! **Bob's** balance exceeds the `Balance` type on the `EduChain`. Because the pezpallet developer
//! did not handle the calculation to add to Bob's balance with any regard to this overflow,
//! **Bob's** balance is now essentially `0`, the operation **wrapped**.
//!
//! <details>
//! <summary><b>Solution: Saturating or Checked</b></summary>
@@ -247,7 +248,7 @@
//!
//! A `u8` parameter, called `proposals_count`, represents the type for counting the number of
//! proposals on-chain. Every time a new proposal is added to the system, this number increases.
//! With the proposal pallet's high usage, it has reached `u8::MAX`s limit of 255, causing
//! With the proposal pezpallet's high usage, it has reached `u8::MAX`s limit of 255, causing
//! `proposals_count` to go to 0. Unfortunately, this results in new proposals overwriting old ones,
//! effectively erasing any notion of past proposals!
//!
@@ -267,17 +268,17 @@
//! From the above, we can clearly see the problematic nature of seemingly simple operations in the
//! runtime, and care should be given to ensure a defensive approach is taken.
//!
//! ### Edge cases of `panic!`-able instances in Substrate
//! ### Edge cases of `panic!`-able instances in Bizinikiwi
//!
//! As you traverse through the codebase (particularly in `substrate/frame`, where the majority of
//! As you traverse through the codebase (particularly in `bizinikiwi/frame`, where the majority of
//! runtime code lives), you may notice that there (only a few!) occurrences where `panic!` is used
//! explicitly. This is used when the runtime should stall, rather than keep running, as that is
//! considered safer. Particularly when it comes to mission-critical components, such as block
//! authoring, consensus, or other protocol-level dependencies, going through with an action may
//! actually cause harm to the network, and thus stalling would be the better option.
//!
//! Take the example of the BABE pallet ([`pallet_babe`]), which doesn't allow for a validator to
//! participate if it is disabled (see: [`frame::traits::DisabledValidators`]):
//! Take the example of the BABE pezpallet ([`pezpallet_babe`]), which doesn't allow for a validator
//! to participate if it is disabled (see: [`pezframe::traits::DisabledValidators`]):
//!
//! ```ignore
//! if T::DisabledValidators::is_disabled(authority_index) {
@@ -358,7 +359,7 @@ mod fake_runtime_types {
#[cfg(test)]
mod tests {
use frame::traits::DefensiveSaturating;
use pezframe::traits::DefensiveSaturating;
#[docify::export]
#[test]
fn checked_add_example() {
@@ -138,7 +138,7 @@
//!
//! The WASM binary is usually not needed, especially when running `check` or `test`. To skip the
//! WASM build, set the `SKIP_WASM_BUILD` environment variable to `1`. For example:
//! `SKIP_WASM_BUILD=1 cargo check -p frame-support`.
//! `SKIP_WASM_BUILD=1 cargo check -p pezframe-support`.
//!
//! ### Cargo Remote
//!
@@ -4,21 +4,21 @@
//! of a blockchain via the [_state transition
//! function_][crate::reference_docs::blockchain_state_machines].
//!
//! Substrate is configurable enough that extrinsics can take any format. In practice, runtimes
//! tend to use our [`sp_runtime::generic::UncheckedExtrinsic`] type to represent extrinsics,
//! Bizinikiwi is configurable enough that extrinsics can take any format. In practice, runtimes
//! tend to use our [`pezsp_runtime::generic::UncheckedExtrinsic`] type to represent extrinsics,
//! because it's generic enough to cater for most (if not all) use cases. In Pezkuwi, this is
//! configured [here](https://github.com/polkadot-fellows/runtimes/blob/94b2798b69ba6779764e20a50f056e48db78ebef/relay/polkadot/src/lib.rs#L1478)
//! at the time of writing.
//!
//! What follows is a description of how extrinsics based on this
//! [`sp_runtime::generic::UncheckedExtrinsic`] type are encoded into bytes. Specifically, we are
//! [`pezsp_runtime::generic::UncheckedExtrinsic`] type are encoded into bytes. Specifically, we are
//! looking at how extrinsics with a format version of 5 are encoded. This version is itself a part
//! of the payload, and if it changes, it indicates that something about the encoding may have
//! changed.
//!
//! # Encoding an Extrinsic
//!
//! At a high level, all extrinsics compatible with [`sp_runtime::generic::UncheckedExtrinsic`]
//! At a high level, all extrinsics compatible with [`pezsp_runtime::generic::UncheckedExtrinsic`]
//! are formed from concatenating some details together, as in the following pseudo-code:
//!
//! ```text
@@ -30,14 +30,14 @@
//! )
//! ```
//!
//! For clarity, the actual implementation in Substrate looks like this:
#![doc = docify::embed!("../../substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs", unchecked_extrinsic_encode_impl)]
//! For clarity, the actual implementation in Bizinikiwi looks like this:
#![doc = docify::embed!("../../bizinikiwi/primitives/runtime/src/generic/unchecked_extrinsic.rs", unchecked_extrinsic_encode_impl)]
//!
//! Let's look at how each of these details is constructed:
//!
//! ## compact_encoded_length
//!
//! This is a [SCALE compact encoded][frame::deps::codec::Compact] integer which is equal to the
//! This is a [SCALE compact encoded][pezframe::deps::codec::Compact] integer which is equal to the
//! length, in bytes, of the rest of the extrinsic details.
//!
//! To obtain this value, we must encode and concatenate together the rest of the extrinsic details
@@ -90,25 +90,26 @@
//!
//! #### from_address
//!
//! This is the [SCALE encoded][frame::deps::codec] address of the sender of the extrinsic. The
//! address is the first generic parameter of [`sp_runtime::generic::UncheckedExtrinsic`], and so
//! This is the [SCALE encoded][pezframe::deps::codec] address of the sender of the extrinsic. The
//! address is the first generic parameter of [`pezsp_runtime::generic::UncheckedExtrinsic`], and so
//! can vary from chain to chain.
//!
//! The address type used on the Pezkuwi relay chain is [`sp_runtime::MultiAddress<AccountId32>`],
//! where `AccountId32` is defined [here][`sp_core::crypto::AccountId32`]. When constructing a
//! signed extrinsic to be submitted to a Pezkuwi node, you'll always use the
//! [`sp_runtime::MultiAddress::Id`] variant to wrap your `AccountId32`.
//! The address type used on the Pezkuwi relay chain is
//! [`pezsp_runtime::MultiAddress<AccountId32>`], where `AccountId32` is defined
//! [here][`pezsp_core::crypto::AccountId32`]. When constructing a signed extrinsic to be submitted
//! to a Pezkuwi node, you'll always use the [`pezsp_runtime::MultiAddress::Id`] variant to wrap
//! your `AccountId32`.
//!
//! #### signature
//!
//! This is the [SCALE encoded][frame::deps::codec] signature. The signature type is configured via
//! the third generic parameter of [`sp_runtime::generic::UncheckedExtrinsic`], which determines the
//! shape of the signature and signing algorithm that should be used.
//! This is the [SCALE encoded][pezframe::deps::codec] signature. The signature type is configured via
//! the third generic parameter of [`pezsp_runtime::generic::UncheckedExtrinsic`], which determines
//! the shape of the signature and signing algorithm that should be used.
//!
//! The signature is obtained by signing the _signed payload_ bytes (see below on how this is
//! constructed) using the private key associated with the address and correct algorithm.
//!
//! The signature type used on the Pezkuwi relay chain is [`sp_runtime::MultiSignature`]; the
//! The signature type used on the Pezkuwi relay chain is [`pezsp_runtime::MultiSignature`]; the
//! variants there are the types of signature that can be provided.
//!
//! ### General extrinsics
@@ -120,12 +121,12 @@
//!
//! ### transaction_extensions_extra
//!
//! This is the concatenation of the [SCALE encoded][frame::deps::codec] bytes representing first a
//! This is the concatenation of the [SCALE encoded][pezframe::deps::codec] bytes representing first a
//! single byte describing the extension version (this is bumped whenever a change occurs in the
//! transaction extension pipeline) followed by the bytes of each of the [_transaction
//! extensions_][sp_runtime::traits::TransactionExtension], and are configured by the fourth generic
//! parameter of [`sp_runtime::generic::UncheckedExtrinsic`]. Learn more about transaction
//! extensions [here][crate::reference_docs::transaction_extensions].
//! extensions_][pezsp_runtime::traits::TransactionExtension], and are configured by the fourth
//! generic parameter of [`pezsp_runtime::generic::UncheckedExtrinsic`]. Learn more about
//! transaction extensions [here][crate::reference_docs::transaction_extensions].
//!
//! When it comes to constructing an extrinsic, each transaction extension has two things that we
//! are interested in here:
@@ -141,22 +142,22 @@
//! configuration. At the time of writing, Pezkuwi configures them
//! [here](https://github.com/polkadot-fellows/runtimes/blob/1dc04eb954eadf8aadb5d83990b89662dbb5a074/relay/polkadot/src/lib.rs#L1432C25-L1432C25).
//! Some of the common transaction extensions are defined
//! [here][frame::deps::frame_system#transaction-extensions].
//! [here][pezframe::deps::pezframe_system#transaction-extensions].
//!
//! Information about exactly which transaction extensions are present on a chain and in what order
//! is also a part of the metadata for the chain. For V15 metadata, it can be [found
//! here][frame::deps::frame_support::__private::metadata::v15::ExtrinsicMetadata].
//! here][pezframe::deps::pezframe_support::__private::metadata::v15::ExtrinsicMetadata].
//!
//! ## call_data
//!
//! This is the main payload of the extrinsic, which is used to determine how the chain's state is
//! altered. This is defined by the second generic parameter of
//! [`sp_runtime::generic::UncheckedExtrinsic`].
//! [`pezsp_runtime::generic::UncheckedExtrinsic`].
//!
//! A call can be anything that implements [`Encode`][frame::deps::codec::Encode]. In FRAME-based
//! A call can be anything that implements [`Encode`][pezframe::deps::codec::Encode]. In FRAME-based
//! runtimes, a call is represented as an enum of enums, where the outer enum represents the FRAME
//! pallet being called, and the inner enum represents the call being made within that pallet, and
//! any arguments to it. Read more about the call enum
//! pezpallet being called, and the inner enum represents the call being made within that pezpallet,
//! and any arguments to it. Read more about the call enum
//! [here][crate::reference_docs::frame_runtime_types].
//!
//! FRAME `Call` enums are automatically generated, and end up looking something like this:
@@ -166,23 +167,23 @@
//!
//! ```text
//! call_data = concat(
//! pallet_index,
//! pezpallet_index,
//! call_index,
//! call_args
//! )
//! ```
//!
//! - `pallet_index` is a single byte denoting the index of the pallet that we are calling into, and
//! is what the tag of the outermost enum will encode to.
//! - `call_index` is a single byte denoting the index of the call that we are making the pallet,
//! - `pezpallet_index` is a single byte denoting the index of the pezpallet that we are calling
//! into, and is what the tag of the outermost enum will encode to.
//! - `call_index` is a single byte denoting the index of the call that we are making the pezpallet,
//! and is what the tag of the inner enum will encode to.
//! - `call_args` are the SCALE encoded bytes for each of the arguments that the call expects, and
//! are typically provided as values to the inner enum.
//!
//! Information about the pallets that exist for a chain (including their indexes), the calls
//! available in each pallet (including their indexes), and the arguments required for each call can
//! be found in the metadata for the chain. For V15 metadata, this information [is
//! here][frame::deps::frame_support::__private::metadata::v15::PalletMetadata].
//! available in each pezpallet (including their indexes), and the arguments required for each call
//! can be found in the metadata for the chain. For V15 metadata, this information [is
//! here][pezframe::deps::pezframe_support::__private::metadata::v15::PalletMetadata].
//!
//! # The Signed Payload Format
//!
@@ -202,13 +203,13 @@
//!
//! The bytes representing `call_data` and `transaction_extensions_extra` can be obtained as
//! descibed above. `transaction_extensions_implicit` is constructed by SCALE encoding the
//! ["implicit" data][sp_runtime::traits::TransactionExtension::Implicit] for each transaction
//! ["implicit" data][pezsp_runtime::traits::TransactionExtension::Implicit] for each transaction
//! extension that the chain is using, in order.
//!
//! Once we've concatenated those together, we hash the result using a Blake2 256bit hasher.
//!
//! The [`sp_runtime::generic::SignedPayload`] type takes care of assembling the correct payload for
//! us, given `call_data` and a tuple of transaction extensions.
//! The [`pezsp_runtime::generic::SignedPayload`] type takes care of assembling the correct payload
//! for us, given `call_data` and a tuple of transaction extensions.
//!
//! # The General Transaction Format
//!
@@ -216,22 +217,22 @@
//! extrinsic, such as a traditionally signed transaction. Instead, general transactions should have
//! one or more extensions in the transaction extension pipeline that auhtorize origins in some way,
//! one of which could be the traditional signature check that happens for all signed transactions
//! in the [Checkable](sp_runtime::traits::Checkable) implementation of
//! [UncheckedExtrinsic](sp_runtime::generic::UncheckedExtrinsic). Therefore, it is up to each
//! in the [Checkable](pezsp_runtime::traits::Checkable) implementation of
//! [UncheckedExtrinsic](pezsp_runtime::generic::UncheckedExtrinsic). Therefore, it is up to each
//! extension to define the format of the payload it will try to check and authorize the right
//! origin type. For an example, look into the [authorization example pallet
//! extensions](pallet_example_authorization_tx_extension::extensions)
//! origin type. For an example, look into the [authorization example pezpallet
//! extensions](pezpallet_example_authorization_tx_extension::extensions)
//!
//! # Example Encoding
//!
//! Using [`sp_runtime::generic::UncheckedExtrinsic`], we can construct and encode an extrinsic as
//! follows:
//! Using [`pezsp_runtime::generic::UncheckedExtrinsic`], we can construct and encode an extrinsic
//! as follows:
#![doc = docify::embed!("./src/reference_docs/extrinsic_encoding.rs", encoding_example)]
#[docify::export]
pub mod call_data {
use codec::{Decode, Encode};
use sp_runtime::{traits::Dispatchable, DispatchResultWithInfo};
use pezsp_runtime::{traits::Dispatchable, DispatchResultWithInfo};
// The outer enum composes calls within
// different pallets together. We have two
@@ -245,7 +246,7 @@ pub mod call_data {
}
// An inner enum represents the calls within
// a specific pallet. "PalletA" has one call,
// a specific pezpallet. "PalletA" has one call,
// "Foo".
#[derive(Encode, Decode, Clone)]
pub enum PalletACall {
@@ -275,9 +276,9 @@ pub mod encoding_example {
use super::call_data::{Call, PalletACall};
use crate::reference_docs::transaction_extensions::transaction_extensions_example;
use codec::Encode;
use sp_core::crypto::AccountId32;
use sp_keyring::sr25519::Keyring;
use sp_runtime::{
use pezsp_core::crypto::AccountId32;
use pezsp_keyring::sr25519::Keyring;
use pezsp_runtime::{
generic::{SignedPayload, UncheckedExtrinsic},
MultiAddress, MultiSignature,
};
@@ -17,17 +17,17 @@
//! }
//! ```
//!
//! within the pallet, if you want to use the standard `println!`, it needs to be wrapped in
//! [`sp_std::if_std`]. Of course, this means that this print code is only available to you in the
//! `std` compiler flag, and never present in a wasm build.
//! within the pezpallet, if you want to use the standard `println!`, it needs to be wrapped in
//! [`pezsp_std::if_std`]. Of course, this means that this print code is only available to you in
//! the `std` compiler flag, and never present in a wasm build.
//!
//! ```
//! // somewhere in your pallet. This is not a real pallet code.
//! mod pallet {
//! struct Pallet;
//! impl Pallet {
//! // somewhere in your pezpallet. This is not a real pezpallet code.
//! mod pezpallet {
//! struct Pezpallet;
//! impl Pezpallet {
//! fn print() {
//! sp_std::if_std! {
//! pezsp_std::if_std! {
//! println!("Hello, world!");
//! }
//! }
@@ -42,9 +42,9 @@
//! 1. `log-level`, signifying how important it is.
//! 2. `log-target`, signifying to which component it belongs.
//!
//! Add log statements to your pallet as such:
//! Add log statements to your pezpallet as such:
//!
//! You can add the log crate to the `Cargo.toml` of the pallet.
//! You can add the log crate to the `Cargo.toml` of the pezpallet.
//!
//! ```text
//! #[dependencies]
@@ -57,49 +57,49 @@
//! ]
//! ```
//!
//! More conveniently, the `frame` umbrella crate re-exports the log crate as [`frame::log`].
//! More conveniently, the `frame` umbrella crate re-exports the log crate as [`pezframe::log`].
//!
//! Then, the pallet can use this crate to emit log statements. In this statement, we use the info
//! level, and the target is `pallet-example`.
//! Then, the pezpallet can use this crate to emit log statements. In this statement, we use the
//! info level, and the target is `pezpallet-example`.
//!
//! ```
//! mod pallet {
//! struct Pallet;
//! mod pezpallet {
//! struct Pezpallet;
//!
//! impl Pallet {
//! impl Pezpallet {
//! fn logs() {
//! frame::log::info!(target: "pallet-example", "Hello, world!");
//! pezframe::log::info!(target: "pezpallet-example", "Hello, world!");
//! }
//! }
//! }
//! ```
//!
//! This will in itself just emit the log messages, **but unless if captured by a logger, they will
//! not go anywhere**. [`sp_api`] provides a handy function to enable the runtime logging:
//! not go anywhere**. [`pezsp_api`] provides a handy function to enable the runtime logging:
//!
//! ```
//! // in your test
//! fn it_also_prints() {
//! sp_api::init_runtime_logger();
//! // call into your pallet, and now it will print `log` statements.
//! pezsp_api::init_runtime_logger();
//! // call into your pezpallet, and now it will print `log` statements.
//! }
//! ```
//!
//! Alternatively, you can use [`sp_tracing::try_init_simple`].
//! Alternatively, you can use [`pezsp_tracing::try_init_simple`].
//!
//! `info`, `error` and `warn` logs are printed by default, but if you want lower level logs to also
//! be printed, you must to add the following compiler flag:
//!
//! ```text
//! RUST_LOG=pallet-example=trace cargo test
//! RUST_LOG=pezpallet-example=trace cargo test
//! ```
//!
//! ## Enabling Logs in Production
//!
//! All logs from the runtime are emitted by default, but there is a feature flag in [`sp_api`],
//! All logs from the runtime are emitted by default, but there is a feature flag in [`pezsp_api`],
//! called `disable-logging`, that can be used to disable all logs in the runtime. This is useful
//! for production chains to reduce the size and overhead of the wasm runtime.
#![doc = docify::embed!("../../substrate/primitives/api/src/lib.rs", init_runtime_logger)]
#![doc = docify::embed!("../../bizinikiwi/primitives/api/src/lib.rs", init_runtime_logger)]
//!
//! Similar to the above, the proper `RUST_LOG` must also be passed to your compiler flag when
//! compiling the runtime.
@@ -107,7 +107,7 @@
//! ## Log Target Prefixing
//!
//! Many [`crate::pezkuwi_sdk::frame_runtime`] pallets emit logs with log target `runtime::<name of
//! pallet>`, for example `runtime::system`. This then allows one to run a node with a wasm blob
//! pezpallet>`, for example `runtime::system`. This then allows one to run a node with a wasm blob
//! compiled with `LOG_TARGET=runtime=debug`, which enables the log target of all pallets who's log
//! target starts with `runtime`.
//!
@@ -115,8 +115,8 @@
//!
//! Under the hood, logging is another instance of host functions under the hood (as defined in
//! [`crate::reference_docs::wasm_meta_protocol`]). The runtime uses a set of host functions under
//! [`sp_io::logging`] and [`sp_io::misc`] to emit all logs and prints. You typically do not need to
//! use these APIs directly.
//! [`pezsp_io::logging`] and [`pezsp_io::misc`] to emit all logs and prints. You typically do not
//! need to use these APIs directly.
//!
//! ## Using Logging in Production
//!
@@ -124,12 +124,12 @@
//! and can lead to consensus issues. This is because with the introduction of
//! [`crate::guides::enable_pov_reclaim`], the node side code will track the storage changes, and
//! tries to update the onchain record of the `proof_size` weight used (stored in
//! [`frame_system::BlockWeight`]) after the block is executed.
//! [`pezframe_system::BlockWeight`]) after the block is executed.
//!
//! If one node has a different log level enabled than the rest of the network, and the extra logs
//! impose additional storage reads, then the amount of `proof_size` weight reclaimed into
//! [`frame_system::BlockWeight`] will be different, causing a state root mismatch, which is
//! typically a fatal error emitted from [`frame_executive`].
//! [`pezframe_system::BlockWeight`] will be different, causing a state root mismatch, which is
//! typically a fatal error emitted from [`pezframe_executive`].
//!
//! This also can also happen in a teyrchain context, and cause discrepancies between the relay
//! chain and the teyrchain, when execution the Teyrchain Validation Function (PVF) on the relay
@@ -151,5 +151,5 @@
//! }
//! ```
//!
//! Please read [this issue](https://github.com/pezkuwichain/pezkuwi-sdk/issues/155) for one
//! Please read [this issue](https://github.com/pezkuwichain/pezkuwi-sdk/issues/298) for one
//! instance of the consensus issues caused by this mistake.
@@ -1,8 +1,8 @@
//! # Offchain Workers
//!
//! This reference document explains how offchain workers work in Substrate and FRAME. The main
//! This reference document explains how offchain workers work in Bizinikiwi and FRAME. The main
//! focus is upon FRAME's implementation of this functionality. Nonetheless, offchain workers are a
//! Substrate-provided feature and can be used with possible alternatives to [`frame`] as well.
//! Bizinikiwi-provided feature and can be used with possible alternatives to [`frame`] as well.
//!
//! Offchain workers are a commonly misunderstood topic, therefore we explain them bottom-up,
//! starting at the fundamentals and then describing the developer interface.
@@ -11,11 +11,11 @@
//!
//! Recall from [`crate::reference_docs::wasm_meta_protocol`] that the node and the runtime
//! communicate with one another via host functions and runtime APIs. Many of these interactions
//! contribute to the actual state transition of the blockchain. For example [`sp_api::Core`] is the
//! main runtime API that is called to execute new blocks.
//! contribute to the actual state transition of the blockchain. For example [`pezsp_api::Core`] is
//! the main runtime API that is called to execute new blocks.
//!
//! Offchain workers are in principle not different in any way: It is a runtime API exposed by the
//! wasm blob ([`sp_offchain::OffchainWorkerApi`]), and the node software calls into it when it
//! wasm blob ([`pezsp_offchain::OffchainWorkerApi`]), and the node software calls into it when it
//! deems fit. But, crucially, this API call is different in that:
//!
//! 1. It can have no impact on the state ie. it is _OFF (the) CHAIN_. If any state is altered
@@ -25,7 +25,7 @@
//!
//! > The main way through which an offchain worker can interact with the state is by submitting an
//! > extrinsic to the chain. This is the ONLY way to alter the state from an offchain worker.
//! > [`pallet_example_offchain_worker`] provides an example of this.
//! > [`pezpallet_example_offchain_worker`] provides an example of this.
//!
//!
//! Given the "Off Chain" nature of this API, it is important to remember that calling this API is
@@ -33,16 +33,16 @@
//! the execution of your blockchain because no state is altered no matter the execution of the
//! offchain worker API.
//!
//! Substrate's CLI allows some degree of configuration about this, allowing node operators to
//! Bizinikiwi's CLI allows some degree of configuration about this, allowing node operators to
//! specify when they want to run the offchain worker API. See
//! [`sc_cli::RunCmd::offchain_worker_params`].
//! [`pezsc_cli::RunCmd::offchain_worker_params`].
//!
//! ## Nondeterministic Execution
//!
//! Needless to say, given the above description, the code in your offchain worker API can be
//! nondeterministic, as it is not part of the blockchain's STF, so it can be executed at unknown
//! times, by unknown nodes, and has no impact on the state. This is why an HTTP
//! ([`sp_runtime::offchain::http`]) API is readily provided to the offchain worker APIs. Because
//! ([`pezsp_runtime::offchain::http`]) API is readily provided to the offchain worker APIs. Because
//! there is no need for determinism in this context.
//!
//! > A common mistake here is for novice developers to see this HTTP API, and imagine that
@@ -54,22 +54,22 @@
//! ## FRAME's API
//!
//! [`frame`] provides a simple API through which pallets can define offchain worker functions. This
//! is part of [`frame::traits::Hooks`], which is implemented as a part of
//! [`frame::pallet_macros::hooks`].
//! is part of [`pezframe::traits::Hooks`], which is implemented as a part of
//! [`pezframe::pezpallet_macros::hooks`].
//!
//! ```
//! #[frame::pallet]
//! pub mod pallet {
//! use frame::prelude::*;
//! #[pezframe::pezpallet]
//! pub mod pezpallet {
//! use pezframe::prelude::*;
//!
//! #[pallet::config]
//! pub trait Config: frame_system::Config {}
//! #[pezpallet::config]
//! pub trait Config: pezframe_system::Config {}
//!
//! #[pallet::pallet]
//! pub struct Pallet<T>(_);
//! #[pezpallet::pezpallet]
//! pub struct Pezpallet<T>(_);
//!
//! #[pallet::hooks]
//! impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
//! #[pezpallet::hooks]
//! impl<T: Config> Hooks<BlockNumberFor<T>> for Pezpallet<T> {
//! fn offchain_worker(block_number: BlockNumberFor<T>) {
//! // ...
//! }
@@ -77,10 +77,10 @@
//! }
//! ```
//!
//! Additionally, [`sp_runtime::offchain`] provides a set of utilities that can be used to moderate
//! the execution of offchain workers.
//! Additionally, [`pezsp_runtime::offchain`] provides a set of utilities that can be used to
//! moderate the execution of offchain workers.
//!
//! ## Think Twice: Why Use Substrate's Offchain Workers?
//! ## Think Twice: Why Use Bizinikiwi's Offchain Workers?
//!
//! Consider the fact that in principle, an offchain worker code written using the above API is no
//! different than an equivalent written with an _actual offchain interaction library_, such as
@@ -88,16 +88,16 @@
//!
//! They can both read from the state, and have no means of updating the state, other than the route
//! of submitting an extrinsic to the chain. Therefore, it is worth thinking twice before embedding
//! a logic as a part of Substrate's offchain worker API. Does it have to be there? Can it not be a
//! a logic as a part of Bizinikiwi's offchain worker API. Does it have to be there? Can it not be a
//! simple, actual offchain application that lives outside of the chain's WASM blob?
//!
//! Some of the reasons why you might want to do the opposite, and actually embed an offchain worker
//! API into the WASM blob are:
//!
//! * Accessing the state is easier within the `offchain_worker` function, as it is already a part
//! of the runtime, and [`frame::pallet_macros::storage`] provides all the tools needed to read
//! of the runtime, and [`pezframe::pezpallet_macros::storage`] provides all the tools needed to read
//! the state. Other client libraries might provide varying degrees of capability here.
//! * It will be updated in synchrony with the runtime. A Substrate's offchain application is part
//! * It will be updated in synchrony with the runtime. A Bizinikiwi's offchain application is part
//! of the same WASM blob, and is therefore guaranteed to be up to date.
//!
//! For example, imagine you have modified a storage item to have a new type. This will possibly
@@ -111,4 +111,4 @@
//!
//! - <https://forum.polkadot.network/t/offchain-workers-design-assumptions-vulnerabilities/2548>
//! - <https://exchange.pezkuwichain.app/questions/11058/how-can-i-create-ocw-that-wont-activates-every-block-but-will-activates-only-w/11060#11060>
//! - [Offchain worker example](https://github.com/pezkuwichain/pezkuwi-sdk/tree/master/substrate/frame/examples/offchain-worker)
//! - [Offchain worker example](https://github.com/pezkuwichain/pezkuwi-sdk/tree/master/bizinikiwi/pezframe/examples/offchain-worker)
@@ -6,8 +6,8 @@
//!
//! FRAME's origin abstractions allow you to convey meanings far beyond just an account-id being the
//! caller of an extrinsic. Nonetheless, an account-id having signed an extrinsic is one of the
//! meanings that an origin can convey. This is the commonly used [`frame_system::ensure_signed`],
//! where the return value happens to be an account-id.
//! meanings that an origin can convey. This is the commonly used
//! [`pezframe_system::ensure_signed`], where the return value happens to be an account-id.
//!
//! Instead, let's establish the following as the correct definition of an origin:
//!
@@ -21,8 +21,8 @@
//! example:
//!
//! * If the majority of token holders agreed upon this. This is more or less what the
//! [`pallet_democracy`] does under the hood ([reference](https://github.com/pezkuwichain/pezkuwi-sdk/blob/edd95b3749754d2ed0c5738588e872c87be91624/substrate/frame/democracy/src/lib.rs#L1603-L1633)).
//! * If a specific ratio of an instance of [`pallet_collective`]/DAO agrees upon this.
//! [`pezpallet_democracy`] does under the hood ([reference](https://github.com/pezkuwichain/pezkuwi-sdk/blob/edd95b3749754d2ed0c5738588e872c87be91624/bizinikiwi/pezframe/democracy/src/lib.rs#L1603-L1633)).
//! * If a specific ratio of an instance of [`pezpallet_collective`]/DAO agrees upon this.
//! * If another consensus system, for example a bridged network or a teyrchain, agrees upon this.
//! * If the majority of validator/authority set agrees upon this[^1].
//! * If caller holds a particular NFT.
@@ -31,88 +31,89 @@
//!
//! ## Context
//!
//! First, let's look at where the `origin` type is encountered in a typical pallet. The `origin:
//! First, let's look at where the `origin` type is encountered in a typical pezpallet. The `origin:
//! OriginFor<T>` has to be the first argument of any given callable extrinsic in FRAME:
#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", call_simple)]
//!
//! Typically, the code of an extrinsic starts with an origin check, such as
//! [`frame_system::ensure_signed`].
//! [`pezframe_system::ensure_signed`].
//!
//! Note that [`OriginFor`](frame_system::pallet_prelude::OriginFor) is merely a shorthand for
//! [`frame_system::Config::RuntimeOrigin`]. Given the name prefix `Runtime`, we can learn that
//! Note that [`OriginFor`](pezframe_system::pezpallet_prelude::OriginFor) is merely a shorthand for
//! [`pezframe_system::Config::RuntimeOrigin`]. Given the name prefix `Runtime`, we can learn that
//! `RuntimeOrigin` is similar to `RuntimeCall` and others, a runtime composite enum that is
//! amalgamated at the runtime level. Read [`crate::reference_docs::frame_runtime_types`] to
//! familiarize yourself with these types.
//!
//! To understand this better, we will next create a pallet with a custom origin, which will add a
//! new variant to `RuntimeOrigin`.
//! To understand this better, we will next create a pezpallet with a custom origin, which will add
//! a new variant to `RuntimeOrigin`.
//!
//! ## Adding Custom Pallet Origin to the Runtime
//! ## Adding Custom Pezpallet Origin to the Runtime
//!
//! For example, given a pallet that defines the following custom origin:
//! For example, given a pezpallet that defines the following custom origin:
#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin)]
//!
//! And a runtime with the following pallets:
#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", runtime_exp)]
//!
//! The type [`crate::reference_docs::frame_origin::runtime_for_origin::RuntimeOrigin`] is expanded.
//! This `RuntimeOrigin` contains a variant for the [`frame_system::RawOrigin`] and the custom
//! origin of the pallet.
//! This `RuntimeOrigin` contains a variant for the [`pezframe_system::RawOrigin`] and the custom
//! origin of the pezpallet.
//!
//! > Notice how the [`frame_system::ensure_signed`] is nothing more than a `match` statement. If
//! > Notice how the [`pezframe_system::ensure_signed`] is nothing more than a `match` statement. If
//! > you want to know where the actual origin of an extrinsic is set (and the signature
//! > verification happens, if any), see
//! > [`sp_runtime::generic::CheckedExtrinsic#trait-implementations`], specifically
//! > [`sp_runtime::traits::Applyable`]'s implementation.
//! > [`pezsp_runtime::generic::CheckedExtrinsic#trait-implementations`], specifically
//! > [`pezsp_runtime::traits::Applyable`]'s implementation.
//!
//! ## Asserting on a Custom Internal Origin
//!
//! In order to assert on a custom origin that is defined within your pallet, we need a way to first
//! convert the `<T as frame_system::Config>::RuntimeOrigin` into the local `enum Origin` of the
//! current pallet. This is a common process that is explained in
//! In order to assert on a custom origin that is defined within your pezpallet, we need a way to
//! first convert the `<T as pezframe_system::Config>::RuntimeOrigin` into the local `enum Origin`
//! of the current pezpallet. This is a common process that is explained in
//! [`crate::reference_docs::frame_runtime_types#
//! adding-further-constraints-to-runtime-composite-enums`].
//!
//! We use the same process here to express that `RuntimeOrigin` has a number of additional bounds,
//! as follows.
//!
//! 1. Defining a custom `RuntimeOrigin` with further bounds in the pallet.
//! 1. Defining a custom `RuntimeOrigin` with further bounds in the pezpallet.
#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin_bound)]
//!
//! 2. Using it in the pallet.
//! 2. Using it in the pezpallet.
#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin_usage)]
//!
//! ## Asserting on a Custom External Origin
//!
//! Very often, a pallet wants to have a parameterized origin that is **NOT** defined within the
//! pallet. In other words, a pallet wants to delegate an origin check to something that is
//! Very often, a pezpallet wants to have a parameterized origin that is **NOT** defined within the
//! pezpallet. In other words, a pezpallet wants to delegate an origin check to something that is
//! specified later at the runtime level. Like many other parameterizations in FRAME, this implies
//! adding a new associated type to `trait Config`.
#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_def)]
//!
//! Then, within the pallet, we can simply use this "unknown" origin check type:
//! Then, within the pezpallet, we can simply use this "unknown" origin check type:
#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_usage)]
//!
//! Finally, at the runtime, any implementation of [`frame::traits::EnsureOrigin`] can be passed.
//! Finally, at the runtime, any implementation of [`pezframe::traits::EnsureOrigin`] can be passed.
#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_provide)]
//!
//! Indeed, some of these implementations of [`frame::traits::EnsureOrigin`] are similar to the ones
//! that we know about: [`frame::runtime::prelude::EnsureSigned`],
//! [`frame::runtime::prelude::EnsureSignedBy`], [`frame::runtime::prelude::EnsureRoot`],
//! [`frame::runtime::prelude::EnsureNone`], etc. But, there are also many more that are not known
//! Indeed, some of these implementations of [`pezframe::traits::EnsureOrigin`] are similar to the ones
//! that we know about: [`pezframe::runtime::prelude::EnsureSigned`],
//! [`pezframe::runtime::prelude::EnsureSignedBy`], [`pezframe::runtime::prelude::EnsureRoot`],
//! [`pezframe::runtime::prelude::EnsureNone`], etc. But, there are also many more that are not known
//! to us, and are defined in other pallets.
//!
//! For example, [`pallet_collective`] defines [`pallet_collective::EnsureMember`] and
//! [`pallet_collective::EnsureProportionMoreThan`] and many more, which is exactly what we alluded
//! to earlier in this document.
//! For example, [`pezpallet_collective`] defines [`pezpallet_collective::EnsureMember`] and
//! [`pezpallet_collective::EnsureProportionMoreThan`] and many more, which is exactly what we
//! alluded to earlier in this document.
//!
//! Make sure to check the full list of [implementors of
//! `EnsureOrigin`](frame::traits::EnsureOrigin#implementors) for more inspiration.
//! `EnsureOrigin`](pezframe::traits::EnsureOrigin#implementors) for more inspiration.
//!
//! ## Obtaining Abstract Origins
//!
//! So far we have learned that FRAME pallets can assert on custom and abstract origin types,
//! whether they are defined within the pallet or not. But how can we obtain these abstract origins?
//! whether they are defined within the pezpallet or not. But how can we obtain these abstract
//! origins?
//!
//! > All extrinsics that come from the outer world can generally only be obtained as either
//! > `signed` or `none` origin.
@@ -125,24 +126,24 @@
//! - [Gavin Wood's speech about FRAME features at Protocol Berg 2023.](https://youtu.be/j7b8Upipmeg?si=83_XUgYuJxMwWX4g&t=195)
//! - [A related StackExchange question.](https://exchange.pezkuwichain.app/questions/10992/how-do-you-find-the-public-key-for-the-medium-spender-track-origin)
//!
//! [^1]: Inherents are essentially unsigned extrinsics that need an [`frame_system::ensure_none`]
//! [^1]: Inherents are essentially unsigned extrinsics that need an [`pezframe_system::ensure_none`]
//! origin check, and through the virtue of being an inherent, are agreed upon by all validators.
use frame::prelude::*;
use pezframe::prelude::*;
#[frame::pallet(dev_mode)]
pub mod pallet_for_origin {
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet_for_origin {
use super::*;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[docify::export(call_simple)]
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
pub fn do_something(_origin: OriginFor<T>) -> DispatchResult {
// ^^^^^^^^^^^^^^^^^^^^^
todo!();
@@ -150,23 +151,23 @@ pub mod pallet_for_origin {
}
}
#[frame::pallet(dev_mode)]
pub mod pallet_with_custom_origin {
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet_with_custom_origin {
use super::*;
#[docify::export(custom_origin_bound)]
#[pallet::config]
pub trait Config: frame_system::Config {
type RuntimeOrigin: From<<Self as frame_system::Config>::RuntimeOrigin>
#[pezpallet::config]
pub trait Config: pezframe_system::Config {
type RuntimeOrigin: From<<Self as pezframe_system::Config>::RuntimeOrigin>
+ Into<Result<Origin, <Self as Config>::RuntimeOrigin>>;
}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[docify::export(custom_origin)]
/// A dummy custom origin.
#[pallet::origin]
#[pezpallet::origin]
#[derive(
PartialEq,
Eq,
@@ -186,13 +187,13 @@ pub mod pallet_with_custom_origin {
}
#[docify::export(custom_origin_usage)]
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
pub fn only_validators(origin: OriginFor<T>) -> DispatchResult {
// first, we convert from `<T as frame_system::Config>::RuntimeOrigin` to `<T as
// first, we convert from `<T as pezframe_system::Config>::RuntimeOrigin` to `<T as
// Config>::RuntimeOrigin`
let local_runtime_origin = <<T as Config>::RuntimeOrigin as From<
<T as frame_system::Config>::RuntimeOrigin,
<T as pezframe_system::Config>::RuntimeOrigin,
>>::from(origin);
// then we convert to `origin`, if possible
let local_origin =
@@ -204,42 +205,42 @@ pub mod pallet_with_custom_origin {
}
pub mod runtime_for_origin {
use super::pallet_with_custom_origin;
use frame::{runtime::prelude::*, testing_prelude::*};
use super::pezpallet_with_custom_origin;
use pezframe::{runtime::prelude::*, testing_prelude::*};
#[docify::export(runtime_exp)]
construct_runtime!(
pub struct Runtime {
System: frame_system,
PalletWithCustomOrigin: pallet_with_custom_origin,
System: pezframe_system,
PalletWithCustomOrigin: pezpallet_with_custom_origin,
}
);
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Self>;
}
impl pallet_with_custom_origin::Config for Runtime {
impl pezpallet_with_custom_origin::Config for Runtime {
type RuntimeOrigin = RuntimeOrigin;
}
}
#[frame::pallet(dev_mode)]
pub mod pallet_with_external_origin {
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet_with_external_origin {
use super::*;
#[docify::export(external_origin_def)]
#[pallet::config]
pub trait Config: frame_system::Config {
#[pezpallet::config]
pub trait Config: pezframe_system::Config {
type ExternalOrigin: EnsureOrigin<Self::RuntimeOrigin>;
}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[docify::export(external_origin_usage)]
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
pub fn externally_checked_ext(origin: OriginFor<T>) -> DispatchResult {
T::ExternalOrigin::ensure_origin(origin)?;
todo!();
@@ -249,22 +250,22 @@ pub mod pallet_with_external_origin {
pub mod runtime_for_external_origin {
use super::*;
use frame::{runtime::prelude::*, testing_prelude::*};
use pezframe::{runtime::prelude::*, testing_prelude::*};
construct_runtime!(
pub struct Runtime {
System: frame_system,
PalletWithExternalOrigin: pallet_with_external_origin,
System: pezframe_system,
PalletWithExternalOrigin: pezpallet_with_external_origin,
}
);
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Self>;
}
#[docify::export(external_origin_provide)]
impl pallet_with_external_origin::Config for Runtime {
type ExternalOrigin = EnsureSigned<<Self as frame_system::Config>::AccountId>;
impl pezpallet_with_external_origin::Config for Runtime {
type ExternalOrigin = EnsureSigned<<Self as pezframe_system::Config>::AccountId>;
}
}
@@ -1,32 +1,33 @@
//! # FRAME Pallet Coupling
//! # FRAME Pezpallet Coupling
//!
//! This reference document explains how FRAME pallets can be combined to interact together.
//!
//! It is suggested to re-read [`crate::pezkuwi_sdk::frame_runtime`], notably the information
//! around [`frame::pallet_macros::config`]. Recall that:
//! around [`pezframe::pezpallet_macros::config`]. Recall that:
//!
//! > Configuration trait of a pallet: It allows a pallet to receive types at a later
//! > point from the runtime that wishes to contain it. It allows the pallet to be parameterized
//! > Configuration trait of a pezpallet: It allows a pezpallet to receive types at a later
//! > point from the runtime that wishes to contain it. It allows the pezpallet to be parameterized
//! > over both types and values.
//!
//! ## Context, Background
//!
//! FRAME pallets, as per described in [`crate::pezkuwi_sdk::frame_runtime`] are:
//!
//! > A pallet is a unit of encapsulated logic. It has a clearly defined responsibility and can be
//! > A pezpallet is a unit of encapsulated logic. It has a clearly defined responsibility and can
//! > be
//! linked to other pallets.
//!
//! That is to say:
//!
//! * *encapsulated*: Ideally, a FRAME pallet contains encapsulated logic which has clear
//! boundaries. It is generally a bad idea to build a single monolithic pallet that does multiple
//! things, such as handling currencies, identities and staking all at the same time.
//! * *encapsulated*: Ideally, a FRAME pezpallet contains encapsulated logic which has clear
//! boundaries. It is generally a bad idea to build a single monolithic pezpallet that does
//! multiple things, such as handling currencies, identities and staking all at the same time.
//! * *linked to other pallets*: But, adhering extensively to the above also hinders the ability to
//! write useful applications. Pallets often need to work with each other, communicate and use
//! each other's functionalities.
//!
//! The broad principle that allows pallets to be linked together is the same way through which a
//! pallet uses its `Config` trait to receive types and values from the runtime that contains it.
//! pezpallet uses its `Config` trait to receive types and values from the runtime that contains it.
//!
//! There are generally two ways to achieve this:
//!
@@ -63,52 +64,52 @@
//!
//! ## Example
//!
//! Consider the following example, in which `pallet-foo` needs another pallet to provide the block
//! author to it, and `pallet-author` which has access to this information.
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", pallet_foo)]
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", pallet_author)]
//! Consider the following example, in which `pezpallet-foo` needs another pezpallet to provide the
//! block author to it, and `pezpallet-author` which has access to this information.
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", pezpallet_foo)]
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", pezpallet_author)]
//!
//! ### Tight Coupling Pallets
//!
//! To tightly couple `pallet-foo` and `pallet-author`, we use Rust's supertrait system. When a
//! pallet makes its own `trait Config` be bounded by another pallet's `trait Config`, it is
//! To tightly couple `pezpallet-foo` and `pezpallet-author`, we use Rust's supertrait system. When
//! a pezpallet makes its own `trait Config` be bounded by another pezpallet's `trait Config`, it is
//! expressing two things:
//!
//! 1. That it can only exist in a runtime if the other pallet is also present.
//! 2. That it can use the other pallet's functionality.
//! 1. That it can only exist in a runtime if the other pezpallet is also present.
//! 2. That it can use the other pezpallet's functionality.
//!
//! `pallet-foo`'s `Config` would then look like:
//! `pezpallet-foo`'s `Config` would then look like:
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", tight_config)]
//!
//! And `pallet-foo` can use the method exposed by `pallet_author::Pallet` directly:
//! And `pezpallet-foo` can use the method exposed by `pezpallet_author::Pezpallet` directly:
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", tight_usage)]
//!
//!
//! ### Loosely Coupling Pallets
//!
//! If `pallet-foo` wants to *not* rely on `pallet-author` directly, it can leverage its
//! If `pezpallet-foo` wants to *not* rely on `pezpallet-author` directly, it can leverage its
//! `Config`'s associated types. First, we need a trait to express the functionality that
//! `pallet-foo` wants to obtain:
//! `pezpallet-foo` wants to obtain:
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", AuthorProvider)]
//!
//! > We sometimes refer to such traits that help two pallets interact as "glue traits".
//!
//! Next, `pallet-foo` states that it needs this trait to be provided to it, at the runtime level,
//! via an associated type:
//! Next, `pezpallet-foo` states that it needs this trait to be provided to it, at the runtime
//! level, via an associated type:
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", loose_config)]
//!
//! Then, `pallet-foo` can use this trait to obtain the block author, without knowing where it comes
//! from:
//! Then, `pezpallet-foo` can use this trait to obtain the block author, without knowing where it
//! comes from:
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", loose_usage)]
//!
//! Then, if `pallet-author` implements this glue-trait:
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", pallet_author_provider)]
//! Then, if `pezpallet-author` implements this glue-trait:
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", pezpallet_author_provider)]
//!
//! And upon the creation of the runtime, the two pallets are linked together as such:
#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", runtime_author_provider)]
//!
//! Crucially, when using loose coupling, we gain the flexibility of providing different
//! implementations of `AuthorProvider`, such that different users of a `pallet-foo` can use
//! implementations of `AuthorProvider`, such that different users of a `pezpallet-foo` can use
//! different ones, without any code change being needed. For example, in the code snippets of this
//! module, you can find [`OtherAuthorProvider`], which is an alternative implementation of
//! [`AuthorProvider`].
@@ -120,11 +121,11 @@
//!
//! ## Frame System
//!
//! With the above information in context, we can conclude that **`frame_system` is a special pallet
//! that is tightly coupled with every other pallet**. This is because it provides the fundamental
//! system functionality that every pallet needs, such as some types like
//! [`frame::prelude::frame_system::Config::AccountId`],
//! [`frame::prelude::frame_system::Config::Hash`], and some functionality such as block number,
//! With the above information in context, we can conclude that **`pezframe_system` is a special
//! pezpallet that is tightly coupled with every other pezpallet**. This is because it provides the
//! fundamental system functionality that every pezpallet needs, such as some types like
//! [`pezframe::prelude::pezframe_system::Config::AccountId`],
//! [`pezframe::prelude::pezframe_system::Config::Hash`], and some functionality such as block number,
//! etc.
//!
//! ## Recap
@@ -132,43 +133,44 @@
//! To recap, consider the following rules of thumb:
//!
//! * In all cases, try and break down big pallets apart with clear boundaries of responsibility. In
//! general, it is easier to argue about multiple pallet if they only communicate together via a
//! known trait, rather than having access to all of each others public items, such as storage and
//! dispatchables.
//! general, it is easier to argue about multiple pezpallet if they only communicate together via
//! a known trait, rather than having access to all of each others public items, such as storage
//! and dispatchables.
//! * If a group of pallets is meant to work together, but is not foreseen to be generalized, or
//! used by others, consider tightly coupling pallets, *if it simplifies the development*.
//! * If a pallet needs a functionality provided by another pallet, but multiple implementations can
//! be foreseen, consider loosely coupling pallets.
//! * If a pezpallet needs a functionality provided by another pezpallet, but multiple
//! implementations can be foreseen, consider loosely coupling pallets.
//!
//! For example, all pallets in `pezkuwi-sdk` that needed to work with currencies could have been
//! tightly coupled with [`pallet_balances`]. But, `pezkuwi-sdk` also provides [`pallet_assets`]
//! (and more implementations by the community), therefore all pallets use traits to loosely couple
//! with balances or assets pallet. More on this in [`crate::reference_docs::frame_tokens`].
//! tightly coupled with [`pezpallet_balances`]. But, `pezkuwi-sdk` also provides
//! [`pezpallet_assets`] (and more implementations by the community), therefore all pallets use
//! traits to loosely couple with balances or assets pezpallet. More on this in
//! [`crate::reference_docs::frame_tokens`].
//!
//! ## Further References
//!
//! - <https://www.youtube.com/watch?v=0eNGZpNkJk4>
//! - <https://exchange.pezkuwichain.app/questions/922/pallet-loose-couplingtight-coupling-and-missing-traits>
//! - <https://exchange.pezkuwichain.app/questions/922/pezpallet-loose-couplingtight-coupling-and-missing-traits>
//!
//! [`AuthorProvider`]: crate::reference_docs::frame_pallet_coupling::AuthorProvider
//! [`OtherAuthorProvider`]: crate::reference_docs::frame_pallet_coupling::OtherAuthorProvider
#![allow(unused)]
use frame::prelude::*;
use pezframe::prelude::*;
#[docify::export]
#[frame::pallet]
pub mod pallet_foo {
#[pezframe::pezpallet]
pub mod pezpallet_foo {
use super::*;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
impl<T: Config> Pallet<T> {
impl<T: Config> Pezpallet<T> {
fn do_stuff_with_author() {
// needs block author here
}
@@ -176,41 +178,42 @@ pub mod pallet_foo {
}
#[docify::export]
#[frame::pallet]
pub mod pallet_author {
#[pezframe::pezpallet]
pub mod pezpallet_author {
use super::*;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
impl<T: Config> Pallet<T> {
impl<T: Config> Pezpallet<T> {
pub fn author() -> T::AccountId {
todo!("somehow has access to the block author and can return it here")
}
}
}
#[frame::pallet]
pub mod pallet_foo_tight {
#[pezframe::pezpallet]
pub mod pezpallet_foo_tight {
use super::*;
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[docify::export(tight_config)]
/// This pallet can only live in a runtime that has both `frame_system` and `pallet_author`.
#[pallet::config]
pub trait Config: frame_system::Config + pallet_author::Config {}
/// This pezpallet can only live in a runtime that has both `pezframe_system` and
/// `pezpallet_author`.
#[pezpallet::config]
pub trait Config: pezframe_system::Config + pezpallet_author::Config {}
#[docify::export(tight_usage)]
impl<T: Config> Pallet<T> {
// anywhere in `pallet-foo`, we can call into `pallet-author` directly, namely because
// `T: pallet_author::Config`
impl<T: Config> Pezpallet<T> {
// anywhere in `pezpallet-foo`, we can call into `pezpallet-author` directly, namely because
// `T: pezpallet_author::Config`
fn do_stuff_with_author() {
let _ = pallet_author::Pallet::<T>::author();
let _ = pezpallet_author::Pezpallet::<T>::author();
}
}
}
@@ -221,33 +224,33 @@ pub trait AuthorProvider<AccountId> {
fn author() -> AccountId;
}
#[frame::pallet]
pub mod pallet_foo_loose {
#[pezframe::pezpallet]
pub mod pezpallet_foo_loose {
use super::*;
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[docify::export(loose_config)]
#[pallet::config]
pub trait Config: frame_system::Config {
/// This pallet relies on the existence of something that implements [`AuthorProvider`],
/// which may or may not be `pallet-author`.
#[pezpallet::config]
pub trait Config: pezframe_system::Config {
/// This pezpallet relies on the existence of something that implements [`AuthorProvider`],
/// which may or may not be `pezpallet-author`.
type AuthorProvider: AuthorProvider<Self::AccountId>;
}
#[docify::export(loose_usage)]
impl<T: Config> Pallet<T> {
impl<T: Config> Pezpallet<T> {
fn do_stuff_with_author() {
let _ = T::AuthorProvider::author();
}
}
}
#[docify::export(pallet_author_provider)]
impl<T: pallet_author::Config> AuthorProvider<T::AccountId> for pallet_author::Pallet<T> {
#[docify::export(pezpallet_author_provider)]
impl<T: pezpallet_author::Config> AuthorProvider<T::AccountId> for pezpallet_author::Pezpallet<T> {
fn author() -> T::AccountId {
pallet_author::Pallet::<T>::author()
pezpallet_author::Pezpallet::<T>::author()
}
}
@@ -269,27 +272,27 @@ impl<AccountId> AuthorProvider<AccountId> for () {
pub mod runtime {
use super::*;
use cumulus_pallet_aura_ext::pallet;
use frame::{runtime::prelude::*, testing_prelude::*};
use pezcumulus_pezpallet_aura_ext::pezpallet;
use pezframe::{runtime::prelude::*, testing_prelude::*};
construct_runtime!(
pub struct Runtime {
System: frame_system,
PalletFoo: pallet_foo_loose,
PalletAuthor: pallet_author,
System: pezframe_system,
PalletFoo: pezpallet_foo_loose,
PalletAuthor: pezpallet_author,
}
);
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Self>;
}
impl pallet_author::Config for Runtime {}
impl pezpallet_author::Config for Runtime {}
#[docify::export(runtime_author_provider)]
impl pallet_foo_loose::Config for Runtime {
type AuthorProvider = pallet_author::Pallet<Runtime>;
impl pezpallet_foo_loose::Config for Runtime {
type AuthorProvider = pezpallet_author::Pezpallet<Runtime>;
// which is also equivalent to
// type AuthorProvider = PalletAuthor;
}
@@ -0,0 +1,296 @@
//! # FRAME Pezpallet Coupling
//!
//! This reference document explains how FRAME pezpallets can be combined to interact together.
//!
//! It is suggested to re-read [`crate::pezkuwi_sdk::frame_runtime`], notably the information
//! around [`pezframe::pezpallet_macros::config`]. Recall that:
//!
//! > Configuration trait of a pezpallet: It allows a pezpallet to receive types at a later
//! > point from the runtime that wishes to contain it. It allows the pezpallet to be parameterized
//! > over both types and values.
//!
//! ## Context, Background
//!
//! FRAME pezpallets, as per described in [`crate::pezkuwi_sdk::frame_runtime`] are:
//!
//! > A pezpallet is a unit of encapsulated logic. It has a clearly defined responsibility and can be
//! linked to other pezpallets.
//!
//! That is to say:
//!
//! * *encapsulated*: Ideally, a FRAME pezpallet contains encapsulated logic which has clear
//! boundaries. It is generally a bad idea to build a single monolithic pezpallet that does multiple
//! things, such as handling currencies, identities and staking all at the same time.
//! * *linked to other pezpallets*: But, adhering extensively to the above also hinders the ability to
//! write useful applications. Pezpallets often need to work with each other, communicate and use
//! each other's functionalities.
//!
//! The broad principle that allows pezpallets to be linked together is the same way through which a
//! pezpallet uses its `Config` trait to receive types and values from the runtime that contains it.
//!
//! There are generally two ways to achieve this:
//!
//! 1. Tight coupling pezpallets.
//! 2. Loose coupling pezpallets.
//!
//! To explain the difference between the two, consider two pezpallets, `A` and `B`. In both cases, `A`
//! wants to use some functionality exposed by `B`.
//!
//! When tightly coupling pezpallets, `A` can only exist in a runtime if `B` is also present in the
//! same runtime. That is, `A` is expressing that can only work if `B` is present.
//!
//! This translates to the following Rust code:
//!
//! ```
//! trait Pezpallet_B_Config {}
//! trait Pezpallet_A_Config: Pezpallet_B_Config {}
//! ```
//!
//! Contrary, when pezpallets are loosely coupled, `A` expresses that some functionality, expressed via
//! a trait `F`, needs to be fulfilled. This trait is then implemented by `B`, and the two pezpallets
//! are linked together at the runtime level. This means that `A` only relies on the implementation
//! of `F`, which may be `B`, or another implementation of `F`.
//!
//! This translates to the following Rust code:
//!
//! ```
//! trait F {}
//! trait Pezpallet_A_Config {
//! type F: F;
//! }
//! // Pezpallet_B will implement and fulfill `F`.
//! ```
//!
//! ## Example
//!
//! Consider the following example, in which `pezpallet-foo` needs another pezpallet to provide the block
//! author to it, and `pezpallet-author` which has access to this information.
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", pezpallet_foo)]
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", pezpallet_author)]
//!
//! ### Tight Coupling Pezpallets
//!
//! To tightly couple `pezpallet-foo` and `pezpallet-author`, we use Rust's supertrait system. When a
//! pezpallet makes its own `trait Config` be bounded by another pezpallet's `trait Config`, it is
//! expressing two things:
//!
//! 1. That it can only exist in a runtime if the other pezpallet is also present.
//! 2. That it can use the other pezpallet's functionality.
//!
//! `pezpallet-foo`'s `Config` would then look like:
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", tight_config)]
//!
//! And `pezpallet-foo` can use the method exposed by `pezpallet_author::Pezpallet` directly:
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", tight_usage)]
//!
//!
//! ### Loosely Coupling Pezpallets
//!
//! If `pezpallet-foo` wants to *not* rely on `pezpallet-author` directly, it can leverage its
//! `Config`'s associated types. First, we need a trait to express the functionality that
//! `pezpallet-foo` wants to obtain:
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", AuthorProvider)]
//!
//! > We sometimes refer to such traits that help two pezpallets interact as "glue traits".
//!
//! Next, `pezpallet-foo` states that it needs this trait to be provided to it, at the runtime level,
//! via an associated type:
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", loose_config)]
//!
//! Then, `pezpallet-foo` can use this trait to obtain the block author, without knowing where it comes
//! from:
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", loose_usage)]
//!
//! Then, if `pezpallet-author` implements this glue-trait:
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", pezpallet_author_provider)]
//!
//! And upon the creation of the runtime, the two pezpallets are linked together as such:
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", runtime_author_provider)]
//!
//! Crucially, when using loose coupling, we gain the flexibility of providing different
//! implementations of `AuthorProvider`, such that different users of a `pezpallet-foo` can use
//! different ones, without any code change being needed. For example, in the code snippets of this
//! module, you can find [`OtherAuthorProvider`], which is an alternative implementation of
//! [`AuthorProvider`].
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", other_author_provider)]
//!
//! A common pattern in pezkuwi-sdk is to provide an implementation of such glu traits for the unit
//! type as a "default/test behavior".
#![doc = docify::embed!("./src/reference_docs/frame_pezpallet_coupling.rs", unit_author_provider)]
//!
//! ## Frame System
//!
//! With the above information in context, we can conclude that **`pezframe_system` is a special pezpallet
//! that is tightly coupled with every other pezpallet**. This is because it provides the fundamental
//! system functionality that every pezpallet needs, such as some types like
//! [`pezframe::prelude::pezframe_system::Config::AccountId`],
//! [`pezframe::prelude::pezframe_system::Config::Hash`], and some functionality such as block number,
//! etc.
//!
//! ## Recap
//!
//! To recap, consider the following rules of thumb:
//!
//! * In all cases, try and break down big pezpallets apart with clear boundaries of responsibility. In
//! general, it is easier to argue about multiple pezpallet if they only communicate together via a
//! known trait, rather than having access to all of each others public items, such as storage and
//! dispatchables.
//! * If a group of pezpallets is meant to work together, but is not foreseen to be generalized, or
//! used by others, consider tightly coupling pezpallets, *if it simplifies the development*.
//! * If a pezpallet needs a functionality provided by another pezpallet, but multiple implementations can
//! be foreseen, consider loosely coupling pezpallets.
//!
//! For example, all pezpallets in `pezkuwi-sdk` that needed to work with currencies could have been
//! tightly coupled with [`pezpallet_balances`]. But, `pezkuwi-sdk` also provides [`pezpallet_assets`]
//! (and more implementations by the community), therefore all pezpallets use traits to loosely couple
//! with balances or assets pezpallet. More on this in [`crate::reference_docs::frame_tokens`].
//!
//! ## Further References
//!
//! - <https://www.youtube.com/watch?v=0eNGZpNkJk4>
//! - <https://exchange.pezkuwichain.app/questions/922/pezpallet-loose-couplingtight-coupling-and-missing-traits>
//!
//! [`AuthorProvider`]: crate::reference_docs::frame_pezpallet_coupling::AuthorProvider
//! [`OtherAuthorProvider`]: crate::reference_docs::frame_pezpallet_coupling::OtherAuthorProvider
#![allow(unused)]
use pezframe::prelude::*;
#[docify::export]
#[pezframe::pezpallet]
pub mod pezpallet_foo {
use super::*;
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
impl<T: Config> Pezpallet<T> {
fn do_stuff_with_author() {
// needs block author here
}
}
}
#[docify::export]
#[pezframe::pezpallet]
pub mod pezpallet_author {
use super::*;
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
impl<T: Config> Pezpallet<T> {
pub fn author() -> T::AccountId {
todo!("somehow has access to the block author and can return it here")
}
}
}
#[pezframe::pezpallet]
pub mod pezpallet_foo_tight {
use super::*;
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[docify::export(tight_config)]
/// This pezpallet can only live in a runtime that has both `pezframe_system` and `pezpallet_author`.
#[pezpallet::config]
pub trait Config: pezframe_system::Config + pezpallet_author::Config {}
#[docify::export(tight_usage)]
impl<T: Config> Pezpallet<T> {
// anywhere in `pezpallet-foo`, we can call into `pezpallet-author` directly, namely because
// `T: pezpallet_author::Config`
fn do_stuff_with_author() {
let _ = pezpallet_author::Pezpallet::<T>::author();
}
}
}
#[docify::export]
/// Abstraction over "something that can provide the block author".
pub trait AuthorProvider<AccountId> {
fn author() -> AccountId;
}
#[pezframe::pezpallet]
pub mod pezpallet_foo_loose {
use super::*;
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[docify::export(loose_config)]
#[pezpallet::config]
pub trait Config: pezframe_system::Config {
/// This pezpallet relies on the existence of something that implements [`AuthorProvider`],
/// which may or may not be `pezpallet-author`.
type AuthorProvider: AuthorProvider<Self::AccountId>;
}
#[docify::export(loose_usage)]
impl<T: Config> Pezpallet<T> {
fn do_stuff_with_author() {
let _ = T::AuthorProvider::author();
}
}
}
#[docify::export(pezpallet_author_provider)]
impl<T: pezpallet_author::Config> AuthorProvider<T::AccountId> for pezpallet_author::Pezpallet<T> {
fn author() -> T::AccountId {
pezpallet_author::Pezpallet::<T>::author()
}
}
pub struct OtherAuthorProvider;
#[docify::export(other_author_provider)]
impl<AccountId> AuthorProvider<AccountId> for OtherAuthorProvider {
fn author() -> AccountId {
todo!("somehow get the block author here")
}
}
#[docify::export(unit_author_provider)]
impl<AccountId> AuthorProvider<AccountId> for () {
fn author() -> AccountId {
todo!("somehow get the block author here")
}
}
pub mod runtime {
use super::*;
use pezcumulus_pezpallet_aura_ext::pezpallet;
use pezframe::{runtime::prelude::*, testing_prelude::*};
construct_runtime!(
pub struct Runtime {
System: pezframe_system,
PezpalletFoo: pezpallet_foo_loose,
PezpalletAuthor: pezpallet_author,
}
);
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Self>;
}
impl pezpallet_author::Config for Runtime {}
#[docify::export(runtime_author_provider)]
impl pezpallet_foo_loose::Config for Runtime {
type AuthorProvider = pezpallet_author::Pezpallet<Runtime>;
// which is also equivalent to
// type AuthorProvider = PezpalletAuthor;
}
}
@@ -5,7 +5,7 @@
//!
//! > As of now, many of these important types are generated within the internals of
//! > [`construct_runtime`], and there is no easy way for you to visually know they exist.
//! > [#pezkuwi-sdk#1378](https://github.com/paritytech/polkadot-sdk/pull/1378) is meant to
//! > [#pezkuwi-sdk#1378](https://github.com/pezkuwichain/pezkuwi-sdk/issues/251) is meant to
//! > significantly improve this. Exploring the rust-docs of a runtime, such as [`runtime`] which is
//! > defined in this module is as of now the best way to learn about these types.
//!
@@ -13,7 +13,7 @@
//!
//! Many types within a FRAME runtime follow the following structure:
//!
//! * Each individual pallet defines a type, for example `Foo`.
//! * Each individual pezpallet defines a type, for example `Foo`.
//! * At the runtime level, these types are amalgamated into a single type, for example
//! `RuntimeFoo`.
//!
@@ -29,24 +29,24 @@
//!
//! ### Example
//!
//! We provide the following two pallets: [`pallet_foo`] and [`pallet_bar`]. Each define a
//! We provide the following two pallets: [`pezpallet_foo`] and [`pezpallet_bar`]. Each define a
//! dispatchable, and `Foo` also defines a custom origin. Lastly, `Bar` defines an additional
//! `GenesisConfig`.
#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_foo)]
#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_bar)]
#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pezpallet_foo)]
#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pezpallet_bar)]
//!
//! Let's explore how each of these affect the [`RuntimeCall`], [`RuntimeOrigin`] and
//! [`RuntimeGenesisConfig`] generated in [`runtime`] respectively.
//!
//! As observed, [`RuntimeCall`] has 3 variants, one for each pallet and one for `frame_system`. If
//! you explore further, you will soon realize that each variant is merely a pointer to the `Call`
//! type in each pallet, for example [`pallet_foo::Call`].
//! As observed, [`RuntimeCall`] has 3 variants, one for each pezpallet and one for
//! `pezframe_system`. If you explore further, you will soon realize that each variant is merely a
//! pointer to the `Call` type in each pezpallet, for example [`pezpallet_foo::Call`].
//!
//! [`RuntimeOrigin`]'s [`OriginCaller`] has two variants, one for system, and one for `pallet_foo`
//! which utilized [`frame::pallet_macros::origin`].
//! [`RuntimeOrigin`]'s [`OriginCaller`] has two variants, one for system, and one for
//! `pezpallet_foo` which utilized [`pezframe::pezpallet_macros::origin`].
//!
//! Finally, [`RuntimeGenesisConfig`] is composed of `frame_system` and a variant for `pallet_bar`'s
//! [`pallet_bar::GenesisConfig`].
//! Finally, [`RuntimeGenesisConfig`] is composed of `pezframe_system` and a variant for
//! `pezpallet_bar`'s [`pezpallet_bar::GenesisConfig`].
//!
//! You can find other composite enums by scanning [`runtime`] for other types who's name starts
//! with `Runtime`. Some of the more noteworthy ones are:
@@ -57,77 +57,78 @@
//!
//! ### Adding Further Constraints to Runtime Composite Enums
//!
//! This section explores a common scenario where a pallet has access to one of these runtime
//! This section explores a common scenario where a pezpallet has access to one of these runtime
//! composite enums, but it wishes to further specify it by adding more trait bounds to it.
//!
//! Let's take the example of `RuntimeCall`. This is an associated type in
//! [`frame_system::Config::RuntimeCall`], and all pallets have access to this type, because they
//! have access to [`frame_system::Config`]. Finally, this type is meant to be set to outer call of
//! the entire runtime.
//! [`pezframe_system::Config::RuntimeCall`], and all pallets have access to this type, because they
//! have access to [`pezframe_system::Config`]. Finally, this type is meant to be set to outer call
//! of the entire runtime.
//!
//! But, let's not forget that this is information that *we know*, and the Rust compiler does not.
//! All that the rust compiler knows about this type is *ONLY* what the trait bounds of
//! [`frame_system::Config::RuntimeCall`] are specifying:
#![doc = docify::embed!("../../substrate/frame/system/src/lib.rs", system_runtime_call)]
//! [`pezframe_system::Config::RuntimeCall`] are specifying:
#![doc = docify::embed!("../../bizinikiwi/pezframe/system/src/lib.rs", system_runtime_call)]
//!
//! So, when at a given pallet, one accesses `<T as frame_system::Config>::RuntimeCall`, the type is
//! extremely opaque from the perspective of the Rust compiler.
//! So, when at a given pezpallet, one accesses `<T as pezframe_system::Config>::RuntimeCall`, the
//! type is extremely opaque from the perspective of the Rust compiler.
//!
//! How can a pallet access the `RuntimeCall` type with further constraints? For example, each
//! pallet has its own `enum Call`, and knows that its local `Call` is a part of `RuntimeCall`,
//! How can a pezpallet access the `RuntimeCall` type with further constraints? For example, each
//! pezpallet has its own `enum Call`, and knows that its local `Call` is a part of `RuntimeCall`,
//! therefore there should be a `impl From<Call<_>> for RuntimeCall`.
//!
//! The only way to express this using Rust's associated types is for the pallet to **define its own
//! associated type `RuntimeCall`, and further specify what it thinks `RuntimeCall` should be**.
//! The only way to express this using Rust's associated types is for the pezpallet to **define its
//! own associated type `RuntimeCall`, and further specify what it thinks `RuntimeCall` should be**.
//!
//! In this case, we will want to assert the existence of [`frame::traits::IsSubType`], which is
//! In this case, we will want to assert the existence of [`pezframe::traits::IsSubType`], which is
//! very similar to [`TryFrom`].
#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", custom_runtime_call)]
//!
//! And indeed, at the runtime level, this associated type would be the same `RuntimeCall` that is
//! passed to `frame_system`.
#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_with_specific_runtime_call_impl)]
//! passed to `pezframe_system`.
#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pezpallet_with_specific_runtime_call_impl)]
//!
//! > In other words, the degree of specificity that [`frame_system::Config::RuntimeCall`] has is
//! > not enough for the pallet to work with. Therefore, the pallet has to define its own associated
//! > In other words, the degree of specificity that [`pezframe_system::Config::RuntimeCall`] has is
//! > not enough for the pezpallet to work with. Therefore, the pezpallet has to define its own
//! > associated
//! > type representing `RuntimeCall`.
//!
//! Another way to look at this is:
//!
//! `pallet_with_specific_runtime_call::Config::RuntimeCall` and `frame_system::Config::RuntimeCall`
//! are two different representations of the same concrete type that is only known when the runtime
//! is being constructed.
//! `pezpallet_with_specific_runtime_call::Config::RuntimeCall` and
//! `pezframe_system::Config::RuntimeCall` are two different representations of the same concrete
//! type that is only known when the runtime is being constructed.
//!
//! Now, within this pallet, this new `RuntimeCall` can be used, and it can use its new trait
//! bounds, such as being [`frame::traits::IsSubType`]:
//! Now, within this pezpallet, this new `RuntimeCall` can be used, and it can use its new trait
//! bounds, such as being [`pezframe::traits::IsSubType`]:
#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", custom_runtime_call_usages)]
//!
//! > Once Rust's "_Associated Type Bounds RFC_" is usable, this syntax can be used to
//! > simplify the above scenario. See [this](https://github.com/pezkuwichain/pezkuwi-sdk/issues/133)
//! > simplify the above scenario. See [this](https://github.com/pezkuwichain/pezkuwi-sdk/issues/278)
//! > issue for more information.
//!
//! ### Asserting Equality of Multiple Runtime Composite Enums
//!
//! Recall that in the above example, `<T as Config>::RuntimeCall` and `<T as
//! frame_system::Config>::RuntimeCall` are expected to be equal types, but at the compile-time we
//! have to represent them with two different associated types with different bounds. Would it not
//! be cool if we had a test to make sure they actually resolve to the same concrete type once the
//! runtime is constructed? The following snippet exactly does that:
//! pezframe_system::Config>::RuntimeCall` are expected to be equal types, but at the compile-time
//! we have to represent them with two different associated types with different bounds. Would it
//! not be cool if we had a test to make sure they actually resolve to the same concrete type once
//! the runtime is constructed? The following snippet exactly does that:
#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", assert_equality)]
//!
//! We leave it to the reader to further explore what [`frame::traits::Hooks::integrity_test`] is,
//! We leave it to the reader to further explore what [`pezframe::traits::Hooks::integrity_test`] is,
//! and what [`core::any::TypeId`] is. Another way to assert this is using
//! [`frame::traits::IsType`].
//! [`pezframe::traits::IsType`].
//!
//! ## Type Aliases
//!
//! A number of type aliases are generated by the `construct_runtime` which are also noteworthy:
//!
//! * [`runtime::PalletFoo`] is an alias to [`pallet_foo::Pallet`]. Same for `PalletBar`, and
//! * [`runtime::PalletFoo`] is an alias to [`pezpallet_foo::Pezpallet`]. Same for `PalletBar`, and
//! `System`
//! * [`runtime::AllPalletsWithSystem`] is an alias for a tuple of all of the above. This type is
//! important to FRAME internals such as `executive`, as it implements traits such as
//! [`frame::traits::Hooks`].
//! [`pezframe::traits::Hooks`].
//!
//! ## Further Details
//!
@@ -139,15 +140,15 @@
//! * See the corresponding lecture in the [PBA Lectures](https://www.youtube.com/watch?v=OCBC1pMYPoc&list=PL-w_i5kwVqbni1Ch2j_RwTIXiB-bwnYqq&index=11).
//!
//!
//! [`construct_runtime`]: frame::runtime::prelude::construct_runtime
//! [`construct_runtime`]: pezframe::runtime::prelude::construct_runtime
//! [`runtime::PalletFoo`]: crate::reference_docs::frame_runtime_types::runtime::PalletFoo
//! [`runtime::AllPalletsWithSystem`]: crate::reference_docs::frame_runtime_types::runtime::AllPalletsWithSystem
//! [`runtime`]: crate::reference_docs::frame_runtime_types::runtime
//! [`pallet_foo`]: crate::reference_docs::frame_runtime_types::pallet_foo
//! [`pallet_foo::Call`]: crate::reference_docs::frame_runtime_types::pallet_foo::Call
//! [`pallet_foo::Pallet`]: crate::reference_docs::frame_runtime_types::pallet_foo::Pallet
//! [`pallet_bar`]: crate::reference_docs::frame_runtime_types::pallet_bar
//! [`pallet_bar::GenesisConfig`]: crate::reference_docs::frame_runtime_types::pallet_bar::GenesisConfig
//! [`pezpallet_foo`]: crate::reference_docs::frame_runtime_types::pezpallet_foo
//! [`pezpallet_foo::Call`]: crate::reference_docs::frame_runtime_types::pezpallet_foo::Call
//! [`pezpallet_foo::Pezpallet`]: crate::reference_docs::frame_runtime_types::pezpallet_foo::Pezpallet
//! [`pezpallet_bar`]: crate::reference_docs::frame_runtime_types::pezpallet_bar
//! [`pezpallet_bar::GenesisConfig`]: crate::reference_docs::frame_runtime_types::pezpallet_bar::GenesisConfig
//! [`RuntimeEvent`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeEvent
//! [`RuntimeGenesisConfig`]:
//! crate::reference_docs::frame_runtime_types::runtime::RuntimeGenesisConfig
@@ -157,17 +158,17 @@
//! [`RuntimeCall`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeCall
//! [`RuntimeHoldReason`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeHoldReason
use frame::prelude::*;
use pezframe::prelude::*;
#[docify::export]
#[frame::pallet(dev_mode)]
pub mod pallet_foo {
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet_foo {
use super::*;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::origin]
#[pezpallet::origin]
#[derive(
PartialEq,
Eq,
@@ -184,11 +185,11 @@ pub mod pallet_foo {
B,
}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
pub fn foo(_origin: OriginFor<T>) -> DispatchResult {
todo!();
}
@@ -200,29 +201,29 @@ pub mod pallet_foo {
}
#[docify::export]
#[frame::pallet(dev_mode)]
pub mod pallet_bar {
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet_bar {
use super::*;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pezpallet::config]
pub trait Config: pezframe_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[pallet::genesis_config]
#[pezpallet::genesis_config]
#[derive(DefaultNoBound)]
pub struct GenesisConfig<T: Config> {
pub initial_account: Option<T::AccountId>,
}
#[pallet::genesis_build]
#[pezpallet::genesis_build]
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
fn build(&self) {}
}
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
pub fn bar(_origin: OriginFor<T>) -> DispatchResult {
todo!();
}
@@ -230,90 +231,90 @@ pub mod pallet_bar {
}
pub mod runtime {
use super::{pallet_bar, pallet_foo};
use frame::{runtime::prelude::*, testing_prelude::*};
use super::{pezpallet_bar, pezpallet_foo};
use pezframe::{runtime::prelude::*, testing_prelude::*};
#[docify::export(runtime_exp)]
construct_runtime!(
pub struct Runtime {
System: frame_system,
PalletFoo: pallet_foo,
PalletBar: pallet_bar,
System: pezframe_system,
PalletFoo: pezpallet_foo,
PalletBar: pezpallet_bar,
}
);
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Self>;
}
impl pallet_foo::Config for Runtime {}
impl pallet_bar::Config for Runtime {}
impl pezpallet_foo::Config for Runtime {}
impl pezpallet_bar::Config for Runtime {}
}
#[frame::pallet(dev_mode)]
pub mod pallet_with_specific_runtime_call {
#[pezframe::pezpallet(dev_mode)]
pub mod pezpallet_with_specific_runtime_call {
use super::*;
use frame::traits::IsSubType;
use pezframe::traits::IsSubType;
#[docify::export(custom_runtime_call)]
/// A pallet that wants to further narrow down what `RuntimeCall` is.
#[pallet::config]
pub trait Config: frame_system::Config {
/// A pezpallet that wants to further narrow down what `RuntimeCall` is.
#[pezpallet::config]
pub trait Config: pezframe_system::Config {
type RuntimeCall: IsSubType<Call<Self>>;
}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
// note that this pallet needs some `call` to have a `enum Call`.
#[pallet::call]
impl<T: Config> Pallet<T> {
// note that this pezpallet needs some `call` to have a `enum Call`.
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
pub fn foo(_origin: OriginFor<T>) -> DispatchResult {
todo!();
}
}
#[docify::export(custom_runtime_call_usages)]
impl<T: Config> Pallet<T> {
impl<T: Config> Pezpallet<T> {
fn _do_something_useful_with_runtime_call(call: <T as Config>::RuntimeCall) {
// check if the runtime call given is of this pallet's variant.
// check if the runtime call given is of this pezpallet's variant.
let _maybe_my_call: Option<&Call<T>> = call.is_sub_type();
todo!();
}
}
#[docify::export(assert_equality)]
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
#[pezpallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pezpallet<T> {
fn integrity_test() {
use core::any::TypeId;
assert_eq!(
TypeId::of::<<T as Config>::RuntimeCall>(),
TypeId::of::<<T as frame_system::Config>::RuntimeCall>()
TypeId::of::<<T as pezframe_system::Config>::RuntimeCall>()
);
}
}
}
pub mod runtime_with_specific_runtime_call {
use super::pallet_with_specific_runtime_call;
use frame::{runtime::prelude::*, testing_prelude::*};
use super::pezpallet_with_specific_runtime_call;
use pezframe::{runtime::prelude::*, testing_prelude::*};
construct_runtime!(
pub struct Runtime {
System: frame_system,
PalletWithSpecificRuntimeCall: pallet_with_specific_runtime_call,
System: pezframe_system,
PalletWithSpecificRuntimeCall: pezpallet_with_specific_runtime_call,
}
);
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = MockBlock<Self>;
}
#[docify::export(pallet_with_specific_runtime_call_impl)]
impl pallet_with_specific_runtime_call::Config for Runtime {
#[docify::export(pezpallet_with_specific_runtime_call_impl)]
impl pezpallet_with_specific_runtime_call::Config for Runtime {
// an implementation of `IsSubType` is provided by `construct_runtime`.
type RuntimeCall = RuntimeCall;
}
@@ -5,17 +5,17 @@
//! 1. on-chain state,
//! 2. a state transition function.
//!
//! In Substrate-based blockchains, state transition functions are referred to as
//! In Bizinikiwi-based blockchains, state transition functions are referred to as
//! [runtimes](https://docs.pezkuwichain.io/sdk/master/polkadot_sdk_docs/reference_docs/blockchain_state_machines/index.html).
//!
//! Traditionally, before Substrate, upgrading state transition functions required node
//! Traditionally, before Bizinikiwi, upgrading state transition functions required node
//! operators to download new software and restart their nodes in a process called
//! [forking](https://en.wikipedia.org/wiki/Fork_(blockchain)).
//!
//! Substrate-based blockchains do not require forking, and instead upgrade runtimes
//! Bizinikiwi-based blockchains do not require forking, and instead upgrade runtimes
//! in a process called "Runtime Upgrades".
//!
//! Forkless runtime upgrades are a defining feature of the Substrate framework. Updating the
//! Forkless runtime upgrades are a defining feature of the Bizinikiwi framework. Updating the
//! runtime logic without forking the code base enables your blockchain to seamlessly evolve
//! over time in a deterministic, rules-based manner. It also removes ambiguity for node operators
//! and other participants in the network about what is the canonical runtime.
@@ -24,26 +24,26 @@
//!
//! ## Performing a Runtime Upgrade
//!
//! To upgrade a runtime, an [`Origin`](frame_system::RawOrigin) with the necessary permissions
//! To upgrade a runtime, an [`Origin`](pezframe_system::RawOrigin) with the necessary permissions
//! (usually via governance) changes the `:code` storage. Usually, this is performed via a call to
//! [`set_code`] (or [`set_code_without_checks`]) with the desired new runtime blob, scheduled
//! using [`pallet_scheduler`].
//! using [`pezpallet_scheduler`].
//!
//! Prior to building the new runtime, don't forget to update the
//! [`RuntimeVersion`](sp_version::RuntimeVersion).
//! [`RuntimeVersion`](pezsp_version::RuntimeVersion).
//!
//! # Migrations
//!
//! It is often desirable to define logic to execute immediately after runtime upgrades (see
//! [this diagram](frame::traits::Hooks)).
//! [this diagram](pezframe::traits::Hooks)).
//!
//! Self-contained pieces of logic that execute after a runtime upgrade are called "Migrations".
//!
//! The typical use case of a migration is to 'migrate' pallet storage from one layout to another,
//! for example when the encoding of a storage item is changed. However, they can also execute
//! arbitrary logic such as:
//! The typical use case of a migration is to 'migrate' pezpallet storage from one layout to
//! another, for example when the encoding of a storage item is changed. However, they can also
//! execute arbitrary logic such as:
//!
//! - Calling arbitrary pallet methods.
//! - Calling arbitrary pezpallet methods.
//! - Mutating arbitrary on-chain state.
//! - Cleaning up some old storage items that are no longer needed.
//!
@@ -54,22 +54,22 @@
//! - Are suitable for migrations which are guaranteed to not exceed the block weight.
//! - Are simply implementations of [`OnRuntimeUpgrade`].
//!
//! To learn best practices for writing single block pallet storage migrations, see the
//! [Single Block Migration Example Pallet](pallet_example_single_block_migrations).
//! To learn best practices for writing single block pezpallet storage migrations, see the
//! [Single Block Migration Example Pezpallet](pezpallet_example_single_block_migrations).
//!
//! ### Scheduling the Single Block Migrations to Run Next Runtime Upgrade
//!
//! Schedule migrations to run next runtime upgrade passing them as a parameter to your
//! [`Config`](frame_system) pallet:
//! [`Config`](pezframe_system) pezpallet:
//!
//! ```ignore
//! /// Tuple of migrations (structs that implement `OnRuntimeUpgrade`)
//! type Migrations = (
//! pallet_example_storage_migration::migrations::v1::versioned::MigrateV0ToV1,
//! pezpallet_example_storage_migration::migrations::v1::versioned::MigrateV0ToV1,
//! MyCustomMigration,
//! // ...more migrations here
//! );
//! impl frame_system::Config for Runtime {
//! impl pezframe_system::Config for Runtime {
//! type SingleBlockMigrations = Migrations;
//! }
//! ```
@@ -114,7 +114,7 @@
//!
//! ### Other useful tools
//!
//! [`Chopsticks`](https://github.com/AcalaNetwork/chopsticks) is another tool in the Substrate
//! [`Chopsticks`](https://github.com/AcalaNetwork/chopsticks) is another tool in the Bizinikiwi
//! ecosystem which developers may find useful to use in addition to `try-runtime-cli` when testing
//! their single block migrations.
//!
@@ -125,10 +125,10 @@
//! Suitable for migrations which could use arbitrary amounts of block weight.
//!
//! See the
//! [multi-block-migrations example](https://github.com/pezkuwichain/pezkuwi-sdk/tree/0d7d2177807ec6b3094f4491a45b0bc0d74d3c8b/substrate/frame/examples/multi-block-migrations)
//! [multi-block-migrations example](https://github.com/pezkuwichain/pezkuwi-sdk/tree/0d7d2177807ec6b3094f4491a45b0bc0d74d3c8b/bizinikiwi/pezframe/examples/multi-block-migrations)
//! for reference.
//!
//! [`OnRuntimeUpgrade`]: frame_support::traits::OnRuntimeUpgrade
//! [`StorageVersion`]: frame_support::traits::StorageVersion
//! [`set_code`]: frame_system::Call::set_code
//! [`set_code_without_checks`]: frame_system::Call::set_code_without_checks
//! [`OnRuntimeUpgrade`]: pezframe_support::traits::OnRuntimeUpgrade
//! [`StorageVersion`]: pezframe_support::traits::StorageVersion
//! [`set_code`]: pezframe_system::Call::set_code
//! [`set_code_without_checks`]: pezframe_system::Call::set_code_without_checks
@@ -8,70 +8,70 @@
//! Let's begin by starting to store a `NewType` in a storage item:
//!
//! ```compile_fail
//! #[frame::pallet]
//! pub mod pallet {
//! # use frame::prelude::*;
//! # #[pallet::config]
//! # pub trait Config: frame_system::Config {}
//! # #[pallet::pallet]
//! # pub struct Pallet<T>(_);
//! #[pezframe::pezpallet]
//! pub mod pezpallet {
//! # use pezframe::prelude::*;
//! # #[pezpallet::config]
//! # pub trait Config: pezframe_system::Config {}
//! # #[pezpallet::pezpallet]
//! # pub struct Pezpallet<T>(_);
//! pub struct NewType(u32);
//
//! #[pallet::storage]
//! #[pezpallet::storage]
//! pub type Something<T> = StorageValue<_, NewType>;
//! }
//! ```
//!
//!
//! This raises a number of compiler errors, like:
//! ```text
//! the trait `MaxEncodedLen` is not implemented for `NewType`, which is required by
//! `frame::prelude::StorageValue<_GeneratedPrefixForStorageSomething<T>, NewType>:
//! `pezframe::prelude::StorageValue<_GeneratedPrefixForStorageSomething<T>, NewType>:
//! StorageInfoTrait`
//! ```
//!
//!
//! This implies the following set of traits that need to be derived for a type to be stored in
//! `frame` storage:
//! ```rust
//! #[frame::pallet]
//! pub mod pallet {
//! # use frame::prelude::*;
//! # #[pallet::config]
//! # pub trait Config: frame_system::Config {}
//! # #[pallet::pallet]
//! # pub struct Pallet<T>(_);
//! #[pezframe::pezpallet]
//! pub mod pezpallet {
//! # use pezframe::prelude::*;
//! # #[pezpallet::config]
//! # pub trait Config: pezframe_system::Config {}
//! # #[pezpallet::pezpallet]
//! # pub struct Pezpallet<T>(_);
//! #[derive(codec::Encode, codec::Decode, codec::MaxEncodedLen, scale_info::TypeInfo)]
//! pub struct NewType(u32);
//!
//! #[pallet::storage]
//! #[pezpallet::storage]
//! pub type Something<T> = StorageValue<_, NewType>;
//! }
//! ```
//!
//!
//! Next, let's look at how this will differ if we are to store a type that is derived from `T` in
//! storage, such as [`frame::prelude::BlockNumberFor`]:
//! storage, such as [`pezframe::prelude::BlockNumberFor`]:
//! ```compile_fail
//! #[frame::pallet]
//! pub mod pallet {
//! # use frame::prelude::*;
//! # #[pallet::config]
//! # pub trait Config: frame_system::Config {}
//! # #[pallet::pallet]
//! # pub struct Pallet<T>(_);
//! #[pezframe::pezpallet]
//! pub mod pezpallet {
//! # use pezframe::prelude::*;
//! # #[pezpallet::config]
//! # pub trait Config: pezframe_system::Config {}
//! # #[pezpallet::pezpallet]
//! # pub struct Pezpallet<T>(_);
//! #[derive(codec::Encode, codec::Decode, codec::MaxEncodedLen, scale_info::TypeInfo)]
//! pub struct NewType<T: Config>(BlockNumberFor<T>);
//!
//! #[pallet::storage]
//! #[pezpallet::storage]
//! pub type Something<T: Config> = StorageValue<_, NewType<T>>;
//! }
//! ```
//!
//!
//! Surprisingly, this will also raise a number of errors, like:
//! ```text
//! the trait `TypeInfo` is not implemented for `T`, which is required
//! by`frame_support::pallet_prelude::StorageValue<pallet_2::_GeneratedPrefixForStorageSomething<T>,
//! pallet_2::NewType<T>>:StorageEntryMetadataBuilder
//! by`pezframe_support::pezpallet_prelude::StorageValue<pezpallet_2::_GeneratedPrefixForStorageSomething<T>,
//! pezpallet_2::NewType<T>>:StorageEntryMetadataBuilder
//! ```
//!
//!
//! Why is that? The underlying reason is that the `TypeInfo` `derive` macro will only work for
//! `NewType` if all of `NewType`'s generics also implement `TypeInfo`. This is not the case for `T`
//! in the example above.
@@ -84,42 +84,42 @@
//! attribute to `NewType`. This additional macro will instruct the `derive` to skip the bound on
//! `T`.
//! ```rust
//! #[frame::pallet]
//! pub mod pallet {
//! # use frame::prelude::*;
//! # #[pallet::config]
//! # pub trait Config: frame_system::Config {}
//! # #[pallet::pallet]
//! # pub struct Pallet<T>(_);
//! #[pezframe::pezpallet]
//! pub mod pezpallet {
//! # use pezframe::prelude::*;
//! # #[pezpallet::config]
//! # pub trait Config: pezframe_system::Config {}
//! # #[pezpallet::pezpallet]
//! # pub struct Pezpallet<T>(_);
//! #[derive(codec::Encode, codec::Decode, codec::MaxEncodedLen, scale_info::TypeInfo)]
//! #[scale_info(skip_type_params(T))]
//! pub struct NewType<T: Config>(BlockNumberFor<T>);
//!
//! #[pallet::storage]
//! #[pezpallet::storage]
//! pub type Something<T: Config> = StorageValue<_, NewType<T>>;
//! }
//! ```
//!
//! Next, let's say we wish to store `NewType` as [`frame::prelude::ValueQuery`], which means it
//!
//! Next, let's say we wish to store `NewType` as [`pezframe::prelude::ValueQuery`], which means it
//! must also implement `Default`. This should be as simple as adding `derive(Default)` to it,
//! right?
//! ```compile_fail
//! #[frame::pallet]
//! pub mod pallet {
//! # use frame::prelude::*;
//! # #[pallet::config]
//! # pub trait Config: frame_system::Config {}
//! # #[pallet::pallet]
//! # pub struct Pallet<T>(_);
//! #[pezframe::pezpallet]
//! pub mod pezpallet {
//! # use pezframe::prelude::*;
//! # #[pezpallet::config]
//! # pub trait Config: pezframe_system::Config {}
//! # #[pezpallet::pezpallet]
//! # pub struct Pezpallet<T>(_);
//! #[derive(codec::Encode, codec::Decode, codec::MaxEncodedLen, scale_info::TypeInfo, Default)]
//! #[scale_info(skip_type_params(T))]
//! pub struct NewType<T: Config>(BlockNumberFor<T>);
//!
//! #[pallet::storage]
//! #[pezpallet::storage]
//! pub type Something<T: Config> = StorageValue<_, NewType<T>, ValueQuery>;
//! }
//! ```
//!
//!
//! Under the hood, the expansion of the `derive(Default)` will suffer from the same restriction as
//! before: it will only work if `T: Default`, and `T` is not `Default`. Note that this is an
//! expected issue: `T` is merely a wrapper of many other types, such as `BlockNumberFor<T>`.
@@ -129,26 +129,26 @@
//! To fix this, frame provides a set of macros that are analogous to normal rust derive macros, but
//! work nicely on top of structs that are generic over `T: Config`. These macros are:
//!
//! - [`frame::prelude::DefaultNoBound`]
//! - [`frame::prelude::DebugNoBound`]
//! - [`frame::prelude::PartialEqNoBound`]
//! - [`frame::prelude::EqNoBound`]
//! - [`frame::prelude::CloneNoBound`]
//! - [`frame::prelude::PartialOrdNoBound`]
//! - [`frame::prelude::OrdNoBound`]
//! - [`pezframe::prelude::DefaultNoBound`]
//! - [`pezframe::prelude::DebugNoBound`]
//! - [`pezframe::prelude::PartialEqNoBound`]
//! - [`pezframe::prelude::EqNoBound`]
//! - [`pezframe::prelude::CloneNoBound`]
//! - [`pezframe::prelude::PartialOrdNoBound`]
//! - [`pezframe::prelude::OrdNoBound`]
//!
//! The above traits are almost certainly needed for your tests - to print your type, assert equality
//! or clone it.
//!
//! We can fix the following example by using [`frame::prelude::DefaultNoBound`].
//! We can fix the following example by using [`pezframe::prelude::DefaultNoBound`].
//! ```rust
//! #[frame::pallet]
//! pub mod pallet {
//! # use frame::prelude::*;
//! # #[pallet::config]
//! # pub trait Config: frame_system::Config {}
//! # #[pallet::pallet]
//! # pub struct Pallet<T>(_);
//! #[pezframe::pezpallet]
//! pub mod pezpallet {
//! # use pezframe::prelude::*;
//! # #[pezpallet::config]
//! # pub trait Config: pezframe_system::Config {}
//! # #[pezpallet::pezpallet]
//! # pub struct Pezpallet<T>(_);
//! #[derive(
//! codec::Encode,
//! codec::Decode,
@@ -159,44 +159,44 @@
//! #[scale_info(skip_type_params(T))]
//! pub struct NewType<T:Config>(BlockNumberFor<T>);
//!
//! #[pallet::storage]
//! #[pezpallet::storage]
//! pub type Something<T: Config> = StorageValue<_, NewType<T>, ValueQuery>;
//! }
//! ```
//!
//!
//! Finally, if a custom type that is provided through `Config` is to be stored in the storage, it
//! is subject to the same trait requirements. The following does not work:
//! ```compile_fail
//! #[frame::pallet]
//! pub mod pallet {
//! use frame::prelude::*;
//! #[pallet::config]
//! pub trait Config: frame_system::Config {
//! #[pezframe::pezpallet]
//! pub mod pezpallet {
//! use pezframe::prelude::*;
//! #[pezpallet::config]
//! pub trait Config: pezframe_system::Config {
//! type CustomType;
//! }
//! #[pallet::pallet]
//! pub struct Pallet<T>(_);
//! #[pallet::storage]
//! #[pezpallet::pezpallet]
//! pub struct Pezpallet<T>(_);
//! #[pezpallet::storage]
//! pub type Something<T: Config> = StorageValue<_, T::CustomType>;
//! }
//! ```
//!
//!
//! But adding the right trait bounds will fix it.
//! ```rust
//! #[frame::pallet]
//! pub mod pallet {
//! use frame::prelude::*;
//! #[pallet::config]
//! pub trait Config: frame_system::Config {
//! #[pezframe::pezpallet]
//! pub mod pezpallet {
//! use pezframe::prelude::*;
//! #[pezpallet::config]
//! pub trait Config: pezframe_system::Config {
//! type CustomType: codec::FullCodec
//! + codec::MaxEncodedLen
//! + scale_info::TypeInfo
//! + Debug
//! + Default;
//! }
//! #[pallet::pallet]
//! pub struct Pallet<T>(_);
//! #[pallet::storage]
//! #[pezpallet::pezpallet]
//! pub struct Pezpallet<T>(_);
//! #[pezpallet::storage]
//! pub type Something<T: Config> = StorageValue<_, T::CustomType>;
//! }
//! ```
@@ -1,6 +1,6 @@
// This file is part of pezkuwi-sdk.
//
// Copyright (C) Parity Technologies (UK) Ltd.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,13 +30,13 @@
//!
//! ## Getting Started
//!
//! The most ubiquitous way to add a token to a FRAME runtime is [`pallet_balances`]. Read
//! The most ubiquitous way to add a token to a FRAME runtime is [`pezpallet_balances`]. Read
//! more about pallets [here](crate::pezkuwi_sdk::frame_runtime#pallets).
//!
//! You may then write custom pallets that interact with [`pallet_balances`]. The fastest way to
//! You may then write custom pallets that interact with [`pezpallet_balances`]. The fastest way to
//! get started with that is by
//! [tightly coupling](crate::reference_docs::frame_pallet_coupling#tight-coupling-pallets) your
//! custom pallet to [`pallet_balances`].
//! custom pezpallet to [`pezpallet_balances`].
//!
//! However, to keep pallets flexible and modular, it is often preferred to
//! [loosely couple](crate::reference_docs::frame_pallet_coupling#loosely--coupling-pallets).
@@ -50,80 +50,81 @@
//! trait implementations.
//!
//! **Traits** define common interfaces that types of tokens should implement. For example, the
//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`) trait specifies an interface
//! for *inspecting* token state such as the total issuance of the token, the balance of individual
//! accounts, etc.
//! [`fungible::Inspect`](`pezframe_support::traits::fungible::Inspect`) trait specifies an
//! interface for *inspecting* token state such as the total issuance of the token, the balance of
//! individual accounts, etc.
//!
//! **Trait implementations** are concrete implementations of these traits. For example, one of the
//! many traits [`pallet_balances`] implements is
//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`)[^1]. It provides the concrete
//! way of inspecting the total issuance, balance of accounts, etc. There can be many
//! many traits [`pezpallet_balances`] implements is
//! [`fungible::Inspect`](`pezframe_support::traits::fungible::Inspect`)[^1]. It provides the
//! concrete way of inspecting the total issuance, balance of accounts, etc. There can be many
//! implementations of the same traits.
//!
//! [^1]: Rust Advanced Tip: The knowledge that [`pallet_balances`] implements
//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`) is not some arcane knowledge
//! that you have to know by heart or memorize. One can simply look at the list of the implementors
//! of any trait in the Rust Doc to find all implementors (e.g.
//! [Mutate trait implementors](https://docs.pezkuwichain.io/sdk/master/frame_support/traits/tokens/fungible/trait.Mutate.html#implementors)),
//! [^1]: Rust Advanced Tip: The knowledge that [`pezpallet_balances`] implements
//! [`fungible::Inspect`](`pezframe_support::traits::fungible::Inspect`) is not some arcane
//! knowledge that you have to know by heart or memorize. One can simply look at the list of the
//! implementors of any trait in the Rust Doc to find all implementors (e.g.
//! [Mutate trait implementors](https://docs.pezkuwichain.io/sdk/master/pezframe_support/traits/tokens/fungible/trait.Mutate.html#implementors)),
//! or use the `rust-analyzer`'s `Implementations` action.
//!
//! The distinction between traits and trait implementations is helpful because it allows pallets
//! and other logic to be generic over their dependencies, avoiding tight coupling.
//!
//! To illustrate this with an example let's consider [`pallet_preimage`]. This pallet takes a
//! To illustrate this with an example let's consider [`pezpallet_preimage`]. This pezpallet takes a
//! deposit in exchange for storing a preimage for later use. A naive implementation of the
//! pallet may use [`pallet_balances`] in a tightly coupled manner, directly calling methods
//! on the pallet to reserve and unreserve deposits. This approach works well,
//! until someone has a use case requiring that an asset from a different pallet such as
//! [`pallet_assets`] is used for the deposit. Rather than tightly coupling [`pallet_preimage`] to
//! [`pallet_balances`], [`pallet_assets`], and every other token-handling pallet, a user
//! could possibly specify that [`pallet_preimage`] does not specify a concrete pallet as a
//! dependency, but instead accepts any dependency which implements the
//! [`currency::ReservableCurrency`](`frame_support::traits::tokens::currency::ReservableCurrency`)
//! trait, namely via its [`Config::Currency`](`pallet_preimage::pallet::Config::Currency`)
//! associated type. This allows [`pallet_preimage`] to support any arbitrary pallet implementing
//! this trait, without needing any knowledge of what those pallets may be or requiring changes to
//! support new pallets which may be written in the future.
//! pezpallet may use [`pezpallet_balances`] in a tightly coupled manner, directly calling methods
//! on the pezpallet to reserve and unreserve deposits. This approach works well,
//! until someone has a use case requiring that an asset from a different pezpallet such as
//! [`pezpallet_assets`] is used for the deposit. Rather than tightly coupling
//! [`pezpallet_preimage`] to [`pezpallet_balances`], [`pezpallet_assets`], and every other
//! token-handling pezpallet, a user could possibly specify that [`pezpallet_preimage`] does not
//! specify a concrete pezpallet as a dependency, but instead accepts any dependency which
//! implements the
//! [`currency::ReservableCurrency`](`pezframe_support::traits::tokens::currency::ReservableCurrency`)
//! trait, namely via its [`Config::Currency`](`pezpallet_preimage::pezpallet::Config::Currency`)
//! associated type. This allows [`pezpallet_preimage`] to support any arbitrary pezpallet
//! implementing this trait, without needing any knowledge of what those pallets may be or requiring
//! changes to support new pallets which may be written in the future.
//!
//! Read more about coupling, and the benefits of loose coupling
//! [here](crate::reference_docs::frame_pallet_coupling).
//!
//! ## Fungible Token Traits in FRAME
//!
//! The [`fungible`](`frame_support::traits::fungible`) crate contains the latest set of FRAME
//! The [`fungible`](`pezframe_support::traits::fungible`) crate contains the latest set of FRAME
//! fungible token traits, and is recommended to use for all new logic requiring a fungible token.
//! See the crate documentation for more info about these fungible traits.
//!
//! [`fungibles`](`frame_support::traits::fungibles`) provides very similar functionality to
//! [`fungible`](`frame_support::traits::fungible`), except it supports managing multiple tokens.
//! [`fungibles`](`pezframe_support::traits::fungibles`) provides very similar functionality to
//! [`fungible`](`pezframe_support::traits::fungible`), except it supports managing multiple tokens.
//!
//! You may notice the trait [`Currency`](`frame_support::traits::Currency`) with similar
//! You may notice the trait [`Currency`](`pezframe_support::traits::Currency`) with similar
//! functionality is also used in the codebase, however this trait is deprecated and existing logic
//! is in the process of being migrated to [`fungible`](`frame_support::traits::fungible`) ([tracking issue](https://github.com/pezkuwichain/pezkuwi-sdk/issues/102)).
//! is in the process of being migrated to [`fungible`](`pezframe_support::traits::fungible`) ([tracking issue](https://github.com/pezkuwichain/pezkuwi-sdk/issues/248)).
//!
//! ## Fungible Token Trait Implementations in FRAME
//!
//! [`pallet_balances`] implements [`fungible`](`frame_support::traits::fungible`), and is the most
//! commonly used fungible implementation in FRAME. Most of the time, it's used for managing the
//! native token of the blockchain network it's used in.
//! [`pezpallet_balances`] implements [`fungible`](`pezframe_support::traits::fungible`), and is the
//! most commonly used fungible implementation in FRAME. Most of the time, it's used for managing
//! the native token of the blockchain network it's used in.
//!
//! [`pallet_assets`] implements [`fungibles`](`frame_support::traits::fungibles`), and is another
//! popular fungible token implementation. It supports the creation and management of multiple
//! assets in a single crate, making it a good choice when a network requires more assets in
//! addition to its native token.
//! [`pezpallet_assets`] implements [`fungibles`](`pezframe_support::traits::fungibles`), and is
//! another popular fungible token implementation. It supports the creation and management of
//! multiple assets in a single crate, making it a good choice when a network requires more assets
//! in addition to its native token.
//!
//! ## Non-Fungible Tokens in FRAME
//!
//! [`pallet_nfts`] is recommended to use for all NFT use cases in FRAME.
//! See the crate documentation for more info about this pallet.
//! [`pezpallet_nfts`] is recommended to use for all NFT use cases in FRAME.
//! See the crate documentation for more info about this pezpallet.
//!
//! [`pallet_uniques`] is deprecated and should not be used.
//! [`pezpallet_uniques`] is deprecated and should not be used.
//!
//!
//! # What Next?
//!
//! - If you are interested in implementing a single fungible token, continue reading the
//! [`fungible`](`frame_support::traits::fungible`) and [`pallet_balances`] docs.
//! [`fungible`](`pezframe_support::traits::fungible`) and [`pezpallet_balances`] docs.
//! - If you are interested in implementing a set of fungible tokens, continue reading the
//! [`fungibles`](`frame_support::traits::fungibles`) trait and [`pallet_assets`] docs.
//! - If you are interested in implementing an NFT, continue reading the [`pallet_nfts`] docs.
//! [`fungibles`](`pezframe_support::traits::fungibles`) trait and [`pezpallet_assets`] docs.
//! - If you are interested in implementing an NFT, continue reading the [`pezpallet_nfts`] docs.
@@ -66,14 +66,14 @@
//! included into a block and leads to some action. This includes user-initiated transactions as
//! well as inherents which are placed into the block by the block-builder.
//!
//! #### Pallet
//! #### Pezpallet
//!
//! Similar to software modules in traditional programming, [FRAME](frame) pallets in Substrate are
//! Similar to software modules in traditional programming, [FRAME](frame) pallets in Bizinikiwi are
//! modular components that encapsulate distinct functionalities or business logic. Just as
//! libraries or modules are used to build and extend the capabilities of a software application,
//! pallets are the foundational building blocks for constructing a blockchain's runtime with frame.
//! They enable the creation of customizable and upgradeable networks, offering a composable
//! framework for a Substrate-based blockchain. Each pallet can be thought of as a plug-and-play
//! framework for a Bizinikiwi-based blockchain. Each pezpallet can be thought of as a plug-and-play
//! module, enhancing the blockchain's functionality in a cohesive and integrated manner.
//!
//! #### Full Node
@@ -1,7 +1,7 @@
//! # Metadata
//!
//! The existence of metadata in pezkuwi-sdk goes back to the (forkless) upgrade-ability of all
//! Substrate-based blockchains, which is achieved through
//! Bizinikiwi-based blockchains, which is achieved through
//! [`crate::reference_docs::wasm_meta_protocol`]. You can learn more about the details of how to
//! deal with these upgrades in [`crate::reference_docs::frame_runtime_upgrades_and_migrations`].
//!
@@ -9,9 +9,9 @@
//! it is hard to know the types internal to the runtime, specifically in light of the fact that
//! they can change at any point in time.
//!
//! This is why all Substrate-based runtimes must expose a [`sp_api::Metadata`] api, which mandates
//! the runtime to return a description of itself. The return type of this api is `Vec<u8>`, meaning
//! that it is up to the runtime developer to decide on the format of this.
//! This is why all Bizinikiwi-based runtimes must expose a [`pezsp_api::Metadata`] api, which
//! mandates the runtime to return a description of itself. The return type of this api is
//! `Vec<u8>`, meaning that it is up to the runtime developer to decide on the format of this.
//!
//! All [`crate::pezkuwi_sdk::frame_runtime`] based runtimes expose a specific metadata language,
//! maintained in <https://github.com/paritytech/frame-metadata> which is adopted in the Pezkuwi
+11 -11
View File
@@ -20,17 +20,17 @@
//! We call this class of documents "reference documents". Our goal should be to minimize the number
//! of "reference" docs, as they incur maintenance burden.
/// Learn how Substrate and FRAME use traits and associated types to make modules generic in a
/// Learn how Bizinikiwi and FRAME use traits and associated types to make modules generic in a
/// type-safe manner.
pub mod trait_based_programming;
/// Learn about the way Substrate and FRAME view their blockchains as state machines.
/// Learn about the way Bizinikiwi and FRAME view their blockchains as state machines.
pub mod blockchain_state_machines;
/// The glossary.
pub mod glossary;
/// Learn about the WASM meta-protocol of all Substrate-based chains.
/// Learn about the WASM meta-protocol of all Bizinikiwi-based chains.
pub mod wasm_meta_protocol;
/// Learn about the differences between smart contracts and a FRAME-based runtime. They are both
@@ -60,8 +60,8 @@ pub mod defensive_programming;
/// `RuntimeCall`.
pub mod frame_runtime_types;
/// Learn about how to make a pallet/runtime that is fee-less and instead uses another mechanism to
/// control usage and sybil attacks.
/// Learn about how to make a pezpallet/runtime that is fee-less and instead uses another mechanism
/// to control usage and sybil attacks.
pub mod fee_less_runtime;
/// Learn about metadata, the main means through which an upgradeable runtime communicates its
@@ -71,14 +71,14 @@ pub mod metadata;
/// Learn about how to add custom host functions to the node.
pub mod custom_host_functions;
/// Learn about how frame-system handles `account-ids`, nonces, consumers and providers.
pub mod frame_system_accounts;
/// Learn about how pezframe-system handles `account-ids`, nonces, consumers and providers.
pub mod pezframe_system_accounts;
/// Advice for configuring your development environment for Substrate development.
/// Advice for configuring your development environment for Bizinikiwi development.
pub mod development_environment_advice;
/// Learn about benchmarking and weight.
pub mod frame_benchmarking_weight;
pub mod pezframe_benchmarking_weight;
/// Learn about the token-related logic in FRAME and how to apply it to your use case.
pub mod frame_tokens;
@@ -86,7 +86,7 @@ pub mod frame_tokens;
/// Learn about chain specification file and the genesis state of the blockchain.
pub mod chain_spec_genesis;
/// Learn about Substrate's CLI, and how it can be extended.
/// Learn about Bizinikiwi's CLI, and how it can be extended.
pub mod cli;
/// Learn about Runtime Upgrades and best practices for writing Migrations.
@@ -112,5 +112,5 @@ pub mod custom_runtime_api_rpc;
/// The [`pezkuwi-omni-node`](https://crates.io/crates/polkadot-omni-node) and its related binaries.
pub mod omni_node;
/// Learn about the state in Substrate.
/// Learn about the state in Bizinikiwi.
pub mod state;
@@ -1,11 +1,11 @@
//! # (Omni) Node
//!
//! This reference doc elaborates on what a Pezkuwi-SDK/Substrate node software is, and what
//! This reference doc elaborates on what a Pezkuwi-SDK/Bizinikiwi node software is, and what
//! various ways exist to run one.
//!
//! The node software, as denoted in [`crate::reference_docs::wasm_meta_protocol`], is everything in
//! a blockchain other than the WASM runtime. It contains common components such as the database,
//! networking, RPC server and consensus. Substrate-based nodes are native binaries that are
//! networking, RPC server and consensus. Bizinikiwi-based nodes are native binaries that are
//! compiled down from the Rust source code. The `node` folder in any of the [`templates`] are
//! examples of this source.
//!
@@ -30,7 +30,7 @@
//!
//! > The notorious `service.rs` in any node template is a good example of this.
//!
//! A [trend](https://github.com/pezkuwichain/pezkuwi-sdk/issues/97) has already been undergoing in
//! A [trend](https://github.com/pezkuwichain/pezkuwi-sdk/issues/243) has already been undergoing in
//! order to de-couple the node and the runtime for a long time. The north star of this effort is
//! twofold :
//!
@@ -42,7 +42,7 @@
//! is the latter.
//!
//! > Note: The OmniNodes are mainly focused on the development needs of **Pezkuwi
//! > teyrchains ONLY**, not (Substrate) solo-chains. For the time being, solo-chains are not
//! > teyrchains ONLY**, not (Bizinikiwi) solo-chains. For the time being, solo-chains are not
//! > supported by the OmniNodes. This might change in the future.
//!
//! ## Types of Nodes
@@ -95,7 +95,7 @@
//! * [`crate::guides::your_first_runtime`]
//! * If need be, the weights of the runtime need to be updated using `frame-omni-bencher`.
//! References:
//! * [`crate::reference_docs::frame_benchmarking_weight`]
//! * [`crate::reference_docs::pezframe_benchmarking_weight`]
//! * Next, [`chain-spec-builder`] is used to generate a `chain_spec.json`, either for development,
//! or for production. References:
//! * [`crate::reference_docs::chain_spec_genesis`]
@@ -115,21 +115,21 @@
//!
//! ### Consensus Engine
//!
//! In any given substrate-based chain, both the node and the runtime will have their own
//! In any given bizinikiwi-based chain, both the node and the runtime will have their own
//! opinion/information about what consensus engine is going to be used.
//!
//! In practice, the majority of the implementation of any consensus engine is in the node side, but
//! the runtime also typically needs to expose a custom runtime-api to enable the particular
//! consensus engine to work, and that particular runtime-api is implemented by a pallet
//! consensus engine to work, and that particular runtime-api is implemented by a pezpallet
//! corresponding to that consensus engine.
//!
//! For example, taking a snippet from [`solochain_template_runtime`], the runtime has to provide
//! this additional runtime-api (compared to [`minimal_template_runtime`]), if the node software is
//! configured to use the Aura consensus engine:
//! For example, taking a snippet from [`pez_solochain_template_runtime`], the runtime has to
//! provide this additional runtime-api (compared to [`pez_minimal_template_runtime`]), if the node
//! software is configured to use the Aura consensus engine:
//!
//! ```text
//! impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
//! fn slot_duration() -> sp_consensus_aura::SlotDuration {
//! impl pezsp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
//! fn slot_duration() -> pezsp_consensus_aura::SlotDuration {
//! ...
//! }
//! fn authorities() -> Vec<AuraId> {
@@ -145,17 +145,17 @@
//!
//! For block authoring, there are a number of options:
//!
//! * [`sc_consensus_manual_seal`]: Useful for testing, where any node can produce a block at any
//! * [`pezsc_consensus_manual_seal`]: Useful for testing, where any node can produce a block at any
//! time. This is often combined with a fixed interval at which a block is produced.
//! * [`sc_consensus_aura`]/[`pallet_aura`]: A simple round-robin block authoring mechanism.
//! * [`sc_consensus_babe`]/[`pallet_babe`]: A more advanced block authoring mechanism, capable of
//! anonymizing the next block author.
//! * [`sc_consensus_pow`]: Proof of Work block authoring.
//! * [`pezsc_consensus_aura`]/[`pezpallet_aura`]: A simple round-robin block authoring mechanism.
//! * [`pezsc_consensus_babe`]/[`pezpallet_babe`]: A more advanced block authoring mechanism,
//! capable of anonymizing the next block author.
//! * [`pezsc_consensus_pow`]: Proof of Work block authoring.
//!
//! For finality, there is one main option shipped with pezkuwi-sdk:
//!
//! * [`sc_consensus_grandpa`]/[`pallet_grandpa`]: A finality gadget that uses a voting mechanism to
//! decide when a block
//! * [`pezsc_consensus_grandpa`]/[`pezpallet_grandpa`]: A finality gadget that uses a voting
//! mechanism to decide when a block
//!
//! **The most important lesson here is that the node and the runtime must have matching consensus
//! components.**
@@ -171,10 +171,10 @@
//! scaling). [`pezkuwi_omni_node_lib::cli::Cli::experimental_use_slot_based`] for fixed factor
//! scaling (a step
//! * Ability to run any runtime with [`--dev-block-time`] flag. This uses
//! [`sc_consensus_manual_seal`] under the hood, and has no restrictions on the runtime's
//! [`pezsc_consensus_manual_seal`] under the hood, and has no restrictions on the runtime's
//! consensus.
//!
//! [This](https://github.com/pezkuwichain/pezkuwi-sdk/issues/143) future improvement to OmniNode
//! [This](https://github.com/pezkuwichain/pezkuwi-sdk/issues/286) future improvement to OmniNode
//! aims to make such checks automatic.
//!
//! ### Runtime conventions
@@ -185,17 +185,17 @@
//! failure.
//!
//! The list of checks may evolve in the future and for now only few rules are implemented:
//! * runtimes must define a type for [`cumulus-pallet-teyrchain-system`], which is recommended to
//! be named as `TeyrchainSystem`.
//! * runtimes must define a type for [`frame-system`] pallet, which is recommended to be named as
//! `System`. The configured [`block number`] here will be used by Omni Node to configure AURA
//! accordingly.
//! * runtimes must define a type for [`pezcumulus-pezpallet-teyrchain-system`], which is
//! recommended to be named as `TeyrchainSystem`.
//! * runtimes must define a type for [`pezframe-system`] pezpallet, which is recommended to be
//! named as `System`. The configured [`block number`] here will be used by Omni Node to configure
//! AURA accordingly.
//!
//! [`templates`]: crate::pezkuwi_sdk::templates
//! [`teyrchain-template`]: https://github.com/pezkuwichain/pezkuwi-sdk-teyrchain-template
//! [`--dev-block-time`]: pezkuwi_omni_node_lib::cli::Cli::dev_block_time
//! [`pezkuwi-omni-node`]: https://crates.io/crates/polkadot-omni-node
//! [`chain-spec-builder`]: https://crates.io/crates/staging-chain-spec-builder
//! [`cumulus-pallet-teyrchain-system`]: https://docs.rs/cumulus-pallet-parachain-system/latest/cumulus_pallet_parachain_system/
//! [`frame-system`]: https://docs.rs/frame-system/latest/frame_system/
//! [`chain-spec-builder`]: https://crates.io/crates/pezstaging-chain-spec-builder
//! [`pezcumulus-pezpallet-teyrchain-system`]: https://docs.rs/cumulus-pallet-parachain-system/latest/cumulus_pallet_parachain_system/
//! [`pezframe-system`]: https://docs.rs/frame-system/latest/frame_system/
//! [`block number`]: https://docs.rs/frame-system/latest/frame_system/pallet/storage_types/struct.Number.html
@@ -47,13 +47,13 @@
//! the 20ms. In a benchmarked environment, it can examine the transactions for their upper bound,
//! and include the ones that are known to fit based on the worst case.
//!
//! The benchmarking code can be written as a part of FRAME pallet, using the macros provided in
//! [`frame_benchmarking`]. See any of the existing pallets in `pezkuwi-sdk`, or the pallets in our
//! [`crate::pezkuwi_sdk::templates`] for examples.
//! The benchmarking code can be written as a part of FRAME pezpallet, using the macros provided in
//! [`pezframe_benchmarking`]. See any of the existing pallets in `pezkuwi-sdk`, or the pallets in
//! our [`crate::pezkuwi_sdk::templates`] for examples.
//!
//! ## Weight
//!
//! Finally, [`sp_weights::Weight`] is the output of the benchmarking process. It is a
//! Finally, [`pezsp_weights::Weight`] is the output of the benchmarking process. It is a
//! two-dimensional data structure that demonstrates the resources consumed by a given block of
//! code (for example, a transaction). The two dimensions are:
//!
@@ -67,29 +67,29 @@
//! it captures the worst case execution of any block of code.
//!
//! Consider:
#![doc = docify::embed!("./src/reference_docs/frame_benchmarking_weight.rs", simple_transfer)]
#![doc = docify::embed!("./src/reference_docs/pezframe_benchmarking_weight.rs", simple_transfer)]
//!
//! If this block of code is to be benchmarked, then the benchmarking code must be written such that
//! it captures the worst case.
//!
//! ## Gluing Pallet Benchmarking with Runtime
//! ## Gluing Pezpallet Benchmarking with Runtime
//!
//! FRAME pallets are mandated to provide their own benchmarking code. Runtimes contain the
//! boilerplate needed to run these benchmarking (see [Running Benchmarks
//! below](#running-benchmarks)). The outcome of running these benchmarks are meant to be fed back
//! into the pallet via a conventional `trait WeightInfo` on `Config`:
#![doc = docify::embed!("src/reference_docs/frame_benchmarking_weight.rs", WeightInfo)]
//! into the pezpallet via a conventional `trait WeightInfo` on `Config`:
#![doc = docify::embed!("src/reference_docs/pezframe_benchmarking_weight.rs", WeightInfo)]
//!
//! Then, individual functions of this trait are the final values that we assigned to the
//! [`frame::pallet_macros::weight`] attribute:
#![doc = docify::embed!("./src/reference_docs/frame_benchmarking_weight.rs", simple_transfer_2)]
//! [`pezframe::pezpallet_macros::weight`] attribute:
#![doc = docify::embed!("./src/reference_docs/pezframe_benchmarking_weight.rs", simple_transfer_2)]
//!
//! ## Manual Refund
//!
//! Back to the assumption of writing benchmarks for worst case: Sometimes, the pre-dispatch weight
//! significantly differ from the post-dispatch actual weight consumed. This can be expressed with
//! the following FRAME syntax:
#![doc = docify::embed!("./src/reference_docs/frame_benchmarking_weight.rs", simple_transfer_3)]
#![doc = docify::embed!("./src/reference_docs/pezframe_benchmarking_weight.rs", simple_transfer_3)]
//!
//! ## Running Benchmarks
//!
@@ -114,7 +114,7 @@
//!
//! Pezkuwi-SDK runtimes use a more performant VM, namely WASM, which does not have metering. In
//! return they have to be benchmarked to provide an upper bound on the resources they consume. This
//! upper bound is represented as [`sp_weights::Weight`].
//! upper bound is represented as [`pezsp_weights::Weight`].
//!
//! ## Future: PolkaVM
//!
@@ -130,28 +130,28 @@
//! [PolkaVM]: https://github.com/koute/polkavm
//! [JAM]: https://graypaper.com
#[frame::pallet(dev_mode)]
#[pezframe::pezpallet(dev_mode)]
#[allow(unused_variables, unreachable_code, unused, clippy::diverging_sub_expression)]
pub mod pallet {
use frame::prelude::*;
pub mod pezpallet {
use pezframe::prelude::*;
#[docify::export]
pub trait WeightInfo {
fn simple_transfer() -> Weight;
}
#[pallet::config]
pub trait Config: frame_system::Config {
#[pezpallet::config]
pub trait Config: pezframe_system::Config {
type WeightInfo: WeightInfo;
}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pezpallet::pezpallet]
pub struct Pezpallet<T>(_);
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pezpallet::call]
impl<T: Config> Pezpallet<T> {
#[docify::export]
#[pallet::weight(10_000)]
#[pezpallet::weight(10_000)]
pub fn simple_transfer(
origin: OriginFor<T>,
destination: T::AccountId,
@@ -167,7 +167,7 @@ pub mod pallet {
}
#[docify::export]
#[pallet::weight(T::WeightInfo::simple_transfer())]
#[pezpallet::weight(T::WeightInfo::simple_transfer())]
pub fn simple_transfer_2(
origin: OriginFor<T>,
destination: T::AccountId,
@@ -184,7 +184,7 @@ pub mod pallet {
#[docify::export]
// This is the worst-case, pre-dispatch weight.
#[pallet::weight(T::WeightInfo::simple_transfer())]
#[pezpallet::weight(T::WeightInfo::simple_transfer())]
pub fn simple_transfer_3(
origin: OriginFor<T>,
destination: T::AccountId,
@@ -195,14 +195,14 @@ pub mod pallet {
if destination_exists {
// simpler code path
// Note that need for .into(), to convert `()` to `PostDispatchInfo`
// See: https://docs.pezkuwichain.io/sdk/master/frame_support/dispatch/struct.PostDispatchInfo.html#impl-From%3C()%3E-for-PostDispatchInfo
// See: https://docs.pezkuwichain.io/sdk/master/pezframe_support/dispatch/struct.PostDispatchInfo.html#impl-From%3C()%3E-for-PostDispatchInfo
Ok(().into())
} else {
// more complex code path
let actual_weight =
todo!("this can likely come from another benchmark that is NOT the worst case");
let pays_fee = todo!("You can set this to `Pays::Yes` or `Pays::No` to change if this transaction should pay fees");
Ok(frame::deps::frame_support::dispatch::PostDispatchInfo {
Ok(pezframe::deps::pezframe_support::dispatch::PostDispatchInfo {
actual_weight: Some(actual_weight),
pays_fee,
})
@@ -2,9 +2,9 @@
//!
//! 🚧 Work In Progress 🚧
//!
//! How `frame_system` handles accountIds. Nonce. Consumers and Providers, reference counting.
//! How `pezframe_system` handles accountIds. Nonce. Consumers and Providers, reference counting.
// - poorly understood topics, needs one great article to rul them all.
// - https://github.com/paritytech/substrate/issues/14425
// - https://github.com/paritytech/substrate/pull/12951
// - https://github.com/pezkuwichain/pezkuwi-sdk/issues/17
// - https://github.com/pezkuwichain/pezkuwi-sdk/issues/40
// - https://exchange.pezkuwichain.app/questions/263/what-is-the-meaning-of-the-account-provider-sufficients-and-consumer
@@ -3,7 +3,7 @@
//! *TL;DR*: If you need to create a *Blockchain*, then write a runtime. If you need to create a
//! *DApp*, then write a Smart Contract.
//!
//! This is a comparative analysis of Substrate-based Runtimes and Smart Contracts, highlighting
//! This is a comparative analysis of Bizinikiwi-based Runtimes and Smart Contracts, highlighting
//! their main differences. Our aim is to equip you with a clear understanding of how these two
//! methods of deploying on-chain logic diverge in their design, usage, and implications.
//!
@@ -12,21 +12,21 @@
//! decentralized applications. Understanding their differences is crucial in choosing the right
//! approach for a specific solution.
//!
//! ## Substrate
//! Substrate is a modular framework that enables the creation of purpose-specific blockchains. In
//! ## Bizinikiwi
//! Bizinikiwi is a modular framework that enables the creation of purpose-specific blockchains. In
//! the Pezkuwi ecosystem you can find two distinct approaches for on-chain code execution:
//! [Runtime Development](#runtime-in-substrate) and [Smart Contracts](#smart-contracts).
//! [Runtime Development](#runtime-in-bizinikiwi) and [Smart Contracts](#smart-contracts).
//!
//! #### Smart Contracts in Substrate
//! #### Smart Contracts in Bizinikiwi
//! Smart Contracts are autonomous, programmable constructs deployed on the blockchain.
//! In [FRAME](frame), Smart Contracts infrastructure is implemented by the
//! [`pallet_contracts`] for WASM-based contracts or the
//! [`pallet_evm`](https://github.com/polkadot-evm/frontier/tree/master/frame/evm) for EVM-compatible contracts. These pallets
//! enable Smart Contract developers to build applications and systems on top of a Substrate-based
//! [`pezpallet_contracts`] for WASM-based contracts or the
//! [`pezpallet_evm`](https://github.com/polkadot-evm/frontier/tree/master/frame/evm) for EVM-compatible contracts. These pallets
//! enable Smart Contract developers to build applications and systems on top of a Bizinikiwi-based
//! blockchain.
//!
//! #### Runtime in Substrate
//! The Runtime is the state transition function of a Substrate-based blockchain. It defines the
//! #### Runtime in Bizinikiwi
//! The Runtime is the state transition function of a Bizinikiwi-based blockchain. It defines the
//! rules for processing transactions and blocks, essentially governing the behavior and
//! capabilities of a blockchain.
//!
@@ -35,7 +35,7 @@
//! | Aspect | Runtime | Smart Contracts |
//! |-----------------------|-------------------------------------------------------------------------|----------------------------------------------------------------------|
//! | **Design Philosophy** | Core logic of a blockchain, allowing broad and deep customization. | Designed for DApps deployed on the blockchain runtime. |
//! | **Development Complexity** | Requires in-depth knowledge of Rust and Substrate. Suitable for complex blockchain architectures. | Easier to develop with knowledge of Smart Contract languages like Solidity or [ink!](https://use.ink/). |
//! | **Development Complexity** | Requires in-depth knowledge of Rust and Bizinikiwi. Suitable for complex blockchain architectures. | Easier to develop with knowledge of Smart Contract languages like Solidity or [ink!](https://use.ink/). |
//! | **Upgradeability and Flexibility** | Offers comprehensive upgradeability with migration logic and on-chain governance, allowing modifications to the entire blockchain logic without hard forks. | Less flexible in upgrade migrations but offers more straightforward deployment and iteration. |
//! | **Performance and Efficiency** | More efficient, optimized for specific needs of the blockchain. | Can be less efficient due to its generic nature (e.g. the overhead of a virtual machine). |
//! | **Security Considerations** | Security flaws can affect the entire blockchain. | Security risks usually localized to the individual contract. |
@@ -70,8 +70,8 @@
//! differing purposes and technical requirements.
//!
//! #### Runtime Development Complexity
//! - **In-depth Knowledge Requirements**: Developing a Runtime in Substrate requires a
//! comprehensive understanding of Rust, Substrate's framework, and blockchain principles.
//! - **In-depth Knowledge Requirements**: Developing a Runtime in Bizinikiwi requires a
//! comprehensive understanding of Rust, Bizinikiwi's framework, and blockchain principles.
//! - **Complex Blockchain Architectures**: Runtime development is suitable for creating complex
//! blockchain architectures. Developers must consider aspects like security, scalability, and
//! network efficiency.
@@ -108,7 +108,7 @@
//! - **Deployment and Iteration**: Smart Contracts, by nature, are designed for more
//! straightforward deployment and iteration. Developers can quickly deploy contracts.
//! - **Contract Code Updates**: Once deployed, although typically immutable, Smart Contracts can be
//! upgraded, but lack of migration logic. The [`pallet_contracts`]
//! upgraded, but lack of migration logic. The [`pezpallet_contracts`]
//! allows for contracts to be upgraded by exposing the `set_code` dispatchable. More details on this
//! can be found in [Ink! documentation on upgradeable contracts](https://use.ink/basics/upgradeable-contracts).
//! - **Isolated Impact**: Upgrades or changes to a smart contract generally impact only that
@@ -123,7 +123,7 @@
//! and optimized for specific needs, while Smart Contracts are more generic and less efficient.
//!
//! #### Runtime Performance and Efficiency
//! - **Optimized for Specific Needs**: Runtime modules in Substrate are tailored to meet the
//! - **Optimized for Specific Needs**: Runtime modules in Bizinikiwi are tailored to meet the
//! specific needs of the blockchain. They are integrated directly into the blockchain's core,
//! allowing them to operate with high efficiency and minimal overhead.
//! - **Direct Access to Blockchain State**: Runtime has direct access to the blockchain's state.
@@ -181,12 +181,12 @@
//! #### Weighing
//! In FRAME-based Runtimes, operations are *weighed*. This means that each operation in the Runtime
//! has a fixed upper cost, known in advance, determined through
//! [benchmarking](crate::reference_docs::frame_benchmarking_weight). Weighing is practical here
//! [benchmarking](crate::reference_docs::pezframe_benchmarking_weight). Weighing is practical here
//! because:
//!
//! - *Predictability*: Runtime operations are part of the blockchain's core logic, which is static
//! until an upgrade occurs. This predictability allows for precise
//! [benchmarking](crate::reference_docs::frame_benchmarking_weight).
//! [benchmarking](crate::reference_docs::pezframe_benchmarking_weight).
//! - *Prevention of Abuse*: By having a fixed upper cost that corresponds to the worst-case
//! complexity scenario of its execution (and a mechanism to refund unused weight), it becomes
//! infeasible for an attacker to create transactions that could unpredictably consume excessive

Some files were not shown because too many files have changed in this diff Show More