Skip to content
Snippets Groups Projects
Commit c05977f9 authored by Pascal Engélibert's avatar Pascal Engélibert :bicyclist:
Browse files

wip

parent b8f94157
No related branches found
No related tags found
No related merge requests found
Pipeline #17329 failed
Showing
with 885 additions and 10 deletions
......@@ -819,6 +819,8 @@ dependencies = [
"pallet-babe",
"pallet-balances",
"pallet-certification",
"pallet-distance",
"pallet-distance-rpc-runtime-api",
"pallet-duniter-account",
"pallet-duniter-wot",
"pallet-grandpa",
......@@ -1472,6 +1474,8 @@ dependencies = [
"maplit",
"memmap2 0.5.0",
"pallet-certification",
"pallet-distance-rpc",
"pallet-distance-rpc-runtime-api",
"pallet-grandpa",
"pallet-transaction-payment-rpc",
"pallet-transaction-payment-rpc-runtime-api",
......@@ -2419,6 +2423,8 @@ dependencies = [
"pallet-balances",
"pallet-certification",
"pallet-collective",
"pallet-distance",
"pallet-distance-rpc-runtime-api",
"pallet-duniter-account",
"pallet-duniter-test-parameters",
"pallet-duniter-wot",
......@@ -2905,13 +2911,13 @@ dependencies = [
[[package]]
name = "http"
version = "0.2.4"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
dependencies = [
"bytes",
"fnv",
"itoa 0.4.7",
"itoa 1.0.1",
]
[[package]]
......@@ -5028,6 +5034,55 @@ dependencies = [
"sp-std",
]
[[package]]
name = "pallet-distance"
version = "1.0.0"
dependencies = [
"frame-support",
"frame-system",
"pallet-authority-members",
"pallet-certification",
"pallet-identity",
"pallet-membership",
"pallet-session",
"parity-scale-codec",
"scale-info",
"sp-core",
"sp-inherents",
"sp-runtime",
"sp-std",
]
[[package]]
name = "pallet-distance-rpc"
version = "1.0.0"
dependencies = [
"frame-support",
"frame-system",
"jsonrpsee 0.14.0",
"pallet-distance-rpc-runtime-api",
"parity-scale-codec",
"scale-info",
"serde",
"sp-api",
"sp-blockchain",
"sp-core",
"sp-rpc",
"sp-runtime",
"sp-std",
]
[[package]]
name = "pallet-distance-rpc-runtime-api"
version = "1.0.0"
dependencies = [
"frame-support",
"pallet-distance",
"parity-scale-codec",
"sp-api",
"sp-runtime",
]
[[package]]
name = "pallet-duniter-account"
version = "3.0.0"
......@@ -9374,9 +9429,9 @@ version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if 0.1.10",
"cfg-if 1.0.0",
"digest 0.10.3",
"rand 0.7.3",
"rand 0.8.4",
"static_assertions",
]
......
......@@ -59,6 +59,8 @@ g1-runtime = { path = 'runtime/g1', optional = true }
gdev-runtime = { path = 'runtime/gdev', optional = true }
gtest-runtime = { path = 'runtime/gtest', optional = true }
pallet-certification = { path = 'pallets/certification' }
pallet-distance-rpc = { path = 'pallets/distance/rpc' }
pallet-distance-rpc-runtime-api = { path = 'pallets/distance/rpc/runtime-api' }
sp-membership = { path = 'primitives/membership' }
# crates.io dependencies
......@@ -128,6 +130,9 @@ members = [
'end2end-tests',
'live-tests',
'pallets/certification',
'pallets/distance',
'pallets/distance/rpc',
'pallets/distance/rpc/runtime-api',
'pallets/duniter-test-parameters',
'pallets/duniter-test-parameters/macro',
'pallets/duniter-wot',
......
......@@ -56,6 +56,7 @@ where
C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
C::Api: BlockBuilder<Block>,
//C::Api: pallet_distance_runtime_api::DistanceApi<Block>,
P: TransactionPool + 'static,
{
use manual_seal::rpc::{ManualSeal, ManualSealApiServer};
......@@ -83,6 +84,9 @@ where
// `YourRpcStruct` should have a reference to a client, which is needed
// to call into the runtime.
// `module.merge(YourRpcTrait::into_rpc(YourRpcStruct::new(ReferenceToClient, ...)))?;`
/*module.merge(pallet_distance_rpc::DistanceApi::into_rpc(
pallet_distance_rpc::Distance::new(client),
))?;*/
Ok(module)
}
......@@ -29,13 +29,13 @@ mod tests;
/*#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;*/
pub use self::traits::*;
pub use pallet::*;
pub use sp_staking::SessionIndex;
pub use types::*;
use self::traits::*;
use frame_support::traits::Get;
use sp_runtime::traits::Convert;
use sp_staking::SessionIndex;
use sp_std::prelude::*;
#[frame_support::pallet]
......
[package]
authors = ['tuxmain <tuxmain@zettascript.org>']
description = 'FRAME pallet distance.'
edition = '2021'
homepage = 'https://duniter.org'
license = 'AGPL-3.0'
name = 'pallet-distance'
readme = 'README.md'
repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
version = '1.0.0'
[features]
default = ['std']
std = [
'codec/std',
'frame-support/std',
'frame-system/std',
'pallet-session/std',
'sp-core/std',
'sp-runtime/std',
'sp-std/std',
]
[dependencies]
pallet-authority-members = { path = "../authority-members", default-features = false }
pallet-certification = { path = "../certification", default-features = false }
pallet-identity = { path = "../identity", default-features = false }
pallet-membership = { path = "../membership", default-features = false }
# substrate
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
[dependencies.codec]
default-features = false
features = ['derive']
package = 'parity-scale-codec'
version = '3.1.5'
[dependencies.frame-support]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-system]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.pallet-session]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-core]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-inherents]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-runtime]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-std]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
### DOC ###
[package.metadata.docs.rs]
targets = ['x86_64-unknown-linux-gnu']
[package]
authors = ['tuxmain <tuxmain@zettascript.org>']
description = 'FRAME pallet distance RPC.'
edition = '2018'
homepage = 'https://substrate.dev'
license = 'AGPL-3.0'
name = 'pallet-distance-rpc'
readme = 'README.md'
repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
version = '1.0.0'
[dependencies]
pallet-distance-rpc-runtime-api = { path = "./runtime-api" }
serde = { version = "1.0", features = ["derive"] }
# substrate
jsonrpsee = { version = "0.14.0", features = ["server", "macros"] }
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
[dependencies.codec]
default-features = false
features = ['derive']
package = 'parity-scale-codec'
version = '3.1.5'
[dependencies.frame-support]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-system]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-api]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-blockchain]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-core]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-rpc]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-runtime]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-std]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
### DOC ###
[package.metadata.docs.rs]
targets = ['x86_64-unknown-linux-gnu']
[package]
authors = ['tuxmain <tuxmain@zettascript.org>']
description = 'FRAME pallet distance RPC runtime API.'
edition = '2018'
homepage = 'https://substrate.dev'
license = 'AGPL-3.0'
name = 'pallet-distance-rpc-runtime-api'
readme = 'README.md'
repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
version = '1.0.0'
[dependencies]
pallet-distance = { path = "../../", default-features = false }
sp-api = { git = "https://github.com/duniter/substrate", branch = "duniter-substrate-v0.9.26", default-features = false }
sp-runtime = { git = "https://github.com/duniter/substrate", branch = "duniter-substrate-v0.9.26", default-features = false }
[dependencies.codec]
default-features = false
features = ['derive']
package = 'parity-scale-codec'
version = '3.1.5'
[dependencies.frame-support]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.26'
[features]
default = ["std"]
std = [
"sp-api/std",
]
#![cfg_attr(not(feature = "std"), no_std)]
pub use pallet_distance::{ComputationMetadata, ComputationResult};
use codec::{Decode, Encode};
use frame_support::pallet_prelude::*;
// Here we declare the runtime API. It is implemented it the `impl` block in
// runtime amalgamator file (the `runtime/src/lib.rs`)
sp_api::decl_runtime_apis! {
pub trait DistanceApi<IdtyIndex: Decode + Encode + PartialEq + TypeInfo> {
fn get_computation_metadata() -> Option<ComputationMetadata>;
fn publish_computation_result(computation_result: ComputationResult<IdtyIndex>);
}
}
// 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 std::sync::Arc;
use codec::{Decode, Encode};
use frame_support::pallet_prelude::*;
use jsonrpsee::{
core::{async_trait, RpcResult},
proc_macros::rpc,
types::error::{CallError, ErrorObject},
};
use serde::{Deserialize, Serialize};
use sp_api::ProvideRuntimeApi;
use sp_blockchain::HeaderBackend;
use sp_core::Bytes;
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
pub use pallet_distance_rpc_runtime_api::{ComputationResult, DistanceApi as DistanceRuntimeApi};
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ComputationMetadata /*<Hash>*/ {
//pub block_hash: Hash,
}
impl From<pallet_distance_rpc_runtime_api::ComputationMetadata> for ComputationMetadata {
fn from(_val: pallet_distance_rpc_runtime_api::ComputationMetadata) -> Self {
Self {}
}
}
/*#[derive(Clone, Serialize, Deserialize)]
pub struct ComputationResult {
}
impl Into<pallet_distance_rpc_runtime_api::ComputationResult> for ComputationResult {
fn into(self) -> pallet_distance_rpc_runtime_api::ComputationResult {
pallet_distance_rpc_runtime_api::ComputationResult{}
}
}*/
#[rpc(client, server)]
pub trait DistanceApi<BlockHash, ResponseType> {
#[method(name = "distance_getComputationMetadata")]
fn get_computation_metadata(
&self,
at: Option<BlockHash>,
) -> RpcResult<Option<ComputationMetadata>>;
#[method(name = "distance_publishComputationResult")]
fn publish_computation_result(
&self,
encoded_computation_result: Bytes,
at: Option<BlockHash>,
) -> RpcResult<ResponseType>;
}
/// Provides RPC methods to query a dispatchable's class, weight and fee.
pub struct Distance<C, P> {
/// Shared reference to the client.
client: Arc<C>,
_marker: std::marker::PhantomData<P>,
}
impl<C, P> Distance<C, P> {
/// Creates a new instance of the Distance Rpc helper.
pub fn new(client: Arc<C>) -> Self {
Self {
client,
_marker: Default::default(),
}
}
}
/// Error type of this RPC api.
pub enum Error {
/// The transaction was not decodable.
DecodeError,
/// The call to runtime failed.
RuntimeError,
}
impl From<Error> for i32 {
fn from(e: Error) -> i32 {
match e {
Error::RuntimeError => 1,
Error::DecodeError => 2,
}
}
}
#[async_trait]
impl<C, Block, IdtyIndex: 'static + Decode + Encode + PartialEq + Send + Sync + TypeInfo>
DistanceApiServer<<Block as BlockT>::Hash, ()> for Distance<C, (Block, IdtyIndex)>
where
Block: BlockT,
C: ProvideRuntimeApi<Block> + HeaderBackend<Block> + Send + Sync + 'static,
C::Api: DistanceRuntimeApi<Block, IdtyIndex>,
{
fn get_computation_metadata(
&self,
at: Option<Block::Hash>,
) -> RpcResult<Option<ComputationMetadata>> {
let api = self.client.runtime_api();
let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));
api.get_computation_metadata(&at).map_or_else(
|e| {
Err(CallError::Custom(ErrorObject::owned(
Error::RuntimeError.into(),
"Unable to query dispatch info.",
Some(e.to_string()),
))
.into())
},
|v| Ok(v.map(Into::into)),
)
}
fn publish_computation_result(
&self,
encoded_computation_result: Bytes,
at: Option<Block::Hash>,
) -> RpcResult<()> {
let api = self.client.runtime_api();
let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));
let computation_result: ComputationResult<IdtyIndex> =
Decode::decode(&mut &*encoded_computation_result).map_err(|e| {
CallError::Custom(ErrorObject::owned(
Error::DecodeError.into(),
"Unable to query dispatch info.",
Some(format!("{:?}", e)),
))
})?;
api.publish_computation_result(&at, computation_result)
.map_err(|e| {
CallError::Custom(ErrorObject::owned(
Error::RuntimeError.into(),
"Unable to query dispatch info.",
Some(e.to_string()),
))
.into()
})
}
}
// Copyright 2021 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/>.
#![cfg_attr(not(feature = "std"), no_std)]
mod median;
mod types;
use median::*;
pub use pallet::*;
pub use types::*;
use frame_support::traits::StorageVersion;
use pallet_authority_members::SessionIndex;
use sp_inherents::{InherentData, InherentIdentifier};
use sp_std::convert::TryInto;
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"distanc0";
type IdtyIndex = u32;
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use sp_runtime::Perbill;
/// The current storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::storage_version(STORAGE_VERSION)]
#[pallet::without_storage_info]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
#[pallet::config]
pub trait Config<I: 'static = ()>:
frame_system::Config
+ pallet_certification::Config<I, IdtyIndex = IdtyIndex>
+ pallet_identity::Config<IdtyIndex = IdtyIndex>
+ pallet_session::Config
{
/// Number of sessions before starting a new computation
type FinalityLag: Get<u32>;
/// Duration of a computation (in sessions)
type ComputationMaxDelay: Get<u32>;
/// Maximum number of identities in the evaluation queue
type QueueSize: Get<Option<u32>>;
/// Maximum number of identities to be evaluated in a session
type MaxEvaluationsPerSession: Get<u32>;
/// Minimum ratio of accessible referees
type MinAccessibleReferees: Get<Perbill>;
}
// STORAGE //
/// Identities to be evaluated in next sessions
#[pallet::storage]
pub type EvaluationQueue<T: Config<I>, I: 'static = ()> = CountedStorageMap<
_,
Twox64Concat,
<T as pallet_certification::Config<I>>::IdtyIndex,
(),
OptionQuery,
GetDefault,
<T as Config<I>>::QueueSize,
>;
/*#[pallet::storage]
pub type IdentitiesBeingEvaluated<T: Config<I>, I: 'static = ()> =
StorageValue<_, Vec<<T as pallet_certification::Config<I>>::IdtyIndex>, OptionQuery>;*/
/// Number of evaluators coming up with some value.
/// Indexed by identity index, then by value.
#[pallet::storage]
pub type EvaluatedIdentities<T: Config<I>, I: 'static = ()> = StorageMap<
_,
Twox64Concat,
<T as pallet_certification::Config<I>>::IdtyIndex,
MedianAcc<Perbill>,
OptionQuery,
GetDefault,
>;
/*/// Number of evaluators coming up with some referee count, indexed by referee count.
#[pallet::storage]
pub type Referees<T: Config<I>, I: 'static = ()> = StorageValue<_, MedianAcc<u32>, OptionQuery>;*/
#[pallet::error]
pub enum Error<T, I = ()> {
IdentityNotInEvaluation,
IdtyNotFound,
NonEligibleForEvaluation,
QueueFull,
UnauthorizedIdentity,
}
#[pallet::hooks]
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {}
// CALLS //
#[pallet::call]
impl<T: Config<I>, I: 'static> Pallet<T, I> {
#[pallet::weight(1_000_000_000)]
pub fn evaluate_distance(
origin: OriginFor<T>,
idty_index: <T as pallet_certification::Config<I>>::IdtyIndex,
) -> DispatchResultWithPostInfo {
let _who = ensure_signed(origin)?;
// TODO check whether origin is authorized to request evaluation
// TODO (maybe) check whether identity is already in queue
// TODO sort queue chronologically
if let Some(queue_size) = <T as Config<I>>::QueueSize::get() {
ensure!(
EvaluationQueue::<T, I>::count() < queue_size,
Error::<T, I>::QueueFull
);
}
ensure!(
pallet_identity::Identities::<T>::contains_key(idty_index),
Error::<T, I>::IdtyNotFound
);
EvaluationQueue::<T, I>::insert(idty_index, ());
Ok(().into())
}
#[pallet::weight(1_000_000_000)]
pub fn update_evaluation(
origin: OriginFor<T>,
computation_result: ComputationResult<<T as pallet_identity::Config>::IdtyIndex>,
) -> DispatchResult {
ensure_none(origin)?;
//assert!(!DidUpdate::<T>::exists(), "At most one distance computation result can be submitted per block");
for (identity, result) in computation_result.identities {
EvaluatedIdentities::<T, I>::try_mutate::<_, _, Error<T, I>, _>(
identity,
|median_acc| {
median_acc
.as_mut()
.ok_or(Error::<T, I>::IdentityNotInEvaluation)?
.push(result);
Ok(())
},
)?;
}
Ok(())
}
}
// PUBLIC FUNCTIONS //
impl<T: Config<I>, I: 'static> Pallet<T, I> {
pub fn get_computation_metadata(
) -> Option<ComputationMetadata /*<<T as frame_system::Config>::Hash>*/> {
None
}
pub fn publish_computation_result(
_computation_result: ComputationResult<<T as pallet_identity::Config>::IdtyIndex>,
) {
}
}
// INTERNAL FUNCTIONS //
impl<T: Config<I>, I: 'static> Pallet<T, I> {}
impl<T: Config<I>, I: 'static> pallet_authority_members::OnNewSession for Pallet<T, I> {
fn on_new_session(index: SessionIndex) -> Weight {
match index % 3 {
0 => {
EvaluationQueue::<T, I>::drain()
.zip(0..<T as Config<I>>::MaxEvaluationsPerSession::get())
.map(|((identity, _), _)| identity)
.for_each(|identity| {
EvaluatedIdentities::<T, I>::insert(identity, MedianAcc::new())
});
}
1 => {}
2 => {
for (_identity, median_acc) in EvaluatedIdentities::<T, I>::drain() {
if let Some(median_result) = median_acc.get_median() {
let median = match median_result {
MedianResult::One(m) => m,
MedianResult::Two(m1, m2) => m1 + (m2 - m1) / 2, // Avoid overflow (since max is 1)
};
if median >= T::MinAccessibleReferees::get() {
todo!();
} else {
todo!();
}
}
}
}
_ => unreachable!("index % 3 < 3"),
}
0
}
}
#[pallet::inherent]
impl<T: Config<I>, I: 'static> ProvideInherent for Pallet<T, I> {
type Call = Call<T, I>;
type Error = InherentError;
const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
fn create_inherent(data: &InherentData) -> Option<Self::Call> {
let inherent_data = data
.get_data::<ComputationResult<<T as pallet_identity::Config>::IdtyIndex>>(
&INHERENT_IDENTIFIER,
)
.expect("Distance inherent data not correctly encoded")
.expect("Distance inherent data must be provided");
Some(Call::update_evaluation {
computation_result: inherent_data,
})
}
fn is_inherent(_call: &Self::Call) -> bool {
true
}
}
}
// Copyright 2021 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 frame_support::pallet_prelude::*;
use sp_std::{cmp::Ordering, vec::Vec};
#[derive(Clone, Debug, Decode, Default, Encode, TypeInfo)]
pub struct MedianAcc<T: Clone + Decode + Encode + Ord + TypeInfo> {
samples: Vec<(T, u32)>,
median_index: Option<u32>,
median_subindex: u32,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum MedianResult<T: Clone + Ord> {
One(T),
Two(T, T),
}
impl<T: Clone + Decode + Encode + Ord + TypeInfo> MedianAcc<T> {
pub fn new() -> Self {
Self {
samples: Vec::new(),
median_index: None,
median_subindex: 0,
}
}
pub fn push(&mut self, sample: T) {
if let Some(median_index) = &mut self.median_index {
match self
.samples
.binary_search_by_key(&sample, |(s, _n)| s.clone())
{
Ok(sample_index) => {
self.samples.get_mut(sample_index).expect("unreachable").1 += 1;
match (sample_index as u32).cmp(median_index) {
Ordering::Greater => {
if self.median_subindex
== self
.samples
.get(*median_index as usize)
.expect("unreachable")
.1
* 2
- 1
{
self.median_subindex = 0;
*median_index += 1;
} else {
self.median_subindex += 1;
}
}
Ordering::Equal => {
self.median_subindex += 1;
}
Ordering::Less => {
if self.median_subindex == 0 {
*median_index -= 1;
self.median_subindex = self
.samples
.get(*median_index as usize)
.expect("unreachable")
.1
* 2
- 1;
} else {
self.median_subindex -= 1;
}
}
}
}
Err(sample_index) => {
self.samples.insert(sample_index, (sample, 1));
if *median_index as usize >= sample_index {
if self.median_subindex == 0 {
self.median_subindex = self
.samples
.get(*median_index as usize)
.expect("unreachable")
.1
* 2
- 1;
} else {
self.median_subindex -= 1;
*median_index += 1;
}
} else if self.median_subindex
== self
.samples
.get(*median_index as usize)
.expect("unreachable")
.1
* 2
- 1
{
self.median_subindex = 0;
*median_index += 1;
} else {
self.median_subindex += 1;
}
}
}
} else {
self.samples.push((sample, 1));
self.median_index = Some(0);
}
}
pub fn get_median(&self) -> Option<MedianResult<T>> {
self.median_index.map(|median_index| {
let (median_sample, median_n) = self
.samples
.get(median_index as usize)
.expect("unreachable");
if self.median_subindex == median_n * 2 - 1 {
MedianResult::Two(
median_sample.clone(),
self.samples
.get(median_index as usize + 1)
.expect("unreachable")
.0
.clone(),
)
} else {
MedianResult::One(median_sample.clone())
}
})
}
}
// Copyright 2021 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 codec::{Decode, Encode};
use frame_support::pallet_prelude::*;
use sp_inherents::IsFatalError;
use sp_runtime::Perbill;
use sp_std::vec::Vec;
#[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug, TypeInfo)]
pub struct ComputationMetadata /*<Hash>*/ {
//pub block_hash: Hash,
}
#[derive(Clone, Decode, Encode, PartialEq, RuntimeDebug, TypeInfo)]
pub struct ComputationResult<IdtyIndex: Decode + Encode + PartialEq + TypeInfo> {
pub identities: Vec<(IdtyIndex, Perbill)>,
}
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
pub enum InherentError {
Foo,
}
impl IsFatalError for InherentError {
fn is_fatal_error(&self) -> bool {
false
}
}
No preview for this file type
......@@ -33,6 +33,8 @@ std = [
'pallet-babe/std',
'pallet-balances/std',
'pallet-certification/std',
'pallet-distance/std',
'pallet-distance-rpc-runtime-api/std',
'pallet-duniter-account/std',
'pallet-duniter-wot/std',
'pallet-grandpa/std',
......@@ -65,6 +67,8 @@ try-runtime = [
duniter-primitives = { path = '../../primitives/duniter', default-features = false }
pallet-authority-members = { path = '../../pallets/authority-members', default-features = false }
pallet-certification = { path = '../../pallets/certification', default-features = false }
pallet-distance = { path = "../../pallets/distance", default-features = false }
pallet-distance-rpc-runtime-api = { path = "../../pallets/distance/rpc/runtime-api", default-features = false }
pallet-duniter-account = { path = '../../pallets/duniter-account', default-features = false }
pallet-duniter-wot = { path = '../../pallets/duniter-wot', default-features = false }
pallet-identity = { path = '../../pallets/identity', default-features = false }
......
......@@ -208,6 +208,15 @@ macro_rules! runtime_apis {
TransactionPayment::query_fee_details(uxt, len)
}
}
impl pallet_distance_rpc_runtime_api::DistanceApi<Block, u32> for Runtime {
fn get_computation_metadata() -> Option<pallet_distance_rpc_runtime_api::ComputationMetadata/*<<T as frame_system::Config>::Hash>*/>
{
Distance::get_computation_metadata()
}
fn publish_computation_result(computation_result: pallet_distance_rpc_runtime_api::ComputationResult<u32>) {
Distance::publish_computation_result(computation_result)
}
}
#[cfg(feature = "try-runtime")]
impl frame_try_runtime::TryRuntime<Block> for Runtime {
......
......@@ -27,11 +27,11 @@ use sp_runtime::traits::IsMember;
pub struct OnNewSessionHandler<Runtime>(core::marker::PhantomData<Runtime>);
impl<Runtime> pallet_authority_members::traits::OnNewSession for OnNewSessionHandler<Runtime>
where
Runtime: pallet_provide_randomness::Config,
Runtime: pallet_provide_randomness::Config + pallet_distance::Config<Instance1>,
{
fn on_new_session(_index: sp_staking::SessionIndex) -> Weight {
fn on_new_session(index: sp_staking::SessionIndex) -> Weight {
pallet_provide_randomness::Pallet::<Runtime>::on_new_epoch();
0
pallet_distance::Pallet::<Runtime, Instance1>::on_new_session(index)
}
}
......
......@@ -468,6 +468,17 @@ macro_rules! pallets_config {
type OnRemovedCert = Wot;
type ValidityPeriod = ValidityPeriod;
}
parameter_types! {
pub const MinAccessibleReferees: Perbill = Perbill::from_percent(80);
}
impl pallet_distance::Config<Instance1> for Runtime {
//type IdtyIndex: IdtyIndex;
type FinalityLag = frame_support::traits::ConstU32<1>;
type ComputationMaxDelay = frame_support::traits::ConstU32<1>;
type QueueSize = frame_support::traits::ConstU32<800>;
type MaxEvaluationsPerSession = frame_support::traits::ConstU32<100>;
type MinAccessibleReferees = MinAccessibleReferees;
}
// SMITHS SUB-WOT //
......
......@@ -63,6 +63,8 @@ std = [
'pallet-balances/std',
'pallet-certification/std',
'pallet-collective/std',
'pallet-distance/std',
'pallet-distance-rpc-runtime-api/std',
'pallet-duniter-test-parameters/std',
'pallet-duniter-account/std',
'pallet-duniter-wot/std',
......@@ -136,6 +138,8 @@ sp-keyring = { git = 'https://github.com/duniter/substrate', branch = 'duniter-s
common-runtime = { path = "../common", default-features = false }
pallet-authority-members = { path = '../../pallets/authority-members', default-features = false }
pallet-certification = { path = '../../pallets/certification', default-features = false }
pallet-distance = { path = "../../pallets/distance", default-features = false }
pallet-distance-rpc-runtime-api = { path = "../../pallets/distance/rpc/runtime-api", default-features = false }
pallet-duniter-test-parameters = { path = '../../pallets/duniter-test-parameters', default-features = false }
pallet-duniter-account = { path = '../../pallets/duniter-account', default-features = false }
pallet-duniter-wot = { path = '../../pallets/duniter-wot', default-features = false }
......
......@@ -313,6 +313,7 @@ construct_runtime!(
Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 41,
Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 42,
Cert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 43,
Distance: pallet_distance::<Instance1>::{Call, Storage} = 44,
// Smiths Sub-Wot
SmithsSubWot: pallet_duniter_wot::<Instance2>::{Pallet} = 50,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment