Commit a5a9a44a authored by Éloïs's avatar Éloïs
Browse files

[feat] gva:bca: add query SendTxs

parent 3d1783c7
......@@ -1162,6 +1162,7 @@ dependencies = [
"duniter-dbs",
"duniter-gva-db",
"duniter-gva-dbs-reader",
"duniter-mempools",
"fast-threadpool",
"futures",
"mockall",
......@@ -1178,6 +1179,7 @@ dependencies = [
"bincode",
"dubp",
"serde",
"smallvec",
"thiserror",
]
......
......@@ -15,6 +15,7 @@ duniter-bca-types = { path = "types", features = ["duniter"] }
duniter-dbs = { path = "../../../duniter-dbs" }
duniter-gva-db = { path = "../db" }
duniter-gva-dbs-reader = { path = "../dbs-reader" }
duniter-mempools = { path = "../../../duniter-mempools" }
fast-threadpool = "0.2.3"
futures = "0.3.6"
once_cell = "1.5"
......
......@@ -15,6 +15,7 @@
mod members_count;
mod prepare_simple_payment;
mod send_txs;
use dubp::crypto::keys::KeyPair;
......@@ -51,5 +52,6 @@ pub(super) async fn execute_req_type(
.sign(&challenge),
}),
BcaReqTypeV0::Ping => Ok(BcaRespTypeV0::Pong),
BcaReqTypeV0::SendTxs(txs) => send_txs::send_txs(bca_executor, txs).await,
}
}
// 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::{crypto::keys::KeyPair, documents::transaction::TransactionDocumentTrait};
use duniter_bca_types::{
rejected_tx::{RejectedTx, RejectedTxReason},
Txs,
};
pub(super) async fn send_txs(
bca_executor: &BcaExecutor,
txs: Txs,
) -> Result<BcaRespTypeV0, ExecReqTypeError> {
let expected_currency = bca_executor.currency.clone();
let server_pubkey = bca_executor.self_keypair.public_key();
let txs_mempool = bca_executor.txs_mempool;
let mut rejected_txs = Vec::new();
for (i, tx) in txs.into_iter().enumerate() {
if let Err(e) = tx.verify(Some(&expected_currency)) {
rejected_txs.push(RejectedTx {
tx_index: i as u16,
reason: RejectedTxReason::InvalidTx(e.to_string()),
});
} else if let Err(rejected_tx) = bca_executor
.dbs_pool
.execute(move |dbs| {
txs_mempool
.add_pending_tx(&dbs.bc_db_ro, server_pubkey, &dbs.txs_mp_db, &tx)
.map_err(|e| RejectedTx {
tx_index: i as u16,
reason: match e {
duniter_mempools::TxMpError::Db(e) => {
RejectedTxReason::DbError(e.to_string())
}
duniter_mempools::TxMpError::Full => RejectedTxReason::MempoolFull,
duniter_mempools::TxMpError::TxAlreadyWritten => {
RejectedTxReason::TxAlreadyWritten
}
},
})
})
.await?
{
rejected_txs.push(rejected_tx);
}
}
Ok(BcaRespTypeV0::RejectedTxs(rejected_txs))
}
......@@ -54,6 +54,7 @@ pub fn set_bca_executor(
dbs_reader: DbsReader,
self_keypair: Ed25519KeyPair,
software_version: &'static str,
txs_mempool: duniter_mempools::TxsMempool,
) {
BCA_EXECUTOR
.set(BcaExecutor {
......@@ -62,6 +63,7 @@ pub fn set_bca_executor(
dbs_reader,
self_keypair,
software_version,
txs_mempool,
})
.unwrap_or_else(|_| panic!("BCA_EXECUTOR already set !"))
}
......@@ -87,6 +89,7 @@ struct BcaExecutor {
dbs_reader: DbsReader,
self_keypair: Ed25519KeyPair,
software_version: &'static str,
txs_mempool: duniter_mempools::TxsMempool,
}
use uninit::extension_traits::VecCapacity;
impl BcaExecutor {
......@@ -265,6 +268,7 @@ mod tests {
Seed32::random().expect("fail to gen random seed"),
),
software_version: "test",
txs_mempool: duniter_mempools::TxsMempool::new(10),
})
}
......
......@@ -9,6 +9,7 @@ edition = "2018"
bincode = "1.3"
dubp = { version = "0.49.0" }
serde = { version = "1.0.105", features = ["derive"] }
smallvec = { version = "1.4.0", features = ["serde"] }
thiserror = "1.0.20"
[features]
......
......@@ -23,6 +23,7 @@
)]
pub mod prepare_payment;
pub mod rejected_tx;
use crate::prepare_payment::{PrepareSimplePayment, PrepareSimplePaymentResp};
......@@ -31,6 +32,7 @@ use dubp::crypto::hashs::Hash;
use dubp::crypto::keys::ed25519::{PublicKey, Signature};
use dubp::wallet::prelude::*;
use serde::{Deserialize, Serialize};
use smallvec::SmallVec;
use thiserror::Error;
pub fn bincode_opts() -> impl bincode::Options {
......@@ -39,26 +41,36 @@ pub fn bincode_opts() -> impl bincode::Options {
.allow_trailing_bytes()
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)]
// Request
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub enum BcaReq {
V0(BcaReqV0),
_V1,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)]
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub struct BcaReqV0 {
pub req_id: usize,
pub req_type: BcaReqTypeV0,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)]
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub enum BcaReqTypeV0 {
MembersCount,
PrepareSimplePayment(PrepareSimplePayment),
ProofServerPubkey { challenge: [u8; 16] },
Ping,
SendTxs(Txs),
}
// Request types helpers
pub type Txs = SmallVec<[dubp::documents::transaction::TransactionDocumentV10; 1]>;
// Response
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub enum BcaResp {
V0(BcaRespV0),
......@@ -82,8 +94,11 @@ pub enum BcaRespTypeV0 {
MembersCount(u64),
PrepareSimplePayment(PrepareSimplePaymentResp),
Pong,
RejectedTxs(Vec<rejected_tx::RejectedTx>),
}
// Result and error
pub type BcaResult = Result<BcaResp, BcaReqExecError>;
#[derive(Clone, Debug, Deserialize, Error, PartialEq, Eq, Serialize)]
......
// 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::*;
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub struct RejectedTx {
pub tx_index: u16,
pub reason: RejectedTxReason,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub enum RejectedTxReason {
DbError(String),
InvalidTx(String),
MempoolFull,
TxAlreadyWritten,
}
......@@ -245,6 +245,7 @@ impl GvaModule {
duniter_gva_dbs_reader::create_dbs_reader(gva_db_ro),
self_keypair,
software_version,
mempools.txs,
);
let gva_schema = duniter_gva_gql::build_schema_with_data(
duniter_gva_gql::GvaSchemaData {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment