Browse Source

Merge #1295: Default 3rd argument of gettxout should be True

a3e1ba3 Default 3rd argument of gettxout should be True (Adam Gibson)
master
Adam Gibson 4 years ago
parent
commit
babad19639
No known key found for this signature in database
GPG Key ID: 141001A1AF77F20B
  1. 20
      jmclient/jmclient/blockchaininterface.py
  2. 2
      jmclient/jmclient/maker.py
  3. 9
      jmclient/jmclient/taker.py
  4. 2
      jmclient/jmclient/wallet.py
  5. 8
      jmclient/test/commontest.py
  6. 4
      jmclient/test/test_wallets.py

20
jmclient/jmclient/blockchaininterface.py

@ -39,7 +39,7 @@ class BlockchainInterface(object):
"""pushes tx to the network, returns False if failed"""
@abc.abstractmethod
def query_utxo_set(self, txouts, includeconf=False):
def query_utxo_set(self, txouts, includeconfs=False):
"""
takes a utxo or a list of utxos
returns None if they are spend or unconfirmed
@ -109,7 +109,7 @@ class ElectrumWalletInterface(BlockchainInterface): #pragma: no cover
log.debug("Pushed via Electrum successfully, hash: " + tx_hash)
return True
def query_utxo_set(self, txout, includeconf=False):
def query_utxo_set(self, txout, includeconfs=False):
"""Behaves as for Core; TODO make it faster if possible.
Note in particular a failed connection should result in
a result list containing at least one "None" which the
@ -141,7 +141,7 @@ class ElectrumWalletInterface(BlockchainInterface): #pragma: no cover
'address': address,
'script': btc.address_to_script(address)
}
if includeconf:
if includeconfs:
if int(u['height']) in [0, -1]:
#-1 means unconfirmed inputs
r['confirms'] = 0
@ -389,15 +389,17 @@ class BitcoinCoreInterface(BlockchainInterface):
return False
return True
def query_utxo_set(self, txout, includeconf=False, includeunconf=False):
def query_utxo_set(self, txout, includeconfs=False, include_mempool=True):
"""If txout is either (a) a single utxo in (txidbin, n) form,
or a list of the same, returns, as a list for each txout item,
the result of gettxout from the bitcoind rpc for those utxos;
if any utxo is invalid, None is returned.
includeconf: if this is True, the current number of confirmations
includeconfs: if this is True, the current number of confirmations
of the prescribed utxo is included in the returned result dict.
includeunconf: if True, utxos which currently have zero confirmations
are included in the result set.
include_mempool: if True, the contents of the mempool are included;
this *both* means that utxos that are spent in in-mempool transactions
are *not* returned, *and* means that utxos that are created in the
mempool but have zero confirmations *are* returned.
If the utxo is of a non-standard type such that there is no address,
the address field in the dict is None.
"""
@ -416,14 +418,14 @@ class BitcoinCoreInterface(BlockchainInterface):
log.warn("Invalid utxo format, ignoring: {}".format(txo))
result.append(None)
continue
ret = self._rpc('gettxout', [txo_hex, txo_idx, includeunconf])
ret = self._rpc('gettxout', [txo_hex, txo_idx, include_mempool])
if ret is None:
result.append(None)
else:
result_dict = {'value': int(Decimal(str(ret['value'])) *
Decimal('1e8')),
'script': hextobin(ret['scriptPubKey']['hex'])}
if includeconf:
if includeconfs:
result_dict['confirms'] = int(ret['confirmations'])
result.append(result_dict)
return result

2
jmclient/jmclient/maker.py

@ -82,7 +82,7 @@ class Maker(object):
#finally, check that the proffered utxo is real, old enough, large enough,
#and corresponds to the pubkey
res = jm_single().bc_interface.query_utxo_set([cr_dict['utxo']],
includeconf=True)
includeconfs=True)
if len(res) != 1 or not res[0]:
reason = "authorizing utxo is not valid"
return reject(reason)

9
jmclient/jmclient/taker.py

@ -558,7 +558,8 @@ class Taker(object):
return verified_data
def _verify_ioauth_inputs(self, nick, utxo_list, auth_pub):
utxo_data = jm_single().bc_interface.query_utxo_set(utxo_list)
utxo_data = jm_single().bc_interface.query_utxo_set(utxo_list,
includeconfs=True)
if None in utxo_data:
raise IoauthInputVerificationError([
"ERROR: outputs unconfirmed or already spent. utxo_data="
@ -570,6 +571,10 @@ class Taker(object):
# Construct the Bitcoin address for the auth_pub field
# Ensure that at least one address from utxos corresponds.
for inp in utxo_data:
if inp["confirms"] <= 0:
raise IoauthInputVerificationError([
f"maker's ({nick}) proposed utxo is not confirmed, "
"rejecting."])
try:
if self.wallet_service.pubkey_has_script(
auth_pub, inp['script']):
@ -756,7 +761,7 @@ class Taker(object):
def filter_by_coin_age_amt(utxos, age, amt):
results = jm_single().bc_interface.query_utxo_set(utxos,
includeconf=True)
includeconfs=True)
newresults = []
too_new = []
too_small = []

2
jmclient/jmclient/wallet.py

@ -2564,7 +2564,7 @@ class FidelityBondMixin(object):
def get_validated_timelocked_fidelity_bond_utxo(cls, utxo, utxo_pubkey, locktime,
cert_expiry, current_block_height):
utxo_data = jm_single().bc_interface.query_utxo_set(utxo, includeconf=True)
utxo_data = jm_single().bc_interface.query_utxo_set(utxo, includeconfs=True)
if utxo_data[0] == None:
return None
if utxo_data[0]["confirms"] <= 0:

8
jmclient/test/commontest.py

@ -72,7 +72,7 @@ class DummyBlockchainInterface(BlockchainInterface):
def reset_confs(self):
self.confs_for_qus = {}
def query_utxo_set(self, txouts, includeconf=False):
def query_utxo_set(self, txouts, includeconfs=False):
if self.qusfail:
#simulate failure to find the utxo
return [None]
@ -97,8 +97,8 @@ class DummyBlockchainInterface(BlockchainInterface):
'fd9711a2ef340750db21efb761f5f7d665d94b312332dc354e252c77e9c48349:0': [50000000, 6]}
wallet_outs = dictchanger(wallet_outs)
if includeconf and set(txouts).issubset(set(wallet_outs)):
#includeconf used as a trigger for a podle check;
if includeconfs and set(txouts).issubset(set(wallet_outs)):
#includeconfs used as a trigger for a podle check;
#here we simulate a variety of amount/age returns
results = []
for to in txouts:
@ -116,7 +116,7 @@ class DummyBlockchainInterface(BlockchainInterface):
result_dict = {'value': 200000000,
'address': "mrcNu71ztWjAQA6ww9kHiW3zBWSQidHXTQ",
'script': hextobin('76a91479b000887626b294a914501a4cd226b58b23598388ac')}
if includeconf:
if includeconfs:
if t in self.confs_for_qus:
confs = self.confs_for_qus[t]
else:

4
jmclient/test/test_wallets.py

@ -44,10 +44,10 @@ def test_query_utxo_set(setup_wallets):
txid2 = do_tx(wallet_service, 20000000)
print("Got txs: ", txid, txid2)
res1 = jm_single().bc_interface.query_utxo_set(
(txid, 0), includeunconf=True)
(txid, 0), include_mempool=True)
res2 = jm_single().bc_interface.query_utxo_set(
[(txid, 0), (txid2, 1)],
includeconf=True, includeunconf=True)
includeconfs=True, include_mempool=True)
assert len(res1) == 1
assert len(res2) == 2
assert all([x in res1[0] for x in ['script', 'value']])

Loading…
Cancel
Save