Implement Fluffy JSON-RPC endpoints. (#2364)
* Implement eth_getBalance, eth_getTransactionCount, eth_getStorageAt and eth_getCode JSON-RPCs. * Fixes.
This commit is contained in:
parent
4c458190e9
commit
1377f93d50
|
@ -349,7 +349,7 @@ proc run(config: PortalConf) {.raises: [CatchableError].} =
|
|||
)
|
||||
if historyNetwork.isSome():
|
||||
rpcHttpServerWithProxy.installEthApiHandlers(
|
||||
historyNetwork.get(), beaconLightClient
|
||||
historyNetwork.get(), beaconLightClient, stateNetwork
|
||||
)
|
||||
rpcHttpServerWithProxy.installPortalApiHandlers(
|
||||
historyNetwork.get().portalProtocol, "history"
|
||||
|
|
|
@ -223,7 +223,8 @@ proc processContentLoop(n: StateNetwork) {.async: (raises: []).} =
|
|||
trace "processContentLoop canceled"
|
||||
|
||||
proc start*(n: StateNetwork) =
|
||||
info "Starting Portal State Network", protocolId = n.portalProtocol.protocolId
|
||||
info "Starting Portal execution state network",
|
||||
protocolId = n.portalProtocol.protocolId
|
||||
n.portalProtocol.start()
|
||||
|
||||
n.processContentLoop = processContentLoop(n)
|
||||
|
|
|
@ -12,9 +12,11 @@ import
|
|||
json_rpc/[rpcproxy, rpcserver],
|
||||
web3/conversions, # sigh, for FixedBytes marshalling
|
||||
web3/eth_api_types,
|
||||
eth/[common/eth_types, rlp],
|
||||
web3/primitives as web3types,
|
||||
eth/common/eth_types,
|
||||
beacon_chain/spec/forks,
|
||||
../network/history/[history_network, history_content],
|
||||
../network/state/[state_network, state_content, state_endpoints],
|
||||
../network/beacon/beacon_light_client
|
||||
|
||||
from ../../nimbus/transaction import getSender, ValidationError
|
||||
|
@ -127,6 +129,7 @@ proc installEthApiHandlers*(
|
|||
rpcServerWithProxy: var RpcProxy,
|
||||
historyNetwork: HistoryNetwork,
|
||||
beaconLightClient: Opt[LightClient],
|
||||
stateNetwork: Opt[StateNetwork],
|
||||
) =
|
||||
# Supported API
|
||||
rpcServerWithProxy.registerProxyMethod("eth_blockNumber")
|
||||
|
@ -343,53 +346,113 @@ proc installEthApiHandlers*(
|
|||
return filteredLogs
|
||||
else:
|
||||
# bloomfilter returned false, there are no logs matching the criteria
|
||||
return
|
||||
@[]
|
||||
return @[]
|
||||
|
||||
# rpcServerWithProxy.rpc("eth_getBalance") do(
|
||||
# data: Address, quantityTag: RtBlockIdentifier
|
||||
# ) -> UInt256:
|
||||
# ## Returns the balance of the account of given address.
|
||||
# ##
|
||||
# ## data: address to check for balance.
|
||||
# ## quantityTag: integer block number, or the string "latest", "earliest" or "pending", see the default block parameter.
|
||||
# ## Returns integer of the current balance in wei.
|
||||
# # TODO
|
||||
# raiseAssert("Not implemented")
|
||||
rpcServerWithProxy.rpc("eth_getBalance") do(
|
||||
data: web3Types.Address, quantityTag: RtBlockIdentifier
|
||||
) -> UInt256:
|
||||
## Returns the balance of the account of given address.
|
||||
##
|
||||
## data: address to check for balance.
|
||||
## quantityTag: integer block number, or the string "latest", "earliest" or "pending", see the default block parameter.
|
||||
## Returns integer of the current balance in wei.
|
||||
if stateNetwork.isNone():
|
||||
raise newException(ValueError, "State sub-network not enabled")
|
||||
|
||||
# rpcServerWithProxy.rpc("eth_getTransactionCount") do(
|
||||
# data: Address, quantityTag: RtBlockIdentifier
|
||||
# ) -> Quantity:
|
||||
# ## Returns the number of transactions sent from an address.
|
||||
# ##
|
||||
# ## data: address.
|
||||
# ## quantityTag: integer block number, or the string "latest", "earliest" or "pending", see the default block parameter.
|
||||
# ## Returns integer of the number of transactions send from this address.
|
||||
# # TODO
|
||||
# raiseAssert("Not implemented")
|
||||
if quantityTag.kind == bidAlias:
|
||||
# TODO: Implement
|
||||
raise newException(ValueError, "tag not yet implemented")
|
||||
else:
|
||||
let
|
||||
blockNumber = quantityTag.number.uint64.u256
|
||||
blockHash = (await historyNetwork.getBlockHashByNumber(blockNumber)).valueOr:
|
||||
raise newException(ValueError, error)
|
||||
|
||||
# rpcServerWithProxy.rpc("eth_getStorageAt") do(
|
||||
# data: Address, slot: UInt256, quantityTag: RtBlockIdentifier
|
||||
# ) -> FixedBytes[32]:
|
||||
# ## Returns the value from a storage position at a given address.
|
||||
# ##
|
||||
# ## data: address of the storage.
|
||||
# ## slot: integer of the position in the storage.
|
||||
# ## quantityTag: integer block number, or the string "latest", "earliest" or "pending", see the default block parameter.
|
||||
# ## Returns: the value at this storage position.
|
||||
# # TODO
|
||||
# raiseAssert("Not implemented")
|
||||
balance = (await stateNetwork.get().getBalance(blockHash, data.EthAddress)).valueOr:
|
||||
# Should we return 0 here or throw a more detailed error?
|
||||
raise newException(ValueError, "Unable to get balance")
|
||||
|
||||
# rpcServerWithProxy.rpc("eth_getCode") do(
|
||||
# data: Address, quantityTag: RtBlockIdentifier
|
||||
# ) -> seq[byte]:
|
||||
# ## Returns code at a given address.
|
||||
# ##
|
||||
# ## data: address
|
||||
# ## quantityTag: integer block number, or the string "latest", "earliest" or "pending", see the default block parameter.
|
||||
# ## Returns the code from the given address.
|
||||
# # TODO
|
||||
# raiseAssert("Not implemented")
|
||||
return balance
|
||||
|
||||
rpcServerWithProxy.rpc("eth_getTransactionCount") do(
|
||||
data: web3Types.Address, quantityTag: RtBlockIdentifier
|
||||
) -> Quantity:
|
||||
## Returns the number of transactions sent from an address.
|
||||
##
|
||||
## data: address.
|
||||
## quantityTag: integer block number, or the string "latest", "earliest" or "pending", see the default block parameter.
|
||||
## Returns integer of the number of transactions send from this address.
|
||||
if stateNetwork.isNone():
|
||||
raise newException(ValueError, "State sub-network not enabled")
|
||||
|
||||
if quantityTag.kind == bidAlias:
|
||||
# TODO: Implement
|
||||
raise newException(ValueError, "tag not yet implemented")
|
||||
else:
|
||||
let
|
||||
blockNumber = quantityTag.number.uint64.u256
|
||||
blockHash = (await historyNetwork.getBlockHashByNumber(blockNumber)).valueOr:
|
||||
raise newException(ValueError, error)
|
||||
|
||||
nonce = (
|
||||
await stateNetwork.get().getTransactionCount(blockHash, data.EthAddress)
|
||||
).valueOr:
|
||||
# Should we return 0 here or throw a more detailed error?
|
||||
raise newException(ValueError, "Unable to get transaction count")
|
||||
return nonce.Quantity
|
||||
|
||||
rpcServerWithProxy.rpc("eth_getStorageAt") do(
|
||||
data: web3Types.Address, slot: UInt256, quantityTag: RtBlockIdentifier
|
||||
) -> FixedBytes[32]:
|
||||
## Returns the value from a storage position at a given address.
|
||||
##
|
||||
## data: address of the storage.
|
||||
## slot: integer of the position in the storage.
|
||||
## quantityTag: integer block number, or the string "latest", "earliest" or "pending", see the default block parameter.
|
||||
## Returns: the value at this storage position.
|
||||
if stateNetwork.isNone():
|
||||
raise newException(ValueError, "State sub-network not enabled")
|
||||
|
||||
if quantityTag.kind == bidAlias:
|
||||
# TODO: Implement
|
||||
raise newException(ValueError, "tag not yet implemented")
|
||||
else:
|
||||
let
|
||||
blockNumber = quantityTag.number.uint64.u256
|
||||
blockHash = (await historyNetwork.getBlockHashByNumber(blockNumber)).valueOr:
|
||||
raise newException(ValueError, error)
|
||||
|
||||
slotValue = (
|
||||
await stateNetwork.get().getStorageAt(blockHash, data.EthAddress, slot)
|
||||
).valueOr:
|
||||
# Should we return 0 here or throw a more detailed error?
|
||||
raise newException(ValueError, "Unable to get storage slot")
|
||||
return FixedBytes[32](slotValue.toBytesBE())
|
||||
|
||||
rpcServerWithProxy.rpc("eth_getCode") do(
|
||||
data: web3Types.Address, quantityTag: RtBlockIdentifier
|
||||
) -> seq[byte]:
|
||||
## Returns code at a given address.
|
||||
##
|
||||
## data: address
|
||||
## quantityTag: integer block number, or the string "latest", "earliest" or "pending", see the default block parameter.
|
||||
## Returns the code from the given address.
|
||||
if stateNetwork.isNone():
|
||||
raise newException(ValueError, "State sub-network not enabled")
|
||||
|
||||
if quantityTag.kind == bidAlias:
|
||||
# TODO: Implement
|
||||
raise newException(ValueError, "tag not yet implemented")
|
||||
else:
|
||||
let
|
||||
blockNumber = quantityTag.number.uint64.u256
|
||||
blockHash = (await historyNetwork.getBlockHashByNumber(blockNumber)).valueOr:
|
||||
raise newException(ValueError, error)
|
||||
|
||||
bytecode = (await stateNetwork.get().getCode(blockHash, data.EthAddress)).valueOr:
|
||||
# Should we return empty sequence here or throw a more detailed error?
|
||||
raise newException(ValueError, "Unable to get code")
|
||||
return bytecode.asSeq()
|
||||
|
||||
# rpcServerWithProxy.rpc("eth_getProof") do(
|
||||
# address: Address, slots: seq[UInt256], quantityTag: RtBlockIdentifier
|
||||
|
|
Loading…
Reference in New Issue