mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
Fixes in response to review
This commit is contained in:
parent
738f505e7b
commit
202a1003ee
11 changed files with 120 additions and 24 deletions
|
|
@ -30,7 +30,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/dashboard"
|
"github.com/ethereum/go-ethereum/dashboard"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethgraphql"
|
"github.com/ethereum/go-ethereum/graphql"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
|
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
|
||||||
|
|
@ -177,7 +177,7 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
||||||
|
|
||||||
// Configure GraphQL if required
|
// Configure GraphQL if required
|
||||||
if ctx.GlobalIsSet(utils.GraphQLEnabledFlag.Name) {
|
if ctx.GlobalIsSet(utils.GraphQLEnabledFlag.Name) {
|
||||||
if err := ethgraphql.RegisterGraphQLService(stack, cfg.Node.GraphQLEndpoint(), cfg.Node.HTTPCors, cfg.Node.HTTPVirtualHosts, cfg.Node.HTTPTimeouts); err != nil {
|
if err := graphql.RegisterGraphQLService(stack, cfg.Node.GraphQLEndpoint(), cfg.Node.GraphQLCors, cfg.Node.GraphQLVirtualHosts, cfg.Node.HTTPTimeouts); err != nil {
|
||||||
utils.Fatalf("Failed to register the Ethereum service: %v", err)
|
utils.Fatalf("Failed to register the Ethereum service: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ var (
|
||||||
utils.GraphQLEnabledFlag,
|
utils.GraphQLEnabledFlag,
|
||||||
utils.GraphQLListenAddrFlag,
|
utils.GraphQLListenAddrFlag,
|
||||||
utils.GraphQLPortFlag,
|
utils.GraphQLPortFlag,
|
||||||
|
utils.GraphQLCORSDomainFlag,
|
||||||
|
utils.GraphQLVirtualHostsFlag,
|
||||||
utils.RPCApiFlag,
|
utils.RPCApiFlag,
|
||||||
utils.WSEnabledFlag,
|
utils.WSEnabledFlag,
|
||||||
utils.WSListenAddrFlag,
|
utils.WSListenAddrFlag,
|
||||||
|
|
|
||||||
|
|
@ -432,15 +432,25 @@ var (
|
||||||
Usage: "Enable the GraphQL server",
|
Usage: "Enable the GraphQL server",
|
||||||
}
|
}
|
||||||
GraphQLListenAddrFlag = cli.StringFlag{
|
GraphQLListenAddrFlag = cli.StringFlag{
|
||||||
Name: "graphqladdr",
|
Name: "graphql.addr",
|
||||||
Usage: "GraphQL server listening interface",
|
Usage: "GraphQL server listening interface",
|
||||||
Value: node.DefaultGraphQLHost,
|
Value: node.DefaultGraphQLHost,
|
||||||
}
|
}
|
||||||
GraphQLPortFlag = cli.IntFlag{
|
GraphQLPortFlag = cli.IntFlag{
|
||||||
Name: "graphqlport",
|
Name: "graphql.port",
|
||||||
Usage: "GraphQL server listening port",
|
Usage: "GraphQL server listening port",
|
||||||
Value: node.DefaultGraphQLPort,
|
Value: node.DefaultGraphQLPort,
|
||||||
}
|
}
|
||||||
|
GraphQLCORSDomainFlag = cli.StringFlag{
|
||||||
|
Name: "graphql.rpccorsdomain",
|
||||||
|
Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
|
||||||
|
Value: "",
|
||||||
|
}
|
||||||
|
GraphQLVirtualHostsFlag = cli.StringFlag{
|
||||||
|
Name: "graphql.rpcvhosts",
|
||||||
|
Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.",
|
||||||
|
Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","),
|
||||||
|
}
|
||||||
RPCCORSDomainFlag = cli.StringFlag{
|
RPCCORSDomainFlag = cli.StringFlag{
|
||||||
Name: "rpccorsdomain",
|
Name: "rpccorsdomain",
|
||||||
Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
|
Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
|
||||||
|
|
@ -811,8 +821,13 @@ func setGraphQL(ctx *cli.Context, cfg *node.Config) {
|
||||||
cfg.GraphQLHost = ctx.GlobalString(GraphQLListenAddrFlag.Name)
|
cfg.GraphQLHost = ctx.GlobalString(GraphQLListenAddrFlag.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.GraphQLPort = ctx.GlobalInt(GraphQLPortFlag.Name)
|
cfg.GraphQLPort = ctx.GlobalInt(GraphQLPortFlag.Name)
|
||||||
|
if ctx.GlobalIsSet(GraphQLCORSDomainFlag.Name) {
|
||||||
|
cfg.GraphQLCors = splitAndTrim(ctx.GlobalString(GraphQLCORSDomainFlag.Name))
|
||||||
|
}
|
||||||
|
if ctx.GlobalIsSet(GraphQLVirtualHostsFlag.Name) {
|
||||||
|
cfg.GraphQLVirtualHosts = splitAndTrim(ctx.GlobalString(GraphQLVirtualHostsFlag.Name))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setWS creates the WebSocket RPC listener interface string from the set
|
// setWS creates the WebSocket RPC listener interface string from the set
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,10 @@ func (b Bytes) String() string {
|
||||||
return Encode(b)
|
return Encode(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImplementsGraphQLType returns true if Bytes implements the specified GraphQL type.
|
||||||
func (b Bytes) ImplementsGraphQLType(name string) bool { return name == "Bytes" }
|
func (b Bytes) ImplementsGraphQLType(name string) bool { return name == "Bytes" }
|
||||||
|
|
||||||
|
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
|
||||||
func (b *Bytes) UnmarshalGraphQL(input interface{}) error {
|
func (b *Bytes) UnmarshalGraphQL(input interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
switch input := input.(type) {
|
switch input := input.(type) {
|
||||||
|
|
@ -204,8 +206,10 @@ func (b *Big) String() string {
|
||||||
return EncodeBig(b.ToInt())
|
return EncodeBig(b.ToInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImplementsGraphQLType returns true if Big implements the provided GraphQL type.
|
||||||
func (b Big) ImplementsGraphQLType(name string) bool { return name == "BigInt" }
|
func (b Big) ImplementsGraphQLType(name string) bool { return name == "BigInt" }
|
||||||
|
|
||||||
|
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
|
||||||
func (b *Big) UnmarshalGraphQL(input interface{}) error {
|
func (b *Big) UnmarshalGraphQL(input interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
switch input := input.(type) {
|
switch input := input.(type) {
|
||||||
|
|
@ -268,8 +272,10 @@ func (b Uint64) String() string {
|
||||||
return EncodeUint64(uint64(b))
|
return EncodeUint64(uint64(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImplementsGraphQLType returns true if Uint64 implements the provided GraphQL type.
|
||||||
func (b Uint64) ImplementsGraphQLType(name string) bool { return name == "Long" }
|
func (b Uint64) ImplementsGraphQLType(name string) bool { return name == "Long" }
|
||||||
|
|
||||||
|
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
|
||||||
func (b *Uint64) UnmarshalGraphQL(input interface{}) error {
|
func (b *Uint64) UnmarshalGraphQL(input interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
switch input := input.(type) {
|
switch input := input.(type) {
|
||||||
|
|
|
||||||
|
|
@ -141,8 +141,10 @@ func (h Hash) Value() (driver.Value, error) {
|
||||||
return h[:], nil
|
return h[:], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
|
||||||
func (_ Hash) ImplementsGraphQLType(name string) bool { return name == "Bytes32" }
|
func (_ Hash) ImplementsGraphQLType(name string) bool { return name == "Bytes32" }
|
||||||
|
|
||||||
|
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
|
||||||
func (h *Hash) UnmarshalGraphQL(input interface{}) error {
|
func (h *Hash) UnmarshalGraphQL(input interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
switch input := input.(type) {
|
switch input := input.(type) {
|
||||||
|
|
@ -281,8 +283,10 @@ func (a Address) Value() (driver.Value, error) {
|
||||||
return a[:], nil
|
return a[:], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
|
||||||
func (a Address) ImplementsGraphQLType(name string) bool { return name == "Address" }
|
func (a Address) ImplementsGraphQLType(name string) bool { return name == "Address" }
|
||||||
|
|
||||||
|
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
|
||||||
func (a *Address) UnmarshalGraphQL(input interface{}) error {
|
func (a *Address) UnmarshalGraphQL(input interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
switch input := input.(type) {
|
switch input := input.(type) {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package ethgraphql
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBuildSchema(t *testing.T) {
|
|
||||||
// Make sure the schema can be parsed and matched up to the object model.
|
|
||||||
_, err := NewHandler(nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Could not construct GraphQL handler: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -14,7 +14,8 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package ethgraphql
|
// Package graphql provides a GraphQL interface to Ethereum node data.
|
||||||
|
package graphql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -38,7 +39,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
graphql "github.com/graph-gophers/graphql-go"
|
graphqlgo "github.com/graph-gophers/graphql-go"
|
||||||
"github.com/graph-gophers/graphql-go/relay"
|
"github.com/graph-gophers/graphql-go/relay"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1021,7 +1022,7 @@ func (r *Resolver) Syncing() (*SyncState, error) {
|
||||||
func NewHandler(be *eth.EthAPIBackend) (http.Handler, error) {
|
func NewHandler(be *eth.EthAPIBackend) (http.Handler, error) {
|
||||||
q := Resolver{be}
|
q := Resolver{be}
|
||||||
|
|
||||||
s, err := graphql.ParseSchema(schema, &q)
|
s, err := graphqlgo.ParseSchema(schema, &q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1034,7 +1035,7 @@ func NewHandler(be *eth.EthAPIBackend) (http.Handler, error) {
|
||||||
return mux, nil
|
return mux, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service encapsulates an ETHGraphQL service.
|
// Service encapsulates a GraphQL service.
|
||||||
type Service struct {
|
type Service struct {
|
||||||
endpoint string // The host:port endpoint for this service.
|
endpoint string // The host:port endpoint for this service.
|
||||||
cors []string // Allowed CORS domains
|
cors []string // Allowed CORS domains
|
||||||
|
|
@ -1,4 +1,26 @@
|
||||||
package ethgraphql
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2016 Muhammed Thanish
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package graphql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
29
graphql/graphql_test.go
Normal file
29
graphql/graphql_test.go
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2018 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library 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 go-ethereum library 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package graphql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuildSchema(t *testing.T) {
|
||||||
|
// Make sure the schema can be parsed and matched up to the object model.
|
||||||
|
_, err := NewHandler(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Could not construct GraphQL handler: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,20 @@
|
||||||
package ethgraphql
|
// Copyright 2018 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library 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 go-ethereum library 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package graphql
|
||||||
|
|
||||||
const schema string = `
|
const schema string = `
|
||||||
# Bytes32 is a 32 byte binary string, represented as 0x-prefixed hexadecimal.
|
# Bytes32 is a 32 byte binary string, represented as 0x-prefixed hexadecimal.
|
||||||
|
|
@ -110,6 +110,20 @@ type Config struct {
|
||||||
// for ephemeral nodes).
|
// for ephemeral nodes).
|
||||||
GraphQLPort int `toml:",omitempty"`
|
GraphQLPort int `toml:",omitempty"`
|
||||||
|
|
||||||
|
// GraphQLCors is the Cross-Origin Resource Sharing header to send to requesting
|
||||||
|
// clients. Please be aware that CORS is a browser enforced security, it's fully
|
||||||
|
// useless for custom HTTP clients.
|
||||||
|
GraphQLCors []string `toml:",omitempty"`
|
||||||
|
|
||||||
|
// GraphQLVirtualHosts is the list of virtual hostnames which are allowed on incoming requests.
|
||||||
|
// This is by default {'localhost'}. Using this prevents attacks like
|
||||||
|
// DNS rebinding, which bypasses SOP by simply masquerading as being within the same
|
||||||
|
// origin. These attacks do not utilize CORS, since they are not cross-domain.
|
||||||
|
// By explicitly checking the Host-header, the server will not allow requests
|
||||||
|
// made against the server with a malicious host domain.
|
||||||
|
// Requests using ip address directly are not affected
|
||||||
|
GraphQLVirtualHosts []string `toml:",omitempty"`
|
||||||
|
|
||||||
// HTTPCors is the Cross-Origin Resource Sharing header to send to requesting
|
// HTTPCors is the Cross-Origin Resource Sharing header to send to requesting
|
||||||
// clients. Please be aware that CORS is a browser enforced security, it's fully
|
// clients. Please be aware that CORS is a browser enforced security, it's fully
|
||||||
// useless for custom HTTP clients.
|
// useless for custom HTTP clients.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue