Refactor sync_kyoto_client
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 fmtandcargo clippybefore committing