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],
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) =

View File

@ -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)

2
vendor/nimbus-eth2 vendored

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