diff --git a/rust-libs/modules/gva/bca/src/exec_req_type.rs b/rust-libs/modules/gva/bca/src/exec_req_type.rs index bf8e8e25568fcd4993389acd29fb0541200d3c1e..08f1e1f21b6c0965b069d3084012167d59469187 100644 --- a/rust-libs/modules/gva/bca/src/exec_req_type.rs +++ b/rust-libs/modules/gva/bca/src/exec_req_type.rs @@ -13,6 +13,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. +mod last_blockstamp_out_of_fork_window; mod members_count; mod prepare_simple_payment; mod send_txs; @@ -39,6 +40,12 @@ pub(super) async fn execute_req_type( _is_whitelisted: bool, ) -> Result<BcaRespTypeV0, ExecReqTypeError> { match req_type { + BcaReqTypeV0::LastBlockstampOutOfForkWindow => { + last_blockstamp_out_of_fork_window::exec_req_last_blockstamp_out_of_fork_window( + bca_executor, + ) + .await + } BcaReqTypeV0::MembersCount => members_count::exec_req_members_count(bca_executor).await, BcaReqTypeV0::PrepareSimplePayment(params) => { prepare_simple_payment::exec_req_prepare_simple_payment(bca_executor, params).await diff --git a/rust-libs/modules/gva/bca/src/exec_req_type/last_blockstamp_out_of_fork_window.rs b/rust-libs/modules/gva/bca/src/exec_req_type/last_blockstamp_out_of_fork_window.rs new file mode 100644 index 0000000000000000000000000000000000000000..c3be288e55341a16faa820878dc4de7bc15188d2 --- /dev/null +++ b/rust-libs/modules/gva/bca/src/exec_req_type/last_blockstamp_out_of_fork_window.rs @@ -0,0 +1,91 @@ +// Copyright (C) 2020 Éloïs SANCHEZ. +// +// This program 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, either version 3 of the +// License, or (at your option) any later version. +// +// This program 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 this program. If not, see <https://www.gnu.org/licenses/>. + +use crate::*; +use dubp::common::prelude::*; + +pub(super) async fn exec_req_last_blockstamp_out_of_fork_window( + bca_executor: &BcaExecutor, +) -> Result<BcaRespTypeV0, ExecReqTypeError> { + let dbs_reader = bca_executor.dbs_reader(); + bca_executor + .dbs_pool + .execute(move |dbs| { + if let Some(current_block) = dbs_reader.get_current_block_meta(&dbs.cm_db)? { + let block_ref_number = if current_block.number < 101 { + 0 + } else { + current_block.number - 101 + }; + let block_ref_hash = dbs_reader + .block(&dbs.bc_db_ro, U32BE(block_ref_number))? + .expect("unreachable") + .hash; + Ok::<_, ExecReqTypeError>(BcaRespTypeV0::LastBlockstampOutOfForkWindow( + Blockstamp { + number: BlockNumber(block_ref_number), + hash: BlockHash(block_ref_hash), + }, + )) + } else { + Err("no blockchain".into()) + } + }) + .await? +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::*; + + #[tokio::test] + async fn test_exec_req_last_blockstamp_out_of_fork_window_no_blockchain() { + let mut dbs_reader = MockDbsReader::new(); + dbs_reader + .expect_get_current_block_meta::<CmV1Db<MemSingleton>>() + .times(1) + .returning(|_| Ok(None)); + let bca_executor = create_bca_executor(dbs_reader).expect("fail to create bca executor"); + + let resp_res = exec_req_last_blockstamp_out_of_fork_window(&bca_executor).await; + + assert_eq!(resp_res, Err(ExecReqTypeError("no blockchain".into()))); + } + + #[tokio::test] + async fn test_exec_req_last_blockstamp_out_of_fork_window_ok() -> Result<(), ExecReqTypeError> { + let mut dbs_reader = MockDbsReader::new(); + dbs_reader + .expect_get_current_block_meta::<CmV1Db<MemSingleton>>() + .times(1) + .returning(|_| Ok(Some(BlockMetaV2::default()))); + dbs_reader + .expect_block() + .times(1) + .returning(|_, _| Ok(Some(BlockMetaV2::default()))); + + let bca_executor = create_bca_executor(dbs_reader).expect("fail to create bca executor"); + + let resp = exec_req_last_blockstamp_out_of_fork_window(&bca_executor).await?; + + assert_eq!( + resp, + BcaRespTypeV0::LastBlockstampOutOfForkWindow(Blockstamp::default()) + ); + + Ok(()) + } +} diff --git a/rust-libs/modules/gva/bca/types/src/lib.rs b/rust-libs/modules/gva/bca/types/src/lib.rs index 0f3a78a339edd6d9bd5d20ed9bd7e9ce517aa846..2d5e9d9cdc570aa93793300d1cd77f28bffa5c5d 100644 --- a/rust-libs/modules/gva/bca/types/src/lib.rs +++ b/rust-libs/modules/gva/bca/types/src/lib.rs @@ -28,9 +28,9 @@ pub mod rejected_tx; use crate::prepare_payment::{PrepareSimplePayment, PrepareSimplePaymentResp}; use bincode::Options as _; -use dubp::crypto::hashs::Hash; use dubp::crypto::keys::ed25519::{PublicKey, Signature}; use dubp::wallet::prelude::*; +use dubp::{common::prelude::Blockstamp, crypto::hashs::Hash}; use serde::{Deserialize, Serialize}; use smallvec::SmallVec; use thiserror::Error; @@ -58,6 +58,7 @@ pub struct BcaReqV0 { #[allow(clippy::large_enum_variant)] #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub enum BcaReqTypeV0 { + LastBlockstampOutOfForkWindow, MembersCount, PrepareSimplePayment(PrepareSimplePayment), ProofServerPubkey { challenge: [u8; 16] }, @@ -91,6 +92,7 @@ pub enum BcaRespTypeV0 { server_pubkey: PublicKey, sig: Signature, }, + LastBlockstampOutOfForkWindow(Blockstamp), MembersCount(u64), PrepareSimplePayment(PrepareSimplePaymentResp), Pong,