主页 > 大陆如何下载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”~