Code Monkey home page Code Monkey logo

bdk's Issues

Compact block filter Blockchain backend

This is an overview issue (based on same issue for murmel) for discussion and tracking the addition of a fully functional compact filters Blockchain backend to bdk. Ideally we'll have additional issues and/or PRs for each missing feature to link to this issue and we check off each feature as it's completed.

The below BIP-157/158 protocol features are based on the BIP-157 Client Operation section. Please suggest additions and corrections in the comments.

Missing protocol features for bdk are indicated below with an unchecked box [ ], completed features with a checked box [x].

Terminology

  • peer: bitcoin full node peer
  • block header: bitcoin standard block header
  • filter header: BIP-157 compact block filter header
  • block filter: BIP-157/158 compact block filter

Peer Discovery

    • Allow user to specify peer addresses
    • Receive peer addresses via [addr] messages from connected peers
    • Store new peer addresses
    • If no provided or previously stored peers, find seed peer addresses via DNS

Connect to Peers

    • Allow user to specify number of peers to connect to
    • Allow user to specify minimum number of BIP-157 peers to connect to
    • Connect to peers and request signalling bits via [version] message
    • Keep track of peers signalling service bit NODE_COMPACT_FILTERS
    • Connect to specified number of peers
    • Connect to minimum number of BIP-157 peers

Request Block Headers

    • Request block headers via [getheaders] message to connected peers
    • Request block headers from genesis to most work block, 1 to 2000 blocks per request
    • Optional: Request block headers from stored checkpoint block instead of genesis block

Receive Block Headers

    • Receive block headers [headers] from peers
    • Build chain of block headers from stored and received new block headers
    • Store new block headers and new block header tip
    • Disconnect peers whose longest chain has significantly less work than known tip
    • Request block filter headers from all peers for any new block header received

Request Filter Headers

    • Allow user to specify start block height for block filter sync
    • Request filter headers via [getcfheaders] message to peers
    • Request from start block height to end block hash (1-1000 per request)
    • Request filter headers for the same block from more than one peer
    • Optional: First request filter headers at intervals of 1000 via [getcfcheckpt] message

Receive Filter Headers

    • Receive filter headers [cfheaders] from peers
    • Verify filter headers from multiple peers are the same
    • If any received filter headers for a block are different,
      • request full block and compute correct block filter and filter header
      • ban peers that provided incorrect filter header
    • Build chain of filter headers from stored and received new filter headers
    • Store verified filter headers, at least to depth of 100
    • Request block filter for any new verified filter header
    • Optional: store more than 100 verified filter headers

Request Block Filters

    • Request block filters after all filter headers are received and verified
    • Request block filters from start block via [getcfilters] message to peers
    • Request from start block height to end block hash (1-1000 per request)
    • Optional: Check if filter header is for empty block filter if so skip request
    • Optional: Request different block filters in parallel from multiple peers

Receive Block Filters

    • Receive block filter [cfilter] from peers
    • Verify block filters sequentially, must link to corresponding filter header
    • Ban any peer that sends an invalid block filter
    • Check block filters for relevance
      • Previous output scripts for transaction inputs
      • ScriptPubKey for transaction outputs

Fetch Full Blocks

    • If fetching full blocks, download from random peers
    • Fetch full blocks from peers even if they don’t support compact block filters
    • Fetch full blocks that correspond to relevant block filters

Mobile hardware security

  • Secure enclave key storage and signing
  • Hardware wallet / HWI
  • HSM runtime support like the nShield

This may need to be moved or companion issues created in bdk-jni (and future bdk-ios) repos

Error parsing multisig descriptor

Example:

use magical_bitcoin_wallet::descriptor::ExtendedDescriptor;
use std::str::FromStr;

fn main() {
    let desc_str = "wsh(multi(1,[9d033c9d/48'/1'/0'/2']tpubDEHKJA6XKc6QaRvc5gunJY9T9cst9m1y8o2owqrvUmXK69ZjWySB7hgB6HvFdTp5MamaKYumSGxL49VUiEjWrhDE8N8BympFWDknLBEPG38/0/*,[6bb3d403/48'/1'/0'/2']tpubDDw2d4rKFtn5ECCq4KQ6GTi73YUQt3Wz2gqyv19kLAPJQKKKzNvEESi9v44sG4Fc6DsBuDgo5FQ9ZxbzQfV2X7jRvsBcT7N5s6g57xS4aUM/0/*))";
    ExtendedDescriptor::from_str(&desc_str).unwrap();
}

Output:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Miniscript(Unexpected("multi(3 args) while parsing Miniscript"))', examples/magical.rs:6:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Here is where the error is being created in rust-miniscript. You can see a couple lines above that is where multi should be handled, but it seems there hasn't been a rust-miniscript release since it was added.

Coin control & UTXO blacklisting

Two related privacy features I'd like to see implemented in the future:

  1. per-UTXO coin control during transaction construction
  2. blacklisting of individual UTXO(s) to combat dusting attacks

Integrate with LDK

BDK should be able to provide blockchain and key services for the Lightning Development Kit (LDK). The LDK traits that need to be implemented by BDK are:

  • lightning::chain::keysinterface::KeysInterface
  • lightning::chain::chaininterface::BroadcasterInterface
  • lightning::chain::chaininterface::FeeEstimator
  • lightning::chain::Filter
  • lightning::chain::Confirm
  • lightning::chain::Access
  • lightning::chain::Watch

PSBT workflow and traits

We are currently discussing in rust-bitcoin how to model the PSBT workflow in rust. Bdk seems to be the most advanced rust wallet implementation so far. Do you have any opinion on rust-bitcoin/rust-bitcoin#457 for example? From what I read in the bdk docs I figure that my wallet trait might be too simple and not capturing UTXO selection parameters very well (something I thought to be intrinsic to a certain wallet impl). Your Signer trait also seems more adapted to the real world as it differentiates between signing single inputs and whole transactions at once. Given your experience, do you think unifying the interface for PSBT handling is feasible (so that e.g. new HW wallet crates can be compatible with all PSBT aware rust software)?

Light client library to monitor mempool

Suggestion from @moneyball. Create a library that allows a light client to use the p2p network to monitor the mempool. today, the only way you can do this is with Core, which implies running a fully validating node. however, there is no reason you need to do IBD or validation in order to just monitor the mempool. why would a light client want to monitor the mempool?

  1. self sovereign improved fee estimation
  2. self sovereign watchtower (for LN or various other L2/custody protocols that have been proposed which require monitoring for certain txn and responding)
  3. perhaps certain analytical tools (would be awesome if devs could focus on the analytical tool and utilize BDK to deal with all the details vs. write from scratch)

Test the descriptor module

  • Test the ToWalletDescriptor trait
    • From &str with and without checksum appended
    • From &str with keys from the right/wrong network
    • From the output of the descriptor!() macro

Moved to #193
- [ ] Test the ExtractPolicy trait
- [ ] Simple descriptors like wpkh(), sh(multi())
- [ ] Both with extended and single keys
- [ ] More complicated descriptor that contains timelocks too in a thresh()
- [ ] Mixed timelocks should fail
- [ ] Multiple timelocks of the same type should be correctly merged together

  • Test the get_checksum() function. It should return the same value as Bitcoin Core's getdescriptorinfo

  • Test the descriptor!() macro

    • Ideally at least one of each "type" of operator should be tested (i.e. one modifier, one "leaf_opcode", one "leaf_opcode_value", etc)
    • Test mixing up key types that implement ToDescriptorKey in multi() or thresh()
    • Test that the valid_networks returned is correctly computed based on the keys present in the descriptor
    • Test that the key_maps are correctly merged together
    • Test that the ScriptContext is correctly validated (i.e. passing a type that only impl ToDescriptorKey<Segwitv0> to a pkh() descriptor should throw a compilation error
  • Test the existing descriptor templates, make sure they are expanded to the right descriptors

Eclipse attack protection

Generally need to think about how to prevent eclipse attacks for light clients that sync block headers from peers. Some ideas of strategies that can be borrowed from Bitcoin Core:

  • general core heuristics: feeler connections, new/tried nodes tables, test-before-evict, etc.
  • using ASMAP table information (https://bitcoincore.reviews/16702.html)
  • reverse header lookup strategies and banning peers that give bad headers

Test Compact Block Filters supported backend

Test all the backends with the #[bdk_blockchain_tests] proc macro like we do with electrum in the CI. This could be done while transitioning to GitHub Actions (see #59).

I would use nigiri to have an electrs/esplora local instance, then a btcd node for compact filters.

Currently the CI downloads and runs the full node but that's pretty slow, we could make docker containers with everything preinstalled for it.

A docker image for electrs was added here: 98803b2

Adding outputs to a wallet at runtime

In several of the more cutting edge Bitcoin protocols you end up in a situation where there is a 2-of-2(A,B) where Alice and Bob own the two keys respectively. Later on, one of the parties (let's say Alice) learns the secret key for B through the execution of the protocol. Now Alice owns the output but needs to store and recall the secret key for B and the details of the output.

I was thinking it would be nice for magical to manage this for me. What I think I want is to be able to add some kind of auxiliary descriptors to a wallet. The wallet could store it in its database and treat it like any of its other unspent outputs. Here are some considerations that come to mind:

  1. You would probably want a coin selection policy that spends these higher priority than outputs derived from your main descriptor (because they are lost if you lose database backup).
  2. When doing things like get_balance you're probably going to want to see how much of your balance is derived from the main descriptor and how much is from these transient descriptors. Likely you will want to "sweep" all of these in one go back to the main wallet descriptor.
  3. Sometimes these outputs have a pending tx that may spend from it in the future (e.g. revoked lightning commitment transactions) so the user needs to spend from it right away. Although it should be the application's job to make sure this happens, it would be cool if you could mark the auxiliary descriptor with a block height or time for which it must be spent before.

I was thinking about trying to implement something like this myself but wanted to check if you had an existing vision for this.

Issues using descriptors with checksums

Starting with an empty ~/.magical-bitcoin, it crashes if we provide a descriptor containing a checksum:

$ magic --descriptor "pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)#gn28ywm7" policies
...
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ChecksumMismatch', examples/repl.rs:71:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Furthermore, a checksum for the entire checksummed descriptor is stored in sled, which causes a conflict when we try to provide the same valid descriptor without a checksum.

$ magic --descriptor "pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)" policies
...
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ChecksumMismatch', examples/repl.rs:71:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

If we delete ~/.magical-bitcoin and re-run the last command it will work.

I believe this line should check to see if the descriptor already contains a valid checksum.

Taproot / Schnorr

This is a tracking issue for other issues and PRs related to supporting Taproot in BDK.

Dependencies

Overall rust-bitcoin org tracking project

rust-bitcoin/rust-bitcoin

rust-bitcoin/rust-miniscript

Send to Single Signature TR Address

Create Single Signature TR Descriptor Wallet

Create Multi Signature TR Descriptor Wallet

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.