bdk-cli icon indicating copy to clipboard operation
bdk-cli copied to clipboard

Refactor sync_kyoto_client

Open Mshehu5 opened this issue 3 weeks ago • 1 comments

Description

This PR addresses issues encountered while implementing persistence for Payjoin specifically around the BlockchainClient being consumed rather than borrowed. While working on persistence I ran into problems while working on resume command which needs a blockchain client to resume states such as monitor_payjoin_proposal (receiver) and process_payjoin_proposal (sender) Because BlockchainClient is consumed the current design effectively requires two separate clients to resume sender and receiver states. I initially considered splitting the command into resume_send and resume_receive but this does not fully solve the issue. In particular the sender’s process_payjoin_proposal may call broadcast_transaction and potentially broadcast multiple transactions for persisted send entries stored in the database which still requires reusable access to the client.

This consumption issue was previously mentioned in #200 and is also noted in a comment at the top of monitor_payjoin_proposal. It prevents the function from being able to resync multiple times and reliably detect when a transaction appears in the mempool. The root cause is that the Kyoto client Box<LightClient> is destructured and spawned into other tasks when passed through sync_kyoto_client making it unusable afterward.

What this PR changes This PR fixes the issue by refactoring sync_kyoto_client

  • The logic responsible for running the Kyoto node and logger is moved into new_blockchain_client.

  • Instead of returning a Box<lightClient> the function now returns a KyotoClientHandle. Previously the boxed client was consumed when destructured inside sync_kyoto_client, preventing reuse. With the new design sync_kyoto_client takes &mut KyotoClientHandle, allowing the client to be Refrenced which can be used syncing and broadcasting transactions without consumption

  • Additionally monitor_payjoin_proposal is refactored to support resyncing demonstrating that the Kyoto client refactor successfully resolves the original limitations

Notes to the reviewers

After refactor I tested the kyoto client on regtest (Cause I do not have access to a signet) I had to set a trusted peer in the code to connect with a cbf count of 1 this worked and I also made transaction using the steps below: N.B Payjoin was also tested for the monitor_payjoin_proposal refactor using steps in project readme

bitcoin.conf 

regtest=1
server=1
rpcuser=user
rpcpassword=password
rpcallowip=127.0.0.1
blockfilterindex=1
listen=1
fallbackfee=0.001

[regtest]
bind=127.0.0.1
port=18444
peerblockfilters=1

Step 1: Create transaction

PSBT=$(cargo run --features cbf,sqlite -- \
  --network $NETWORK \
  wallet \
  --wallet sender_wallet \
  --ext-descriptor "$SENDER_EXT_DESC" \
  --int-descriptor "$SENDER_INT_DESC" \
  --database-type $DATABASE_TYPE \
  create_tx --to $RECEIVER_ADDR:50000 --fee_rate 1.0 | jq -r '.psbt')

Step 2: Sign transaction

SIGNED_PSBT=$(cargo run --features cbf,sqlite -- \
  --network $NETWORK \
  wallet \
  --wallet sender_wallet \
  --ext-descriptor "$SENDER_EXT_DESC" \
  --int-descriptor "$SENDER_INT_DESC" \
  --database-type $DATABASE_TYPE \
  sign "$PSBT" | jq -r '.psbt')

Step 3: Broadcast transaction

cargo run --features cbf,sqlite -- \
  --network $NETWORK \
  wallet \
  --wallet sender_wallet \
  --ext-descriptor "$SENDER_EXT_DESC" \
  --int-descriptor "$SENDER_INT_DESC" \
  --database-type $DATABASE_TYPE \
  --client-type $CLIENT_TYPE \
  --cbf-peer $CBF_PEER \
  --cbf-conn-count $CBF_CONN_COUNT \
  broadcast --psbt "$SIGNED_PSBT"

Mine a block to confirm bitcoin-cli -regtest generatetoaddress 1 $(bitcoin-cli -regtest getnewaddress)

Checking Transaction Status After broadcasting, wait a moment and sync your wallet: Sync wallet

cargo run --features cbf,sqlite -- \
  --network $NETWORK \
  wallet \
  --wallet sender_wallet \
  --ext-descriptor "$SENDER_EXT_DESC" \
  --int-descriptor "$SENDER_INT_DESC" \
  --database-type $DATABASE_TYPE \
  --client-type $CLIENT_TYPE \
  --cbf-peer $CBF_PEER \
  --cbf-conn-count $CBF_CONN_COUNT \
  sync

Check balance

cargo run --features cbf,sqlite -- \
  --network $NETWORK \
  wallet \
  --wallet sender_wallet \
  --ext-descriptor "$SENDER_EXT_DESC" \
  --int-descriptor "$SENDER_INT_DESC" \
  --database-type $DATABASE_TYPE \
  balance

List recent transactions

cargo run --features cbf,sqlite -- \
  --network $NETWORK \
  wallet \
  --wallet sender_wallet \
  --ext-descriptor "$SENDER_EXT_DESC" \
  --int-descriptor "$SENDER_INT_DESC" \
  --database-type $DATABASE_TYPE \
  transactions

Checklists

All Submissions:

  • [x] I've signed all my commits
  • [x] I followed the contribution guidelines
  • [x] I ran cargo fmt and cargo clippy before committing

Mshehu5 avatar Dec 21 '25 15:12 Mshehu5