diff --git a/.helix/config.toml b/.helix/config.toml new file mode 100644 index 0000000..053d9dc --- /dev/null +++ b/.helix/config.toml @@ -0,0 +1,7 @@ +[editor.lsp] +display-inlay-hints = true + + + [keys.normal.space] + "H" = ":toggle lsp.display-inlay-hints" + diff --git a/Cargo.lock b/Cargo.lock index 98cf827..1dac883 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1523,6 +1523,27 @@ dependencies = [ "sp-runtime", ] +[[package]] +name = "department-funding-rpc" +version = "0.1.0" +dependencies = [ + "department-funding-runtime-api", + "jsonrpsee", + "sc-rpc", + "sc-rpc-api", + "sp-api", + "sp-blockchain", + "sp-runtime", +] + +[[package]] +name = "department-funding-runtime-api" +version = "0.1.0" +dependencies = [ + "frame-support", + "sp-api", +] + [[package]] name = "der" version = "0.6.1" @@ -4492,6 +4513,8 @@ name = "node-template" version = "4.0.0-dev" dependencies = [ "clap", + "department-funding-rpc", + "department-funding-runtime-api", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", diff --git a/node/Cargo.toml b/node/Cargo.toml index 249e2e6..f2fde94 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -70,6 +70,12 @@ profile-validation-runtime-api = {path="../pallets/profile-validation/profile-va profile-validation-rpc = { path="../pallets/profile-validation/profile-validation-rpc", default-features = false} +# Department funding rpc +department-funding-runtime-api = {path="../pallets/department-funding/department-funding-runtime-api", default-features = false} +department-funding-rpc= { path="../pallets/department-funding/department-funding-rpc", default-features = false} + + + [build-dependencies] substrate-build-script-utils = { version = "3.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } diff --git a/pallets/department-funding/department-funding-rpc/Cargo.toml b/pallets/department-funding/department-funding-rpc/Cargo.toml new file mode 100644 index 0000000..3b6101a --- /dev/null +++ b/pallets/department-funding/department-funding-rpc/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "department-funding-rpc" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +jsonrpsee = { version = "0.16.2", features = ["client-core", "server", "macros"] } +sc-rpc = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-rpc-api = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-runtime = { default-features = false, version = "7.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +department-funding-runtime-api = { default-features= false, path="../department-funding-runtime-api"} \ No newline at end of file diff --git a/pallets/department-funding/department-funding-rpc/src/lib.rs b/pallets/department-funding/department-funding-rpc/src/lib.rs new file mode 100644 index 0000000..4f430cd --- /dev/null +++ b/pallets/department-funding/department-funding-rpc/src/lib.rs @@ -0,0 +1,261 @@ +use jsonrpsee::{ + core::{Error as JsonRpseeError, RpcResult}, + proc_macros::rpc, + types::error::{CallError, ErrorCode, ErrorObject}, +}; +use department_funding_runtime_api::DepartmentFundingApi as DepartmentFundingRuntimeApi; +use sp_api::codec::Codec; +use sp_api::ProvideRuntimeApi; +use sp_blockchain::HeaderBackend; +use sp_runtime::traits::Block as BlockT; +use std::sync::Arc; +type ChallengePostId = u64; +type DepartmentRequiredFundId = u64; + +#[rpc(client, server)] +pub trait DepartmentFundingApi { + #[method(name = "departmentfunding_challengerevidence")] + fn get_challengers_evidence( + &self, + department_required_fund_id: DepartmentRequiredFundId, + offset: u64, + limit: u16, + at: Option, + ) -> RpcResult>; + #[method(name = "departmentfunding_evidenceperiodendblock")] + fn get_evidence_period_end_block( + &self, + department_required_fund_id: DepartmentRequiredFundId, + at: Option, + ) -> RpcResult>; + #[method(name = "departmentfunding_stakingperiodendblock")] + fn get_staking_period_end_block( + &self, + department_required_fund_id: DepartmentRequiredFundId, + at: Option, + ) -> RpcResult>; + #[method(name = "departmentfunding_drawingperiodend")] + fn get_drawing_period_end( + &self, + department_required_fund_id: DepartmentRequiredFundId, + at: Option, + ) -> RpcResult<(u64, u64, bool)>; + #[method(name = "departmentfunding_commitendblock")] + fn get_commit_period_end_block( + &self, + department_required_fund_id: DepartmentRequiredFundId, + at: Option, + ) -> RpcResult>; + #[method(name = "departmentfunding_voteendblock")] + fn get_vote_period_end_block( + &self, + department_required_fund_id: DepartmentRequiredFundId, + at: Option, + ) -> RpcResult>; + #[method(name = "departmentfunding_selectedjuror")] + fn selected_as_juror( + &self, + department_required_fund_id: DepartmentRequiredFundId, + who: AccountId, + at: Option, + ) -> RpcResult; +} + +/// A struct that implements the `SumStorageApi`. +pub struct DepartmentFunding { + // If you have more generics, no need to SumStorage + // just use a tuple like SumStorage + client: Arc, + _marker: std::marker::PhantomData, +} + +impl DepartmentFunding { + /// Create new `SumStorage` instance with the given reference to the client. + pub fn new(client: Arc) -> 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 for i32 { + fn from(e: Error) -> i32 { + match e { + Error::RuntimeError => 1, + Error::DecodeError => 2, + } + } +} + + +impl DepartmentFundingApiServer<::Hash, AccountId> for DepartmentFunding +where + Block: BlockT, + AccountId: Codec, + C: Send + Sync + 'static, + C: ProvideRuntimeApi, + C: HeaderBackend, + C::Api: DepartmentFundingRuntimeApi, +{ + fn get_challengers_evidence( + &self, + department_required_fund_id: DepartmentRequiredFundId, + offset: u64, + limit: u16, + at: Option, + ) -> RpcResult> { + let api = self.client.runtime_api(); + let at = at.unwrap_or_else(|| + // If the block hash is not supplied assume the best block. + self.client.info().best_hash); + + let runtime_api_result = + api.get_challengers_evidence(at, department_required_fund_id, offset, limit); + fn map_err(error: impl ToString, desc: &'static str) -> CallError { + CallError::Custom(ErrorObject::owned( + Error::RuntimeError.into(), + desc, + Some(error.to_string()), + )) + } + let res = runtime_api_result.map_err(|e| map_err(e, "Unable to query dispatch info."))?; + Ok(res) + } + fn get_evidence_period_end_block( + &self, + department_required_fund_id: DepartmentRequiredFundId, + at: Option, + ) -> RpcResult> { + let api = self.client.runtime_api(); + let at = at.unwrap_or_else(|| + // If the block hash is not supplied assume the best block. + self.client.info().best_hash); + + let runtime_api_result = api.get_evidence_period_end_block(at, department_required_fund_id); + fn map_err(error: impl ToString, desc: &'static str) -> CallError { + CallError::Custom(ErrorObject::owned( + Error::RuntimeError.into(), + desc, + Some(error.to_string()), + )) + } + let res = runtime_api_result.map_err(|e| map_err(e, "Unable to query dispatch info."))?; + Ok(res) + } + fn get_staking_period_end_block( + &self, + department_required_fund_id: DepartmentRequiredFundId, + at: Option, + ) -> RpcResult> { + let api = self.client.runtime_api(); + let at = at.unwrap_or_else(|| + // If the block hash is not supplied assume the best block. + self.client.info().best_hash); + + let runtime_api_result = api.get_staking_period_end_block(at, department_required_fund_id); + fn map_err(error: impl ToString, desc: &'static str) -> CallError { + CallError::Custom(ErrorObject::owned( + Error::RuntimeError.into(), + desc, + Some(error.to_string()), + )) + } + let res = runtime_api_result.map_err(|e| map_err(e, "Unable to query dispatch info."))?; + Ok(res) + } + fn get_drawing_period_end( + &self, + department_required_fund_id: DepartmentRequiredFundId, + at: Option, + ) -> RpcResult<(u64, u64, bool)> { + let api = self.client.runtime_api(); + let at = at.unwrap_or_else(|| + // If the block hash is not supplied assume the best block. + self.client.info().best_hash); + + let runtime_api_result = api.get_drawing_period_end(at, department_required_fund_id); + fn map_err(error: impl ToString, desc: &'static str) -> CallError { + CallError::Custom(ErrorObject::owned( + Error::RuntimeError.into(), + desc, + Some(error.to_string()), + )) + } + let res = runtime_api_result.map_err(|e| map_err(e, "Unable to query dispatch info."))?; + Ok(res) + } + + fn get_commit_period_end_block( + &self, + department_required_fund_id: DepartmentRequiredFundId, + at: Option, + ) -> RpcResult> { + let api = self.client.runtime_api(); + let at = at.unwrap_or_else(|| + // If the block hash is not supplied assume the best block. + self.client.info().best_hash); + + let runtime_api_result = api.get_commit_period_end_block(at, department_required_fund_id); + fn map_err(error: impl ToString, desc: &'static str) -> CallError { + CallError::Custom(ErrorObject::owned( + Error::RuntimeError.into(), + desc, + Some(error.to_string()), + )) + } + let res = runtime_api_result.map_err(|e| map_err(e, "Unable to query dispatch info."))?; + Ok(res) + } + + fn get_vote_period_end_block( + &self, + department_required_fund_id: DepartmentRequiredFundId, + at: Option, + ) -> RpcResult> { + let api = self.client.runtime_api(); + let at = at.unwrap_or_else(|| + // If the block hash is not supplied assume the best block. + self.client.info().best_hash); + + let runtime_api_result = api.get_vote_period_end_block(at, department_required_fund_id); + fn map_err(error: impl ToString, desc: &'static str) -> CallError { + CallError::Custom(ErrorObject::owned( + Error::RuntimeError.into(), + desc, + Some(error.to_string()), + )) + } + let res = runtime_api_result.map_err(|e| map_err(e, "Unable to query dispatch info."))?; + Ok(res) + } + + fn selected_as_juror( + &self, + department_required_fund_id: DepartmentRequiredFundId, + who: AccountId, + at: Option, + ) -> RpcResult { + let api = self.client.runtime_api(); + let at = at.unwrap_or_else(|| + // If the block hash is not supplied assume the best block. + self.client.info().best_hash); + + let runtime_api_result = api.selected_as_juror(at, department_required_fund_id, who); + fn map_err(error: impl ToString, desc: &'static str) -> CallError { + CallError::Custom(ErrorObject::owned( + Error::RuntimeError.into(), + desc, + Some(error.to_string()), + )) + } + let res = runtime_api_result.map_err(|e| map_err(e, "Unable to query dispatch info."))?; + Ok(res) + } +} \ No newline at end of file diff --git a/pallets/department-funding/department-funding-runtime-api/Cargo.toml b/pallets/department-funding/department-funding-runtime-api/Cargo.toml new file mode 100644 index 0000000..feb6e7e --- /dev/null +++ b/pallets/department-funding/department-funding-runtime-api/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "department-funding-runtime-api" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +sp-api = { default-features = false, version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +frame-support = { default-features = false, version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42"} + +[features] +default = ["std"] +std = [ + "sp-api/std", + "frame-support/std", +] \ No newline at end of file diff --git a/pallets/department-funding/department-funding-runtime-api/src/lib.rs b/pallets/department-funding/department-funding-runtime-api/src/lib.rs new file mode 100644 index 0000000..1c7f702 --- /dev/null +++ b/pallets/department-funding/department-funding-runtime-api/src/lib.rs @@ -0,0 +1,20 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +// use frame_support::sp_std::{vec::Vec}; +// or +use frame_support::sp_std::{prelude::*}; +use sp_api::codec::Codec; +type ChallengePostId = u64; +type DepartmentRequiredFundId= u64; + +sp_api::decl_runtime_apis! { + pub trait DepartmentFundingApi where AccountId: Codec { + fn get_challengers_evidence(department_required_fund_id: DepartmentRequiredFundId, offset: u64, limit: u16) -> Vec; + fn get_evidence_period_end_block(department_required_fund_id: DepartmentRequiredFundId) -> Option; + fn get_staking_period_end_block(department_required_fund_id: DepartmentRequiredFundId) -> Option; + fn get_drawing_period_end(department_required_fund_id: DepartmentRequiredFundId) -> (u64, u64, bool); + fn get_commit_period_end_block(department_required_fund_id: DepartmentRequiredFundId) -> Option; + fn get_vote_period_end_block(department_required_fund_id: DepartmentRequiredFundId) -> Option; + fn selected_as_juror(department_required_fund_id: DepartmentRequiredFundId, who: AccountId) -> bool; + } +} \ No newline at end of file diff --git a/pallets/department-funding/src/extras.rs b/pallets/department-funding/src/extras.rs index b1016c9..435004c 100644 --- a/pallets/department-funding/src/extras.rs +++ b/pallets/department-funding/src/extras.rs @@ -157,4 +157,118 @@ impl Pallet { }, } } + + pub fn get_evidence_period_end_block(department_required_fund_id: DepartmentRequiredFundId) -> Option { + let now = >::block_number(); + + let block_number = + Self::get_block_number_of_schelling_game(department_required_fund_id).unwrap(); + + let key = SumTreeName::DepartmentRequiredFund { + department_required_fund_id, + block_number: block_number.clone(), + }; + + + let phase_data = Self::get_phase_data(); + + let result = T::SchellingGameSharedSource::get_evidence_period_end_block_helper_link( + key, phase_data, now, + ); + result + + + } + + + // End block code start + + + pub fn get_staking_period_end_block(department_required_fund_id: DepartmentRequiredFundId) -> Option { + let now = >::block_number(); + + let block_number = + Self::get_block_number_of_schelling_game(department_required_fund_id).unwrap(); + + let key = SumTreeName::DepartmentRequiredFund { + department_required_fund_id, + block_number: block_number.clone(), + }; + + let phase_data = Self::get_phase_data(); + + let result = T::SchellingGameSharedSource::get_staking_period_end_block_helper_link( + key, phase_data, now, + ); + result + } + + pub fn get_drawing_period_end(department_required_fund_id: DepartmentRequiredFundId) -> (u64, u64, bool) { + let block_number = + Self::get_block_number_of_schelling_game(department_required_fund_id).unwrap(); + + let key = SumTreeName::DepartmentRequiredFund { + department_required_fund_id, + block_number: block_number.clone(), + }; + let phase_data = Self::get_phase_data(); + + let result = + T::SchellingGameSharedSource::get_drawing_period_end_helper_link(key, phase_data); + result + } + + pub fn get_commit_period_end_block(department_required_fund_id: DepartmentRequiredFundId) -> Option { + let now = >::block_number(); + + let block_number = + Self::get_block_number_of_schelling_game(department_required_fund_id).unwrap(); + + let key = SumTreeName::DepartmentRequiredFund { + department_required_fund_id, + block_number: block_number.clone(), + }; + + let phase_data = Self::get_phase_data(); + + let result = T::SchellingGameSharedSource::get_commit_period_end_block_helper_link( + key, phase_data, now, + ); + result + } + + pub fn get_vote_period_end_block(department_required_fund_id: DepartmentRequiredFundId) -> Option { + let now = >::block_number(); + + let block_number = + Self::get_block_number_of_schelling_game(department_required_fund_id).unwrap(); + + let key = SumTreeName::DepartmentRequiredFund { + department_required_fund_id, + block_number: block_number.clone(), + }; + + let phase_data = Self::get_phase_data(); + + let result = T::SchellingGameSharedSource::get_vote_period_end_block_helper_link( + key, phase_data, now, + ); + result + } + + pub fn selected_as_juror(department_required_fund_id: DepartmentRequiredFundId, who: T::AccountId) -> bool { + let block_number = + Self::get_block_number_of_schelling_game(department_required_fund_id).unwrap(); + + let key = SumTreeName::DepartmentRequiredFund { + department_required_fund_id, + block_number: block_number.clone(), + }; + + let result = T::SchellingGameSharedSource::selected_as_juror_helper_link(key, who); + result + } + + // End block code end + }