mirror of
https://git.wownero.com/lza_menace/wownero-python.git
synced 2024-08-15 03:25:25 +00:00
Add retrieval of transaction from daemon
This commit is contained in:
parent
df9dd7152b
commit
44d87be2e6
6 changed files with 208 additions and 0 deletions
|
@ -71,6 +71,22 @@ class JSONRPCDaemon(object):
|
|||
return res['headers']
|
||||
raise exceptions.BackendException(res['status'])
|
||||
|
||||
def transactions(self, hashes):
|
||||
res = self.raw_request('/get_transactions', {
|
||||
'txs_hashes': hashes,
|
||||
'decode_as_json': True})
|
||||
if res['status'] != 'OK':
|
||||
raise exceptions.BackendException(res['status'])
|
||||
txs = []
|
||||
for tx in res.get('txs', []):
|
||||
txs.append(Transaction(
|
||||
hash=tx['tx_hash'],
|
||||
height=None if tx['in_pool'] else tx['block_height'],
|
||||
timestamp=datetime.fromtimestamp(tx['block_timestamp']) if 'block_timestamp' in tx else None,
|
||||
blob=tx['as_hex'],
|
||||
json=json.loads(tx['as_json'])))
|
||||
return txs
|
||||
|
||||
def raw_request(self, path, data):
|
||||
hdr = {'Content-Type': 'application/json'}
|
||||
_log.debug(u"Request: {path}\nData: {data}".format(
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import six
|
||||
|
||||
class Daemon(object):
|
||||
"""Monero daemon.
|
||||
|
||||
|
@ -51,3 +53,13 @@ class Daemon(object):
|
|||
:rtype: list of dict
|
||||
"""
|
||||
return self._backend.headers(start_height, end_height)
|
||||
|
||||
def transactions(self, hashes):
|
||||
"""
|
||||
Returns transactions matching given hashes. Accepts single hash or a sequence.
|
||||
|
||||
:hashes: str or list of str
|
||||
"""
|
||||
if isinstance(hashes, six.string_types):
|
||||
hashes = [hashes]
|
||||
return self._backend.transactions(hashes)
|
||||
|
|
|
@ -72,8 +72,13 @@ class Transaction(object):
|
|||
timestamp = None
|
||||
key = None
|
||||
blob = None
|
||||
json = None
|
||||
confirmations = None
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
return len(self.blob)//2
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.hash = kwargs.get('hash', self.hash)
|
||||
self.fee = kwargs.get('fee', self.fee)
|
||||
|
@ -81,6 +86,7 @@ class Transaction(object):
|
|||
self.timestamp = kwargs.get('timestamp', self.timestamp)
|
||||
self.key = kwargs.get('key', self.key)
|
||||
self.blob = kwargs.get('blob', self.blob)
|
||||
self.json = kwargs.get('json', self.json)
|
||||
self.confirmations = kwargs.get('confirmations', self.confirmations)
|
||||
|
||||
def __repr__(self):
|
||||
|
|
82
tests/data/test_jsonrpcdaemon/test_transactions.json
Normal file
82
tests/data/test_jsonrpcdaemon/test_transactions.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -10,6 +10,7 @@ from .base import JSONTestCase
|
|||
class JSONRPCDaemonTestCase(JSONTestCase):
|
||||
jsonrpc_url = 'http://127.0.0.1:18081/json_rpc'
|
||||
mempool_url = 'http://127.0.0.1:18081/get_transaction_pool'
|
||||
transactions_url = 'http://127.0.0.1:18081/get_transactions'
|
||||
data_subdir = 'test_jsonrpcdaemon'
|
||||
|
||||
def setUp(self):
|
||||
|
@ -37,3 +38,33 @@ class JSONRPCDaemonTestCase(JSONTestCase):
|
|||
self.assertEqual(txs[1].confirmations, 0)
|
||||
self.assertGreater(txs[0].fee, 0)
|
||||
self.assertGreater(txs[1].fee, 0)
|
||||
|
||||
@responses.activate
|
||||
def test_transactions(self):
|
||||
responses.add(responses.POST, self.transactions_url,
|
||||
json=self._read('test_transactions.json'),
|
||||
status=200)
|
||||
txs = self.daemon.transactions([
|
||||
"050679bd5717cd4c3d0ed1db7dac4aa7e8a222ffc7661b249e5a595a3af37d3c", # @471570
|
||||
"e3a3b8361777c8f4f1fd423b86655b5c775de0230b44aa5b82f506135a96c53a", # @451993
|
||||
"e2871c4203e29433257219bc20fa58c68dc12efed8f05a86d59921969a2b97cc", # @472279
|
||||
"035a1cfadd2f80124998f5af8c7bb6703743a4f322d0a20b7f7b502956ada59d", # mempool
|
||||
"feed00000000000face00000000000bad00000000000beef00000000000acab0", # doesn't exist
|
||||
])
|
||||
self.assertEqual(len(txs), 4)
|
||||
self.assertEqual(txs[0].hash,
|
||||
"050679bd5717cd4c3d0ed1db7dac4aa7e8a222ffc7661b249e5a595a3af37d3c")
|
||||
self.assertEqual(txs[0].height, 471570)
|
||||
self.assertEqual(txs[0].size, 2826)
|
||||
self.assertEqual(txs[1].hash,
|
||||
"e3a3b8361777c8f4f1fd423b86655b5c775de0230b44aa5b82f506135a96c53a")
|
||||
self.assertEqual(txs[1].height, 451993)
|
||||
self.assertEqual(txs[1].size, 2596)
|
||||
self.assertEqual(txs[2].hash,
|
||||
"e2871c4203e29433257219bc20fa58c68dc12efed8f05a86d59921969a2b97cc")
|
||||
self.assertEqual(txs[2].height, 472279)
|
||||
self.assertEqual(txs[2].size, 2796)
|
||||
self.assertEqual(txs[3].hash,
|
||||
"035a1cfadd2f80124998f5af8c7bb6703743a4f322d0a20b7f7b502956ada59d")
|
||||
self.assertIsNone(txs[3].height)
|
||||
self.assertEqual(txs[3].size, 2724)
|
||||
|
|
61
utils/dumptx.py
Executable file
61
utils/dumptx.py
Executable file
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/python
|
||||
import argparse
|
||||
import json
|
||||
import logging
|
||||
import operator
|
||||
import re
|
||||
import sys
|
||||
|
||||
from monero.backends.jsonrpc import JSONRPCDaemon
|
||||
from monero.daemon import Daemon
|
||||
|
||||
|
||||
def url_data(url):
|
||||
gs = re.compile(r"^(?P<host>[^:\s]+)(?::(?P<port>[0-9]+))?$").match(url).groupdict()
|
||||
return dict(filter(operator.itemgetter(1), gs.items()))
|
||||
|
||||
|
||||
argsparser = argparse.ArgumentParser(
|
||||
description="Retrieve transaction(s) from daemon and print them"
|
||||
)
|
||||
argsparser.add_argument("tx_id", nargs="+", type=str, help="Transaction id (hash)")
|
||||
argsparser.add_argument(
|
||||
"-d",
|
||||
dest="daemon_rpc_url",
|
||||
type=url_data,
|
||||
default="127.0.0.1:18081",
|
||||
help="Daemon RPC URL [host[:port]]",
|
||||
)
|
||||
argsparser.add_argument(
|
||||
"-t", dest="timeout", type=int, default=30, help="Request timeout"
|
||||
)
|
||||
argsparser.add_argument(
|
||||
"-v",
|
||||
dest="verbosity",
|
||||
action="count",
|
||||
default=0,
|
||||
help="Verbosity (repeat to increase; -v for INFO, -vv for DEBUG",
|
||||
)
|
||||
args = argsparser.parse_args()
|
||||
level = logging.WARNING
|
||||
if args.verbosity == 1:
|
||||
level = logging.INFO
|
||||
elif args.verbosity > 1:
|
||||
level = logging.DEBUG
|
||||
logging.basicConfig(level=level, format="%(asctime)-15s %(message)s")
|
||||
|
||||
d = Daemon(JSONRPCDaemon(timeout=args.timeout, **args.daemon_rpc_url))
|
||||
|
||||
txs = list(d.transactions(args.tx_id))
|
||||
print("Found {:d} transaction(s)".format(len(txs)))
|
||||
if len(txs) > 0:
|
||||
print("-" * 79)
|
||||
for tx in txs:
|
||||
print("id: {:s}".format(tx.hash))
|
||||
print(
|
||||
"height: {:s}".format("None" if tx.height is None else "{:d}".format(tx.height))
|
||||
)
|
||||
print("size: {:d}".format(tx.size))
|
||||
print("JSON:")
|
||||
print(json.dumps(tx.json, indent=2))
|
||||
print("-" * 79)
|
Loading…
Reference in a new issue