Commit 9d06b99b authored by Millicent Billette's avatar Millicent Billette Committed by Éloïs
Browse files

[feat] gva: add request endpoints(api_list)

parent 2ec3c922
// 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 duniter_dbs::databases::dunp_v1::DunpV1DbReadable;
#[cfg(test)]
mod tests {
use super::*;
use duniter_dbs::databases::dunp_v1::DunpV1DbWritable;
use duniter_dbs::PeerCardDbV1;
#[test]
fn test_empty_endpoints() -> KvResult<()> {
// Populate DB
let dunp_db = duniter_dbs::databases::dunp_v1::DunpV1Db::<Mem>::open(MemConf::default())?;
let db_reader = DbsReaderImpl::mem();
let pk = PublicKey::default();
dunp_db
.peers_old_write()
.upsert(PubKeyKeyV2(pk), PeerCardDbV1::default())?;
// Request Data
let api_list = vec!["GVA".to_owned()];
assert_eq!(
db_reader.endpoints_(&dunp_db, api_list)?,
Vec::<String>::new()
);
Ok(())
}
#[test]
fn test_endpoints_with_empty_api_list() -> KvResult<()> {
let dummy_endpoint = "GVA S domain.tld 443 gva";
// Populate DB
let dunp_db = duniter_dbs::databases::dunp_v1::DunpV1Db::<Mem>::open(MemConf::default())?;
let db_reader = DbsReaderImpl::mem();
let pk = PublicKey::default();
let peer = PeerCardDbV1 {
endpoints: vec![dummy_endpoint.to_owned()],
..Default::default()
};
dunp_db.peers_old_write().upsert(PubKeyKeyV2(pk), peer)?;
// Request Data
let api_list = vec![];
assert_eq!(
db_reader.endpoints_(&dunp_db, api_list)?,
Vec::<String>::new()
);
Ok(())
}
#[test]
fn test_single_peer_endpoints() -> KvResult<()> {
let dummy_endpoint = "GVA S domain.tld 443 gva";
// Populate DB
let dunp_db = duniter_dbs::databases::dunp_v1::DunpV1Db::<Mem>::open(MemConf::default())?;
let db_reader = DbsReaderImpl::mem();
let pk = PublicKey::default();
let peer = PeerCardDbV1 {
endpoints: vec![dummy_endpoint.to_owned()],
..Default::default()
};
dunp_db.peers_old_write().upsert(PubKeyKeyV2(pk), peer)?;
// Request Data
let api_list = vec!["GVA".to_owned()];
assert_eq!(
db_reader.endpoints_(&dunp_db, api_list)?,
vec![dummy_endpoint.to_owned()]
);
Ok(())
}
}
impl DbsReaderImpl {
pub(super) fn endpoints_<DB: DunpV1DbReadable>(
&self,
network_db: &DB,
mut api_list: Vec<String>,
) -> KvResult<Vec<String>> {
if api_list.is_empty() {
return Ok(vec![]);
}
for api in &mut api_list {
api.push(' ');
}
network_db.peers_old().iter(.., |it| {
it.values()
.map_ok(|peer| {
peer.endpoints.into_iter().filter(|endpoint| {
api_list
.iter()
.any(|api| endpoint.starts_with(api.as_str()))
})
})
.flatten_ok()
.collect::<Result<Vec<String>, _>>()
})
}
}
......@@ -24,6 +24,7 @@
pub mod block;
pub mod current_frame;
pub mod endpoints;
pub mod find_inputs;
pub mod idty;
pub mod pagination;
......@@ -41,7 +42,7 @@ use dubp::documents::transaction::TransactionDocumentV10;
use dubp::{block::DubpBlockV10, common::crypto::hashs::Hash};
use dubp::{common::prelude::BlockNumber, wallet::prelude::*};
use duniter_bca_types::utxo::Utxo;
use duniter_dbs::FileBackend;
use duniter_dbs::{databases::dunp_v1::DunpV1DbReadable, FileBackend};
use duniter_dbs::{
databases::{
bc_v2::{BcV2DbReadable, BcV2DbRo},
......@@ -85,6 +86,11 @@ pub trait DbsReader {
bc_db: &BcV2DbRo<FileBackend>,
page_info: PageInfo<block::BlockCursor>,
) -> KvResult<PagedData<Vec<(block::BlockCursor, BlockMetaV2)>>>;
fn endpoints<Db: 'static + DunpV1DbReadable>(
&self,
network_db: &Db,
api_list: Vec<String>,
) -> KvResult<Vec<String>>;
fn find_inputs<TxsMpDb: 'static + TxsMpV2DbReadable>(
&self,
bc_db: &BcV2DbRo<FileBackend>,
......@@ -186,6 +192,14 @@ impl DbsReader for DbsReaderImpl {
self.blocks_(bc_db, page_info)
}
fn endpoints<Db: 'static + DunpV1DbReadable>(
&self,
network_db: &Db,
api_list: Vec<String>,
) -> KvResult<Vec<String>> {
self.endpoints_(network_db, api_list)
}
fn find_inputs<TxsMpDb: 'static + TxsMpV2DbReadable>(
&self,
bc_db: &BcV2DbRo<FileBackend>,
......
......@@ -17,6 +17,7 @@ pub mod account_balance;
pub mod block;
pub mod current_block;
pub mod current_frame;
pub mod endpoints;
pub mod first_utxos_of_scripts;
pub mod gen_tx;
pub mod idty;
......@@ -33,6 +34,7 @@ pub struct QueryRoot(
queries::block::BlockQuery,
queries::current_block::CurrentBlockQuery,
queries::current_frame::CurrentFrameQuery,
queries::endpoints::EndpointsQuery,
queries::first_utxos_of_scripts::FirstUtxosQuery,
queries::gen_tx::GenTxsQuery,
queries::idty::IdtyQuery,
......
// 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::*;
// e2e requester pour obtenir la fiche de peer et un tableau de heads pour une pubKey donnée
// e2e requester pour obtenir la list des endpoints connu filtrable par type (gva, bma, ws2p, es?data-pod)
// ? e2e list endpoints type
// ? renomer dunp_v1 en network_v1 & DunpV1Db & co
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::*;
use duniter_dbs::databases::dunp_v1::DunpV1Db;
#[tokio::test]
async fn endpoints_gva_resolver() -> anyhow::Result<()> {
let mock_cm = MockAsyncAccessor::new();
let mut mock_dbs_reader = MockDbsReader::new();
mock_dbs_reader
.expect_endpoints::<DunpV1Db<FileBackend>>()
.times(1)
.returning(|_, _| {
Ok(vec![
"GVA S g1.librelois.fr 443 gva".to_owned(),
"GVA S domain.tld 443 gva".to_owned(),
])
});
let schema = create_schema(mock_cm, mock_dbs_reader)?;
assert_eq!(
exec_graphql_request(&schema, r#"{ endpoints(apiList:["GVA"]) }"#).await?,
serde_json::json!({
"data": {
"endpoints": [
"GVA S g1.librelois.fr 443 gva",
"GVA S domain.tld 443 gva"
]
}
})
);
Ok(())
}
}
#[derive(Default)]
pub(crate) struct EndpointsQuery;
#[async_graphql::Object]
impl EndpointsQuery {
/// Get endpoints known by the node
async fn endpoints(
&self,
ctx: &async_graphql::Context<'_>,
#[graphql(
desc = "filter endpoints by api (exact match endpoint first word, case sensitive)"
)]
api_list: Vec<String>,
) -> async_graphql::Result<Vec<String>> {
let data = ctx.data::<GvaSchemaData>()?;
let dbs_reader = data.dbs_reader();
Ok(data
.dbs_pool
.execute(move |dbs| dbs_reader.endpoints(&dbs.dunp_db, api_list))
.await??)
}
}
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