Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GraphQL API #17903

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4b53623
Initial work on a graphql API
Arachnid Oct 13, 2018
e0f4d7e
Added receipts, and more transaction fields.
Arachnid Oct 14, 2018
c46a697
Finish receipts, add logs
Arachnid Oct 14, 2018
ed02332
Add transactionCount to block
Arachnid Oct 14, 2018
cd53e60
Add types and .
Arachnid Oct 15, 2018
4e3be4f
Update Block type to be compatible with ethql
Arachnid Oct 15, 2018
9286152
Rename nonce to transactionCount in Account, to be compatible with ethql
Arachnid Oct 15, 2018
4ecd3de
Update transaction, receipt and log to match ethql
Arachnid Oct 15, 2018
76e45cf
Add query operator, for a range of blocks
Arachnid Oct 15, 2018
460d158
Added ommerCount to Block
Arachnid Oct 15, 2018
75aeee1
Add transactionAt and ommerAt to Block
Arachnid Oct 15, 2018
42bbab1
Added sendRawTransaction mutation
Arachnid Oct 16, 2018
c6c6a7a
Add Call and EstimateGas to graphQL API
Arachnid Oct 16, 2018
59e2a7f
Refactored to use hexutil.Bytes instead of HexBytes
Arachnid Oct 16, 2018
8790e18
Replace BigNum with hexutil.Big
Arachnid Oct 16, 2018
ba6f531
Refactor call and estimateGas to use ethapi struct type
Arachnid Oct 16, 2018
268a03b
Replace ethgraphql.Address with common.Address
Arachnid Oct 16, 2018
21cef58
Replace ethgraphql.Hash with common.Hash
Arachnid Oct 16, 2018
d92e373
Converted most quantities to Long instead of Int
Arachnid Oct 16, 2018
b235d18
Add support for logs
Arachnid Oct 16, 2018
549d649
Fix bug in runFilter
Arachnid Oct 16, 2018
19735c1
Restructured Transaction to work primarily with headers, so uncle dat…
Arachnid Oct 16, 2018
135b7d9
Add gasPrice API
Arachnid Oct 16, 2018
0e6fa8e
Add protocolVersion API
Arachnid Oct 16, 2018
32068e0
Add syncing API
Arachnid Oct 16, 2018
c3387f8
Moved schema into its own source file
Arachnid Oct 16, 2018
a79bacd
Move some single use args types into anonymous structs
Arachnid Oct 16, 2018
c5f893d
Add doc-comments
Arachnid Oct 17, 2018
205f82e
Fixed backend fetching to use context
Arachnid Oct 17, 2018
844aa56
Added (very) basic tests
Arachnid Oct 17, 2018
5719808
Add documentation to the graphql schema
Arachnid Oct 17, 2018
532ec8e
Fix reversion for formatting of big numbers
Arachnid Oct 18, 2018
c104779
Correct spelling error
Arachnid Oct 18, 2018
1c5ed0d
s/BigInt/Long/
Arachnid Oct 19, 2018
84874ac
Update common/types.go
holiman Oct 19, 2018
738f505
Merge branch 'master' into graphql
Arachnid Nov 22, 2018
202a100
Fixes in response to review
Arachnid Nov 22, 2018
c780558
Fix lint error
Arachnid Nov 22, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cmd/geth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ 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"
Expand Down Expand Up @@ -174,6 +175,13 @@ func makeFullNode(ctx *cli.Context) *node.Node {
utils.RegisterShhService(stack, &cfg.Shh)
}

// Configure GraphQL if required
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)
}
}

// Add the Ethereum Stats daemon if requested.
if cfg.Ethstats.URL != "" {
utils.RegisterEthStatsService(stack, cfg.Ethstats.URL)
Expand Down
5 changes: 5 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ var (
utils.RPCEnabledFlag,
utils.RPCListenAddrFlag,
utils.RPCPortFlag,
utils.GraphQLEnabledFlag,
utils.GraphQLListenAddrFlag,
utils.GraphQLPortFlag,
utils.GraphQLCORSDomainFlag,
utils.GraphQLVirtualHostsFlag,
utils.RPCApiFlag,
utils.WSEnabledFlag,
utils.WSListenAddrFlag,
Expand Down
43 changes: 43 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,30 @@ 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,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been working on reformatting the flags a bit for a while now, making them more namespace-y. E.g.

  --mine                         Enable mining
  --miner.threads value          Number of CPU threads to use for mining (default: 0)
  --miner.notify value           Comma separated HTTP URL list to notify of new work packages
  --miner.gasprice "1000000000"  Minimum gas price for mining a transaction
  --miner.gastarget value        Target gas floor for mined blocks (default: 8000000)

Please use the same format for any new flag: graphql.addr, graphql.port

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, instead of piggiebacking on RPCCors and RPCVhosts, please define a separate set. Since we're talking about two different TCP endpoints, it's imho necessary to be able to configure them separately.

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)",
Expand Down Expand Up @@ -788,6 +812,24 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) {
}
}

// setGraphQL creates the GraphQL listener interface string from the set
// command line flags, returning empty if the GraphQL endpoint is disabled.
func setGraphQL(ctx *cli.Context, cfg *node.Config) {
if ctx.GlobalBool(GraphQLEnabledFlag.Name) && cfg.GraphQLHost == "" {
cfg.GraphQLHost = "127.0.0.1"
if ctx.GlobalIsSet(GraphQLListenAddrFlag.Name) {
cfg.GraphQLHost = ctx.GlobalString(GraphQLListenAddrFlag.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
// command line flags, returning empty if the HTTP endpoint is disabled.
func setWS(ctx *cli.Context, cfg *node.Config) {
Expand Down Expand Up @@ -975,6 +1017,7 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
SetP2PConfig(ctx, &cfg.P2P)
setIPC(ctx, cfg)
setHTTP(ctx, cfg)
setGraphQL(ctx, cfg)
setWS(ctx, cfg)
setNodeUserIdent(ctx, cfg)

Expand Down
55 changes: 55 additions & 0 deletions common/hexutil/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,25 @@ func (b Bytes) String() string {
return Encode(b)
}

// ImplementsGraphQLType returns true if Bytes implements the specified GraphQL type.
func (b Bytes) ImplementsGraphQLType(name string) bool { return name == "Bytes" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public method. Please add a method doc for it.


// UnmarshalGraphQL unmarshals the provided GraphQL query data.
func (b *Bytes) UnmarshalGraphQL(input interface{}) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public method. Please add a method doc for it.

var err error
switch input := input.(type) {
gballet marked this conversation as resolved.
Show resolved Hide resolved
case string:
data, err := Decode(input)
if err != nil {
return err
}
*b = data
default:
err = fmt.Errorf("Unexpected type for Bytes: %v", input)
}
return err
}

// UnmarshalFixedJSON decodes the input as a string with 0x prefix. The length of out
// determines the required input length. This function is commonly used to implement the
// UnmarshalJSON method for fixed-size types.
Expand Down Expand Up @@ -187,6 +206,25 @@ func (b *Big) String() string {
return EncodeBig(b.ToInt())
}

// ImplementsGraphQLType returns true if Big implements the provided GraphQL type.
func (b Big) ImplementsGraphQLType(name string) bool { return name == "BigInt" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public method. Please add a method doc for it.


// UnmarshalGraphQL unmarshals the provided GraphQL query data.
func (b *Big) UnmarshalGraphQL(input interface{}) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public method. Please add a method doc for it.

var err error
switch input := input.(type) {
gballet marked this conversation as resolved.
Show resolved Hide resolved
case string:
return b.UnmarshalText([]byte(input))
case int32:
var num big.Int
num.SetInt64(int64(input))
*b = Big(num)
default:
err = fmt.Errorf("Unexpected type for BigInt: %v", input)
}
return err
}

// Uint64 marshals/unmarshals as a JSON string with 0x prefix.
// The zero value marshals as "0x0".
type Uint64 uint64
Expand Down Expand Up @@ -234,6 +272,23 @@ func (b Uint64) String() string {
return EncodeUint64(uint64(b))
}

// ImplementsGraphQLType returns true if Uint64 implements the provided GraphQL type.
func (b Uint64) ImplementsGraphQLType(name string) bool { return name == "Long" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public method. Please add a method doc for it.


// UnmarshalGraphQL unmarshals the provided GraphQL query data.
func (b *Uint64) UnmarshalGraphQL(input interface{}) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public method. Please add a method doc for it.

var err error
switch input := input.(type) {
gballet marked this conversation as resolved.
Show resolved Hide resolved
case string:
return b.UnmarshalText([]byte(input))
case int32:
*b = Uint64(input)
default:
err = fmt.Errorf("Unexpected type for Long: %v", input)
}
return err
}

// Uint marshals/unmarshals as a JSON string with 0x prefix.
// The zero value marshals as "0x0".
type Uint uint
Expand Down
30 changes: 30 additions & 0 deletions common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,21 @@ func (h Hash) Value() (driver.Value, error) {
return h[:], nil
}

// ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
func (_ Hash) ImplementsGraphQLType(name string) bool { return name == "Bytes32" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public method. Please add a method doc for it.


// UnmarshalGraphQL unmarshals the provided GraphQL query data.
func (h *Hash) UnmarshalGraphQL(input interface{}) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public method. Please add a method doc for it.

var err error
switch input := input.(type) {
gballet marked this conversation as resolved.
Show resolved Hide resolved
case string:
*h = HexToHash(input)
default:
err = fmt.Errorf("Unexpected type for Bytes32: %v", input)
}
return err
}

// UnprefixedHash allows marshaling a Hash without 0x prefix.
type UnprefixedHash Hash

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

// ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
func (a Address) ImplementsGraphQLType(name string) bool { return name == "Address" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public method. Please add a method doc for it.


// UnmarshalGraphQL unmarshals the provided GraphQL query data.
func (a *Address) UnmarshalGraphQL(input interface{}) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a public method. Please add a method doc for it.

var err error
switch input := input.(type) {
gballet marked this conversation as resolved.
Show resolved Hide resolved
case string:
*a = HexToAddress(input)
default:
err = fmt.Errorf("Unexpected type for Address: %v", input)
}
return err
}

// UnprefixedAddress allows marshaling an Address without 0x prefix.
type UnprefixedAddress Address

Expand Down
Loading