Skip to content

Commit be253da

Browse files
Merge pull request #447 from YusukeShimizu/codex/update-elements-mainnet-requirement
elements: require 23.3.1 on Liquid
2 parents 7dfc00f + d24ebf2 commit be253da

7 files changed

Lines changed: 190 additions & 9 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ To run Elements for L-BTC swaps, see the [Elements setup guide](./docs/setup_ele
7070

7171
To run LWK for L-BTC swaps, see the [LWK setup guide](./docs/setup_lwk.md).
7272

73+
> **Important**
74+
> Liquid mainnet L-BTC swaps require a backend that follows the post-[ELIP 203](https://raw.githubusercontent.com/ElementsProject/ELIPs/main/elip-0203.mediawiki) chain tip. When using Elements RPC, run Elements 23.3.1 or newer; Elements 23.3.3 is recommended.
75+
7376
> **Note**
7477
> Most of the benefits of PeerSwap come from using L-BTC. Swaps using L-BTC are more private, faster, and avoid the mainchain blockchain during high fee environments that can make swaps uneconomical.
7578

docs/setup-nix.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This document explains how to set up and maintain the Nix development environmen
55
## Overview
66

77
PeerSwap uses Nix flakes for reproducible development environments and Cachix for fast binary caching. This setup provides:
8-
- Deterministic build environments across all platforms
8+
- Deterministic build environments on supported package platforms
99
- Fast CI/CD builds through binary caching
1010
- Consistent developer experience
1111

@@ -45,6 +45,44 @@ direnv allow
4545
# Without direnv (manual)
4646
nix develop
4747
```
48+
49+
> **Note**
50+
> The full daemon integration environment is Linux-oriented because it includes
51+
> Bitcoin Core, Elements, Core Lightning, LND, and related daemon dependencies.
52+
> On macOS, the full shell may fail to evaluate unsupported Linux-only packages.
53+
> Run end-to-end tests on Linux, matching CI.
54+
55+
### Integration and E2E Tests
56+
57+
The CI integration jobs run inside `nix-shell` on Linux. Use the same entry
58+
point locally on a Linux machine or CI-equivalent runner:
59+
60+
```bash
61+
nix-shell --run "elementsd --version"
62+
nix-shell --run "make test-bins"
63+
```
64+
65+
Run individual matrix targets with the same environment used in CI:
66+
67+
```bash
68+
nix-shell --run "RUN_INTEGRATION_TESTS=1 PAYMENT_RETRY_TIME=10 PEERSWAP_TEST_FILTER=peerswap INTEGRATION_TEST_PARALLEL=6 make test-matrix-liquid_clncln"
69+
```
70+
71+
Available matrix targets are:
72+
73+
```text
74+
bitcoin_clncln
75+
bitcoin_mixed
76+
bitcoin_lndlnd
77+
liquid_clncln
78+
liquid_mixed
79+
liquid_lndlnd
80+
misc_1
81+
misc_2
82+
misc_3
83+
lnd
84+
```
85+
4886
### Binary Cache (Cachix)
4987

5088
The project automatically uses the `peerswap` Cachix cache for faster builds. If you don't have Cachix installed:

docs/setup_elementsd.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ If you would rather just download the binary instead, skip to the next section.
1717

1818
Download the `elementsd` binary release [here](https://github.com/ElementsProject/elements/releases).
1919
> [!IMPORTANT]
20-
> The minimum required version for peerswap is now updated to Elements 23.2.5. Please ensure you are using this version or later to maintain compatibility and functionality. You can find the release details here: [Elements 23.2.5](https://github.com/ElementsProject/elements/releases/tag/elements-23.2.5).
20+
> Liquid mainnet L-BTC swaps require Elements 23.3.1 or newer. Elements 23.3.3 is the recommended stable release. The [ELIP 203](https://raw.githubusercontent.com/ElementsProject/ELIPs/main/elip-0203.mediawiki) Liquid mainnet hard fork is active, and older `elementsd` versions cannot follow the post-fork chain. You can find current binaries on the [Elements releases](https://github.com/ElementsProject/elements/releases) page.
2121
2222
Extract the archive
2323

@@ -27,6 +27,19 @@ Copy the binaries to your PATH
2727

2828
`cp elements*/elementsd elements*/elements-cli /usr/local/bin`
2929

30+
Confirm the installed version:
31+
32+
`elements-cli --version`
33+
34+
For Liquid mainnet, confirm that your node follows the post-fork chain tip:
35+
36+
`elements-cli -chain=liquidv1 getblockchaininfo`
37+
38+
Check that `blocks` is close to `headers` and that `verificationprogress` shows the node is synced. If `blocks` stops advancing on Liquid mainnet, upgrade `elementsd` before using L-BTC swaps.
39+
40+
> **Note**
41+
> [ELIP 201](https://raw.githubusercontent.com/ElementsProject/ELIPs/main/elip-0201.mediawiki) is not the Liquid hard fork that requires the `elementsd` upgrade. The consensus-affecting hard fork is ELIP 203.
42+
3043

3144
## Configuring
3245

@@ -83,4 +96,3 @@ To create a new Liquid receiving address:
8396
To send L-BTC to a Liquid address:
8497

8598
`elements-cli -rpcwallet=peerswap sendtoaddress [address] [amount in decimal form, e.g. 0.1 for 0.10000000 L-BTC]`
86-

docs/setup_lwk.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ To set up `lwk` for PeerSwap, follow the steps here.
55
lwk is currently under development and changes are being made.
66
**peerswap has been tested only with [cli_0.5.1](https://github.com/Blockstream/lwk/releases/tag/cli_0.5.1)**.
77

8+
> [!IMPORTANT]
9+
> Liquid mainnet L-BTC swaps require the LWK/Electrum backend to follow the post-[ELIP 203](https://raw.githubusercontent.com/ElementsProject/ELIPs/main/elip-0203.mediawiki) chain tip. If you run your own backend, make sure it is backed by an Elements node that supports the active Liquid mainnet hard fork.
10+
811
## wallet
912
peerswap assumes a wallet with blinding-key set in singlesig to lwk.
1013

@@ -31,7 +34,7 @@ lwk_cli server start
3134
```
3235

3336
## electrum
34-
peerswap uses [esplora-electrs](https://github.com/Blockstream/electrs) to communicate with the luqiud chain.
37+
peerswap uses [esplora-electrs](https://github.com/Blockstream/electrs) to communicate with the Liquid chain.
3538
By default, peerswap connects to `blockstream.info:995` used by lwk, so no configuration is needed.
3639

3740
If you want to use your own chain, follow the instructions in [esplora-electrs](https://github.com/Blockstream/electrs) to start Electrum JSON-RPC server.
@@ -63,4 +66,4 @@ signername="signername"
6366
walletname="walletname"
6467
network="liquid"
6568
liquidswaps=true
66-
```
69+
```

elements/client.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
package elements
22

33
import (
4+
"fmt"
45
"strings"
56
"time"
67

78
"github.com/elementsproject/glightning/gelements"
89
"github.com/elementsproject/peerswap/log"
910
)
1011

12+
const (
13+
liquidMainnetChain = "liquidv1"
14+
15+
minLiquidMainnetElementsVersion = 230301
16+
minLiquidMainnetElementsVersionString = "23.3.1"
17+
recommendedLiquidMainnetElementsVersion = "23.3.3"
18+
unsupportedLiquidMainnetElementsErrorText = "unsupported elementsd version for Liquid mainnet"
19+
)
20+
1121
type ElementsClientBuilder struct {
1222
}
1323

@@ -34,11 +44,18 @@ func NewClient(rpcUser, rpcPassword, rpcHost, RpcPasswordFile string, rpcPort ui
3444
}
3545

3646
backoff = 1
47+
versionChecked := false
3748
for {
3849
info, err := c.GetChainInfo()
3950
if err != nil {
4051
return nil, err
4152
}
53+
if !versionChecked {
54+
if err := checkLiquidMainnetElementsVersion(c, info.Chain); err != nil {
55+
return nil, err
56+
}
57+
versionChecked = true
58+
}
4259
if info.VerificationProgress < 1. {
4360
// Waiting for block verification to catch up.
4461
log.Infof("Elementsd still syncing, progress: %f", info.VerificationProgress)
@@ -49,3 +66,35 @@ func NewClient(rpcUser, rpcPassword, rpcHost, RpcPasswordFile string, rpcPort ui
4966
return c, nil
5067
}
5168
}
69+
70+
func checkLiquidMainnetElementsVersion(c *gelements.Elements, chain string) error {
71+
if chain != liquidMainnetChain {
72+
return nil
73+
}
74+
info, err := c.GetNetworkInfo()
75+
if err != nil {
76+
return err
77+
}
78+
return validateLiquidMainnetElementsVersion(chain, info.Version, info.Subversion)
79+
}
80+
81+
func validateLiquidMainnetElementsVersion(chain string, version int, subversion string) error {
82+
if chain != liquidMainnetChain || version >= minLiquidMainnetElementsVersion {
83+
return nil
84+
}
85+
86+
return fmt.Errorf(
87+
"%s: Liquid mainnet requires elementsd %s or newer after ELIP 203; "+
88+
"detected version %s (%s). Upgrade to Elements %s or newer, preferably %s",
89+
unsupportedLiquidMainnetElementsErrorText,
90+
minLiquidMainnetElementsVersionString,
91+
formatElementsVersion(version),
92+
subversion,
93+
minLiquidMainnetElementsVersionString,
94+
recommendedLiquidMainnetElementsVersion,
95+
)
96+
}
97+
98+
func formatElementsVersion(version int) string {
99+
return fmt.Sprintf("%d.%d.%d", version/10000, version/100%100, version%100)
100+
}

elements/client_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package elements
2+
3+
import (
4+
"strings"
5+
"testing"
6+
)
7+
8+
func TestValidateLiquidMainnetElementsVersion(t *testing.T) {
9+
t.Parallel()
10+
11+
tests := []struct {
12+
name string
13+
chain string
14+
version int
15+
subversion string
16+
wantErr bool
17+
}{
18+
{
19+
name: "liquid mainnet rejects 23.2.5",
20+
chain: liquidMainnetChain,
21+
version: 230205,
22+
subversion: "/Elements Core:23.2.5/",
23+
wantErr: true,
24+
},
25+
{
26+
name: "liquid mainnet accepts 23.3.1",
27+
chain: liquidMainnetChain,
28+
version: 230301,
29+
subversion: "/Elements Core:23.3.1/",
30+
},
31+
{
32+
name: "liquid mainnet accepts 23.3.3",
33+
chain: liquidMainnetChain,
34+
version: 230303,
35+
subversion: "/Elements Core:23.3.3/",
36+
},
37+
{
38+
name: "liquid testnet does not enforce mainnet minimum",
39+
chain: "liquidtestnet",
40+
version: 230205,
41+
subversion: "/Elements Core:23.2.5/",
42+
},
43+
{
44+
name: "liquid regtest does not enforce mainnet minimum",
45+
chain: "liquidregtest",
46+
version: 230205,
47+
subversion: "/Elements Core:23.2.5/",
48+
},
49+
}
50+
51+
for _, tt := range tests {
52+
tt := tt
53+
t.Run(tt.name, func(t *testing.T) {
54+
t.Parallel()
55+
56+
err := validateLiquidMainnetElementsVersion(tt.chain, tt.version, tt.subversion)
57+
if (err != nil) != tt.wantErr {
58+
t.Fatalf("validateLiquidMainnetElementsVersion() error = %v, wantErr %v", err, tt.wantErr)
59+
}
60+
if !tt.wantErr {
61+
return
62+
}
63+
64+
for _, want := range []string{
65+
unsupportedLiquidMainnetElementsErrorText,
66+
minLiquidMainnetElementsVersionString,
67+
recommendedLiquidMainnetElementsVersion,
68+
tt.subversion,
69+
} {
70+
if !strings.Contains(err.Error(), want) {
71+
t.Fatalf("validateLiquidMainnetElementsVersion() error = %q, want substring %q", err, want)
72+
}
73+
}
74+
})
75+
}
76+
}

flake.nix

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@
6262

6363
# Bitcoin/Elements daemons (used by integration tests / local networks).
6464
# Version checks:
65-
# - `bitcoind --version` (bitcoind 30.0)
66-
# - `elementsd --version` (elementsd 23.2.4)
65+
# - `bitcoind --version` (bitcoind 31.0)
66+
# - `elementsd --version` (elementsd 23.3.3)
6767
bitcoind
6868
elementsd
6969

7070
# Lightning implementations (used by integration tests / local setups).
7171
# Version checks:
72-
# - `lightningd --version` (Core Lightning / clightning 25.09.2)
73-
# - `lnd --version` (lnd 0.19.3-beta)
72+
# - `lightningd --version` (Core Lightning / clightning 26.04.1)
73+
# - `lnd --version` (lnd 0.20.1-beta)
7474
clightning
7575
lnd
7676

0 commit comments

Comments
 (0)