gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/miningpool/blockmanager.go (about) 1 package pool 2 3 import ( 4 "errors" 5 "time" 6 7 "gitlab.com/SiaPrime/SiaPrime/modules" 8 "gitlab.com/SiaPrime/SiaPrime/types" 9 ) 10 11 var ( 12 errLateHeader = errors.New("header is old, block could not be recovered") 13 ) 14 15 func (p *Pool) blockForWorkWithoutDevFund() types.Block { 16 p.persist.mu.Lock() 17 defer p.persist.mu.Unlock() 18 19 b := p.sourceBlock 20 b.Transactions = p.blockTxns.transactions() 21 22 // Update the timestamp. 23 if b.Timestamp < types.CurrentTimestamp() { 24 b.Timestamp = types.CurrentTimestamp() 25 } 26 27 payoutVal := b.CalculateSubsidy(p.persist.BlockHeight + 1) 28 p.log.Printf("building a new source block, block id is: %s\n", b.ID()) 29 p.log.Printf("miner fees cost: %s", b.CalculateMinerFees().String()) 30 p.log.Printf("# transactions: %d", len(b.Transactions)) 31 p.log.Printf("payout value is: %s", payoutVal.String()) 32 b.MinerPayouts = []types.SiacoinOutput{{ 33 Value: payoutVal, 34 UnlockHash: p.persist.Settings.PoolWallet, 35 }} 36 37 return b 38 } 39 40 func (p *Pool) blockForWorkWithDevFund() types.Block { 41 p.persist.mu.Lock() 42 defer p.persist.mu.Unlock() 43 44 b := p.sourceBlock 45 b.Transactions = p.blockTxns.transactions() 46 47 // Update the timestamp. 48 if b.Timestamp < types.CurrentTimestamp() { 49 b.Timestamp = types.CurrentTimestamp() 50 } 51 52 minerPayoutVal, subsidyPayoutVal := b.CalculateSubsidies(p.persist.BlockHeight + 1) 53 subsidyUnlockHash := types.DevFundUnlockHash 54 if types.BurnAddressBlockHeight != types.BlockHeight(0) && (p.persist.BlockHeight+1) >= types.BurnAddressBlockHeight { 55 subsidyUnlockHash = types.BurnAddressUnlockHash 56 } 57 p.log.Printf("building a new source block, block id is: %s\n", b.ID()) 58 p.log.Printf("miner fees cost: %s", b.CalculateMinerFees().String()) 59 p.log.Printf("# transactions: %d", len(b.Transactions)) 60 p.log.Printf("payout value is: %s", minerPayoutVal.String()) 61 b.MinerPayouts = []types.SiacoinOutput{{ 62 Value: minerPayoutVal, 63 UnlockHash: p.persist.Settings.PoolWallet, 64 }, { 65 Value: subsidyPayoutVal, 66 UnlockHash: subsidyUnlockHash, 67 }} 68 69 return b 70 } 71 72 // blockForWork returns a block that is ready for nonce grinding, including 73 // correct miner payouts. 74 func (p *Pool) blockForWork() types.Block { 75 if types.DevFundEnabled && p.persist.BlockHeight+1 >= types.DevFundInitialBlockHeight { 76 return p.blockForWorkWithDevFund() 77 } 78 return p.blockForWorkWithoutDevFund() 79 } 80 81 // newSourceBlock creates a new source block for the block manager so that new 82 // headers will use the updated source block. 83 func (p *Pool) newSourceBlock() { 84 // To guarantee garbage collection of old blocks, delete all header entries 85 // that have not been reached for the current block. 86 for p.memProgress%(HeaderMemory/BlockMemory) != 0 { 87 delete(p.blockMem, p.headerMem[p.memProgress]) 88 delete(p.arbDataMem, p.headerMem[p.memProgress]) 89 p.memProgress++ 90 if p.memProgress == HeaderMemory { 91 p.memProgress = 0 92 } 93 } 94 95 // Update the source block. 96 block := p.blockForWork() 97 p.saveSync() 98 p.sourceBlock = block 99 p.sourceBlockTime = time.Now() 100 } 101 102 // managedSubmitBlock takes a solved block and submits it to the blockchain. 103 func (p *Pool) managedSubmitBlock(b types.Block) error { 104 p.log.Printf("managedSubmitBlock called on block id: %s, block has %d txs\n", b.ID(), len(b.Transactions)) 105 // Give the block to the consensus set. 106 err := p.cs.AcceptBlock(b) 107 // Add the miner to the blocks list if the only problem is that it's stale. 108 if err == modules.ErrNonExtendingBlock { 109 // p.log.Debugf("Waiting to lock pool\n") 110 p.mu.Lock() 111 p.persist.SetBlocksFound(append(p.persist.GetBlocksFound(), b.ID())) 112 // p.log.Debugf("Unlocking pool\n") 113 p.mu.Unlock() 114 p.log.Println("Mined a stale block - block appears valid but does not extend the blockchain") 115 return err 116 } 117 if err == modules.ErrBlockUnsolved { 118 // p.log.Println("Mined an unsolved block - header submission appears to be incorrect") 119 return err 120 } 121 if err != nil { 122 p.tpool.PurgeTransactionPool() 123 p.log.Println("ERROR: an invalid block was submitted:", err) 124 return err 125 } 126 // p.log.Debugf("Waiting to lock pool\n") 127 p.mu.Lock() 128 defer func() { 129 // p.log.Debugf("Unlocking pool\n") 130 p.mu.Unlock() 131 }() 132 133 // Grab a new address for the miner. Call may fail if the wallet is locked 134 // or if the wallet addresses have been exhausted. 135 p.persist.SetBlocksFound(append(p.persist.GetBlocksFound(), b.ID())) 136 // var uc types.UnlockConditions 137 // uc, err = p.wallet.NextAddress() 138 // if err != nil { 139 // return err 140 // } 141 // p.persist.Address = uc.UnlockHash() 142 return p.saveSync() 143 }