From 9cbc363ba0a0b8ab1aec8bdd29c167e954bfae2f Mon Sep 17 00:00:00 2001 From: Pranav Konde <76070589+pranavkonde@users.noreply.github.com> Date: Fri, 14 Mar 2025 18:39:29 +0530 Subject: [PATCH 1/2] bugfix: approval validate returns False on total DC reached --- fplus-lib/src/core/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fplus-lib/src/core/mod.rs b/fplus-lib/src/core/mod.rs index 7245b42..39e200a 100644 --- a/fplus-lib/src/core/mod.rs +++ b/fplus-lib/src/core/mod.rs @@ -4463,6 +4463,17 @@ _The initial issue can be edited in order to solve the request of the verifier. Ok(application_file) } + + pub fn reached_total_datacap(self) -> Self { + let empty = "".to_string(); + + LifeCycle { + is_active: false, + updated_at: Utc::now().to_string(), + active_request: Some(empty), + ..self + } + } } #[derive(Serialize, Deserialize, Debug)] From 7cdc8a6497d8cf145f44c7b3e611d52da47a0318 Mon Sep 17 00:00:00 2001 From: Pranav Konde <76070589+pranavkonde@users.noreply.github.com> Date: Fri, 14 Mar 2025 21:16:01 +0530 Subject: [PATCH 2/2] validate Client Project Datacap Lifecycle props in json --- fplus-lib/src/core/application/lifecycle.rs | 52 ++++++++++++++++++--- fplus-lib/src/core/application/mod.rs | 32 ++++++++++--- 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/fplus-lib/src/core/application/lifecycle.rs b/fplus-lib/src/core/application/lifecycle.rs index 3ab29c1..f652dfc 100644 --- a/fplus-lib/src/core/application/lifecycle.rs +++ b/fplus-lib/src/core/application/lifecycle.rs @@ -46,25 +46,31 @@ impl LifeCycle { /// Change Application state to Proposal from Governance Review /// Actor input is the actor who is changing the state - pub fn finish_governance_review(&self, actor: String, current_allocation_id: String) -> Self { - LifeCycle { + pub fn finish_governance_review(&self, actor: String, current_allocation_id: String) -> Result { + let new_lifecycle = LifeCycle { state: AppState::ReadyToSign, validated_by: actor, validated_at: Utc::now().to_string(), updated_at: Utc::now().to_string(), active_request: Some(current_allocation_id), ..self.clone() - } + }; + + new_lifecycle.validate()?; + Ok(new_lifecycle) } - pub fn sign_grant_datacap_proposal(&self, validated_by: &str) -> Self { - LifeCycle { + pub fn sign_grant_datacap_proposal(&self, validated_by: &str) -> Result { + let new_lifecycle = LifeCycle { state: AppState::StartSignDatacap, updated_at: Utc::now().to_string(), validated_by: validated_by.into(), validated_at: Utc::now().to_string(), ..self.clone() - } + }; + + new_lifecycle.validate()?; + Ok(new_lifecycle) } pub fn update_lifecycle_after_sign( @@ -154,4 +160,38 @@ impl LifeCycle { ..self.clone() } } + + pub fn validate(&self) -> Result<(), String> { + if self.client_on_chain_address.is_empty() { + return Err("Client on-chain address is required".to_string()); + } + if self.multisig_address.is_empty() { + return Err("Multisig address is required".to_string()); + } + + match self.state { + AppState::Granted | AppState::StartSignDatacap => { + if self.validated_by.is_empty() { + return Err("Validated by is required for Granted/StartSignDatacap state".to_string()); + } + if self.validated_at.is_empty() { + return Err("Validated at is required for Granted/StartSignDatacap state".to_string()); + } + } + AppState::ReadyToSign => { + if self.validated_by.is_empty() { + return Err("Validated by is required for ReadyToSign state".to_string()); + } + if self.validated_at.is_empty() { + return Err("Validated at is required for ReadyToSign state".to_string()); + } + if self.active_request.is_none() || self.active_request.as_ref().unwrap().is_empty() { + return Err("Active request ID is required for ReadyToSign state".to_string()); + } + } + _ => {} + } + + Ok(()) + } } diff --git a/fplus-lib/src/core/application/mod.rs b/fplus-lib/src/core/application/mod.rs index c85472d..f146e84 100644 --- a/fplus-lib/src/core/application/mod.rs +++ b/fplus-lib/src/core/application/mod.rs @@ -124,21 +124,25 @@ impl file::ApplicationFile { sps_change_request: &SpsChangeRequest, app_state: &AppState, request_id: &String, - ) -> Self { - let new_life_cycle = - self.lifecycle - .clone() - .update_lifecycle_after_sign(app_state, validated_by, request_id); + ) -> Result { + let new_life_cycle = self.lifecycle + .clone() + .update_lifecycle_after_sign(app_state, validated_by, request_id)?; + let sps_change_requests = self .allowed_sps .clone() .unwrap_or_default() .add_change_request(sps_change_request); - Self { + + let new_app = Self { lifecycle: new_life_cycle, allowed_sps: Some(sps_change_requests), ..self.clone() - } + }; + + new_app.validate()?; + Ok(new_app) } pub fn update_changing_sps_request( @@ -212,6 +216,20 @@ impl file::ApplicationFile { ..self.clone() } } + pub fn validate(&self) -> Result<(), String> { + self.lifecycle.validate()?; + + match self.lifecycle.state { + AppState::ReadyToSign | AppState::StartSignDatacap | AppState::Granted => { + if self.allocation.0.is_empty() { + return Err("Allocations are required for this state".to_string()); + } + } + _ => {} + } + + Ok(()) + } } impl std::str::FromStr for file::ApplicationFile {