Commit 4da37489 authored by Éloïs's avatar Éloïs
Browse files

[ref] gva_dbs_reader: create trait DbsReader

parent 750fff3f
......@@ -1318,6 +1318,7 @@ dependencies = [
"duniter-dbs",
"duniter-gva-db",
"maplit",
"mockall",
"resiter",
"smallvec",
"unwrap",
......@@ -2330,11 +2331,11 @@ dependencies = [
[[package]]
name = "mockall"
version = "0.8.3"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cabea45a7fc0e37093f4f30a5e2b62602253f91791c057d5f0470c63260c3d"
checksum = "18d614ad23f9bb59119b8b5670a85c7ba92c5e9adf4385c81ea00c51c8be33d5"
dependencies = [
"cfg-if 0.1.10",
"cfg-if 1.0.0",
"downcast",
"fragile",
"lazy_static",
......@@ -2345,11 +2346,11 @@ dependencies = [
[[package]]
name = "mockall_derive"
version = "0.8.3"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c461918bf7f59eefb1459252756bf2351a995d6bd510d0b2061bd86bcdabfa6"
checksum = "5dd4234635bca06fc96c7368d038061e0aae1b00a764dc817e900dc974e3deea"
dependencies = [
"cfg-if 0.1.10",
"cfg-if 1.0.0",
"proc-macro2",
"quote",
"syn",
......
......@@ -19,7 +19,7 @@ chrono = { version = "0.4.15", optional = true }
dubp = { version = "0.49.0", features = ["duniter"] }
kv_typed = { path = "../tools/kv_typed", default-features = false }
log = "0.4.8"
mockall = { version = "0.8.0", optional = true }
mockall = { version = "0.9.1", optional = true }
parking_lot = "0.11.0"
paste = "1.0.2"
rand = "0.7.3"
......
......@@ -35,7 +35,7 @@ warp = "0.3"
[dev-dependencies]
duniter-dbs = { path = "../../duniter-dbs", features = ["mem"] }
mockall = "0.8.0"
mockall = "0.9.1"
serde_json = "1.0.53"
tokio = { version = "1.2", features = ["macros", "rt-multi-thread", "time"] }
unwrap = "1.2.1"
......@@ -25,5 +25,6 @@ uninit = "0.4.0"
[dev-dependencies]
duniter-dbs = { path = "../../../duniter-dbs", features = ["mem"] }
duniter-gva-dbs-reader = { path = "../dbs-reader", features = ["mock"] }
tokio = { version = "1.2", features = ["macros", "rt-multi-thread", "time"] }
mockall = "0.8.0"
mockall = "0.9.1"
......@@ -142,7 +142,7 @@ mod tests {
.times(1)
.returning(|_, _| Ok(Some(BlockMetaV2::default())));
dbs_reader
.expect_find_inputs::<BcV2DbRo<FileBackend>, TxsMpV2Db<FileBackend>>()
.expect_find_inputs::<TxsMpV2Db<FileBackend>>()
.times(1)
.returning(|_, _, _, _, _| Ok((vec![], SourceAmount::default())));
let bca_executor = create_bca_executor(dbs_reader).expect("fail to create bca executor");
......@@ -182,7 +182,7 @@ mod tests {
.times(1)
.returning(|_, _| Ok(Some(BlockMetaV2::default())));
dbs_reader
.expect_find_inputs::<BcV2DbRo<FileBackend>, TxsMpV2Db<FileBackend>>()
.expect_find_inputs::<TxsMpV2Db<FileBackend>>()
.times(1)
.returning(move |_, _, _, _, _| Ok((vec![input], SourceAmount::with_base0(57))));
let bca_executor = create_bca_executor(dbs_reader).expect("fail to create bca executor");
......
......@@ -37,22 +37,23 @@ use duniter_bca_types::{
};
pub use duniter_dbs::kv_typed::prelude::*;
use duniter_dbs::{FileBackend, SharedDbs};
use duniter_gva_dbs_reader::DbsReader;
use futures::{prelude::stream::FuturesUnordered, StreamExt, TryStream, TryStreamExt};
use once_cell::sync::OnceCell;
use smallvec::SmallVec;
use tokio::task::JoinError;
#[cfg(test)]
use crate::tests::DbsReader;
use crate::tests::DbsReaderImpl;
#[cfg(not(test))]
use duniter_gva_dbs_reader::DbsReader;
use duniter_gva_dbs_reader::DbsReaderImpl;
static BCA_EXECUTOR: OnceCell<BcaExecutor> = OnceCell::new();
pub fn set_bca_executor(
currency: String,
dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
dbs_reader: DbsReader,
dbs_reader: DbsReaderImpl,
self_keypair: Ed25519KeyPair,
software_version: &'static str,
txs_mempool: duniter_mempools::TxsMempool,
......@@ -87,7 +88,7 @@ where
struct BcaExecutor {
currency: String,
dbs_pool: fast_threadpool::ThreadPoolAsyncHandler<SharedDbs<FileBackend>>,
dbs_reader: DbsReader,
dbs_reader: DbsReaderImpl,
self_keypair: Ed25519KeyPair,
software_version: &'static str,
txs_mempool: duniter_mempools::TxsMempool,
......@@ -202,7 +203,7 @@ impl BcaExecutor {
#[cfg(not(test))]
impl BcaExecutor {
#[inline(always)]
pub fn dbs_reader(&self) -> DbsReader {
pub fn dbs_reader(&self) -> DbsReaderImpl {
self.dbs_reader
}
}
......@@ -224,35 +225,14 @@ mod tests {
pub use duniter_dbs::databases::cm_v1::{CmV1Db, CmV1DbReadable};
pub use duniter_dbs::databases::txs_mp_v2::{TxsMpV2Db, TxsMpV2DbReadable};
pub use duniter_dbs::BlockMetaV2;
pub use duniter_gva_dbs_reader::MockDbsReader;
pub use futures::TryStreamExt;
mockall::mock! {
pub DbsReader {
fn block(&self, bc_db: &BcV2DbRo<FileBackend>, number: U32BE) -> KvResult<Option<BlockMetaV2>>;
fn find_inputs<BcDb: 'static + BcV2DbReadable, TxsMpDb: 'static + TxsMpV2DbReadable>(
&self,
bc_db: &BcDb,
txs_mp_db: &TxsMpDb,
amount: SourceAmount,
script: &WalletScriptV10,
use_mempool_sources: bool,
) -> anyhow::Result<(Vec<TransactionInputV10>, SourceAmount)>;
fn get_current_block<CmDb: 'static + CmV1DbReadable>(
&self,
cm_db: &CmDb,
) -> KvResult<Option<DubpBlockV10>>;
fn get_current_block_meta<CmDb: 'static + CmV1DbReadable>(
&self,
cm_db: &CmDb,
) -> KvResult<Option<BlockMetaV2>>;
}
}
pub type DbsReader = duniter_dbs::kv_typed::prelude::Arc<MockDbsReader>;
pub type DbsReaderImpl = duniter_dbs::kv_typed::prelude::Arc<MockDbsReader>;
impl BcaExecutor {
#[inline(always)]
pub fn dbs_reader(&self) -> DbsReader {
pub fn dbs_reader(&self) -> DbsReaderImpl {
self.dbs_reader.clone()
}
}
......
......@@ -11,12 +11,16 @@ edition = "2018"
[lib]
path = "src/lib.rs"
[features]
mock = ["mockall"]
[dependencies]
anyhow = "1.0.34"
arrayvec = "0.5.1"
duniter-dbs = { path = "../../../duniter-dbs" }
duniter-gva-db = { path = "../db" }
dubp = { version = "0.49.0", features = ["duniter"] }
mockall = { version = "0.9.1", optional = true }
resiter = "0.4.0"
[dev-dependencies]
......
......@@ -35,8 +35,8 @@ impl FromStr for BlockCursor {
}
}
impl DbsReader {
pub fn block(
impl DbsReaderImpl {
pub(super) fn block_(
&self,
bc_db: &BcV2DbRo<FileBackend>,
number: U32BE,
......@@ -44,7 +44,7 @@ impl DbsReader {
bc_db.blocks_meta().get(&number)
}
pub fn blocks(
pub(super) fn blocks_(
&self,
bc_db: &BcV2DbRo<FileBackend>,
page_info: PageInfo<BlockCursor>,
......@@ -151,15 +151,13 @@ where
mod tests {
use super::*;
use duniter_dbs::databases::bc_v2::BcV2DbWritable;
use duniter_gva_db::GvaV1DbWritable;
use std::num::NonZeroUsize;
#[test]
fn test_block() -> KvResult<()> {
let bc_db = duniter_dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())?;
let bc_db_ro = bc_db.get_ro_handler();
let db_reader = create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) });
let db_reader = DbsReaderImpl::mem();
bc_db
.blocks_meta_write()
......@@ -176,9 +174,8 @@ mod tests {
#[test]
fn test_blocks() -> KvResult<()> {
let bc_db = duniter_dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())?;
let bc_db_ro = bc_db.get_ro_handler();
let db_reader = create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) });
let db_reader = DbsReaderImpl::mem();
for i in 0..20 {
bc_db.blocks_meta_write().upsert(
......
......@@ -17,8 +17,11 @@ use duniter_dbs::BlockMetaV2;
use crate::*;
impl DbsReader {
pub fn get_current_frame<BcDb: BcV2DbReadable, CmDb: CmV1DbReadable>(
impl DbsReaderImpl {
pub(super) fn get_current_frame_<
BcDb: 'static + BcV2DbReadable,
CmDb: 'static + CmV1DbReadable,
>(
&self,
bc_db: &BcDb,
cm_db: &CmDb,
......
......@@ -22,10 +22,10 @@ use dubp::{documents::transaction::TransactionInputV10, wallet::prelude::*};
pub(super) const MIN_AMOUNT: i64 = 100;
impl DbsReader {
pub fn find_inputs<BcDb: BcV2DbReadable, TxsMpDb: TxsMpV2DbReadable>(
impl DbsReaderImpl {
pub(super) fn find_inputs_<TxsMpDb: 'static + TxsMpV2DbReadable>(
&self,
bc_db: &BcDb,
bc_db: &BcV2DbRo<FileBackend>,
txs_mp_db: &TxsMpDb,
amount: SourceAmount,
script: &WalletScriptV10,
......@@ -81,7 +81,7 @@ impl DbsReader {
bc_db,
issuer,
PageInfo::default(),
Some(&pending_uds_bn),
Some(pending_uds_bn),
Some(amount - inputs_sum),
)?;
inputs.extend(uds.into_iter().map(|(block_number, source_amount)| {
......@@ -149,6 +149,7 @@ mod tests {
#[test]
fn test_find_inputs() -> anyhow::Result<()> {
let bc_db = duniter_dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
let bc_db_ro = bc_db.get_ro_handler();
let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())?;
let db_reader = create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) });
let txs_mp_db =
......@@ -191,7 +192,7 @@ mod tests {
// Gen tx1
let (inputs, inputs_sum) = db_reader.find_inputs(
&bc_db,
&bc_db_ro,
&txs_mp_db,
SourceAmount::with_base0(550),
&script,
......@@ -210,7 +211,7 @@ mod tests {
// Gen tx2
let (inputs, inputs_sum) = db_reader.find_inputs(
&bc_db,
&bc_db_ro,
&txs_mp_db,
SourceAmount::with_base0(550),
&script,
......@@ -226,7 +227,7 @@ mod tests {
// Gen tx3 (use pending utxo)
let (inputs, inputs_sum) = db_reader.find_inputs(
&bc_db,
&bc_db_ro,
&txs_mp_db,
SourceAmount::with_base0(750),
&script,
......
......@@ -15,8 +15,8 @@
use crate::*;
impl DbsReader {
pub fn idty(
impl DbsReaderImpl {
pub(super) fn idty_(
&self,
bc_db: &BcV2DbRo<FileBackend>,
pubkey: PublicKey,
......@@ -32,15 +32,12 @@ impl DbsReader {
mod tests {
use super::*;
use duniter_dbs::databases::bc_v2::BcV2DbWritable;
use duniter_gva_db::GvaV1DbWritable;
#[test]
fn test_idty() -> KvResult<()> {
let bc_db = duniter_dbs::databases::bc_v2::BcV2Db::<Mem>::open(MemConf::default())?;
let gva_db = duniter_gva_db::GvaV1Db::<Mem>::open(MemConf::default())?;
let bc_db_ro = bc_db.get_ro_handler();
let db_reader = create_dbs_reader(unsafe { std::mem::transmute(&gva_db.get_ro_handler()) });
let db_reader = DbsReaderImpl::mem();
let pk = PublicKey::default();
bc_db
......
......@@ -69,15 +69,161 @@ impl std::fmt::Display for WrongCursor {
}
impl std::error::Error for WrongCursor {}
#[cfg_attr(feature = "mock", mockall::automock)]
pub trait DbsReader {
fn all_uds_of_pubkey(
&self,
bc_db: &BcV2DbRo<FileBackend>,
pubkey: PublicKey,
page_info: PageInfo<BlockNumber>,
) -> KvResult<PagedData<uds_of_pubkey::UdsWithSum>>;
fn block(&self, bc_db: &BcV2DbRo<FileBackend>, number: U32BE) -> KvResult<Option<BlockMetaV2>>;
fn blocks(
&self,
bc_db: &BcV2DbRo<FileBackend>,
page_info: PageInfo<block::BlockCursor>,
) -> KvResult<PagedData<Vec<(block::BlockCursor, BlockMetaV2)>>>;
fn find_inputs<TxsMpDb: 'static + TxsMpV2DbReadable>(
&self,
bc_db: &BcV2DbRo<FileBackend>,
txs_mp_db: &TxsMpDb,
amount: SourceAmount,
script: &WalletScriptV10,
use_mempool_sources: bool,
) -> anyhow::Result<(
Vec<dubp::documents::transaction::TransactionInputV10>,
SourceAmount,
)>;
fn find_script_utxos<TxsMpDb: 'static + TxsMpV2DbReadable>(
&self,
txs_mp_db_ro: &TxsMpDb,
amount_target_opt: Option<SourceAmount>,
page_info: PageInfo<utxos::UtxoCursor>,
script: &WalletScriptV10,
) -> anyhow::Result<PagedData<utxos::UtxosWithSum>>;
fn first_scripts_utxos(
&self,
first: usize,
scripts: &[WalletScriptV10],
) -> anyhow::Result<Vec<arrayvec::ArrayVec<[utxos::Utxo; utxos::MAX_FIRST_UTXOS]>>>;
fn get_account_balance(
&self,
account_script: &WalletScriptV10,
) -> KvResult<Option<SourceAmountValV2>>;
fn get_blockchain_time(&self, block_number: BlockNumber) -> anyhow::Result<u64>;
fn get_current_block<CmDb: 'static + CmV1DbReadable>(
&self,
cm_db: &CmDb,
) -> KvResult<Option<DubpBlockV10>>;
fn get_current_block_meta<CmDb: 'static + CmV1DbReadable>(
&self,
cm_db: &CmDb,
) -> KvResult<Option<BlockMetaV2>>;
fn get_current_frame<BcDb: 'static + BcV2DbReadable, CmDb: 'static + CmV1DbReadable>(
&self,
bc_db: &BcDb,
cm_db: &CmDb,
) -> anyhow::Result<Vec<duniter_dbs::BlockMetaV2>>;
fn get_current_ud<BcDb: 'static + BcV2DbReadable>(
&self,
bc_db: &BcDb,
) -> KvResult<Option<SourceAmount>>;
fn get_txs_history_bc_received(
&self,
from: Option<u64>,
page_info: PageInfo<txs_history::TxBcCursor>,
script_hash: Hash,
to: Option<u64>,
) -> KvResult<PagedData<VecDeque<duniter_gva_db::GvaTxDbV1>>>;
fn get_txs_history_bc_sent(
&self,
from: Option<u64>,
page_info: PageInfo<txs_history::TxBcCursor>,
script_hash: Hash,
to: Option<u64>,
) -> KvResult<PagedData<VecDeque<duniter_gva_db::GvaTxDbV1>>>;
fn get_txs_history_mempool<TxsMpDb: 'static + TxsMpV2DbReadable>(
&self,
txs_mp_db_ro: &TxsMpDb,
pubkey: PublicKey,
) -> KvResult<(Vec<TransactionDocumentV10>, Vec<TransactionDocumentV10>)>;
fn idty(
&self,
bc_db: &BcV2DbRo<FileBackend>,
pubkey: PublicKey,
) -> KvResult<Option<duniter_dbs::IdtyDbV2>>;
fn unspent_uds_of_pubkey(
&self,
bc_db: &BcV2DbRo<FileBackend>,
pubkey: PublicKey,
page_info: PageInfo<BlockNumber>,
bn_to_exclude_opt: Option<std::collections::BTreeSet<BlockNumber>>,
amount_target_opt: Option<SourceAmount>,
) -> KvResult<PagedData<uds_of_pubkey::UdsWithSum>>;
}
#[derive(Clone, Copy, Debug)]
pub struct DbsReader(&'static GvaV1DbRo<FileBackend>);
pub struct DbsReaderImpl(&'static GvaV1DbRo<FileBackend>);
pub fn create_dbs_reader(gva_db_ro: &'static GvaV1DbRo<FileBackend>) -> DbsReader {
DbsReader(gva_db_ro)
pub fn create_dbs_reader(gva_db_ro: &'static GvaV1DbRo<FileBackend>) -> DbsReaderImpl {
DbsReaderImpl(gva_db_ro)
}
impl DbsReader {
pub fn get_account_balance(
impl DbsReader for DbsReaderImpl {
fn all_uds_of_pubkey(
&self,
bc_db: &BcV2DbRo<FileBackend>,
pubkey: PublicKey,
page_info: PageInfo<BlockNumber>,
) -> KvResult<PagedData<uds_of_pubkey::UdsWithSum>> {
self.all_uds_of_pubkey_(bc_db, pubkey, page_info)
}
fn block(&self, bc_db: &BcV2DbRo<FileBackend>, number: U32BE) -> KvResult<Option<BlockMetaV2>> {
self.block_(bc_db, number)
}
fn blocks(
&self,
bc_db: &BcV2DbRo<FileBackend>,
page_info: PageInfo<block::BlockCursor>,
) -> KvResult<PagedData<Vec<(block::BlockCursor, BlockMetaV2)>>> {
self.blocks_(bc_db, page_info)
}
fn find_inputs<TxsMpDb: 'static + TxsMpV2DbReadable>(
&self,
bc_db: &BcV2DbRo<FileBackend>,
txs_mp_db: &TxsMpDb,
amount: SourceAmount,
script: &WalletScriptV10,
use_mempool_sources: bool,
) -> anyhow::Result<(
Vec<dubp::documents::transaction::TransactionInputV10>,
SourceAmount,
)> {
self.find_inputs_(bc_db, txs_mp_db, amount, script, use_mempool_sources)
}
fn find_script_utxos<TxsMpDb: 'static + TxsMpV2DbReadable>(
&self,
txs_mp_db_ro: &TxsMpDb,
amount_target_opt: Option<SourceAmount>,
page_info: PageInfo<utxos::UtxoCursor>,
script: &WalletScriptV10,
) -> anyhow::Result<PagedData<utxos::UtxosWithSum>> {
self.find_script_utxos_(txs_mp_db_ro, amount_target_opt, page_info, script)
}
fn first_scripts_utxos(
&self,
first: usize,
scripts: &[WalletScriptV10],
) -> anyhow::Result<Vec<ArrayVec<[utxos::Utxo; utxos::MAX_FIRST_UTXOS]>>> {
self.first_scripts_utxos_(first, scripts)
}
fn get_account_balance(
&self,
account_script: &WalletScriptV10,
) -> KvResult<Option<SourceAmountValV2>> {
......@@ -86,40 +232,98 @@ impl DbsReader {
.get(duniter_dbs::WalletConditionsV2::from_ref(account_script))
}
pub fn get_current_block<CmDb: CmV1DbReadable>(
fn get_blockchain_time(&self, block_number: BlockNumber) -> anyhow::Result<u64> {
Ok(self
.0
.blockchain_time()
.get(&U32BE(block_number.0))?
.unwrap_or_else(|| unreachable!()))
}
fn get_current_block<CmDb: CmV1DbReadable>(
&self,
cm_db: &CmDb,
) -> KvResult<Option<DubpBlockV10>> {
Ok(cm_db.current_block().get(&())?.map(|db_block| db_block.0))
}
pub fn get_current_block_meta<CmDb: CmV1DbReadable>(
fn get_current_block_meta<CmDb: CmV1DbReadable>(
&self,
cm_db: &CmDb,
) -> KvResult<Option<BlockMetaV2>> {
cm_db.current_block_meta().get(&())
}
pub fn get_current_ud<BcDb: BcV2DbReadable>(
fn get_current_frame<BcDb: 'static + BcV2DbReadable, CmDb: 'static + CmV1DbReadable>(
&self,
bc_db: &BcDb,
) -> KvResult<Option<SourceAmount>> {
cm_db: &CmDb,
) -> anyhow::Result<Vec<BlockMetaV2>> {
self.get_current_frame_(bc_db, cm_db)
}
fn get_current_ud<BcDb: BcV2DbReadable>(&self, bc_db: &BcDb) -> KvResult<Option<SourceAmount>> {
bc_db
.uds_reval()
.iter_rev(.., |it| it.values().map_ok(|v| v.0).next_res())
}
pub fn get_blockchain_time(&self, block_number: BlockNumber) -> anyhow::Result<u64> {
Ok(self
.0
.blockchain_time()
.get(&U32BE(block_number.0))?
.unwrap_or_else(|| unreachable!()))
fn get_txs_history_bc_received(
&self,
from: Option<u64>,
page_info: PageInfo<txs_history::TxBcCursor>,
script_hash: Hash,
to: Option<u64>,
) -> KvResult<PagedData<VecDeque<GvaTxDbV1>>> {
self.get_txs_history_bc_received_(from, page_info, script_hash, to)
}
fn get_txs_history_bc_sent(
&self,
from: Option<u64>,
page_info: PageInfo<txs_history::TxBcCursor>,
script_hash: Hash,
to: Option<u64>,
) -> KvResult<PagedData<VecDeque<GvaTxDbV1>>> {
self.get_txs_history_bc_sent_(from, page_info, script_hash, to)
}
fn get_txs_history_mempool<TxsMpDb: 'static + TxsMpV2DbReadable>(
&self,
txs_mp_db_ro: &TxsMpDb,
pubkey: PublicKey,
) -> KvResult<(Vec<TransactionDocumentV10>, Vec<TransactionDocumentV10>)> {
self.get_txs_history_mempool_(txs_mp_db_ro, pubkey)
}
fn idty(
&self,
bc_db: &BcV2DbRo<FileBackend>,
pubkey: PublicKey,
) -> KvResult<Option<duniter_dbs::IdtyDbV2>> {
self.idty_(bc_db, pubkey)
}
fn unspent_uds_of_pubkey(
&self,
bc_db: &BcV2DbRo<FileBackend>,
pubkey: PublicKey,
page_info: PageInfo<BlockNumber>,
bn_to_exclude_opt: Option<BTreeSet<BlockNumber>>,