git / moonbite-network / tests/test_sweep_to_vault.py · raw

"""ADR-015 sweep tool: only founder coins, vault verified, batches fit, dry run sends nothing."""import importlib.utilimport osfrom decimal import Decimalimport pytest_spec = importlib.util.spec_from_file_location(    "sweep_to_vault", os.path.join(os.path.dirname(__file__), "..", "tools", "vault", "sweep_to_vault.py"))sweep = importlib.util.module_from_spec(_spec)_spec.loader.exec_module(sweep)def coins(n, addr=sweep.FOUNDER_ADDRESSES[0]):    return [{"txid": f"{i:064x}", "vout": 0, "amount": Decimal("10"), "address": addr} for i in range(n)]class FakeCli:    def __init__(self, utxos, vault=sweep.VAULT):        self.utxos, self.vault, self.calls = utxos, vault, []    def __call__(self, method, *params):        self.calls.append((method, params))        if method == "decodescript":            return {"asm": "1886907600 OP_CHECKLOCKTIMEVERIFY OP_DROP ...", "segwit": {"address": self.vault}}        if method == "listunspent":            assert params[0] == 100 and params[2] == sweep.FOUNDER_ADDRESSES   # mature, founder-only            return self.utxos        if method == "createrawtransaction":            return "raw"        if method == "signrawtransactionwithwallet":            return {"complete": True, "hex": "signed"}        if method == "testmempoolaccept":            return [{"allowed": True}]        if method == "sendrawtransaction":            return "txid%d" % len([c for c in self.calls if c[0] == "sendrawtransaction"])        raise AssertionError(method)def run(monkeypatch, fake, *extra, tmp_path=None):    monkeypatch.setattr(sweep, "Cli", lambda cmd: fake)    args = ["--cli", "moonbite-cli", *extra]    if tmp_path is not None:        args += ["--log", str(tmp_path / "log.txt")]    return sweep.main(args)def test_batches_stay_under_the_size_limit_and_fees_are_small():    b = sweep.plan(coins(2673), 400, 2)    assert len(b) == 7 and sum(len(x["inputs"]) for x in b) == 2673    assert all(sweep.vbytes(len(x["inputs"])) < 100_000 for x in b)    assert sum(x["send"] + x["fee"] for x in b) == Decimal("26730")    assert sum(x["fee"] for x in b) < Decimal("0.01")def test_dry_run_sends_nothing(monkeypatch):    fake = FakeCli(coins(5))    assert run(monkeypatch, fake) == 0    assert not any(m == "sendrawtransaction" for m, _ in fake.calls)def test_wrong_vault_refuses(monkeypatch):    fake = FakeCli(coins(5), vault="moon1qsomethingelse")    with pytest.raises(SystemExit, match="Vault check FAILED"):        run(monkeypatch, fake, "--send")    assert not any(m == "sendrawtransaction" for m, _ in fake.calls)def test_send_pays_only_the_vault_and_logs_txids(monkeypatch, tmp_path):    fake = FakeCli(coins(900))    assert run(monkeypatch, fake, "--send", "--batch", "400", tmp_path=tmp_path) == 0    outs = [p[1] for m, p in fake.calls if m == "createrawtransaction"]    assert len(outs) == 3 and all(list(o.keys()) == [sweep.VAULT] for o in outs)    assert (tmp_path / "log.txt").read_text().count("txid") == 3