Transaction 交換
每個客戶端都會廣播本地生成的Transaction,並轉給來自其它節點的Transaction,本文主要描述Transaction之間的交換與流轉過程。
大家也可以閱讀以下文章,來理解Transaction是如何被確定是合法的
https://en.bitcoin.it/wiki/Protocol_rules#.22tx.22_messages
錢包發送交易
客戶端定期調用main.cpp中的 SendMessages()函數,此函數中又調用 ResendWalletTransactions來發送本地生成的transactions。
在這裡他會檢查看最近以來是否有一個新的block,如果有,並且本地的transaction還不在block中,那麼交易會被發送到所以連接上的節點,這個檢查只會每30分鐘做一次。
只有當時間戳早於當前新接收到的block 5分鐘以上,transaction才會被再次廣播出去。發送順序將會是越老的交易,越先被發送。
定時廣播
客戶端定期調用main.cpp中的 SendMessages()函數,這個函數還會決定是否一個消息會被發送給其它節點。
對於每個消息處理流程中,會有一個被選為trickle node的節點,這個節點是被選出來,只用來接收addr消息。
客戶端隨機抽取1/4的交易數據來發送,除非遠端節點是trickle node,trickle node會接收所有的transactions,這裡看起來是很奇怪,不過的確是這樣。如果一個節點只接收1/4(而不是所有的數據),同時這1/4數據中,代碼實現時,也剔除了所有來自本地錢包的交易數據的發送,注釋上標明這是為了增加隱私。
轉發消息
如果一個客戶端收到一個tx的交易消息,它被稱為RelayMessage,也叫RelayInventory,也會放入一個即將發送給其它節點的消息池子中去。
一些關鍵性代碼說明:
1.wallet.cpp中的CWallet::ResendWalletTransactions
2.pnodeTrickle = [GetRand(vNodesCopy.size())];
SendMessages(pnode, pnode == pnodeTrickle);
代碼在net.cpp中ThreadMessageHandler2()
3.main.cpp的SendMessages()中的
if (fSendTrickle)
4. main.cpp的SendMessages()中的
bool fTrickleWait = ((hashRand & 3) != 0)
5.main.cpp的SendMessages()中的
// trickle out tx inv to protect privacy
if (inv.type == MSG_TX && !fSendTrickle)
{
6.main.cpp的SendMessages()中的
// always trickle our own transactions
if (!fTrickleWait)
{
CWalletTx wtx;
if (GetTransaction(inv.hash, wtx))
if (wtx.fFromMe)
fTrickleWait = true;
}
7.net.h中的RelayMessage 和 RelayInventory
(待續)