cloudhead / nakamoto

Privacy-preserving Bitcoin light-client implementation in Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Track transaction submission status

cloudhead opened this issue · comments

One of the most important functions of a light client is to submit transactions to the network and track their status.

The status of a transaction can be represented with the following enum:

enum TransactionStatus {
  /// The transaction was sent to one or more peers on the network, and is unconfirmed.
  Pending {
    /// Number of announcements of this transaction from other peers.
    announcements: usize
  },
  /// The transaction was included in a block.
  Confirmed {
    /// Height of the block.
    height: Height,
    /// Hash of the block.
    block: BlockHash
  },
  /// The transaction is not likely to confirm, as another transaction has spent its output.
  Stale { replaced_by: TxId }
}

When a transaction is sent to a peer, the status starts as Pending.

There are then a few ways that a wallet can track transaction status with the client:

(a) By scanning cfilters, the wallet can check whether a tx was included in a block (confirmed)
(b) By listening for transaction announcements which include the sent transaction, the wallet can gain confidence that the tx will soon be included in a block, since other nodes consider it valid. The status is still pending, but it is more likely to be confirmed.
(c) By sending a getdata message to random peers, requesting the tx. This could be useful when re-connecting to the network or when the client is restarting and may have missed some messages, and we don't want to wait for the next block to be mined. Note that this only returns txs still in the mempool.

For (b) to work, I believe we will have to set relay: true in our version message, but this means we will receive all transactions, which is a significant amount of bandwidth. This needs to be further researched.

The most reliable method is of course (a) and that's what should be made possible first if it isn't already.

In terms of APIs, we could imagine a Handle::submit_transaction(tx: Transaction, chan::Receiver<TransactionStatus>) function. The client can then send transaction updates over the channel to the wallet.

Most of the logic for transaction tracking should be in the Client, not the protocol.

Closed by #43