Skip to content

Commit

Permalink
Merge JoinMarket-Org#1150: Add freeze method to RPC-API
Browse files Browse the repository at this point in the history
29b459a Add freeze method to RPC-API (Adam Gibson)
  • Loading branch information
AdamISZ committed Jan 18, 2022
2 parents 3266015 + 29b459a commit 7a98c3e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 9 deletions.
43 changes: 43 additions & 0 deletions jmclient/jmclient/wallet-rpc-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,31 @@ paths:
$ref: "#/components/responses/401-Unauthorized"
'409':
$ref: '#/components/responses/409-NoConfig'
/wallet/{walletname}/freeze:
post:
security:
- bearerAuth: []
summary: freeze or unfreeze an individual utxo for spending
operationId: freeze
description: freeze or unfreeze an individual utxo for spending
parameters:
- name: walletname
in: path
description: name of wallet including .jmdat
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/FreezeRequest'
description: utxo string and freeze toggle as boolean
responses:
'200':
$ref: "#/components/responses/Freeze-200-OK"
'400':
$ref: '#/components/responses/400-BadRequest'
/wallet/{walletname}/getseed:
get:
security:
Expand Down Expand Up @@ -432,6 +457,16 @@ components:
scheme: bearer
bearerFormat: JWT
schemas:
FreezeRequest:
type: object
required:
- utxo-string
- freeze
properties:
utxo-string:
type: string
freeze:
type: boolean
ConfigSetRequest:
type: object
required:
Expand Down Expand Up @@ -464,6 +499,8 @@ components:
type: string
ConfigSetResponse:
type: object
FreezeResponse:
type: object
DoCoinjoinRequest:
type: object
required:
Expand Down Expand Up @@ -830,6 +867,12 @@ components:
application/json:
schema:
$ref: "#/components/schemas/GetSeedResponse"
Freeze-200-OK:
description: "freeze or unfreeze utxo action completed successfully"
content:
application/json:
schema:
$ref: "#/components/schemas/FreezeResponse"
202-Accepted:
description: The request has been submitted successfully for processing, but the processing has not been completed.
204-NoResultFound:
Expand Down
31 changes: 30 additions & 1 deletion jmclient/jmclient/wallet_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
StorageError, StoragePasswordError, JmwalletdWebSocketServerFactory, \
JmwalletdWebSocketServerProtocol, RetryableStorageError, \
SegwitWalletFidelityBonds, wallet_gettimelockaddress
from jmbase.support import get_log
from jmbase.support import get_log, utxostr_to_utxo

jlog = get_log()

Expand Down Expand Up @@ -786,6 +786,35 @@ def configset(self, request, walletname):
# null return indicates success in updating:
return make_jmwalletd_response(request)

@app.route('/wallet/<string:walletname>/freeze', methods=["POST"])
def freeze(self, request, walletname):
""" Freeze (true) or unfreeze (false), for spending a specified utxo
in this wallet. Note that this is persisted in the wallet file,
so the status survives across sessions. Note that re-application of
the same state is allowed and does not alter the 200 OK return.
"""
self.check_cookie(request)
if not self.wallet_name == walletname:
raise InvalidRequestFormat()
freeze_json = self.get_POST_body(request, ["utxo-string", "freeze"])
if not freeze_json:
raise InvalidRequestFormat()
to_disable = freeze_json["freeze"]
valid, txidindex = utxostr_to_utxo(freeze_json["utxo-string"])
if not valid:
raise InvalidRequestFormat()
txid, index = txidindex
try:
# note: this does not raise or fail if the applied
# disable state (true/false) is the same as the current
# one; that is accepted and not an error.
self.wallet_service.disable_utxo(txid, index, to_disable)
except AssertionError:
# should be impossible because format checked by
# utxostr_to_utxo:
raise InvalidRequestFormat()
return make_jmwalletd_response(request)

def get_listutxos_response(self, utxos):
res = []
for k, v in utxos.items():
Expand Down
35 changes: 27 additions & 8 deletions jmclient/test/test_wallet_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,16 +381,31 @@ def process_new_addr_response(self, response, code):
assert validate_address(json_body["address"])[0]

@defer.inlineCallbacks
def test_listutxos(self):
def test_listutxos_and_freeze(self):
self.daemon.auth_disabled = True
agent = get_nontor_agent()
addr = self.get_route_root()
addr += "/wallet/"
addr += self.daemon.wallet_name
addr += "/utxos"
pre_addr = self.get_route_root()
pre_addr += "/wallet/"
pre_addr += self.daemon.wallet_name
addr = pre_addr + "/utxos"
addr = addr.encode()
yield self.do_request(agent, b"GET", addr, None,
self.process_listutxos_response)
# Test of freezing is currently very primitive: we only
# check that the action was accepted; a full test would
# involve checking that spending the coin works or doesn't
# work, as expected.
addr = pre_addr + "/freeze"
addr = addr.encode()
utxostr = self.mixdepth1_utxos[0]["utxo"]
body = BytesProducer(json.dumps({"utxo-string": utxostr,
"freeze": True}).encode())
yield self.do_request(agent, b"POST", addr, body,
self.process_utxo_freeze)
body = BytesProducer(json.dumps({"utxo-string": utxostr,
"freeze": False}).encode())
yield self.do_request(agent, b"POST", addr, body,
self.process_utxo_freeze)

def process_listutxos_response(self, response, code):
assert code == 200
Expand All @@ -399,11 +414,15 @@ def process_listutxos_response(self, response, code):
# have depend on what other tests occurred.
# For now, we at least check that we have 3 utxos in mixdepth
# 1 because none of the other tests spend them:
mixdepth1_utxos = 0
mixdepth1_utxos = []
for d in json_body["utxos"]:
if d["mixdepth"] == 1:
mixdepth1_utxos += 1
assert mixdepth1_utxos == 3
mixdepth1_utxos.append(d)
assert len(mixdepth1_utxos) == 3
self.mixdepth1_utxos = mixdepth1_utxos

def process_utxo_freeze(self, response, code):
assert code == 200

@defer.inlineCallbacks
def test_session(self):
Expand Down

0 comments on commit 7a98c3e

Please sign in to comment.