From 14c392107e0ef9fd086e25284bf02e07bf61f9b7 Mon Sep 17 00:00:00 2001 From: Erick Casanova Date: Fri, 14 Oct 2022 11:24:52 -0500 Subject: [PATCH] Fix #187 add a new validation, when is meet move the proposal to a finalized status to show that now the proposal can be broadcasted --- pallets/bitcoin-vaults/src/functions.rs | 33 ++++++++++++++----------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/pallets/bitcoin-vaults/src/functions.rs b/pallets/bitcoin-vaults/src/functions.rs index 6f6f3d1f..a51eab1a 100644 --- a/pallets/bitcoin-vaults/src/functions.rs +++ b/pallets/bitcoin-vaults/src/functions.rs @@ -107,7 +107,7 @@ impl Pallet { } pub fn do_save_psbt(signer: T::AccountId, proposal_id: [u8;32], signature_payload: BoundedVec) -> DispatchResult{ - // validations: proposal exists, signer is member of vault, proposal is pending, + // validations: proposal exists, signer is member of vault, proposal is pending, let vault_id = >::get(proposal_id).ok_or(Error::::ProposalNotFound)?.vault_id; let vault = >::get(vault_id).ok_or(Error::::VaultNotFound)?; ensure!(vault.is_vault_member(&signer), Error::::SignerPermissionsNeeded); @@ -121,6 +121,9 @@ impl Pallet { let signed_already = p.signed_psbts.iter().find(|&signature|{ signature.signer ==signer }).is_some(); ensure!(!signed_already, Error::::AlreadySigned); p.signed_psbts.try_push(signature).map_err(|_| Error::::ExceedMaxCosignersPerVault)?; + if p.signed_psbts.len() as u32 == vault.threshold { + p.status.clone_from(&ProposalStatus::ReadyToFinalize(false)); + } } Ok(()) })?; @@ -136,9 +139,9 @@ impl Pallet { // can be called by any vault signer ensure!(vault.is_vault_member(&signer), Error::::SignerPermissionsNeeded); // if its finalized then fire error "already finalized" or "already broadcasted" - ensure!(proposal.status.eq(&ProposalStatus::Pending) || proposal.status.eq(&ProposalStatus::Finalized), + ensure!(proposal.status.eq(&ProposalStatus::Pending) || proposal.status.eq(&ProposalStatus::Finalized), Error::::PendingProposalRequired ); - // signs must be greater or equal than threshold + // signs must be greater or equal than threshold ensure!(proposal.signed_psbts.len() as u32 >= vault.threshold, Error::::NotEnoughSignatures); // set status to: ready to be finalized >::try_mutate::<_,(),DispatchError,_>(proposal_id, |proposal|{ @@ -174,7 +177,7 @@ impl Pallet { } /*---- Offchain extrinsics ----*/ - + pub fn do_insert_descriptors(vault_id: [u8;32], descriptors: Descriptors, status: BDKStatus) -> DispatchResult { >::try_mutate(vault_id, | v |{ match v { @@ -225,8 +228,8 @@ impl Pallet { pub fn get_pending_vaults() -> Vec<[u8; 32]> { >::iter() .filter_map(|(entry, vault)| { - if vault.descriptors.output_descriptor.is_empty() && - (vault.offchain_status.eq(&BDKStatus::::Pending) || + if vault.descriptors.output_descriptor.is_empty() && + (vault.offchain_status.eq(&BDKStatus::::Pending) || vault.offchain_status.eq(&BDKStatus::::RecoverableError( BoundedVec::::default() )) ) { Some(entry) @@ -240,8 +243,8 @@ impl Pallet { pub fn get_pending_proposals() -> Vec<[u8; 32]>{ >::iter() .filter_map(|(id, proposal)|{ - if proposal.psbt.is_empty() && - (proposal.offchain_status.eq(&BDKStatus::::Pending) || + if proposal.psbt.is_empty() && + (proposal.offchain_status.eq(&BDKStatus::::Pending) || proposal.offchain_status.eq(&BDKStatus::::RecoverableError( BoundedVec::::default() )) ){ Some(id) @@ -353,7 +356,7 @@ impl Pallet { }; body.push(("threshold".chars().collect::>(), JsonValue::Number(threshold))); let vault_signers = vault.cosigners.clone().to_vec(); - + //get the xpub for each cosigner let xpubs = Self::get_accounts_xpubs(vault_signers).map_err(|_| Self::build_offchain_err(false, "One of the cosigner xpubs wasn't found"))?; @@ -428,7 +431,7 @@ impl Pallet { vault_payload.change_descriptor.clone_from(&descriptors.1); }, Err(status) => {vault_payload.status.clone_from(&status)}, - }; + }; // Build offchain vaults struct and push it to a Vec generated_vaults.push(vault_payload); }); @@ -492,7 +495,7 @@ impl Pallet { Ok(response_body) } - pub fn gen_proposals_payload_by_bulk(pending_proposals : Vec<[u8;32]>, api_endpoint: Vec, + pub fn gen_proposals_payload_by_bulk(pending_proposals : Vec<[u8;32]>, api_endpoint: Vec, json_builder: &dyn Fn([u8;32])-> Result,OffchainStatus> ) -> Vec{ let mut generated_proposals = Vec::::new(); @@ -531,7 +534,7 @@ impl Pallet { let mapped_signatures: Vec = proposal.signed_psbts.iter().map(|psbt|{ JsonValue::String(str::from_utf8(&psbt.signature).unwrap_or_default().chars().collect()) }).collect(); - + let broadcast= match proposal.status{ ProposalStatus::ReadyToFinalize(flag) => flag, _ => false, @@ -544,7 +547,7 @@ impl Pallet { // // Parse the JSON and print the resulting lite-json structure. Ok(jsonSerialize::format(&json_object, 4) ) } - + // pub fn bdk_gen_finalized_proposal(proposal_id: [u8;32])-> Result,OffchainStatus >{ // let raw_json = Self::gen_finalize_json_body(proposal_id)?; // let request_body = @@ -564,7 +567,7 @@ impl Pallet { // let mut finalized_proposals = Vec::::new(); // finalized_proposals // } - + fn build_offchain_err(recoverable: bool, msj: &str )-> OffchainStatus{ let bounded_msj = msj.as_bytes().to_vec(); match recoverable{ @@ -638,4 +641,4 @@ impl BlockNumberProvider for Pallet { fn current_block_number() -> Self::BlockNumber { >::block_number() } -} \ No newline at end of file +}