github.com/ZuluSpl0it/Sia@v1.3.7/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 may 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 desynchronized. 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 // ChildTarget defines the target of any block that would be the child 115 // of the block most recently appended to the consensus set. 116 ChildTarget types.Target 117 118 // MinimumValidChildTimestamp defines the minimum allowed timestamp for 119 // any block that is the child of the block most recently appended to 120 // the consensus set. 121 MinimumValidChildTimestamp types.Timestamp 122 123 // Synced indicates whether or not the ConsensusSet is synced with its 124 // peers. 125 Synced bool 126 127 // TryTransactionSet is an unlocked version of 128 // ConsensusSet.TryTransactionSet. This allows the TryTransactionSet 129 // function to be called by a subscriber during 130 // ProcessConsensusChange. 131 TryTransactionSet func([]types.Transaction) (ConsensusChange, error) 132 } 133 134 // A SiacoinOutputDiff indicates the addition or removal of a SiacoinOutput in 135 // the consensus set. 136 SiacoinOutputDiff struct { 137 Direction DiffDirection 138 ID types.SiacoinOutputID 139 SiacoinOutput types.SiacoinOutput 140 } 141 142 // A FileContractDiff indicates the addition or removal of a FileContract in 143 // the consensus set. 144 FileContractDiff struct { 145 Direction DiffDirection 146 ID types.FileContractID 147 FileContract types.FileContract 148 } 149 150 // A SiafundOutputDiff indicates the addition or removal of a SiafundOutput in 151 // the consensus set. 152 SiafundOutputDiff struct { 153 Direction DiffDirection 154 ID types.SiafundOutputID 155 SiafundOutput types.SiafundOutput 156 } 157 158 // A DelayedSiacoinOutputDiff indicates the introduction of a siacoin output 159 // that cannot be spent until after maturing for 144 blocks. When the output 160 // has matured, a SiacoinOutputDiff will be provided. 161 DelayedSiacoinOutputDiff struct { 162 Direction DiffDirection 163 ID types.SiacoinOutputID 164 SiacoinOutput types.SiacoinOutput 165 MaturityHeight types.BlockHeight 166 } 167 168 // A SiafundPoolDiff contains the value of the siafundPool before the block 169 // was applied, and after the block was applied. When applying the diff, set 170 // siafundPool to 'Adjusted'. When reverting the diff, set siafundPool to 171 // 'Previous'. 172 SiafundPoolDiff struct { 173 Direction DiffDirection 174 Previous types.Currency 175 Adjusted types.Currency 176 } 177 178 // A ConsensusSet accepts blocks and builds an understanding of network 179 // consensus. 180 ConsensusSet interface { 181 // AcceptBlock adds a block to consensus. An error will be returned if the 182 // block is invalid, has been seen before, is an orphan, or doesn't 183 // contribute to the heaviest fork known to the consensus set. If the block 184 // does not become the head of the heaviest known fork but is otherwise 185 // valid, it will be remembered by the consensus set but an error will 186 // still be returned. 187 AcceptBlock(types.Block) error 188 189 // BlockAtHeight returns the block found at the input height, with a 190 // bool to indicate whether that block exists. 191 BlockAtHeight(types.BlockHeight) (types.Block, bool) 192 193 // BlocksByID returns a block found for a given ID and its height, with 194 // a bool to indicate whether that block exists. 195 BlockByID(types.BlockID) (types.Block, types.BlockHeight, bool) 196 197 // ChildTarget returns the target required to extend the current heaviest 198 // fork. This function is typically used by miners looking to extend the 199 // heaviest fork. 200 ChildTarget(types.BlockID) (types.Target, bool) 201 202 // Close will shut down the consensus set, giving the module enough time to 203 // run any required closing routines. 204 Close() error 205 206 // ConsensusSetSubscribe adds a subscriber to the list of subscribers 207 // and gives them every consensus change that has occurred since the 208 // change with the provided id. There are a few special cases, 209 // described by the ConsensusChangeX variables in this package. 210 // A channel can be provided to abort the subscription process. 211 ConsensusSetSubscribe(ConsensusSetSubscriber, ConsensusChangeID, <-chan struct{}) error 212 213 // CurrentBlock returns the latest block in the heaviest known 214 // blockchain. 215 CurrentBlock() types.Block 216 217 // Flush will cause the consensus set to finish all in-progress 218 // routines. 219 Flush() error 220 221 // Height returns the current height of consensus. 222 Height() types.BlockHeight 223 224 // Synced returns true if the consensus set is synced with the network. 225 Synced() bool 226 227 // InCurrentPath returns true if the block id presented is found in the 228 // current path, false otherwise. 229 InCurrentPath(types.BlockID) bool 230 231 // MinimumValidChildTimestamp returns the earliest timestamp that is 232 // valid on the current longest fork according to the consensus set. This is 233 // a required piece of information for the miner, who could otherwise be at 234 // risk of mining invalid blocks. 235 MinimumValidChildTimestamp(types.BlockID) (types.Timestamp, bool) 236 237 // StorageProofSegment returns the segment to be used in the storage proof for 238 // a given file contract. 239 StorageProofSegment(types.FileContractID) (uint64, error) 240 241 // TryTransactionSet checks whether the transaction set would be valid if 242 // it were added in the next block. A consensus change is returned 243 // detailing the diffs that would result from the application of the 244 // transaction. 245 TryTransactionSet([]types.Transaction) (ConsensusChange, error) 246 247 // Unsubscribe removes a subscriber from the list of subscribers, 248 // allowing for garbage collection and rescanning. If the subscriber is 249 // not found in the subscriber database, no action is taken. 250 Unsubscribe(ConsensusSetSubscriber) 251 } 252 ) 253 254 // Append takes to ConsensusChange objects and adds all of their diffs together. 255 // 256 // NOTE: It is possible for diffs to overlap or be inconsistent. This function 257 // should only be used with consecutive or disjoint consensus change objects. 258 func (cc ConsensusChange) Append(cc2 ConsensusChange) ConsensusChange { 259 return ConsensusChange{ 260 RevertedBlocks: append(cc.RevertedBlocks, cc2.RevertedBlocks...), 261 AppliedBlocks: append(cc.AppliedBlocks, cc2.AppliedBlocks...), 262 SiacoinOutputDiffs: append(cc.SiacoinOutputDiffs, cc2.SiacoinOutputDiffs...), 263 FileContractDiffs: append(cc.FileContractDiffs, cc2.FileContractDiffs...), 264 SiafundOutputDiffs: append(cc.SiafundOutputDiffs, cc2.SiafundOutputDiffs...), 265 DelayedSiacoinOutputDiffs: append(cc.DelayedSiacoinOutputDiffs, cc2.DelayedSiacoinOutputDiffs...), 266 } 267 }