mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-04 00:05:22 +00:00
add more query fields and resolvers to graphql api
after EIP2718/EIP2930, we have additional fields: type AccessTuple { address: Address! storageKeys : [Bytes32!] } type Transaction { r: BigInt! s: BigInt! v: BigInt! # Envelope transaction support type: Int accessList: [AccessTuple!] } close #606
This commit is contained in:
parent
af1537fcab
commit
0ecf9fe1af
@ -33,6 +33,7 @@ type
|
||||
ethPending = "Pending"
|
||||
ethQuery = "Query"
|
||||
ethMutation = "Mutation"
|
||||
ethAccessTuple = "AccessTuple"
|
||||
|
||||
HeaderNode = ref object of Node
|
||||
header: BlockHeader
|
||||
@ -54,6 +55,9 @@ type
|
||||
index: int
|
||||
tx: TxNode
|
||||
|
||||
AclNode = ref object of Node
|
||||
acl: AccessPair
|
||||
|
||||
GraphqlContextRef = ref GraphqlContextObj
|
||||
GraphqlContextObj = object of Graphql
|
||||
ids: array[EthTypes, Name]
|
||||
@ -104,6 +108,14 @@ proc logNode(ctx: GraphqlContextRef, log: Log, index: int, tx: TxNode): Node =
|
||||
tx: tx
|
||||
)
|
||||
|
||||
proc aclNode(ctx: GraphqlContextRef, accessPair: AccessPair): Node =
|
||||
AclNode(
|
||||
kind: nkMap,
|
||||
typeName: ctx.ids[ethAccessTuple],
|
||||
pos: Pos(),
|
||||
acl: accessPair
|
||||
)
|
||||
|
||||
proc getAccountDb(chainDB: BaseChainDB, header: BlockHeader): ReadOnlyStateDB =
|
||||
## Retrieves the account db from canonical head
|
||||
## we don't use accounst_cache here because it's only read operations
|
||||
@ -638,6 +650,34 @@ proc txLogs(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
list.add logNode(ctx, n, i, tx)
|
||||
ok(list)
|
||||
|
||||
proc txR(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
let tx = TxNode(parent)
|
||||
bigIntNode(tx.tx.R)
|
||||
|
||||
proc txS(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
let tx = TxNode(parent)
|
||||
bigIntNode(tx.tx.S)
|
||||
|
||||
proc txV(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
let tx = TxNode(parent)
|
||||
bigIntNode(tx.tx.V)
|
||||
|
||||
proc txType(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
let tx = TxNode(parent)
|
||||
let typ = resp(ord(tx.tx.txType))
|
||||
ok(typ)
|
||||
|
||||
proc txAccessList(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
let ctx = GraphqlContextRef(ud)
|
||||
let tx = TxNode(parent)
|
||||
if tx.tx.txType == LegacyTxType:
|
||||
ok(respNull())
|
||||
else:
|
||||
var list = respList()
|
||||
for x in tx.tx.accessListTx.accessList:
|
||||
list.add aclNode(ctx, x)
|
||||
ok(list)
|
||||
|
||||
const txProcs = {
|
||||
"from": txFrom,
|
||||
"hash": txHash,
|
||||
@ -653,7 +693,31 @@ const txProcs = {
|
||||
"gasUsed": txGasUsed,
|
||||
"cumulativeGasUsed": txCumulativeGasUsed,
|
||||
"createdContract": txCreatedContract,
|
||||
"logs": txLogs
|
||||
"logs": txLogs,
|
||||
"r": txR,
|
||||
"s": txS,
|
||||
"v": txV,
|
||||
"type": txType,
|
||||
"accessList": txAccessList
|
||||
}
|
||||
|
||||
proc aclAddress(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
let acl = AclNode(parent)
|
||||
resp(acl.acl.address)
|
||||
|
||||
proc aclStorageKeys(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
let acl = AclNode(parent)
|
||||
if acl.acl.storageKeys.len == 0:
|
||||
ok(respNull())
|
||||
else:
|
||||
var list = respList()
|
||||
for n in acl.acl.storageKeys:
|
||||
list.add resp(n).get()
|
||||
ok(list)
|
||||
|
||||
const aclProcs = {
|
||||
"address": aclAddress,
|
||||
"storageKeys": aclStorageKeys
|
||||
}
|
||||
|
||||
proc blockNumberImpl(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
@ -1086,17 +1150,17 @@ type
|
||||
qcFields = "fields"
|
||||
qcBlock = "block"
|
||||
qcTransaction = "Transaction"
|
||||
|
||||
|
||||
EthQueryComplexity = ref object of QueryComplexity
|
||||
names: array[QcNames, Name]
|
||||
|
||||
proc calcQC(qc: QueryComplexity, field: FieldRef): int {.cdecl,
|
||||
|
||||
proc calcQC(qc: QueryComplexity, field: FieldRef): int {.cdecl,
|
||||
gcsafe, raises: [Defect, CatchableError].} =
|
||||
let qc = EthQueryComplexity(qc)
|
||||
if field.parentType.sym.name == qc.names[qcType] and
|
||||
field.field.name.name == qc.names[qcFields]:
|
||||
return 100
|
||||
elif field.parentType.sym.name == qc.names[qcTransaction] and
|
||||
elif field.parentType.sym.name == qc.names[qcTransaction] and
|
||||
field.field.name.name == qc.names[qcBlock]:
|
||||
return 100
|
||||
else:
|
||||
@ -1110,7 +1174,7 @@ proc newQC(ctx: GraphqlContextRef): EthQueryComplexity =
|
||||
let name = ctx.createName($n)
|
||||
qc.names[n] = name
|
||||
qc
|
||||
|
||||
|
||||
proc initEthApi(ctx: GraphqlContextRef) =
|
||||
ctx.customScalar("Bytes32", scalarBytes32)
|
||||
ctx.customScalar("Address", scalarAddress)
|
||||
@ -1131,10 +1195,11 @@ proc initEthApi(ctx: GraphqlContextRef) =
|
||||
ctx.addResolvers(ctx, ctx.ids[ethPending ], pendingProcs)
|
||||
ctx.addResolvers(ctx, ctx.ids[ethQuery ], queryProcs)
|
||||
ctx.addResolvers(ctx, ctx.ids[ethMutation ], mutationProcs)
|
||||
ctx.addResolvers(ctx, ctx.ids[ethAccessTuple], aclProcs)
|
||||
|
||||
var qc = newQC(ctx)
|
||||
ctx.addInstrument(qc)
|
||||
|
||||
|
||||
let res = ctx.parseSchema(ethSchema)
|
||||
if res.isErr:
|
||||
echo res.error
|
||||
|
@ -62,6 +62,15 @@ type Log {
|
||||
transaction: Transaction!
|
||||
}
|
||||
|
||||
# EIP-2718 Access List
|
||||
type AccessTuple {
|
||||
# access list address
|
||||
address: Address!
|
||||
|
||||
# access list storage keys, null if not present
|
||||
storageKeys: [Bytes32!]
|
||||
}
|
||||
|
||||
# Transaction is an Ethereum transaction.
|
||||
type Transaction {
|
||||
# Hash is the hash of this transaction.
|
||||
@ -123,6 +132,21 @@ type Transaction {
|
||||
# Logs is a list of log entries emitted by this transaction. If the
|
||||
# transaction has not yet been mined, this field will be null.
|
||||
logs: [Log!]
|
||||
|
||||
# signature field R
|
||||
r: BigInt!
|
||||
|
||||
# signature fields S
|
||||
s: BigInt!
|
||||
|
||||
# signature fields V
|
||||
v: BigInt!
|
||||
|
||||
# EIP 2718: envelope transaction support
|
||||
type: Int
|
||||
|
||||
# EIP 2930: optional access list, null if not present
|
||||
accessList: [AccessTuple!]
|
||||
}
|
||||
|
||||
# BlockFilterCriteria encapsulates log filter criteria for a filter applied
|
||||
|
@ -29,6 +29,7 @@
|
||||
{"name":"Bytes"},
|
||||
{"name":"String"},
|
||||
{"name":"Bytes32"},
|
||||
{"name":"AccessTuple"},
|
||||
{"name":"BlockFilterCriteria"},
|
||||
{"name":"ID"},
|
||||
{"name":"Pending"},
|
||||
@ -194,6 +195,14 @@
|
||||
logs {
|
||||
__typename
|
||||
}
|
||||
r
|
||||
s
|
||||
v
|
||||
type
|
||||
accessList {
|
||||
address
|
||||
storageKeys
|
||||
}
|
||||
}
|
||||
transactionAt(index: 0) {
|
||||
__typename
|
||||
@ -230,7 +239,12 @@
|
||||
"gasUsed":21000,
|
||||
"cumulativeGasUsed":21000,
|
||||
"createdContract":null,
|
||||
"logs":[]
|
||||
"logs":[],
|
||||
"r":"0x77c7cd36820c71821c1aed59de46e70e701c4a8dd89c9ba508ab722210f60da8",
|
||||
"s":"0x3f29825d40c7c3f7bff3ca69267e0f3fb74b2d18b8c2c4e3c135b5d3b06e288d",
|
||||
"v":"0x1b",
|
||||
"type":0,
|
||||
"accessList":null
|
||||
}
|
||||
],
|
||||
"transactionAt":{
|
||||
|
Loading…
x
Reference in New Issue
Block a user