Skip to content
This repository was archived by the owner on Aug 2, 2021. It is now read-only.

Commit f91312d

Browse files
kshinnArachnid
authored andcommitted
GraphQL master FF for review (#18445)
* Initial work on a graphql API * Added receipts, and more transaction fields. * Finish receipts, add logs * Add transactionCount to block * Add types and . * Update Block type to be compatible with ethql * Rename nonce to transactionCount in Account, to be compatible with ethql * Update transaction, receipt and log to match ethql * Add query operator, for a range of blocks * Added ommerCount to Block * Add transactionAt and ommerAt to Block * Added sendRawTransaction mutation * Add Call and EstimateGas to graphQL API * Refactored to use hexutil.Bytes instead of HexBytes * Replace BigNum with hexutil.Big * Refactor call and estimateGas to use ethapi struct type * Replace ethgraphql.Address with common.Address * Replace ethgraphql.Hash with common.Hash * Converted most quantities to Long instead of Int * Add support for logs * Fix bug in runFilter * Restructured Transaction to work primarily with headers, so uncle data is reported properly * Add gasPrice API * Add protocolVersion API * Add syncing API * Moved schema into its own source file * Move some single use args types into anonymous structs * Add doc-comments * Fixed backend fetching to use context * Added (very) basic tests * Add documentation to the graphql schema * Fix reversion for formatting of big numbers * Correct spelling error * s/BigInt/Long/ * Update common/types.go * Fixes in response to review * Fix lint error * Updated calls on private functions * Fix typo in graphql.go * Rollback ethapi breaking changes for graphql support Co-Authored-By: Arachnid <[email protected]>
1 parent 105008b commit f91312d

File tree

42 files changed

+6704
-39
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+6704
-39
lines changed

cmd/geth/config.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/ethereum/go-ethereum/cmd/utils"
3131
"github.com/ethereum/go-ethereum/dashboard"
3232
"github.com/ethereum/go-ethereum/eth"
33+
"github.com/ethereum/go-ethereum/graphql"
3334
"github.com/ethereum/go-ethereum/node"
3435
"github.com/ethereum/go-ethereum/params"
3536
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
@@ -176,6 +177,13 @@ func makeFullNode(ctx *cli.Context) *node.Node {
176177
utils.RegisterShhService(stack, &cfg.Shh)
177178
}
178179

180+
// Configure GraphQL if required
181+
if ctx.GlobalIsSet(utils.GraphQLEnabledFlag.Name) {
182+
if err := graphql.RegisterGraphQLService(stack, cfg.Node.GraphQLEndpoint(), cfg.Node.GraphQLCors, cfg.Node.GraphQLVirtualHosts, cfg.Node.HTTPTimeouts); err != nil {
183+
utils.Fatalf("Failed to register the Ethereum service: %v", err)
184+
}
185+
}
186+
179187
// Add the Ethereum Stats daemon if requested.
180188
if cfg.Ethstats.URL != "" {
181189
utils.RegisterEthStatsService(stack, cfg.Ethstats.URL)

cmd/geth/main.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ var (
141141
utils.RPCEnabledFlag,
142142
utils.RPCListenAddrFlag,
143143
utils.RPCPortFlag,
144+
utils.GraphQLEnabledFlag,
145+
utils.GraphQLListenAddrFlag,
146+
utils.GraphQLPortFlag,
147+
utils.GraphQLCORSDomainFlag,
148+
utils.GraphQLVirtualHostsFlag,
144149
utils.RPCApiFlag,
145150
utils.WSEnabledFlag,
146151
utils.WSListenAddrFlag,

cmd/utils/flags.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,30 @@ var (
435435
Usage: "HTTP-RPC server listening port",
436436
Value: node.DefaultHTTPPort,
437437
}
438+
GraphQLEnabledFlag = cli.BoolFlag{
439+
Name: "graphql",
440+
Usage: "Enable the GraphQL server",
441+
}
442+
GraphQLListenAddrFlag = cli.StringFlag{
443+
Name: "graphql.addr",
444+
Usage: "GraphQL server listening interface",
445+
Value: node.DefaultGraphQLHost,
446+
}
447+
GraphQLPortFlag = cli.IntFlag{
448+
Name: "graphql.port",
449+
Usage: "GraphQL server listening port",
450+
Value: node.DefaultGraphQLPort,
451+
}
452+
GraphQLCORSDomainFlag = cli.StringFlag{
453+
Name: "graphql.rpccorsdomain",
454+
Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
455+
Value: "",
456+
}
457+
GraphQLVirtualHostsFlag = cli.StringFlag{
458+
Name: "graphql.rpcvhosts",
459+
Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.",
460+
Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","),
461+
}
438462
RPCCORSDomainFlag = cli.StringFlag{
439463
Name: "rpccorsdomain",
440464
Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
@@ -796,6 +820,24 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) {
796820
}
797821
}
798822

823+
// setGraphQL creates the GraphQL listener interface string from the set
824+
// command line flags, returning empty if the GraphQL endpoint is disabled.
825+
func setGraphQL(ctx *cli.Context, cfg *node.Config) {
826+
if ctx.GlobalBool(GraphQLEnabledFlag.Name) && cfg.GraphQLHost == "" {
827+
cfg.GraphQLHost = "127.0.0.1"
828+
if ctx.GlobalIsSet(GraphQLListenAddrFlag.Name) {
829+
cfg.GraphQLHost = ctx.GlobalString(GraphQLListenAddrFlag.Name)
830+
}
831+
}
832+
cfg.GraphQLPort = ctx.GlobalInt(GraphQLPortFlag.Name)
833+
if ctx.GlobalIsSet(GraphQLCORSDomainFlag.Name) {
834+
cfg.GraphQLCors = splitAndTrim(ctx.GlobalString(GraphQLCORSDomainFlag.Name))
835+
}
836+
if ctx.GlobalIsSet(GraphQLVirtualHostsFlag.Name) {
837+
cfg.GraphQLVirtualHosts = splitAndTrim(ctx.GlobalString(GraphQLVirtualHostsFlag.Name))
838+
}
839+
}
840+
799841
// setWS creates the WebSocket RPC listener interface string from the set
800842
// command line flags, returning empty if the HTTP endpoint is disabled.
801843
func setWS(ctx *cli.Context, cfg *node.Config) {
@@ -978,6 +1020,7 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
9781020
SetP2PConfig(ctx, &cfg.P2P)
9791021
setIPC(ctx, cfg)
9801022
setHTTP(ctx, cfg)
1023+
setGraphQL(ctx, cfg)
9811024
setWS(ctx, cfg)
9821025
setNodeUserIdent(ctx, cfg)
9831026

common/hexutil/json.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,25 @@ func (b Bytes) String() string {
7272
return Encode(b)
7373
}
7474

75+
// ImplementsGraphQLType returns true if Bytes implements the specified GraphQL type.
76+
func (b Bytes) ImplementsGraphQLType(name string) bool { return name == "Bytes" }
77+
78+
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
79+
func (b *Bytes) UnmarshalGraphQL(input interface{}) error {
80+
var err error
81+
switch input := input.(type) {
82+
case string:
83+
data, err := Decode(input)
84+
if err != nil {
85+
return err
86+
}
87+
*b = data
88+
default:
89+
err = fmt.Errorf("Unexpected type for Bytes: %v", input)
90+
}
91+
return err
92+
}
93+
7594
// UnmarshalFixedJSON decodes the input as a string with 0x prefix. The length of out
7695
// determines the required input length. This function is commonly used to implement the
7796
// UnmarshalJSON method for fixed-size types.
@@ -187,6 +206,25 @@ func (b *Big) String() string {
187206
return EncodeBig(b.ToInt())
188207
}
189208

209+
// ImplementsGraphQLType returns true if Big implements the provided GraphQL type.
210+
func (b Big) ImplementsGraphQLType(name string) bool { return name == "BigInt" }
211+
212+
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
213+
func (b *Big) UnmarshalGraphQL(input interface{}) error {
214+
var err error
215+
switch input := input.(type) {
216+
case string:
217+
return b.UnmarshalText([]byte(input))
218+
case int32:
219+
var num big.Int
220+
num.SetInt64(int64(input))
221+
*b = Big(num)
222+
default:
223+
err = fmt.Errorf("Unexpected type for BigInt: %v", input)
224+
}
225+
return err
226+
}
227+
190228
// Uint64 marshals/unmarshals as a JSON string with 0x prefix.
191229
// The zero value marshals as "0x0".
192230
type Uint64 uint64
@@ -234,6 +272,23 @@ func (b Uint64) String() string {
234272
return EncodeUint64(uint64(b))
235273
}
236274

275+
// ImplementsGraphQLType returns true if Uint64 implements the provided GraphQL type.
276+
func (b Uint64) ImplementsGraphQLType(name string) bool { return name == "Long" }
277+
278+
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
279+
func (b *Uint64) UnmarshalGraphQL(input interface{}) error {
280+
var err error
281+
switch input := input.(type) {
282+
case string:
283+
return b.UnmarshalText([]byte(input))
284+
case int32:
285+
*b = Uint64(input)
286+
default:
287+
err = fmt.Errorf("Unexpected type for Long: %v", input)
288+
}
289+
return err
290+
}
291+
237292
// Uint marshals/unmarshals as a JSON string with 0x prefix.
238293
// The zero value marshals as "0x0".
239294
type Uint uint

common/types.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,21 @@ func (h Hash) Value() (driver.Value, error) {
141141
return h[:], nil
142142
}
143143

144+
// ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
145+
func (_ Hash) ImplementsGraphQLType(name string) bool { return name == "Bytes32" }
146+
147+
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
148+
func (h *Hash) UnmarshalGraphQL(input interface{}) error {
149+
var err error
150+
switch input := input.(type) {
151+
case string:
152+
*h = HexToHash(input)
153+
default:
154+
err = fmt.Errorf("Unexpected type for Bytes32: %v", input)
155+
}
156+
return err
157+
}
158+
144159
// UnprefixedHash allows marshaling a Hash without 0x prefix.
145160
type UnprefixedHash Hash
146161

@@ -268,6 +283,21 @@ func (a Address) Value() (driver.Value, error) {
268283
return a[:], nil
269284
}
270285

286+
// ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
287+
func (a Address) ImplementsGraphQLType(name string) bool { return name == "Address" }
288+
289+
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
290+
func (a *Address) UnmarshalGraphQL(input interface{}) error {
291+
var err error
292+
switch input := input.(type) {
293+
case string:
294+
*a = HexToAddress(input)
295+
default:
296+
err = fmt.Errorf("Unexpected type for Address: %v", input)
297+
}
298+
return err
299+
}
300+
271301
// UnprefixedAddress allows marshaling an Address without 0x prefix.
272302
type UnprefixedAddress Address
273303

0 commit comments

Comments
 (0)