def test_sendrawtransaction(genesis_block_hash): # sendrawtransaction should only allow txs that the simulator has not mined yet bitcoin_cli().sendrawtransaction( transaction.create_dummy_transaction().hex()) # Any tx with invalid format or that matches with an already mined transaction should fail try: # Trying to resend the coinbase tx of the genesis block 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: # Sending random values try: bitcoin_cli().sendrawtransaction(v) assert False except JSONRPCException as e: assert True # Trying with a valid tx try: tx = transaction.create_dummy_transaction() bitcoin_cli().sendrawtransaction(tx.hex()) assert True except JSONRPCException as e: assert False
def test_getblockhash(genesis_block_hash): # First block assert bitcoin_cli().getblockhash(0) == 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_generate(): best_block_hash = bitcoin_cli().getbestblockhash() best_block = bitcoin_cli().getblock(best_block_hash) requests.post(url="http://{}:{}/generate".format(conf.BTC_RPC_HOST, conf.BTC_RPC_PORT), timeout=5) new_best_block_hash = bitcoin_cli().getbestblockhash() new_best_block = bitcoin_cli().getblock(new_best_block_hash) assert best_block_hash != new_best_block_hash assert new_best_block.get("height") == best_block.get("height") + 1
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_getblock(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 best_block = bitcoin_cli().getblock(bitcoin_cli().getbestblockhash()) requests.post(url="http://{}:{}/generate".format(conf.BTC_RPC_HOST, conf.BTC_RPC_PORT), timeout=5) # Check that the confirmation counting works old_best = bitcoin_cli().getblock(best_block.get("hash")) best_block = bitcoin_cli().getblock(bitcoin_cli().getbestblockhash()) assert best_block.get("confirmations") == old_best.get("confirmations") - 1
def test_create_fork(): best_block_hash = bitcoin_cli().getbestblockhash() requests.post(url="http://{}:{}/generate".format(conf.BTC_RPC_HOST, conf.BTC_RPC_PORT), timeout=5) new_best_block_hash = bitcoin_cli().getbestblockhash() # Create a fork (new block at same height as old best) requests.post( url="http://{}:{}/fork".format(conf.BTC_RPC_HOST, conf.BTC_RPC_PORT), json={"parent": best_block_hash}, timeout=5, ) # Mine an additional block to make the best tip change requests.post(url="http://{}:{}/generate".format(conf.BTC_RPC_HOST, conf.BTC_RPC_PORT), timeout=5) # Check that the old best block is now in a fork orphan_block = bitcoin_cli().getblock(new_best_block_hash) assert orphan_block.get("confirmations") == -1 assert orphan_block.get("previousblockhash") == best_block_hash new_best_block_hash = bitcoin_cli().getbestblockhash() forked_block = bitcoin_cli().getblock(new_best_block_hash) # Check that the new best links to the original best assert forked_block.get("confirmations") == bitcoin_cli().getblock( best_block_hash).get("confirmations") - 2 assert bitcoin_cli().getblock(forked_block.get("previousblockhash")).get( "previousblockhash") == best_block_hash
def test_getbestblockhash(): # Get block hash should return the tip of the best chain best_block_hash = bitcoin_cli().getbestblockhash() # If we generate a new block, the tip should that block requests.post(url="http://{}:{}/generate".format(conf.BTC_RPC_HOST, conf.BTC_RPC_PORT), timeout=5) new_best_block_hash = bitcoin_cli().getbestblockhash() assert bitcoin_cli().getblock(new_best_block_hash).get( "previousblockhash") == best_block_hash # If we fork and generate a few blocks (surpassing the current tip) the best block hash should change requests.post( url="http://{}:{}/fork".format(conf.BTC_RPC_HOST, conf.BTC_RPC_PORT), json={"parent": best_block_hash}, timeout=5, ) # The tip should still be the same (we have a block at the same height but the previous one was seen first) assert bitcoin_cli().getbestblockhash() == new_best_block_hash requests.post(url="http://{}:{}/generate".format(conf.BTC_RPC_HOST, conf.BTC_RPC_PORT), timeout=5) # The tip should have changed now, and the old chain should be a fork assert bitcoin_cli().getbestblockhash() != new_best_block_hash assert bitcoin_cli().getblock(new_best_block_hash).get( "confirmations") == -1
def test_decoderawtransaction(genesis_block_hash): # decoderawtransaction should only return if the given transaction is properly formatted (can be deserialized using # (TX.deserialize(raw_tx). 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 it should also work for a random transaction hex in our simulation random_tx = transaction.create_dummy_transaction() tx = bitcoin_cli().decoderawtransaction(random_tx.hex()) 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_help(): # Help should always return 0 assert bitcoin_cli().help() == 0
def test_getblockcount(): # getblockcount should always return a positive integer bc = bitcoin_cli().getblockcount() assert isinstance(bc, int) assert bc >= 0