func test: allow to run using electrs backend
This commit is contained in:
parent
a85d4887e9
commit
371e31e3f3
@ -3,6 +3,7 @@ from bip32.utils import _pubkey_to_fingerprint
|
||||
from bip380.descriptors import Descriptor
|
||||
from concurrent import futures
|
||||
from test_framework.bitcoind import Bitcoind
|
||||
from test_framework.electrs import Electrs
|
||||
from test_framework.lianad import Lianad
|
||||
from test_framework.signer import SingleSigner, MultiSigner
|
||||
from test_framework.utils import (
|
||||
@ -126,6 +127,16 @@ def bitcoin_backend(directory, bitcoind):
|
||||
if BITCOIN_BACKEND_TYPE is BitcoinBackendType.Bitcoind:
|
||||
yield bitcoind
|
||||
bitcoind.cleanup()
|
||||
elif BITCOIN_BACKEND_TYPE is BitcoinBackendType.Electrs:
|
||||
electrs = Electrs(
|
||||
electrs_dir=os.path.join(directory, "electrs"),
|
||||
bitcoind_dir=bitcoind.bitcoin_dir,
|
||||
bitcoind_rpcport=bitcoind.rpcport,
|
||||
bitcoind_p2pport=bitcoind.p2pport,
|
||||
)
|
||||
electrs.startup()
|
||||
yield electrs
|
||||
electrs.cleanup()
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@ -238,7 +238,8 @@ def test_rescan_edge_cases(lianad, bitcoind):
|
||||
outpoints_before = set(c["outpoint"] for c in coins_before)
|
||||
bitcoind.generate_block(1)
|
||||
lianad.restart_fresh(bitcoind)
|
||||
assert len(list_coins()) == 0
|
||||
if BITCOIN_BACKEND_TYPE is BitcoinBackendType.Bitcoind:
|
||||
assert len(list_coins()) == 0
|
||||
|
||||
# We can be stopped while we are rescanning
|
||||
lianad.rpc.startrescan(initial_tip["time"])
|
||||
@ -252,7 +253,8 @@ def test_rescan_edge_cases(lianad, bitcoind):
|
||||
bitcoind.generate_block(1)
|
||||
lianad.restart_fresh(bitcoind)
|
||||
wait_for(lambda: lianad.rpc.getinfo()["rescan_progress"] is None)
|
||||
assert len(list_coins()) == 0
|
||||
if BITCOIN_BACKEND_TYPE is BitcoinBackendType.Bitcoind:
|
||||
assert len(list_coins()) == 0
|
||||
|
||||
# There can be a reorg when we start rescanning
|
||||
reorg_shift(initial_tip["height"], txs)
|
||||
@ -271,7 +273,8 @@ def test_rescan_edge_cases(lianad, bitcoind):
|
||||
lianad.restart_fresh(bitcoind)
|
||||
wait_synced()
|
||||
wait_for(lambda: lianad.rpc.getinfo()["rescan_progress"] is None)
|
||||
assert len(list_coins()) == 0
|
||||
if BITCOIN_BACKEND_TYPE is BitcoinBackendType.Bitcoind:
|
||||
assert len(list_coins()) == 0
|
||||
|
||||
# We can be rescanning when a reorg happens
|
||||
lianad.rpc.startrescan(initial_tip["time"])
|
||||
@ -350,7 +353,8 @@ def test_rescan_and_recovery(lianad, bitcoind):
|
||||
|
||||
# Clear lianad state
|
||||
lianad.restart_fresh(bitcoind)
|
||||
assert len(lianad.rpc.listcoins()["coins"]) == 0
|
||||
if BITCOIN_BACKEND_TYPE is BitcoinBackendType.Bitcoind:
|
||||
assert len(lianad.rpc.listcoins()["coins"]) == 0
|
||||
|
||||
# Start rescan
|
||||
lianad.rpc.startrescan(initial_tip["time"])
|
||||
|
||||
79
tests/test_framework/electrs.py
Normal file
79
tests/test_framework/electrs.py
Normal file
@ -0,0 +1,79 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
from ephemeral_port_reserve import reserve
|
||||
from test_framework.utils import BitcoinBackend, TailableProc, ELECTRS_PATH
|
||||
|
||||
|
||||
class Electrs(BitcoinBackend):
|
||||
def __init__(
|
||||
self,
|
||||
bitcoind_dir,
|
||||
bitcoind_rpcport,
|
||||
bitcoind_p2pport,
|
||||
electrs_dir,
|
||||
rpcport=None,
|
||||
):
|
||||
TailableProc.__init__(self, electrs_dir, verbose=False)
|
||||
|
||||
if rpcport is None:
|
||||
rpcport = reserve()
|
||||
|
||||
# Prometheus metrics can't be deactivated in Electrs. Configure the port so it doesn't
|
||||
# conflict with other instances when running tests in parallel.
|
||||
monitoring_port = reserve()
|
||||
|
||||
self.electrs_dir = electrs_dir
|
||||
self.rpcport = rpcport
|
||||
|
||||
regtestdir = os.path.join(electrs_dir, "regtest")
|
||||
if not os.path.exists(regtestdir):
|
||||
os.makedirs(regtestdir)
|
||||
|
||||
self.cmd_line = [
|
||||
ELECTRS_PATH,
|
||||
"--conf",
|
||||
"{}/electrs.toml".format(regtestdir),
|
||||
]
|
||||
electrs_conf = {
|
||||
"daemon_dir": bitcoind_dir,
|
||||
"cookie_file": os.path.join(bitcoind_dir, "regtest", ".cookie"),
|
||||
"daemon_rpc_addr": f"127.0.0.1:{bitcoind_rpcport}",
|
||||
"daemon_p2p_addr": f"127.0.0.1:{bitcoind_p2pport}",
|
||||
"db_dir": electrs_dir,
|
||||
"network": "regtest",
|
||||
"electrum_rpc_addr": f"127.0.0.1:{self.rpcport}",
|
||||
"monitoring_addr": f"127.0.0.1:{monitoring_port}",
|
||||
}
|
||||
self.conf_file = os.path.join(regtestdir, "electrs.toml")
|
||||
with open(self.conf_file, "w") as f:
|
||||
for k, v in electrs_conf.items():
|
||||
f.write(f'{k} = "{v}"\n')
|
||||
|
||||
self.env = {"RUST_LOG": "DEBUG"}
|
||||
|
||||
def start(self):
|
||||
TailableProc.start(self)
|
||||
logging.info("Electrs started")
|
||||
|
||||
def startup(self):
|
||||
try:
|
||||
self.start()
|
||||
except Exception:
|
||||
self.stop()
|
||||
raise
|
||||
|
||||
def stop(self):
|
||||
return TailableProc.stop(self)
|
||||
|
||||
def cleanup(self):
|
||||
try:
|
||||
self.stop()
|
||||
except Exception:
|
||||
self.proc.kill()
|
||||
self.proc.wait()
|
||||
|
||||
def append_to_lianad_conf(self, conf_file):
|
||||
with open(conf_file, "a") as f:
|
||||
f.write("[electrum_config]\n")
|
||||
f.write(f"addr = '127.0.0.1:{self.rpcport}'\n")
|
||||
@ -5,6 +5,8 @@ import shutil
|
||||
from bip380.descriptors import Descriptor
|
||||
from bip380.miniscript import SatisfactionMaterial
|
||||
from test_framework.utils import (
|
||||
BITCOIN_BACKEND_TYPE,
|
||||
BitcoinBackendType,
|
||||
UnixDomainSocketRpc,
|
||||
TailableProc,
|
||||
VERBOSE,
|
||||
@ -43,6 +45,7 @@ class Lianad(TailableProc):
|
||||
self.cmd_line = [LIANAD_PATH, "--conf", f"{self.conf_file}"]
|
||||
socket_path = os.path.join(os.path.join(datadir, "regtest"), "lianad_rpc")
|
||||
self.rpc = UnixDomainSocketRpc(socket_path)
|
||||
self.bitcoin_backend = bitcoin_backend
|
||||
|
||||
with open(self.conf_file, "w") as f:
|
||||
f.write(f"data_dir = '{datadir}'\n")
|
||||
@ -103,8 +106,9 @@ class Lianad(TailableProc):
|
||||
self.stop()
|
||||
dir_path = os.path.join(self.datadir, "regtest")
|
||||
shutil.rmtree(dir_path)
|
||||
wallet_path = os.path.join(dir_path, "lianad_watchonly_wallet")
|
||||
bitcoind.node_rpc.unloadwallet(wallet_path)
|
||||
if BITCOIN_BACKEND_TYPE is BitcoinBackendType.Bitcoind:
|
||||
wallet_path = os.path.join(dir_path, "lianad_watchonly_wallet")
|
||||
bitcoind.node_rpc.unloadwallet(wallet_path)
|
||||
self.start()
|
||||
wait_for(
|
||||
lambda: self.rpc.getinfo()["block_height"] == bitcoind.rpc.getblockcount()
|
||||
|
||||
@ -26,6 +26,7 @@ LIANAD_PATH = os.getenv("LIANAD_PATH", DEFAULT_MS_PATH)
|
||||
|
||||
class BitcoinBackendType(str, enum.Enum):
|
||||
Bitcoind = "bitcoind"
|
||||
Electrs = "electrs"
|
||||
|
||||
|
||||
DEFAULT_BITCOIN_BACKEND_TYPE = "bitcoind"
|
||||
@ -34,6 +35,8 @@ BITCOIN_BACKEND_TYPE = BitcoinBackendType(
|
||||
)
|
||||
DEFAULT_BITCOIND_PATH = "bitcoind"
|
||||
BITCOIND_PATH = os.getenv("BITCOIND_PATH", DEFAULT_BITCOIND_PATH)
|
||||
DEFAULT_ELECTRS_PATH = "electrs"
|
||||
ELECTRS_PATH = os.getenv("ELECTRS_PATH", DEFAULT_ELECTRS_PATH)
|
||||
OLD_LIANAD_PATH = os.getenv("OLD_LIANAD_PATH", None)
|
||||
IS_NOT_BITCOIND_24 = bool(int(os.getenv("IS_NOT_BITCOIND_24", True)))
|
||||
USE_TAPROOT = bool(
|
||||
|
||||
@ -7,6 +7,8 @@ from fixtures import *
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.serializations import PSBT
|
||||
from test_framework.utils import (
|
||||
BitcoinBackendType,
|
||||
BITCOIN_BACKEND_TYPE,
|
||||
wait_for,
|
||||
RpcError,
|
||||
OLD_LIANAD_PATH,
|
||||
@ -260,6 +262,10 @@ def test_coinbase_deposit(lianad, bitcoind):
|
||||
OLD_LIANAD_PATH is None or USE_TAPROOT,
|
||||
reason="Need the old lianad binary to create the datadir.",
|
||||
)
|
||||
@pytest.mark.skipif(
|
||||
BITCOIN_BACKEND_TYPE is not BitcoinBackendType.Bitcoind,
|
||||
reason="Only bitcoind backend was available for older lianad versions.",
|
||||
)
|
||||
def test_migration(lianad_multisig, bitcoind):
|
||||
"""Test we can start a newer lianad on a datadir created by an older lianad."""
|
||||
lianad = lianad_multisig
|
||||
@ -315,6 +321,10 @@ def bitcoind_wait_new_block(bitcoind):
|
||||
@pytest.mark.skipif(
|
||||
not IS_NOT_BITCOIND_24, reason="Need 'generateblock' with 'submit=False'"
|
||||
)
|
||||
@pytest.mark.skipif(
|
||||
BITCOIN_BACKEND_TYPE is not BitcoinBackendType.Bitcoind,
|
||||
reason="Tests the retry logic specific to the bitcoind backend.",
|
||||
)
|
||||
def test_retry_on_workqueue_exceeded(lianad, bitcoind, executor):
|
||||
"""Make sure we retry requests to bitcoind if it is temporarily overloaded."""
|
||||
# Start by reducing the work queue to a single slot. Note we need to stop lianad
|
||||
|
||||
@ -686,11 +686,13 @@ def test_start_rescan(lianad, bitcoind):
|
||||
# descriptor.
|
||||
coins_before = sorted_coins()
|
||||
lianad.restart_fresh(bitcoind)
|
||||
assert len(list_coins()) == 0
|
||||
if BITCOIN_BACKEND_TYPE is BitcoinBackendType.Bitcoind:
|
||||
assert len(list_coins()) == 0
|
||||
|
||||
# The wallet isn't aware what derivation indexes were used. Necessarily it'll start
|
||||
# from 0.
|
||||
assert lianad.rpc.getnewaddress() == first_address
|
||||
if BITCOIN_BACKEND_TYPE is BitcoinBackendType.Bitcoind:
|
||||
assert lianad.rpc.getnewaddress() == first_address
|
||||
|
||||
# Once the rescan is done, we must have detected all previous transactions.
|
||||
lianad.rpc.startrescan(initial_timestamp)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user