diff --git a/fluffy/conf.nim b/fluffy/conf.nim index a14bb3351..4521b7662 100644 --- a/fluffy/conf.nim +++ b/fluffy/conf.nim @@ -15,7 +15,6 @@ import chronicles, eth/keys, eth/p2p/discoveryv5/[enr, node, routing_table], - json_rpc/rpcproxy, nimcrypto/hash, stew/byteutils, eth/net/nat, # must be late (compilation annoyance) @@ -36,13 +35,10 @@ proc defaultDataDir*(): string = const defaultListenAddress* = (static parseIpAddress("0.0.0.0")) defaultAdminListenAddress* = (static parseIpAddress("127.0.0.1")) - defaultProxyAddress* = (static "http://127.0.0.1:8546") - defaultClientConfig* = getHttpClientConfig(defaultProxyAddress) defaultListenAddressDesc = $defaultListenAddress defaultAdminListenAddressDesc = $defaultAdminListenAddress defaultDataDirDesc = defaultDataDir() - defaultClientConfigDesc = $(defaultClientConfig.httpUri) defaultStorageCapacity* = 2000'u32 # 2 GB default defaultStorageCapacityDesc* = $defaultStorageCapacity @@ -192,15 +188,6 @@ type name: "rpc-address" .}: IpAddress - # it makes little sense to have default value here in final release, but until then - # it would be troublesome to add some fake uri param every time - proxyUri* {. - defaultValue: defaultClientConfig, - defaultValueDesc: $defaultClientConfigDesc, - desc: "URI of eth client where to proxy unimplemented JSON-RPC methods to", - name: "proxy-uri" - .}: ClientConfig - tableIpLimit* {. hidden, desc: @@ -329,20 +316,6 @@ proc parseCmdArg*(T: type PrivateKey, p: string): T {.raises: [ValueError].} = proc completeCmdArg*(T: type PrivateKey, val: string): seq[string] = return @[] -proc parseCmdArg*(T: type ClientConfig, p: string): T {.raises: [ValueError].} = - let uri = parseUri(p) - if (uri.scheme == "http" or uri.scheme == "https"): - getHttpClientConfig(p) - elif (uri.scheme == "ws" or uri.scheme == "wss"): - getWebSocketClientConfig(p) - else: - raise newException( - ValueError, "Proxy uri should have defined scheme (http/https/ws/wss)" - ) - -proc completeCmdArg*(T: type ClientConfig, val: string): seq[string] = - return @[] - proc parseCmdArg*( T: type set[PortalSubnetwork], p: string ): T {.raises: [ValueError].} = diff --git a/fluffy/fluffy.nim b/fluffy/fluffy.nim index 5c6f6a27a..bb8aa208a 100644 --- a/fluffy/fluffy.nim +++ b/fluffy/fluffy.nim @@ -17,7 +17,6 @@ import metrics, metrics/chronos_httpserver, json_rpc/clients/httpclient, - json_rpc/rpcproxy, results, stew/[byteutils, io2], eth/keys, @@ -216,30 +215,29 @@ proc run(config: PortalConf) {.raises: [CatchableError].} = # Note: Set maxRequestBodySize to 4MB instead of 1MB as there are blocks # that reach that limit (in hex, for gossip method). rpcHttpServer.addHttpServer(ta, maxRequestBodySize = 4 * 1_048_576) - var rpcHttpServerWithProxy = RpcProxy.new(rpcHttpServer, config.proxyUri) - rpcHttpServerWithProxy.installDiscoveryApiHandlers(d) - rpcHttpServerWithProxy.installWeb3ApiHandlers() + rpcHttpServer.installDiscoveryApiHandlers(d) + rpcHttpServer.installWeb3ApiHandlers() if node.stateNetwork.isSome(): - rpcHttpServerWithProxy.installPortalApiHandlers( + rpcHttpServer.installPortalApiHandlers( node.stateNetwork.value.portalProtocol, "state" ) if node.historyNetwork.isSome(): - rpcHttpServerWithProxy.installEthApiHandlers( + rpcHttpServer.installEthApiHandlers( node.historyNetwork.value, node.beaconLightClient, node.stateNetwork ) - rpcHttpServerWithProxy.installPortalApiHandlers( + rpcHttpServer.installPortalApiHandlers( node.historyNetwork.value.portalProtocol, "history" ) - rpcHttpServerWithProxy.installPortalDebugApiHandlers( + rpcHttpServer.installPortalDebugApiHandlers( node.historyNetwork.value.portalProtocol, "history" ) if node.beaconNetwork.isSome(): - rpcHttpServerWithProxy.installPortalApiHandlers( + rpcHttpServer.installPortalApiHandlers( node.beaconNetwork.value.portalProtocol, "beacon" ) - # TODO: Test proxy with remote node over HTTPS - waitFor rpcHttpServerWithProxy.start() + + rpcHttpServer.start() runForever() diff --git a/fluffy/rpc/rpc_discovery_api.nim b/fluffy/rpc/rpc_discovery_api.nim index 6c5c68e77..02383c09b 100644 --- a/fluffy/rpc/rpc_discovery_api.nim +++ b/fluffy/rpc/rpc_discovery_api.nim @@ -9,7 +9,7 @@ import std/sequtils, - json_rpc/[rpcproxy, rpcserver], + json_rpc/rpcserver, stew/byteutils, eth/p2p/discoveryv5/protocol as discv5_protocol, ./rpc_types @@ -23,9 +23,7 @@ type PongResponse* = object PongResponse.useDefaultSerializationIn JrpcConv -proc installDiscoveryApiHandlers*( - rpcServer: RpcServer | RpcProxy, d: discv5_protocol.Protocol -) = +proc installDiscoveryApiHandlers*(rpcServer: RpcServer, d: discv5_protocol.Protocol) = ## Discovery v5 JSON-RPC API such as defined here: ## https://github.com/ethereum/portal-network-specs/tree/master/jsonrpc diff --git a/fluffy/rpc/rpc_eth_api.nim b/fluffy/rpc/rpc_eth_api.nim index 2271ef542..4d68e7db4 100644 --- a/fluffy/rpc/rpc_eth_api.nim +++ b/fluffy/rpc/rpc_eth_api.nim @@ -9,7 +9,7 @@ import std/[times, sequtils, strutils, typetraits], - json_rpc/[rpcproxy, rpcserver], + json_rpc/rpcserver, chronicles, web3/conversions, # sigh, for FixedBytes marshalling web3/eth_api_types, @@ -35,12 +35,6 @@ from ../../nimbus/beacon/web3_eth_conv import w3Addr, w3Hash, ethHash # - eth_getBlockTransactionCountByHash # - eth_getLogs - Partially: only requests by block hash # -# In order to be able to use Fluffy as drop-in replacement for apps/tools that -# use the JSON RPC API, unsupported methods can be forwarded to a configured -# web3 provider. -# Supported methods will be handled by Fluffy by making use of the Portal network, -# unsupported methods will be proxied to the given web3 provider. -# # Some similar code as from nimbus `rpc_utils`, but avoiding that import as it # brings in a lot more. Should restructure `rpc_utils` a bit before using that. @@ -128,94 +122,19 @@ func init*( blockObject proc installEthApiHandlers*( - rpcServerWithProxy: var RpcProxy, + rpcServer: RpcServer, historyNetwork: HistoryNetwork, beaconLightClient: Opt[LightClient], stateNetwork: Opt[StateNetwork], ) = - # Supported API - rpcServerWithProxy.registerProxyMethod("eth_blockNumber") - - rpcServerWithProxy.registerProxyMethod("eth_call") - - # rpcServerWithProxy.registerProxyMethod("eth_chainId") - - rpcServerWithProxy.registerProxyMethod("eth_estimateGas") - - rpcServerWithProxy.registerProxyMethod("eth_feeHistory") - - #rpcServerWithProxy.registerProxyMethod("eth_getBalance") - - # rpcServerWithProxy.registerProxyMethod("eth_getBlockByHash") - - # rpcServerWithProxy.registerProxyMethod("eth_getBlockByNumber") - - # rpcServerWithProxy.registerProxyMethod("eth_getBlockTransactionCountByHash") - - rpcServerWithProxy.registerProxyMethod("eth_getBlockTransactionCountByNumber") - - #rpcServerWithProxy.registerProxyMethod("eth_getCode") - - rpcServerWithProxy.registerProxyMethod("eth_getRawTransactionByHash") - - rpcServerWithProxy.registerProxyMethod("eth_getRawTransactionByBlockHashAndIndex") - - rpcServerWithProxy.registerProxyMethod("eth_getRawTransactionByBlockNumberAndIndex") - - #rpcServerWithProxy.registerProxyMethod("eth_getStorageAt") - - rpcServerWithProxy.registerProxyMethod("eth_getTransactionByBlockHashAndIndex") - - rpcServerWithProxy.registerProxyMethod("eth_getTransactionByBlockNumberAndIndex") - - rpcServerWithProxy.registerProxyMethod("eth_getTransactionByHash") - - #rpcServerWithProxy.registerProxyMethod("eth_getTransactionCount") - - rpcServerWithProxy.registerProxyMethod("eth_getTransactionReceipt") - - rpcServerWithProxy.registerProxyMethod("eth_getUncleByBlockHashAndIndex") - - rpcServerWithProxy.registerProxyMethod("eth_getUncleByBlockNumberAndIndex") - - rpcServerWithProxy.registerProxyMethod("eth_getUncleCountByBlockHash") - - rpcServerWithProxy.registerProxyMethod("eth_getUncleCountByBlockNumber") - - #rpcServerWithProxy.registerProxyMethod("eth_getProof") - - rpcServerWithProxy.registerProxyMethod("eth_sendRawTransaction") - - # Optional API - - rpcServerWithProxy.registerProxyMethod("eth_gasPrice") - - rpcServerWithProxy.registerProxyMethod("eth_getFilterChanges") - - rpcServerWithProxy.registerProxyMethod("eth_getFilterLogs") - - # rpcServerWithProxy.registerProxyMethod("eth_getLogs") - - rpcServerWithProxy.registerProxyMethod("eth_newBlockFilter") - - rpcServerWithProxy.registerProxyMethod("eth_newFilter") - - rpcServerWithProxy.registerProxyMethod("eth_newPendingTransactionFilter") - - rpcServerWithProxy.registerProxyMethod("eth_pendingTransactions") - - rpcServerWithProxy.registerProxyMethod("eth_syncing") - - rpcServerWithProxy.registerProxyMethod("eth_uninstallFilter") - # Supported API through the Portal Network - rpcServerWithProxy.rpc("eth_chainId") do() -> Quantity: + rpcServer.rpc("eth_chainId") do() -> Quantity: # The Portal Network can only support MainNet at the moment, so always return # 1 return Quantity(uint64(1)) - rpcServerWithProxy.rpc("eth_getBlockByHash") do( + rpcServer.rpc("eth_getBlockByHash") do( data: eth_api_types.Hash256, fullTransactions: bool ) -> Opt[BlockObject]: ## Returns information about a block by hash. @@ -232,7 +151,7 @@ proc installEthApiHandlers*( return Opt.some(BlockObject.init(header, body, fullTransactions)) - rpcServerWithProxy.rpc("eth_getBlockByNumber") do( + rpcServer.rpc("eth_getBlockByNumber") do( quantityTag: RtBlockIdentifier, fullTransactions: bool ) -> Opt[BlockObject]: if quantityTag.kind == bidAlias: @@ -286,7 +205,7 @@ proc installEthApiHandlers*( return Opt.some(BlockObject.init(header, body, fullTransactions)) - rpcServerWithProxy.rpc("eth_getBlockTransactionCountByHash") do( + rpcServer.rpc("eth_getBlockTransactionCountByHash") do( data: eth_api_types.Hash256 ) -> Quantity: ## Returns the number of transactions in a block from a block matching the @@ -309,12 +228,10 @@ proc installEthApiHandlers*( # of tx hash -> block number -> block hash, in order to get the receipt # from from the block with that block hash. The Canonical Indices Network # would need to be implemented to get this information. - # rpcServerWithProxy.rpc("eth_getTransactionReceipt") do( + # rpcServer.rpc("eth_getTransactionReceipt") do( # data: EthHashStr) -> Opt[ReceiptObject]: - rpcServerWithProxy.rpc("eth_getLogs") do( - filterOptions: FilterOptions - ) -> seq[LogObject]: + rpcServer.rpc("eth_getLogs") do(filterOptions: FilterOptions) -> seq[LogObject]: if filterOptions.blockHash.isNone(): # Currently only queries by blockhash are supported. # TODO: Can impolement range queries by block number now. @@ -346,7 +263,7 @@ proc installEthApiHandlers*( # bloomfilter returned false, there are no logs matching the criteria return @[] - rpcServerWithProxy.rpc("eth_getBalance") do( + rpcServer.rpc("eth_getBalance") do( data: web3Types.Address, quantityTag: RtBlockIdentifier ) -> UInt256: ## Returns the balance of the account of given address. @@ -369,7 +286,7 @@ proc installEthApiHandlers*( return balance - rpcServerWithProxy.rpc("eth_getTransactionCount") do( + rpcServer.rpc("eth_getTransactionCount") do( data: web3Types.Address, quantityTag: RtBlockIdentifier ) -> Quantity: ## Returns the number of transactions sent from an address. @@ -391,7 +308,7 @@ proc installEthApiHandlers*( raise newException(ValueError, "Unable to get transaction count") return nonce.Quantity - rpcServerWithProxy.rpc("eth_getStorageAt") do( + rpcServer.rpc("eth_getStorageAt") do( data: web3Types.Address, slot: UInt256, quantityTag: RtBlockIdentifier ) -> FixedBytes[32]: ## Returns the value from a storage position at a given address. @@ -414,7 +331,7 @@ proc installEthApiHandlers*( raise newException(ValueError, "Unable to get storage slot") return FixedBytes[32](slotValue.toBytesBE()) - rpcServerWithProxy.rpc("eth_getCode") do( + rpcServer.rpc("eth_getCode") do( data: web3Types.Address, quantityTag: RtBlockIdentifier ) -> seq[byte]: ## Returns code at a given address. @@ -436,7 +353,7 @@ proc installEthApiHandlers*( raise newException(ValueError, "Unable to get code") return bytecode.asSeq() - rpcServerWithProxy.rpc("eth_getProof") do( + rpcServer.rpc("eth_getProof") do( data: web3Types.Address, slots: seq[UInt256], quantityTag: RtBlockIdentifier ) -> ProofResponse: ## Returns information about an account and storage slots along with account @@ -483,7 +400,7 @@ proc installEthApiHandlers*( # TODO: Should we move these debug methods into a separate debug rpcServer? - rpcServerWithProxy.rpc("debug_getBalanceByStateRoot") do( + rpcServer.rpc("debug_getBalanceByStateRoot") do( data: web3Types.Address, stateRoot: web3types.Hash256 ) -> UInt256: ## Returns the balance of the account of given address. @@ -504,7 +421,7 @@ proc installEthApiHandlers*( return balance - rpcServerWithProxy.rpc("debug_getTransactionCountByStateRoot") do( + rpcServer.rpc("debug_getTransactionCountByStateRoot") do( data: web3Types.Address, stateRoot: web3types.Hash256 ) -> Quantity: ## Returns the number of transactions sent from an address. @@ -524,7 +441,7 @@ proc installEthApiHandlers*( raise newException(ValueError, "Unable to get transaction count") return nonce.Quantity - rpcServerWithProxy.rpc("debug_getStorageAtByStateRoot") do( + rpcServer.rpc("debug_getStorageAtByStateRoot") do( data: web3Types.Address, slot: UInt256, stateRoot: web3types.Hash256 ) -> FixedBytes[32]: ## Returns the value from a storage position at a given address. @@ -545,7 +462,7 @@ proc installEthApiHandlers*( raise newException(ValueError, "Unable to get storage slot") return FixedBytes[32](slotValue.toBytesBE()) - rpcServerWithProxy.rpc("debug_getCodeByStateRoot") do( + rpcServer.rpc("debug_getCodeByStateRoot") do( data: web3Types.Address, stateRoot: web3types.Hash256 ) -> seq[byte]: ## Returns code at a given address. @@ -566,7 +483,7 @@ proc installEthApiHandlers*( return bytecode.asSeq() - rpcServerWithProxy.rpc("debug_getProofByStateRoot") do( + rpcServer.rpc("debug_getProofByStateRoot") do( data: web3Types.Address, slots: seq[UInt256], stateRoot: web3types.Hash256 ) -> ProofResponse: ## Returns information about an account and storage slots along with account diff --git a/fluffy/rpc/rpc_portal_api.nim b/fluffy/rpc/rpc_portal_api.nim index aa69cd474..923da9075 100644 --- a/fluffy/rpc/rpc_portal_api.nim +++ b/fluffy/rpc/rpc_portal_api.nim @@ -9,7 +9,7 @@ import std/[sequtils, json], - json_rpc/[rpcproxy, rpcserver], + json_rpc/rpcserver, json_serialization/std/tables, stew/byteutils, ../network/wire/portal_protocol, @@ -41,7 +41,7 @@ TraceResponse.useDefaultSerializationIn JrpcConv # as the proc becomes generic, where the rpc macro from router.nim can no longer # be found, which is why we export rpcserver which should export router. proc installPortalApiHandlers*( - rpcServer: RpcServer | RpcProxy, p: PortalProtocol, network: static string + rpcServer: RpcServer, p: PortalProtocol, network: static string ) = let invalidKeyErr = diff --git a/fluffy/rpc/rpc_portal_debug_api.nim b/fluffy/rpc/rpc_portal_debug_api.nim index c6c06b703..0b37e31af 100644 --- a/fluffy/rpc/rpc_portal_debug_api.nim +++ b/fluffy/rpc/rpc_portal_debug_api.nim @@ -8,7 +8,7 @@ {.push raises: [].} import - json_rpc/[rpcproxy, rpcserver], + json_rpc/rpcserver, stew/byteutils, ../network/wire/portal_protocol, ../eth_data/history_data_seeding, @@ -19,7 +19,7 @@ export rpcserver # Non-spec-RPCs that are used for testing, debugging and seeding data without a # bridge. proc installPortalDebugApiHandlers*( - rpcServer: RpcServer | RpcProxy, p: PortalProtocol, network: static string + rpcServer: RpcServer, p: PortalProtocol, network: static string ) = ## Portal debug API calls related to storage and seeding from Era1 files. rpcServer.rpc("portal_" & network & "GossipHeaders") do( diff --git a/fluffy/rpc/rpc_web3_api.nim b/fluffy/rpc/rpc_web3_api.nim index 9176620eb..375291b33 100644 --- a/fluffy/rpc/rpc_web3_api.nim +++ b/fluffy/rpc/rpc_web3_api.nim @@ -7,10 +7,10 @@ {.push raises: [].} -import json_rpc/[rpcproxy, rpcserver], ../version +import json_rpc/rpcserver, ../version export rpcserver -proc installWeb3ApiHandlers*(rpcServer: RpcServer | RpcProxy) = +proc installWeb3ApiHandlers*(rpcServer: RpcServer) = rpcServer.rpc("web3_clientVersion") do() -> string: return clientVersion diff --git a/fluffy/tests/test_discovery_rpc.nim b/fluffy/tests/test_discovery_rpc.nim index 945fc96e6..5bcba8d94 100644 --- a/fluffy/tests/test_discovery_rpc.nim +++ b/fluffy/tests/test_discovery_rpc.nim @@ -10,7 +10,7 @@ import chronos, testutils/unittests, - json_rpc/[rpcproxy, rpcserver], + json_rpc/rpcserver, json_rpc/clients/httpclient, stint, eth/p2p/discoveryv5/enr, @@ -21,7 +21,7 @@ import type TestCase = ref object localDiscovery: discv5_protocol.Protocol - server: RpcProxy + server: RpcHttpServer client: RpcHttpClient proc setupTest(rng: ref HmacDrbgContext): Future[TestCase] {.async.} = @@ -31,20 +31,17 @@ proc setupTest(rng: ref HmacDrbgContext): Future[TestCase] {.async.} = ta = initTAddress(localSrvAddress, localSrvPort) localDiscoveryNode = initDiscoveryNode(rng, PrivateKey.random(rng[]), localAddress(20302)) - fakeProxyConfig = getHttpClientConfig("http://127.0.0.1:8546") client = newRpcHttpClient() - var rpcHttpServerWithProxy = RpcProxy.new([ta], fakeProxyConfig) + let rpcHttpServer = RpcHttpServer.new() + rpcHttpServer.addHttpServer(ta, maxRequestBodySize = 4 * 1_048_576) - rpcHttpServerWithProxy.installDiscoveryApiHandlers(localDiscoveryNode) + rpcHttpServer.installDiscoveryApiHandlers(localDiscoveryNode) - await rpcHttpServerWithProxy.start() - await client.connect( - localSrvAddress, rpcHttpServerWithProxy.localAddress[0].port, false - ) - return TestCase( - localDiscovery: localDiscoveryNode, server: rpcHttpServerWithProxy, client: client - ) + rpcHttpServer.start() + await client.connect(localSrvAddress, rpcHttpServer.localAddress[0].port, false) + return + TestCase(localDiscovery: localDiscoveryNode, server: rpcHttpServer, client: client) proc stop(testCase: TestCase) {.async.} = await testCase.server.stop()