Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 0 additions & 58 deletions tests/coins/btc/test_without_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

from bitcart import BTC

from ...utils import assert_contains, data_check

pytestmark = pytest.mark.asyncio


Expand Down Expand Up @@ -48,69 +46,13 @@ async def test_validate_key(btc, key, expected):
assert await btc.validate_key(key) == expected


async def get_tx(btc, tx_hash):
# TODO: remove when protocol 1.5 is released
# This is temporarily using SPV verification to reliably get confirmations
# This helps avoiding CI failures, see https://github.com/spesmilo/electrum/issues/7342
return await btc.server.get_transaction(tx_hash, use_spv=True)


async def get_address(btc, address):
out = await btc.server.getaddresshistory(address)
for i in out:
i["tx"] = await get_tx(btc, i["tx_hash"])
return out


async def test_get_tx(btc):
info = await get_tx(btc, "15967d9ed9b63f068c7578d54b7adff859f4aadc1253ba316b429d251da6b48c")
assert_contains({"version": 2, "locktime": 1895035}, info)
data_check(info, "confirmations", int)
assert info["confirmations"] > 0
data_check(info, "inputs", list, 1)
assert_contains(
{
"prevout_hash": "3fb55b64df34ded97e97cbd5cfc17b6f114a086950fbb0bffe3c985bfa9f5af8",
"prevout_n": 1,
"coinbase": False,
"nsequence": 4294967294,
"scriptSig": "",
"witness": [
"30440220331290fdbb259fde31d6e0c4eea883e7b7442b1fb1dab0b763cd82c1c5b27a6a02205f37387895fbedb5514a6eb3f374c3943ffefd5df589ac5c59f34f99558386a501",
"0314ef5ee304b86a5c2bbc9d9e1987cd0cb156ca6942ea41dfb487f8d5494bc5bf",
],
},
info["inputs"][0],
)
data_check(info, "outputs", list, 2)
assert info["outputs"][0] == {
"scriptpubkey": "a9144eee7441c8104f1470e6dde89f1439cab91fdc9987",
"address": "2MzSaML6Y3kGn7mPx1T9xXZW1r2N9vKhGo2",
"value_sats": 1515748829,
}


async def test_config_methods(btc):
k, v = "auto_connect", False
await btc.set_config(k, v)
assert await btc.get_config(k) == v
await btc.set_config(k, True)


async def test_get_address(btc):
txes = await get_address(btc, "2MzSaML6Y3kGn7mPx1T9xXZW1r2N9vKhGo2")
assert isinstance(txes, list)
tx = txes[0]
assert tx["tx_hash"] == "15967d9ed9b63f068c7578d54b7adff859f4aadc1253ba316b429d251da6b48c"
assert tx["height"] == 1895036
tx2 = await get_tx(btc, tx["tx_hash"])
# To avoid comparing exact confirmations
# TODO: remove when SPV verification is the default
tx["tx"].pop("confirmations")
tx2.pop("confirmations")
assert tx["tx"] == tx2


async def test_create_wallet(btc, tmp_path):
wallet_path = os.path.join(str(tmp_path), "my_wallet")
wallet = await btc.server.create(wallet_path=wallet_path)
Expand Down
43 changes: 43 additions & 0 deletions tests/regtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,49 @@ def check_tx(tx, broadcast):
# if it is not broadcast, it returns raw transaction


async def fetch_regtest_tx(wallet, tx_hash):
return await wallet.server.get_transaction(tx_hash, use_spv=True)


async def fetch_regtest_address_history(wallet, address):
out = await wallet.server.getaddresshistory(address)
for tx_info in out:
tx_info["tx"] = await fetch_regtest_tx(wallet, tx_info["tx_hash"])
return out


def without_confirmations(tx):
comparable_tx = tx.copy()
comparable_tx.pop("confirmations")
return comparable_tx


async def test_get_tx(regtest_wallet):
txes = await fetch_regtest_address_history(regtest_wallet, BTC_ADDRESS)
tx_hash = txes[0]["tx_hash"]

info = await fetch_regtest_tx(regtest_wallet, tx_hash)

data_check(info, "confirmations", int)
assert info["confirmations"] > 0
data_check(info, "inputs", list)
data_check(info, "outputs", list)
assert any(output.get("address") == BTC_ADDRESS for output in info["outputs"])


async def test_get_address(regtest_wallet):
txes = await fetch_regtest_address_history(regtest_wallet, BTC_ADDRESS)

assert isinstance(txes, list)
assert len(txes) > 0
tx = txes[0]
data_check(tx, "tx_hash", str, 64)
data_check(tx, "height", int)
assert tx["height"] > 0
tx2 = await fetch_regtest_tx(regtest_wallet, tx["tx_hash"])
assert without_confirmations(tx["tx"]) == without_confirmations(tx2)


@pytest.mark.parametrize("fee,feerate,broadcast", TEST_PARAMS)
async def test_payment_to_single(regtest_wallet, fee, feerate, broadcast, wait_for_balance):
check_tx(
Expand Down
21 changes: 21 additions & 0 deletions tests/test_test_suite_boundaries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import ast
from pathlib import Path

SYNC_DEPENDENT_TESTS = {"test_get_tx", "test_get_address"}


def get_test_names(test_file: Path) -> set[str]:
tree = ast.parse(test_file.read_text())
return {node.name for node in tree.body if isinstance(node, ast.AsyncFunctionDef | ast.FunctionDef)}


def test_default_btc_without_wallet_tests_do_not_include_sync_dependent_cases():
test_names = get_test_names(Path("tests/coins/btc/test_without_wallet.py"))

assert test_names.isdisjoint(SYNC_DEPENDENT_TESTS)


def test_regtest_suite_includes_sync_dependent_cases():
test_names = get_test_names(Path("tests/regtest.py"))

assert SYNC_DEPENDENT_TESTS.issubset(test_names)