Skip to content

Commit

Permalink
implement graphql api (#1274)
Browse files Browse the repository at this point in the history
  • Loading branch information
laizy committed Oct 26, 2020
1 parent dd99dc4 commit 15f7791
Show file tree
Hide file tree
Showing 14 changed files with 1,032 additions and 16 deletions.
8 changes: 8 additions & 0 deletions cmd/config.go
Expand Up @@ -40,10 +40,12 @@ func SetOntologyConfig(ctx *cli.Context) (*config.OntologyConfig, error) {
setP2PNodeConfig(ctx, cfg.P2PNode)
setRpcConfig(ctx, cfg.Rpc)
setRestfulConfig(ctx, cfg.Restful)
setGraphQLConfig(ctx, cfg.GraphQL)
setWebSocketConfig(ctx, cfg.Ws)
if cfg.Genesis.ConsensusType == config.CONSENSUS_TYPE_SOLO {
cfg.Ws.EnableHttpWs = true
cfg.Restful.EnableHttpRestful = true
cfg.GraphQL.EnableGraphQL = true
cfg.Consensus.EnableConsensus = true
cfg.P2PNode.NetworkId = config.NETWORK_ID_SOLO_NET
cfg.P2PNode.NetworkName = config.GetNetworkName(cfg.P2PNode.NetworkId)
Expand Down Expand Up @@ -187,6 +189,12 @@ func setRestfulConfig(ctx *cli.Context, cfg *config.RestfulConfig) {
cfg.HttpMaxConnections = ctx.Uint(utils.GetFlagName(utils.RestfulMaxConnsFlag))
}

func setGraphQLConfig(ctx *cli.Context, cfg *config.GraphQLConfig) {
cfg.EnableGraphQL = ctx.Bool(utils.GetFlagName(utils.GraphQLEnableFlag))
cfg.GraphQLPort = ctx.Uint(utils.GetFlagName(utils.GraphQLPortFlag))
cfg.MaxConnections = ctx.Uint(utils.GetFlagName(utils.GraphQLMaxConnsFlag))
}

func setWebSocketConfig(ctx *cli.Context, cfg *config.WebSocketConfig) {
cfg.EnableHttpWs = ctx.Bool(utils.GetFlagName(utils.WsEnabledFlag))
cfg.HttpWsPort = ctx.Uint(utils.GetFlagName(utils.WsPortFlag))
Expand Down
8 changes: 8 additions & 0 deletions cmd/usage.go
Expand Up @@ -177,6 +177,14 @@ var AppHelpFlagGroups = []flagGroup{
utils.RestfulMaxConnsFlag,
},
},
{
Name: "GRAPHQL",
Flags: []cli.Flag{
utils.GraphQLEnableFlag,
utils.GraphQLPortFlag,
utils.GraphQLMaxConnsFlag,
},
},
{
Name: "WEB SOCKET",
Flags: []cli.Flag{
Expand Down
20 changes: 17 additions & 3 deletions cmd/utils/flags.go
Expand Up @@ -82,7 +82,6 @@ var (
Usage: "Block data storage `<path>`",
Value: config.DEFAULT_DATA_DIR,
}

//Consensus setting
EnableConsensusFlag = cli.BoolFlag{
Name: "enable-consensus",
Expand All @@ -103,7 +102,6 @@ var (
Usage: "Min gas price `<value>` of transaction to be accepted by tx pool.",
Value: config.DEFAULT_GAS_PRICE,
}

//Test Mode setting
EnableTestModeFlag = cli.BoolFlag{
Name: "testmode",
Expand Down Expand Up @@ -199,7 +197,23 @@ var (
RestfulMaxConnsFlag = cli.UintFlag{
Name: "restmaxconns",
Usage: "Restful server maximum connections `<number>`",
Value: config.DEFAULT_REST_MAX_CONN,
Value: config.DEFAULT_HTTP_MAX_CONN,
}

//GraphQL setting
GraphQLEnableFlag = cli.BoolFlag{
Name: "graphql",
Usage: "Enable graphql api server",
}
GraphQLPortFlag = cli.UintFlag{
Name: "graphql-port",
Usage: "GraphQL server listening port `<number>`",
Value: config.DEFAULT_GRAPHQL_PORT,
}
GraphQLMaxConnsFlag = cli.UintFlag{
Name: "graphql-max-connection",
Usage: "GraphQL server maximum connections `<number>`",
Value: config.DEFAULT_HTTP_MAX_CONN,
}

//Account setting
Expand Down
20 changes: 20 additions & 0 deletions common/common.go
Expand Up @@ -20,8 +20,11 @@ package common

import (
"encoding/hex"
"fmt"
"math/rand"
"os"

"github.com/ontio/ontology-crypto/keypair"
)

// GetNonce returns random nonce
Expand Down Expand Up @@ -55,3 +58,20 @@ func FileExisted(filename string) bool {
_, err := os.Stat(filename)
return err == nil || os.IsExist(err)
}

func PubKeyToHex(pub keypair.PublicKey) string {
nodeid := hex.EncodeToString(keypair.SerializePublicKey(pub))
return nodeid
}

func PubKeyFromHex(nodeid string) (keypair.PublicKey, error) {
pubKey, err := hex.DecodeString(nodeid)
if err != nil {
return nil, err
}
pk, err := keypair.DeserializePublicKey(pubKey)
if err != nil {
return nil, fmt.Errorf("deserialize failed: %s", err)
}
return pk, err
}
14 changes: 13 additions & 1 deletion common/config/config.go
Expand Up @@ -60,9 +60,10 @@ const (
DEFAULT_NODE_PORT = 20338
DEFAULT_RPC_PORT = 20336
DEFAULT_RPC_LOCAL_PORT = 20337
DEFAULT_GRAPHQL_PORT = 20333
DEFAULT_REST_PORT = 20334
DEFAULT_WS_PORT = 20335
DEFAULT_REST_MAX_CONN = 1024
DEFAULT_HTTP_MAX_CONN = 1024
DEFAULT_MAX_CONN_IN_BOUND = 1024
DEFAULT_MAX_CONN_OUT_BOUND = 1024
DEFAULT_MAX_CONN_IN_BOUND_FOR_SINGLE_IP = 16
Expand Down Expand Up @@ -648,6 +649,12 @@ type RestfulConfig struct {
HttpKeyPath string
}

type GraphQLConfig struct {
EnableGraphQL bool
GraphQLPort uint
MaxConnections uint
}

type WebSocketConfig struct {
EnableHttpWs bool
HttpWsPort uint
Expand All @@ -662,6 +669,7 @@ type OntologyConfig struct {
P2PNode *P2PNodeConfig
Rpc *RpcConfig
Restful *RestfulConfig
GraphQL *GraphQLConfig
Ws *WebSocketConfig
}

Expand Down Expand Up @@ -706,6 +714,10 @@ func NewOntologyConfig() *OntologyConfig {
EnableHttpRestful: true,
HttpRestPort: DEFAULT_REST_PORT,
},
GraphQL: &GraphQLConfig{
EnableGraphQL: false,
GraphQLPort: DEFAULT_GRAPHQL_PORT,
},
Ws: &WebSocketConfig{
EnableHttpWs: true,
HttpWsPort: DEFAULT_WS_PORT,
Expand Down
15 changes: 3 additions & 12 deletions consensus/vbft/config/types.go
Expand Up @@ -19,30 +19,21 @@
package vconfig

import (
"encoding/hex"
"encoding/json"
"fmt"

"github.com/ontio/ontology-crypto/keypair"
"github.com/ontio/ontology/common"
"github.com/ontio/ontology/core/types"
)

// PubkeyID returns a marshaled representation of the given public key.
func PubkeyID(pub keypair.PublicKey) string {
nodeid := hex.EncodeToString(keypair.SerializePublicKey(pub))
return nodeid
return common.PubKeyToHex(pub)
}

func Pubkey(nodeid string) (keypair.PublicKey, error) {
pubKey, err := hex.DecodeString(nodeid)
if err != nil {
return nil, err
}
pk, err := keypair.DeserializePublicKey(pubKey)
if err != nil {
return nil, fmt.Errorf("deserialize failed: %s", err)
}
return pk, err
return common.PubKeyFromHex(nodeid)
}

func VbftBlock(header *types.Header) (*VbftBlockInfo, error) {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -11,6 +11,7 @@ require (
github.com/gorilla/websocket v1.4.1
github.com/gosuri/uilive v0.0.3 // indirect
github.com/gosuri/uiprogress v0.0.1
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277
github.com/hashicorp/golang-lru v0.5.3
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c
github.com/itchyny/base58-go v0.1.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -102,6 +102,7 @@ github.com/gosuri/uilive v0.0.3 h1:kvo6aB3pez9Wbudij8srWo4iY6SFTTxTKOkb+uRCE8I=
github.com/gosuri/uilive v0.0.3/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8=
github.com/gosuri/uiprogress v0.0.1 h1:0kpv/XY/qTmFWl/SkaJykZXrBBzwwadmW8fRb7RJSxw=
github.com/gosuri/uiprogress v0.0.1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277 h1:E0whKxgp2ojts0FDgUA8dl62bmH0LxKanMoBr6MDTDM=
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
Expand Down Expand Up @@ -157,6 +158,7 @@ github.com/ontio/ontology-eventbus v0.9.1 h1:nt3AXWx3gOyqtLiU4EwI92Yc4ik/pWHu9xR
github.com/ontio/ontology-eventbus v0.9.1/go.mod h1:hCQIlbdPckcfykMeVUdWrqHZ8d30TBdmLfXCVWGkYhM=
github.com/ontio/wagon v0.4.1 h1:3A8BxTMVGrQnyWxD1h8w5PLvN9GZMWjC75Jw+5Vgpe0=
github.com/ontio/wagon v0.4.1/go.mod h1:oTPdgWT7WfPlEyzVaHSn1vQPMSbOpQPv+WphxibWlhg=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6 h1:lNCW6THrCKBiJBpz8kbVGjC7MgdCGKwuvBgc7LoD6sw=
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
Expand Down
171 changes: 171 additions & 0 deletions http/graphql/scalar.go
@@ -0,0 +1,171 @@
/*
* Copyright (C) 2018 The ontology Authors
* This file is part of The ontology library.
*
* The ontology is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ontology 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with The ontology. If not, see <http://www.gnu.org/licenses/>.
*/
package graphql

import (
"encoding/json"
"fmt"
"strconv"
"strings"

"github.com/ontio/ontology/common"
)

type Uint32 uint32

func (Uint32) ImplementsGraphQLType(name string) bool {
return name == "Uint32"
}

func (t *Uint32) UnmarshalGraphQL(input interface{}) error {
switch input := input.(type) {
case uint32:
*t = Uint32(input)
return nil
case int32:
*t = Uint32(input)
return nil
case int64:
*t = Uint32(input)
return nil
default:
return fmt.Errorf("wrong type for Uint32: %T", input)
}
}

func (t Uint32) MarshalJSON() ([]byte, error) {
return json.Marshal(uint32(t))
}

type Uint64 uint64

func (Uint64) ImplementsGraphQLType(name string) bool {
return name == "Uint64"
}

func (t *Uint64) UnmarshalGraphQL(input interface{}) error {
switch input := input.(type) {
case uint32:
*t = Uint64(input)
case int32:
*t = Uint64(input)
case int:
*t = Uint64(input)
case uint:
*t = Uint64(input)
case uint64:
*t = Uint64(input)
case int64:
*t = Uint64(input)
case string:
val, err := strconv.ParseUint(input, 10, 64)
if err != nil {
return fmt.Errorf("wrong type for Uint64: %T", input)
}
*t = Uint64(val)
default:
return fmt.Errorf("wrong type for Uint64: %T", input)
}
return nil
}

func (t Uint64) MarshalJSON() ([]byte, error) {
return json.Marshal(strconv.FormatUint(uint64(t), 10))
}

type Addr struct {
common.Address
}

func (Addr) ImplementsGraphQLType(name string) bool {
return name == "Address"
}

func (t *Addr) UnmarshalGraphQL(input interface{}) error {
var err error
switch input := input.(type) {
case string:
if strings.HasPrefix(input, "0x") {
t.Address, err = common.AddressFromHexString(input[2:])
}

if err == nil {
t.Address, err = common.AddressFromBase58(input)
}
default:
return fmt.Errorf("wrong type for Address: %T", input)
}
return err
}

func (t Addr) MarshalJSON() ([]byte, error) {
return json.Marshal(t.Address.ToBase58())
}

type H256 common.Uint256

func (H256) ImplementsGraphQLType(name string) bool {
return name == "H256"
}

func (t *H256) UnmarshalGraphQL(input interface{}) error {
switch input := input.(type) {
case string:
if strings.HasPrefix(input, "0x") {
input = input[2:]
}

hash, err := common.Uint256FromHexString(input)
if err != nil {
return err
}
*t = H256(hash)
return nil
default:
return fmt.Errorf("wrong type for H256: %T", input)
}
}

func (t H256) MarshalJSON() ([]byte, error) {
hash := common.Uint256(t)
return json.Marshal(hash.ToHexString())
}

type PubKey string

func (PubKey) ImplementsGraphQLType(name string) bool {
return name == "PubKey"
}

func (key *PubKey) UnmarshalGraphQL(input interface{}) error {
switch input := input.(type) {
case string:
_, err := common.PubKeyFromHex(input)
if err != nil {
return err
}
*key = PubKey(input)
return nil
default:
return fmt.Errorf("wrong type for PubKey: %T", input)
}
}

func (key PubKey) MarshalJSON() ([]byte, error) {
return json.Marshal(string(key))
}

0 comments on commit 15f7791

Please sign in to comment.