/
server_mining.go
82 lines (65 loc) · 1.84 KB
/
server_mining.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package server
import (
"time"
"github.com/michain/dotcoin/chain"
"github.com/michain/dotcoin/protocol"
"github.com/michain/dotcoin/logx"
)
const(
MinimumTxInNewBlock = 1
ZeroTxInNewBlock = 0
)
func (s *Server) LoopMining(){
for{
runMining(s)
time.Sleep(10 * time.Second)
}
}
// RunMining run mine block with mempool
func runMining(s *Server) (*chain.Block, error){
var newBlock *chain.Block
minimumTxCount := MinimumTxInNewBlock
if s.Config.EnabledEmptyTxInNewBlock{
minimumTxCount = ZeroTxInNewBlock
}
if s.TXMemPool.Count() >= minimumTxCount && len(s.minerAddress) > 0 {
var txs []*chain.Transaction
//reward miningAddress in this node
cbTx := chain.NewCoinbaseTX(s.minerAddress, "", coinbaseReward)
txs = append(txs, cbTx)
for _, tx := range s.TXMemPool.TxDescs() {
if s.BlockChain.VerifyTransaction(tx) {
txs = append(txs, tx)
}
}
if minimumTxCount != ZeroTxInNewBlock && len(txs) == 0 {
//TODO log err info
return nil, ErrorAllTXInvalid
}
//rebuild utxo set
isSuccess := false
newBlock, isSuccess = s.BlockChain.MineBlock(txs)
if !isSuccess{
logx.Warnf("MineBlock failde")
}else {
s.BlockChain.GetUTXOSet().Rebuild()
logx.Info("MineBlock Success", " hash: ", newBlock.GetHash().String(), " reward: ", coinbaseReward, " txs: ", len(newBlock.Transactions))
for _, tx := range txs {
if !tx.IsCoinBase() {
s.TXMemPool.RemoveTransaction(tx)
s.TXMemPool.RemoveOrphan(tx)
}
}
// Broadcast inv message to other node
hash := newBlock.GetHash()
inv := protocol.NewInvInfo(protocol.InvTypeBlock, *hash)
msgSend := protocol.NewMsgInv()
msgSend.AddInvInfo(inv)
s.Peer.BroadcastMessage(msgSend)
logx.Debugf("Server Mining Broadcast block [%v] inv message", hash.String())
}
}else{
logx.Tracef("MineBlock failde: no tx to mine")
}
return newBlock, nil
}