Skip to content
Snippets Groups Projects
Commit 548e93a3 authored by Éloïs's avatar Éloïs
Browse files

[feat] gva: add queries node summary and block by number

parent 17598ab8
No related branches found
No related tags found
1 merge request!226Resolve "GVA: create skeleton & implement current Block request"
......@@ -100,7 +100,7 @@ pub fn get_block<DB: DbReadable>(
blockstamp: Blockstamp,
) -> Result<Option<DbBlock>, DbError> {
db.read(|r| {
let opt_dal_block = get_dal_block_in_local_blockchain(db, r, blockstamp.id)?;
let opt_dal_block = get_db_block_in_local_blockchain(db, r, blockstamp.id)?;
if opt_dal_block.is_none() {
get_fork_block(db, r, blockstamp)
} else {
......@@ -145,11 +145,11 @@ pub fn get_block_in_local_blockchain<DB: DbReadable, R: DbReader>(
r: &R,
block_number: BlockNumber,
) -> Result<Option<BlockDocument>, DbError> {
Ok(get_dal_block_in_local_blockchain(db, r, block_number)?.map(|dal_block| dal_block.block))
Ok(get_db_block_in_local_blockchain(db, r, block_number)?.map(|dal_block| dal_block.block))
}
/// Get block in local blockchain
pub fn get_dal_block_in_local_blockchain<DB: DbReadable, R: DbReader>(
pub fn get_db_block_in_local_blockchain<DB: DbReadable, R: DbReader>(
db: &DB,
r: &R,
block_number: BlockNumber,
......
......@@ -39,9 +39,9 @@ pub use durs_dbs_tools::kv_db::{
KvFileDbRead as DbReadable, KvFileDbRoHandler as BcDbRo, KvFileDbSchema, KvFileDbStoreType,
KvFileDbValue as DbValue, Readable as DbReader,
};
pub use durs_dbs_tools::DbError;
use constants::*;
use durs_dbs_tools::DbError;
use maplit::hashmap;
use std::path::Path;
......
......@@ -10,7 +10,6 @@ edition = "2018"
path = "src/lib.rs"
[dependencies]
proc-macro2 = "1.0.6"
actix-web = "1.0.8"
dubp-block-doc = { path = "../../dubp/block-doc"} #, version = "0.1.0" }
durs-bc-db-reader = { path = "../../modules-lib/bc-db-reader" }
......@@ -22,13 +21,14 @@ durs-network-documents = { path = "../../dunp/network-documents" }
dubp-common-doc = { path = "../../dubp/common-doc"} #, version = "0.1.0" }
durs-common-tools = { path = "../../tools/common-tools" }
dubp-currency-params = { path = "../../dubp/currency-params" }
chrono = "0.4.9"
failure = "0.1.5"
futures = "0.1"
futures-cpupool = "0.1"
juniper = "0.14.0"
juniper-from-schema = "0.5.0"
log = "0.4.8"
proc-macro2 = "1.0.6"
serde = "1.0.102"
serde_derive = "1.0.102"
serde_json = "1.0.41"
......
......@@ -5,16 +5,40 @@ schema {
}
type Query {
node: Node! @juniper(ownership: "owned")
current: Block @juniper(ownership: "owned")
block(number: Int!): Block @juniper(ownership: "owned")
}
type Mutation {
noop: Boolean!
}
#################################
# NODE types
#################################
type Summary {
software: String! @juniper(infallible: true, ownership: "owned")
version: String! @juniper(infallible: true, ownership: "owned")
}
type Node {
summary: Summary! @juniper(infallible: true)
}
#################################
# Block type
#################################
scalar DateTimeUtc @juniper(with_time_zone: false)
type Block {
version: Int!
currency: String!
issuer: String!
number: Int!
hash: String!,
commonTime: DateTimeUtc!
}
......@@ -22,23 +22,37 @@ static mut CONTEXT: Option<Context> = None;
#[derive(Debug)]
pub struct Context {
db: BcDbRo,
software_name: &'static str,
software_version: &'static str,
}
impl juniper::Context for Context {}
impl Context {
pub fn new(db: BcDbRo) -> Self {
Context { db }
pub fn new(db: BcDbRo, software_name: &'static str, software_version: &'static str) -> Self {
Context {
db,
software_name,
software_version,
}
}
pub fn get_db(&self) -> &BcDbRo {
&self.db
}
pub fn get_software_name(&self) -> &'static str {
&self.software_name
}
pub fn get_software_version(&self) -> &'static str {
&self.software_version
}
}
pub fn init(db: BcDbRo) {
pub fn init(db: BcDbRo, soft_name: &'static str, soft_version: &'static str) {
unsafe {
CONTEXT.replace(Context::new(db));
CONTEXT.replace(Context::new(db, soft_name, soft_version));
}
}
......
......@@ -12,13 +12,15 @@
//
// 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/>.
//
// model and resolvers implementation
// ! model and resolvers implementation
mod block;
use self::block::Block;
use crate::context::Context;
use dubp_block_doc::block::BlockDocumentTrait;
use dubp_common_doc::traits::Document;
use durs_bc_db_reader::BcDbRo;
use dubp_common_doc::BlockNumber;
use durs_bc_db_reader::{BcDbRo, DbError, DbReadable};
use juniper::Executor;
use juniper::FieldResult;
use juniper_from_schema::graphql_schema_from_file;
......@@ -28,61 +30,85 @@ graphql_schema_from_file!("resources/schema.gql");
pub struct Query;
pub struct Block {
version: i32,
currency: String,
issuer: String,
number: i32,
pub struct Summary {
software: &'static str,
version: &'static str,
}
pub struct Node {
summary: Summary,
}
fn db_err_to_juniper_err(e: DbError) -> juniper::FieldError {
juniper::FieldError::from(format!("Db error: {:?}", e))
}
impl QueryFields for Query {
fn field_node(
&self,
executor: &Executor<'_, Context>,
_trail: &QueryTrail<'_, Node, Walked>,
) -> FieldResult<Node> {
Ok(Node {
summary: Summary {
software: executor.context().get_software_name(),
version: executor.context().get_software_version(),
},
})
}
fn field_current(
&self,
_executor: &Executor<'_, Context>,
executor: &Executor<'_, Context>,
_trail: &QueryTrail<'_, Block, Walked>,
) -> FieldResult<Option<Block>> {
let db: &BcDbRo = &_executor.context().get_db();
let current_blockstamp = durs_bc_db_reader::current_meta_datas::get_current_blockstamp(db);
match current_blockstamp {
Ok(option) => match option {
Some(v) => {
let current_block = durs_bc_db_reader::blocks::get_block(db, v);
match current_block {
Ok(current_block_option) => match current_block_option {
Some(block) => Ok(Some(Block {
version: block.block.version() as i32,
currency: block.block.currency().to_string(),
issuer: block.block.issuers()[0].to_string(),
number: block.block.number().0 as i32,
})),
None => Ok(None),
},
Err(_e) => Err(juniper::FieldError::from("No current block available")),
}
let db: &BcDbRo = &executor.context().get_db();
db.read(|r| {
if let Some(current_blockstamp) =
durs_bc_db_reader::current_meta_datas::get_current_blockstamp_(db, r)?
{
block::get_block(db, r, current_blockstamp.id)
} else {
Ok(None)
}
None => Ok(None),
},
Err(_e) => Err(juniper::FieldError::from("No current block available")),
})
.map_err(db_err_to_juniper_err)
}
fn field_block(
&self,
executor: &Executor<'_, Context>,
_trail: &QueryTrail<'_, Block, Walked>,
number: i32,
) -> FieldResult<Option<Block>> {
let db: &BcDbRo = &executor.context().get_db();
let block_number = if number >= 0 {
BlockNumber(number as u32)
} else {
return Err(juniper::FieldError::from("Block number must be positive."));
};
db.read(|r| block::get_block(db, r, block_number))
.map_err(|e| juniper::FieldError::from(format!("Db error: {:?}", e)))
}
}
impl BlockFields for Block {
fn field_version(&self, _executor: &Executor<'_, Context>) -> FieldResult<&i32> {
Ok(&self.version)
impl NodeFields for Node {
fn field_summary(
&self,
_executor: &Executor<'_, Context>,
_trail: &QueryTrail<'_, Summary, Walked>,
) -> &Summary {
&self.summary
}
fn field_currency(&self, _executor: &Executor<'_, Context>) -> FieldResult<&String> {
Ok(&self.currency)
}
fn field_issuer(&self, _executor: &Executor<'_, Context>) -> FieldResult<&String> {
Ok(&self.issuer)
impl SummaryFields for Summary {
fn field_software(&self, _executor: &Executor<'_, Context>) -> String {
self.software.to_owned()
}
fn field_number(&self, _executor: &Executor<'_, Context>) -> FieldResult<&i32> {
Ok(&self.number)
fn field_version(&self, _executor: &Executor<'_, Context>) -> String {
self.version.to_owned()
}
}
......
// Copyright (C) 2017-2019 The AXIOM TEAM Association.
//
// 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/>.
// ! Block model and resolvers
use crate::context::Context;
use chrono::NaiveDateTime;
use dubp_block_doc::block::BlockDocumentTrait;
use dubp_common_doc::traits::Document;
use dubp_common_doc::BlockNumber;
use durs_bc_db_reader::{BcDbRo, DbError, DbReader};
use durs_common_tools::fatal_error;
use juniper::{Executor, FieldResult};
pub struct Block {
version: i32,
currency: String,
issuer: String,
number: i32,
hash: String,
common_time: NaiveDateTime,
}
impl super::BlockFields for Block {
fn field_version(&self, _executor: &Executor<'_, Context>) -> FieldResult<&i32> {
Ok(&self.version)
}
fn field_currency(&self, _executor: &Executor<'_, Context>) -> FieldResult<&String> {
Ok(&self.currency)
}
fn field_issuer(&self, _executor: &Executor<'_, Context>) -> FieldResult<&String> {
Ok(&self.issuer)
}
fn field_number(&self, _executor: &Executor<'_, Context>) -> FieldResult<&i32> {
Ok(&self.number)
}
fn field_hash(&self, _executor: &Executor<'_, Context>) -> FieldResult<&String> {
Ok(&self.hash)
}
fn field_common_time(&self, _executor: &Executor<'_, Context>) -> FieldResult<&NaiveDateTime> {
Ok(&self.common_time)
}
}
pub fn get_block<R: DbReader>(
db: &BcDbRo,
r: &R,
block_number: BlockNumber,
) -> Result<Option<Block>, DbError> {
durs_bc_db_reader::blocks::get_db_block_in_local_blockchain(db, r, block_number).map(
|block_opt| {
block_opt.map(|db_block| Block {
version: db_block.block.version() as i32,
currency: db_block.block.currency().to_string(),
issuer: db_block.block.issuers()[0].to_string(),
number: db_block.block.number().0 as i32,
hash: db_block
.block
.hash()
.unwrap_or_else(|| fatal_error!("DbBlock without hash."))
.to_string(),
common_time: NaiveDateTime::from_timestamp(db_block.block.common_time() as i64, 0),
})
},
)
}
......@@ -68,7 +68,7 @@ pub fn start_web_server(
// Instanciate the context
let db_path = durs_conf::get_blockchain_db_path(soft_meta_datas.profile_path.clone());
if let Ok(db) = durs_bc_db_reader::open_db_ro(&std::path::Path::new(&db_path)) {
context::init(db);
context::init(db, soft_meta_datas.soft_name, soft_meta_datas.soft_version);
} else {
fatal_error!("GVA: fail to open DB.");
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment