Use separeate client and server in lcproxy (#1208)
* Use separate client and server in lc proxy
This commit is contained in:
parent
0353803012
commit
5aaf16049f
|
@ -14,6 +14,7 @@ import
|
|||
std/[os, strutils],
|
||||
chronicles, chronicles/chronos_tools, chronos,
|
||||
eth/keys,
|
||||
json_rpc/[rpcserver, rpcclient],
|
||||
beacon_chain/eth1/eth1_monitor,
|
||||
beacon_chain/gossip_processing/optimistic_processor,
|
||||
beacon_chain/networking/topic_params,
|
||||
|
@ -27,16 +28,16 @@ from beacon_chain/consensus_object_pools/consensus_manager import runForkchoiceU
|
|||
from beacon_chain/gossip_processing/block_processor import newExecutionPayload
|
||||
from beacon_chain/gossip_processing/eth2_processor import toValidationResult
|
||||
|
||||
proc initRpcProxy(config: LcProxyConf): RpcProxy {.raises: [CatchableError, Defect].} =
|
||||
let ta = initTAddress(config.rpcAddress, config.rpcPort)
|
||||
let clientConfig =
|
||||
proc initRpcClient(config: LcProxyConf): Future[RpcClient] {.async.} =
|
||||
case config.web3ClientConfig.kind
|
||||
of WsClient:
|
||||
getWebSocketClientConfig(config.web3ClientConfig.url)
|
||||
let wssClient = newRpcWebSocketClient()
|
||||
await wssClient.connect(config.web3ClientConfig.url)
|
||||
return wssClient
|
||||
of HttpClient:
|
||||
getHttpClientConfig(config.web3ClientConfig.url)
|
||||
|
||||
return RpcProxy.new([ta], clientConfig)
|
||||
let httpClient = newRpcHttpClient()
|
||||
await httpClient.connect(config.web3ClientConfig.url)
|
||||
return httpClient
|
||||
|
||||
# TODO Find what can throw exception
|
||||
proc run() {.raises: [Exception, Defect].} =
|
||||
|
@ -88,9 +89,13 @@ proc run() {.raises: [Exception, Defect].} =
|
|||
forkDigests, getBeaconTime, genesis_validators_root
|
||||
)
|
||||
|
||||
rpcServerWithProxy = initRpcProxy(config)
|
||||
rpcClient = waitFor initRpcClient(config)
|
||||
|
||||
lcProxy = LightClientRpcProxy(proxy: rpcServerWithProxy)
|
||||
rpcHttpServer = newRpcHttpServer(
|
||||
[initTAddress(config.rpcAddress, config.rpcPort)]
|
||||
)
|
||||
|
||||
lcProxy = LightClientRpcProxy(server: rpcHttpServer, client: rpcClient)
|
||||
|
||||
optimisticHandler = proc(signedBlock: ForkedMsgTrustedSignedBeaconBlock):
|
||||
Future[void] {.async.} =
|
||||
|
@ -135,7 +140,7 @@ proc run() {.raises: [Exception, Defect].} =
|
|||
|
||||
waitFor network.startListening()
|
||||
waitFor network.start()
|
||||
waitFor lcProxy.proxy.start()
|
||||
lcProxy.server.start()
|
||||
|
||||
proc onFinalizedHeader(
|
||||
lightClient: LightClient, finalizedHeader: BeaconBlockHeader) =
|
||||
|
|
|
@ -8,44 +8,63 @@
|
|||
{.push raises: [Defect].}
|
||||
|
||||
import
|
||||
json_rpc/[rpcproxy, rpcserver],
|
||||
web3/conversions,
|
||||
../../nimbus/rpc/[hexstrings, rpc_types],
|
||||
stint,
|
||||
chronicles,
|
||||
json_rpc/[rpcserver, rpcclient],
|
||||
web3,
|
||||
web3/ethhexstrings,
|
||||
beacon_chain/eth1/eth1_monitor,
|
||||
beacon_chain/spec/forks
|
||||
|
||||
export rpcproxy, forks
|
||||
export forks
|
||||
|
||||
logScope:
|
||||
topics = "light_proxy"
|
||||
|
||||
template encodeQuantity(value: UInt256): HexQuantityStr =
|
||||
HexQuantityStr("0x" & value.toHex())
|
||||
hexQuantityStr("0x" & value.toHex())
|
||||
|
||||
proc encodeQuantity(q: Quantity): hexstrings.HexQuantityStr =
|
||||
return hexstrings.encodeQuantity(distinctBase(q))
|
||||
template encodeQuantity(value: Quantity): HexQuantityStr =
|
||||
hexQuantityStr(encodeQuantity(value.uint64))
|
||||
|
||||
type LightClientRpcProxy* = ref object
|
||||
proxy*: RpcProxy
|
||||
client*: RpcClient
|
||||
server*: RpcHttpServer
|
||||
executionPayload*: Opt[ExecutionPayloadV1]
|
||||
|
||||
proc installEthApiHandlers*(lcProxy: LightClientRpcProxy) =
|
||||
template payload(): Opt[ExecutionPayloadV1] = lcProxy.executionPayload
|
||||
|
||||
lcProxy.proxy.rpc("eth_blockNumber") do() -> HexQuantityStr:
|
||||
lcProxy.server.rpc("eth_blockNumber") do() -> HexQuantityStr:
|
||||
## Returns the number of most recent block.
|
||||
if payload.isNone:
|
||||
raise newException(ValueError, "Syncing")
|
||||
|
||||
return encodeQuantity(payload.get.blockNumber)
|
||||
|
||||
lcProxy.proxy.rpc("eth_getBlockByNumber") do(
|
||||
quantityTag: string, fullTransactions: bool) -> Option[rpc_types.BlockObject]:
|
||||
## Returns information about a block by number.
|
||||
# TODO quantity tag should be better typed
|
||||
lcProxy.server.rpc("eth_getBalance") do(address: Address, quantityTag: string) -> HexQuantityStr:
|
||||
if payload.isNone:
|
||||
raise newException(ValueError, "Syncing")
|
||||
|
||||
if quantityTag != "latest":
|
||||
# TODO for now we support only latest block, as its semanticly most streight
|
||||
# forward i.e it is last received and valid ExecutionPayloadV1.
|
||||
# Ultimatly we could keep track of n last valid payload and support number
|
||||
# queries for this set of blocks
|
||||
# `Pending` coud be mapped to some optimisc header with block fetched on demand
|
||||
raise newException(ValueError, "Only latest block is supported")
|
||||
|
||||
if fullTransactions:
|
||||
raise newException(ValueError, "Transaction bodies not supported")
|
||||
# When requesting state for `latest` block number, we need to translate
|
||||
# `latest` to actual block number as `latest` on proxy and on data provider
|
||||
# can mean different blocks and ultimatly piece received piece of state
|
||||
# must by validated against correct state root
|
||||
let blockNumber = payload.get.blockNumber.uint64
|
||||
|
||||
return some rpc_types.BlockObject(number: some(encodeQuantity(payload.get.blockNumber)))
|
||||
info "Forwarding get_Balance", executionBn = blockNumber
|
||||
|
||||
# TODO this could be realised by eth_getProof as it return also balance
|
||||
# of the account
|
||||
let b = await lcProxy.client.eth_getBalance(address, blockId(blockNumber))
|
||||
|
||||
return encodeQuantity(b)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 64972e3c8a6eccc49054e95a893048916b1806a4
|
||||
Subproject commit 59092e5b3bc38ed42995fc7276f7c4601b890988
|
Loading…
Reference in New Issue