github.com/johnathanhowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/modules/consensus.go (about) 1 package modules 2 3 import ( 4 "errors" 5 6 "github.com/NebulousLabs/Sia/crypto" 7 "github.com/NebulousLabs/Sia/types" 8 ) 9 10 const ( 11 // ConsensusDir is the name of the directory used for all of the consensus 12 // persistence files. 13 ConsensusDir = "consensus" 14 15 // DiffApply indicates that a diff is being applied to the consensus set. 16 DiffApply DiffDirection = true 17 18 // DiffRevert indicates that a diff is being reverted from the consensus 19 // set. 20 DiffRevert DiffDirection = false 21 ) 22 23 var ( 24 // ConsensusChangeBeginning is a special consensus change id that tells the 25 // consensus set to provide all consensus changes starting from the very 26 // first diff, which includes the genesis block diff. 27 ConsensusChangeBeginning = ConsensusChangeID{} 28 29 // ConsensusChangeRecent is a special consensus change id that tells the 30 // consensus set to provide the most recent consensus change, instead of 31 // starting from a specific value (which many not be known to the caller). 32 ConsensusChangeRecent = ConsensusChangeID{1} 33 34 // ErrBlockKnown is an error indicating that a block is already in the 35 // database. 36 ErrBlockKnown = errors.New("block already present in database") 37 38 // ErrBlockUnsolved indicates that a block did not meet the required POW 39 // target. 40 ErrBlockUnsolved = errors.New("block does not meet target") 41 42 // ErrInvalidConsensusChangeID indicates that ConsensusSetPersistSubscribe 43 // was called with a consensus change id that is not recognized. Most 44 // commonly, this means that the consensus set was deleted or replaced and 45 // now the module attempting the subscription has desynchonized. This error 46 // should be handled by the module, and not reported to the user. 47 ErrInvalidConsensusChangeID = errors.New("consensus subscription has invalid id - files are inconsistent") 48 49 // ErrNonExtendingBlock indicates that a block is valid but does not result 50 // in a fork that is the heaviest known fork - the consensus set has not 51 // changed as a result of seeing the block. 52 ErrNonExtendingBlock = errors.New("block does not extend the longest fork") 53 ) 54 55 type ( 56 // ConsensusChangeID is the id of a consensus change. 57 ConsensusChangeID crypto.Hash 58 59 // A DiffDirection indicates the "direction" of a diff, either applied or 60 // reverted. A bool is used to restrict the value to these two possibilities. 61 DiffDirection bool 62 63 // A ConsensusSetSubscriber is an object that receives updates to the consensus 64 // set every time there is a change in consensus. 65 ConsensusSetSubscriber interface { 66 // ProcessConsensusChange sends a consensus update to a module through 67 // a function call. Updates will always be sent in the correct order. 68 // There may not be any reverted blocks, but there will always be 69 // applied blocks. 70 ProcessConsensusChange(ConsensusChange) 71 } 72 73 // A ConsensusChange enumerates a set of changes that occurred to the consensus set. 74 ConsensusChange struct { 75 // ID is a unique id for the consensus change derived from the reverted 76 // and applied blocks. 77 ID ConsensusChangeID 78 79 // RevertedBlocks is the list of blocks that were reverted by the change. 80 // The reverted blocks were always all reverted before the applied blocks 81 // were applied. The revered blocks are presented in the order that they 82 // were reverted. 83 RevertedBlocks []types.Block 84 85 // AppliedBlocks is the list of blocks that were applied by the change. The 86 // applied blocks are always all applied after all the reverted blocks were 87 // reverted. The applied blocks are presented in the order that they were 88 // applied. 89 AppliedBlocks []types.Block 90 91 // SiacoinOutputDiffs contains the set of siacoin diffs that were applied 92 // to the consensus set in the recent change. The direction for the set of 93 // diffs is 'DiffApply'. 94 SiacoinOutputDiffs []SiacoinOutputDiff 95 96 // FileContractDiffs contains the set of file contract diffs that were 97 // applied to the consensus set in the recent change. The direction for the 98 // set of diffs is 'DiffApply'. 99 FileContractDiffs []FileContractDiff 100 101 // SiafundOutputDiffs contains the set of siafund diffs that were applied 102 // to the consensus set in the recent change. The direction for the set of 103 // diffs is 'DiffApply'. 104 SiafundOutputDiffs []SiafundOutputDiff 105 106 // DelayedSiacoinOutputDiffs contains the set of delayed siacoin output 107 // diffs that were applied to the consensus set in the recent change. 108 DelayedSiacoinOutputDiffs []DelayedSiacoinOutputDiff 109 110 // SiafundPoolDiffs are the siafund pool diffs that were applied to the 111 // consensus set in the recent change. 112 SiafundPoolDiffs []SiafundPoolDiff 113 } 114 115 // A SiacoinOutputDiff indicates the addition or removal of a SiacoinOutput in 116 // the consensus set. 117 SiacoinOutputDiff struct { 118 Direction DiffDirection 119 ID types.SiacoinOutputID 120 SiacoinOutput types.SiacoinOutput 121 } 122 123 // A FileContractDiff indicates the addition or removal of a FileContract in 124 // the consensus set. 125 FileContractDiff struct { 126 Direction DiffDirection 127 ID types.FileContractID 128 FileContract types.FileContract 129 } 130 131 // A SiafundOutputDiff indicates the addition or removal of a SiafundOutput in 132 // the consensus set. 133 SiafundOutputDiff struct { 134 Direction DiffDirection 135 ID types.SiafundOutputID 136 SiafundOutput types.SiafundOutput 137 } 138 139 // A DelayedSiacoinOutputDiff indicates the introduction of a siacoin output 140 // that cannot be spent until after maturing for 144 blocks. When the output 141 // has matured, a SiacoinOutputDiff will be provided. 142 DelayedSiacoinOutputDiff struct { 143 Direction DiffDirection 144 ID types.SiacoinOutputID 145 SiacoinOutput types.SiacoinOutput 146 MaturityHeight types.BlockHeight 147 } 148 149 // A SiafundPoolDiff contains the value of the siafundPool before the block 150 // was applied, and after the block was applied. When applying the diff, set 151 // siafundPool to 'Adjusted'. When reverting the diff, set siafundPool to 152 // 'Previous'. 153 SiafundPoolDiff struct { 154 Direction DiffDirection 155 Previous types.Currency 156 Adjusted types.Currency 157 } 158 159 // A ConsensusSet accepts blocks and builds an understanding of network 160 // consensus. 161 ConsensusSet interface { 162 // AcceptBlock adds a block to consensus. An error will be returned if the 163 // block is invalid, has been seen before, is an orphan, or doesn't 164 // contribute to the heaviest fork known to the consensus set. If the block 165 // does not become the head of the heaviest known fork but is otherwise 166 // valid, it will be remembered by the consensus set but an error will 167 // still be returned. 168 AcceptBlock(types.Block) error 169 170 // BlockAtHeight returns the block found at the input height, with a 171 // bool to indicate whether that block exists. 172 BlockAtHeight(types.BlockHeight) (types.Block, bool) 173 174 // ChildTarget returns the target required to extend the current heaviest 175 // fork. This function is typically used by miners looking to extend the 176 // heaviest fork. 177 ChildTarget(types.BlockID) (types.Target, bool) 178 179 // Close will shut down the consensus set, giving the module enough time to 180 // run any required closing routines. 181 Close() error 182 183 // ConsensusSetSubscribe adds a subscriber to the list of subscribers, 184 // and gives them every consensus change that has occurred since the 185 // change with the provided id. There are a few special cases, 186 // described by the ConsensusChangeX variables in this package. 187 ConsensusSetSubscribe(ConsensusSetSubscriber, ConsensusChangeID) error 188 189 // CurrentBlock returns the latest block in the heaviest known 190 // blockchain. 191 CurrentBlock() types.Block 192 193 // Height returns the current height of consensus. 194 Height() types.BlockHeight 195 196 // Synced returns true if the consensus set is synced with the network. 197 Synced() bool 198 199 // InCurrentPath returns true if the block id presented is found in the 200 // current path, false otherwise. 201 InCurrentPath(types.BlockID) bool 202 203 // MinimumValidChildTimestamp returns the earliest timestamp that is 204 // valid on the current longest fork according to the consensus set. This is 205 // a required piece of information for the miner, who could otherwise be at 206 // risk of mining invalid blocks. 207 MinimumValidChildTimestamp(types.BlockID) (types.Timestamp, bool) 208 209 // StorageProofSegment returns the segment to be used in the storage proof for 210 // a given file contract. 211 StorageProofSegment(types.FileContractID) (uint64, error) 212 213 // TryTransactionSet checks whether the transaction set would be valid if 214 // it were added in the next block. A consensus change is returned 215 // detailing the diffs that would result from the application of the 216 // transaction. 217 TryTransactionSet([]types.Transaction) (ConsensusChange, error) 218 219 // Unsubscribe removes a subscriber from the list of subscribers, 220 // allowing for garbage collection and rescanning. If the subscriber is 221 // not found in the subscriber database, no action is taken. 222 Unsubscribe(ConsensusSetSubscriber) 223 } 224 ) 225 226 // Append takes to ConsensusChange objects and adds all of their diffs together. 227 // 228 // NOTE: It is possible for diffs to overlap or be inconsistent. This function 229 // should only be used with consecutive or disjoint consensus change objects. 230 func (cc ConsensusChange) Append(cc2 ConsensusChange) ConsensusChange { 231 return ConsensusChange{ 232 RevertedBlocks: append(cc.RevertedBlocks, cc2.RevertedBlocks...), 233 AppliedBlocks: append(cc.AppliedBlocks, cc2.AppliedBlocks...), 234 SiacoinOutputDiffs: append(cc.SiacoinOutputDiffs, cc2.SiacoinOutputDiffs...), 235 FileContractDiffs: append(cc.FileContractDiffs, cc2.FileContractDiffs...), 236 SiafundOutputDiffs: append(cc.SiafundOutputDiffs, cc2.SiafundOutputDiffs...), 237 DelayedSiacoinOutputDiffs: append(cc.DelayedSiacoinOutputDiffs, cc2.DelayedSiacoinOutputDiffs...), 238 } 239 }