Enable verbose mode in blockchain.transaction.get (#397)
getrawtransaction: optional verbose mode Update PROTOCOL.rst docs
This commit is contained in:
parent
824dc76d95
commit
cf49b737d3
@ -19,6 +19,7 @@ install:
|
|||||||
- pip install pyrocksdb
|
- pip install pyrocksdb
|
||||||
- pip install tribus-hash
|
- pip install tribus-hash
|
||||||
- pip install pytest-cov
|
- pip install pytest-cov
|
||||||
|
- pip install pylru
|
||||||
# command to run tests
|
# command to run tests
|
||||||
script: pytest --cov=server --cov=lib --cov=wallet
|
script: pytest --cov=server --cov=lib --cov=wallet
|
||||||
# Dont report coverage from nightly
|
# Dont report coverage from nightly
|
||||||
|
|||||||
@ -930,11 +930,11 @@ Protocol Version 1.2
|
|||||||
Protocol version 1.2 introduces new methods `blockchain.block.headers`,
|
Protocol version 1.2 introduces new methods `blockchain.block.headers`,
|
||||||
`mempool.get_fee_histogram`.
|
`mempool.get_fee_histogram`.
|
||||||
|
|
||||||
`blockchain.block.get_chunk` and all methods beginning
|
* `blockchain.block.get_chunk` and all methods beginning `blockchain.address.` are deprecated
|
||||||
`blockchain.address.` are deprecated and support will be removed in
|
and support will be removed in some future protocol version. You should update your code to use `blockchain.block.headers`
|
||||||
some future protocol version. You should update your code to use
|
and `Script Hashes`_ with the scripthash methods introduced in protocol 1.1 instead.
|
||||||
`blockchain.block.headers` and `Script Hashes`_ with the scripthash
|
|
||||||
methods introduced in protocol 1.1 instead.
|
* `blockchain.transaction.get` now has an optional parameter *verbose*.
|
||||||
|
|
||||||
blockchain.block.headers
|
blockchain.block.headers
|
||||||
========================
|
========================
|
||||||
@ -978,7 +978,7 @@ Return concatenated block headers as hexadecimal from the main chain.
|
|||||||
|
|
||||||
{
|
{
|
||||||
"count": 2,
|
"count": 2,
|
||||||
"hex": "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1cdb606e857233e0e61bc6649ffff001d01e36299'"
|
"hex": "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1cdb606e857233e0e61bc6649ffff001d01e36299"
|
||||||
"max": 2016
|
"max": 2016
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1003,3 +1003,25 @@ intervals is currently not part of the protocol.
|
|||||||
|
|
||||||
.. _JSON RPC 1.0: http://json-rpc.org/wiki/specification
|
.. _JSON RPC 1.0: http://json-rpc.org/wiki/specification
|
||||||
.. _JSON RPC 2.0: http://json-rpc.org/specification
|
.. _JSON RPC 2.0: http://json-rpc.org/specification
|
||||||
|
|
||||||
|
|
||||||
|
blockchain.transaction.get
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Return a raw transaction.
|
||||||
|
|
||||||
|
blockchain.transaction.get(**tx_hash**, **verbose**=False)
|
||||||
|
|
||||||
|
**tx_hash**
|
||||||
|
|
||||||
|
The transaction hash as a hexadecimal string.
|
||||||
|
|
||||||
|
**verbose**
|
||||||
|
Verbose mode, passed on to bitcoind in **getrawtransaction**.
|
||||||
|
|
||||||
|
**Response**
|
||||||
|
|
||||||
|
In non-verbose mode return the raw transaction as a hexadecimal string.
|
||||||
|
|
||||||
|
If verbose, returns what your coin's bitcoind returns; see its
|
||||||
|
documentation for details.
|
||||||
|
|||||||
@ -842,13 +842,14 @@ class Controller(ServerBase):
|
|||||||
to the daemon's memory pool.'''
|
to the daemon's memory pool.'''
|
||||||
return await self.daemon_request('relayfee')
|
return await self.daemon_request('relayfee')
|
||||||
|
|
||||||
async def transaction_get(self, tx_hash):
|
async def transaction_get(self, tx_hash, verbose=False):
|
||||||
'''Return the serialized raw transaction given its hash
|
'''Return the serialized raw transaction given its hash
|
||||||
|
|
||||||
tx_hash: the transaction hash as a hexadecimal string
|
tx_hash: the transaction hash as a hexadecimal string
|
||||||
|
verbose: passed on to the daemon
|
||||||
'''
|
'''
|
||||||
self.assert_tx_hash(tx_hash)
|
self.assert_tx_hash(tx_hash)
|
||||||
return await self.daemon_request('getrawtransaction', tx_hash)
|
return await self.daemon_request('getrawtransaction', tx_hash, verbose)
|
||||||
|
|
||||||
async def transaction_get_1_0(self, tx_hash, height=None):
|
async def transaction_get_1_0(self, tx_hash, height=None):
|
||||||
'''Return the serialized raw transaction given its hash
|
'''Return the serialized raw transaction given its hash
|
||||||
|
|||||||
@ -262,9 +262,9 @@ class Daemon(LoggedClass):
|
|||||||
network_info = await self.getnetworkinfo()
|
network_info = await self.getnetworkinfo()
|
||||||
return network_info['relayfee']
|
return network_info['relayfee']
|
||||||
|
|
||||||
async def getrawtransaction(self, hex_hash):
|
async def getrawtransaction(self, hex_hash, verbose=False):
|
||||||
'''Return the serialized raw transaction with the given hash.'''
|
'''Return the serialized raw transaction with the given hash.'''
|
||||||
return await self._send_single('getrawtransaction', (hex_hash, 0))
|
return await self._send_single('getrawtransaction', (hex_hash, int(verbose)))
|
||||||
|
|
||||||
async def getrawtransactions(self, hex_hashes, replace_errs=True):
|
async def getrawtransactions(self, hex_hashes, replace_errs=True):
|
||||||
'''Return the serialized raw transactions with the given hashes.
|
'''Return the serialized raw transactions with the given hashes.
|
||||||
|
|||||||
104
tests/server/test_api.py
Normal file
104
tests/server/test_api.py
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import asyncio
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from lib.jsonrpc import RPCError
|
||||||
|
from server.env import Env
|
||||||
|
from server.controller import Controller
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
|
||||||
|
def set_env():
|
||||||
|
env = mock.create_autospec(Env)
|
||||||
|
env.coin = mock.Mock()
|
||||||
|
env.loop_policy = None
|
||||||
|
env.max_sessions = 0
|
||||||
|
env.max_subs = 0
|
||||||
|
env.max_send = 0
|
||||||
|
env.bandwidth_limit = 0
|
||||||
|
env.identities = ''
|
||||||
|
env.tor_proxy_host = env.tor_proxy_port = None
|
||||||
|
env.peer_discovery = env.PD_SELF = False
|
||||||
|
env.daemon_url = 'http://localhost:8000/'
|
||||||
|
return env
|
||||||
|
|
||||||
|
|
||||||
|
async def coro(res):
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def raise_exception(exc, msg):
|
||||||
|
raise exc(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_text_exception(test, exception):
|
||||||
|
res = err = None
|
||||||
|
try:
|
||||||
|
res = loop.run_until_complete(test)
|
||||||
|
except Exception as e:
|
||||||
|
err = e
|
||||||
|
assert isinstance(err, exception), (res, err)
|
||||||
|
|
||||||
|
|
||||||
|
def test_transaction_get():
|
||||||
|
async def test_verbose_ignore_by_backend():
|
||||||
|
env = set_env()
|
||||||
|
sut = Controller(env)
|
||||||
|
sut.daemon_request = mock.Mock()
|
||||||
|
sut.daemon_request.return_value = coro('11'*32)
|
||||||
|
res = await sut.transaction_get('ff'*32, True)
|
||||||
|
assert res == '11'*32
|
||||||
|
|
||||||
|
async def test_verbose_ok():
|
||||||
|
env = set_env()
|
||||||
|
sut = Controller(env)
|
||||||
|
sut.daemon_request = mock.Mock()
|
||||||
|
response = {
|
||||||
|
"hex": "00"*32,
|
||||||
|
"blockhash": "ff"*32
|
||||||
|
}
|
||||||
|
sut.daemon_request.return_value = coro(response)
|
||||||
|
res = await sut.transaction_get('ff'*32, True)
|
||||||
|
assert res == response
|
||||||
|
|
||||||
|
response = {
|
||||||
|
"hex": "00"*32,
|
||||||
|
"blockhash": None
|
||||||
|
}
|
||||||
|
sut.daemon_request.return_value = coro(response)
|
||||||
|
res = await sut.transaction_get('ff'*32, True)
|
||||||
|
assert res == response
|
||||||
|
|
||||||
|
async def test_no_verbose():
|
||||||
|
env = set_env()
|
||||||
|
sut = Controller(env)
|
||||||
|
sut.daemon_request = mock.Mock()
|
||||||
|
response = 'cafebabe'*64
|
||||||
|
sut.daemon_request.return_value = coro(response)
|
||||||
|
res = await sut.transaction_get('ff'*32)
|
||||||
|
assert res == response
|
||||||
|
|
||||||
|
async def test_verbose_failure():
|
||||||
|
env = set_env()
|
||||||
|
sut = Controller(env)
|
||||||
|
sut.daemon_request = mock.Mock()
|
||||||
|
sut.daemon_request.return_value = coro(raise_exception(RPCError, 'some unhandled error'))
|
||||||
|
await sut.transaction_get('ff' * 32, True)
|
||||||
|
|
||||||
|
async def test_wrong_txhash():
|
||||||
|
env = set_env()
|
||||||
|
sut = Controller(env)
|
||||||
|
sut.daemon_request = mock.Mock()
|
||||||
|
await sut.transaction_get('cafe')
|
||||||
|
sut.daemon_request.assert_not_called()
|
||||||
|
|
||||||
|
loop.run_until_complete(asyncio.gather(
|
||||||
|
*[
|
||||||
|
test_verbose_ignore_by_backend(),
|
||||||
|
test_verbose_ok(),
|
||||||
|
test_no_verbose()
|
||||||
|
]
|
||||||
|
))
|
||||||
|
|
||||||
|
for error_test in [test_verbose_failure, test_wrong_txhash]:
|
||||||
|
ensure_text_exception(error_test(), RPCError)
|
||||||
Loading…
Reference in New Issue
Block a user