Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
e3ec77f5
Unverified
Commit
e3ec77f5
authored
Jun 12, 2019
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd, graphql, node: graphql flag polishes, les integration
parent
2b546660
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
203 additions
and
164 deletions
+203
-164
config.go
cmd/geth/config.go
+2
-7
usage.go
cmd/geth/usage.go
+9
-4
flags.go
cmd/utils/flags.go
+56
-34
graphiql.go
graphql/graphiql.go
+5
-5
graphql.go
graphql/graphql.go
+7
-103
graphql_test.go
graphql/graphql_test.go
+1
-2
service.go
graphql/service.go
+103
-0
backend.go
internal/ethapi/backend.go
+11
-2
defaults.go
node/defaults.go
+9
-7
No files found.
cmd/geth/config.go
View file @
e3ec77f5
...
...
@@ -30,7 +30,6 @@ import (
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/dashboard"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/graphql"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"
whisper
"github.com/ethereum/go-ethereum/whisper/whisperv6"
...
...
@@ -177,14 +176,10 @@ func makeFullNode(ctx *cli.Context) *node.Node {
}
utils
.
RegisterShhService
(
stack
,
&
cfg
.
Shh
)
}
// Configure GraphQL if required
// Configure GraphQL if requested
if
ctx
.
GlobalIsSet
(
utils
.
GraphQLEnabledFlag
.
Name
)
{
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
.
RegisterGraphQLService
(
stack
,
cfg
.
Node
.
GraphQLEndpoint
(),
cfg
.
Node
.
GraphQLCors
,
cfg
.
Node
.
GraphQLVirtualHosts
,
cfg
.
Node
.
HTTPTimeouts
)
}
// Add the Ethereum Stats daemon if requested.
if
cfg
.
Ethstats
.
URL
!=
""
{
utils
.
RegisterEthStatsService
(
stack
,
cfg
.
Ethstats
.
URL
)
...
...
cmd/geth/usage.go
View file @
e3ec77f5
...
...
@@ -156,20 +156,25 @@ var AppHelpFlagGroups = []flagGroup{
{
Name
:
"API AND CONSOLE"
,
Flags
:
[]
cli
.
Flag
{
utils
.
IPCDisabledFlag
,
utils
.
IPCPathFlag
,
utils
.
RPCEnabledFlag
,
utils
.
RPCListenAddrFlag
,
utils
.
RPCPortFlag
,
utils
.
RPCApiFlag
,
utils
.
RPCGlobalGasCap
,
utils
.
RPCCORSDomainFlag
,
utils
.
RPCVirtualHostsFlag
,
utils
.
WSEnabledFlag
,
utils
.
WSListenAddrFlag
,
utils
.
WSPortFlag
,
utils
.
WSApiFlag
,
utils
.
WSAllowedOriginsFlag
,
utils
.
IPCDisabledFlag
,
utils
.
IPCPathFlag
,
utils
.
RPCCORSDomainFlag
,
utils
.
RPCVirtualHostsFlag
,
utils
.
GraphQLEnabledFlag
,
utils
.
GraphQLListenAddrFlag
,
utils
.
GraphQLPortFlag
,
utils
.
GraphQLCORSDomainFlag
,
utils
.
GraphQLVirtualHostsFlag
,
utils
.
JSpathFlag
,
utils
.
ExecFlag
,
utils
.
PreloadJSFlag
,
...
...
cmd/utils/flags.go
View file @
e3ec77f5
...
...
@@ -20,6 +20,7 @@ package utils
import
(
"crypto/ecdsa"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"math/big"
...
...
@@ -45,6 +46,7 @@ import (
"github.com/ethereum/go-ethereum/eth/gasprice"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethstats"
"github.com/ethereum/go-ethereum/graphql"
"github.com/ethereum/go-ethereum/les"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
...
...
@@ -57,6 +59,7 @@ import (
"github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/p2p/netutil"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
whisper
"github.com/ethereum/go-ethereum/whisper/whisperv6"
pcsclite
"github.com/gballet/go-libpcsclite"
cli
"gopkg.in/urfave/cli.v1"
...
...
@@ -474,6 +477,14 @@ var (
Usage
:
"Disables db compaction after import"
,
}
// RPC settings
IPCDisabledFlag
=
cli
.
BoolFlag
{
Name
:
"ipcdisable"
,
Usage
:
"Disable the IPC-RPC server"
,
}
IPCPathFlag
=
DirectoryFlag
{
Name
:
"ipcpath"
,
Usage
:
"Filename for IPC socket/pipe within the datadir (explicit paths escape it)"
,
}
RPCEnabledFlag
=
cli
.
BoolFlag
{
Name
:
"rpc"
,
Usage
:
"Enable the HTTP-RPC server"
,
...
...
@@ -488,30 +499,6 @@ var (
Usage
:
"HTTP-RPC server listening port"
,
Value
:
node
.
DefaultHTTPPort
,
}
GraphQLEnabledFlag
=
cli
.
BoolFlag
{
Name
:
"graphql"
,
Usage
:
"Enable the GraphQL server"
,
}
GraphQLListenAddrFlag
=
cli
.
StringFlag
{
Name
:
"graphql.addr"
,
Usage
:
"GraphQL server listening interface"
,
Value
:
node
.
DefaultGraphQLHost
,
}
GraphQLPortFlag
=
cli
.
IntFlag
{
Name
:
"graphql.port"
,
Usage
:
"GraphQL server listening port"
,
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
{
Name
:
"rpccorsdomain"
,
Usage
:
"Comma separated list of domains from which to accept cross origin requests (browser enforced)"
,
...
...
@@ -527,14 +514,6 @@ var (
Usage
:
"API's offered over the HTTP-RPC interface"
,
Value
:
""
,
}
IPCDisabledFlag
=
cli
.
BoolFlag
{
Name
:
"ipcdisable"
,
Usage
:
"Disable the IPC-RPC server"
,
}
IPCPathFlag
=
DirectoryFlag
{
Name
:
"ipcpath"
,
Usage
:
"Filename for IPC socket/pipe within the datadir (explicit paths escape it)"
,
}
WSEnabledFlag
=
cli
.
BoolFlag
{
Name
:
"ws"
,
Usage
:
"Enable the WS-RPC server"
,
...
...
@@ -559,6 +538,30 @@ var (
Usage
:
"Origins from which to accept websockets requests"
,
Value
:
""
,
}
GraphQLEnabledFlag
=
cli
.
BoolFlag
{
Name
:
"graphql"
,
Usage
:
"Enable the GraphQL server"
,
}
GraphQLListenAddrFlag
=
cli
.
StringFlag
{
Name
:
"graphql.addr"
,
Usage
:
"GraphQL server listening interface"
,
Value
:
node
.
DefaultGraphQLHost
,
}
GraphQLPortFlag
=
cli
.
IntFlag
{
Name
:
"graphql.port"
,
Usage
:
"GraphQL server listening port"
,
Value
:
node
.
DefaultGraphQLPort
,
}
GraphQLCORSDomainFlag
=
cli
.
StringFlag
{
Name
:
"graphql.corsdomain"
,
Usage
:
"Comma separated list of domains from which to accept cross origin requests (browser enforced)"
,
Value
:
""
,
}
GraphQLVirtualHostsFlag
=
cli
.
StringFlag
{
Name
:
"graphql.vhosts"
,
Usage
:
"Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard."
,
Value
:
strings
.
Join
(
node
.
DefaultConfig
.
GraphQLVirtualHosts
,
","
),
}
ExecFlag
=
cli
.
StringFlag
{
Name
:
"exec"
,
Usage
:
"Execute JavaScript statement"
,
...
...
@@ -874,7 +877,6 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) {
cfg
.
HTTPHost
=
ctx
.
GlobalString
(
RPCListenAddrFlag
.
Name
)
}
}
if
ctx
.
GlobalIsSet
(
RPCPortFlag
.
Name
)
{
cfg
.
HTTPPort
=
ctx
.
GlobalInt
(
RPCPortFlag
.
Name
)
}
...
...
@@ -916,7 +918,6 @@ func setWS(ctx *cli.Context, cfg *node.Config) {
cfg
.
WSHost
=
ctx
.
GlobalString
(
WSListenAddrFlag
.
Name
)
}
}
if
ctx
.
GlobalIsSet
(
WSPortFlag
.
Name
)
{
cfg
.
WSPort
=
ctx
.
GlobalInt
(
WSPortFlag
.
Name
)
}
...
...
@@ -1546,12 +1547,33 @@ func RegisterEthStatsService(stack *node.Node, url string) {
var
lesServ
*
les
.
LightEthereum
ctx
.
Service
(
&
lesServ
)
// Let ethstats use whichever is not nil
return
ethstats
.
New
(
url
,
ethServ
,
lesServ
)
});
err
!=
nil
{
Fatalf
(
"Failed to register the Ethereum Stats service: %v"
,
err
)
}
}
// RegisterGraphQLService is a utility function to construct a new service and register it against a node.
func
RegisterGraphQLService
(
stack
*
node
.
Node
,
endpoint
string
,
cors
,
vhosts
[]
string
,
timeouts
rpc
.
HTTPTimeouts
)
{
if
err
:=
stack
.
Register
(
func
(
ctx
*
node
.
ServiceContext
)
(
node
.
Service
,
error
)
{
// Try to construct the GraphQL service backed by a full node
var
ethServ
*
eth
.
Ethereum
if
err
:=
ctx
.
Service
(
&
ethServ
);
err
==
nil
{
return
graphql
.
New
(
ethServ
.
APIBackend
,
endpoint
,
cors
,
vhosts
,
timeouts
)
}
// Try to construct the GraphQL service backed by a light node
var
lesServ
*
les
.
LightEthereum
if
err
:=
ctx
.
Service
(
&
lesServ
);
err
==
nil
{
return
graphql
.
New
(
lesServ
.
ApiBackend
,
endpoint
,
cors
,
vhosts
,
timeouts
)
}
// Well, this should not have happened, bail out
return
nil
,
errors
.
New
(
"no Ethereum service"
)
});
err
!=
nil
{
Fatalf
(
"Failed to register the GraphQL service: %v"
,
err
)
}
}
func
SetupMetrics
(
ctx
*
cli
.
Context
)
{
if
metrics
.
Enabled
{
log
.
Info
(
"Enabling metrics collection"
)
...
...
graphql/graphiql.go
View file @
e3ec77f5
...
...
@@ -60,11 +60,11 @@ var graphiql = []byte(`
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/graphiql/0.1
1.11
/graphiql.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/
2.0.3
/fetch.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.
2.0
/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.
2.0
/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/graphiql/0.1
1.11
/graphiql.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/graphiql/0.1
3.0
/graphiql.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/
3.0.0
/fetch.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.
8.5
/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.
8.5
/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/graphiql/0.1
3.0
/graphiql.min.js"></script>
</head>
<body style="width: 100%; height: 100%; margin: 0; overflow: hidden;">
<div id="graphiql" style="height: 100vh;">Loading...</div>
...
...
graphql/graphql.go
View file @
e3ec77f5
...
...
@@ -20,9 +20,6 @@ package graphql
import
(
"context"
"errors"
"fmt"
"net"
"net/http"
"time"
"github.com/ethereum/go-ethereum"
...
...
@@ -32,16 +29,10 @@ import (
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
graphqlgo
"github.com/graph-gophers/graphql-go"
"github.com/graph-gophers/graphql-go/relay"
)
var
OnlyOnMainChainError
=
errors
.
New
(
"This operation is only available for blocks on the canonical chain."
)
...
...
@@ -49,7 +40,7 @@ var BlockInvariantError = errors.New("Block objects must be instantiated with at
// Account represents an Ethereum account at a particular block.
type
Account
struct
{
backend
*
eth
.
EthAPI
Backend
backend
ethapi
.
Backend
address
common
.
Address
blockNumber
rpc
.
BlockNumber
}
...
...
@@ -102,7 +93,7 @@ func (a *Account) Storage(ctx context.Context, args struct{ Slot common.Hash })
// Log represents an individual log message. All arguments are mandatory.
type
Log
struct
{
backend
*
eth
.
EthAPI
Backend
backend
ethapi
.
Backend
transaction
*
Transaction
log
*
types
.
Log
}
...
...
@@ -134,7 +125,7 @@ func (l *Log) Data(ctx context.Context) hexutil.Bytes {
// Transaction represents an Ethereum transaction.
// backend and hash are mandatory; all others will be fetched when required.
type
Transaction
struct
{
backend
*
eth
.
EthAPI
Backend
backend
ethapi
.
Backend
hash
common
.
Hash
tx
*
types
.
Transaction
block
*
Block
...
...
@@ -349,7 +340,7 @@ const (
// backend, and either num or hash are mandatory. All other fields are lazily fetched
// when required.
type
Block
struct
{
backend
*
eth
.
EthAPI
Backend
backend
ethapi
.
Backend
num
*
rpc
.
BlockNumber
hash
common
.
Hash
header
*
types
.
Header
...
...
@@ -745,7 +736,7 @@ type BlockFilterCriteria struct {
// runFilter accepts a filter and executes it, returning all its results as
// `Log` objects.
func
runFilter
(
ctx
context
.
Context
,
be
*
eth
.
EthAPI
Backend
,
filter
*
filters
.
Filter
)
([]
*
Log
,
error
)
{
func
runFilter
(
ctx
context
.
Context
,
be
ethapi
.
Backend
,
filter
*
filters
.
Filter
)
([]
*
Log
,
error
)
{
logs
,
err
:=
filter
.
Logs
(
ctx
)
if
err
!=
nil
||
logs
==
nil
{
return
nil
,
err
...
...
@@ -888,7 +879,7 @@ func (b *Block) EstimateGas(ctx context.Context, args struct {
}
type
Pending
struct
{
backend
*
eth
.
EthAPI
Backend
backend
ethapi
.
Backend
}
func
(
p
*
Pending
)
TransactionCount
(
ctx
context
.
Context
)
(
int32
,
error
)
{
...
...
@@ -947,7 +938,7 @@ func (p *Pending) EstimateGas(ctx context.Context, args struct {
// Resolver is the top-level object in the GraphQL hierarchy.
type
Resolver
struct
{
backend
*
eth
.
EthAPI
Backend
backend
ethapi
.
Backend
}
func
(
r
*
Resolver
)
Block
(
ctx
context
.
Context
,
args
struct
{
...
...
@@ -1088,7 +1079,6 @@ func (r *Resolver) Logs(ctx context.Context, args struct{ Filter FilterCriteria
// Construct the range filter
filter
:=
filters
.
NewRangeFilter
(
filters
.
Backend
(
r
.
backend
),
begin
,
end
,
addresses
,
topics
)
return
runFilter
(
ctx
,
r
.
backend
,
filter
)
}
...
...
@@ -1145,89 +1135,3 @@ func (r *Resolver) Syncing() (*SyncState, error) {
// Otherwise gather the block sync stats
return
&
SyncState
{
progress
},
nil
}
// NewHandler returns a new `http.Handler` that will answer GraphQL queries.
// It additionally exports an interactive query browser on the / endpoint.
func
NewHandler
(
be
*
eth
.
EthAPIBackend
)
(
http
.
Handler
,
error
)
{
q
:=
Resolver
{
be
}
s
,
err
:=
graphqlgo
.
ParseSchema
(
schema
,
&
q
)
if
err
!=
nil
{
return
nil
,
err
}
h
:=
&
relay
.
Handler
{
Schema
:
s
}
mux
:=
http
.
NewServeMux
()
mux
.
Handle
(
"/"
,
GraphiQL
{})
mux
.
Handle
(
"/graphql"
,
h
)
mux
.
Handle
(
"/graphql/"
,
h
)
return
mux
,
nil
}
// Service encapsulates a GraphQL service.
type
Service
struct
{
endpoint
string
// The host:port endpoint for this service.
cors
[]
string
// Allowed CORS domains
vhosts
[]
string
// Recognised vhosts
timeouts
rpc
.
HTTPTimeouts
// Timeout settings for HTTP requests.
backend
*
eth
.
EthAPIBackend
// The backend that queries will operate onn.
handler
http
.
Handler
// The `http.Handler` used to answer queries.
listener
net
.
Listener
// The listening socket.
}
// Protocols returns the list of protocols exported by this service.
func
(
s
*
Service
)
Protocols
()
[]
p2p
.
Protocol
{
return
nil
}
// APIs returns the list of APIs exported by this service.
func
(
s
*
Service
)
APIs
()
[]
rpc
.
API
{
return
nil
}
// Start is called after all services have been constructed and the networking
// layer was also initialized to spawn any goroutines required by the service.
func
(
s
*
Service
)
Start
(
server
*
p2p
.
Server
)
error
{
var
err
error
s
.
handler
,
err
=
NewHandler
(
s
.
backend
)
if
err
!=
nil
{
return
err
}
if
s
.
listener
,
err
=
net
.
Listen
(
"tcp"
,
s
.
endpoint
);
err
!=
nil
{
return
err
}
go
rpc
.
NewHTTPServer
(
s
.
cors
,
s
.
vhosts
,
s
.
timeouts
,
s
.
handler
)
.
Serve
(
s
.
listener
)
log
.
Info
(
"GraphQL endpoint opened"
,
"url"
,
fmt
.
Sprintf
(
"http://%s"
,
s
.
endpoint
))
return
nil
}
// Stop terminates all goroutines belonging to the service, blocking until they
// are all terminated.
func
(
s
*
Service
)
Stop
()
error
{
if
s
.
listener
!=
nil
{
s
.
listener
.
Close
()
s
.
listener
=
nil
log
.
Info
(
"GraphQL endpoint closed"
,
"url"
,
fmt
.
Sprintf
(
"http://%s"
,
s
.
endpoint
))
}
return
nil
}
// NewService constructs a new service instance.
func
NewService
(
backend
*
eth
.
EthAPIBackend
,
endpoint
string
,
cors
,
vhosts
[]
string
,
timeouts
rpc
.
HTTPTimeouts
)
(
*
Service
,
error
)
{
return
&
Service
{
endpoint
:
endpoint
,
cors
:
cors
,
vhosts
:
vhosts
,
timeouts
:
timeouts
,
backend
:
backend
,
},
nil
}
// RegisterGraphQLService is a utility function to construct a new service and register it against a node.
func
RegisterGraphQLService
(
stack
*
node
.
Node
,
endpoint
string
,
cors
,
vhosts
[]
string
,
timeouts
rpc
.
HTTPTimeouts
)
error
{
return
stack
.
Register
(
func
(
ctx
*
node
.
ServiceContext
)
(
node
.
Service
,
error
)
{
var
ethereum
*
eth
.
Ethereum
if
err
:=
ctx
.
Service
(
&
ethereum
);
err
!=
nil
{
return
nil
,
err
}
return
NewService
(
ethereum
.
APIBackend
,
endpoint
,
cors
,
vhosts
,
timeouts
)
})
}
graphql/graphql_test.go
View file @
e3ec77f5
...
...
@@ -22,8 +22,7 @@ import (
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
{
if
_
,
err
:=
newHandler
(
nil
);
err
!=
nil
{
t
.
Errorf
(
"Could not construct GraphQL handler: %v"
,
err
)
}
}
graphql/service.go
0 → 100644
View file @
e3ec77f5
// Copyright 2019 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
(
"fmt"
"net"
"net/http"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc"
"github.com/graph-gophers/graphql-go"
"github.com/graph-gophers/graphql-go/relay"
)
// Service encapsulates a GraphQL service.
type
Service
struct
{
endpoint
string
// The host:port endpoint for this service.
cors
[]
string
// Allowed CORS domains
vhosts
[]
string
// Recognised vhosts
timeouts
rpc
.
HTTPTimeouts
// Timeout settings for HTTP requests.
backend
ethapi
.
Backend
// The backend that queries will operate onn.
handler
http
.
Handler
// The `http.Handler` used to answer queries.
listener
net
.
Listener
// The listening socket.
}
// New constructs a new GraphQL service instance.
func
New
(
backend
ethapi
.
Backend
,
endpoint
string
,
cors
,
vhosts
[]
string
,
timeouts
rpc
.
HTTPTimeouts
)
(
*
Service
,
error
)
{
return
&
Service
{
endpoint
:
endpoint
,
cors
:
cors
,
vhosts
:
vhosts
,
timeouts
:
timeouts
,
backend
:
backend
,
},
nil
}
// Protocols returns the list of protocols exported by this service.
func
(
s
*
Service
)
Protocols
()
[]
p2p
.
Protocol
{
return
nil
}
// APIs returns the list of APIs exported by this service.
func
(
s
*
Service
)
APIs
()
[]
rpc
.
API
{
return
nil
}
// Start is called after all services have been constructed and the networking
// layer was also initialized to spawn any goroutines required by the service.
func
(
s
*
Service
)
Start
(
server
*
p2p
.
Server
)
error
{
var
err
error
s
.
handler
,
err
=
newHandler
(
s
.
backend
)
if
err
!=
nil
{
return
err
}
if
s
.
listener
,
err
=
net
.
Listen
(
"tcp"
,
s
.
endpoint
);
err
!=
nil
{
return
err
}
go
rpc
.
NewHTTPServer
(
s
.
cors
,
s
.
vhosts
,
s
.
timeouts
,
s
.
handler
)
.
Serve
(
s
.
listener
)
log
.
Info
(
"GraphQL endpoint opened"
,
"url"
,
fmt
.
Sprintf
(
"http://%s"
,
s
.
endpoint
))
return
nil
}
// newHandler returns a new `http.Handler` that will answer GraphQL queries.
// It additionally exports an interactive query browser on the / endpoint.
func
newHandler
(
backend
ethapi
.
Backend
)
(
http
.
Handler
,
error
)
{
q
:=
Resolver
{
backend
}
s
,
err
:=
graphql
.
ParseSchema
(
schema
,
&
q
)
if
err
!=
nil
{
return
nil
,
err
}
h
:=
&
relay
.
Handler
{
Schema
:
s
}
mux
:=
http
.
NewServeMux
()
mux
.
Handle
(
"/"
,
GraphiQL
{})
mux
.
Handle
(
"/graphql"
,
h
)
mux
.
Handle
(
"/graphql/"
,
h
)
return
mux
,
nil
}
// Stop terminates all goroutines belonging to the service, blocking until they
// are all terminated.
func
(
s
*
Service
)
Stop
()
error
{
if
s
.
listener
!=
nil
{
s
.
listener
.
Close
()
s
.
listener
=
nil
log
.
Info
(
"GraphQL endpoint closed"
,
"url"
,
fmt
.
Sprintf
(
"http://%s"
,
s
.
endpoint
))
}
return
nil
}
internal/ethapi/backend.go
View file @
e3ec77f5
...
...
@@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
...
...
@@ -47,9 +48,10 @@ type Backend interface {
ExtRPCEnabled
()
bool
RPCGasCap
()
*
big
.
Int
// global gas cap for eth_call over rpc: DoS protection
// Block
C
hain API
// Block
c
hain API
SetHead
(
number
uint64
)
HeaderByNumber
(
ctx
context
.
Context
,
blockNr
rpc
.
BlockNumber
)
(
*
types
.
Header
,
error
)
HeaderByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
*
types
.
Header
,
error
)
BlockByNumber
(
ctx
context
.
Context
,
blockNr
rpc
.
BlockNumber
)
(
*
types
.
Block
,
error
)
StateAndHeaderByNumber
(
ctx
context
.
Context
,
blockNr
rpc
.
BlockNumber
)
(
*
state
.
StateDB
,
*
types
.
Header
,
error
)
GetBlock
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
*
types
.
Block
,
error
)
...
...
@@ -60,7 +62,7 @@ type Backend interface {
SubscribeChainHeadEvent
(
ch
chan
<-
core
.
ChainHeadEvent
)
event
.
Subscription
SubscribeChainSideEvent
(
ch
chan
<-
core
.
ChainSideEvent
)
event
.
Subscription
// T
xP
ool API
// T
ransaction p
ool API
SendTx
(
ctx
context
.
Context
,
signedTx
*
types
.
Transaction
)
error
GetTransaction
(
ctx
context
.
Context
,
txHash
common
.
Hash
)
(
*
types
.
Transaction
,
common
.
Hash
,
uint64
,
uint64
,
error
)
GetPoolTransactions
()
(
types
.
Transactions
,
error
)
...
...
@@ -70,6 +72,13 @@ type Backend interface {
TxPoolContent
()
(
map
[
common
.
Address
]
types
.
Transactions
,
map
[
common
.
Address
]
types
.
Transactions
)
SubscribeNewTxsEvent
(
chan
<-
core
.
NewTxsEvent
)
event
.
Subscription
// Filter API
BloomStatus
()
(
uint64
,
uint64
)
GetLogs
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
([][]
*
types
.
Log
,
error
)
ServiceFilter
(
ctx
context
.
Context
,
session
*
bloombits
.
MatcherSession
)
SubscribeLogsEvent
(
ch
chan
<-
[]
*
types
.
Log
)
event
.
Subscription
SubscribeRemovedLogsEvent
(
ch
chan
<-
core
.
RemovedLogsEvent
)
event
.
Subscription
ChainConfig
()
*
params
.
ChainConfig
CurrentBlock
()
*
types
.
Block
}
...
...
node/defaults.go
View file @
e3ec77f5
...
...
@@ -38,13 +38,15 @@ const (
// DefaultConfig contains reasonable default settings.
var
DefaultConfig
=
Config
{
DataDir
:
DefaultDataDir
(),
HTTPPort
:
DefaultHTTPPort
,
HTTPModules
:
[]
string
{
"net"
,
"web3"
},
HTTPVirtualHosts
:
[]
string
{
"localhost"
},
HTTPTimeouts
:
rpc
.
DefaultHTTPTimeouts
,
WSPort
:
DefaultWSPort
,
WSModules
:
[]
string
{
"net"
,
"web3"
},
DataDir
:
DefaultDataDir
(),
HTTPPort
:
DefaultHTTPPort
,
HTTPModules
:
[]
string
{
"net"
,
"web3"
},
HTTPVirtualHosts
:
[]
string
{
"localhost"
},
HTTPTimeouts
:
rpc
.
DefaultHTTPTimeouts
,
WSPort
:
DefaultWSPort
,
WSModules
:
[]
string
{
"net"
,
"web3"
},
GraphQLPort
:
DefaultGraphQLPort
,
GraphQLVirtualHosts
:
[]
string
{
"localhost"
},
P2P
:
p2p
.
Config
{
ListenAddr
:
":30303"
,
MaxPeers
:
50
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment