Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • nodes/rust/duniter-v2s
  • llaq/lc-core-substrate
  • pini-gh/duniter-v2s
  • vincentux/duniter-v2s
  • mildred/duniter-v2s
  • d0p1/duniter-v2s
  • bgallois/duniter-v2s
  • Nicolas80/duniter-v2s
8 results
Show changes
Commits on Source (65)
Showing
with 11609 additions and 5119 deletions
[alias] [alias]
sanity-gdev = "test -p duniter-live-tests --test sanity_gdev -- --nocapture" sanity-gdev = "test -Zgit=shallow-deps -p duniter-live-tests --test sanity_gdev -- --nocapture"
tu = "test --workspace --exclude duniter-end2end-tests --exclude duniter-live-tests --features constant-fees" tu = "test -Zgit=shallow-deps --workspace --exclude duniter-end2end-tests --exclude duniter-live-tests --features constant-fees" # Unit tests with constant-fees
tf = "test -Zgit=shallow-deps --workspace --exclude duniter-end2end-tests --exclude duniter-live-tests test_fee" # Custom fee model tests
# `te` and `cucumber` are synonyms # `te` and `cucumber` are synonyms
te = "test -p duniter-end2end-tests --test cucumber_tests --features constant-fees --" te = "test -p duniter-end2end-tests --test cucumber_tests --features constant-fees --"
cucumber-build = "build --features constant-fees" cucumber-build = "build -Zgit=shallow-deps --features constant-fees"
cucumber = "test -p duniter-end2end-tests --test cucumber_tests --" cucumber = "test -Zgit=shallow-deps -p duniter-end2end-tests --test cucumber_tests --"
ta = "test --workspace --exclude duniter-live-tests --features constant-fees" ta = "test -Zgit=shallow-deps --workspace --exclude duniter-live-tests --features constant-fees"
tb = "test --features runtime-benchmarks -p" tb = "test -Zgit=shallow-deps --features runtime-benchmarks -p"
rbp = "run --release --features runtime-benchmarks -- benchmark pallet --chain=dev --steps=50 --repeat=20 --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=. --pallet" rbp = "run -Zgit=shallow-deps --release --features runtime-benchmarks -- benchmark pallet --chain=dev --steps=50 --repeat=20 --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=. --pallet"
xtask = "run --package xtask --" xtask = "run -Zgit=shallow-deps --package xtask --"
cucumber-node = "run -- --chain=gdev_dev --execution=Native --sealing=manual --force-authoring --rpc-cors=all --tmp --ws-port 9944 --alice --features constant-fees" cucumber-node = "run -Zgit=shallow-deps -- --chain=gdev_dev --execution=Native --sealing=manual --force-authoring --rpc-cors=all --tmp --rpc-port 9944 --alice --features constant-fees"
...@@ -23,6 +23,12 @@ workflow: ...@@ -23,6 +23,12 @@ workflow:
- Cargo.toml - Cargo.toml
- Cargo.lock - Cargo.lock
.is_network_branch: &is_network_branch
if: $CI_PIPELINE_SOURCE != "merge_request_event" && $CI_COMMIT_BRANCH =~ /^(network\/).+/
.is_runtime_branch: &is_runtime_branch
if: $CI_PIPELINE_SOURCE != "merge_request_event" && $CI_COMMIT_BRANCH =~ /^(runtime\/).+/
sanity_tests: sanity_tests:
extends: .env extends: .env
rules: rules:
...@@ -41,7 +47,6 @@ check_labels: ...@@ -41,7 +47,6 @@ check_labels:
script: script:
- ./scripts/check_labels.sh $CI_MERGE_REQUEST_LABELS $CI_MERGE_REQUEST_MILESTONE - ./scripts/check_labels.sh $CI_MERGE_REQUEST_LABELS $CI_MERGE_REQUEST_MILESTONE
check_metadata: check_metadata:
extends: .env extends: .env
stage: tests stage: tests
...@@ -63,7 +68,7 @@ fmt_and_clippy: ...@@ -63,7 +68,7 @@ fmt_and_clippy:
when: manual when: manual
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH == "master"' - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH == "master"'
when: never when: never
- if: '$CI_COMMIT_BRANCH =~ /^(release\/runtime-)[0-9].*/' - <<: *is_network_branch
when: never when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: always when: always
...@@ -73,7 +78,7 @@ fmt_and_clippy: ...@@ -73,7 +78,7 @@ fmt_and_clippy:
- cargo fmt -- --version - cargo fmt -- --version
- cargo fmt -- --check - cargo fmt -- --check
- cargo clippy -- -V - cargo clippy -- -V
- cargo clippy --features runtime-benchmarks --all --tests -- -D warnings - cargo clippy -Zgit=shallow-deps --features runtime-benchmarks --all --tests -- -D warnings
run_benchmarks: run_benchmarks:
extends: .env extends: .env
...@@ -81,20 +86,25 @@ run_benchmarks: ...@@ -81,20 +86,25 @@ run_benchmarks:
rules: rules:
- if: $CI_COMMIT_REF_NAME =~ /^wip*$/ - if: $CI_COMMIT_REF_NAME =~ /^wip*$/
when: manual when: manual
- <<: *is_network_branch
when: never
- if: $CI_COMMIT_TAG - if: $CI_COMMIT_TAG
when: never when: never
- if: '$CI_MERGE_REQUEST_ID || $CI_COMMIT_BRANCH == "master"' - if: '$CI_MERGE_REQUEST_ID || $CI_COMMIT_BRANCH == "master"'
- when: manual - when: manual
script: script:
- cargo build --release --features runtime-benchmarks - cargo build -Zgit=shallow-deps --release --features runtime-benchmarks
- target/release/duniter benchmark storage --chain=dev --mul=2 --state-version=1 - target/release/duniter benchmark storage --chain=dev --mul=2 --state-version=1 --weight-path=./runtime/gdev/src/weights/
- target/release/duniter benchmark overhead --chain=dev --wasm-execution=compiled --warmup=1 --repeat=100 - target/release/duniter benchmark overhead --chain=dev --wasm-execution=compiled --warmup=1 --repeat=100 --weight-path=./runtime/gdev/src/weights/
- target/release/duniter benchmark pallet --chain=dev --steps=5 --repeat=2 --pallet="*" --extrinsic="*" --wasm-execution=compiled - target/release/duniter benchmark pallet --chain=dev --steps=5 --repeat=2 --pallet="*" --extrinsic="*" --wasm-execution=compiled --output=./runtime/gdev/src/weights/
# FIXME: "gtest_build" - cargo build -Zgit=shallow-deps --release --features runtime-benchmarks # Check if autogenerated weights work
gdev_build:
gtest_build:
stage: build stage: build
image: rust:1-bullseye extends: .env
rules: rules:
- <<: *is_network_branch
when: never
- if: $CI_COMMIT_REF_NAME =~ /^wip*$/ - if: $CI_COMMIT_REF_NAME =~ /^wip*$/
when: manual when: manual
- if: $CI_COMMIT_TAG - if: $CI_COMMIT_TAG
...@@ -106,163 +116,253 @@ gdev_build: ...@@ -106,163 +116,253 @@ gdev_build:
variables: variables:
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
script: script:
- apt-get update - cargo build -Zgit=shallow-deps --no-default-features --features gtest
- apt-get install -y clang cmake protobuf-compiler
- cargo build --no-default-features --features gtest
gdev_srtool_build: build_deb:
stage: build stage: deploy
extends: .env
rules: rules:
- if: $CI_COMMIT_REF_NAME =~ /^wip*$/ - if: $CI_COMMIT_REF_NAME =~ /^wip*$/
when: manual when: manual
- if: $CI_COMMIT_TAG - if: $CI_COMMIT_TAG
when: never when: never
- if: $CI_COMMIT_BRANCH =~ /^(release\/runtime-)[0-9].*/ - <<: *is_network_branch
when: never needs: ["build_raw_specs"]
when: always
- if: '$CI_MERGE_REQUEST_ID || $CI_COMMIT_BRANCH == "master"' - if: '$CI_MERGE_REQUEST_ID || $CI_COMMIT_BRANCH == "master"'
- when: manual - when: manual
image: paritytech/srtool:1.74.0-0.13.0
variables: variables:
PACKAGE: gdev-runtime DEBIAN_FRONTEND: noninteractive
RUNTIME_DIR: runtime/gdev
SRTOOL_OUTPUT: $CI_PROJECT_DIR/release/srtool_output_gdev.json
script: script:
- echo "Building runtime for gdev" - cargo install cargo-deb
- mkdir -p $CI_PROJECT_DIR/release - cargo build -Zgit=shallow-deps --release
- echo -e "[toolchain]\nchannel = \"`curl -s https://raw.githubusercontent.com/paritytech/srtool/master/RUSTC_VERSION`\"\ncomponents = [ \"rust-std\", \"rust-src\" ]\ntargets = [ \"wasm32-unknown-unknown\" ]" > $RUNTIME_DIR/rust-toolchain.toml # Workaround see !239 - cargo deb --no-build -p duniter
# Copy sources to the expected directory of srtool artifacts:
- cp -R * /build/ paths:
# Build the runtime - target/debian/duniter*.deb
- /srtool/build --app --json -cM | tee -a $SRTOOL_OUTPUT
- mv /build/runtime/gdev/target/srtool/release/wbuild/gdev-runtime/gdev_runtime.compact.compressed.wasm $CI_PROJECT_DIR/release/ build_rpm:
tags: stage: deploy
- kepler extends: .env
rules:
- if: $CI_COMMIT_REF_NAME =~ /^wip*$/
when: manual
- if: $CI_COMMIT_TAG
when: never
- <<: *is_network_branch
needs: ["build_raw_specs"]
when: always
- if: '$CI_MERGE_REQUEST_ID || $CI_COMMIT_BRANCH == "master"'
- when: manual
script:
- cargo install cargo-generate-rpm
- cargo build -Zgit=shallow-deps --release
- cargo generate-rpm -p node
artifacts:
paths:
- target/generate-rpm/duniter*.rpm
tests: tests:
stage: tests stage: tests
image: rust:1-bullseye extends: .env
rules: rules:
- if: $CI_COMMIT_REF_NAME =~ /^wip*$/ - if: $CI_COMMIT_REF_NAME =~ /^wip*$/
when: manual when: manual
- if: $CI_COMMIT_TAG - if: $CI_COMMIT_TAG
when: never when: never
- if: $CI_COMMIT_BRANCH =~ /^(release\/runtime-)[0-9].*/ - <<: *is_network_branch
when: never when: never
- if: '$CI_MERGE_REQUEST_ID || $CI_COMMIT_BRANCH == "master"' - if: '$CI_MERGE_REQUEST_ID || $CI_COMMIT_BRANCH == "master"'
- when: manual - when: manual
variables: variables:
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
script: script:
- apt-get update
- apt-get install -y clang cmake protobuf-compiler
- cargo tu - cargo tu
- cargo tf
- cargo cucumber-build - cargo cucumber-build
- cargo cucumber - cargo cucumber
.deploy_docker_multiplatform: .network_branch_vars: &define_network_branch_vars
- export NETWORK=$(echo $CI_COMMIT_BRANCH | sed -e "s/network\///g")
- echo "NETWORK = $NETWORK"
- export RUNTIME=$(echo $NETWORK | grep -Po "gdev|gtest|g1")
- echo "RUNTIME = $RUNTIME"
# srtool specific
- export RUNTIME_DIR=runtime/$RUNTIME
- echo "RUNTIME_DIR = $RUNTIME_DIR"
# srtool specific
- export PACKAGE=$RUNTIME-runtime
- echo "PACKAGE = $PACKAGE"
# GitLab milestone : used for both GitLab and Docker releases. Milestone must match source code's runtime version to fetch the git changes for release notes.
- export CLIENT_VERSION=$(cat node/Cargo.toml | grep version | sed "s/version = \"//g" | sed "s/\"//")
- echo $CLIENT_VERSION
- export RUNTIME_VERSION=$(cat runtime/$RUNTIME/src/lib.rs | grep "spec_version:" | sed "s/ *spec_version. //g" | sed "s/,//g")
- echo $RUNTIME_VERSION
- export CLIENT_MILESTONE="client-$CLIENT_VERSION"
- echo $CLIENT_MILESTONE
- export NETWORK_RELEASE="$NETWORK"
- echo $NETWORK_RELEASE
- export DOCKER_TAG="$RUNTIME_VERSION-$CLIENT_VERSION"
# Tags for Docker images
- export IMAGE_NAME="duniter/duniter-v2s-$NETWORK"
- echo $IMAGE_NAME
- export MANIFEST=localhost/manifest-$IMAGE_NAME:$DOCKER_TAG
- echo $MANIFEST
# Files to be pushed in a release
- export RELEASE_FILE_G1_DATA=release/genesis.json
- echo $RELEASE_FILE_G1_DATA
- export RELEASE_FILE_SPEC_CONFIG=release/${RUNTIME}.yaml
- echo $RELEASE_FILE_SPEC_CONFIG
- export RELEASE_FILE_SPEC=release/${RUNTIME}.json
- echo $RELEASE_FILE_SPEC
- export RELEASE_FILE_WASM=release/${RUNTIME}_runtime.compact.compressed.wasm
- echo $RELEASE_FILE_WASM
- export RELEASE_FILE_RAW_SPEC=release/${RUNTIME}-raw.json
- echo $RELEASE_FILE_RAW_SPEC
- export RELEASE_FILE_CLIENT_SPEC=release/gdev_client-specs.yaml
- echo $RELEASE_FILE_CLIENT_SPEC
- export CLIENT_RELEASE_NAME=$RUNTIME-$RUNTIME_VERSION-$CLIENT_VERSION
- echo $CLIENT_RELEASE_NAME
.release_runtime_vars: &define_release_runtime_vars
- echo "RUNTIME = $RUNTIME"
- export RUNTIME_VERSION=$(cat runtime/$RUNTIME/src/lib.rs | grep "spec_version:" | sed "s/ *spec_version. //g" | sed "s/,//g")
- echo $RUNTIME_VERSION
- export RUNTIME_MILESTONE="runtime-$RUNTIME_VERSION"
- echo $RUNTIME_MILESTONE
- export SRTOOL_OUTPUT=$CI_PROJECT_DIR/release/srtool_output_$RUNTIME.json
- echo "SRTOOL_OUTPUT = $SRTOOL_OUTPUT"
- export RELEASE_FILE_WASM=release/${RUNTIME}_runtime.compact.compressed.wasm
- echo $RELEASE_FILE_WASM
# srtool specific
- export RUNTIME_DIR=runtime/$RUNTIME
- echo "RUNTIME_DIR = $RUNTIME_DIR"
# srtool specific
- export PACKAGE=$RUNTIME-runtime
- echo "PACKAGE = $PACKAGE"
trigger_runtime_release:
stage: build
rules:
- <<: *is_runtime_branch
when: manual
variables:
RUNTIME: gdev
script:
- *define_release_runtime_vars
- echo "Vérification de l'absence de la release $RUNTIME_MILESTONE"
- echo "Contrôle de l'URL https://git.duniter.org/api/v4/projects/$CI_PROJECT_ID/releases/$RUNTIME_MILESTONE"
- curl -s https://git.duniter.org/api/v4/projects/$CI_PROJECT_ID/releases/$RUNTIME_MILESTONE --fail 1>/dev/null && (echo "Release déjà présente" && exit 1) || echo "Release absente"
trigger_network_release:
stage: build stage: build
rules: rules:
- if: $CI_PIPELINE_SOURCE != "merge_request_event" && $CI_COMMIT_BRANCH =~ /^(release\/runtime-)[0-9].*/ - <<: *is_network_branch
when: manual when: manual
# changes: script:
# - node/specs/$CHAIN-raw.json - *define_network_branch_vars
- echo "Vérification de l'absence de la release $NETWORK"
- echo "Contrôle de l'URL https://git.duniter.org/api/v4/projects/$CI_PROJECT_ID/releases/$NETWORK"
- curl -s https://git.duniter.org/api/v4/projects/$CI_PROJECT_ID/releases/$NETWORK --fail 1>/dev/null && (echo "Release déjà présente" && exit 1) || echo "Release absente"
trigger_client_release:
stage: build
rules:
- <<: *is_network_branch
when: manual
script:
- *define_network_branch_vars
- echo "Vérification de la présence de la release $NETWORK"
- echo "Contrôle de l'URL https://git.duniter.org/api/v4/projects/$CI_PROJECT_ID/releases/$NETWORK"
- curl -s https://git.duniter.org/api/v4/projects/$CI_PROJECT_ID/releases/$NETWORK --fail 1>/dev/null && echo "Release présente" || (echo "Release absente" && exit 1)
docker_deploy:
stage: release
needs: ["build_raw_specs"]
rules:
- <<: *is_network_branch
- when: never - when: never
before_script: before_script:
- sh -c "[ -n '$DUNITERTEAM_PASSWD' ] || ( echo No access to environment variable 'DUNITERTEAM_PASSWD'; exit 1 )" - sh -c "[ -n '$DUNITERTEAM_PASSWD' ] || ( echo No access to environment variable 'DUNITERTEAM_PASSWD'; exit 1 )"
- podman login -u "duniterteam" -p "$DUNITERTEAM_PASSWD" docker.io - podman login -u "duniterteam" -p "$DUNITERTEAM_PASSWD" docker.io
script: script:
- export MILESTONE=$(echo $CI_COMMIT_BRANCH | sed -e "s/release\///g") - *define_network_branch_vars
- echo $MILESTONE
- export MANIFEST=localhost/manifest-$IMAGE_NAME:$MILESTONE
- echo $MANIFEST
- podman manifest rm "$MANIFEST" 2>/dev/null || true - podman manifest rm "$MANIFEST" 2>/dev/null || true
- podman build --layers --platform linux/amd64,linux/arm64 --manifest "$MANIFEST" -f docker/Dockerfile $PODMAN_BUILD_OPTIONS . - podman build --layers --platform linux/amd64,linux/arm64 --manifest "$MANIFEST" -f docker/Dockerfile --build-arg chain=$RUNTIME .
- podman manifest push --all "$MANIFEST" "docker://docker.io/$IMAGE_NAME:$MILESTONE" - podman manifest push --all "$MANIFEST" "docker://docker.io/$IMAGE_NAME:$DOCKER_TAG"
- podman manifest push --all "$MANIFEST" "docker://docker.io/$IMAGE_NAME:latest" - podman manifest push --all "$MANIFEST" "docker://docker.io/$IMAGE_NAME:latest"
after_script: after_script:
- *define_network_branch_vars
- echo $MANIFEST
- podman manifest rm "$MANIFEST" - podman manifest rm "$MANIFEST"
variables:
IMAGE_NAME: "duniter/duniter-v2s-$CHAIN"
PODMAN_BUILD_OPTIONS: "--build-arg chain=$CHAIN"
tags: tags:
- podman - podman
gdev_docker_deploy:
extends: .deploy_docker_multiplatform
variables:
CHAIN: gdev
gtest_docker_deploy:
extends: .deploy_docker_multiplatform
variables:
CHAIN: gtest
readme_docker_release_tag:
stage: deploy_readme
rules:
- if: "$CI_COMMIT_TAG && $CI_COMMIT_TAG =~ /^(v|runtime-)[0-9].*/"
- when: never
image:
name: chko/docker-pushrm
entrypoint: ["/bin/sh", "-c", "/docker-pushrm"]
variables:
DOCKER_USER: duniterteam
DOCKER_PASS: "$DUNITERTEAM_PASSWD"
PUSHRM_SHORT: "Duniter v2 based on Substrate framework"
PUSHRM_TARGET: "docker.io/duniter/duniter-v2s"
PUSHRM_DEBUG: 1
PUSHRM_FILE: "$CI_PROJECT_DIR/docker/README.md"
script: "/bin/true"
############## SRTOOL ############## ############## SRTOOL ##############
.srtool: # The Network Runtime is only built when creating a network release (i.e.: genesis)
build_network_runtime:
stage: build stage: build
needs: ["trigger_network_release"]
rules: rules:
- if: $CI_PIPELINE_SOURCE != "merge_request_event" && $CI_COMMIT_BRANCH =~ /^(release\/runtime-)[0-9].*/ - <<: *is_network_branch
image: paritytech/srtool:1.74.0-0.13.0 image: paritytech/srtool:1.77.0-0.15.0
variables: variables:
PACKAGE: $RUNTIME-runtime SRTOOL_OUTPUT: $CI_PROJECT_DIR/release/network_srtool_output.json
RUNTIME_DIR: runtime/$RUNTIME
SRTOOL_OUTPUT: $CI_PROJECT_DIR/release/srtool_output_$RUNTIME.json
script: script:
- echo "Building runtime for $RUNTIME" - *define_network_branch_vars
- echo $CI_COMMIT_BRANCH | sed -e "s/release\///g" - echo "SRTOOL_OUTPUT = $SRTOOL_OUTPUT"
- mkdir -p $CI_PROJECT_DIR/release - mkdir -p $CI_PROJECT_DIR/release
- echo -e "[toolchain]\nchannel = \"`curl -s https://raw.githubusercontent.com/paritytech/srtool/master/RUSTC_VERSION`\"\ncomponents = [ \"rust-std\", \"rust-src\" ]" > $RUNTIME_DIR/rust-toolchain.toml # Workaround see !239
# Copy sources to the expected directory of srtool # Copy sources to the expected directory of srtool
- cp -R * /build/ - cp -R * /build/
# Build the runtime # Build the runtime
- /srtool/build --app --json -cM | tee -a $SRTOOL_OUTPUT - /srtool/build --app --json -cM | tee -a $SRTOOL_OUTPUT
- mv /build/runtime/$RUNTIME/target/srtool/release/wbuild/$RUNTIME-runtime/${RUNTIME}_runtime.compact.compressed.wasm $CI_PROJECT_DIR/release/ - mv /build/runtime/$RUNTIME/target/srtool/release/wbuild/$RUNTIME-runtime/${RUNTIME}_runtime.compact.compressed.wasm $CI_PROJECT_DIR/release/
artifacts: artifacts:
expire_in: never
name: "runtime" name: "runtime"
paths: paths:
- $CI_PROJECT_DIR/release - $CI_PROJECT_DIR/release
tags: tags:
- kepler - kepler
gdev_srtool: build_gdev_runtime:
extends: .srtool stage: build
needs: ["trigger_runtime_release"]
rules:
- <<: *is_runtime_branch
image: paritytech/srtool:1.77.0-0.15.0
variables: variables:
RUNTIME: gdev RUNTIME: gdev
script:
gtest_srtool: - *define_release_runtime_vars
extends: .srtool - mkdir -p $CI_PROJECT_DIR/release
variables: # Copy sources to the expected directory of srtool
RUNTIME: gtest - cp -R * /build/
# Build the runtime
- /srtool/build --app --json -cM | tee -a $SRTOOL_OUTPUT
- mv /build/runtime/$RUNTIME/target/srtool/release/wbuild/$RUNTIME-runtime/${RUNTIME}_runtime.compact.compressed.wasm $CI_PROJECT_DIR/release/
artifacts:
expire_in: never
name: "runtime"
paths:
- $CI_PROJECT_DIR/release
tags:
- kepler
############## SPECS ############## ############## SPECS ##############
create_g1_data: g1_data:
stage: build stage: build
needs: ["trigger_network_release"]
rules: rules:
- if: $CI_PIPELINE_SOURCE != "merge_request_event" && $CI_COMMIT_BRANCH =~ /^(release\/runtime-)[0-9].*/ - <<: *is_network_branch
image: python:3.9.18 image: h30x/py-g1-migrator # this image already has plyvel python requirement and dependency
variables: variables:
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
LEVELDB_PATH: /dump/duniter_default/data/leveldb LEVELDB_PATH: /dump/duniter_default/data/leveldb
script: script:
- *define_network_branch_vars
# Duniter 1.8.7 dump # Duniter 1.8.7 dump
- mkdir /dump - mkdir /dump
- cd /dump - cd /dump
...@@ -270,8 +370,6 @@ create_g1_data: ...@@ -270,8 +370,6 @@ create_g1_data:
# - bin/duniter sync g1.cgeek.fr --store-txs --nointeractive --mdb 1.8.7 # - bin/duniter sync g1.cgeek.fr --store-txs --nointeractive --mdb 1.8.7
# - mkdir -p /tmp/backup-g1-duniter-1.8.7 # - mkdir -p /tmp/backup-g1-duniter-1.8.7
# - cp -R $HOME/.config/duniter/1.8.7/data /tmp/backup-g1-duniter-1.8.7 # - cp -R $HOME/.config/duniter/1.8.7/data /tmp/backup-g1-duniter-1.8.7
# - cp -R $HOME/.config/duniter/1.8.7/g1 /tmp/backup-g1-duniter-1.8.7
# - cp -R $HOME/.config/duniter/1.8.7/txs.db /tmp/backup-g1-duniter-1.8.7
# - tar -cvzf /tmp/backup-g1-duniter-1.8.7.tgz /tmp/backup-g1-duniter-1.8.7 # - tar -cvzf /tmp/backup-g1-duniter-1.8.7.tgz /tmp/backup-g1-duniter-1.8.7
# Then the file is uploaded to dl.cgeek.fr manually # Then the file is uploaded to dl.cgeek.fr manually
- curl https://dl.cgeek.fr/public/backup-g1-duniter-1.8.7.tgz -o g1-dump.tgz - curl https://dl.cgeek.fr/public/backup-g1-duniter-1.8.7.tgz -o g1-dump.tgz
...@@ -279,128 +377,158 @@ create_g1_data: ...@@ -279,128 +377,158 @@ create_g1_data:
- rm g1-dump.tgz - rm g1-dump.tgz
- mv tmp/backup-g1-duniter-1.8.7 duniter_default - mv tmp/backup-g1-duniter-1.8.7 duniter_default
# py-g1-migrator conversion # py-g1-migrator conversion
- git clone https://git.duniter.org/tools/py-g1-migrator.git -b import_identities_from_leveldb /py-g1-migrator - git clone https://git.duniter.org/tools/py-g1-migrator.git --depth 1 /py-g1-migrator
- cd /py-g1-migrator - cd /py-g1-migrator
- rm -rf inputs/* # Export genesis file
- apt-get update - ./main.py # ./output/genesis.json
- apt-get install -y sqlite3 libleveldb-dev jq # Expore history files for squid
- pip install -r requirements.txt - ./squid-block.py # ./output/block_hist.json
# Export identities and wallets - ./squid-cert.py # ./output/cert_hist.json
- ./main.py - ./squid-tx.py # ./output/tx_hist.json
# Export transaction history
- sqlite3 /dump/duniter_default/txs.db --json "select time,comment,issuers,outputs from txs;" > inputs/transactions_history.json 2>> inputs/txs.err
- ./generate_transactions_history.py
# Merge in one file
- 'jq -s "{ identities: .[0].identities, wallets: .[0].wallets, initial_monetary_mass: .[0].initial_monetary_mass, current_block: .[0].current_block, transactions_history: .[1] }" output/gtest_genesis.json output/history.json > output/g1-data.json'
# Make the exported file available for next jobs # Make the exported file available for next jobs
- mkdir -p $CI_PROJECT_DIR/release/ - mkdir -p $CI_PROJECT_DIR/release/
- cp output/g1-data.json $CI_PROJECT_DIR/release/ - cp output/genesis.json $CI_PROJECT_DIR/$RELEASE_FILE_G1_DATA
- cp output/block_hist.json $CI_PROJECT_DIR/release/
- cp output/cert_hist.json $CI_PROJECT_DIR/release/
- cp output/tx_hist.json $CI_PROJECT_DIR/release/
artifacts: artifacts:
expire_in: never
paths: paths:
- $CI_PROJECT_DIR/release/ - $CI_PROJECT_DIR/release/
tags: tags:
- kepler - kepler
.build_specs: build_specs:
stage: build stage: build
needs: ["build_network_runtime", "g1_data"]
rules: rules:
- if: $CI_PIPELINE_SOURCE != "merge_request_event" && $CI_COMMIT_BRANCH =~ /^(release\/runtime-)[0-9].*/ - <<: *is_network_branch
image: rust:1-bullseye extends: .env
variables: variables:
WASM_FILE: $CI_PROJECT_DIR/release/${RUNTIME}_runtime.compact.compressed.wasm
DUNITER_GENESIS_DATA: $CI_PROJECT_DIR/release/g1-data.json
DUNITER_GENESIS_EXPORT: $CI_PROJECT_DIR/release/${RUNTIME}-indexer.json
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
script: script:
- *define_network_branch_vars
- export FEATURES="--features $RUNTIME --no-default-features"
- echo "FEATURES = $FEATURES"
- export WASM_FILE="$CI_PROJECT_DIR/$RELEASE_FILE_WASM"
- echo "WASM_FILE = $WASM_FILE"
- export DUNITER_GENESIS_DATA=$CI_PROJECT_DIR/$RELEASE_FILE_G1_DATA
- echo "DUNITER_GENESIS_DATA = $DUNITER_GENESIS_DATA"
- apt-get update - apt-get update
- apt-get install -y clang cmake protobuf-compiler - apt-get install -y clang cmake protobuf-compiler
- cargo run ${FEATURES} -- build-spec --chain=${RUNTIME}_live > release/${RUNTIME}.json # Build the spec file (including the G1 data), e.g.: "release/gdev.json"
- cargo run ${FEATURES} -- build-spec --chain=release/${RUNTIME}.json --disable-default-bootnode --raw > release/${RUNTIME}-raw.json - cargo run -Zgit=shallow-deps ${FEATURES} -- build-spec --chain=${RUNTIME}_live > $RELEASE_FILE_SPEC
- cp node/specs/${RUNTIME}_client-specs.yaml release/ # Save spec configuration file for release
- cp resources/${RUNTIME}.yaml $RELEASE_FILE_SPEC_CONFIG
artifacts: artifacts:
expire_in: never
name: "runtime" name: "runtime"
paths: paths:
- $CI_PROJECT_DIR/release - $CI_PROJECT_DIR/release
tags: tags:
- kepler - kepler
gdev_specs: build_raw_specs:
extends: .build_specs stage: build
needs: needs: ["trigger_client_release"]
- gdev_srtool rules:
- create_g1_data - <<: *is_network_branch
variables: image: rust:1-bullseye
RUNTIME: gdev script:
- *define_network_branch_vars
gtest_specs: - export FEATURES="--features $RUNTIME --no-default-features"
extends: .build_specs - echo "FEATURES = $FEATURES"
needs: - apt-get update
- gtest_srtool - apt-get install -y clang cmake protobuf-compiler jq
- create_g1_data # Print chainspec to file
variables: - cargo xtask print-spec $NETWORK_RELEASE > ${RUNTIME}-printed.json
RUNTIME: gtest # Merge client specs into chainspec file (to update bootnodes for example)
FEATURES: --features gtest --no-default-features # 1. Download yq to create a json client spec file
- wget https://github.com/mikefarah/yq/releases/download/v4.44.6/yq_linux_arm64 -O yq
- chmod +x ./yq
# 2. YML -> JSON for the client specs
- cat node/specs/${RUNTIME}_client-specs.yaml | ./yq --output-format json > node/specs/${RUNTIME}_client-specs.json
# 3. Merge the client spec file into chainspec file and create the final spec file (e.g. gdev.json)
- jq -s '.[0] * .[1]' node/specs/${RUNTIME}_client-specs.json ${RUNTIME}-printed.json > ${RUNTIME}.json
# Produce raw spec file
- mkdir -p $CI_PROJECT_DIR/release
- cargo run -Zgit=shallow-deps ${FEATURES} -- build-spec --chain=${RUNTIME}.json --disable-default-bootnode --raw > $RELEASE_FILE_RAW_SPEC
artifacts:
expire_in: never
name: "runtime"
paths:
- $CI_PROJECT_DIR/release
tags:
- kepler
############## RELEASE ############## ############## RELEASE ##############
create_release: create_network_release:
stage: release stage: release
needs: ["build_specs"]
rules: rules:
- if: $CI_PIPELINE_SOURCE != "merge_request_event" && $CI_COMMIT_BRANCH =~ /^(release\/runtime-)[0-9].*/ - <<: *is_network_branch
needs: ["create_g1_data", "gdev_srtool", "gtest_srtool"]
when: manual
image: rust:1-bullseye image: rust:1-bullseye
variables: variables:
SRTOOL_OUTPUT_GDEV: $CI_PROJECT_DIR/release/srtool_output_gdev.json # Used by `release-network` command
SRTOOL_OUTPUT_GTEST: $CI_PROJECT_DIR/release/srtool_output_gtest.json SRTOOL_OUTPUT: $CI_PROJECT_DIR/release/network_srtool_output.json
SRTOOL_OUTPUT_G1: $CI_PROJECT_DIR/release/srtool_output_g1.json
script: script:
- *define_network_branch_vars
# Release creation # Release creation
- export MILESTONE=$(echo $CI_COMMIT_BRANCH | sed -e "s/release\///g") - cargo xtask release-network $NETWORK_RELEASE $CI_COMMIT_BRANCH
- cargo xtask release-runtime $MILESTONE $CI_COMMIT_BRANCH # g1-data (initial data)
# We always ship runtimes: this is both a proof and a convenience - cargo xtask create-asset-link $NETWORK_RELEASE g1-data.json https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/$RELEASE_FILE_G1_DATA
- cargo xtask create-asset-link $MILESTONE g1-data.json https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/release/g1-data.json # gdev.yaml (spec configuration)
- cargo xtask create-asset-link $MILESTONE gdev_runtime.compact.compressed.wasm https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/release/gdev_runtime.compact.compressed.wasm - cargo xtask create-asset-link $NETWORK_RELEASE ${RUNTIME}.yaml https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/$RELEASE_FILE_SPEC_CONFIG
- cargo xtask create-asset-link $MILESTONE gtest_runtime.compact.compressed.wasm https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/release/gtest_runtime.compact.compressed.wasm # initial runtime
- cargo xtask create-asset-link $MILESTONE gdev_client-specs.yaml https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/release/gdev_client-specs.yaml - cargo xtask create-asset-link $NETWORK_RELEASE ${RUNTIME}_runtime.compact.compressed.wasm https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/$RELEASE_FILE_WASM
- cargo xtask create-asset-link $MILESTONE gtest_client-specs.yaml https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/release/gtest_client-specs.yaml # the result: gdev.json (genesis)
- cargo xtask create-asset-link $NETWORK_RELEASE ${RUNTIME}.json https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/$RELEASE_FILE_SPEC
artifacts: artifacts:
expire_in: never
paths: paths:
- $CI_PROJECT_DIR/release/ - $CI_PROJECT_DIR/release/
tags: tags:
- kepler - kepler
# ------ RELEASE: ADD SPECS ------ create_client_release:
.release_specs:
stage: release stage: release
needs: ["build_raw_specs"]
rules: rules:
- if: $CI_PIPELINE_SOURCE != "merge_request_event" && $CI_COMMIT_BRANCH =~ /^(release\/runtime-)[0-9].*/ - <<: *is_network_branch
image: rust:1-bullseye image: rust:1-bullseye
script: script:
- export MILESTONE=$(echo $CI_COMMIT_BRANCH | sed -e "s/release\///g") - *define_network_branch_vars
- cargo xtask create-asset-link $MILESTONE ${RUNTIME}.json https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/release/${RUNTIME}.json # Create the GitLab release page + tag and associate the milestone
- cargo xtask create-asset-link $MILESTONE ${RUNTIME}-raw.json https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/release/${RUNTIME}-raw.json - cargo xtask release-client $CLIENT_RELEASE_NAME $CI_COMMIT_BRANCH $CLIENT_MILESTONE
- cargo xtask create-asset-link $MILESTONE ${RUNTIME}-indexer.json https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/release/${RUNTIME}-indexer.json # Add the client assets
- echo "Release Docker file..." - cargo xtask create-asset-link $CLIENT_RELEASE_NAME ${RUNTIME}_client-specs.yaml https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/$RELEASE_FILE_CLIENT_SPEC
- cargo xtask create-asset-link $CLIENT_RELEASE_NAME ${RUNTIME}-raw.json https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/$RELEASE_FILE_RAW_SPEC
artifacts: artifacts:
expire_in: never
paths: paths:
- $CI_PROJECT_DIR/release/ - $CI_PROJECT_DIR/release/
tags: tags:
- kepler - kepler
release_gdev_specs: create_runtime_release:
extends: .release_specs stage: release
needs: needs: ["build_gdev_runtime"]
- create_release rules:
- gdev_specs - <<: *is_runtime_branch
image: rust:1-bullseye
variables: variables:
RUNTIME: gdev RUNTIME: gdev
script:
release_gtest_specs: - *define_release_runtime_vars
extends: .release_specs # Create the GitLab release page + tag and associate the milestone.
needs: # Note: the release name = the release tag = runtime milesone ($RUNTIME_MILESTONE)
- create_release - cargo xtask release-runtime $RUNTIME_MILESTONE $RUNTIME $CI_COMMIT_BRANCH $RUNTIME_MILESTONE
- gtest_specs - cargo xtask create-asset-link $RUNTIME_MILESTONE ${RUNTIME}_runtime.compact.compressed.wasm https://nodes.pages.duniter.org/-/rust/duniter-v2s/-/jobs/$CI_JOB_ID/artifacts/$RELEASE_FILE_WASM
variables: # In the future: also build gtest and g1 runtimes and atach them
RUNTIME: gtest artifacts:
expire_in: never
paths:
- $CI_PROJECT_DIR/release/
tags:
- kepler
...@@ -29,7 +29,7 @@ USER duniter ...@@ -29,7 +29,7 @@ USER duniter
# check if executable works in this container # check if executable works in this container
RUN /usr/local/bin/duniter --version RUN /usr/local/bin/duniter --version
EXPOSE 30333 9933 9944 EXPOSE 30333 9944
VOLUME ["/duniter"] VOLUME ["/duniter"]
ENTRYPOINT ["/usr/local/bin/duniter"] ENTRYPOINT ["/usr/local/bin/duniter"]
source diff could not be displayed: it is too large. Options to address this: view the blob.
...@@ -47,64 +47,68 @@ version = '1.0.0' ...@@ -47,64 +47,68 @@ version = '1.0.0'
[workspace.dependencies] [workspace.dependencies]
# crates.io dependencies # crates.io dependencies
anyhow = { version = "1.0.79", default-features = false } anyhow = { version = "1.0.81", default-features = false }
base64 = { version = "0.22.1", default-features = false }
countmap = { version = "0.2.0", default-features = false } countmap = { version = "0.2.0", default-features = false }
ctrlc = { version = "3.4.2", default-features = false } ctrlc = { version = "3.4.4", default-features = false }
cucumber = { version = "0.20.2", default-features = false } cucumber = { version = "0.20.2", default-features = false }
env_logger = { version = "0.11.1", default-features = false } env_logger = { version = "0.11.3", default-features = false }
notify = { version = "6.1.1", default-features = false } notify = { version = "6.1.1", default-features = false }
portpicker = { version = "0.1.1", default-features = false } portpicker = { version = "0.1.1", default-features = false }
notify-debouncer-mini = { version = "0.4.1", default-features = false } notify-debouncer-mini = { version = "0.4.1", default-features = false }
async-io = { version = "2.3.1", default-features = false } async-io = { version = "2.3.1", default-features = false }
async-trait = { version = "0.1.77", default-features = false } async-trait = { version = "0.1.78", default-features = false }
thiserror = { version = "1.0.56", default-features = false } thiserror = { version = "1.0.58", default-features = false }
frame-metadata = { version = "16.0.0", default-features = false } frame-metadata = { version = "16.0.0", default-features = false }
graphql_client = { version = "0.10.0" } graphql_client = { version = "0.13.0" }
bs58 = { version = "0.5.0", default-features = false } bs58 = { version = "0.5.1", default-features = false }
placeholder = { version = "1.1.3", default-features = false } placeholder = { version = "1.1.4", default-features = false }
getrandom = { version = "0.2.12", default-features = false } clap = { version = "4.5.3" }
clap = { version = "4.4.18" } clap_complete = { version = "4.5.1" }
clap_complete = { version = "4.4.10" } reqwest = { version = "0.12.0", default-features = false, features = [
reqwest = { version = "0.11.11", default-features = false } "rustls-tls",
] }
glob = { version = "0.3.1", default-features = false } glob = { version = "0.3.1", default-features = false }
convert_case = { version = "0.6.0", default-features = false } convert_case = { version = "0.6.0", default-features = false }
subweight-core = { version = "3.3.1", default-features = false } subweight-core = { version = "3.3.1", default-features = false }
version_check = { version = "0.9.2", default-features = false } version_check = { version = "0.9.4", default-features = false }
codec = { package = "parity-scale-codec", version = "3.6.9", default-features = false } codec = { package = "parity-scale-codec", version = "3.6.9", default-features = false }
enum-as-inner = { version = "=0.5.1", default-features = false } #https://github.com/bluejekyll/trust-dns/issues/1946 enum-as-inner = { version = "=0.5.1", default-features = false } #https://github.com/bluejekyll/trust-dns/issues/1946
futures = { version = "0.3.30", default-features = false } futures = { version = "0.3.30", default-features = false }
tera = { version = "1", default-features = false } tera = { version = "1", default-features = false }
hex = { version = "0.4.3", default-features = false } hex = { version = "0.4.3", default-features = false }
jsonrpsee = { version = "0.20.3", default-features = false } # Version should exactly match polkadot one jsonrpsee = { version = "0.24.3", default-features = false } # Version should exactly match polkadot one
lazy_static = { version = "1.4.0", default-features = false } lazy_static = { version = "1.4.0", default-features = false }
log = { version = "0.4.20", default-features = false } log = { version = "0.4.21", default-features = false }
maplit = { version = '1.0.2', default-features = false } maplit = { version = '1.0.2', default-features = false }
proc-macro2 = { version = '1.0.76', default-features = false } proc-macro2 = { version = '1.0.79', default-features = false }
quote = { version = '1.0.35', default-features = false } quote = { version = '1.0.35', default-features = false }
syn = { version = '2.0.48', default-features = false } syn = { version = '2.0.53', default-features = false }
memmap2 = { version = "0.9.4", default-features = false } memmap2 = { version = "0.9.4", default-features = false }
num-format = { version = "0.4.4", default-features = false } num-format = { version = "0.4.4", default-features = false }
smallvec = { version = "1.13.1", default-features = false } smallvec = { version = "1.13.2", default-features = false }
hex-literal = { version = '0.4.1', default-features = false } hex-literal = { version = '0.4.1', default-features = false }
scale-info = { version = "2.10.0", default-features = false } scale-info = { version = "2.11.0", default-features = false }
scale-value = { version = "0.13.0", default-features = false } scale-value = { version = "0.14.1", default-features = false }
serde = { version = "1.0.196", default-features = false } serde = { version = "1.0.197", default-features = false }
serde_derive = { version = "1.0.196", default-features = false } serde_derive = { version = "1.0.197", default-features = false }
serde_yaml = { version = "0.9.27", default-features = false } serde_yaml = { version = "0.9.33", default-features = false }
serde_json = { version = "1.0.64", default-features = false } serde_json = { version = "1.0.114", default-features = false }
fnv = { version = "1.0.7", default-features = false } fnv = { version = "1.0.7", default-features = false }
tokio = { version = "1.35.1", default-features = false } tokio = { version = "1.36.0", default-features = false }
time = { version = "0.3.31", default-features = false } time = { version = "0.3.34", default-features = false }
time-macros = { version = "0.2.16", default-features = false } time-macros = { version = "0.2.17", default-features = false }
num-traits = { version = "0.2.17", default-features = false } num-traits = { version = "0.2.18", default-features = false }
rayon = { version = "1.8.1", default-features = false } rayon = { version = "1.9.0", default-features = false }
simple_logger = { version = "4.3.3", default-features = false } simple_logger = { version = "4.3.3", default-features = false }
bincode = { version = "1.3.3", default-features = false } bincode = { version = "1.3.3", default-features = false }
dubp-wot = { version = "0.11.1", default-features = false } dubp-wot = { version = "0.11.1", default-features = false }
flate2 = { version = "1.0.28", default-features = false } flate2 = { version = "1.0.28", default-features = false }
array-bytes = { version = "6.2.2", default-features = false }
parking_lot = { version = "0.12.1" }
# Subxt # Subxt
subxt = { git = 'https://github.com/duniter/subxt', branch = 'subxt-v0.34.0-duniter-substrate-v1.7.1', default-features = false } subxt = { git = 'https://github.com/duniter/subxt', branch = 'subxt-v0.38.0-duniter-substrate-v1.17.0', default-features = false }
# local dependencies # local dependencies
weight-analyzer = { path = "resources/weight_analyzer", default-features = false } weight-analyzer = { path = "resources/weight_analyzer", default-features = false }
...@@ -136,86 +140,90 @@ sp-distance = { path = 'primitives/distance', default-features = false } ...@@ -136,86 +140,90 @@ sp-distance = { path = 'primitives/distance', default-features = false }
sp-membership = { path = 'primitives/membership', default-features = false } sp-membership = { path = 'primitives/membership', default-features = false }
# substrate dependencies # substrate dependencies
pallet-transaction-payment-rpc = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-transaction-payment-rpc = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
frame-benchmarking = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } frame-benchmarking = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
frame-executive = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } frame-metadata-hash-extension = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
frame-support = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } frame-executive = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
frame-system = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } frame-support = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
frame-system-benchmarking = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } frame-system = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
frame-system-rpc-runtime-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } frame-system-benchmarking = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
frame-try-runtime = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } frame-system-rpc-runtime-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-atomic-swap = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } frame-try-runtime = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-authority-discovery = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-atomic-swap = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-authorship = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-authority-discovery = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-babe = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-authorship = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-balances = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-babe = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-collective = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-balances = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-grandpa = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-collective = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-im-online = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-grandpa = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-multisig = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-im-online = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-preimage = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-multisig = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-proxy = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-preimage = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-scheduler = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-proxy = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-session = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-scheduler = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-sudo = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-session = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-timestamp = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-sudo = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-transaction-payment = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-timestamp = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-transaction-payment-rpc-runtime-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-transaction-payment = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-treasury = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-transaction-payment-rpc-runtime-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
pallet-utility = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-treasury = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } pallet-utility = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-arithmetic = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-block-builder = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-arithmetic = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-client-db = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-block-builder = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-client-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-client-db = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-consensus-grandpa = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-client-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-consensus-babe = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-consensus-grandpa = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-consensus-babe-rpc = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-rpc = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-blockchain = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-consensus-grandpa-rpc = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-offchain = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-consensus-babe = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
try-runtime-cli = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-consensus-babe-rpc = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-consensus-babe = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-blockchain = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-consensus-grandpa = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-offchain = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-core = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-consensus-babe = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-inherents = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-consensus-grandpa = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-offchain = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-core = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-runtime = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-inherents = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-session = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-offchain = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-std = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-runtime = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-staking = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-session = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-weights = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-staking = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-transaction-pool = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-weights = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-version = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-transaction-pool = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-cli = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-version = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-service = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-cli = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-trie = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-service = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-authority-discovery = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-trie = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-genesis-builder = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-authority-discovery = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-keyring = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-genesis-builder = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-consensus = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-keyring = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-core-hashing = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-consensus = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-keystore = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-core-hashing = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-rpc-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-keystore = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
substrate-wasm-builder = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-rpc-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-io = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } substrate-wasm-builder = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
substrate-build-script-utils = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1' } sp-io = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
node-primitives = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } substrate-build-script-utils = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0' }
frame-benchmarking-cli = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } node-primitives = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-chain-spec = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } frame-benchmarking-cli = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-consensus = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-chain-spec = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-consensus-manual-seal = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-consensus = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-executor = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-consensus-manual-seal = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-telemetry = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-executor = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-transaction-pool = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-telemetry = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-basic-authorship = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-transaction-pool = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-network = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-basic-authorship = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-keystore = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-network = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-storage = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-network-sync = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-timestamp = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-network-test = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-transaction-storage-proof = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sc-utils = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-transaction-pool-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-keystore = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-state-machine = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-storage = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
substrate-frame-rpc-system = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.7.1', default-features = false } sp-timestamp = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-transaction-storage-proof = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sc-transaction-pool-api = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
sp-state-machine = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
substrate-frame-rpc-system = { git = 'https://github.com/duniter/duniter-polkadot-sdk', branch = 'duniter-substrate-v1.17.0', default-features = false }
# The list of dependencies below (which can be both direct and indirect dependencies) are crates # The list of dependencies below (which can be both direct and indirect dependencies) are crates
# that are suspected to be CPU-intensive, and that are unlikely to require debugging (as some of # that are suspected to be CPU-intensive, and that are unlikely to require debugging (as some of
...@@ -239,9 +247,6 @@ cranelift-wasm = { opt-level = 3 } ...@@ -239,9 +247,6 @@ cranelift-wasm = { opt-level = 3 }
crc32fast = { opt-level = 3 } crc32fast = { opt-level = 3 }
crossbeam-deque = { opt-level = 3 } crossbeam-deque = { opt-level = 3 }
crypto-mac = { opt-level = 3 } crypto-mac = { opt-level = 3 }
curve25519-dalek = { opt-level = 3 }
ed25519-dalek = { opt-level = 3 }
flate2 = { opt-level = 3 }
futures-channel = { opt-level = 3 } futures-channel = { opt-level = 3 }
hashbrown = { opt-level = 3 } hashbrown = { opt-level = 3 }
hash-db = { opt-level = 3 } hash-db = { opt-level = 3 }
...@@ -267,7 +272,6 @@ smallvec = { opt-level = 3 } ...@@ -267,7 +272,6 @@ smallvec = { opt-level = 3 }
snow = { opt-level = 3 } snow = { opt-level = 3 }
twox-hash = { opt-level = 3 } twox-hash = { opt-level = 3 }
uint = { opt-level = 3 } uint = { opt-level = 3 }
wasmi = { opt-level = 3 }
x25519-dalek = { opt-level = 3 } x25519-dalek = { opt-level = 3 }
yamux = { opt-level = 3 } yamux = { opt-level = 3 }
zeroize = { opt-level = 3 } zeroize = { opt-level = 3 }
......
...@@ -10,34 +10,46 @@ ...@@ -10,34 +10,46 @@
<img alt="logov2" src="https://duniter.fr/img/duniterv2.svg" width="128" height="128"/> <img alt="logov2" src="https://duniter.fr/img/duniterv2.svg" width="128" height="128"/>
</div> </div>
## Documentation TOC ## Documentation
- [README](./README.md) Multiple documentation sources are available depending on the level of detail you need.
- Full technical Rust doc (auto-generated with `cargo xtask gen-doc`) : https://doc-duniter-org.ipns.pagu.re/duniter/
- User and client developer doc (official website) : https://duniter.org/wiki/duniter-v2/
- Internal documentation (within git repository), see table of contents below : [./doc](./doc)
### Internal documentation TOC
- [README](./README.md) (this file)
- [Use](#use) - [Use](#use)
- [Test](#test)
- [Contribute](#contribute) - [Contribute](#contribute)
- [Structure](#project-structure) - [License](#license)
- [docker](./docker/) docker-related documentation - [docs](./docs/) internal documentation
- [docs](./docs/) - [api](./docs/api/) API
- [api](./docs/api/) - [manual](./docs/api/manual.md) manage account and identities
- [manual](./docs/api/manual.md)
- [runtime-calls](./docs/api/runtime-calls.md) the calls you can submit through the RPC API - [runtime-calls](./docs/api/runtime-calls.md) the calls you can submit through the RPC API
- [dev](./docs/dev/) - [runtime-errors](./docs/api/runtime-errors.md) the errors you can get submitting a call
- [runtime-events](./docs/api/runtime-events.md) the events you can get submitting a call
- [dev](./docs/dev/) developer documentation
- [beginner-walkthrough](./docs/dev/beginner-walkthrough.md) - [beginner-walkthrough](./docs/dev/beginner-walkthrough.md)
- [git-conventions](./docs/dev/git-conventions.md) - [git-conventions](./docs/dev/git-conventions.md)
- [pallet_conventions](./docs/dev/pallet_conventions.md)
- [launch-a-live-network](./docs/dev/launch-a-live-network.md) - [launch-a-live-network](./docs/dev/launch-a-live-network.md)
- [setup](./docs/dev/setup.md) - [setup](./docs/dev/setup.md)
- [compilation features](./docs/dev/compilation.md) - [compilation features](./docs/dev/compilation.md)
- [verify-runtime-code](./docs/dev/verify-runtime-code.md) - [verify-runtime-code](./docs/dev/verify-runtime-code.md)
- [weights-benchmarking](./docs/dev/weights-benchmarking.md) - [weights-benchmarking](./docs/dev/weights-benchmarking.md)
- [upgrade-substrate](./docs/dev/upgrade-substrate.md) - [upgrade-substrate](./docs/dev/upgrade-substrate.md)
- [test](./docs/test/)
- [replay-block](./docs/test/replay-block.md) - [replay-block](./docs/test/replay-block.md)
- [user](./docs/user/) - [user](./docs/user/) user documentation
- [autocompletion](./docs/user/autocompletion.md) - [autocompletion](./docs/user/autocompletion.md)
- [build-for-arm](./docs/user/build-for-arm.md) - [debian installation](./docs/user/installation_debian.md)
- [mirror](./docs/user/mirror.md) deploy a permanent ǦDev mirror node - [distance](./docs/user/distance.md)
- [smith](./docs/user/smith.md) deploy a permanent ǦDev validator node - [fees](./docs/user/fees.md)
- [packaging](./docs/packaging/) packaging
- [build-for-arm](./docs/packaging/build-for-arm.md) build for ARM architecture
- [build-debian](./docs/packaging/build-deb.md) build a native Debian package
- [docker](./docker/) docker-related documentation
- [end2end-tests](./end2end-tests/) automated end to end tests written with cucumber - [end2end-tests](./end2end-tests/) automated end to end tests written with cucumber
- [live-tests](./live-tests/) sanity checks to test the storage of a live chain - [live-tests](./live-tests/) sanity checks to test the storage of a live chain
...@@ -47,23 +59,23 @@ ...@@ -47,23 +59,23 @@
The easiest way is to use the docker image. The easiest way is to use the docker image.
Minimal command to deploy a **temporary** mirror peer: Minimal command to deploy a temporary mirror peer:
```docker ```docker
docker run -it -p9944:9944 -e DUNITER_CHAIN_NAME=gdev duniter/duniter-v2s:v0.4.0 --tmp --execution=Wasm docker run -it -p9944:9944 -e DUNITER_CHAIN_NAME=gdev duniter/duniter-v2s-gdev-800:latest
``` ```
To go further, read [How to deploy a permanent mirror node on ĞDev network](./docs/user/rpc.md). To go further, read [How to deploy a permanent mirror node on ĞDev network 🔗](https://duniter.org/wiki/duniter-v2/#run-a-mirror-node).
### Create your local blockchain ### Create your local blockchain
It can be useful to deploy your local blockchain, for instance to have a controlled environment to develop/test an application that interacts with the blockchain. It can be useful to deploy your local blockchain, for instance to have a controlled environment to develop/test an application that interacts with the blockchain.
```docker ```docker
docker run -it -p9944:9944 duniter/duniter-v2s:v0.4.0 --tmp docker run -it -p9944:9944 duniter/duniter-v2s-gdev-800:latest
``` ```
Or use the `docker-compose.yml` at the root of this repository. Or use the [`docker-compose.yml`](./docker-compose.yml) at the root of this repository.
#### Control when your local blockchain should produce blocks #### Control when your local blockchain should produce blocks
...@@ -74,34 +86,9 @@ You can decide when to produce blocks with the cli option `--sealing` which has ...@@ -74,34 +86,9 @@ You can decide when to produce blocks with the cli option `--sealing` which has
- `--sealing=instant`: produce a block immediately upon receiving a transaction into the transaction pool - `--sealing=instant`: produce a block immediately upon receiving a transaction into the transaction pool
- `--sealing=manual`: produce a block upon receiving an RPC request (method `engine_createBlock`). - `--sealing=manual`: produce a block upon receiving an RPC request (method `engine_createBlock`).
### Autocompletion ### Shell autocompletion
See [autocompletion](./docs/user/autocompletion.md).
## Test See [autocompletion](./docs/user/autocompletion.md) to generate shell autocompletion for duniter commands.
### Test a specific commit
At each commit on master, an image with the tag `debug-sha-********` is published, where `********`
corresponds to the first 8 hash characters of the commit.
Usage:
```docker
docker run -it -p9944:9944 --name duniter-v2s duniter/duniter-v2s:debug-sha-b836f1a6
```
Then open `https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944` in a browser.
Enable detailed logging:
```docker
docker run -it -p9944:9944 --name duniter-v2s \
-e RUST_LOG=debug \
-e RUST_BACKTRACE=1 \
-lruntime=debug \
duniter/duniter-v2s:debug-sha-b836f1a6
```
## Contribute ## Contribute
...@@ -128,20 +115,11 @@ cargo build ...@@ -128,20 +115,11 @@ cargo build
Use Rust's native `cargo` command to build and launch the node: Use Rust's native `cargo` command to build and launch the node:
```sh ```sh
cargo run -- --dev --tmp cargo run -- --dev
``` ```
This will deploy a local blockchain with test accounts (Alice, Bob, etc) in the genesis. This will deploy a local blockchain with test accounts (Alice, Bob, etc) in the genesis.
Open `https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944` to watch and interact with your node.
## Single-Node Development Chain
This command will start the single-node development chain with persistent state:
```bash
./target/debug/duniter --dev --tmp
```
Then open `https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944` in a browser.
Start the development chain with detailed logging: Start the development chain with detailed logging:
...@@ -149,140 +127,11 @@ Start the development chain with detailed logging: ...@@ -149,140 +127,11 @@ Start the development chain with detailed logging:
RUST_LOG=debug RUST_BACKTRACE=1 ./target/debug/duniter -lruntime=debug --dev RUST_LOG=debug RUST_BACKTRACE=1 ./target/debug/duniter -lruntime=debug --dev
``` ```
## Multi-Node Local Testnet ## License
If you want to see the multi-node consensus algorithm in action, refer to
[our Start a Private Network tutorial](https://substrate.dev/docs/en/tutorials/start-a-private-network/).
### Purge previous local testnet
```
./target/debug/duniter purge-chain --base-path /tmp/alice --chain local
./target/debug/duniter purge-chain --base-path /tmp/bob --chain local
```
### Start Alice's node
```bash
./target/debug/duniter \
--base-path /tmp/alice \
--chain local \
--alice \
--port 30333 \
--ws-port 9945 \
--rpc-port 9933 \
--node-key 0000000000000000000000000000000000000000000000000000000000000001 \
--validator
```
### Start Bob's node
```bash See [LICENSE](./LICENSE)
./target/debug/duniter \
--base-path /tmp/bob \
--chain local \
--bob \
--port 30334 \
--ws-port 9946 \
--rpc-port 9934 \
--validator \
--bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp
```
## Project Structure
A Substrate project such as this consists of a number of components that are spread across a few
directories.
### Node
A blockchain node is an application that allows users to participate in a blockchain network.
Substrate-based blockchain nodes expose a number of capabilities:
- Networking: Substrate nodes use the [`libp2p`](https://libp2p.io/) networking stack to allow the
nodes in the network to communicate with one another.
- Consensus: Blockchains must have a way to come to
[consensus](https://substrate.dev/docs/en/knowledgebase/advanced/consensus) on the state of the
network. Substrate makes it possible to supply custom consensus engines and also ships with
several consensus mechanisms that have been built on top of
[Web3 Foundation research](https://research.web3.foundation/en/latest/polkadot/NPoS/index.html).
- RPC Server: A remote procedure call (RPC) server is used to interact with Substrate nodes.
There are several files in the `node` directory - take special note of the following:
- [`chain_spec.rs`](./node/src/chain_spec.rs): A
[chain specification](https://substrate.dev/docs/en/knowledgebase/integrate/chain-spec) is a
source code file that defines a Substrate chain's initial (genesis) state. Chain specifications
are useful for development and testing, and critical when architecting the launch of a
production chain. Take note of the `development_chain_spec` and `testnet_genesis` functions, which
are used to define the genesis state for the local development chain configuration. These
functions identify some
[well-known accounts](https://substrate.dev/docs/en/knowledgebase/integrate/subkey#well-known-keys)
and use them to configure the blockchain's initial state.
- [`service.rs`](./node/src/service.rs): This file defines the node implementation. Take note of
the libraries that this file imports and the names of the functions it invokes. In particular,
there are references to consensus-related topics, such as the
[longest chain rule](https://substrate.dev/docs/en/knowledgebase/advanced/consensus#longest-chain-rule),
the [Babe](https://substrate.dev/docs/en/knowledgebase/advanced/consensus#babe) block authoring
mechanism and the
[GRANDPA](https://substrate.dev/docs/en/knowledgebase/advanced/consensus#grandpa) finality
gadget.
After the node has been [built](#build), refer to the embedded documentation to learn more about the
capabilities and configuration parameters that it exposes:
```shell
./target/debug/duniter --help
``` ```
### Runtime
In Substrate, the terms
"[runtime](https://substrate.dev/docs/en/knowledgebase/getting-started/glossary#runtime)" and
"[state transition function](https://substrate.dev/docs/en/knowledgebase/getting-started/glossary#stf-state-transition-function)"
are analogous - they refer to the core logic of the blockchain that is responsible for validating
blocks and executing the state changes they define. The Substrate project in this repository uses
the [FRAME](https://substrate.dev/docs/en/knowledgebase/runtime/frame) framework to construct a
blockchain runtime. FRAME allows runtime developers to declare domain-specific logic in modules
called "pallets". At the heart of FRAME is a helpful
[macro language](https://substrate.dev/docs/en/knowledgebase/runtime/macros) that makes it easy to
create pallets and flexibly compose them to create blockchains that can address
[a variety of needs](https://www.substrate.io/substrate-users/).
Review the [FRAME runtime implementation](./runtime/src/lib.rs) included in this template and note
the following:
- This file configures several pallets to include in the runtime. Each pallet configuration is
defined by a code block that begins with `impl $PALLET_NAME::Config for Runtime`.
- The pallets are composed into a single runtime by way of the
[`construct_runtime!`](https://crates.parity.io/frame_support/macro.construct_runtime.html)
macro, which is part of the core
[FRAME Support](https://substrate.dev/docs/en/knowledgebase/runtime/frame#support-library)
library.
### Pallets
The runtime in this project is constructed using many FRAME pallets that ship with the
[core Substrate repository](https://github.com/paritytech/substrate/tree/master/frame) and a
template pallet that is [defined in the `pallets`](./pallets/template/src/lib.rs) directory.
A FRAME pallet is compromised of a number of blockchain primitives:
- Storage: FRAME defines a rich set of powerful
[storage abstractions](https://substrate.dev/docs/en/knowledgebase/runtime/storage) that makes
it easy to use Substrate's efficient key-value database to manage the evolving state of a
blockchain.
- Dispatchables: FRAME pallets define special types of functions that can be invoked (dispatched)
from outside of the runtime in order to update its state.
- Events: Substrate uses [events](https://substrate.dev/docs/en/knowledgebase/runtime/events) to
notify users of important changes in the runtime.
- Errors: When a dispatchable fails, it returns an error.
- Config: The `Config` configuration interface is used to define the types and parameters upon
which a FRAME pallet depends.
## License
CopyLeft 2021-2023 Axiom-Team CopyLeft 2021-2023 Axiom-Team
Some parts borrowed from Polkadot (Parity Technologies (UK) Ltd.) Some parts borrowed from Polkadot (Parity Technologies (UK) Ltd.)
...@@ -298,3 +147,4 @@ GNU Affero General Public License for more details. ...@@ -298,3 +147,4 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
```
...@@ -13,14 +13,10 @@ targets = ["x86_64-unknown-linux-gnu"] ...@@ -13,14 +13,10 @@ targets = ["x86_64-unknown-linux-gnu"]
[features] [features]
std = [ std = [
"codec/std",
"frame-support/std", "frame-support/std",
"log/std",
"pallet-distance/std", "pallet-distance/std",
"scale-info/std",
"sp-core/std", "sp-core/std",
"sp-distance/std", "sp-distance/std",
"sp-keystore/std",
"sp-runtime/std", "sp-runtime/std",
] ]
runtime-benchmarks = [ runtime-benchmarks = [
...@@ -36,14 +32,11 @@ try-runtime = [ ...@@ -36,14 +32,11 @@ try-runtime = [
] ]
[dependencies] [dependencies]
codec = { workspace = true, features = ["derive"] }
frame-support = { workspace = true } frame-support = { workspace = true }
log = { workspace = true } log = { workspace = true }
pallet-distance = { workspace = true } pallet-distance = { workspace = true }
sc-client-api = { workspace = true } sc-client-api = { workspace = true }
scale-info = { workspace = true, features = ["derive"] }
sp-core = { workspace = true } sp-core = { workspace = true }
sp-distance = { workspace = true } sp-distance = { workspace = true }
sp-keystore = { workspace = true }
sp-runtime = { workspace = true } sp-runtime = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
# Distance Oracle Inherent Data Provider
You can find the autogenerated documentation at: [https://doc-duniter-org.ipns.pagu.re/dc_distance/index.html](https://doc-duniter-org.ipns.pagu.re/dc_distance/index.html).
...@@ -14,13 +14,37 @@ ...@@ -14,13 +14,37 @@
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>. // along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
use codec::{Decode, Encode}; //! # Distance Oracle Inherent Data Provider
//!
//! This crate provides functionality for creating an **inherent data provider**
//! specifically designed for the "Distance Oracle".
//! The inherent data provider is responsible for fetching and delivering
//! computation results required for the runtime to process distance evaluations.
//!
//! ## Relationship with Distance Oracle
//!
//! The **distance-oracle** is responsible for computing distance evaluations,
//! storing the results to be read in the next period, and saving them to files.
//! These files are then read by **this inherent data provider**
//! to provide the required data to the runtime.
//!
//! ## Overview
//!
//! - Retrieves **period index** and **evaluation results** from the storage and file system.
//! - Determines whether the computation results for the current period have already been published.
//! - Reads and parses evaluation result files when available, providing the necessary data to the runtime.
use frame_support::pallet_prelude::*; use frame_support::pallet_prelude::*;
use sc_client_api::{ProvideUncles, StorageKey, StorageProvider}; use sc_client_api::{ProvideUncles, StorageKey, StorageProvider};
use scale_info::TypeInfo;
use sp_runtime::{generic::BlockId, traits::Block as BlockT, AccountId32}; use sp_runtime::{generic::BlockId, traits::Block as BlockT, AccountId32};
use std::path::PathBuf; use std::path::PathBuf;
/// The file version that should match the distance oracle one.
/// This ensures that the smith avoids accidentally submitting invalid data
/// in case there are changes in logic between the runtime and the oracle,
/// thereby preventing potential penalties.
const VERSION_PREFIX: &str = "001-";
type IdtyIndex = u32; type IdtyIndex = u32;
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
...@@ -35,38 +59,42 @@ pub fn create_distance_inherent_data_provider<B, C, Backend>( ...@@ -35,38 +59,42 @@ pub fn create_distance_inherent_data_provider<B, C, Backend>(
parent: B::Hash, parent: B::Hash,
distance_dir: PathBuf, distance_dir: PathBuf,
owner_keys: &[sp_core::sr25519::Public], owner_keys: &[sp_core::sr25519::Public],
) -> Result<sp_distance::InherentDataProvider<IdtyIndex>, sc_client_api::blockchain::Error> ) -> sp_distance::InherentDataProvider<IdtyIndex>
where where
B: BlockT, B: BlockT,
C: ProvideUncles<B> + StorageProvider<B, Backend>, C: ProvideUncles<B> + StorageProvider<B, Backend>,
Backend: sc_client_api::Backend<B>, Backend: sc_client_api::Backend<B>,
IdtyIndex: Decode + Encode + PartialEq + TypeInfo, IdtyIndex: Decode + Encode + PartialEq + TypeInfo,
{ {
let &[owner_key] = owner_keys else { // Retrieve the period_index from storage.
log::error!("🧙 [distance oracle] Expected exactly one Babe owner key, found {}: oracle cannot work", owner_keys.len()); let period_index = client
return Ok(sp_distance::InherentDataProvider::<IdtyIndex>::new(None));
};
let owner_key = sp_runtime::AccountId32::new(owner_key.0);
let pool_index = client
.storage( .storage(
parent, parent,
&StorageKey( &StorageKey(
frame_support::storage::storage_prefix(b"Distance", b"CurrentPoolIndex").to_vec(), frame_support::storage::storage_prefix(b"Distance", b"CurrentPeriodIndex").to_vec(),
), ),
) )
.expect("CurrentIndex is Err") .ok()
.map_or(0, |raw| { .flatten()
u32::decode(&mut &raw.0[..]).expect("cannot decode CurrentIndex") .and_then(|raw| u32::decode(&mut &raw.0[..]).ok());
});
// Return early if the storage is inaccessible or the data is corrupted.
let period_index = match period_index {
Some(index) => index,
None => {
log::error!("🧙 [distance inherent] PeriodIndex decoding failed.");
return sp_distance::InherentDataProvider::<IdtyIndex>::new(None);
}
};
// Retrieve the published_results from storage.
let published_results = client let published_results = client
.storage( .storage(
parent, parent,
&StorageKey( &StorageKey(
frame_support::storage::storage_prefix( frame_support::storage::storage_prefix(
b"Distance", b"Distance",
match pool_index { match period_index % 3 {
0 => b"EvaluationPool0", 0 => b"EvaluationPool0",
1 => b"EvaluationPool1", 1 => b"EvaluationPool1",
2 => b"EvaluationPool2", 2 => b"EvaluationPool2",
...@@ -75,42 +103,84 @@ where ...@@ -75,42 +103,84 @@ where
) )
.to_vec(), .to_vec(),
), ),
)? )
.map_or_else(Default::default, |raw| { .ok()
pallet_distance::EvaluationPool::<AccountId32, IdtyIndex>::decode(&mut &raw.0[..]) .flatten()
.expect("cannot decode EvaluationPool") .and_then(|raw| {
pallet_distance::EvaluationPool::<AccountId32, IdtyIndex>::decode(&mut &raw.0[..]).ok()
}); });
// Return early if the storage is inaccessible or the data is corrupted.
let published_results = match published_results {
Some(published_results) => published_results,
None => {
log::info!("🧙 [distance inherent] No published result at this block.");
return sp_distance::InherentDataProvider::<IdtyIndex>::new(None);
}
};
// Find the account associated with the BABE key that is in our owner keys.
let mut local_account = None;
for key in owner_keys {
// Session::KeyOwner is StorageMap<_, Twox64Concat, (KeyTypeId, Vec<u8>), AccountId32, OptionQuery>
// Slices (variable length) and array (fixed length) are encoded differently, so the `.as_slice()` is needed
let item_key = (sp_runtime::KeyTypeId(*b"babe"), key.0.as_slice()).encode();
let mut storage_key =
frame_support::storage::storage_prefix(b"Session", b"KeyOwner").to_vec();
storage_key.extend_from_slice(&sp_core::twox_64(&item_key));
storage_key.extend_from_slice(&item_key);
if let Some(raw_data) = client
.storage(parent, &StorageKey(storage_key))
.ok()
.flatten()
{
if let Ok(key_owner) = AccountId32::decode(&mut &raw_data.0[..]) {
local_account = Some(key_owner);
break;
} else {
log::warn!("🧙 [distance inherent] Cannot decode key owner value");
}
}
}
// Have we already published a result for this period? // Have we already published a result for this period?
if published_results.evaluators.contains(&owner_key) { if let Some(local_account) = local_account {
log::debug!("🧙 [distance oracle] Already published a result for this period"); if published_results.evaluators.contains(&local_account) {
return Ok(sp_distance::InherentDataProvider::<IdtyIndex>::new(None)); log::debug!("🧙 [distance inherent] Already published a result for this period");
return sp_distance::InherentDataProvider::<IdtyIndex>::new(None);
}
} else {
log::error!("🧙 [distance inherent] Cannot find our BABE owner key");
return sp_distance::InherentDataProvider::<IdtyIndex>::new(None);
} }
// Read evaluation result from file, if it exists // Read evaluation result from file, if it exists
log::debug!( log::debug!(
"🧙 [distance oracle] Reading evaluation result from file {:?}", "🧙 [distance inherent] Reading evaluation result from file {:?}",
distance_dir.clone().join(pool_index.to_string()) distance_dir.clone().join(period_index.to_string())
); );
let evaluation_result = match std::fs::read(distance_dir.join(pool_index.to_string())) { let evaluation_result = match std::fs::read(
distance_dir.join(VERSION_PREFIX.to_owned() + &period_index.to_string()),
) {
Ok(data) => data, Ok(data) => data,
Err(e) => { Err(e) => {
match e.kind() { match e.kind() {
std::io::ErrorKind::NotFound => { std::io::ErrorKind::NotFound => {
log::debug!("🧙 [distance oracle] Evaluation result file not found"); log::debug!("🧙 [distance inherent] Evaluation result file not found. Please ensure that the oracle version matches {}", VERSION_PREFIX);
} }
_ => { _ => {
log::error!( log::error!(
"🧙 [distance oracle] Cannot read distance evaluation result file: {e:?}" "🧙 [distance inherent] Cannot read distance evaluation result file: {e:?}"
); );
} }
} }
return Ok(sp_distance::InherentDataProvider::<IdtyIndex>::new(None)); return sp_distance::InherentDataProvider::<IdtyIndex>::new(None);
} }
}; };
log::info!("🧙 [distance oracle] Providing evaluation result"); log::info!("🧙 [distance inherent] Providing evaluation result");
Ok(sp_distance::InherentDataProvider::<IdtyIndex>::new(Some( sp_distance::InherentDataProvider::<IdtyIndex>::new(Some(
sp_distance::ComputationResult::decode(&mut evaluation_result.as_slice()).unwrap(), sp_distance::ComputationResult::decode(&mut evaluation_result.as_slice()).unwrap(),
))) ))
} }
...@@ -12,27 +12,23 @@ required-features = ["standalone"] ...@@ -12,27 +12,23 @@ required-features = ["standalone"]
[features] [features]
default = ["standalone", "std"] default = ["standalone", "std"]
# Feature standalone is for CLI executable
standalone = ["clap", "tokio"] standalone = ["clap", "tokio"]
# Feature std is needed
std = [ std = [
"codec/std", "codec/std",
"fnv/std", "fnv/std",
"hex/std",
"log/std",
"num-traits/std",
"sp-core/std", "sp-core/std",
"sp-distance/std", "sp-distance/std",
"sp-runtime/std", "sp-runtime/std",
] ]
try-runtime = ["sp-distance/try-runtime", "sp-runtime/try-runtime"] try-runtime = ["sp-distance/try-runtime", "sp-runtime/try-runtime"]
runtime-benchmarks = []
[dependencies] [dependencies]
clap = { workspace = true, features = ["derive"], optional = true } clap = { workspace = true, features = ["derive"], optional = true }
codec = { workspace = true } codec = { workspace = true }
fnv = { workspace = true } fnv = { workspace = true }
hex = { workspace = true }
log = { workspace = true } log = { workspace = true }
num-traits = { workspace = true }
rayon = { workspace = true } rayon = { workspace = true }
simple_logger = { workspace = true } simple_logger = { workspace = true }
sp-core = { workspace = true } sp-core = { workspace = true }
......
# Distance oracle # Distance Oracle
> for explanation about the Duniter web of trust, see https://duniter.org/wiki/web-of-trust/deep-dive-wot/ You can find the autogenerated documentation at: [https://doc-duniter-org.ipns.pagu.re/distance_oracle/index.html](https://doc-duniter-org.ipns.pagu.re/distance_oracle/index.html).
Distance computation on the Duniter web of trust is an expensive operation that should not be included in the runtime for multiple reasons:
- it could exceed the time available for a block computation
- it takes a lot of resource from the host machine
- the result is not critical to the operation of Ğ1
It is then separated into an other program that the user (a duniter smith) can choose to run or not. This program publishes its result in a inherent and the network selects the median of the results given by the smith who published some.
## Structure
This feature is organized in multiple parts:
- **/distance-oracle/** (here): binary executing the distance algorithm
- **/primitives/distance/**: primitive types used both by client and runtime
- **/client/distance/**: exposes the `create_distance_inherent_data_provider` which provides data to the runtime
- **/pallets/distance/**: distance pallet exposing type, traits, storage/calls/hooks executing in the runtime
## Usage (with Docker)
See [docker-compose.yml](../docker-compose.yml) for an example of how to run the distance oracle with Docker.
Output:
2023-12-09T14:45:05.942Z INFO [distance_oracle] Nothing to do: Pool does not exist
Waiting 1800 seconds before next execution...
\ No newline at end of file
...@@ -19,13 +19,14 @@ ...@@ -19,13 +19,14 @@
use crate::runtime; use crate::runtime;
use log::debug; use log::debug;
use sp_core::H256;
pub type Client = subxt::OnlineClient<crate::RuntimeConfig>; pub type Client = subxt::OnlineClient<crate::RuntimeConfig>;
pub type AccountId = subxt::utils::AccountId32; pub type AccountId = subxt::utils::AccountId32;
pub type IdtyIndex = u32; pub type IdtyIndex = u32;
pub type EvaluationPool =
runtime::runtime_types::pallet_distance::types::EvaluationPool<AccountId, IdtyIndex>;
pub type H256 = subxt::utils::H256;
pub async fn client(rpc_url: String) -> Client { pub async fn client(rpc_url: impl AsRef<str>) -> Client {
Client::from_insecure_url(rpc_url) Client::from_insecure_url(rpc_url)
.await .await
.expect("Cannot create RPC client") .expect("Cannot create RPC client")
...@@ -40,11 +41,11 @@ pub async fn parent_hash(client: &Client) -> H256 { ...@@ -40,11 +41,11 @@ pub async fn parent_hash(client: &Client) -> H256 {
.hash() .hash()
} }
pub async fn current_pool_index(client: &Client, parent_hash: H256) -> u32 { pub async fn current_period_index(client: &Client, parent_hash: H256) -> u32 {
client client
.storage() .storage()
.at(parent_hash) .at(parent_hash)
.fetch(&runtime::storage().distance().current_pool_index()) .fetch(&runtime::storage().distance().current_period_index())
.await .await
.expect("Cannot fetch current pool index") .expect("Cannot fetch current pool index")
.unwrap_or_default() .unwrap_or_default()
...@@ -54,7 +55,7 @@ pub async fn current_pool( ...@@ -54,7 +55,7 @@ pub async fn current_pool(
client: &Client, client: &Client,
parent_hash: H256, parent_hash: H256,
current_pool_index: u32, current_pool_index: u32,
) -> Option<runtime::runtime_types::pallet_distance::types::EvaluationPool<AccountId, IdtyIndex>> { ) -> Option<EvaluationPool> {
client client
.storage() .storage()
.at(parent_hash) .at(parent_hash)
...@@ -106,17 +107,26 @@ pub async fn member_iter(client: &Client, evaluation_block: H256) -> MemberIter ...@@ -106,17 +107,26 @@ pub async fn member_iter(client: &Client, evaluation_block: H256) -> MemberIter
} }
pub struct MemberIter( pub struct MemberIter(
subxt::backend::StreamOfResults<( subxt::backend::StreamOfResults<
Vec<u8>, subxt::storage::StorageKeyValuePair<
runtime::runtime_types::sp_membership::MembershipData<u32>, subxt::storage::StaticAddress<
)>, (),
runtime::runtime_types::sp_membership::MembershipData<u32>,
(),
(),
subxt::utils::Yes,
>,
>,
>,
); );
impl MemberIter { impl MemberIter {
pub async fn next(&mut self) -> Result<Option<IdtyIndex>, subxt::error::Error> { pub async fn next(&mut self) -> Result<Option<IdtyIndex>, subxt::error::Error> {
self.0.next().await.transpose().map(|i| { self.0
i.map(|(storage_key, _membership_data)| idty_id_from_storage_key(&storage_key)) .next()
}) .await
.transpose()
.map(|i| i.map(|j| idty_id_from_storage_key(&j.key_bytes)))
} }
} }
...@@ -131,15 +141,29 @@ pub async fn cert_iter(client: &Client, evaluation_block: H256) -> CertIter { ...@@ -131,15 +141,29 @@ pub async fn cert_iter(client: &Client, evaluation_block: H256) -> CertIter {
) )
} }
pub struct CertIter(subxt::backend::StreamOfResults<(Vec<u8>, Vec<(IdtyIndex, u32)>)>); pub struct CertIter(
subxt::backend::StreamOfResults<
subxt::storage::StorageKeyValuePair<
subxt::storage::StaticAddress<
(),
Vec<(u32, u32)>,
(),
subxt::utils::Yes,
subxt::utils::Yes,
>,
>,
>,
);
impl CertIter { impl CertIter {
pub async fn next( pub async fn next(
&mut self, &mut self,
) -> Result<Option<(IdtyIndex, Vec<(IdtyIndex, u32)>)>, subxt::error::Error> { ) -> Result<Option<(IdtyIndex, Vec<(IdtyIndex, u32)>)>, subxt::error::Error> {
self.0.next().await.transpose().map(|i| { self.0
i.map(|(storage_key, issuers)| (idty_id_from_storage_key(&storage_key), issuers)) .next()
}) .await
.transpose()
.map(|i| i.map(|j| (idty_id_from_storage_key(&j.key_bytes), j.value)))
} }
} }
......
...@@ -14,6 +14,38 @@ ...@@ -14,6 +14,38 @@
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
//! # Distance Oracle
//!
//! The **Distance Oracle** is a standalone program designed to calculate the distances between identities in the Duniter Web of Trust (WoT). This process is computationally intensive and is therefore decoupled from the main runtime. It allows smith users to choose whether to run the oracle and provide results to the network.
//!
//! The **oracle** works in conjunction with the **Inherent Data Provider** and the **Distance Pallet** in the runtime to deliver periodic computation results. The **Inherent Data Provider** fetches and supplies these results to the runtime, ensuring that the necessary data for distance evaluations is available to be processed at the appropriate time in the runtime lifecycle.
//!
//! ## Structure
//!
//! The Distance Oracle is organized into the following modules:
//!
//! 1. **`/distance-oracle/`**: Contains the main binary for executing the distance computation.
//! 2. **`/primitives/distance/`**: Defines primitive types shared between the client and runtime.
//! 3. **`/client/distance/`**: Exposes the `create_distance_inherent_data_provider`, which feeds data into the runtime through the Inherent Data Provider.
//! 4. **`/pallets/distance/`**: A pallet that handles distance-related types, traits, storage, and hooks in the runtime, coordinating the interaction between the oracle, inherent data provider, and runtime.
//!
//! ## How it works
//! - The **Distance Pallet** adds an evaluation request at period `i` in the runtime.
//! - The **Distance Oracle** evaluates this request at period `i + 1`, computes the necessary results and stores them on disk.
//! - The **Inherent Data Provider** reads this evaluation result from disk at period `i + 2` and provides it to the runtime to perform the required operations.
//!
//! ## Usage
//!
//! ### Docker Integration
//!
//! To run the Distance Oracle, use the provided Docker setup. Refer to the [docker-compose.yml](../docker-compose.yml) file for an example configuration.
//!
//! Example Output:
//! ```text
//! 2023-12-09T14:45:05.942Z INFO [distance_oracle] Nothing to do: Pool does not exist
//! Waiting 1800 seconds before next execution...
//! ```
#[cfg(not(test))] #[cfg(not(test))]
pub mod api; pub mod api;
#[cfg(test)] #[cfg(test)]
...@@ -24,17 +56,20 @@ mod tests; ...@@ -24,17 +56,20 @@ mod tests;
#[cfg(test)] #[cfg(test)]
pub use mock as api; pub use mock as api;
use api::{AccountId, IdtyIndex}; use api::{AccountId, EvaluationPool, IdtyIndex, H256};
use codec::Encode; use codec::Encode;
use fnv::{FnvHashMap, FnvHashSet}; use fnv::{FnvHashMap, FnvHashSet};
use log::{debug, error, info, warn}; use log::{debug, info, warn};
use rayon::iter::IntoParallelRefIterator; use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use rayon::iter::ParallelIterator; use std::{io::Write, path::PathBuf};
use std::io::Write;
use std::path::PathBuf; /// The file version must match the version used by the inherent data provider.
/// This ensures that the smith avoids accidentally submitting invalid data
/// in case there are changes in logic between the runtime and the oracle,
/// thereby preventing potential penalties.
const VERSION_PREFIX: &str = "001-";
// TODO select metadata file using features
#[subxt::subxt(runtime_metadata_path = "../resources/metadata.scale")] #[subxt::subxt(runtime_metadata_path = "../resources/metadata.scale")]
pub mod runtime {} pub mod runtime {}
...@@ -44,13 +79,14 @@ impl subxt::config::Config for RuntimeConfig { ...@@ -44,13 +79,14 @@ impl subxt::config::Config for RuntimeConfig {
type Address = subxt::ext::sp_runtime::MultiAddress<Self::AccountId, u32>; type Address = subxt::ext::sp_runtime::MultiAddress<Self::AccountId, u32>;
type AssetId = (); type AssetId = ();
type ExtrinsicParams = subxt::config::substrate::SubstrateExtrinsicParams<Self>; type ExtrinsicParams = subxt::config::substrate::SubstrateExtrinsicParams<Self>;
type Hash = sp_core::H256; type Hash = subxt::utils::H256;
type Hasher = subxt::config::substrate::BlakeTwo256; type Hasher = subxt::config::substrate::BlakeTwo256;
type Header = type Header =
subxt::config::substrate::SubstrateHeader<u32, subxt::config::substrate::BlakeTwo256>; subxt::config::substrate::SubstrateHeader<u32, subxt::config::substrate::BlakeTwo256>;
type Signature = subxt::ext::sp_runtime::MultiSignature; type Signature = subxt::ext::sp_runtime::MultiSignature;
} }
/// Represents a tipping amount.
#[derive(Copy, Clone, Debug, Default, Encode)] #[derive(Copy, Clone, Debug, Default, Encode)]
pub struct Tip { pub struct Tip {
#[codec(compact)] #[codec(compact)]
...@@ -69,6 +105,7 @@ impl From<u64> for Tip { ...@@ -69,6 +105,7 @@ impl From<u64> for Tip {
} }
} }
/// Represents configuration parameters.
pub struct Settings { pub struct Settings {
pub evaluation_result_dir: PathBuf, pub evaluation_result_dir: PathBuf,
pub rpc_url: String, pub rpc_url: String,
...@@ -83,9 +120,18 @@ impl Default for Settings { ...@@ -83,9 +120,18 @@ impl Default for Settings {
} }
} }
pub async fn run_and_save(client: &api::Client, settings: Settings) { /// Runs the evaluation process, saves the results, and cleans up old files.
let Some((evaluation, current_pool_index, evaluation_result_path)) = ///
run(client, &settings, true).await /// This function performs the following steps:
/// 1. Runs the evaluation task by invoking `compute_distance_evaluation`, which provides:
/// - The evaluation results.
/// - The current period index.
/// - The file path where the results should be stored.
/// 2. Saves the evaluation results to a file in the specified directory.
/// 3. Cleans up outdated evaluation files.
pub async fn run(client: &api::Client, settings: &Settings) {
let Some((evaluation, current_period_index, evaluation_result_path)) =
compute_distance_evaluation(client, settings).await
else { else {
return; return;
}; };
...@@ -113,82 +159,52 @@ pub async fn run_and_save(client: &api::Client, settings: Settings) { ...@@ -113,82 +159,52 @@ pub async fn run_and_save(client: &api::Client, settings: Settings) {
) )
}); });
// Remove old results // When a new result is written, remove old results except for the current period used by the inherent logic and the next period that was just generated.
let mut files_to_remove = Vec::new(); settings
for entry in settings
.evaluation_result_dir .evaluation_result_dir
.read_dir() .read_dir()
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
panic!( panic!(
"Cannot read distance evaluation result directory `{0:?}`: {e:?}", "Cannot read distance evaluation result directory `{:?}`: {:?}",
settings.evaluation_result_dir settings.evaluation_result_dir, e
) )
}) })
.flatten() .flatten()
{ .filter_map(|entry| {
if let Ok(entry_name) = entry.file_name().into_string() { entry
if let Ok(entry_pool) = entry_name.parse::<isize>() { .file_name()
if current_pool_index as isize - entry_pool > 3 { .to_str()
files_to_remove.push(entry.path()); .and_then(|name| {
} name.split('-').last()?.parse::<u32>().ok().filter(|&pool| {
} pool != current_period_index && pool != current_period_index + 1
} })
} })
files_to_remove.into_iter().for_each(|f| { .map(|_| entry.path())
std::fs::remove_file(&f) })
.unwrap_or_else(move |e| warn!("Cannot remove old result file `{f:?}`: {e:?}")); .for_each(|path| {
}); std::fs::remove_file(&path)
.unwrap_or_else(|e| warn!("Cannot remove file `{:?}`: {:?}", path, e));
});
} }
/// Returns `Option<(evaluation, current_pool_index, evaluation_result_path)>` /// Evaluates distance for the current period and prepares results for storage.
pub async fn run( ///
/// This function performs the following steps:
/// 1. Prepares the evaluation context using `prepare_evaluation_context`. If the context is not
/// ready (e.g., no pending evaluations, or results already exist), it returns `None`.
/// 2. Evaluates distances for all identities in the evaluation pool.
/// 3. Returns the evaluation results, the current period index, and the path to store the results.
///
pub async fn compute_distance_evaluation(
client: &api::Client, client: &api::Client,
settings: &Settings, settings: &Settings,
handle_fs: bool,
) -> Option<(Vec<sp_runtime::Perbill>, u32, PathBuf)> { ) -> Option<(Vec<sp_runtime::Perbill>, u32, PathBuf)> {
let parent_hash = api::parent_hash(client).await; let (evaluation_block, current_period_index, evaluation_pool, evaluation_result_path) =
prepare_evaluation_context(client, settings).await?;
let max_depth = api::max_referee_distance(client).await;
let current_pool_index = api::current_pool_index(client, parent_hash).await; info!("Evaluating distance for period {}", current_period_index);
// Fetch the pending identities
let Some(evaluation_pool) = api::current_pool(client, parent_hash, current_pool_index).await
else {
info!("Nothing to do: Pool does not exist");
return None;
};
// Stop if nothing to evaluate
if evaluation_pool.evaluations.0.is_empty() {
info!("Nothing to do: Pool is empty");
return None;
}
let evaluation_result_path = settings
.evaluation_result_dir
.join((current_pool_index + 1).to_string());
if handle_fs {
// Stop if already evaluated
if evaluation_result_path
.try_exists()
.expect("Result path unavailable")
{
info!("Nothing to do: File already exists");
return None;
}
std::fs::create_dir_all(&settings.evaluation_result_dir).unwrap_or_else(|e| {
error!(
"Cannot create distance evaluation result directory `{0:?}`: {e:?}",
settings.evaluation_result_dir
);
});
}
info!("Evaluating distance for pool {}", current_pool_index); let max_depth = api::max_referee_distance(client).await;
let evaluation_block = api::evaluation_block(client, parent_hash).await;
// member idty -> issued certs // member idty -> issued certs
let mut members = FnvHashMap::<IdtyIndex, u32>::default(); let mut members = FnvHashMap::<IdtyIndex, u32>::default();
...@@ -243,9 +259,75 @@ pub async fn run( ...@@ -243,9 +259,75 @@ pub async fn run(
.map(|(idty, _)| distance_rule(&received_certs, &referees, max_depth, *idty)) .map(|(idty, _)| distance_rule(&received_certs, &referees, max_depth, *idty))
.collect(); .collect();
Some((evaluation, current_pool_index, evaluation_result_path)) Some((evaluation, current_period_index, evaluation_result_path))
}
/// Prepares the context for the next evaluation task.
///
/// This function performs the following steps:
/// 1. Fetches the parent hash of the latest block from the API.
/// 2. Determines the current period index.
/// 3. Retrieves the evaluation pool for the current period.
/// - If the pool does not exist or is empty, it returns `None`.
/// 4. Checks if the evaluation result file for the next period already exists.
/// - If it exists, the task has already been completed, so the function returns `None`.
/// 5. Ensures the evaluation result directory is available, creating it if necessary.
/// 6. Retrieves the block number of the evaluation.
///
async fn prepare_evaluation_context(
client: &api::Client,
settings: &Settings,
) -> Option<(H256, u32, EvaluationPool, PathBuf)> {
let parent_hash = api::parent_hash(client).await;
let current_period_index = api::current_period_index(client, parent_hash).await;
// Fetch the pending identities
let Some(evaluation_pool) =
api::current_pool(client, parent_hash, current_period_index % 3).await
else {
info!("Nothing to do: Pool does not exist");
return None;
};
// Stop if nothing to evaluate
if evaluation_pool.evaluations.0.is_empty() {
info!("Nothing to do: Pool is empty");
return None;
}
// The result is saved in a file named `current_period_index + 1`.
// It will be picked up during the next period by the inherent.
let evaluation_result_path = settings
.evaluation_result_dir
.join(VERSION_PREFIX.to_owned() + &(current_period_index + 1).to_string());
// Stop if already evaluated
if evaluation_result_path
.try_exists()
.expect("Result path unavailable")
{
info!("Nothing to do: File already exists");
return None;
}
#[cfg(not(test))]
std::fs::create_dir_all(&settings.evaluation_result_dir).unwrap_or_else(|e| {
panic!(
"Cannot create distance evaluation result directory `{0:?}`: {e:?}",
settings.evaluation_result_dir
);
});
Some((
api::evaluation_block(client, parent_hash).await,
current_period_index,
evaluation_pool,
evaluation_result_path,
))
} }
/// Recursively explores the certification graph to identify referees accessible within a given depth.
fn distance_rule_recursive( fn distance_rule_recursive(
received_certs: &FnvHashMap<IdtyIndex, Vec<IdtyIndex>>, received_certs: &FnvHashMap<IdtyIndex, Vec<IdtyIndex>>,
referees: &FnvHashMap<IdtyIndex, u32>, referees: &FnvHashMap<IdtyIndex, u32>,
...@@ -291,7 +373,7 @@ fn distance_rule_recursive( ...@@ -291,7 +373,7 @@ fn distance_rule_recursive(
} }
} }
/// Returns the fraction `nb_accessible_referees / nb_referees` /// Calculates the fraction of accessible referees to total referees for a given identity.
fn distance_rule( fn distance_rule(
received_certs: &FnvHashMap<IdtyIndex, Vec<IdtyIndex>>, received_certs: &FnvHashMap<IdtyIndex, Vec<IdtyIndex>>,
referees: &FnvHashMap<IdtyIndex, u32>, referees: &FnvHashMap<IdtyIndex, u32>,
......
// Copyright 2023 Axiom-Team // Copyright 2023-2024 Axiom-Team
// //
// This file is part of Duniter-v2S. // This file is part of Duniter-v2S.
// //
...@@ -20,6 +20,10 @@ use clap::Parser; ...@@ -20,6 +20,10 @@ use clap::Parser;
struct Cli { struct Cli {
#[clap(short = 'd', long, default_value = "/tmp/duniter/chains/gdev/distance")] #[clap(short = 'd', long, default_value = "/tmp/duniter/chains/gdev/distance")]
evaluation_result_dir: String, evaluation_result_dir: String,
/// Number of seconds between two evaluations (oneshot if absent)
#[clap(short = 'i', long)]
interval: Option<u64>,
/// Node used for fetching state
#[clap(short = 'u', long, default_value = "ws://127.0.0.1:9944")] #[clap(short = 'u', long, default_value = "ws://127.0.0.1:9944")]
rpc_url: String, rpc_url: String,
/// Log level (off, error, warn, info, debug, trace) /// Log level (off, error, warn, info, debug, trace)
...@@ -36,12 +40,21 @@ async fn main() { ...@@ -36,12 +40,21 @@ async fn main() {
.init() .init()
.unwrap(); .unwrap();
distance_oracle::run_and_save( let client = distance_oracle::api::client(&cli.rpc_url).await;
&distance_oracle::api::client(cli.rpc_url.clone()).await,
distance_oracle::Settings { let settings = distance_oracle::Settings {
evaluation_result_dir: cli.evaluation_result_dir.into(), evaluation_result_dir: cli.evaluation_result_dir.into(),
rpc_url: cli.rpc_url, rpc_url: cli.rpc_url,
}, };
)
.await; if let Some(duration) = cli.interval {
let mut interval = tokio::time::interval(std::time::Duration::from_secs(duration));
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
loop {
distance_oracle::run(&client, &settings).await;
interval.tick().await;
}
} else {
distance_oracle::run(&client, &settings).await;
}
} }
...@@ -19,7 +19,6 @@ use crate::runtime::runtime_types::{ ...@@ -19,7 +19,6 @@ use crate::runtime::runtime_types::{
}; };
use dubp_wot::{data::rusty::RustyWebOfTrust, WebOfTrust, WotId}; use dubp_wot::{data::rusty::RustyWebOfTrust, WebOfTrust, WotId};
use sp_core::H256;
use std::collections::BTreeSet; use std::collections::BTreeSet;
pub struct Client { pub struct Client {
...@@ -28,13 +27,14 @@ pub struct Client { ...@@ -28,13 +27,14 @@ pub struct Client {
} }
pub type AccountId = subxt::ext::sp_runtime::AccountId32; pub type AccountId = subxt::ext::sp_runtime::AccountId32;
pub type IdtyIndex = u32; pub type IdtyIndex = u32;
pub type H256 = subxt::utils::H256;
pub struct EvaluationPool<AccountId: Ord, IdtyIndex> { pub struct EvaluationPool {
pub evaluations: (Vec<(IdtyIndex, MedianAcc<Perbill>)>,), pub evaluations: (Vec<(IdtyIndex, MedianAcc<Perbill>)>,),
pub evaluators: BTreeSet<AccountId>, pub evaluators: BTreeSet<AccountId>,
} }
pub async fn client(_rpc_url: String) -> Client { pub async fn client(_rpc_url: impl AsRef<str>) -> Client {
unimplemented!() unimplemented!()
} }
...@@ -46,7 +46,7 @@ pub async fn parent_hash(_client: &Client) -> H256 { ...@@ -46,7 +46,7 @@ pub async fn parent_hash(_client: &Client) -> H256 {
Default::default() Default::default()
} }
pub async fn current_pool_index(_client: &Client, _parent_hash: H256) -> u32 { pub async fn current_period_index(_client: &Client, _parent_hash: H256) -> u32 {
0 0
} }
...@@ -54,7 +54,7 @@ pub async fn current_pool( ...@@ -54,7 +54,7 @@ pub async fn current_pool(
client: &Client, client: &Client,
_parent_hash: H256, _parent_hash: H256,
_current_session: u32, _current_session: u32,
) -> Option<EvaluationPool<AccountId, IdtyIndex>> { ) -> Option<EvaluationPool> {
Some(EvaluationPool { Some(EvaluationPool {
evaluations: (client evaluations: (client
.wot .wot
...@@ -64,7 +64,10 @@ pub async fn current_pool( ...@@ -64,7 +64,10 @@ pub async fn current_pool(
.zip(0..client.pool_len) .zip(0..client.pool_len)
.map(|(wot_id, _)| { .map(|(wot_id, _)| {
(wot_id.0 as IdtyIndex, unsafe { (wot_id.0 as IdtyIndex, unsafe {
std::mem::transmute((Vec::<()>::new(), Option::<u32>::None, 0)) std::mem::transmute::<
(std::vec::Vec<()>, std::option::Option<u32>, i32),
MedianAcc<Perbill>,
>((Vec::<()>::new(), Option::<u32>::None, 0))
}) })
}) })
.collect(),), .collect(),),
......
...@@ -58,7 +58,7 @@ async fn test_distance_against_v1() { ...@@ -58,7 +58,7 @@ async fn test_distance_against_v1() {
client.pool_len = n; client.pool_len = n;
let t_a = std::time::Instant::now(); let t_a = std::time::Instant::now();
let results = crate::run(&client, &Default::default(), false) let results = crate::compute_distance_evaluation(&client, &Default::default())
.await .await
.unwrap(); .unwrap();
println!("new time: {}", t_a.elapsed().as_millis()); println!("new time: {}", t_a.elapsed().as_millis());
......
# This is a minimal docker-compose.yml template for running a Duniter instance # This is a minimal docker-compose.yml template for running a Duniter mirror node
# For more detailed examples, look at docker/compose folder # For more detailed examples, look at docker/compose folder
version: "3.5"
services: services:
duniter-v2s: duniter-v2s-mirror:
container_name: duniter-v2s container_name: duniter-v2s-mirror
# choose the version of the image here # the image tells which network you are connecting to
image: duniter/duniter-v2s:latest # here it is gdev network
image: duniter/duniter-v2s-gdev-800:latest
ports: ports:
# telemetry # prometheus telemetry to monitor resource use
- 9615:9615 - 9615:9615
# rpc # RPC API (ws and http)
- 9933:9933
# rpc-ws
- 9944:9944 - 9944:9944
# p2p # public p2p endpoint
- 30333:30333 - 30333:30333
environment: environment:
DUNITER_NODE_NAME: "duniter_local" # read https://duniter.org/wiki/duniter-v2/configure-docker/
DUNITER_CHAIN_NAME: "gdev" # to configure these
volumes: DUNITER_NODE_NAME: duniter_local
- duniter-local-data:/var/lib/duniter DUNITER_CHAIN_NAME: gdev
distance-oracle: DUNITER_PUBLIC_ADDR: /dns/your.domain.name/tcp/30333
container_name: distance-oracle DUNITER_LISTEN_ADDR: /ip4/0.0.0.0/tcp/30333
# choose the version of the image here
image: duniter/duniter-v2s:latest
entrypoint: docker-distance-entrypoint
environment:
ORACLE_RPC_URL: "ws://duniter-v2s:9944"
ORACLE_RESULT_DIR: "/var/lib/duniter/chains/gdev/distance/"
ORACLE_EXECUTION_INTERVAL: "1800"
ORACLE_MAX_DEPTH: "5"
ORACLE_LOG_LEVEL: "info"
volumes: volumes:
- duniter-local-data:/var/lib/duniter - duniter-local-data:/var/lib/duniter
......
# Workaround for https://github.com/containers/buildah/issues/4742 # Workaround for https://github.com/containers/buildah/issues/4742
FROM debian:bullseye-slim as target FROM debian:bullseye-slim AS target
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Build Stage # Build Stage
...@@ -7,14 +7,19 @@ FROM debian:bullseye-slim as target ...@@ -7,14 +7,19 @@ FROM debian:bullseye-slim as target
# When building for a foreign arch, use cross-compilation # When building for a foreign arch, use cross-compilation
# https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/ # https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/
FROM --platform=$BUILDPLATFORM rust:1-bullseye as build FROM --platform=$BUILDPLATFORM rust:1-bullseye AS build
ARG BUILDPLATFORM ARG BUILDPLATFORM
ARG TARGETPLATFORM ARG TARGETPLATFORM
# Debug
RUN echo "BUILDPLATFORM = $BUILDPLATFORM"
RUN echo "TARGETPLATFORM = $TARGETPLATFORM"
# We need the target arch triplet in both Debian and rust flavor # We need the target arch triplet in both Debian and rust flavor
RUN echo "DEBIAN_ARCH_TRIPLET='$(dpkg-architecture -A${TARGETPLATFORM#linux/} -qDEB_TARGET_MULTIARCH)'" >>/root/dynenv RUN echo "DEBIAN_ARCH_TRIPLET='$(dpkg-architecture -A${TARGETPLATFORM#linux/} -qDEB_TARGET_MULTIARCH)'" >>/root/dynenv
RUN . /root/dynenv && \ RUN . /root/dynenv && \
echo "RUST_ARCH_TRIPLET='$(echo "$DEBIAN_ARCH_TRIPLET" | sed -E 's/-linux-/-unknown&/')'" >>/root/dynenv echo "RUST_ARCH_TRIPLET='$(echo "$DEBIAN_ARCH_TRIPLET" | sed -E 's/-linux-/-unknown&/')'" >>/root/dynenv
RUN cat /root/dynenv
WORKDIR /root WORKDIR /root
...@@ -48,8 +53,8 @@ ARG chain="gdev" ...@@ -48,8 +53,8 @@ ARG chain="gdev"
RUN set -x && \ RUN set -x && \
cat /root/dynenv && \ cat /root/dynenv && \
. /root/dynenv && \ . /root/dynenv && \
cargo build --locked $CARGO_OPTIONS --no-default-features $BENCH_OPTIONS --features $chain --target "$RUST_ARCH_TRIPLET" && \ cargo build -Zgit=shallow-deps --locked $CARGO_OPTIONS --no-default-features $BENCH_OPTIONS --features $chain --target "$RUST_ARCH_TRIPLET" && \
cargo build --locked $CARGO_OPTIONS --target "$RUST_ARCH_TRIPLET" --package distance-oracle && \ cargo build -Zgit=shallow-deps --locked $CARGO_OPTIONS --target "$RUST_ARCH_TRIPLET" --package distance-oracle && \
mkdir -p build && \ mkdir -p build && \
mv target/$RUST_ARCH_TRIPLET/$TARGET_FOLDER/duniter build/ && \ mv target/$RUST_ARCH_TRIPLET/$TARGET_FOLDER/duniter build/ && \
mv target/$RUST_ARCH_TRIPLET/$TARGET_FOLDER/distance-oracle build/ mv target/$RUST_ARCH_TRIPLET/$TARGET_FOLDER/distance-oracle build/
...@@ -58,7 +63,7 @@ RUN set -x && \ ...@@ -58,7 +63,7 @@ RUN set -x && \
ARG cucumber=0 ARG cucumber=0
RUN if [ "$cucumber" != 0 ] && [ "$TARGETPLATFORM" = "$BUILDPLATFORM" ]; then \ RUN if [ "$cucumber" != 0 ] && [ "$TARGETPLATFORM" = "$BUILDPLATFORM" ]; then \
cargo ta && \ cargo ta && \
cargo test --workspace --exclude duniter-end2end-tests --exclude duniter-live-tests --features=runtime-benchmarks,constant-fees \ cargo test -Zgit=shallow-deps --workspace --exclude duniter-end2end-tests --exclude duniter-live-tests --features=runtime-benchmarks,constant-fees \
cd target/debug/deps/ && \ cd target/debug/deps/ && \
rm cucumber_tests-*.d && \ rm cucumber_tests-*.d && \
mv cucumber_tests* ../../../build/duniter-cucumber; \ mv cucumber_tests* ../../../build/duniter-cucumber; \
...@@ -83,13 +88,17 @@ RUN apt-get clean && rm -rf /var/lib/apt/lists/* ...@@ -83,13 +88,17 @@ RUN apt-get clean && rm -rf /var/lib/apt/lists/*
RUN adduser --home /var/lib/duniter duniter RUN adduser --home /var/lib/duniter duniter
# Configuration # Configuration
# rpc, rpc-ws, p2p, telemetry # rpc, p2p, telemetry
EXPOSE 9933 9944 30333 9615 EXPOSE 9944 30333 9615
VOLUME /var/lib/duniter VOLUME /var/lib/duniter
ENTRYPOINT ["docker-entrypoint"] ENTRYPOINT ["docker-entrypoint"]
USER duniter USER duniter
# Intall # Intall
COPY --from=build /root/build /usr/local/bin/ COPY --from=build /root/build /usr/local/bin/
COPY --from=build /root/dynenv /var/lib/duniter
COPY docker/docker-entrypoint /usr/local/bin/ COPY docker/docker-entrypoint /usr/local/bin/
COPY docker/docker-distance-entrypoint /usr/local/bin/ COPY docker/docker-distance-entrypoint /usr/local/bin/
# Debug
RUN cat /var/lib/duniter/dynenv
...@@ -16,9 +16,7 @@ services: ...@@ -16,9 +16,7 @@ services:
ports: ports:
# Prometheus endpoint # Prometheus endpoint
- 9615:9615 - 9615:9615
# rpc via http # rpc
- 9933:9933
# rpc via websocket
- 9944:9944 - 9944:9944
# p2p # p2p
- 30333:30333 - 30333:30333
...@@ -60,20 +58,24 @@ volumes: ...@@ -60,20 +58,24 @@ volumes:
## Environment variables ## Environment variables
| Name | Description | Default | | Name | Description | Default |
|------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------| | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `DUNITER_NODE_NAME` | The node name. This name will appear on the Substrate telemetry server when telemetry is enabled. | Random name | | `DUNITER_NODE_NAME` | The node name. This name will appear on the Substrate telemetry server when telemetry is enabled. | Random name |
| `DUNITER_CHAIN_NAME` | The currency to process. "gdev" uses the embeded chainspec. A path allows to use a local json raw chainspec. | `dev` (development mode) | | `DUNITER_CHAIN_NAME` | The currency to process. "gdev" uses the embeded chainspec. A path allows to use a local json raw chainspec. | `dev` (development mode) |
| `DUNITER_PUBLIC_ADDR` | The libp2p public address base. See [libp2p documentation](https://docs.libp2p.io/concepts/fundamentals/addressing/). This variable is useful when the node is behind a reverse proxy with its ports not directly exposed.<br>Note: the `p2p/<peer_id>` part of the address shouldn't be set in this variable. It is automatically added by Duniter. | duniter-v2s guesses one from the node's IPv4 address. | | `DUNITER_PUBLIC_ADDR` | The libp2p public address base. See [libp2p documentation](https://docs.libp2p.io/concepts/fundamentals/addressing/). This variable is useful when the node is behind a reverse proxy with its ports not directly exposed.<br>Note: the `p2p/<peer_id>` part of the address shouldn't be set in this variable. It is automatically added by Duniter. | duniter-v2s guesses one from the node's IPv4 address. |
| `DUNITER_LISTEN_ADDR` | The libp2p listen address. See [libp2p documentation](https://docs.libp2p.io/concepts/fundamentals/addressing/). This variable is useful when running a validator node behind a reverse proxy, to force the P2P end point in websocket mode with:<br> `DUNITER_LISTEN_ADDR=/ip4/0.0.0.0/tcp/30333/ws` | Non validator node: `/ip4/0.0.0.0/tcp/30333/ws`<br>Validator node: `/ip4/0.0.0.0/tcp/30333` | | `DUNITER_LISTEN_ADDR` | The libp2p listen address. See [libp2p documentation](https://docs.libp2p.io/concepts/fundamentals/addressing/). This variable is useful when running a validator node behind a reverse proxy, to force the P2P end point in websocket mode with:<br> `DUNITER_LISTEN_ADDR=/ip4/0.0.0.0/tcp/30333/ws` | Non validator node: `/ip4/0.0.0.0/tcp/30333/ws`<br>Validator node: `/ip4/0.0.0.0/tcp/30333` |
| `DUNITER_RPC_CORS` | Value of the polkadot `--rpc-cors` option. | `all` | | `DUNITER_RPC_CORS` | Value of the polkadot `--rpc-cors` option. | `all` |
| `DUNITER_VALIDATOR` | Boolean (`true` / `false`) to run the node in validator mode. Configure the polkadot options `--validator --rpc-methods Unsafe`. | `false` | | `DUNITER_VALIDATOR` | Boolean (`true` / `false`) to run the node in validator mode. Configure the polkadot options `--validator --rpc-methods Unsafe`. | `false` |
| `DUNITER_DISABLE_PROMETHEUS` | Boolean to disable the Prometheus endpoint on port 9615. | `false` | | `DUNITER_DISABLE_PROMETHEUS` | Boolean to disable the Prometheus endpoint on port 9615. | `false` |
| `DUNITER_DISABLE_TELEMETRY` | Boolean to disable connecting to the Substrate telemetry server. | `false` | | `DUNITER_DISABLE_TELEMETRY` | Boolean to disable connecting to the Substrate telemetry server. | `false` |
| `DUNITER_PRUNING_PROFILE` | * `default`<br> * `archive`: keep all blocks and state blocks<br> * `light`: keep only last 256 state blocks and last 14400 blocks (one day duration) | `default` | | `DUNITER_PRUNING_PROFILE` | _ `default`<br> _ `archive`: keep all blocks and state blocks<br> \* `light`: keep only last 256 state blocks and last 14400 blocks (one day duration) | `default` |
| `DUNITER_PUBLIC_RPC` | The public RPC endpoint to gossip on the network and make available in the apps. | None |
| `DUNITER_PUBLIC_SQUID` | The public Squid graphql endpoint to gossip on the network and make available in the apps. | None |
| `DUNITER_PUBLIC_ENDPOINTS` | Path to a JSON file containing public endpoints to gossip on the network. The file should use the following format:<br>```{"endpoints": [ { "protocol": "rpc", "address": "wss://gdev.example.com" }, { "protocol": "squid", "address": "gdev.example.com/graphql/v1" }]}``` | None |
## Other Duniter options ## Other Duniter options
You can pass any other option to Duniter using the `command` docker-compose element: You can pass any other option to Duniter using the `command` docker-compose element:
``` ```
command: command:
# workaround for substrate issue #12073 # workaround for substrate issue #12073
...@@ -92,6 +94,7 @@ docker compose up -d ...@@ -92,6 +94,7 @@ docker compose up -d
## Running duniter subcommands or custom set of options ## Running duniter subcommands or custom set of options
To run duniter from the command line without the default configuration detailed in the "Environment variables" section use `--` as the first argument. For example: To run duniter from the command line without the default configuration detailed in the "Environment variables" section use `--` as the first argument. For example:
``` ```
$ docker run --rm duniter/duniter-v2s-gdev:latest -- key generate $ docker run --rm duniter/duniter-v2s-gdev:latest -- key generate
$ docker run --rm duniter/duniter-v2s-gdev:latest -- --chain gdev ... $ docker run --rm duniter/duniter-v2s-gdev:latest -- --chain gdev ...
......
FROM paritytech/ci-linux:production
# Set the working directory
WORKDIR /app/
# Copy the toolchain
COPY rust-toolchain.toml ./
# Install toolchain, substrate and cargo-deb with cargo cache
RUN --mount=type=cache,target=/root/.cargo \
cargo install cargo-deb
# Create a dummy project to cache dependencies
COPY Cargo.toml .
COPY rust-toolchain.toml ./
RUN --mount=type=cache,target=/app/target \
--mount=type=cache,target=/root/.cargo/registry \
mkdir src && \
sed -i '/git = \|version = /!d' Cargo.toml && \
sed -i 's/false/true/' Cargo.toml && \
sed -i '1s/^/\[package\]\nname\=\"Dummy\"\n\[dependencies\]\n/' Cargo.toml && \
echo "fn main() {}" > src/main.rs && \
cargo build -Zgit=shallow-deps --release && \
rm -rf src Cargo.lock Cargo.toml
# Copy the entire project
COPY . .
# Build the project and create Debian packages
RUN --mount=type=cache,target=/app/target \
--mount=type=cache,target=/root/.cargo/registry \
cargo build -Zgit=shallow-deps --release && \
cargo deb --no-build -p duniter && \
cp -r ./target/debian/ ./
# Clean up unnecessary files to reduce image size
RUN rm -rf /app/target/release /root/.cargo/registry