Skip to content

Latest commit

 

History

History
120 lines (94 loc) · 3.64 KB

File metadata and controls

120 lines (94 loc) · 3.64 KB

Server application for providing APIs to a Drivechain frontend.

Dependencies:

  1. just
  2. Go
  3. Rust via rustup
  4. buf

Building and running:

$ just build

# This assumes you're running drivechaind in signet mode.
# A modified version of bitcoin core where the only change
# is 60 second blocktimes. You can also start this with:
# $ docker compose up mainchain
# Or download directly from https://github.com/barebitcoin/bitcoin-patched
#
$ drivechaind \
  -rpcuser=user \
  -rpcpassword=password \
  -server \
  -signet \
  -signetblocktime=60 \
  -signetchallenge=00141f61d57873d70d28bd28b3c9f9d6bf818b5a0d6a \
  -listen

#
# Then, start the bip300301_enforcer
$ ./enforcer/bin/bip300301_enforcer \
  --node-rpc-password=password \
  --node-rpc-user=user \
  --node-rpc-port=38332

# Finally, start the server.
# We're connecting to a public Electrum server, running
# /without/ SSL.
#
# The same Electrum server also powers the mempool instance
# at https://drivechain.ngu-tek.no.
$ ./bin/bitwindowd \
  --electrum.host=drivechain.live:50001 \
  --electrum.no-ssl \
  --bitcoincore.rpcuser=user \
  --bitcoincore.rpcpassword=password \
  --bitcoincore.host=localhost:8332

Architecture

graph TD;
    A[Flutter-based Frontend] -->|Connect/gRPC| B[Go Server];
    B -->|Unspecified Protocol| C[CUSF Enforcer];
    C -->|`invalidateblock` RPC|D;
    B -->|Connect/gRPC via btc-buf proxy, \nZMQ via either raw conn or btc-buf| D[Bitcoin Core Node];
    B -.->|Shells out to| E[bdk-cli];
Loading
  • All wallet functionality is handled by bdk-cli
  • Bitcoin Core is strictly used for reading chain data. Wallet is entirely untouched

Pros:

  • Devs are way more proficient in Go than Rust
  • Availability of Connect for Go. Makes it really simple to spin up a server that supports both gRPC and REST.
  • Availability of strongly typed Bitcoin Core RPC-system through btc-buf

Cons:

  • Shelling out to BDK sounds brittle. Does it contain all the functionality we need? On the other hand, perhaps this is a nice barrier of sorts. BDK is a big beast...
  • Have to pass in the raw descriptor (which contains the xpriv) for each command. Is this OK?

PoC: have been able to generate an address, receive funds to it, sync and print the updated balance. This was on testnet, with a public Electrum node hosted by Blockstream at electrum.blockstream.info:60002. Code for this is in server/main.go.

Further validations that need to happen before we're confident that this works:

  1. Verify we're able to send. This shouldn't be too hard, just haven't gotten around to it.
  2. Verify we're able to connect to our own signet network (this needs to be created!). Will bdk-cli crash if the signet network has other parameters?
  3. Verify we're able to modify btc-buf to run in-memory. Should be easy enough. If not, we'll just use rpcclient from btcd.

Other alternatives considered

Writing this in Rust

Pros:

  • Raw access to BDK

Cons:

  • Rust is really complex
graph TD;
    A[Flutter-based Frontend] -->|Connect/gRPC| B["Server (Rust with BDK)"];
    B -->|JSON-RPC + ZMQ| C[Bitcoin Core Node];
    B -->|Unspecified Protocol| D[CUSF Enforcer];
Loading

Go-based BDK FFI

There's no official FFI bindings for Go. Can use 3rd party Go bindings for Uniffi (which is what powers the BDK FFI). Haven't looked into this. Might not be needed at all.