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
Select Git revision
Loading items

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
Select Git revision
Loading items
Show changes
Showing
with 8838 additions and 1634 deletions
// Copyright 2023 Axiom-Team
//
// This file is part of Duniter-v2S.
//
// Duniter-v2S is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// Duniter-v2S is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// 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/>.
use dubp_wot::{
data::rusty::RustyWebOfTrust, operations::distance::DistanceCalculator, WebOfTrust,
};
use flate2::read::ZlibDecoder;
use sp_runtime::Perbill;
use std::{fs::File, io::Read};
#[tokio::test]
#[ignore = "long to execute"]
async fn test_distance_against_v1() {
let wot = wot_from_v1_file();
let n = wot.size();
let min_certs_for_referee = (wot.get_enabled().len() as f32).powf(1. / 5.).ceil() as u32;
// Reference implementation
let ref_calculator = dubp_wot::operations::distance::RustyDistanceCalculator;
let t_a = std::time::Instant::now();
let ref_results: Vec<Perbill> = wot
.get_enabled()
.into_iter()
.chain(wot.get_disabled().into_iter())
.zip(0..n)
.map(|(i, _)| {
let result = ref_calculator
.compute_distance(
&wot,
dubp_wot::operations::distance::WotDistanceParameters {
node: i,
sentry_requirement: min_certs_for_referee,
step_max: 5,
x_percent: 0.8,
},
)
.unwrap();
Perbill::from_rational(result.success, result.sentries)
})
.collect();
println!("ref time: {}", t_a.elapsed().as_millis());
// Our implementation
let mut client = crate::api::client_from_wot(wot);
client.pool_len = n;
let t_a = std::time::Instant::now();
let results = crate::compute_distance_evaluation(&client, &Default::default())
.await
.unwrap();
println!("new time: {}", t_a.elapsed().as_millis());
assert_eq!(results.0.len(), n);
let mut errors: Vec<_> = results
.0
.iter()
.zip(ref_results.iter())
.map(|(r, r_ref)| r.deconstruct() as i64 - r_ref.deconstruct() as i64)
.collect();
errors.sort_unstable();
println!(
"Error: {:?} / {:?} / {:?} / {:?} / {:?} (min / 1Q / med / 3Q / max)",
errors[0],
errors[errors.len() / 4],
errors[errors.len() / 2],
errors[errors.len() * 3 / 4],
errors[errors.len() - 1]
);
let correct_results = results
.0
.iter()
.zip(ref_results.iter())
.map(|(r, r_ref)| (r == r_ref) as usize)
.sum::<usize>();
println!("Correct results: {correct_results} / {n}");
assert_eq!(correct_results, n);
}
fn wot_from_v1_file() -> RustyWebOfTrust {
let file = File::open("wot.deflate").expect("Cannot open wot.deflate");
let mut decompressor = ZlibDecoder::new(file);
let mut decompressed_bytes = Vec::new();
decompressor
.read_to_end(&mut decompressed_bytes)
.expect("Cannot decompress wot.deflate");
bincode::deserialize::<RustyWebOfTrust>(&decompressed_bytes).expect("Cannot decode wot.deflate")
}
File added
version: "3.5" # This is a minimal docker-compose.yml template for running a Duniter mirror node
# For more detailed examples, look at docker/compose folder
services: services:
duniter-v2s: duniter-v2s-mirror:
container_name: duniter-v2s container_name: duniter-v2s-mirror
image: duniter/duniter-v2s:v0.1.0 # the image tells which network you are connecting to
# 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_INSTANCE_NAME: "duniter_local" # read https://duniter.org/wiki/duniter-v2/configure-docker/
DUNITER_CHAIN_NAME: "dev" # to configure these
#DUNITER_DISABLE_PROMETHEUS: "false" DUNITER_NODE_NAME: duniter_local
DUNITER_CHAIN_NAME: gdev
DUNITER_PUBLIC_ADDR: /dns/your.domain.name/tcp/30333
DUNITER_LISTEN_ADDR: /ip4/0.0.0.0/tcp/30333
volumes: volumes:
- duniter-local-data:/var/lib/duniter - duniter-local-data:/var/lib/duniter
......
# Workaround for https://github.com/containers/buildah/issues/4742
FROM debian:bullseye-slim AS target
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Build Stage # Build Stage
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Building for Debian buster because we need the binary to be compatible # When building for a foreign arch, use cross-compilation
# with the image paritytech/ci-linux:production (currently based on # https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/
# debian:buster-slim) used by the gitlab CI FROM --platform=$BUILDPLATFORM rust:1-bullseye AS build
FROM rust:1-buster as build ARG BUILDPLATFORM
ARG TARGETPLATFORM
# Debug
RUN echo "BUILDPLATFORM = $BUILDPLATFORM"
RUN echo "TARGETPLATFORM = $TARGETPLATFORM"
# 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 . /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
# Copy source tree # Copy source tree
COPY . . COPY . .
RUN test -x build/duniter || \ RUN apt-get update && \
( \ DEBIAN_FRONTEND=noninteractive apt-get install -y clang cmake protobuf-compiler
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y clang \
)
# build duniter # build duniter
ARG threads=1 ARG debug=0
RUN test -x build/duniter || \ RUN if [ "$debug" = 0 ]; then \
( \ echo "CARGO_OPTIONS=--release" >>/root/dynenv && \
CARGO_PROFILE_RELEASE_LTO="true" \ echo "TARGET_FOLDER=release" >>/root/dynenv; \
cargo build --release -j $threads && \ else \
mkdir -p build && \ echo "TARGET_FOLDER=debug" >>/root/dynenv; \
mv target/release/duniter build/ \ fi
)
# Create fake duniter-cucumber if is not exist # Configure cross-build environment if need be
# The goal is to avoid error later, this binary is optional RUN set -x && \
RUN test -x build/duniter-cucumber || \ if [ "$TARGETPLATFORM" != "$BUILDPLATFORM" ]; then \
( \ . /root/dynenv && \
apt install -y gcc-$DEBIAN_ARCH_TRIPLET binutils-$DEBIAN_ARCH_TRIPLET && \
rustup target add "$RUST_ARCH_TRIPLET" && \
: https://github.com/rust-lang/cargo/issues/4133 && \
echo "RUSTFLAGS='-C linker=$DEBIAN_ARCH_TRIPLET-gcc'; export RUSTFLAGS" >>/root/dynenv; \
fi
# Build
ARG chain="gdev"
RUN set -x && \
cat /root/dynenv && \
. /root/dynenv && \
cargo build -Zgit=shallow-deps --locked $CARGO_OPTIONS --no-default-features $BENCH_OPTIONS --features $chain --target "$RUST_ARCH_TRIPLET" && \
cargo build -Zgit=shallow-deps --locked $CARGO_OPTIONS --target "$RUST_ARCH_TRIPLET" --package distance-oracle && \
mkdir -p build && \ mkdir -p build && \
touch build/duniter-cucumber \ mv target/$RUST_ARCH_TRIPLET/$TARGET_FOLDER/duniter build/ && \
) mv target/$RUST_ARCH_TRIPLET/$TARGET_FOLDER/distance-oracle build/
# Run tests if requested, except when cross-building
ARG cucumber=0
RUN if [ "$cucumber" != 0 ] && [ "$TARGETPLATFORM" = "$BUILDPLATFORM" ]; then \
cargo ta && \
cargo test -Zgit=shallow-deps --workspace --exclude duniter-end2end-tests --exclude duniter-live-tests --features=runtime-benchmarks,constant-fees \
cd target/debug/deps/ && \
rm cucumber_tests-*.d && \
mv cucumber_tests* ../../../build/duniter-cucumber; \
fi
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Final Stage # Final Stage
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
FROM debian:buster-slim FROM target
LABEL maintainer="Gilles Filippini <gilles.filippini@pini.fr>" LABEL maintainer="Gilles Filippini <gilles.filippini@pini.fr>"
LABEL version="0.0.0" LABEL version="0.0.0"
LABEL description="Crypto-currency software (based on Substrate framework) to operate Ğ1 libre currency" LABEL description="Crypto-currency software (based on Substrate framework) to operate Ğ1 libre currency"
# Required certificates for RPC connections
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates
RUN update-ca-certificates
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/duniter /usr/local/bin/duniter COPY --from=build /root/build /usr/local/bin/
COPY --from=build /root/build/duniter-cucumber /usr/local/bin/duniter-cucumber 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/
# Debug
RUN cat /var/lib/duniter/dynenv
# duniter/duniter-v2s
Duniter is the software that supports the [Ğ1 libre-currency blockchain](https://duniter.org/).
[Duniter v2s](https://git.duniter.org/nodes/rust/duniter-v2s) is a complete rewrite of Duniter based on the Substrate / Polkadot framework. **This is alpha state work in progress.**
## Minimal docker-compose file for an mirror node
```
version: "3.5"
services:
duniter-mirror:
image: duniter/duniter-v2s-gdev:latest
restart: unless-stopped
ports:
# Prometheus endpoint
- 9615:9615
# rpc
- 9944:9944
# p2p
- 30333:30333
volumes:
- data-mirror:/var/lib/duniter/
environment:
- DUNITER_CHAIN_NAME=gdev
- DUNITER_NODE_NAME=<my-node-name>
volumes:
data-mirror:
```
## Minimal docker-compose file for a validator node
```
version: "3.5"
services:
duniter-validator:
image: duniter/duniter-v2s-gdev:latest
restart: unless-stopped
ports:
# Prometheus endpoint
- 9615:9615
# p2p
- 30333:30333
volumes:
- data-validator:/var/lib/duniter/
environment:
- DUNITER_CHAIN_NAME=gdev
- DUNITER_VALIDATOR=true
- DUNITER_NODE_NAME=<my-validator-node-name>
volumes:
data-validator:
```
## Environment variables
| 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_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_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_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_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_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
You can pass any other option to Duniter using the `command` docker-compose element:
```
command:
# workaround for substrate issue #12073
# https://github.com/paritytech/substrate/issues/12073
- "--wasm-execution=interpreted-i-know-what-i-do"
```
## Start Duniter
Once you are happy with your `docker-compose.yml` file, run in the same folder:
```bash
docker compose up -d
```
## 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:
```
$ docker run --rm duniter/duniter-v2s-gdev:latest -- key generate
$ 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
# docker-compose.yml template for running a Duniter smith node
# for more doc, see https://duniter.org/wiki/duniter-v2/
services:
# duniter smith node
duniter-v2s-smith:
container_name: duniter-v2s-smith
image: duniter/duniter-v2s-gdev-800:latest
ports:
# RPC API of a smith node should not be exposed publicly!
- 127.0.0.1:9944:9944
# public p2p endpoint
- 30333:30333
environment:
DUNITER_NODE_NAME: duniter_smith
DUNITER_CHAIN_NAME: gdev
DUNITER_VALIDATOR: true
DUNITER_PRUNING_PROFILE: light
DUNITER_PUBLIC_ADDR: /dns/your.domain.name/tcp/30333
DUNITER_LISTEN_ADDR: /ip4/0.0.0.0/tcp/30333
volumes:
- duniter-smith-data:/var/lib/duniter
# distance oracle
distance-oracle:
container_name: distance-oracle
# choose the version of the image here
image: duniter/duniter-v2s-gdev:latest
entrypoint: docker-distance-entrypoint
environment:
ORACLE_RPC_URL: ws://duniter-v2s-smith:9944
ORACLE_RESULT_DIR: /var/lib/duniter/chains/gdev/distance/
ORACLE_EXECUTION_INTERVAL: 1800
ORACLE_LOG_LEVEL: info
volumes:
- duniter-smith-data:/var/lib/duniter
volumes:
duniter-smith-data:
version: "3.4"
services:
duniter-rpc:
image: duniter/duniter-v2s:v0.1.0
restart: unless-stopped
ports:
# telemetry
- 127.0.0.1:9615:9615
# rpc
- 127.0.0.1:9933:9933
# rpc-ws
- 127.0.0.1:9944:9944
# p2p
- 30333:30333
volumes:
- ./node.key:/etc/duniter/node.key
- duniter-rpc-data:/var/lib/duniter/
environment:
- DUNITER_CHAIN_NAME=gdev
command:
- "--execution"
- "Wasm"
- "--node-key-file"
- "/var/lib/duniter/node.key"
- "--public-addr"
# SERVER_DOMAIN should be replaced by a domain name that point on your server
#
# The PEER_ID should be replaced by the output of this command:
# docker run --rm -it --entrypoint duniter -v $PWD:/var/lib/duniter/ duniter/duniter-v2s:v0.1.0 key generate-node-key --file /var/lib/duniter/node.key
- "/dns/${SERVER_DOMAIN?SERVER_DOMAIN should be set}/tcp/30333/p2p/${PEER_ID?PEER_ID should be set}"
- "--rpc-cors"
- "all"
volumes:
duniter-rpc-data:
version: "3.4"
services:
duniter-rpc:
image: duniter/duniter-v2s:v0.1.0
restart: unless-stopped
ports:
# telemetry
- 127.0.0.1:9615:9615
# rpc
- 127.0.0.1:9933:9933
# rpc-ws
- 127.0.0.1:9944:9944
# p2p
- 30333:30333
volumes:
- ./node.key:/etc/duniter/validator-node.key
- duniter-rpc-data:/var/lib/duniter/
environment:
- DUNITER_CHAIN_NAME=gdev
command:
- "--execution=Wasm"
- "--node-key-file=/var/lib/duniter/node.key"
- "--public-addr"
# SERVER_DOMAIN should be replaced by a domain name that point on your server
#
# The PEER_ID should be replaced by the output of this command:
# docker run --rm -it --entrypoint -v $PWD/duniter-rpc/:/var/lib/duniter/ duniter duniter/duniter-v2s:v0.1.0 key generate-node-key --file /var/lib/duniter/node-key.txt
- "/dns/${SERVER_DOMAIN?SERVER_DOMAIN should be set}/tcp/30333/p2p/${PEER_ID?PEER_ID should be set}"
- "--rpc-cors=all"
duniter-validator:
image: duniter/duniter-v2s:v0.1.0
restart: unless-stopped
ports:
# telemetry
- 127.0.0.1:9616:9615
# rpc
- 127.0.0.1:9934:9933
# rpc-ws
- 127.0.0.1:9945:9944
# p2p
- 30334:30333
volumes:
- ./node.key:/etc/duniter/validator-node.key
- duniter-validator-data:/var/lib/duniter/
environment:
- DUNITER_CHAIN_NAME=gdev
command:
- "--execution=Wasm"
- "--node-key-file=/var/lib/duniter/node.key"
- "--public-addr"
# SERVER_DOMAIN should be replaced by a domain name that point on your server
#
# The PEER_ID should be replaced by the output of this command:
# docker run --rm -it --entrypoint -v $PWD/duniter-rpc/:/var/lib/duniter/ duniter duniter/duniter-v2s:v0.1.0 key generate-node-key --file /var/lib/duniter/node-key.txt
- "/dns/${SERVER_DOMAIN?SERVER_DOMAIN should be set}/tcp/30333/p2p/${VALIDATOR_PEER_ID?VALIDATOR_PEER_ID should be set}"
- "--rpc-cors=all"
- "--rpc-methods=Unsafe"
- "--validator"
version: "3.4"
services:
duniter-rpc:
image: duniter/duniter-v2s:DUNITER_IMAGE_TAG
restart: unless-stopped
ports:
- "9944:9944"
- "30333:30333"
volumes:
- ./duniter-rpc/:/var/lib/duniter/
environment:
- DUNITER_CHAIN_NAME=/var/lib/duniter/CURRENCY-raw.json
command:
- "--bootnodes"
- "/dns/duniter-validator/tcp/30333/p2p/VALIDATOR_NODE_KEY"
- "--node-key-file"
- "/var/lib/duniter/node-key"
- "--rpc-cors"
- "all"
duniter-validator:
image: duniter/duniter-v2s:DUNITER_IMAGE_TAG
restart: unless-stopped
ports:
- "127.0.0.1:9945:9944"
- "30334:30333"
volumes:
- ./duniter-validator/:/var/lib/duniter/
environment:
- DUNITER_CHAIN_NAME=/var/lib/duniter/CURRENCY-raw.json
command:
- "--bootnodes"
- "/dns/duniter-rpc/tcp/30333/p2p/RPC_NODE_KEY"
- "--node-key-file"
- "/var/lib/duniter/node-key"
- "--rpc-methods=Unsafe"
- "--validator"
- "--rpc-cors"
- "all"
#!/bin/bash
# Custom startup if a first argument is present and is equal to '--'
# then we just run duniter with the provided arguments (but the '--')
# without applying all the automated configuration below
if [ "$1" = -- ]; then
shift
distance-oracle "$@"
else
ORACLE_RESULT_DIR="${ORACLE_RESULT_DIR:-/distance}"
ORACLE_EXECUTION_INTERVAL="${ORACLE_EXECUTION_INTERVAL:-1800}"
ORACLE_RPC_URL="${ORACLE_RPC_URL:-ws://127.0.0.1:9944}"
ORACLE_LOG_LEVEL="${ORACLE_LOG_LEVEL:-info}"
while [ true ]; do
distance-oracle --evaluation-result-dir "$ORACLE_RESULT_DIR" --rpc-url "$ORACLE_RPC_URL" --log "$ORACLE_LOG_LEVEL"
echo "Waiting $ORACLE_EXECUTION_INTERVAL seconds before next execution..."
sleep $ORACLE_EXECUTION_INTERVAL
done
fi
#!/bin/bash #!/bin/bash
# Custom startup if a first argument is present and is equal to '--'
# then we just run duniter with the provided arguments (but the '--')
# without applying all the automated configuration below
if [ "$1" = -- ]; then
shift
exec duniter "$@"
fi
# Normal startup
function boolean () { function boolean () {
echo "$1" | sed -E 's/^(true|yes|1)$/true/i' echo "$1" | sed -E 's/^(true|yes|1)$/true/i'
} }
...@@ -12,12 +21,8 @@ function ternary () { ...@@ -12,12 +21,8 @@ function ternary () {
fi fi
} }
if [ -n "$DUNITER_INSTANCE_NAME" ]; then # Define chain name at the beginning
set -- "$@" --name "$DUNITER_INSTANCE_NAME" # with #274 we could have default given in network branch
fi
DUNITER_DISABLE_PROMETHEUS=$(boolean "${DUNITER_DISABLE_PROMETHEUS:-false}")
DUNITER_CHAIN_NAME="${DUNITER_CHAIN_NAME:-dev}" DUNITER_CHAIN_NAME="${DUNITER_CHAIN_NAME:-dev}"
case "$DUNITER_CHAIN_NAME" in case "$DUNITER_CHAIN_NAME" in
dev) dev)
...@@ -28,10 +33,93 @@ case "$DUNITER_CHAIN_NAME" in ...@@ -28,10 +33,93 @@ case "$DUNITER_CHAIN_NAME" in
;; ;;
esac esac
# Node name will appear on network
DUNITER_NODE_NAME="${DUNITER_NODE_NAME:-$DUNITER_INSTANCE_NAME}"
if [ -n "$DUNITER_NODE_NAME" ]; then
set -- "$@" --name "$DUNITER_NODE_NAME"
fi
# Path of key file. Should be generated below if not present before starting Duniter
_DUNITER_KEY_FILE=/var/lib/duniter/node.key
set -- "$@" --node-key-file "$_DUNITER_KEY_FILE"
# Generate node.key if not existing (chain name is required)
if [ ! -f "$_DUNITER_KEY_FILE" ]; then
echo "Generating node key file '$_DUNITER_KEY_FILE'..."
duniter key generate-node-key --file "$_DUNITER_KEY_FILE" "${chain[@]}"
else
echo "Node key file '$_DUNITER_KEY_FILE' exists."
fi
# Log peer ID
_DUNITER_PEER_ID="$(duniter key inspect-node-key --file "$_DUNITER_KEY_FILE")"
echo "Node peer ID is '$_DUNITER_PEER_ID'."
# Define public address (with dns, correct port and protocol for instance)
if [ -n "$DUNITER_PUBLIC_ADDR" ]; then
set -- "$@" --public-addr "$DUNITER_PUBLIC_ADDR"
fi
# Define public RPC endpoint (gossiped on the network)
if [ -n "$DUNITER_PUBLIC_RPC" ]; then
set -- "$@" --public-rpc "$DUNITER_PUBLIC_RPC"
fi
# Define public Squid endpoint (gossiped on the network)
if [ -n "$DUNITER_PUBLIC_SQUID" ]; then
set -- "$@" --public-squid "$DUNITER_PUBLIC_SQUID"
fi
# Define public endpoints from JSON file (gossiped on the network)
if [ -n "$DUNITER_PUBLIC_ENDPOINTS" ]; then
set -- "$@" --public-endpoints "$DUNITER_PUBLIC_ENDPOINTS"
fi
# Define listen address (inside docker)
if [ -n "$DUNITER_LISTEN_ADDR" ]; then
set -- "$@" --listen-addr "$DUNITER_LISTEN_ADDR"
fi
DUNITER_RPC_CORS="${DUNITER_RPC_CORS:-all}"
set -- "$@" --rpc-cors "$DUNITER_RPC_CORS"
# In case of validator, unsafe rpc methods are needed (like rotate_key) and should not be exposed publicly
DUNITER_VALIDATOR=$(boolean "${DUNITER_VALIDATOR:-false}")
if [ "$DUNITER_VALIDATOR" = true ]; then
set -- "$@" --rpc-methods Unsafe --validator
fi
DUNITER_DISABLE_PROMETHEUS=$(boolean "${DUNITER_DISABLE_PROMETHEUS:-false}")
if [ "$DUNITER_DISABLE_PROMETHEUS" = true ]; then
set -- "$@" --no-prometheus
fi
DUNITER_DISABLE_TELEMETRY=$(boolean "${DUNITER_DISABLE_TELEMETRY:-false}")
if [ "$DUNITER_DISABLE_TELEMETRY" = true ]; then
set -- "$@" --no-telemetry
fi
# Set pruning profile
DUNITER_PRUNING_PROFILE="${DUNITER_PRUNING_PROFILE:-default}"
case "$DUNITER_PRUNING_PROFILE" in
default)
;;
archive)
set -- "$@" --state-pruning archive --blocks-pruning archive
;;
light)
set -- "$@" --blocks-pruning 14400
;;
*)
echo "ERROR: ignoring unknown DUNITER_PRUNING_PROFILE value '$DUNITER_PRUNING_PROFILE'" >&2
;;
esac
# Set main command
# Since we are inside docker, we can bind to all interfaces.
# User will bind port to host interface or set reverse proxy when needed.
set -- "$@" \ set -- "$@" \
"${chain[@]}" \ "${chain[@]}" \
$(ternary "$DUNITER_DISABLE_PROMETHEUS" --no-prometheus) \ -d /var/lib/duniter --unsafe-rpc-external
-d /var/lib/duniter --unsafe-rpc-external --unsafe-ws-external
echo "Starting duniter with parameters:" "$@" echo "Starting duniter with parameters:" "$@"
exec duniter "$@" exec duniter "$@"
# Manual for wallet developers # Manual for wallet developers
This functionnal documentation presents how wallets can interact with the blockchain. This functional documentation presents how wallets can interact with the blockchain.
It is intended to complete the [runtime calls documentation](./runtime-calls.md) in a runtime-specific way to fit the real needs of wallet developers. It is intended to complete the [runtime calls documentation](./runtime-calls.md) in a runtime-specific way to fit the real needs of wallet developers.
Only ĞDev is covered for now. NOTE : a more detailed doc is available at <https://duniter.org/wiki/duniter-v2/doc/>
## Notations ## Notations
...@@ -11,27 +11,52 @@ Only ĞDev is covered for now. ...@@ -11,27 +11,52 @@ Only ĞDev is covered for now.
## Account existence ## Account existence
An account exists if and only if it contains at least the existential deposit (2 ĞD). An account exists if and only if it contains at least the existential deposit (`balances.existentialDeposit` = 1 ĞD).
## Become member ## Become member
Only use `identity` pallet. The `membership` calls are disabled. Only use `identity` pallet.
1. The account that wants to gain membership needs to exists. 1. The account that wants to gain membership needs to exists.
1. Any account that already has membership and respects the identity creation period can create an identity for another account, using `identity.createIdentity`. 1. Any account that already has membership and respects the identity creation period can create an identity for another account, using `identity.createIdentity`.
1. The account has to confirm its identity with a name, using `identity.confirmIdentity`. The name must be ASCII alphanumeric, punctuation or space characters: `` /^[-!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~a-zA-Z0-9 ]{3,64}$/ `` (additionally, trailing spaces and double spaces are forbidden, as a phishing countermeasure). If the name is already used, the call will fail. 1. The account has to confirm its identity with a name, using `identity.confirmIdentity`. The name must be ASCII alphanumeric, punctuation or space characters: `` /^[-!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~a-zA-Z0-9 ]{3,64}$/ `` (additionally, trailing spaces and double spaces are forbidden, as a phishing countermeasure). If the name is already used, the call will fail.
1. 4 different member accounts must certify the account using `cert.addCert`.
1. The distance evaluation must be requested for the pending identity using `distance.requestDistanceEvaluation`.
1. 3 distance sessions later, if the distance rule is respected, identity is validated automatically.
## Change key
A member can request a key change via the `identity.change_onwner_key` call. It needs the following SCALE encoded (see SCALE encoding section below) payload:
- The new owner key payload prefix (rust definition: `b"icok"`)
- the genesis block hash. (rust type `[u8; 32]` (`H256`))
- The identity index (rust type `u64`)
- The old key (rust type `u64`)
This payload must be signed with the new key.
## Revoke an identity ## Revoke an identity
Revoking an identity makes it lose its membership, hence UD creation and governance rights. Orher data such as balance will remain. Revoking an identity makes it lose its membership, hence UD creation and governance rights. Other data such as balance will remain.
This feature is useful in case the user has lost their private key. This feature is useful in case the user has lost their private key since the revocation document can be made in advance.
### Generate the revocation payload ### Generate the revocation payload
1. Scale-encode the revocation payload, that is the concatenation of the 32-bits public key and the genesis block hash. The revocation needs this SCALE encoded (see SCALE encoding section below) payload:
2. Store this payload and its signature.
- The revocation payload prefix (rust definition: `b"revo"`)
- The identity index (rust type `u64`)
- the genesis block hash. (rust type `[u8; 32]` (`H256`))
This payload must be signed with the corresponding revocation key.
### Effectively revoke the identity ### Effectively revoke the identity
1. From any origin that can pay the fee, use `identity.revokeIdentity` with the revocation payload. 1. From any origin that can pay the fee, use `identity.revokeIdentity` with the revocation payload.
## SCALE encoding
SCALE codec documentation: https://docs.substrate.io/reference/scale-codec/.
At the end of this documentation you'll find links to SCALE codec implementation for other languages.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# Beginner walkthrough
This is a beginner tutorial for those who do not have a previous experience with Rust ecosystem or need guidance to get familiar with Duniter v2s project. You'll need a development machine with an internet connection, at least **20 GB of free storage**, and **an hour or two** depending on your computing power.
This walkthrough is based on the following video (french), don't hesitate to record an english voiceover if you feel so.
[![preview](https://tube.p2p.legal/lazy-static/previews/654006dc-66c0-4e37-a32f-b7b5a1c13213.jpg)](https://tube.p2p.legal/w/n4TXxQ4SqxzpHPY4TNMXFu)
> video walkthrough on peertube https://tube.p2p.legal/w/n4TXxQ4SqxzpHPY4TNMXFu
## Requirements
If you are on a debian based system, you can install the required packages with:
```bash
sudo apt install cmake pkg-config libssl-dev git build-essential clang libclang-dev curl protobuf-compiler
```
Else, look at the corresponding section in the [system setup documentation](./setup.md).
Rust recommended installation method is through the rustup script that you can run with:
```bash
curl https://sh.rustup.rs -sSf | sh
```
If you reopen your terminal, it will give you access to the `rustup`, `rustc` and `cargo` commands. You can then install the required Rust toolchains with:
```bash
rustup default stable
rustup update nightly
rustup update stable
rustup target add wasm32-unknown-unknown --toolchain nightly
```
This can take about **2 minutes**.
## Build project
After cloning wherever you want the `duniter-v2s` repo with:
```bash
git clone https://git.duniter.org/nodes/rust/duniter-v2s.git
```
you can go to the root folder and build the substrate client and default runtime with:
```bash
cargo build
```
This will take about **2 minutes** to download dependencies plus between 5 and **15 minutes** to build in debug mode depending on the power of your processor. At this point, you built the *substrate client* (a kind of "shell" in which lies the runtime) and the default *runtime* itself. You can run a local blockchain with:
```bash
cargo run -- --dev --tmp # here, --dev means --chain=dev which selects the gdev runtime
```
When you see the logs, the blockchain is running and you can connect to it with polkadotjs app: [https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:9944](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944). You should see blocks being added every 6 seconds. You can use Alice, Bob, etc test accounts to submit extrinsics.
## Autocompletion
When using Duniter commands, you will benefit a lot from commands autocompletion. This can be achieved by following [autocompletion documentation](../user/autocompletion.md) for you shell. If you use bash the commands are:
```bash
# create local dir to store completion script
mkdir -p ~/.local/share/duniter
# export the bash completion file
cargo run -- completion --generator bash > ~/.local/share/duniter/completion.bash
# add the following line to your ~/.bashrc to automatically load completion on startup
[[ -f $HOME/.local/share/duniter/completion.bash ]] && source $HOME/.local/share/duniter/completion.bash
```
You will then benefit from completion using `<Tab>` key and `*`.
## End-to-end tests using cucumber
Cucumber end2end tests are a good way to dive in Duniter's business procedure. They work by spawning a local blockchain and submitting extrinsics to it. You can build and run the cucumber tests by running:
```bash
cargo cucumber
```
which should take about **4 minutes** to build and run the tests. A highly detailed documentation about the end2end tests is available [in the dedicated folder](../../end2end-tests/README.md), you will learn how to read and modify the tests.
## Get in touch with us
Wether you are stuck and need help or have sucessfully completed this tutorial, don't hesitate to get in touch with us on the Duniter forum! If you found this walkthrough useful, please 🙏 let us know on the [walkthrough topic](https://forum.duniter.org/t/contribuer-a-duniter-tutoriel-video/9770) on the forum 😊.
\ No newline at end of file