主页 > 大陆如何下载imtoken > 比特币钱包-btcwallet(五)接收区块,同步本地交易和UTXO

比特币钱包-btcwallet(五)接收区块,同步本地交易和UTXO

大陆如何下载imtoken 2023-03-07 06:46:39

本文介绍钱包如何接收区块链的交易通知并同步交易:

打开钱包或创建钱包后,如果连接的区块链客户端不为空,则会调用SynchronizeRPC接口准备接受请求。

比如OpenWallet的源码

func (s *loaderServer) OpenWallet(ctx context.Context, req *pb.OpenWalletRequest) (
    *pb.OpenWalletResponse, error) {
    // Use an insecure public passphrase when the request's is empty.
    pubPassphrase := req.PublicPassphrase
    if len(pubPassphrase) == 0 {
        pubPassphrase = []byte(wallet.InsecurePubPassphrase)
    }
    wallet, err := s.loader.OpenExistingWallet(pubPassphrase, false)
    if err != nil {
        return nil, translateError(err)
    }
    s.mu.Lock()
    if s.rpcClient != nil {
        // 打开同步RPC的接口。
        wallet.SynchronizeRPC(s.rpcClient)
    }
    s.mu.Unlock()
    return &pb.OpenWalletResponse{}, nil
}

在 SynchronizeRPC 中启动了多个 gorotines。

    go w.handleChainNotifications() // 处理来自区块链的消息,包括区块、交易的变换。
    go w.rescanBatchHandler() //
    go w.rescanProgressHandler()
    go w.rescanRPCHandler() // 

handleChainNotifications中的通知消息分为以下几种:(与本文无关的代码省略比特币钱包区块同步一般多久,只保留对应的分支)

func (w *Wallet) handleChainNotifications() {
    defer w.wg.Done()
    log.Info("Welcome to zhangpeng's btcwallet , rpcClientConnectLoop in SynchronizeRPC, handleChainNotifications")
    chainClient, err := w.requireChainClient()
    if err != nil {
        log.Errorf("handleChainNotifications called without RPC client")
        return
    }
    for {
        select {
        case n, ok := <-chainClient.Notifications():
            if !ok {
                return
            }
            var notificationName string
            var err error
            switch n := n.(type) {
            case chain.ClientConnected:
                // 来自chain的连接请求。
                ...
            case chain.BlockConnected:
                // 区块已经连接的通知。
                ...
                notificationName = "block connected"
            case chain.BlockDisconnected:
                // 区块断开连接的通知
                ...
            case chain.RelevantTx:
                // 区块相关交易的通知。
                err = walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
                    return w.addRelevantTx(tx, n.TxRecord, n.Block)
                })
                notificationName = "relevant transaction"
            case chain.FilteredBlockConnected:
                                // 区块新产生,多个交易
                // Atomically update for the whole block.
                if len(n.RelevantTxs) > 0 {
                    err = walletdb.Update(w.db, func(
                        tx walletdb.ReadWriteTx) error {
                        var err error
                        for _, rec := range n.RelevantTxs {
                            err = w.addRelevantTx(tx, rec,
                                n.Block)
                            if err != nil {
                                return err
                            }
                        }
                        return nil
                    })
                }
                notificationName = "filtered block connected"
            // The following require some database maintenance, but also
            // need to be reported to the wallet's rescan goroutine.
            case *chain.RescanProgress:
                // rescan正在执行中的通知。一般发生在钱包刚刚连接区块链节点的时候
                ... 
            case *chain.RescanFinished:
                // rescan执行完成的通知。
                ...
            }
                ...
        case <-w.quit:
            return
        }
    }
}

生成块时,将发送 FilteredBlockConnected 消息。 我们来看看FilteredBlockConnected的过程。

case chain.FilteredBlockConnected:
                fmt.Println("zp wallet, 消息通知。。。。整个区块")
                // Atomically update for the whole block.
                if len(n.RelevantTxs) > 0 {
                    err = walletdb.Update(w.db, func(
                        tx walletdb.ReadWriteTx) error {
                        var err error
                        for _, rec := range n.RelevantTxs {
                            err = w.addRelevantTx(tx, rec,
                                n.Block)
                            if err != nil {
                                return err
                            }
                        }
                        return nil
                    })
                }
                notificationName = "filtered block connected"

里面的核心方法是addRelevantTx。 我们来看看这个过程:#L275

比特币钱包区块同步一般多久_比特币钱包同步加速_比特币钱包提币要多久

添加相关Tx.png

本文是《比特币步步为营》的第十一篇文章——《btcwallet(5)接收区块,同步本地交易和UTXO》。

有什么问题可以直接留言比特币钱包区块同步一般多久,也可以关注公众号“chainerup”提问留言,或者加入知识星球“chainerup”~