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
Showing
with 822 additions and 54 deletions
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:
db:
image: postgres:12
restart: always
volumes:
- /var/lib/postgresql/data
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
duniter-rpc:
image: duniter/duniter-v2s:DUNITER_IMAGE_TAG
restart: unless-stopped
......@@ -47,57 +38,3 @@ services:
- "--validator"
- "--rpc-cors"
- "all"
indexer:
image: subsquid/hydra-indexer:5
restart: unless-stopped
environment:
- WORKERS_NUMBER=1
- DB_NAME=indexer
- DB_HOST=db
- DB_USER=postgres
- DB_PASS=postgres
- DB_PORT=5432
- REDIS_URI=redis://redis:6379/0
- FORCE_HEIGHT=true
- BLOCK_HEIGHT=0 # starting block height
- WS_PROVIDER_ENDPOINT_URI=ws://duniter-rpc:9944/
depends_on:
- db
- redis
command: >
sh -c "yarn db:bootstrap && yarn start:prod"
indexer-gateway:
image: subsquid/hydra-indexer-gateway:5
restart: unless-stopped
depends_on:
- redis
- db
- indexer-status-service
- indexer
ports:
- "4010:8080"
environment:
- DEV_MODE=true
- DB_NAME=indexer
- DB_HOST=db
- DB_USER=postgres
- DB_PASS=postgres
- DB_PORT=5432
- HYDRA_INDEXER_STATUS_SERVICE=http://indexer-status-service:8081/status
indexer-status-service:
image: subsquid/hydra-indexer-status-service:5
restart: unless-stopped
depends_on:
- redis
environment:
REDIS_URI: redis://redis:6379/0
PORT: 8081
redis:
image: redis:6.0-alpine
restart: always
ports:
- "6379"
FROM rust:latest
RUN dpkg --add-architecture armhf && \
apt-get update && apt-get upgrade -y && \
apt-get install -y aptitude && \
aptitude install -y \
gcc-arm-linux-gnueabihf \
g++-arm-linux-gnueabihf \
pkg-config \
cmake \
libssl-dev \
git \
clang \
libclang-dev \
libssl-dev:armhf
# Install nightly with armv7 and w32-u-u
RUN rustup install nightly-2021-11-12-x86_64-unknown-linux-gnu && \
rustup target add armv7-unknown-linux-gnueabihf --toolchain \
nightly-2021-11-12-x86_64-unknown-linux-gnu && \
rustup target add wasm32-unknown-unknown --toolchain \
nightly-2021-11-12-x86_64-unknown-linux-gnu && \
cargo +nightly-2021-11-12-x86_64-unknown-linux-gnu install --git \
https://github.com/alexcrichton/wasm-gc --force
ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER arm-linux-gnueabihf-gcc
ENV PKG_CONFIG_ALLOW_CROSS 1
ENV PKG_CONFIG_PATH /usr/lib/arm-linux-gnueabihf/pkgconfig/
# Disallow the `pkg-config` crate to look for the config for zlib, because build.rs of `libz-sys`
# gets confused and pulls the system-wide library (i.e. of the host) instead of the target when
# cross-compiling. This essentially leads to static linking of zlib.
#
# Alternatively, we can supply LIBZ_SYS_STATIC=1. Weirdly enough, installing libgtk-3-dev:armhf
# also solves the problem somehow.
#
# Here is the related issue: https://github.com/rust-lang/libz-sys/issues/49
ENV ZLIB_NO_PKG_CONFIG 1
# This is for compiling GUI apps.
# RUN aptitude install -y libasound2-dev:armhf libgtk-3-dev:armhf libsdl2-dev:armhf
RUN useradd rust --user-group --create-home --shell /bin/bash --groups sudo
WORKDIR /home/rust/src
# Manual for wallet developers
This functionnal 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.
Only ĞDev is covered for now.
## Notations
1 ĞD = 100 units
## Account existence
An account exists if and only if it contains at least the existential deposit (2 ĞD).
## Become member
Only use `identity` pallet. The `membership` calls are disabled.
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. 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.
## Revoke an identity
Revoking an identity makes it lose its membership, hence UD creation and governance rights. Orher data such as balance will remain.
This feature is useful in case the user has lost their private key.
### 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.
2. Store this payload and its signature.
### Effectively revoke the identity
1. From any origin that can pay the fee, use `identity.revokeIdentity` with the revocation payload.
......@@ -8,6 +8,7 @@ the transactor. This is the only call category that can be submitted with an ext
through on-chain governance mechanisms.
1. Inherent calls: This kind of call is invoked by the author of the block itself
(usually automatically by the node).
1. Disabled calls: These calls are disabled for different reasons (to be documented).
## User calls
......@@ -2151,3 +2152,169 @@ call: Box<<T as Config>::Call>
</p>
</details>
## Disabled calls
There are **7** disabled calls organized in **4** pallets.
### 0: System
<details><summary>1: remark(remark)</summary>
<p>
### Index
`1`
### Documentation
Make some on-chain remark.
### Types of parameters
```rust
remark: Vec<u8>
```
</p>
</details>
<details><summary>8: remark_with_event(remark)</summary>
<p>
### Index
`8`
### Documentation
Make some on-chain remark and emit event.
### Types of parameters
```rust
remark: Vec<u8>
```
</p>
</details>
### 14: Session
<details><summary>0: set_keys(keys, proof)</summary>
<p>
### Index
`0`
### Documentation
Sets the session key(s) of the function caller to `keys`.
Allows an account to set its session key prior to becoming a validator.
This doesn't take effect until the next session.
The dispatch origin of this function must be signed.
### Types of parameters
```rust
keys: T::Keys,
proof: Vec<u8>
```
</p>
</details>
<details><summary>1: purge_keys()</summary>
<p>
### Index
`1`
### Documentation
Removes any session key(s) of the function caller.
This doesn't take effect until the next session.
The dispatch origin of this function must be Signed and the account must be either be
convertible to a validator ID using the chain's typical addressing system (this usually
means being a controller account) or directly convertible into a validator ID (which
usually means being a stash account).
</p>
</details>
### 42: Membership
<details><summary>2: claim_membership(maybe_idty_id)</summary>
<p>
### Index
`2`
### Documentation
### Types of parameters
```rust
maybe_idty_id: Option<T::IdtyId>
```
</p>
</details>
<details><summary>4: revoke_membership(maybe_idty_id)</summary>
<p>
### Index
`4`
### Documentation
### Types of parameters
```rust
maybe_idty_id: Option<T::IdtyId>
```
</p>
</details>
### 52: SmithsMembership
<details><summary>2: claim_membership(maybe_idty_id)</summary>
<p>
### Index
`2`
### Documentation
### Types of parameters
```rust
maybe_idty_id: Option<T::IdtyId>
```
</p>
</details>
......@@ -15,3 +15,7 @@ Then, the runtime wasm bytecode is generated in this location:
```
runtime/gdev/target/srtool/release/wbuild/gdev-runtime/gdev_runtime.compact.compressed.wasm
```
To compare it to last official :
- download it here : https://git.duniter.org/nodes/rust/duniter-v2s/-/releases
- compare `sha256sum` of it and of the one you've built
# How to replay a block
You can use `try-runtime` subcommand to replay a block against a real satte from a live network.
1. Checkout the git tag of the runtime version at the block you want to replay
2. Build duniter with feature `try-runtime`: `cargo build --features try-runtime`
3. Find the hash of the block to replay
4. Choose an RPC endpoint without path (try-runtime not support path)
5. Replay the block a first time to get the state:
```
duniter try-runtime --exectuion=Native execute-block --block-at 0x2633026e3e428b010cfe08d215b6253843a9fe54db28748ca56de37e6a83c644 live -s tmp/snapshot1 -u ws://localhost:9944
```
6. Then, replay the block as many times as you need against your local snapshot:
```
duniter try-runtime --exectuion=Native execute-block --block-at 0x2633026e3e428b010cfe08d215b6253843a9fe54db28748ca56de37e6a83c644 --block-ws-uri ws://localhost:9944 snap -s tmp/snapshot1
```
try-runtime does not allow (for now) to store the block locally, only the storage can be stored.
# Autocompletion
One can generate autocompletion for its favorite shell using the following option:
```sh
cargo run --release -- completion --generator <GENERATOR>
```
Where `GENERATOR` can be any of `bash`, `elvish`, `fish`, `powershell` and `zsh`.
## Bash
First, get the completion file in a known place:
```sh
mkdir -p ~/.local/share/duniter
cargo run --release -- completion --generator bash > ~/.local/share/duniter/completion.bash
```
You can now manually source the file when needed:
```sh
source ~/.local/share/duniter/completion.bash
```
Or you can automatically source it at `bash` startup by adding this to your `~/.bashrc` file:
```sh
[[ -f $HOME/.local/share/duniter/completion.bash ]] && source $HOME/.local/share/duniter/completion.bash
```
You can now enjoy semantic completion of the `./target/release/duniter` command using `<Tab>` key.
# How to build duniter-v2s for arm
1. Create a docker image that contains the build environment
```bash
docker build -t duniter-v2s-arm-builder -f docker/cross-arm.Dockerfile .
```
2. Use this docker image to cross-compile duniter-v2s for armv7
```bash
./scripts/cross-build-arm.sh
```
then, get the final binary at `target/armv7-unknown-linux-gnueabihf/release/duniter`.
# How to deploy a permanent rpc node on ĞDev network
## Publish a node
### Duniter part
- Add this docker-compose on your server :
[docker/compose/gdev-rpc.docker-compose.yml](https://git.duniter.org/nodes/rust/duniter-v2s/-/blob/master/docker/compose/gdev-rpc.docker-compose.yml)
- Rename the file : `mv gdev-mirror.docker-compose.yml docker-compose.yml`
- In the same folder, create a `.env` file that defime environment variables `SERVER_DOMAIN` and `PEER_ID`:
```
SERVER_DOMAIN=YOUR_DOMAIN
PEER_ID=YOUR_PEER_ID
```
Your `PEER_ID` shoud be generated with 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`
- If you have write access errors run in docker-compose.yml folder : `chmod o+rwX -R .`
- `docker-compose up -d` to start your node
### Reverse-proxy part (with Nginx)
In `/etc/nginx/sites-enabled/gdev.YOUR_DOMAIN` put (you can probably do simpler) :
```
server {
server_name gdev.YOUR_DOMAIN.fr;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/nginx/ssl/YOUR_DOMAIN.cert;
ssl_certificate_key /etc/nginx/ssl/YOUR_DOMAIN.key;
root /nowhere;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_read_timeout 90;
location /http {
proxy_pass http://localhost:9933;
proxy_http_version 1.1;
}
location /ws {
proxy_pass http://localhost:9944;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_read_timeout 1200s;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
}
```
and replace `YOUR_DOMAIN` by your domain each time.
- [generate your ssl certificates](https://github.com/acmesh-official/acme.sh) with let's encrypt
if you don't already have a wildcard certificate.
- `service nginx reload`
Your node is now online as a rpc node. It's fully capable for wallet use.
To go further, read [How to become a (black)smith](./smith.md)
## Upgrade your node with minimal interruption
1. Modify docker image tag on your compose file
2. Run `docker compose pull`, this will pull the new image.
3. Run `docker compose up -d --remove-orphans`, this will recreate the container
4. Verify that your node restarted well `docker compose logs duniter-rpc`
5. Remove the old image `docker images rmi duniter/duniter-v2s:OLD_TAG`
# How to become a (black)smith
## Publish a node
### Duniter part
- Add this docker-compose on your server :
[docker/compose/gdev-validator.docker-compose.yml](https://git.duniter.org/nodes/rust/duniter-v2s/-/blob/master/docker/compose/gdev-validator.docker-compose.yml)
- Create a `.env` file that define environment variables `SERVER_DOMAIN`, `PEER_ID` and `VALIDATOR_PEER_ID`:
- `SERVER_DOMAIN`: a domain name that point on your server
- `PEER_ID`: Your rpc node peer id, shoud be generated with this command: `docker run --rm -it --entrypoint -v $PWD:/var/lib/duniter/ duniter duniter/duniter-v2s:v0.1.0 key generate-node-key --file /var/lib/duniter/rpc-node.key`
- `VALIDATOR_PEER_ID`: Your validator node peer id, shoud be generated with this command: `docker run --rm -it --entrypoint -v $PWD:/var/lib/duniter/ duniter duniter/duniter-v2s:v0.1.0 key generate-node-key --file /var/lib/duniter/validator-node.key`
Note: duniter-rpc PEER_ID and duniter-validator PEER_ID isn't the same.
- If you have write access errors run in docker-compose.yml folder : `chmod o+rwX -R .`
- `docker-compose up -d` to start your node
### Reverse-proxy part (with Nginx)
In `/etc/nginx/sites-enabled/gdev.YOUR_DOMAIN` put (you can probably do simpler) :
```
server {
server_name gdev.YOUR_DOMAIN.fr;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/nginx/ssl/YOUR_DOMAIN.cert;
ssl_certificate_key /etc/nginx/ssl/YOUR_DOMAIN.key;
root /nowhere;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_read_timeout 90;
location /http {
proxy_pass http://localhost:9933;
proxy_http_version 1.1;
}
location /ws {
proxy_pass http://localhost:9944;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_read_timeout 1200s;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
}
```
and replace `YOUR_DOMAIN` by your domain each time.
- [generate your ssl certificates](https://github.com/acmesh-official/acme.sh) with let's encrypt
if you don't already have a wildcard certificate.
- `service nginx reload`
Your node is now online as a rpc node. It's fully capable for wallet use.
## Join the Smith WoT
- add polkadot webextension to be able to authentificate with your account.
- Go to [any node with polkadotjs ui](https://gdev.1000i100.fr/dev-ui/?rpc=wss://gdev.1000i100.fr/ws)
- Ask to join Smith WoT (you need to already be in the main WoT)
- developer > extrinsics > YOUR_SMITH_ACCOUNT > smithMembership > requestMemberShip(metadata)
- add your p2p endpoint (optional)
- add your session key (follow point 1 to 4 from Validate blocks > Generate and publish your session key)
- Send the query
- Await smith certification : developer > extrinsics > CERTIFIER_SMITH_ACCOUNT > smithCert > addCert(receiver)
When you have at least 3 certifications, your'in !
## Validate blocks (blacksmith work)
- Generate and publish your session keys
1. create an ssh bridge from your desktop/laptop to your server : `ssh -L 9945:localhost:9945 SSH_USER@YOUR_SERVER`
2. In your browser go to [polkadotjs : ws://localhost:9945](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2Flocalhost%3A9945#/explorer)
3. In the UI : developer > appel RPC > author > rotateKey() and run
4. copy the result in clipboard
5. In the UI : developer > extrinsics > YOUR_SMITH_ACCOUNT > authorityMembers > setSessionKeys(keys) then copy your session keys and run the query.
6. **wait 48h to verify you keep sync**
- Join
- In the UI : developer > extrinsics > YOUR_SMITH_ACCOUNT > authorityMembers > goOnline()
If you're not able to monitor, reboot, act on your node, goOffline() to avoid penality to the blockchain and to you.
## Upgrade your node with minimal interruption
1. Modify docker image tag on your compose file
2. Run `docker compose pull`, this will pull the new image.
3. Run `docker compose up -d --remove-orphans`, this will recreate the container
4. Verify that your node restarted well `docker compose logs duniter-validator`
5. Remove the old image `docker images rmi duniter/duniter-v2s:OLD_TAG`
......@@ -9,6 +9,7 @@ repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
version = '3.0.0'
[dev-dependencies]
anyhow = "1.0"
async-trait = "0.1"
clap = { version = "3.0", features = ["derive"] }
ctrlc = "3.2.2"
......
# Duniter-v2s integration tests
# Duniter-v2s end2end tests
## cucumber functionnal tests
## Cucumber functionnal tests
We use [cucumber] to be able to describe test scenarios in human language.
......@@ -20,7 +20,7 @@ Feature: Balance transfer
Then dave should have 5 ĞD
```
### create a new functional test
### Create a new functional test
To create a new test scenario, simply create a new file with a name of your choice in the
`/cucumber-features` folder and give it the extension `.feature`.
......@@ -47,44 +47,16 @@ Feature: My awesome feature
Then We should observe that
```
### Test users
6 test users are provided:
- alice
- bob
- charlie
- dave
- eve
- ferdie
### genesis state
Each scenario bootstraps its own blockchain with its own genesis state.
By default, all scenarios use the same configuration for the genesis, which is located in the file
`/cucumber-genesis/default.json`.
You can define a custom genesis state for each scenario with the tag `@genesis.confName`.
### Steps
The genesis configuration must then be defined in a json file located at
`/cucumber-genesis/confName.json`.
You can also define a custom genesis at the feature level, all the scenarios of this feature will
then inherit the genesis configuration.
### Currency amounts
Amounts must be expressed as an integer of `ĞD` or `UD`, decimal numbers are not supported.
If you need more precision, you can express amounts in cents of ĞD (write `cĞD`), or in thousandths
of UD (write `mUD`).
Each scenario is a list of steps. In our context (blockchain), only the `When` and `Then` steps make sense, `Given` being the genesis.
#### When
List of possible actions:
- transfer: `alice send 5 ĞD to bob`
- transfer_ud: `alice send 3 UD to bob`
- transfer: `alice sends 5 ĞD to bob`
- transfer_ud: `alice sends 3 UD to bob`
- transfer_all: `alice sends all her ĞDs to bob`
#### Then
......@@ -95,36 +67,72 @@ List of possible actions:
Example: `alice should have 10 ĞD`
### Universal dividend creation
#### Then
- Check the current UD amount
Usage: `Current UD amount should be {amount}.{cents} ĞD`
Example: `Current UD amount should be 10.00 ĞD`
- Check the monetary mass
Usage: `Monetary mass should be {amount}.{cents} ĞD`
Example: `Monetary mass should be 30.00 ĞD`
### Test users
6 test users are provided:
- alice
- bob
- charlie
- dave
- eve
- ferdie
### Currency amounts
Amounts must be expressed as an integer of `ĞD` or `UD`, decimal numbers are not supported.
If you need more precision, you can express amounts in cents of ĞD (write `cĞD`), or in thousandths
of UD (write `mUD`).
### Genesis state
Each scenario bootstraps its own blockchain with its own genesis state.
By default, all scenarios use the same configuration for the genesis, which is located in the file
`/cucumber-genesis/default.json`.
You can define a custom genesis state for each scenario with the tag `@genesis.confName`.
The genesis configuration must then be defined in a json file located at
`/cucumber-genesis/confName.json`.
You can also define a custom genesis at the feature level, all the scenarios of this feature will
then inherit the genesis configuration.
### ignoreErrors
For some scenarios, you may need to perform an action (When) that fails voluntarily, in this case you must add the tag @ignoreErrors to your scenario, otherwise it will be considered as failed
### Run cucumber functional tests
The cucumber tests use the last debug binary in your `target` folder. Make sure this binary corresponds to the executable you want to test by running `cargo build` before.
To run the cucumber tests, you will need to have the rust toolchain installed locally.
To run all the scenarios (there are many) use the command: `cargo cucumber`
You can filter the `.feature` files to run with the option `i`, for instante:
You can filter the `.feature` files to run with the option `i`, for instance:
```
cargo cucumber -i monetary*
```
Will only run `.feature` files that start with `"monetary"`.
will only run `.feature` files that start with `"monetary"`.
The features will be tested in parallel and logs files will be written in the `end2end-tests` folder.
If you get an `Error: Timeout`, look at the logs to understand why Duniter did not launch successfully. You can also set the environment variable `DUNITER_END2END_TESTS_SPAWN_NODE_TIMEOUT` to increase the timeout for node spawn.
### Contribute to the code that runs the tests
......
Feature: Balance transfer
Scenario: Create a new account with enough funds
When alice sends 5 ĞD to dave
Then dave should have 5 ĞD
When 1 block later
"""
The blockchain should automatically withdraw account creation tax (3 ĞD)
"""
Then dave should have 2 ĞD
Scenario: Create a new account without enough funds then retry with enough funds
When alice sends 2 ĞD to eve
Then eve should have 2 ĞD
When 1 block later
"""
The blockchain should automatically destroy Eve account
because Eve does not have enough funds to pay the new account tax
"""
Then eve should have 0 ĞD
When alice send 5 ĞD to eve
Then eve should have 5 ĞD
When 1 block later
"""
The blockchain should automatically withdraw account creation tax (3 ĞD)
"""
Then eve should have 2 ĞD
@ignoreErrors
Scenario: Create a new account without any funds
Then eve should have 0 ĞD
When eve send 0 ĞD to alice
Then alice should have 10 ĞD
When alice send 5 ĞD to eve
Then eve should have 5 ĞD
When 1 block later
"""
The blockchain should automatically withdraw account creation tax (3 ĞD)
"""
Then eve should have 2 ĞD
Feature: Balance transfer
Scenario: If alice sends 5 ĞD to Dave, Dave will get 5 ĞD
Given alice have 10 ĞD
When alice send 5 ĞD to dave
Then dave should have 5 ĞD
@genesis.wot
Feature: Certification
Scenario: Dave certifies Alice
When dave certifies alice
Then alice should be certified by dave
@ignoreErrors
Scenario: Dave certifies Alice (but dave is not certified by charlie, this test should fail)
When dave certifies alice
Then dave should be certified by charlie
\ No newline at end of file
@genesis.default
Feature: Balance transfer all
Scenario: If alice sends all her ĞDs to Dave, Dave will get 8 ĞD
When alice sends all her ĞDs to dave
Scenario: If bob sends all his ĞDs to Dave
When bob sends all her ĞDs to dave
"""
Alice is a smith member, as such she is not allowed to empty her account completely,
if she tries to do so, the existence deposit (2 ĞD) must remain.
Bob is a member, as such he is not allowed to empty his account completely,
if he tries to do so, the existence deposit (2 ĞD) must remain.
"""
Then alice should have 2 ĞD
Then dave should have 8 ĞD
Then bob should have 2 ĞD
"""
10 ĞD (initial Bob balance) - 2 ĞD (Existential deposit) - 0.02 ĞD (transaction fees)
"""
Then dave should have 798 cĞD
{
"first_ud": 1000,
"first_ud_reeval": 100,
"identities": {
"Alice": {
"balance": 1000,
"certs": ["Bob", "Charlie", "Dave"],
"pubkey": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
},
"Bob": {
"balance": 1000,
"certs": ["Alice", "Charlie", "Dave"],
"pubkey": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
},
"Charlie": {
"balance": 1000,
"certs": ["Alice", "Bob"],
"pubkey": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y"
},
"Dave": {
"balance": 1000,
"certs": [],
"pubkey": "5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy"
}
},
"parameters": {
"babe_epoch_duration": 30,
"cert_period": 15,
"cert_max_by_issuer": 10,
"cert_min_received_cert_to_issue_cert": 2,
"cert_renewable_period": 50,
"cert_validity_period": 1000,
"idty_confirm_period": 40,
"idty_creation_period": 50,
"membership_period": 1000,
"membership_renewable_period": 50,
"pending_membership_period": 500,
"ud_creation_period": 10,
"ud_reeval_period": 100,
"smith_cert_period": 15,
"smith_cert_max_by_issuer": 8,
"smith_cert_min_received_cert_to_issue_cert": 2,
"smith_cert_renewable_period": 50,
"smith_cert_validity_period": 1000,
"smith_membership_period": 1000,
"smith_membership_renewable_period": 20,
"smith_pending_membership_period": 500,
"smiths_wot_first_cert_issuable_on": 20,
"smiths_wot_min_cert_for_membership": 2,
"wot_first_cert_issuable_on": 20,
"wot_min_cert_for_create_idty_right": 2,
"wot_min_cert_for_membership": 2
},
"smiths": {
"Alice": {
"certs": ["Bob", "Charlie"]
},
"Bob": {
"certs": ["Alice", "Charlie"]
},
"Charlie": {
"certs": ["Alice", "Bob"]
}
},
"sudo_key": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
}
// Copyright 2021 Axiom-Team
//
// This file is part of Substrate-Libre-Currency.
//
// Substrate-Libre-Currency 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.
//
// Substrate-Libre-Currency 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 Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
use super::node_runtime::runtime_types::gdev_runtime;
use super::node_runtime::runtime_types::pallet_certification;
use super::*;
use sp_keyring::AccountKeyring;
use subxt::{sp_runtime::MultiAddress, PairSigner};
pub async fn certify(
api: &Api,
client: &Client,
from: AccountKeyring,
to: AccountKeyring,
) -> Result<()> {
let from = PairSigner::new(from.pair());
let to = to.to_account_id();
let _events = create_block_with_extrinsic(
client,
api.tx()
.cert()
.add_cert(to)
.create_signed(&from, ())
.await?,
)
.await?;
Ok(())
}
......@@ -17,10 +17,12 @@
#![allow(clippy::enum_variant_names, dead_code, unused_imports)]
pub mod balances;
pub mod cert;
#[subxt::subxt(runtime_metadata_path = "../resources/metadata.scale")]
pub mod node_runtime {}
use anyhow::anyhow;
use serde_json::Value;
use sp_keyring::AccountKeyring;
use std::io::prelude::*;
......