From c9f6ac861033f06ef048d10b46463e15bf2c7480 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Fri, 11 Aug 2023 08:33:58 -0600 Subject: [PATCH] RPC-API: add getinfo endpoint. This commit creates a new endpoint /getinfo which currently returns only the version of Joinmarket (JM_CORE_VERSION) running in the backend joinmarketd. In future commits the returned dict may add more information, for example the current block height of the connected Bitcoin Core node. Additionally, this commit fixes the response type of the /rescanblockchain endpoint as defined in the OpenAPI spec. --- docs/api/wallet-rpc.yaml | 34 +++++++++++++++++++++++++++++++- jmclient/jmclient/wallet_rpc.py | 15 +++++++++++++- jmclient/test/test_wallet_rpc.py | 16 ++++++++++++++- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/docs/api/wallet-rpc.yaml b/docs/api/wallet-rpc.yaml index e3f9a2c..1e13ed9 100644 --- a/docs/api/wallet-rpc.yaml +++ b/docs/api/wallet-rpc.yaml @@ -138,6 +138,16 @@ paths: $ref: '#/components/responses/401-Unauthorized' '404': $ref: '#/components/responses/404-NotFound' + /getinfo: + get: + security: + - {} + summary: get info on backend + operationId: version + description: get information about backend, including the version of Joinmarket running. + responses: + '200': + $ref: "#/components/responses/Getinfo-200-OK" /wallet/all: get: summary: get current available wallets @@ -754,6 +764,22 @@ components: items: type: string example: "2021/10/26 16:40:21,133986791,1,200000000,2680,2680,0.08," + GetinfoResponse: + type: object + required: + - version + properties: + version: + type: string + example: "0.9.10" + RescanBlockchainResponse: + type: object + required: + - walletname + properties: + walletname: + type: string + example: "wallet.jmdat" SessionResponse: type: object required: @@ -1106,12 +1132,18 @@ components: application/json: schema: $ref: "#/components/schemas/SessionResponse" + Getinfo-200-OK: + description: "successful Joinmarket getinfo response" + content: + application/json: + schema: + $ref: "#/components/schemas/GetinfoResponse" RescanBlockchain-200-OK: description: "Blockchain rescan started successfully" content: application/json: schema: - $ref: "#/components/schemas/SessionResponse" + $ref: "#/components/schemas/RescanBlockchainResponse" Create-201-OK: description: "wallet created successfully" content: diff --git a/jmclient/jmclient/wallet_rpc.py b/jmclient/jmclient/wallet_rpc.py index 15abc12..a6c7efd 100644 --- a/jmclient/jmclient/wallet_rpc.py +++ b/jmclient/jmclient/wallet_rpc.py @@ -27,7 +27,7 @@ from jmclient import Taker, jm_single, \ tumbler_filter_orders_callback, tumbler_taker_finished_update, \ validate_address, FidelityBondMixin, BaseWallet, WalletError, \ ScheduleGenerationErrorNoFunds, BIP39WalletMixin -from jmbase.support import get_log, utxostr_to_utxo +from jmbase.support import get_log, utxostr_to_utxo, JM_CORE_VERSION jlog = get_log() @@ -602,6 +602,10 @@ class JMWalletDaemon(Service): Note that it technically "shouldn't" require a wallet to be loaded, but since we hide all blockchain access behind the wallet service, it currently *does* require this. + An additional subtlety to bear in mind: the action of rescanblockchain + depends on the *currently loaded Bitcoin Core wallet*, that Core wallet + load event is currently done on startup of Joinmarket, depending on + the setting in the joinmarket.cfg file. """ print_req(request) self.check_cookie(request) @@ -615,6 +619,15 @@ class JMWalletDaemon(Service): self.services["wallet"].rescanblockchain(blockheight) return make_jmwalletd_response(request, walletname=walletname) + @app.route('/getinfo', methods=['GET']) + def version(self, request): + """ This route sends information about the backend, including + the running version of Joinmarket, + back to the client. It does *not* pay attention to any state, + including authentication tokens. + """ + return make_jmwalletd_response(request,version=JM_CORE_VERSION) + @app.route('/session', methods=['GET']) def session(self, request): """ This route functions as a heartbeat, and communicates diff --git a/jmclient/test/test_wallet_rpc.py b/jmclient/test/test_wallet_rpc.py index b14f746..63b697e 100644 --- a/jmclient/test/test_wallet_rpc.py +++ b/jmclient/test/test_wallet_rpc.py @@ -10,7 +10,7 @@ from autobahn.twisted.websocket import WebSocketClientFactory, \ connectWS from jmbase import get_nontor_agent, hextobin, BytesProducer, get_log -from jmbase.support import get_free_tcp_ports +from jmbase.support import get_free_tcp_ports, JM_CORE_VERSION from jmbitcoin import CTransaction from jmclient import ( load_test_config, @@ -685,6 +685,20 @@ class TrialTestWRPC_DisplayWallet(WalletRPCTestBase, unittest.TestCase): yield self.do_request(agent, b"POST", addr, body, self.process_do_coinjoin_response) + @defer.inlineCallbacks + def test_getinfo(self): + agent = get_nontor_agent() + addr = self.get_route_root() + addr += "/getinfo" + addr = addr.encode() + yield self.do_request(agent, b"GET", addr, None, + self.process_getinfo_response) + + def process_getinfo_response(self, response, code): + assert code==200 + responseobj = json.loads(response.decode("utf-8")) + assert responseobj["version"] == JM_CORE_VERSION + def process_do_coinjoin_response(self, response, code): assert code == 202 # response code is already checked to be 200