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 (9)
Showing
with 259 additions and 41 deletions
This project is tracked on our hosted gitlab server at: https://git.duniter.org/nodes/typescript/duniter/gitlab
This project is tracked on our hosted gitlab server at: https://git.duniter.org/nodes/rust/duniter-v2s
The current github repository is a simple clone taken up to date at each push on the main gitlab repository.
......
......@@ -8,6 +8,7 @@ workflow:
rules:
- changes:
- docker/Dockerfile
- end2end-tests/**/*
- node/**/*
- pallets/**/*
- runtime/**/*
......
{
"editor.formatOnSave": true,
"editor.rulers": [100],
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.rulers": [
100
],
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[yaml]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
......@@ -19,4 +15,4 @@
"port_rpc": 19932,
"port_ws": 19933
}
}
}
\ No newline at end of file
......@@ -31,7 +31,9 @@ Please read [Developer documentation] before contribute.
2. Ensure that you respect the [commit naming conventions].
3. Ensure that all automated tests pass with the `npm test` command.
3. Ensure that all automated tests pass with the `cargo test` command.
3. Ensure that the code is well formated `cargo fmt` and comply with the good practices `cargo clippy`. If you have been working on tests, check everything with `cargo clippy --all --tests`.
4. Update the documentation with details of changes to the interface, this includes new environment
variables, exposed ports, useful file locations and container parameters.
......
......@@ -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>
......@@ -20,6 +20,7 @@ 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;
......
......@@ -22,6 +22,7 @@ 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;
......
# 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`.
......@@ -55,8 +55,8 @@ Each scenario is a list of steps. In our context (blockchain), only the `When` a
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
......@@ -96,7 +96,7 @@ Amounts must be expressed as an integer of `ĞD` or `UD`, decimal numbers are no
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
### Genesis state
Each scenario bootstraps its own blockchain with its own genesis state.
......@@ -117,17 +117,22 @@ For some scenarios, you may need to perform an action (When) that fails voluntar
### 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 founds
When alice send 5 ĞD to dave
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
"""
......@@ -9,13 +9,13 @@ Feature: Balance transfer
"""
Then dave should have 2 ĞD
Scenario: Create a new account without enough founds then retry with enough founds
When alice send 2 ĞD to eve
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 Evec account
because Eve not have enough founds to pay the new account tax
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
......@@ -27,7 +27,7 @@ Feature: Balance transfer
Then eve should have 2 ĞD
@ignoreErrors
Scenario: Create a new account without any founds
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
......
......@@ -119,7 +119,7 @@ fn parse_amount(amount: u64, unit: &str) -> (u64, bool) {
}
}
#[given(regex = r"([a-zA-Z]+) have (\d+) (ĞD|cĞD|UD|mUD)")]
#[given(regex = r"([a-zA-Z]+) ha(?:ve|s) (\d+) (ĞD|cĞD|UD|mUD)")]
async fn who_have(world: &mut DuniterWorld, who: String, amount: u64, unit: String) -> Result<()> {
// Parse inputs
let who = AccountKeyring::from_str(&who).expect("unknown to");
......@@ -149,7 +149,7 @@ async fn n_blocks_later(world: &mut DuniterWorld, n: usize) -> Result<()> {
Ok(())
}
#[when(regex = r"([a-zA-Z]+) send (\d+) (ĞD|cĞD|UD|mUD) to ([a-zA-Z]+)")]
#[when(regex = r"([a-zA-Z]+) sends? (\d+) (ĞD|cĞD|UD|mUD) to ([a-zA-Z]+)")]
async fn transfer(
world: &mut DuniterWorld,
from: String,
......
......@@ -400,5 +400,10 @@
"tokenSymbol": "ĞD"
},
"protocolId": null,
"telemetryEndpoints": null
"telemetryEndpoints": [
[
"wss://telemetry.polkadot.io/submit/",
0
]
]
}
......@@ -17,7 +17,7 @@
use super::*;
use crate::mock::*;
use crate::MemberData;
use frame_support::{assert_err, assert_ok};
use frame_support::{assert_noop, assert_ok};
use sp_runtime::testing::UintAuthorityId;
const EMPTY: Vec<u64> = Vec::new();
......@@ -249,7 +249,7 @@ fn test_too_many_authorities() {
UintAuthorityId(15).into(),
));
assert_eq!(AuthorityMembers::authorities_counter(), 4);
assert_err!(
assert_noop!(
AuthorityMembers::go_online(Origin::signed(15)),
Error::<Test>::TooManyAuthorities,
);
......
......@@ -249,7 +249,20 @@ impl<T: Config<I>, I: 'static> pallet_identity::traits::OnIdtyChange<T> for Pall
}
IdtyEvent::Confirmed => {}
IdtyEvent::Validated => {}
IdtyEvent::Removed => {}
IdtyEvent::Removed { status } => {
if status != IdtyStatus::Validated {
if let Err(e) =
<pallet_certification::Pallet<T, I>>::remove_all_certs_received_by(
frame_system::Origin::<T>::Root.into(),
idty_index,
)
{
sp_std::if_std! {
println!("fail to remove certs received by some idty: {:?}", e)
}
}
}
}
}
0
}
......
......@@ -16,7 +16,7 @@
use crate::mock::Identity;
use crate::mock::*;
use frame_support::assert_err;
use frame_support::assert_noop;
use frame_support::assert_ok;
use frame_support::instances::Instance1;
use frame_system::{EventRecord, Phase};
......@@ -43,7 +43,7 @@ fn test_creator_not_allowed_to_create_idty() {
// Alice should not be able to create an identity before block #2
// because Alice.next_issuable_on = 2
assert_err!(
assert_noop!(
Identity::create_identity(Origin::signed(1), 4),
pallet_identity::Error::<Test>::CreatorNotAllowedToCreateIdty
);
......@@ -81,7 +81,7 @@ fn test_revoke_smiths_them_rejoin() {
// Dave should not be able to re-request membership before the RevocationPeriod end
run_to_block(3);
assert_err!(
assert_noop!(
SmithsMembership::request_membership(Origin::signed(4), crate::MembershipMetaData(4)),
pallet_membership::Error::<Test, crate::Instance2>::MembershipRevokedRecently
);
......@@ -281,9 +281,31 @@ fn test_idty_membership_expire_them_requested() {
assert!(Identity::identity(3).is_none());
// Alice can't renew her cert to Charlie
assert_err!(
assert_noop!(
Cert::add_cert(Origin::signed(1), 3),
pallet_certification::Error::<Test, Instance1>::ReceiverNotFound
);
});
}
#[test]
fn test_unvalidated_idty_certs_removal() {
new_test_ext(5, 2).execute_with(|| {
// Alice creates Ferdie identity
run_to_block(2);
assert_ok!(Identity::create_identity(Origin::signed(1), 6));
// Ferdie confirms his identity
run_to_block(3);
assert_ok!(Identity::confirm_identity(
Origin::signed(6),
IdtyName::from("Ferdie"),
));
// After PendingMembershipPeriod, Ferdie identity should expire
// and his received certifications should be removed
assert_eq!(Cert::certs_by_receiver(6).len(), 1);
run_to_block(6);
assert_eq!(Cert::certs_by_receiver(6).len(), 0);
});
}
......@@ -525,7 +525,12 @@ pub mod pallet {
Identities::<T>::remove(idty_index);
frame_system::Pallet::<T>::dec_sufficients(&idty_val.owner_key);
Self::deposit_event(Event::IdtyRemoved { idty_index });
T::OnIdtyChange::on_idty_change(idty_index, IdtyEvent::Removed);
T::OnIdtyChange::on_idty_change(
idty_index,
IdtyEvent::Removed {
status: idty_val.status,
},
);
}
0
}
......
......@@ -17,7 +17,7 @@
use crate::mock::*;
use crate::{Error, GenesisIdty, IdtyName, IdtyValue, RevocationPayload};
use codec::Encode;
//use frame_support::assert_err;
//use frame_support::assert_noop;
use frame_support::assert_ok;
use frame_system::{EventRecord, Phase};
use sp_runtime::testing::TestSignature;
......
......@@ -27,7 +27,7 @@ pub enum IdtyEvent<T: crate::Config> {
Created { creator: T::IdtyIndex },
Confirmed,
Validated,
Removed,
Removed { status: IdtyStatus },
}
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug)]
......
......@@ -91,7 +91,7 @@ macro_rules! pallets_config {
type PalletsOrigin = OriginCaller;
type Call = Call;
type MaximumWeight = MaximumSchedulerWeight;
type ScheduleOrigin = frame_system::EnsureSigned<AccountId>;
type ScheduleOrigin = EnsureRoot<AccountId>;
type OriginPrivilegeCmp = EqualPrivilegeOnly;
type MaxScheduledPerBlock = MaxScheduledPerBlock;
type WeightInfo = pallet_scheduler::weights::SubstrateWeight<Runtime>;
......
......@@ -18,7 +18,7 @@ mod common;
use common::*;
use frame_support::traits::{PalletInfo, StorageInfo, StorageInfoTrait};
use frame_support::{assert_err, assert_ok};
use frame_support::{assert_noop, assert_ok};
use frame_support::{StorageHasher, Twox128};
use gdev_runtime::*;
use sp_keyring::AccountKeyring;
......@@ -295,7 +295,7 @@ fn test_create_new_account() {
// We can't remove the account until the random id is assigned
run_to_block(4);
assert_err!(
assert_noop!(
Balances::transfer(
frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(),
MultiAddress::Id(AccountKeyring::Alice.to_account_id()),
......
......@@ -4,7 +4,7 @@ description = "Duniter-v2s xtask"
edition = "2018"
license = "AGPL-3.0"
name = "xtask"
repository = "https://git.duniter.org/nodes/typescript/duniter"
repository = "https://git.duniter.org/nodes/rust/duniter-v2s"
version = "0.1.0"
[[bin]]
......