From cd6aa1a755face848d4cfe84112384741dc4b630 Mon Sep 17 00:00:00 2001 From: 1xstj <106580853+1xstj@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:58:49 +0000 Subject: [PATCH] fix : fix rpc result response and add tests --- pallets/jobs/rpc/runtime-api/src/lib.rs | 8 +- pallets/jobs/rpc/src/lib.rs | 12 +-- pallets/jobs/src/rpc.rs | 29 ++----- pallets/jobs/src/tests.rs | 104 +++++++++++++++++++++++- primitives/src/jobs/mod.rs | 16 +--- runtime/testnet/src/lib.rs | 6 +- 6 files changed, 122 insertions(+), 53 deletions(-) diff --git a/pallets/jobs/rpc/runtime-api/src/lib.rs b/pallets/jobs/rpc/runtime-api/src/lib.rs index 4a95cab71..145194e97 100644 --- a/pallets/jobs/rpc/runtime-api/src/lib.rs +++ b/pallets/jobs/rpc/runtime-api/src/lib.rs @@ -21,7 +21,7 @@ use parity_scale_codec::Codec; use sp_runtime::{traits::MaybeDisplay, Serialize}; use sp_std::vec::Vec; use tangle_primitives::{ - jobs::{JobId, RpcResponseJobsData, RpcResponsePhaseOneResult}, + jobs::{JobId, PhaseResult, RpcResponseJobsData}, roles::RoleType, }; @@ -59,7 +59,7 @@ sp_api::decl_runtime_apis! { /// An optional `RpcResponseJobsData` containing the account ID of the job. fn query_job_by_id(role_type: RoleType, job_id: JobId) -> Option>>; - /// Queries the phase one result of a job by its key and ID. + /// Queries the result of a job by its role_type and ID. /// /// # Arguments /// @@ -68,8 +68,8 @@ sp_api::decl_runtime_apis! { /// /// # Returns /// - /// An `Option` containing the phase one result of the job, wrapped in an `RpcResponsePhaseOneResult`. - fn query_phase_one_by_id(role_type: RoleType, job_id: JobId) -> Option>>; + /// An `Option` containing the phase one result of the job, wrapped in an `PhaseResult`. + fn query_job_result(role_type: RoleType, job_id: JobId) -> Option>>; /// Queries next job ID. /// diff --git a/pallets/jobs/rpc/src/lib.rs b/pallets/jobs/rpc/src/lib.rs index 0abe1f084..84aa8fee4 100644 --- a/pallets/jobs/rpc/src/lib.rs +++ b/pallets/jobs/rpc/src/lib.rs @@ -30,7 +30,7 @@ use sp_runtime::{ }; use std::sync::Arc; use tangle_primitives::{ - jobs::{JobId, RpcResponseJobsData, RpcResponsePhaseOneResult}, + jobs::{JobId, PhaseResult, RpcResponseJobsData}, roles::RoleType, }; @@ -56,12 +56,12 @@ pub trait JobsApi { ) -> RpcResult>>; #[method(name = "jobs_queryPhaseOneById")] - fn query_phase_one_by_id( + fn query_job_result( &self, at: Option, role_type: RoleType, job_id: JobId, - ) -> RpcResult>>; + ) -> RpcResult>>; #[method(name = "jobs_queryNextJobId")] fn query_next_job_id(&self, at: Option) -> RpcResult; @@ -116,16 +116,16 @@ where } } - fn query_phase_one_by_id( + fn query_job_result( &self, at: Option<::Hash>, role_type: RoleType, job_id: JobId, - ) -> RpcResult>>> { + ) -> RpcResult>>> { let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); - match api.query_phase_one_by_id(at, role_type, job_id) { + match api.query_job_result(at, role_type, job_id) { Ok(res) => Ok(res), Err(e) => Err(runtime_error_into_rpc_err(e)), } diff --git a/pallets/jobs/src/rpc.rs b/pallets/jobs/src/rpc.rs index 0c1867291..4027cf93b 100644 --- a/pallets/jobs/src/rpc.rs +++ b/pallets/jobs/src/rpc.rs @@ -1,6 +1,6 @@ use super::*; pub use tangle_primitives::jobs::RpcResponseJobsData; -use tangle_primitives::{jobs::RpcResponsePhaseOneResult, roles::RoleType}; +use tangle_primitives::{jobs::PhaseResult, roles::RoleType}; impl Pallet { /// Queries jobs associated with a specific validator. @@ -73,31 +73,12 @@ impl Pallet { /// # Returns /// /// An `Option` containing the phase one result of the job, wrapped in an - /// `RpcResponsePhaseOneResult`. - pub fn query_phase_one_by_id( + /// `PhaseResult`. + pub fn query_job_result( role_type: RoleType, job_id: JobId, - ) -> Option>> { - if let Some(job_info) = SubmittedJobs::::get(role_type, job_id) { - if !job_info.job_type.is_phase_one() { - let result = KnownResults::::get( - job_info.job_type.get_role_type(), - job_info.job_type.clone().get_phase_one_id().unwrap(), - ) - .unwrap(); - - let info = RpcResponsePhaseOneResult { - owner: job_info.owner, - result: result.result, - job_type: job_info.job_type, - ttl: job_info.ttl, - }; - - return Some(info) - } - } - - None + ) -> Option>> { + KnownResults::::get(role_type, job_id) } /// Queries next job ID. diff --git a/pallets/jobs/src/tests.rs b/pallets/jobs/src/tests.rs index 3cb948313..d2b1e9bda 100644 --- a/pallets/jobs/src/tests.rs +++ b/pallets/jobs/src/tests.rs @@ -23,7 +23,7 @@ use sp_runtime::AccountId32; use tangle_primitives::{ jobs::{ DKGTSSPhaseOneJobType, DKGTSSPhaseTwoJobType, DKGTSSSignatureResult, DigitalSignatureType, - JobSubmission, JobType, + JobSubmission, JobType, RpcResponseJobsData, }, roles::{RoleType, ThresholdSignatureRoleType}, }; @@ -201,6 +201,108 @@ fn jobs_submission_e2e_works_for_dkg() { }); } +#[test] +fn jobs_rpc_tests() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + + let participants = vec![ALICE, BOB, CHARLIE, DAVE, EVE]; + + let threshold_signature_role_type = ThresholdSignatureRoleType::TssGG20; + let submission = JobSubmission { + expiry: 10, + ttl: 200, + job_type: JobType::DKGTSSPhaseOne(DKGTSSPhaseOneJobType { + participants: participants.clone(), + threshold: 3, + permitted_caller: Some(TEN), + role_type: threshold_signature_role_type, + }), + }; + assert_ok!(Jobs::submit_job(RuntimeOrigin::signed(TEN), submission)); + + let stored_job = + SubmittedJobs::::get(RoleType::Tss(threshold_signature_role_type), 0).unwrap(); + let expected_rpc_response = RpcResponseJobsData { + job_id: 0, + job_type: stored_job.job_type, + ttl: stored_job.ttl, + expiry: stored_job.expiry, + }; + + // query jobs by validator should work + for validator in participants { + assert_eq!( + Jobs::query_jobs_by_validator(validator), + Some(vec![expected_rpc_response.clone()]) + ); + } + + assert_eq!( + Jobs::query_job_by_id(RoleType::Tss(threshold_signature_role_type), 0), + Some(expected_rpc_response) + ); + assert_eq!(Jobs::query_next_job_id(), 1); + + // submit a solution for this job + assert_ok!(Jobs::submit_job_result( + RuntimeOrigin::signed(TEN), + RoleType::Tss(ThresholdSignatureRoleType::TssGG20), + 0, + JobResult::DKGPhaseOne(DKGTSSKeySubmissionResult { + signatures: vec![], + threshold: 3, + participants: vec![], + key: vec![], + signature_type: DigitalSignatureType::Ecdsa + }) + )); + + assert_eq!(Jobs::query_job_by_id(RoleType::Tss(threshold_signature_role_type), 0), None); + assert_eq!(Jobs::query_next_job_id(), 1); + + let expected_result = + KnownResults::::get(RoleType::Tss(ThresholdSignatureRoleType::TssGG20), 0); + assert_eq!( + Jobs::query_job_result(RoleType::Tss(threshold_signature_role_type), 0), + expected_result + ); + + let submission = JobSubmission { + expiry: 10, + ttl: 0, + job_type: JobType::DKGTSSPhaseTwo(DKGTSSPhaseTwoJobType { + phase_one_id: 0, + submission: vec![], + role_type: threshold_signature_role_type, + }), + }; + assert_ok!(Jobs::submit_job(RuntimeOrigin::signed(TEN), submission)); + + let stored_job = + SubmittedJobs::::get(RoleType::Tss(threshold_signature_role_type), 1).unwrap(); + let expected_rpc_response = RpcResponseJobsData { + job_id: 1, + job_type: stored_job.job_type, + ttl: stored_job.ttl, + expiry: stored_job.expiry, + }; + + assert_eq!( + Jobs::query_job_by_id(RoleType::Tss(threshold_signature_role_type), 1), + Some(expected_rpc_response) + ); + assert_eq!(Jobs::query_next_job_id(), 2); + + let expected_result = + KnownResults::::get(RoleType::Tss(ThresholdSignatureRoleType::TssGG20), 1); + assert_eq!( + Jobs::query_job_result(RoleType::Tss(threshold_signature_role_type), 1), + expected_result + ); + }); +} + // TODO : Integrate after zksaas pallet // #[test] // fn jobs_submission_e2e_works_for_zksaas() { diff --git a/primitives/src/jobs/mod.rs b/primitives/src/jobs/mod.rs index b172c0654..05e43f332 100644 --- a/primitives/src/jobs/mod.rs +++ b/primitives/src/jobs/mod.rs @@ -194,6 +194,7 @@ pub enum JobState { /// Represents a job submission with specified `AccountId` and `BlockNumber`. #[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct PhaseResult { /// The owner's account ID. pub owner: AccountId, @@ -256,21 +257,6 @@ pub struct RpcResponseJobsData { pub ttl: BlockNumber, } -#[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct RpcResponsePhaseOneResult { - /// The owner's account ID. - pub owner: AccountId, - /// The type of the job result. - pub result: JobResult, - /// The type of the job submission. - pub job_type: JobType, - - /// The time-to-live (TTL) for the job, which determines the maximum allowed time for this job - /// to be available. After the TTL expires, the job can no longer be used. - pub ttl: BlockNumber, -} - #[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Clone)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum JobResult { diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index a87beae47..1ac99e677 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -70,7 +70,7 @@ use sp_version::RuntimeVersion; use static_assertions::const_assert; pub use tangle_crypto_primitives::crypto::AuthorityId as RoleKeyId; use tangle_primitives::{ - jobs::{JobId, RpcResponseJobsData, RpcResponsePhaseOneResult}, + jobs::{JobId, PhaseResult, RpcResponseJobsData}, roles::RoleType, }; @@ -1413,8 +1413,8 @@ impl_runtime_apis! { Jobs::query_job_by_id(role_type, job_id) } - fn query_phase_one_by_id(role_type: RoleType, job_id: JobId) -> Option>> { - Jobs::query_phase_one_by_id(role_type, job_id) + fn query_job_result(role_type: RoleType, job_id: JobId) -> Option>> { + Jobs::query_job_result(role_type, job_id) } fn query_next_job_id() -> JobId {