Skip to content

Commit 8ce332e

Browse files
committed
Run tests on regtest
1 parent 840404a commit 8ce332e

27 files changed

+910
-522
lines changed

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- name: Generate cache key
2323
run: echo "${{ matrix.rust }}" | tee .cache_key
2424
- name: cache
25-
uses: actions/cache@v2
25+
uses: actions/cache@v3
2626
with:
2727
path: |
2828
~/.cargo/registry

.github/workflows/test.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,33 @@ jobs:
2525
run: make cargo-test
2626
- name: Run wasm-pack test
2727
run: make wasm-test
28+
29+
regtest-test:
30+
name: Run regtest tests
31+
runs-on: ubuntu-latest
32+
steps:
33+
- name: Checkout
34+
uses: actions/checkout@v3
35+
with:
36+
submodules: recursive
37+
- name: Set up Docker
38+
uses: docker/setup-buildx-action@v2
39+
- name: Set up Docker Compose
40+
run: |
41+
sudo apt-get update
42+
sudo apt-get install -y docker-compose
43+
- name: Set default toolchain
44+
run: rustup default nightly
45+
- name: Set profile
46+
run: rustup set profile minimal
47+
- name: Add wasm target
48+
run: rustup target add wasm32-unknown-unknown
49+
- name: Install wasm-pack
50+
run: cargo install wasm-pack
51+
- name: Start regtest environment
52+
working-directory: regtest
53+
run: sh start.sh
54+
- name: Run cargo regtest tests
55+
run: make cargo-regtest-test
56+
- name: Run WASM regtest tests
57+
run: make wasm-regtest-test

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "regtest/boltz"]
2+
path = regtest/boltz
3+
url = https://github.com/BoltzExchange/regtest

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ secp256k1-zkp = { git = "https://github.com/danielgranhao/rust-secp256k1-zkp.git
5757

5858
[dev-dependencies]
5959
futures-util = "0.3.31"
60+
serial_test = "3.2.0"
6061

6162
[target.'cfg(not(all(target_family = "wasm", target_os = "unknown")))'.dev-dependencies]
6263
bitcoind = { version = "0.36.0", features = ["25_0"] }
@@ -65,9 +66,14 @@ tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread"] }
6566

6667
[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dev-dependencies]
6768
wasm-bindgen-test = "0.3.50"
69+
wasm-bindgen = "0.2.100"
70+
gloo-timers = { version = "0.3.0", features = ["futures"] }
71+
futures = "0.3.31"
6872

6973
[features]
7074
default = ["esplora"]
7175
lnurl = ["dep:lnurl-rs"]
7276
esplora = []
7377
electrum = ["dep:electrum-client"]
78+
# Feature to enable tests that require previous initialization of a regtest environment
79+
regtest = []

Makefile

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ ifeq ($(UNAME), Darwin)
44
CLANG_PREFIX += AR=$(shell brew --prefix llvm)/bin/llvm-ar CC=$(shell brew --prefix llvm)/bin/clang
55
endif
66

7+
LND_MACAROON_HEX=$(shell xxd -p regtest/boltz/data/lnd1/data/chain/bitcoin/regtest/admin.macaroon | tr -d '\n')
8+
BITCOIND_COOKIE=$(shell cat regtest/boltz/data/bitcoind/regtest/.cookie)
9+
REGTEST_PREFIX = LND_MACAROON_HEX=$(LND_MACAROON_HEX) BITCOIND_COOKIE=$(BITCOIND_COOKIE)
10+
711
init:
812
cargo install wasm-pack
913

@@ -19,20 +23,36 @@ clippy: cargo-clippy wasm-clippy
1923

2024
test: cargo-test wasm-test
2125

26+
regtest-test: cargo-regtest-test wasm-regtest-test
27+
2228
cargo-clippy:
2329
cargo clippy --all-targets --all-features -- -D warnings
2430

2531
cargo-test:
26-
cargo test -- --nocapture
32+
cargo test --features "esplora, electrum, lnurl" -- --nocapture
33+
34+
cargo-regtest-test:
35+
$(REGTEST_PREFIX) cargo test regtest --features "electrum, regtest" -- --nocapture
2736

2837
wasm-clippy:
2938
$(CLANG_PREFIX) cargo clippy --target=wasm32-unknown-unknown --all-features -- -D warnings
3039

40+
BROWSER ?= firefox
41+
3142
wasm-test:
32-
$(CLANG_PREFIX) wasm-pack test --headless --firefox
43+
$(CLANG_PREFIX) wasm-pack test --headless --$(BROWSER)
3344

3445
wasm-test-chrome:
35-
$(CLANG_PREFIX) wasm-pack test --headless --chrome
46+
BROWSER=chrome $(MAKE) wasm-test
3647

3748
wasm-test-safari:
38-
$(CLANG_PREFIX) wasm-pack test --headless --safari
49+
BROWSER=safari $(MAKE) wasm-test
50+
51+
wasm-regtest-test:
52+
$(CLANG_PREFIX) $(REGTEST_PREFIX) WASM_BINDGEN_TEST_TIMEOUT=500 wasm-pack test --headless --$(BROWSER) --features regtest -- regtest
53+
54+
wasm-regtest-test-chrome:
55+
BROWSER=chrome $(MAKE) wasm-regtest-test
56+
57+
wasm-regtest-test-safari:
58+
BROWSER=safari $(MAKE) wasm-regtest-test

regtest/boltz

Submodule boltz added at 0379ce3

regtest/proxy/Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM python:3.10-slim
2+
3+
WORKDIR /app
4+
5+
RUN apt-get update && apt-get install -y \
6+
&& rm -rf /var/lib/apt/lists/*
7+
8+
RUN pip install --upgrade pip
9+
10+
COPY requirements.txt .
11+
RUN pip install --no-cache-dir -r requirements.txt
12+
13+
COPY ssl_proxy.py .
14+
15+
EXPOSE 51234
16+
17+
CMD ["gunicorn", "--bind", "0.0.0.0:51234", "--workers", "2", "ssl_proxy:app"]

regtest/proxy/docker-compose.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
services:
2+
ssl-proxy:
3+
network_mode: "host"
4+
build: .

regtest/proxy/requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
flask==2.2.5
2+
flask-cors==3.0.10
3+
requests==2.28.2
4+
gunicorn==20.1.0
5+
werkzeug==2.2.3

regtest/proxy/ssl_proxy.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from flask import Flask, request, json, Response
2+
from flask_cors import CORS
3+
import requests
4+
import logging
5+
6+
app = Flask(__name__)
7+
CORS(app) # Allow all origins
8+
9+
# Configure logging
10+
logging.basicConfig(level=logging.INFO)
11+
logger = logging.getLogger(__name__)
12+
13+
14+
@app.route('/proxy', methods=['GET', 'POST', 'PUT', 'DELETE'])
15+
def proxy_request():
16+
target_url = request.headers.get('X-Proxy-URL')
17+
18+
if not target_url:
19+
return Response(
20+
json.dumps({"error": "No target URL provided"}),
21+
status=400,
22+
mimetype='application/json'
23+
)
24+
25+
try:
26+
# Log the incoming request details
27+
logger.info(f"Proxy request to: {target_url}")
28+
logger.info(f"Request method: {request.method}")
29+
logger.info(f"Request headers: {dict(request.headers)}")
30+
31+
# Try to log request body
32+
try:
33+
request_body = request.get_json(silent=True)
34+
logger.info(f"Request body: {request_body}")
35+
except Exception as body_log_error:
36+
logger.error(f"Could not log request body: {body_log_error}")
37+
38+
# Prepare headers, excluding Flask-specific ones
39+
headers = {
40+
key: value for (key, value) in request.headers
41+
if key not in ['Host', 'X-Proxy-URL', 'Content-Length']
42+
}
43+
44+
# Determine the method and make the request
45+
methods = {
46+
'GET': requests.get,
47+
'POST': requests.post,
48+
'PUT': requests.put,
49+
'DELETE': requests.delete
50+
}
51+
52+
method = methods.get(request.method)
53+
if not method:
54+
return Response(
55+
json.dumps({"error": "Unsupported HTTP method"}),
56+
status=405,
57+
mimetype='application/json'
58+
)
59+
60+
# Prepare request arguments
61+
kwargs = {
62+
'url': target_url,
63+
'headers': headers,
64+
'verify': False # Bypass SSL verification
65+
}
66+
67+
# Add data for methods that support it
68+
if request.method in ['POST', 'PUT']:
69+
# Try to parse request data as JSON if possible
70+
request_json = request.get_json(silent=True)
71+
if request_json:
72+
kwargs['json'] = request_json
73+
else:
74+
kwargs['data'] = request.get_data()
75+
76+
# Make the request
77+
try:
78+
response = method(**kwargs)
79+
except Exception as request_error:
80+
logger.error(f"Request error: {request_error}")
81+
return Response(
82+
json.dumps({
83+
"error": "Failed to make request to target service",
84+
"details": str(request_error)
85+
}),
86+
status=500,
87+
mimetype='application/json'
88+
)
89+
90+
return Response(
91+
response.text,
92+
status=response.status_code,
93+
mimetype='application/json'
94+
)
95+
96+
except Exception as e:
97+
logger.error(f"Unexpected error: {e}")
98+
return Response(
99+
json.dumps({"error": str(e)}),
100+
status=500,
101+
mimetype='application/json'
102+
)
103+
104+
105+
if __name__ == '__main__':
106+
app.run(host='0.0.0.0', port=51234)

regtest/start.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
set -xe
3+
4+
cd proxy
5+
docker compose down
6+
docker compose up --remove-orphans -d
7+
8+
cd ../boltz
9+
./start.sh

regtest/stop.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
set -xe
3+
4+
cd boltz
5+
./stop.sh
6+
7+
cd ../proxy
8+
docker compose down --volumes

set_regtest_env.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
export LND_MACAROON_HEX=$(xxd -p regtest/boltz/data/lnd1/data/chain/bitcoin/regtest/admin.macaroon | tr -d '\n')
3+
export BITCOIND_COOKIE=$(<regtest/boltz/data/bitcoind/regtest/.cookie)
4+
5+
echo "LND_MACAROON_HEX set to: $LND_MACAROON_HEX"
6+
echo "BITCOIND_COOKIE set to: $BITCOIND_COOKIE"

src/error.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub enum Error {
2626
Hash(bitcoin::hashes::FromSliceError),
2727
Locktime(String),
2828
Url(url::ParseError),
29-
WebSocket(tokio_tungstenite_wasm::Error),
29+
WebSocket(Box<tokio_tungstenite_wasm::Error>),
3030
Taproot(String),
3131
Musig2(String),
3232
Generic(String),
@@ -186,7 +186,7 @@ impl From<url::ParseError> for Error {
186186

187187
impl From<tokio_tungstenite_wasm::Error> for Error {
188188
fn from(value: tokio_tungstenite_wasm::Error) -> Self {
189-
Self::WebSocket(value)
189+
Self::WebSocket(value.into())
190190
}
191191
}
192192

0 commit comments

Comments
 (0)