Skip to content
This repository has been archived by the owner on Sep 13, 2022. It is now read-only.

feat: Update juniper, supports async #149

Merged
merged 3 commits into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ common-crypto = { path = "../../common/crypto"}

http-service = "0.4"
http = "0.2"
tide = "0.5"
juniper = "0.14"
tide = "0.6"
juniper = { git = "https://github.com/graphql-rust/juniper", rev = "eff086a", features = ["async"] }
juniper_codegen = "0.14"
async-trait = "0.1"
hex = "0.4"
Expand Down
90 changes: 48 additions & 42 deletions core/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#[macro_use]
extern crate juniper_codegen;

pub mod adapter;
pub mod config;
mod schema;
Expand All @@ -10,7 +7,7 @@ use std::sync::Arc;

use futures::executor::block_on;
use http::status::StatusCode;
use juniper::{FieldError, FieldResult};
use juniper::FieldResult;
use tide::{Request, Response, ResultExt, Server};

use common_crypto::{
Expand Down Expand Up @@ -38,51 +35,52 @@ struct State {
// context.
struct Query;
// Switch to async/await fn https://github.com/graphql-rust/juniper/issues/2
#[juniper::object(Context = State)]
#[juniper::graphql_object(Context = State)]
impl Query {
#[graphql(name = "getBlock", description = "Get the block")]
fn get_latest_block(state_ctx: &State, height: Option<Uint64>) -> FieldResult<Block> {
async fn get_latest_block(state_ctx: &State, height: Option<Uint64>) -> FieldResult<Block> {
let height = match height {
Some(id) => Some(id.try_into_u64()?),
None => None,
};

let block = block_on(
state_ctx
.adapter
.get_block_by_height(Context::new(), height),
)?;
let block = state_ctx
.adapter
.get_block_by_height(Context::new(), height)
.await?;

Ok(Block::from(block))
}

#[graphql(name = "getTransaction", description = "Get the transaction by hash")]
fn get_transaction(state_ctx: &State, tx_hash: Hash) -> FieldResult<SignedTransaction> {
async fn get_transaction(state_ctx: &State, tx_hash: Hash) -> FieldResult<SignedTransaction> {
let hash = protocol::types::Hash::from_hex(&tx_hash.as_hex())?;
let stx = block_on(
state_ctx
.adapter
.get_transaction_by_hash(Context::new(), hash),
)?;

let stx = state_ctx
.adapter
.get_transaction_by_hash(Context::new(), hash)
.await?;

Ok(SignedTransaction::from(stx))
}

#[graphql(
name = "getReceipt",
description = "Get the receipt by transaction hash"
)]
fn get_receipt(state_ctx: &State, tx_hash: Hash) -> FieldResult<Receipt> {
async fn get_receipt(state_ctx: &State, tx_hash: Hash) -> FieldResult<Receipt> {
let hash = protocol::types::Hash::from_hex(&tx_hash.as_hex())?;
let receipt = block_on(
state_ctx
.adapter
.get_receipt_by_tx_hash(Context::new(), hash),
)?;

let receipt = state_ctx
.adapter
.get_receipt_by_tx_hash(Context::new(), hash)
.await?;

Ok(Receipt::from(receipt))
}

#[graphql(name = "queryService", description = "query service")]
fn query_service(
async fn query_service(
state_ctx: &State,
height: Option<Uint64>,
cycles_limit: Option<Uint64>,
Expand Down Expand Up @@ -112,35 +110,40 @@ impl Query {

let address = protocol::types::Address::from_hex(&caller.as_hex())?;

let exec_resp = block_on(state_ctx.adapter.query_service(
Context::new(),
height,
cycles_limit,
cycles_price,
address,
service_name,
method,
payload,
))?;
let exec_resp = state_ctx
.adapter
.query_service(
Context::new(),
height,
cycles_limit,
cycles_price,
address,
service_name,
method,
payload,
)
.await?;
Ok(ExecResp::from(exec_resp))
}
}

struct Mutation;
// Switch to async/await fn https://github.com/graphql-rust/juniper/issues/2
#[juniper::object(Context = State)]
#[juniper::graphql_object(Context = State)]
impl Mutation {
#[graphql(name = "sendTransaction", description = "send transaction")]
fn send_transaction(
async fn send_transaction(
state_ctx: &State,
input_raw: InputRawTransaction,
input_encryption: InputTransactionEncryption,
) -> FieldResult<Hash> {
let stx = to_signed_transaction(input_raw, input_encryption)?;
let tx_hash = stx.tx_hash.clone();

block_on(state_ctx.adapter.insert_signed_txs(Context::new(), stx))
.map_err(FieldError::from)?;
state_ctx
.adapter
.insert_signed_txs(Context::new(), stx)
.await?;

Ok(Hash::from(tx_hash))
}
Expand All @@ -149,7 +152,7 @@ impl Mutation {
name = "unsafeSendTransaction",
deprecated = "DON'T use it in production! This is just for development."
)]
fn unsafe_send_transaction(
async fn unsafe_send_transaction(
state_ctx: &State,
input_raw: InputRawTransaction,
input_privkey: Bytes,
Expand All @@ -168,8 +171,10 @@ impl Mutation {
signature: signature.to_bytes(),
pubkey: pubkey.to_bytes(),
};
block_on(state_ctx.adapter.insert_signed_txs(Context::new(), stx))
.map_err(FieldError::from)?;
state_ctx
.adapter
.insert_signed_txs(Context::new(), stx)
.await?;

Ok(Hash::from(tx_hash))
}
Expand All @@ -191,7 +196,8 @@ async fn handle_graphql(mut req: Request<State>) -> Response {
};

let schema = Schema::new(Query, Mutation);
let response = query.execute(&schema, req.state());
let state = &req.state().clone();
let response = query.execute_async(&schema, state).await;
let status = if response.is_ok() {
StatusCode::OK
} else {
Expand Down
8 changes: 4 additions & 4 deletions core/api/src/schema/block.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::schema::{Address, Bytes, Hash, MerkleRoot, Uint64};

#[derive(GraphQLObject, Clone)]
#[derive(juniper::GraphQLObject, Clone)]
#[graphql(
description = "Block is a single digital record created within a blockchain. \
Each block contains a record of the previous Block, \
Expand All @@ -14,7 +14,7 @@ pub struct Block {
ordered_tx_hashes: Vec<Hash>,
}

#[derive(GraphQLObject, Clone)]
#[derive(juniper::GraphQLObject, Clone)]
#[graphql(description = "A block header is like the metadata of a block.")]
pub struct BlockHeader {
#[graphql(
Expand Down Expand Up @@ -47,7 +47,7 @@ pub struct BlockHeader {
pub validators: Vec<Validator>,
}

#[derive(GraphQLObject, Clone)]
#[derive(juniper::GraphQLObject, Clone)]
#[graphql(description = "The verifier of the block header proved")]
pub struct Proof {
pub height: Uint64,
Expand All @@ -57,7 +57,7 @@ pub struct Proof {
pub bitmap: Bytes,
}

#[derive(GraphQLObject, Clone)]
#[derive(juniper::GraphQLObject, Clone)]
#[graphql(description = "Validator address set")]
pub struct Validator {
pub address: Address,
Expand Down
10 changes: 5 additions & 5 deletions core/api/src/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub use transaction::{
SignedTransaction,
};

#[derive(GraphQLObject, Clone)]
#[derive(juniper::GraphQLObject, Clone)]
pub struct ExecResp {
ret: String,
is_error: bool,
Expand All @@ -31,20 +31,20 @@ impl From<protocol::traits::ExecResp> for ExecResp {
}
}

#[derive(GraphQLScalarValue, Clone)]
#[derive(juniper::GraphQLScalarValue, Clone)]
#[graphql(description = "The output digest of Keccak hash function")]
pub struct Hash(String);
pub type MerkleRoot = Hash;

#[derive(GraphQLScalarValue, Clone)]
#[derive(juniper::GraphQLScalarValue, Clone)]
#[graphql(description = "20 bytes of account address")]
pub struct Address(String);

#[derive(GraphQLScalarValue, Clone)]
#[derive(juniper::GraphQLScalarValue, Clone)]
#[graphql(description = "Uint64")]
pub struct Uint64(String);

#[derive(GraphQLScalarValue, Clone)]
#[derive(juniper::GraphQLScalarValue, Clone)]
#[graphql(description = "Bytes corresponding hex string.")]
pub struct Bytes(String);

Expand Down
6 changes: 3 additions & 3 deletions core/api/src/schema/receipt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::schema::{Hash, MerkleRoot, Uint64};

#[derive(GraphQLObject, Clone)]
#[derive(juniper::GraphQLObject, Clone)]
pub struct Receipt {
pub state_root: MerkleRoot,
pub height: Uint64,
Expand All @@ -10,13 +10,13 @@ pub struct Receipt {
pub response: ReceiptResponse,
}

#[derive(GraphQLObject, Clone)]
#[derive(juniper::GraphQLObject, Clone)]
pub struct Event {
pub service: String,
pub data: String,
}

#[derive(GraphQLObject, Clone)]
#[derive(juniper::GraphQLObject, Clone)]
pub struct ReceiptResponse {
pub service_name: String,
pub method: String,
Expand Down
6 changes: 3 additions & 3 deletions core/api/src/schema/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use protocol::ProtocolResult;

use crate::schema::{Bytes, Hash, SchemaError, Uint64};

#[derive(GraphQLObject, Clone)]
#[derive(juniper::GraphQLObject, Clone)]
pub struct SignedTransaction {
pub chain_id: Hash,
pub cycles_limit: Uint64,
Expand Down Expand Up @@ -39,7 +39,7 @@ impl From<protocol::types::SignedTransaction> for SignedTransaction {
// GraphQLInputObject
// #####################

#[derive(GraphQLInputObject, Clone)]
#[derive(juniper::GraphQLInputObject, Clone)]
#[graphql(description = "There was many types of transaction in Muta, \
A transaction often require computing resources or write data to chain,\
these resources are valuable so we need to pay some token for them.\
Expand Down Expand Up @@ -68,7 +68,7 @@ pub struct InputRawTransaction {
pub payload: String,
}

#[derive(GraphQLInputObject, Clone)]
#[derive(juniper::GraphQLInputObject, Clone)]
#[graphql(description = "Signature of the transaction")]
pub struct InputTransactionEncryption {
#[graphql(description = "The digest of the transaction")]
Expand Down