diff --git a/chainreg/chainparams.go b/chainreg/chainparams.go index 33006d5a2..166a1fec5 100644 --- a/chainreg/chainparams.go +++ b/chainreg/chainparams.go @@ -22,6 +22,14 @@ var BitcoinTestNetParams = BitcoinNetParams{ CoinType: keychain.CoinTypeTestnet, } +// BitcoinTestNet4Params contains parameters specific to the 4th version of the +// test network. +var BitcoinTestNet4Params = BitcoinNetParams{ + Params: &bitcoinCfg.TestNet4Params, + RPCPort: "48334", + CoinType: keychain.CoinTypeTestnet, +} + // BitcoinMainNetParams contains parameters specific to the current Bitcoin // mainnet. var BitcoinMainNetParams = BitcoinNetParams{ @@ -53,8 +61,9 @@ var BitcoinRegTestNetParams = BitcoinNetParams{ CoinType: keychain.CoinTypeTestnet, } -// IsTestnet tests if the givern params correspond to a testnet -// parameter configuration. +// IsTestnet tests if the given params correspond to a testnet parameter +// configuration. func IsTestnet(params *BitcoinNetParams) bool { - return params.Params.Net == bitcoinWire.TestNet3 + return params.Params.Net == bitcoinWire.TestNet3 || + params.Params.Net == bitcoinWire.TestNet4 } diff --git a/chainreg/chainregistry.go b/chainreg/chainregistry.go index a9a9ede70..3f9f738b2 100644 --- a/chainreg/chainregistry.go +++ b/chainreg/chainregistry.go @@ -838,6 +838,15 @@ var ( 0x01, 0xea, 0x33, 0x09, 0x00, 0x00, 0x00, 0x00, }) + // BitcoinTestnet4Genesis is the genesis hash of Bitcoin's testnet4 + // chain. + BitcoinTestnet4Genesis = chainhash.Hash([chainhash.HashSize]byte{ + 0x43, 0xf0, 0x8b, 0xda, 0xb0, 0x50, 0xe3, 0x5b, + 0x56, 0x7c, 0x86, 0x4b, 0x91, 0xf4, 0x7f, 0x50, + 0xae, 0x72, 0x5a, 0xe2, 0xde, 0x53, 0xbc, 0xfb, + 0xba, 0xf2, 0x84, 0xda, 0x00, 0x00, 0x00, 0x00, + }) + // BitcoinSignetGenesis is the genesis hash of Bitcoin's signet chain. BitcoinSignetGenesis = chainhash.Hash([chainhash.HashSize]byte{ 0xf6, 0x1e, 0xee, 0x3b, 0x63, 0xa3, 0x80, 0xa4, diff --git a/cmd/commands/main.go b/cmd/commands/main.go index 71a8531d9..ec593f1ad 100644 --- a/cmd/commands/main.go +++ b/cmd/commands/main.go @@ -286,7 +286,7 @@ func contextWithMetadata(ctx context.Context, func extractPathArgs(ctx *cli.Context) (string, string, error) { network := strings.ToLower(ctx.GlobalString("network")) switch network { - case "mainnet", "testnet", "regtest", "simnet", "signet": + case "mainnet", "testnet", "testnet4", "regtest", "simnet", "signet": default: return "", "", fmt.Errorf("unknown network: %v", network) } @@ -386,8 +386,9 @@ func Main() { }, cli.StringFlag{ Name: "network, n", - Usage: "The network lnd is running on, e.g. mainnet, " + - "testnet, etc.", + Usage: "The network lnd is running on; valid values " + + "are: mainnet, testnet, testnet4, regtest, " + + "signet and simnet.", Value: "mainnet", EnvVar: envVarNetwork, }, @@ -555,9 +556,12 @@ func networkParams(ctx *cli.Context) (*chaincfg.Params, error) { case "mainnet": return &chaincfg.MainNetParams, nil - case "testnet": + case "testnet", "testnet3": return &chaincfg.TestNet3Params, nil + case "testnet4": + return &chaincfg.TestNet4Params, nil + case "regtest": return &chaincfg.RegressionNetParams, nil diff --git a/config.go b/config.go index be0838be2..2390a3ee2 100644 --- a/config.go +++ b/config.go @@ -1208,6 +1208,10 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser, numNets++ cfg.ActiveNetParams = chainreg.BitcoinTestNetParams } + if cfg.Bitcoin.TestNet4 { + numNets++ + cfg.ActiveNetParams = chainreg.BitcoinTestNet4Params + } if cfg.Bitcoin.RegTest { numNets++ cfg.ActiveNetParams = chainreg.BitcoinRegTestNetParams @@ -1265,8 +1269,8 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser, cfg.ActiveNetParams.Params = &chainParams } if numNets > 1 { - str := "The mainnet, testnet, regtest, simnet and signet " + - "params can't be used together -- choose one " + + str := "The mainnet, testnet, testnet4, regtest, simnet and " + + "signet params can't be used together -- choose one " + "of the five" return nil, mkErr(str) @@ -1275,9 +1279,10 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser, // The target network must be provided, otherwise, we won't // know how to initialize the daemon. if numNets == 0 { - str := "either --bitcoin.mainnet, or bitcoin.testnet, " + - "bitcoin.simnet, bitcoin.regtest or bitcoin.signet " + - "must be specified" + str := "either --bitcoin.mainnet, or --bitcoin.testnet, " + + "--bitcoin.testnet4, --bitcoin.simnet, " + + "--bitcoin.regtest or --bitcoin.signet must be " + + "specified" return nil, mkErr(str) } @@ -2202,7 +2207,7 @@ func extractBitcoindRPCParams(networkName, bitcoindDataDir, bitcoindConfigPath, switch networkName { case "mainnet": chainDir = "" - case "regtest", "testnet3", "signet": + case "regtest", "testnet3", "testnet4", "signet": chainDir = networkName default: return "", "", "", "", fmt.Errorf("unexpected networkname %v", networkName) diff --git a/docs/release-notes/release-notes-0.19.0.md b/docs/release-notes/release-notes-0.19.0.md index baaee0705..13efa1831 100644 --- a/docs/release-notes/release-notes-0.19.0.md +++ b/docs/release-notes/release-notes-0.19.0.md @@ -234,6 +234,9 @@ close transaction. * [The server](https://github.com/lightningnetwork/lnd/pull/9458) now allocates restricted slots for certain peers. This is configured by --num-restricted-slots. +* [The bitcoin `testnet4` test network is now also + supported](https://github.com/lightningnetwork/lnd/pull/9620). + ## RPC Updates * Some RPCs that previously just returned an empty response message now at least diff --git a/go.mod b/go.mod index 98f35eef2..d1351bca0 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,14 @@ require ( github.com/NebulousLabs/go-upnp v0.0.0-20180202185039-29b680b06c82 github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 github.com/andybalholm/brotli v1.0.4 - github.com/btcsuite/btcd v0.24.3-0.20241210095828-e646d437e95b + github.com/btcsuite/btcd v0.24.3-0.20250318170759-4f4ea81776d6 github.com/btcsuite/btcd/btcec/v2 v2.3.4 github.com/btcsuite/btcd/btcutil v1.1.5 github.com/btcsuite/btcd/btcutil/psbt v1.1.8 github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c github.com/btcsuite/btclog/v2 v2.0.1-0.20250110154127-3ae4bf1cb318 - github.com/btcsuite/btcwallet v0.16.11 + github.com/btcsuite/btcwallet v0.16.12 github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5 github.com/btcsuite/btcwallet/wallet/txrules v1.2.2 github.com/btcsuite/btcwallet/walletdb v1.4.4 @@ -31,7 +31,7 @@ require ( github.com/jessevdk/go-flags v1.4.0 github.com/jrick/logrotate v1.1.2 github.com/kkdai/bstream v1.0.0 - github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd + github.com/lightninglabs/neutrino v0.16.1 github.com/lightninglabs/neutrino/cache v1.1.2 github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb github.com/lightningnetwork/lnd/cert v1.2.2 @@ -64,7 +64,7 @@ require ( google.golang.org/protobuf v1.33.0 gopkg.in/macaroon-bakery.v2 v2.0.1 gopkg.in/macaroon.v2 v2.0.0 - pgregory.net/rapid v1.1.0 + pgregory.net/rapid v1.2.0 ) require ( diff --git a/go.sum b/go.sum index 9c69f3fc6..a79d0f443 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= -github.com/btcsuite/btcd v0.24.3-0.20241210095828-e646d437e95b h1:VQoobSrWdxICuqFU3tKVu/Lzk7BTk9SsCgRr5dUvC70= -github.com/btcsuite/btcd v0.24.3-0.20241210095828-e646d437e95b/go.mod h1:zHK7t7sw8XbsCkD64WePHE3r3k9/XoGAcf6mXV14c64= +github.com/btcsuite/btcd v0.24.3-0.20250318170759-4f4ea81776d6 h1:8n9k3I7e8DkpdQ5YAP4j8ly/LSsbe6qX9vmVbrUGvVw= +github.com/btcsuite/btcd v0.24.3-0.20250318170759-4f4ea81776d6/go.mod h1:OmM4kFtB0klaG/ZqT86rQiyw/1iyXlJgc3UHClPhhbs= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= @@ -95,8 +95,8 @@ github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c/go.mod h1:w7xnGOhw github.com/btcsuite/btclog/v2 v2.0.1-0.20250110154127-3ae4bf1cb318 h1:oCjIcinPt7XQ644MP/22JcjYEC84qRc3bRBH0d7Hhd4= github.com/btcsuite/btclog/v2 v2.0.1-0.20250110154127-3ae4bf1cb318/go.mod h1:XItGUfVOxotJL8kkuk2Hj3EVow5KCugXl3wWfQ6K0AE= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcwallet v0.16.11 h1:c8RgW/HO79if8P+KFQLQE00ITmFnLPKAzIy9FwxE37A= -github.com/btcsuite/btcwallet v0.16.11/go.mod h1:1HJXYbjJzgumlnxOC2+ViR1U+gnHWoOn7WeK5OfY1eU= +github.com/btcsuite/btcwallet v0.16.12 h1:9SREKY892i1xTGlGLcu6x7O+WSQFn6+uQrSuskAOqh0= +github.com/btcsuite/btcwallet v0.16.12/go.mod h1:jBn+ThFrx/QqW0nXiGvXtJytju4aVoW7C0hY4s/+9vo= github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5 h1:Rr0njWI3r341nhSPesKQ2JF+ugDSzdPoeckS75SeDZk= github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5/go.mod h1:+tXJ3Ym0nlQc/iHSwW1qzjmPs3ev+UVWMbGgfV1OZqU= github.com/btcsuite/btcwallet/wallet/txrules v1.2.2 h1:YEO+Lx1ZJJAtdRrjuhXjWrYsmAk26wLTlNzxt2q0lhk= @@ -444,8 +444,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf h1:HZKvJUHlcXI/f/O0Avg7t8sqkPo78HFzjmeYFl6DPnc= github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk= -github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd h1:D8aRocHpoCv43hL8egXEMYyPmyOiefFHZ66338KQB2s= -github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd/go.mod h1:x3OmY2wsA18+Kc3TSV2QpSUewOCiscw2mKpXgZv2kZk= +github.com/lightninglabs/neutrino v0.16.1 h1:5Kz4ToxncEVkpKC6fwUjXKtFKJhuxlG3sBB3MdJTJjs= +github.com/lightninglabs/neutrino v0.16.1/go.mod h1:L+5UAccpUdyM7yDgmQySgixf7xmwBgJtOfs/IP26jCs= github.com/lightninglabs/neutrino/cache v1.1.2 h1:C9DY/DAPaPxbFC+xNNEI/z1SJY9GS3shmlu5hIQ798g= github.com/lightninglabs/neutrino/cache v1.1.2/go.mod h1:XJNcgdOw1LQnanGjw8Vj44CvguYA25IMKjWFZczwZuo= github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display h1:pRdza2wleRN1L2fJXd6ZoQ9ZegVFTAb2bOQfruJPKcY= @@ -1076,8 +1076,8 @@ modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= -pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/lncfg/chain.go b/lncfg/chain.go index 36586ff3a..cbcb9d0ee 100644 --- a/lncfg/chain.go +++ b/lncfg/chain.go @@ -17,6 +17,7 @@ type Chain struct { MainNet bool `long:"mainnet" description:"Use the main network"` TestNet3 bool `long:"testnet" description:"Use the test network"` + TestNet4 bool `long:"testnet4" description:"Use the testnet4 test network"` SimNet bool `long:"simnet" description:"Use the simulation test network"` RegTest bool `long:"regtest" description:"Use the regression test network"` SigNet bool `long:"signet" description:"Use the signet test network"` diff --git a/lncfg/config.go b/lncfg/config.go index 94ca02f46..178ef203b 100644 --- a/lncfg/config.go +++ b/lncfg/config.go @@ -108,6 +108,14 @@ func CleanAndExpandPath(path string) string { // NormalizeNetwork returns the common name of a network type used to create // file paths. This allows differently versioned networks to use the same path. func NormalizeNetwork(network string) string { + // The 4th testnet isn't the "default" yet, so we'll want to explicitly + // point that to a "testnet4" directory. + if network == "testnet4" { + return network + } + + // We want to collapse "testnet3" and "testnet" to the same "testnet" + // directory. if strings.HasPrefix(network, "testnet") { return "testnet" } diff --git a/lnd.go b/lnd.go index 2b46e83c9..e63ddc196 100644 --- a/lnd.go +++ b/lnd.go @@ -194,6 +194,9 @@ func Main(cfg *Config, lisCfg ListenerCfg, implCfg *ImplementationCfg, case cfg.Bitcoin.TestNet3: network = "testnet" + case cfg.Bitcoin.TestNet4: + network = "testnet4" + case cfg.Bitcoin.MainNet: network = "mainnet" diff --git a/lnrpc/lightning.pb.go b/lnrpc/lightning.pb.go index 42ce54284..c2ff05f3e 100644 --- a/lnrpc/lightning.pb.go +++ b/lnrpc/lightning.pb.go @@ -6265,8 +6265,8 @@ type GetInfoResponse struct { SyncedToChain bool `protobuf:"varint,9,opt,name=synced_to_chain,json=syncedToChain,proto3" json:"synced_to_chain,omitempty"` // Whether we consider ourselves synced with the public channel graph. SyncedToGraph bool `protobuf:"varint,18,opt,name=synced_to_graph,json=syncedToGraph,proto3" json:"synced_to_graph,omitempty"` - // Whether the current node is connected to testnet. This field is - // deprecated and the network field should be used instead + // Whether the current node is connected to testnet or testnet4. This field is + // deprecated and the network field should be used instead. // // Deprecated: Marked as deprecated in lightning.proto. Testnet bool `protobuf:"varint,10,opt,name=testnet,proto3" json:"testnet,omitempty"` diff --git a/lnrpc/lightning.proto b/lnrpc/lightning.proto index 2de09da1f..ca40e4b4c 100644 --- a/lnrpc/lightning.proto +++ b/lnrpc/lightning.proto @@ -2008,8 +2008,8 @@ message GetInfoResponse { bool synced_to_graph = 18; /* - Whether the current node is connected to testnet. This field is - deprecated and the network field should be used instead + Whether the current node is connected to testnet or testnet4. This field is + deprecated and the network field should be used instead. */ bool testnet = 10 [deprecated = true]; diff --git a/lnrpc/lightning.swagger.json b/lnrpc/lightning.swagger.json index c1a5ab4b4..69478fc94 100644 --- a/lnrpc/lightning.swagger.json +++ b/lnrpc/lightning.swagger.json @@ -5196,7 +5196,7 @@ }, "testnet": { "type": "boolean", - "title": "Whether the current node is connected to testnet. This field is\ndeprecated and the network field should be used instead" + "description": "Whether the current node is connected to testnet or testnet4. This field is\ndeprecated and the network field should be used instead." }, "chains": { "type": "array", diff --git a/lntest/node/config.go b/lntest/node/config.go index 6cba60941..d71723aac 100644 --- a/lntest/node/config.go +++ b/lntest/node/config.go @@ -222,6 +222,8 @@ func (cfg *BaseNodeConfig) GenArgs() []string { switch cfg.NetParams { case &chaincfg.TestNet3Params: args = append(args, "--bitcoin.testnet") + case &chaincfg.TestNet4Params: + args = append(args, "--bitcoin.testnet4") case &chaincfg.SimNetParams: args = append(args, "--bitcoin.simnet") case &chaincfg.RegressionNetParams: diff --git a/sample-lnd.conf b/sample-lnd.conf index 4b9c68afa..53be66404 100644 --- a/sample-lnd.conf +++ b/sample-lnd.conf @@ -621,6 +621,9 @@ ; Use Bitcoin's test network. ; bitcoin.testnet=false ; +; Use Bitcoin's 4th version test network. +; bitcoin.testnet4=false +; ; Use Bitcoin's simulation test network ; bitcoin.simnet=false diff --git a/server.go b/server.go index ad521cd67..19d836a4e 100644 --- a/server.go +++ b/server.go @@ -2594,6 +2594,12 @@ func (s *server) Start() error { chainreg.BitcoinTestnetGenesis, ) } + if s.cfg.Bitcoin.TestNet4 { + setSeedList( + s.cfg.Bitcoin.DNSSeeds, + chainreg.BitcoinTestnet4Genesis, + ) + } if s.cfg.Bitcoin.SigNet { setSeedList( s.cfg.Bitcoin.DNSSeeds,