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

Commit

Permalink
feat: Update juniper, supports async (#149)
Browse files Browse the repository at this point in the history
* feat: Update juniper

* fix ci

* fix ci
  • Loading branch information
yejiayu authored Feb 7, 2020
1 parent 05f6396 commit cbabf50
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 59 deletions.
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

0 comments on commit cbabf50

Please sign in to comment.