github.com/johnathanhowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/modules/miner/update.go (about) 1 package miner 2 3 import ( 4 "github.com/NebulousLabs/Sia/encoding" 5 "github.com/NebulousLabs/Sia/modules" 6 "github.com/NebulousLabs/Sia/types" 7 ) 8 9 // ProcessConsensusDigest will update the miner's most recent block. 10 func (m *Miner) ProcessConsensusChange(cc modules.ConsensusChange) { 11 m.mu.Lock() 12 defer m.mu.Unlock() 13 14 for _, block := range cc.RevertedBlocks { 15 // Only doing the block check if the height is above zero saves hashing 16 // and saves a nontrivial amount of time during IBD. 17 if m.persist.Height > 0 || block.ID() != types.GenesisID { 18 m.persist.Height-- 19 } else if m.persist.Height != 0 { 20 // Sanity check - if the current block is the genesis block, the 21 // miner height should be set to zero. 22 m.log.Critical("Miner has detected a genesis block, but the height of the miner is set to ", m.persist.Height) 23 m.persist.Height = 0 24 } 25 } 26 for _, block := range cc.AppliedBlocks { 27 // Only doing the block check if the height is above zero saves hashing 28 // and saves a nontrivial amount of time during IBD. 29 if m.persist.Height > 0 || block.ID() != types.GenesisID { 30 m.persist.Height++ 31 } else if m.persist.Height != 0 { 32 // Sanity check - if the current block is the genesis block, the 33 // miner height should be set to zero. 34 m.log.Critical("Miner has detected a genesis block, but the height of the miner is set to ", m.persist.Height) 35 m.persist.Height = 0 36 } 37 } 38 // Sanity check - if the most recent block in the miner is the same as the 39 // most recent block in the consensus set, then the height of the consensus 40 // set and the height of the miner should be the same. 41 lastID := cc.AppliedBlocks[len(cc.AppliedBlocks)-1].ID() 42 if lastID == m.cs.CurrentBlock().ID() { 43 if m.persist.Height != m.cs.Height() { 44 m.log.Critical("Miner has a height mismatch: expecting ", m.cs.Height(), " but got ", m.persist.Height, ". Recent update had ", len(cc.RevertedBlocks), " reverted blocks, and ", len(cc.AppliedBlocks), " applied blocks.") 45 m.persist.Height = m.cs.Height() 46 } 47 } 48 49 // Update the unsolved block. 50 var exists1, exists2 bool 51 m.persist.UnsolvedBlock.ParentID = lastID 52 m.persist.Target, exists1 = m.cs.ChildTarget(m.persist.UnsolvedBlock.ParentID) 53 m.persist.UnsolvedBlock.Timestamp, exists2 = m.cs.MinimumValidChildTimestamp(m.persist.UnsolvedBlock.ParentID) 54 if !exists1 { 55 m.log.Critical("miner was unable to find parent id of an unsolved block in the consensus set") 56 } 57 if !exists2 { 58 m.log.Critical("miner was unable to find child timestamp of an unsovled block in the consensus set") 59 } 60 61 // There is a new parent block, the source block should be updated to keep 62 // the stale rate as low as possible. 63 m.newSourceBlock() 64 m.persist.RecentChange = cc.ID 65 err := m.save() 66 if err != nil { 67 m.log.Println(err) 68 } 69 } 70 71 // ReceiveUpdatedUnconfirmedTransactions will replace the current unconfirmed 72 // set of transactions with the input transactions. 73 func (m *Miner) ReceiveUpdatedUnconfirmedTransactions(unconfirmedTransactions []types.Transaction, _ modules.ConsensusChange) { 74 m.mu.Lock() 75 defer m.mu.Unlock() 76 77 // Edge case - if there are no transactions, set the block's transactions 78 // to nil and return. 79 if len(unconfirmedTransactions) == 0 { 80 m.persist.UnsolvedBlock.Transactions = nil 81 return 82 } 83 84 // Add transactions to the block until the block size limit is reached. 85 // Transactions are assumed to be in a sensible order. 86 var i int 87 remainingSize := int(types.BlockSizeLimit - 5e3) 88 for i = range unconfirmedTransactions { 89 remainingSize -= len(encoding.Marshal(unconfirmedTransactions[i])) 90 if remainingSize < 0 { 91 break 92 } 93 } 94 m.persist.UnsolvedBlock.Transactions = unconfirmedTransactions[:i+1] 95 }