Skip to content

Feat/btcd nodes#810

Draft
lucasdbr05 wants to merge 9 commits into
bitcoin-dev-project:mainfrom
lucasdbr05:feat/btcd-nodes
Draft

Feat/btcd nodes#810
lucasdbr05 wants to merge 9 commits into
bitcoin-dev-project:mainfrom
lucasdbr05:feat/btcd-nodes

Conversation

@lucasdbr05

Copy link
Copy Markdown

Add btcd node support to Warnet

This PR integrates btcd as a first-class node implementation in Warnet

What's Changed

  • To enable btcd support, we added a new Helm chart under resources/charts/btcd along with a 6-node simnet example network under examples/networks/6_node_btcd.

  • Configuration and Helpers: updated constants.py and added btcd.py to manage implementation constants, detect pod chains/ports, and format credential flags for the btcctl CLI.

  • RPC and Log Routing: modified bitcoin.py to dynamically route RPC calls (using bitcoin-cli or btcctl accordingly) and stream logs from the correct active container.

  • Deployment: updated deploy.py to spin up the appropriate Helm chart based on the node's configured implementation and collect port definitions for the fork observer.

Testing

  • Run the 6-node simnet example:
    warnet deploy examples/networks/6_node_btcd
    
  • Execute the RPC test scenario:
    warnet run resources/scenarios/test_scenarios/btcd_rpc_test.py
    
  • Execute the btcd miner scenario:
     warnet run resources/scenarios/btcd_miner.py
    

lucasdbr05 and others added 9 commits June 29, 2026 13:42
Add a new Helm chart for btcd nodes, including:
- Chart.yaml with chart metadata and dependencies
- values.yaml with default configuration values
- Configmap template for btcd node configuration
- Pod template for running the btcd container
- PVC template for persistent volume claims
- Service template for exposing the btcd node
- ServiceMonitor template for Prometheus scraping
- _helpers.tpl with reusable template helpers
- NOTES.txt with post-install instructions
Add example network configurations for btcd nodes, including:
- 6_node_btcd: a 6-node btcd-only network topology
Extend warnet to support btcd nodes alongside Bitcoin Core
Add a lightweight JSON-RPC client for btcd nodes. It handles HTTPS communication with self-signed TLS certificates. It exposes standard Bitcoin RPC methods alongside btcd-specific extensions.
@pinheadmz

Copy link
Copy Markdown
Contributor

Added a lint commit and rebased on main to run CI

@pinheadmz pinheadmz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really great work, thank you! I'm so glad you're using Warnet for the fountain codes research. The PR is coming along great, I have some feedback. The biggest blocker being the hard coded configuration values in _rpc(). I think everything else should work but could be cleaner. I also left some notes about abstracting the node implementation even further to make it easier for the next one we add ;-)

Also, the scenario and network you added are great but I'd like to see an extra test added to the CI that deploys the network, runs the two scenarios, then sends some commands to assert the expected values (like block height, wallet balance, etc). See the test/ directory for examples, and add your new test to .github/workflows/test.yml

p.s. seeing a ton of these log messages from all the btcd nodes, all with unique port numbers:

2026/06/29 17:59:46 http: TLS handshake error from 10.1.0.1:60012: EOF

*/}}
{{- define "btcd.chainFlag" -}}
{{- if eq .Values.global.chain "regtest" -}}
simnet=1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

b84ca37

btcd doesn't have a regtest? is simnet different in any other way?

restartPolicy: Never

image:
repository: lucasdbr05/btcd

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

b84ca37

Anything special about this image? do the lightning labs / roasbeef / btcsuite repository images on docker hub work as well?

Comment thread src/warnet/bitcoin.py Outdated

cmd = f"kubectl -n {namespace} exec {tank} --container {BITCOINCORE_CONTAINER} -- bitcoin-cli {method} {param_str}"
if is_btcd:
cmd = f"kubectl -n {namespace} exec {tank} --container {container} -- /bin/linux_amd64/btcctl --rpcuser=user --rpcpass=gn0cchi --rpccert=/root/.btcd/rpc.cert --rpcserver=127.0.0.1:18334 --simnet {method} {param_str}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dddc5f0

We can't hard code rpc credentials or network name. We don't have to for Bitcoin Core because bitcoin-cli can read all the configuration details from bitcoin.conf. If btcctl doesn't do something similar we need a different way to get the config from the environment

Comment thread src/warnet/bitcoin.py
log_container = BTCD_CONTAINER
else:
log_container = BITCOINCORE_CONTAINER
logs = pod_log(pod_name, log_container)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dddc5f0

Since we're breaking the seal on alternative implementations here, lets prepare for more. Instead of this kind "if btcd/else bitcoin core" logic everywhere, I think a cleaner approach would be to add details directly to the pod metadata.

For example we already have this line:

    pod_name = tank.metadata.name

why not also add metadata like

   bitcoin_implementation_name = tank.metadata.bitcoin_implementation

where the value is either "btcd", "bitcoincore", or None ?

The same kind of technique could replace _get_node_container()

This way if we ever add more implementations, the labels in their charts will do most of the work

chain: regtest

implementation: btcd
restartPolicy: OnFailure

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c47fbbb

Is this required for btcd? For lnd for example we expect it to crash and restart a few times on deployment while it waits for the bitcoin core node to come up. However, for bitcoin core itself we usually don't want this, because if bitcoin core crashes we don't want it to silently restart, we want to know why it crashed.

"tank": pod.metadata.name,
"namespace": pod.metadata.namespace,
"chain": pod.metadata.labels["chain"],
"implementation": pod.metadata.labels.get("implementation", "bitcoincore"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d1e1d8d

This relates to my comment about adding labels to the chart. We shouldn't need a default here, just add the "bitcoincore" to the bitcoin core chart.

Comment thread src/warnet/control.py
"commander.py",
"test_framework",
"ln_framework",
"btcd_framework",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d1e1d8d

This is ok for now, obviously we do the same thing for LN. But if we keep adding dependencies to the commander it'll get bloated. No need to change anything now but it might be time to start thinking about how to filter out unneeded stuff.

restartPolicy: OnFailure

# TODO: find a better approach to can mine blocks (this address is just for tests)
config: |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f50d525

We have ensure_miner() in the bitcoin test framework. Then in the mining scenario we call that and then getnewaddress

class BtcdRpcTest(Commander):
def set_test_params(self):
self.num_nodes = 1
self.mining_addr = "Sh6VJ4TabWtfBm9kvLWPzj8WGNsMmtyaGF"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f50d525

I assume these coins go nowhere? Or is the btcd wallet deterministic?

Comment thread resources/scenarios/btcd_miner.py Outdated

def _log_status(self, round_num: int, status: dict):
self.log.info(
f"┌─────────────────────────────────────────────────────────────┐"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something just a little bit wrong with the tables in my output

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants