forked from cerc-io/plugeth
f91312dbdb
* 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 <arachnid@notdot.net>
207 lines
3.9 KiB
Go
207 lines
3.9 KiB
Go
package common
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
"text/scanner"
|
|
|
|
"github.com/graph-gophers/graphql-go/errors"
|
|
)
|
|
|
|
type Literal interface {
|
|
Value(vars map[string]interface{}) interface{}
|
|
String() string
|
|
Location() errors.Location
|
|
}
|
|
|
|
type BasicLit struct {
|
|
Type rune
|
|
Text string
|
|
Loc errors.Location
|
|
}
|
|
|
|
func (lit *BasicLit) Value(vars map[string]interface{}) interface{} {
|
|
switch lit.Type {
|
|
case scanner.Int:
|
|
value, err := strconv.ParseInt(lit.Text, 10, 32)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return int32(value)
|
|
|
|
case scanner.Float:
|
|
value, err := strconv.ParseFloat(lit.Text, 64)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return value
|
|
|
|
case scanner.String:
|
|
value, err := strconv.Unquote(lit.Text)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return value
|
|
|
|
case scanner.Ident:
|
|
switch lit.Text {
|
|
case "true":
|
|
return true
|
|
case "false":
|
|
return false
|
|
default:
|
|
return lit.Text
|
|
}
|
|
|
|
default:
|
|
panic("invalid literal")
|
|
}
|
|
}
|
|
|
|
func (lit *BasicLit) String() string {
|
|
return lit.Text
|
|
}
|
|
|
|
func (lit *BasicLit) Location() errors.Location {
|
|
return lit.Loc
|
|
}
|
|
|
|
type ListLit struct {
|
|
Entries []Literal
|
|
Loc errors.Location
|
|
}
|
|
|
|
func (lit *ListLit) Value(vars map[string]interface{}) interface{} {
|
|
entries := make([]interface{}, len(lit.Entries))
|
|
for i, entry := range lit.Entries {
|
|
entries[i] = entry.Value(vars)
|
|
}
|
|
return entries
|
|
}
|
|
|
|
func (lit *ListLit) String() string {
|
|
entries := make([]string, len(lit.Entries))
|
|
for i, entry := range lit.Entries {
|
|
entries[i] = entry.String()
|
|
}
|
|
return "[" + strings.Join(entries, ", ") + "]"
|
|
}
|
|
|
|
func (lit *ListLit) Location() errors.Location {
|
|
return lit.Loc
|
|
}
|
|
|
|
type ObjectLit struct {
|
|
Fields []*ObjectLitField
|
|
Loc errors.Location
|
|
}
|
|
|
|
type ObjectLitField struct {
|
|
Name Ident
|
|
Value Literal
|
|
}
|
|
|
|
func (lit *ObjectLit) Value(vars map[string]interface{}) interface{} {
|
|
fields := make(map[string]interface{}, len(lit.Fields))
|
|
for _, f := range lit.Fields {
|
|
fields[f.Name.Name] = f.Value.Value(vars)
|
|
}
|
|
return fields
|
|
}
|
|
|
|
func (lit *ObjectLit) String() string {
|
|
entries := make([]string, 0, len(lit.Fields))
|
|
for _, f := range lit.Fields {
|
|
entries = append(entries, f.Name.Name+": "+f.Value.String())
|
|
}
|
|
return "{" + strings.Join(entries, ", ") + "}"
|
|
}
|
|
|
|
func (lit *ObjectLit) Location() errors.Location {
|
|
return lit.Loc
|
|
}
|
|
|
|
type NullLit struct {
|
|
Loc errors.Location
|
|
}
|
|
|
|
func (lit *NullLit) Value(vars map[string]interface{}) interface{} {
|
|
return nil
|
|
}
|
|
|
|
func (lit *NullLit) String() string {
|
|
return "null"
|
|
}
|
|
|
|
func (lit *NullLit) Location() errors.Location {
|
|
return lit.Loc
|
|
}
|
|
|
|
type Variable struct {
|
|
Name string
|
|
Loc errors.Location
|
|
}
|
|
|
|
func (v Variable) Value(vars map[string]interface{}) interface{} {
|
|
return vars[v.Name]
|
|
}
|
|
|
|
func (v Variable) String() string {
|
|
return "$" + v.Name
|
|
}
|
|
|
|
func (v *Variable) Location() errors.Location {
|
|
return v.Loc
|
|
}
|
|
|
|
func ParseLiteral(l *Lexer, constOnly bool) Literal {
|
|
loc := l.Location()
|
|
switch l.Peek() {
|
|
case '$':
|
|
if constOnly {
|
|
l.SyntaxError("variable not allowed")
|
|
panic("unreachable")
|
|
}
|
|
l.ConsumeToken('$')
|
|
return &Variable{l.ConsumeIdent(), loc}
|
|
|
|
case scanner.Int, scanner.Float, scanner.String, scanner.Ident:
|
|
lit := l.ConsumeLiteral()
|
|
if lit.Type == scanner.Ident && lit.Text == "null" {
|
|
return &NullLit{loc}
|
|
}
|
|
lit.Loc = loc
|
|
return lit
|
|
case '-':
|
|
l.ConsumeToken('-')
|
|
lit := l.ConsumeLiteral()
|
|
lit.Text = "-" + lit.Text
|
|
lit.Loc = loc
|
|
return lit
|
|
case '[':
|
|
l.ConsumeToken('[')
|
|
var list []Literal
|
|
for l.Peek() != ']' {
|
|
list = append(list, ParseLiteral(l, constOnly))
|
|
}
|
|
l.ConsumeToken(']')
|
|
return &ListLit{list, loc}
|
|
|
|
case '{':
|
|
l.ConsumeToken('{')
|
|
var fields []*ObjectLitField
|
|
for l.Peek() != '}' {
|
|
name := l.ConsumeIdentWithLoc()
|
|
l.ConsumeToken(':')
|
|
value := ParseLiteral(l, constOnly)
|
|
fields = append(fields, &ObjectLitField{name, value})
|
|
}
|
|
l.ConsumeToken('}')
|
|
return &ObjectLit{fields, loc}
|
|
|
|
default:
|
|
l.SyntaxError("invalid value")
|
|
panic("unreachable")
|
|
}
|
|
}
|