Use separeate client and server in lcproxy (#1208)

* Use separate client and server in lc proxy
This commit is contained in:
KonradStaniec 2022-08-31 07:48:48 +02:00 committed by GitHub
parent 0353803012
commit 5aaf16049f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 29 deletions

View File

@ -14,6 +14,7 @@ import
std/[os, strutils], std/[os, strutils],
chronicles, chronicles/chronos_tools, chronos, chronicles, chronicles/chronos_tools, chronos,
eth/keys, eth/keys,
json_rpc/[rpcserver, rpcclient],
beacon_chain/eth1/eth1_monitor, beacon_chain/eth1/eth1_monitor,
beacon_chain/gossip_processing/optimistic_processor, beacon_chain/gossip_processing/optimistic_processor,
beacon_chain/networking/topic_params, 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/block_processor import newExecutionPayload
from beacon_chain/gossip_processing/eth2_processor import toValidationResult from beacon_chain/gossip_processing/eth2_processor import toValidationResult
proc initRpcProxy(config: LcProxyConf): RpcProxy {.raises: [CatchableError, Defect].} = proc initRpcClient(config: LcProxyConf): Future[RpcClient] {.async.} =
let ta = initTAddress(config.rpcAddress, config.rpcPort)
let clientConfig =
case config.web3ClientConfig.kind case config.web3ClientConfig.kind
of WsClient: of WsClient:
getWebSocketClientConfig(config.web3ClientConfig.url) let wssClient = newRpcWebSocketClient()
await wssClient.connect(config.web3ClientConfig.url)
return wssClient
of HttpClient: of HttpClient:
getHttpClientConfig(config.web3ClientConfig.url) let httpClient = newRpcHttpClient()
await httpClient.connect(config.web3ClientConfig.url)
return RpcProxy.new([ta], clientConfig) return httpClient
# TODO Find what can throw exception # TODO Find what can throw exception
proc run() {.raises: [Exception, Defect].} = proc run() {.raises: [Exception, Defect].} =
@ -88,9 +89,13 @@ proc run() {.raises: [Exception, Defect].} =
forkDigests, getBeaconTime, genesis_validators_root 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): optimisticHandler = proc(signedBlock: ForkedMsgTrustedSignedBeaconBlock):
Future[void] {.async.} = Future[void] {.async.} =
@ -135,7 +140,7 @@ proc run() {.raises: [Exception, Defect].} =
waitFor network.startListening() waitFor network.startListening()
waitFor network.start() waitFor network.start()
waitFor lcProxy.proxy.start() lcProxy.server.start()
proc onFinalizedHeader( proc onFinalizedHeader(
lightClient: LightClient, finalizedHeader: BeaconBlockHeader) = lightClient: LightClient, finalizedHeader: BeaconBlockHeader) =

View File

@ -8,44 +8,63 @@
{.push raises: [Defect].} {.push raises: [Defect].}
import import
json_rpc/[rpcproxy, rpcserver], stint,
web3/conversions, chronicles,
../../nimbus/rpc/[hexstrings, rpc_types], json_rpc/[rpcserver, rpcclient],
web3,
web3/ethhexstrings,
beacon_chain/eth1/eth1_monitor, beacon_chain/eth1/eth1_monitor,
beacon_chain/spec/forks beacon_chain/spec/forks
export rpcproxy, forks export forks
logScope:
topics = "light_proxy"
template encodeQuantity(value: UInt256): HexQuantityStr = template encodeQuantity(value: UInt256): HexQuantityStr =
HexQuantityStr("0x" & value.toHex()) hexQuantityStr("0x" & value.toHex())
proc encodeQuantity(q: Quantity): hexstrings.HexQuantityStr = template encodeQuantity(value: Quantity): HexQuantityStr =
return hexstrings.encodeQuantity(distinctBase(q)) hexQuantityStr(encodeQuantity(value.uint64))
type LightClientRpcProxy* = ref object type LightClientRpcProxy* = ref object
proxy*: RpcProxy client*: RpcClient
server*: RpcHttpServer
executionPayload*: Opt[ExecutionPayloadV1] executionPayload*: Opt[ExecutionPayloadV1]
proc installEthApiHandlers*(lcProxy: LightClientRpcProxy) = proc installEthApiHandlers*(lcProxy: LightClientRpcProxy) =
template payload(): Opt[ExecutionPayloadV1] = lcProxy.executionPayload 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. ## Returns the number of most recent block.
if payload.isNone: if payload.isNone:
raise newException(ValueError, "Syncing") raise newException(ValueError, "Syncing")
return encodeQuantity(payload.get.blockNumber) return encodeQuantity(payload.get.blockNumber)
lcProxy.proxy.rpc("eth_getBlockByNumber") do( # TODO quantity tag should be better typed
quantityTag: string, fullTransactions: bool) -> Option[rpc_types.BlockObject]: lcProxy.server.rpc("eth_getBalance") do(address: Address, quantityTag: string) -> HexQuantityStr:
## Returns information about a block by number.
if payload.isNone: if payload.isNone:
raise newException(ValueError, "Syncing") raise newException(ValueError, "Syncing")
if quantityTag != "latest": 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") raise newException(ValueError, "Only latest block is supported")
if fullTransactions: # When requesting state for `latest` block number, we need to translate
raise newException(ValueError, "Transaction bodies not supported") # `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)

2
vendor/nimbus-eth2 vendored

@ -1 +1 @@
Subproject commit 64972e3c8a6eccc49054e95a893048916b1806a4 Subproject commit 59092e5b3bc38ed42995fc7276f7c4601b890988