mirror of
https://github.com/aljazceru/python-teos.git
synced 2025-12-17 22:24:23 +01:00
The simulator has been updated to work with real transaction structures instead of transaction hashes. It now supports: - Non-SegWit transaction format - Generation of blocks event-wise and time-wise Some small issues have also been fixed. With the new approach, the simulator can be used in a broader range of tests. Moreover tests can run faster since they do not have to wait for blocks. Instead, the generation of new blocks can be triggered by the test.
148 lines
4.5 KiB
Python
148 lines
4.5 KiB
Python
import re
|
|
import os
|
|
import pytest
|
|
from time import sleep
|
|
from threading import Thread
|
|
|
|
from test.simulator.transaction import TX
|
|
from test.simulator.bitcoind_sim import run_simulator
|
|
from pisa.utils.auth_proxy import AuthServiceProxy, JSONRPCException
|
|
from pisa.conf import BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT
|
|
|
|
MIXED_VALUES = values = [-1, 500, '', '111', [], 1.1, None, '', "a" * 31, "b" * 33, os.urandom(32).hex()]
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def run_bitcoind():
|
|
bitcoind_thread = Thread(target=run_simulator, kwargs={"mode": "event"})
|
|
bitcoind_thread.daemon = True
|
|
bitcoind_thread.start()
|
|
|
|
# It takes a little bit of time to start the API (otherwise the requests are sent too early and they fail)
|
|
sleep(0.1)
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def genesis_block_hash(run_bitcoind):
|
|
return bitcoin_cli.getblockhash(0)
|
|
|
|
|
|
def check_hash_format(txid):
|
|
# TODO: #12-check-txid-regexp
|
|
return isinstance(txid, str) and re.search(r'^[0-9A-Fa-f]{64}$', txid) is not None
|
|
|
|
|
|
bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT))
|
|
|
|
|
|
def test_help(run_bitcoind):
|
|
# Help should always return 0
|
|
assert(bitcoin_cli.help() == 0)
|
|
|
|
|
|
# FIXME: Better assert for the exceptions would be nice (check the returned errno is the expected one)
|
|
|
|
def test_getblockhash(genesis_block_hash):
|
|
# First block
|
|
assert(check_hash_format(genesis_block_hash))
|
|
|
|
# Check that the values are within range and of the proper format (all should fail)
|
|
for v in MIXED_VALUES:
|
|
try:
|
|
bitcoin_cli.getblockhash(v)
|
|
assert False
|
|
except JSONRPCException as e:
|
|
assert True
|
|
|
|
|
|
def test_get_block(genesis_block_hash):
|
|
# getblock should return a list of transactions and the height
|
|
block = bitcoin_cli.getblock(genesis_block_hash)
|
|
assert(isinstance(block.get('tx'), list))
|
|
assert(len(block.get('tx')) != 0)
|
|
assert(isinstance(block.get('height'), int))
|
|
|
|
# It should fail for wrong data formats and random ids
|
|
for v in MIXED_VALUES:
|
|
try:
|
|
bitcoin_cli.getblock(v)
|
|
assert False
|
|
except JSONRPCException as e:
|
|
assert True
|
|
|
|
|
|
def test_decoderawtransaction(genesis_block_hash):
|
|
# decoderawtransaction should only return if the given transaction matches a txid format
|
|
block = bitcoin_cli.getblock(genesis_block_hash)
|
|
coinbase_txid = block.get('tx')[0]
|
|
|
|
coinbase_tx = bitcoin_cli.getrawtransaction(coinbase_txid).get("hex")
|
|
tx = bitcoin_cli.decoderawtransaction(coinbase_tx)
|
|
|
|
assert(isinstance(tx, dict))
|
|
assert(isinstance(tx.get('txid'), str))
|
|
assert(check_hash_format(tx.get('txid')))
|
|
|
|
# Therefore should also work for a random transaction hex in our simulation
|
|
random_tx = TX.create_dummy_transaction()
|
|
tx = bitcoin_cli.decoderawtransaction(random_tx)
|
|
assert(isinstance(tx, dict))
|
|
assert(isinstance(tx.get('txid'), str))
|
|
assert(check_hash_format(tx.get('txid')))
|
|
|
|
# But it should fail for not proper formatted one
|
|
for v in MIXED_VALUES:
|
|
try:
|
|
bitcoin_cli.decoderawtransaction(v)
|
|
assert False
|
|
except JSONRPCException as e:
|
|
assert True
|
|
|
|
|
|
def test_sendrawtransaction(genesis_block_hash):
|
|
# sendrawtransaction should only allow txids that the simulator has not mined yet
|
|
bitcoin_cli.sendrawtransaction(TX.create_dummy_transaction())
|
|
|
|
# Any data not matching the txid format or that matches with an already mined transaction should fail
|
|
try:
|
|
genesis_tx = bitcoin_cli.getblock(genesis_block_hash).get("tx")[0]
|
|
bitcoin_cli.sendrawtransaction(genesis_tx)
|
|
assert False
|
|
|
|
except JSONRPCException as e:
|
|
assert True
|
|
|
|
for v in MIXED_VALUES:
|
|
try:
|
|
bitcoin_cli.sendrawtransaction(v)
|
|
assert False
|
|
except JSONRPCException as e:
|
|
assert True
|
|
|
|
|
|
def test_getrawtransaction(genesis_block_hash):
|
|
# getrawtransaction should work for existing transactions, and fail for non-existing ones
|
|
genesis_tx = bitcoin_cli.getblock(genesis_block_hash).get("tx")[0]
|
|
tx = bitcoin_cli.getrawtransaction(genesis_tx)
|
|
|
|
assert(isinstance(tx, dict))
|
|
assert(isinstance(tx.get('confirmations'), int))
|
|
|
|
for v in MIXED_VALUES:
|
|
try:
|
|
bitcoin_cli.getrawtransaction(v)
|
|
assert False
|
|
except JSONRPCException as e:
|
|
assert True
|
|
|
|
|
|
def test_getblockcount():
|
|
# getblockcount should always return a positive integer
|
|
bc = bitcoin_cli.getblockcount()
|
|
assert (isinstance(bc, int))
|
|
assert (bc >= 0)
|
|
|
|
|
|
|
|
|