Commit graph

4360 commits

Author SHA1 Message Date
Olaoluwa Osuntokun
abec11012e version: bump to v0.26.0-beta for final release
In this commit, we drop the rc1 pre-release suffix, taking the version
from v0.26.0-beta.rc1 to v0.26.0-beta for the final release.
2026-06-18 15:45:55 -07:00
Olaoluwa Osuntokun
9dcdd4814b
Merge pull request #2548 from guggero/netsync-simnet-sync-candidate
Some checks are pending
Build and Test / Build (push) Waiting to run
Build and Test / Unit coverage (push) Waiting to run
Build and Test / Unit race (push) Waiting to run
Build and Test / Unit rpctest (push) Waiting to run
netsync: require block-serving services on regtest/simnet sync peers
2026-06-17 11:10:57 -07:00
Olaoluwa Osuntokun
3b9f0eb4ff
Merge pull request #2551 from ellemouton/ellemouton/rpcclient-submitpackage
rpcclient: add typed SubmitPackage method
2026-06-17 11:09:57 -07:00
Elle Mouton
de3d460e76
rpcclient: add typed SubmitPackage method
Add SubmitPackage / SubmitPackageAsync / FutureSubmitPackageResult,
wrapping the submitpackage RPC the same way TestMempoolAccept wraps
testmempoolaccept: serialize the topologically-sorted package to hex,
issue the btcjson submitpackage command, and decode the response into
btcjson.SubmitPackageResult (which already maps the raw fields to
higher-level types via its UnmarshalJSON).

This keeps the multi-backend RPC layering intact so callers (e.g.
btcwallet's chain.Interface) can invoke a typed method instead of a
RawRequest. submitpackage is a Bitcoin Core RPC (v24+); btcd has no
server handler for it.
2026-06-17 08:59:16 -07:00
Oli
a7e980dd34
netsync: require block-serving services on regtest/simnet sync peers
Commit 26124d275 made every peer a sync candidate on regtest and
simnet so that nodes on non-localhost networks (e.g. Docker bridge
networks) can be synced from. Dropping the address requirement was
the intent, but the change also dropped the service-flag requirement,
so light clients became eligible sync peers.

A light client (e.g. neutrino) advertises a recent best height but
can serve neither headers nor blocks. Electing one as the sync peer
stalls the sync until the stall handler disconnects it, and with
other light client connections present the next one is elected and
stalls again, livelocking the sync indefinitely. This surfaced in
neutrino's sync tests, where a btcd simnet node connected to both a
neutrino instance and other btcd nodes never synced.

Keep accepting any peer address on regtest/simnet, but require the
peer to signal SFNodeNetwork or SFNodeNetworkLimited like on any
other network.
2026-06-17 13:45:43 +02:00
Yong
1966c38453
Merge pull request #2536 from kcalvinalvin/2026-05-30-run-and-fix-broken-integration-tests-1
Some checks failed
Build and Test / Build (push) Has been cancelled
Build and Test / Unit coverage (push) Has been cancelled
Build and Test / Unit race (push) Has been cancelled
Build and Test / Unit rpctest (push) Has been cancelled
.github: actually run the integration tests in the CI
2026-06-04 15:18:53 +08:00
Calvin Kim
f8ce7a7da8 rpctest: scope shared state to the current process
Two pieces of rpctest's global state silently aliased across concurrent
test processes (which is what `go test ./...` does by default, so any
`make unit` that exercises -tags=rpctest hit this):

- btcdExecutablePath compiled to a fixed path /tmp/btcd/rpctest/btcd.
  Two `go build` invocations would race on the same file, occasionally
  yielding a truncated or stale binary and downstream "tls: certificate
  signed by unknown authority" failures when the harness tried to talk
  to the resulting node.

- lastPort started at the same defaultNodePort in every process. The
  bind-test in NextAvailablePort closes the listener before returning,
  so two processes climbing from the same base would frequently hand
  out the same port and one harness would die with "connection refused"
  when btcd failed to bind.

Suffix the executable with a random uint32 and seed lastPort with a
random offset into a 50k-port window so each process climbs through
its own range.
2026-05-30 17:49:55 +09:00
Calvin Kim
bfb36e52e7 netsync: process inv announcements when no syncPeer is set
handleInvMsg early-returned for any inv from a non-syncPeer whenever
sm.current() was false, with the comment that it prevents fetching a
mass of orphans. That guard assumes a syncPeer is already fetching
blocks; when syncPeer is nil, the assumption breaks down and the
early return becomes a deadlock.

The deadlock is reachable whenever two nodes connect at equal heights:
startSync exits without picking a syncPeer (no peer is "higher"), and
nothing later promotes the freshly-mined blocks the peer announces via
inv. The pre-verack disconnect and sync-race regression tests in
integration/sync_race_test.go fail consistently because of this.

Only skip the inv when we actually have a syncPeer. When syncPeer is
nil, fall through and let the normal request path queue the block --
the inv is the only signal that there are blocks to fetch.
2026-05-30 17:25:51 +09:00
Calvin Kim
79752a8880 btcjson: accept null in StringOrArray.UnmarshalJSON
StringOrArray.MarshalJSON emits JSON null for a nil slice (see existing
test "nil slice marshals as null" in TestStringOrArrayMarshalJSON), but
UnmarshalJSON did not have a matching case for null and fell to the
default branch, returning "invalid string_or_array value: <nil>". A
round trip of a nil slice therefore failed.

This bit the rpcclient against btcd's own getblockchaininfo, whose
Warnings field is a StringOrArray that the server leaves as a nil slice
when there are no warnings. Every rpctest integration test that touches
GetBlockChainInfo (TestBIP0009, TestBIP0068AndBIP0112Activation,
TestBIP0113Activation, TestPrune) failed to decode the response.

Handle the nil case explicitly so null decodes back to a nil slice, and
add regression cases for "warnings: null" and an omitted warnings field
to TestGetBlockChainInfoWarnings.
2026-05-30 16:47:18 +09:00
Calvin Kim
221178501c integration: fix p2a_test build under -tags=rpctest
p2a_test.go calls btcutil.NewAddressPayToAnchor, but the
NewAddressPayToAnchor constructor lives in the address/v2 module's
address package. Import that package and call it through there so the
integration package builds when -tags=rpctest is set.
2026-05-30 16:47:18 +09:00
Calvin Kim
61c215ec1a ci: run rpctest integration tests
`make build`, `make unit-cover`, and `make unit-race` all use plain
`go test` without the rpctest build tag, so anything under
//go:build rpctest -- the entire integration/ package outside of
rpctest/, and parts of rpctest/ itself -- is not exercised by CI.
Bugs that only surface under -tags=rpctest can land on master without
detection.

Add a test-rpctest job that runs `make unit` (which sets
-tags=rpctest) so rpctest-tagged tests are part of every push and PR.
2026-05-30 16:47:18 +09:00
Olaoluwa Osuntokun
b3cbf4f80e
Merge pull request #2532 from Roasbeef/release-v0.26-rc1
multi: pin new v2 submodule tags and bump to v0.26.0-beta.rc1
2026-05-14 19:51:29 -07:00
Olaoluwa Osuntokun
fdad1fab1f multi: pin new v2 submodule tags and bump to v0.26.0-beta.rc1
In this commit, we strip all of the local `replace ... => ../...`
directives that were introduced as part of #1825 (the v2 module
restructuring), now that proper tags exist for every freshly carved-out
submodule. Every in-tree go.mod is pinned to the newly published tags:
chainhash/v2.0.0, wire/v2.0.0, chaincfg/v2.0.0, address/v2.0.0,
txscript/v2.0.0, btcutil/v2.0.0, psbt/v2.0.0, and btcec is bumped to
v2.5.0 since it now depends on chainhash/v2 (previously
chaincfg/chainhash).

While here, we also unify the Go toolchain to 1.25 across every
submodule so the workspace resolves a consistent set of language
features.

Finally, we bump the main btcd version to v0.26.0-beta.rc1 in
preparation for the upcoming release candidate.
2026-05-14 19:25:06 -07:00
Olaoluwa Osuntokun
258049c9eb
Merge pull request #1825 from guggero/btcec-v2-no-circular-dep
mod: remove `btcutil` circular dependency with main module
2026-05-14 19:18:54 -07:00
Oliver Gugger
b29ce97350 rpcwebsocket: fi linter complaint about unused functions 2026-05-14 18:05:33 -07:00
Oliver Gugger
9dfa926fff server: fix linter issue 2026-05-14 18:05:33 -07:00
Oliver Gugger
c0cfa06111 multi: update make and CI goals with new packages 2026-05-14 18:05:33 -07:00
Oliver Gugger
dccea8feba multi: use new v2 modules everywhere 2026-05-14 18:05:33 -07:00
Oliver Gugger
c0db6dfa11 psbt: move to top-level module, use v2, remove btcutil dep 2026-05-14 18:01:00 -07:00
Oliver Gugger
e9ec6ec506 btcutil: remove circular dependency, use v2 2026-05-14 18:00:53 -07:00
Oliver Gugger
55a463a35f txscript: turn into own module, use v2 2026-05-14 17:59:25 -07:00
Oliver Gugger
3000c455f8 address: move to top-level module, use v2 2026-05-14 17:56:18 -07:00
Oliver Gugger
bd65d6d6bb chaincfg: add own module, use v2 2026-05-14 17:56:18 -07:00
Oliver Gugger
039baa2520 wire: make own module, use v2 2026-05-14 17:56:18 -07:00
Oliver Gugger
bf8006d8e7 btcec: use new chainhash/v2 module 2026-05-14 17:56:18 -07:00
Oliver Gugger
28c77e7dcf chainhash: move to top-level module, use v2 2026-05-14 17:54:44 -07:00
Olaoluwa Osuntokun
44d51eb043
Merge pull request #2531 from Roasbeef/release-prep-bump-modules
multi: bump in-tree go.mod files to new submodule tags
2026-05-14 17:44:43 -07:00
Olaoluwa Osuntokun
62cc0a6b77 multi: appease go 1.26 vet for non-const format + goroutine Fatalf
In this commit, we fix two go vet errors that go 1.26 now treats as
hard failures during test compilation.

In btcjson/help.go, the final result row of a complex help description
was emitted via fmt.Fprintf with a non-constant format string (the
result text could contain '%' chars). Switch to fmt.Fprint, since
there are no format args here anyway.

In btcec/schnorr/musig2/musig2_test.go, the nonce-registration loop
ran inside a goroutine and called t.Fatalf on failure. Fatalf only
exits the calling goroutine, so the test goroutine would keep running
with stale state. Use t.Errorf + return so the failure is recorded
correctly and the goroutine exits cleanly.
2026-05-14 17:36:51 -07:00
Olaoluwa Osuntokun
1863073cb0 multi: bump Go toolchain to 1.25, build CI with 1.26.3
In this commit, we update every in-tree go.mod to declare go 1.25 and
have CI build with 1.26.3 (Dockerfile uses the golang:1.26-alpine base).
Docs that mention the minimum required Go version are aligned with the
new floor as well.

Fixes #2527, which flagged the README.md / go.mod version mismatch (the
README claimed 1.22 while the root + v2transport go.mod files already
required 1.23.2).
2026-05-14 17:32:02 -07:00
Olaoluwa Osuntokun
e59dfeb949 multi: bump in-tree go.mod files to newly tagged submodule versions
In this commit, we pin every in-tree go.mod to the freshly cut submodule
tags ahead of a btcd point release: btcec/v2.4.0, btcutil/v1.2.0,
btcutil/psbt/v1.2.0, and chaincfg/chainhash/v1.2.0. The btcec bump also
drags secp256k1 up to v4.4.0 (and blake256 to v1.1.0 transitively) for
every module that imports btcec.

v2transport stays at v1.0.1 since no v2transport code changed since the
last tag, but its go.mod is bumped here so the workspace resolves to a
consistent set of internal deps.
2026-05-14 17:02:20 -07:00
Olaoluwa Osuntokun
90540b821e
Merge pull request #2524 from MPins/verifylows
Add VerifyLowS helper function to ECDSA signature
2026-05-14 16:47:38 -07:00
Olaoluwa Osuntokun
c728090e63
Merge pull request #2461 from kcalvinalvin/2025-11-12-fix-android-builds
btcutil, main: fix android builds
2026-05-14 16:31:35 -07:00
Olaoluwa Osuntokun
2c05692401 github: cross-compile android/arm64 in CI
Add a build step to the existing Build job that cross-compiles both the
top-level module and btcutil for GOOS=android GOARCH=arm64.

This catches regressions in the android-specific build path (e.g. the
net_android.go wrapper around anet.InterfaceAddrs) without needing an
emulator or NDK toolchain - android/arm64 builds without cgo.
2026-05-14 16:22:50 -07:00
Olaoluwa Osuntokun
73af4d6f88 btcutil: rename interfaceAddrs to InterfaceAddrs in appengine variant
The previous commit exported the interfaceAddrs helper in net.go but
missed the parallel definition in net_noop.go (build tag: appengine),
which left builds with -tags appengine broken with:

    ./certgen.go:79:16: undefined: InterfaceAddrs

Rename the appengine no-op variant to match, restoring the appengine
build.
2026-05-14 16:22:44 -07:00
Olaoluwa Osuntokun
8bffc8ada8
Merge pull request #2526 from JLSchuler99/rpcclient-httpurl-no-resolve
rpcclient: compute httpURL once at construction time
2026-05-14 16:18:57 -07:00
Calvin Kim
589d7c0ae0 main: use btcutil.InterfaceAddr
We use this as the net.InterfaceAddr is broken from android 11.
2026-05-14 16:16:14 -07:00
Calvin Kim
0f603feffa main: update go.mod and go.sum
We update go.mod and go.sum to point to the local btcutil library.

This commit should be updated later on so that we do it right.
2026-05-14 16:16:14 -07:00
Calvin Kim
c90e88ee23 btcutil: export interfaceAddr 2026-05-14 16:16:14 -07:00
Calvin Kim
153bf6d828 btcutil: use anet instead of net for android builds
Golang's net package has been broken for android since android 11
and the node will not be able to call net.InterfaceAddr() without
root.

For android builds, we use anet so that the btcd node can be used
without root.
2026-05-14 16:16:14 -07:00
Jacob Schuler
807cbce3bf rpcclient: compute httpURL once at construction time
httpURL was being recomputed on every JSON-RPC POST. It went through
ParseAddressString to discriminate Unix sockets from TCP, which
called net.ResolveTCPAddr and triggered a DNS lookup whose result
was thrown away.

Both inputs (config.Host and config.DisableTLS) are immutable after
New, so the URL is constant for the life of the Client. Compute it
once and store it on the Client, mirroring the parsedDialAddr cache
already in newHTTPClient.

The httpURL method now uses HasPrefix and runs exactly once per
Client. Drop its (string, error) signature — with the resolve gone
nothing can fail. Add table coverage for the URL strings, plus a
wiring test that catches refactors of New silently dropping the
assignment to Client.httpURL.
2026-05-14 16:04:31 -07:00
Olaoluwa Osuntokun
56613bb876
Merge pull request #2480 from Aharonee/bugfix/peer_race_condition
server: fix peer add/done race between peerHandler and syncManager
2026-05-14 15:59:07 -07:00
Olaoluwa Osuntokun
f2a24d41d1 server: document peerLifecycle channel buffer sizing
The peerLifecycle channel is sized cfg.MaxPeers*2 because each
peer can emit two lifecycle events (peerAdd followed by peerDone).
Without an inline comment a future reader could "simplify" the
factor to cfg.MaxPeers and tighten back-pressure under normal
connect/disconnect churn, causing peerLifecycleHandler goroutines
to block.
2026-05-12 16:20:56 -07:00
Olaoluwa Osuntokun
e6f589e515 server: gate handleDonePeerMsg on peerAdded, not VerAckReceived
peer.processRemoteVerAckMsg sets verAckReceived=true *before* it
invokes the OnVerAck listener that closes verAckCh. If the peer
disconnects in that window, the peerLifecycleHandler select may
pick Peer.Done() over verAckCh and skip the peerAdd send -- yet
VerAckReceived() still returns true. handleDonePeerMsg would then
call syncManager.DonePeer for a peer that was never NewPeer'd
(sync manager logs a warning and discards).

Add an explicit peerAdded atomic.Bool on serverPeer. Set it in
peerLifecycleHandler after peerAdd has been enqueued. Gate the
syncManager.DonePeer + orphan eviction in handleDonePeerMsg on
peerAdded.Load() so those side effects only fire for peers that
were actually registered.

This tightens the "peerAdd precedes peerDone, or peerAdd is
skipped entirely" invariant from this PR into something explicit
rather than something derived from a flag that races OnVerAck.
2026-05-12 16:20:43 -07:00
Olaoluwa Osuntokun
f1b95f8fd9 server: guard OnVerAck with sync.Once
The prior select/default+close() guard on verAckCh is correct only
under the invariant that OnVerAck is invoked from a single goroutine
(peer.processRemoteVerAckMsg on the input handler). The two steps
are not atomic: any future change that invokes listeners off the
input goroutine would let two concurrent callers both observe
default and panic on double-close.

Replace the guard with sync.Once. This makes the close-once
contract obviously correct rather than correct-by-distant-invariant
and drops the dead "called more than once" log path.
2026-05-12 16:20:15 -07:00
Olaoluwa Osuntokun
aacc9882ca
Merge pull request #2491 from btcsuite/block-fix
wire: reject messages with unconsumed trailing payload bytes
2026-05-12 15:04:56 -07:00
Olaoluwa Osuntokun
d12d39dae1
Merge pull request #2433 from Roasbeef/p2a
multi: recognize new standard P2A output type
2026-05-12 15:04:12 -07:00
Olaoluwa Osuntokun
de921aee28 rpctest: add new e2e test for new P2A behavior
We make sure it'll be accepted into the mempool, and can be spent
without a witness.
2026-05-12 10:56:34 -07:00
Olaoluwa Osuntokun
2682f2c1e3 mempool: add p2a specific policy
P2A is standard if the witness and the sigscript is empty. We make a
smol refactor to be able to write a unit test for the input
standardness.
2026-05-12 10:56:34 -07:00
Olaoluwa Osuntokun
891bcb2db8 txscript: recognize P2A witness program during script execution
In this commit, we modify the execution logic, such that the P2A witness
program doesn't appear as a unknown witness program version. For
execution, we just make sure the script passes.
2026-05-12 10:56:34 -07:00
Olaoluwa Osuntokun
053fb4c1d3 txscript: add tests for new P2A awareness 2026-05-12 10:56:34 -07:00