github.com/btcsuite/btcd@v0.24.0/blockchain/blockindex.go (about) 1 // Copyright (c) 2015-2017 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package blockchain 6 7 import ( 8 "math/big" 9 "sort" 10 "sync" 11 "time" 12 13 "github.com/btcsuite/btcd/chaincfg" 14 "github.com/btcsuite/btcd/chaincfg/chainhash" 15 "github.com/btcsuite/btcd/database" 16 "github.com/btcsuite/btcd/wire" 17 ) 18 19 // blockStatus is a bit field representing the validation state of the block. 20 type blockStatus byte 21 22 const ( 23 // statusDataStored indicates that the block's payload is stored on disk. 24 statusDataStored blockStatus = 1 << iota 25 26 // statusValid indicates that the block has been fully validated. 27 statusValid 28 29 // statusValidateFailed indicates that the block has failed validation. 30 statusValidateFailed 31 32 // statusInvalidAncestor indicates that one of the block's ancestors has 33 // has failed validation, thus the block is also invalid. 34 statusInvalidAncestor 35 36 // statusNone indicates that the block has no validation state flags set. 37 // 38 // NOTE: This must be defined last in order to avoid influencing iota. 39 statusNone blockStatus = 0 40 ) 41 42 // HaveData returns whether the full block data is stored in the database. This 43 // will return false for a block node where only the header is downloaded or 44 // kept. 45 func (status blockStatus) HaveData() bool { 46 return status&statusDataStored != 0 47 } 48 49 // KnownValid returns whether the block is known to be valid. This will return 50 // false for a valid block that has not been fully validated yet. 51 func (status blockStatus) KnownValid() bool { 52 return status&statusValid != 0 53 } 54 55 // KnownInvalid returns whether the block is known to be invalid. This may be 56 // because the block itself failed validation or any of its ancestors is 57 // invalid. This will return false for invalid blocks that have not been proven 58 // invalid yet. 59 func (status blockStatus) KnownInvalid() bool { 60 return status&(statusValidateFailed|statusInvalidAncestor) != 0 61 } 62 63 // blockNode represents a block within the block chain and is primarily used to 64 // aid in selecting the best chain to be the main chain. The main chain is 65 // stored into the block database. 66 type blockNode struct { 67 // NOTE: Additions, deletions, or modifications to the order of the 68 // definitions in this struct should not be changed without considering 69 // how it affects alignment on 64-bit platforms. The current order is 70 // specifically crafted to result in minimal padding. There will be 71 // hundreds of thousands of these in memory, so a few extra bytes of 72 // padding adds up. 73 74 // parent is the parent block for this node. 75 parent *blockNode 76 77 // ancestor is a block that is more than one block back from this node. 78 ancestor *blockNode 79 80 // hash is the double sha 256 of the block. 81 hash chainhash.Hash 82 83 // workSum is the total amount of work in the chain up to and including 84 // this node. 85 workSum *big.Int 86 87 // height is the position in the block chain. 88 height int32 89 90 // Some fields from block headers to aid in best chain selection and 91 // reconstructing headers from memory. These must be treated as 92 // immutable and are intentionally ordered to avoid padding on 64-bit 93 // platforms. 94 version int32 95 bits uint32 96 nonce uint32 97 timestamp int64 98 merkleRoot chainhash.Hash 99 100 // status is a bitfield representing the validation state of the block. The 101 // status field, unlike the other fields, may be written to and so should 102 // only be accessed using the concurrent-safe NodeStatus method on 103 // blockIndex once the node has been added to the global index. 104 status blockStatus 105 } 106 107 // initBlockNode initializes a block node from the given header and parent node, 108 // calculating the height and workSum from the respective fields on the parent. 109 // This function is NOT safe for concurrent access. It must only be called when 110 // initially creating a node. 111 func initBlockNode(node *blockNode, blockHeader *wire.BlockHeader, parent *blockNode) { 112 *node = blockNode{ 113 hash: blockHeader.BlockHash(), 114 workSum: CalcWork(blockHeader.Bits), 115 version: blockHeader.Version, 116 bits: blockHeader.Bits, 117 nonce: blockHeader.Nonce, 118 timestamp: blockHeader.Timestamp.Unix(), 119 merkleRoot: blockHeader.MerkleRoot, 120 } 121 if parent != nil { 122 node.parent = parent 123 node.height = parent.height + 1 124 node.workSum = node.workSum.Add(parent.workSum, node.workSum) 125 node.buildAncestor() 126 } 127 } 128 129 // newBlockNode returns a new block node for the given block header and parent 130 // node, calculating the height and workSum from the respective fields on the 131 // parent. This function is NOT safe for concurrent access. 132 func newBlockNode(blockHeader *wire.BlockHeader, parent *blockNode) *blockNode { 133 var node blockNode 134 initBlockNode(&node, blockHeader, parent) 135 return &node 136 } 137 138 // Header constructs a block header from the node and returns it. 139 // 140 // This function is safe for concurrent access. 141 func (node *blockNode) Header() wire.BlockHeader { 142 // No lock is needed because all accessed fields are immutable. 143 prevHash := &zeroHash 144 if node.parent != nil { 145 prevHash = &node.parent.hash 146 } 147 return wire.BlockHeader{ 148 Version: node.version, 149 PrevBlock: *prevHash, 150 MerkleRoot: node.merkleRoot, 151 Timestamp: time.Unix(node.timestamp, 0), 152 Bits: node.bits, 153 Nonce: node.nonce, 154 } 155 } 156 157 // invertLowestOne turns the lowest 1 bit in the binary representation of a number into a 0. 158 func invertLowestOne(n int32) int32 { 159 return n & (n - 1) 160 } 161 162 // getAncestorHeight returns a suitable ancestor for the node at the given height. 163 func getAncestorHeight(height int32) int32 { 164 // We pop off two 1 bits of the height. 165 // This results in a maximum of 330 steps to go back to an ancestor 166 // from height 1<<29. 167 return invertLowestOne(invertLowestOne(height)) 168 } 169 170 // buildAncestor sets an ancestor for the given blocknode. 171 func (node *blockNode) buildAncestor() { 172 if node.parent != nil { 173 node.ancestor = node.parent.Ancestor(getAncestorHeight(node.height)) 174 } 175 } 176 177 // Ancestor returns the ancestor block node at the provided height by following 178 // the chain backwards from this node. The returned block will be nil when a 179 // height is requested that is after the height of the passed node or is less 180 // than zero. 181 // 182 // This function is safe for concurrent access. 183 func (node *blockNode) Ancestor(height int32) *blockNode { 184 if height < 0 || height > node.height { 185 return nil 186 } 187 188 // Traverse back until we find the desired node. 189 n := node 190 for n != nil && n.height != height { 191 // If there's an ancestor available, use it. Otherwise, just 192 // follow the parent. 193 if n.ancestor != nil { 194 // Calculate the height for this ancestor and 195 // check if we can take the ancestor skip. 196 if getAncestorHeight(n.height) >= height { 197 n = n.ancestor 198 continue 199 } 200 } 201 202 // We couldn't take the ancestor skip so traverse back to the parent. 203 n = n.parent 204 } 205 206 return n 207 } 208 209 // Height returns the blockNode's height in the chain. 210 // 211 // NOTE: Part of the HeaderCtx interface. 212 func (node *blockNode) Height() int32 { 213 return node.height 214 } 215 216 // Bits returns the blockNode's nBits. 217 // 218 // NOTE: Part of the HeaderCtx interface. 219 func (node *blockNode) Bits() uint32 { 220 return node.bits 221 } 222 223 // Timestamp returns the blockNode's timestamp. 224 // 225 // NOTE: Part of the HeaderCtx interface. 226 func (node *blockNode) Timestamp() int64 { 227 return node.timestamp 228 } 229 230 // Parent returns the blockNode's parent. 231 // 232 // NOTE: Part of the HeaderCtx interface. 233 func (node *blockNode) Parent() HeaderCtx { 234 if node.parent == nil { 235 // This is required since node.parent is a *blockNode and if we 236 // do not explicitly return nil here, the caller may fail when 237 // nil-checking this. 238 return nil 239 } 240 241 return node.parent 242 } 243 244 // RelativeAncestorCtx returns the blockNode's ancestor that is distance blocks 245 // before it in the chain. This is equivalent to the RelativeAncestor function 246 // below except that the return type is different. 247 // 248 // This function is safe for concurrent access. 249 // 250 // NOTE: Part of the HeaderCtx interface. 251 func (node *blockNode) RelativeAncestorCtx(distance int32) HeaderCtx { 252 ancestor := node.RelativeAncestor(distance) 253 if ancestor == nil { 254 // This is required since RelativeAncestor returns a *blockNode 255 // and if we do not explicitly return nil here, the caller may 256 // fail when nil-checking this. 257 return nil 258 } 259 260 return ancestor 261 } 262 263 // RelativeAncestor returns the ancestor block node a relative 'distance' blocks 264 // before this node. This is equivalent to calling Ancestor with the node's 265 // height minus provided distance. 266 // 267 // This function is safe for concurrent access. 268 func (node *blockNode) RelativeAncestor(distance int32) *blockNode { 269 return node.Ancestor(node.height - distance) 270 } 271 272 // CalcPastMedianTime calculates the median time of the previous few blocks 273 // prior to, and including, the block node. 274 // 275 // This function is safe for concurrent access. 276 func CalcPastMedianTime(node HeaderCtx) time.Time { 277 // Create a slice of the previous few block timestamps used to calculate 278 // the median per the number defined by the constant medianTimeBlocks. 279 timestamps := make([]int64, medianTimeBlocks) 280 numNodes := 0 281 iterNode := node 282 for i := 0; i < medianTimeBlocks && iterNode != nil; i++ { 283 timestamps[i] = iterNode.Timestamp() 284 numNodes++ 285 286 iterNode = iterNode.Parent() 287 } 288 289 // Prune the slice to the actual number of available timestamps which 290 // will be fewer than desired near the beginning of the block chain 291 // and sort them. 292 timestamps = timestamps[:numNodes] 293 sort.Sort(timeSorter(timestamps)) 294 295 // NOTE: The consensus rules incorrectly calculate the median for even 296 // numbers of blocks. A true median averages the middle two elements 297 // for a set with an even number of elements in it. Since the constant 298 // for the previous number of blocks to be used is odd, this is only an 299 // issue for a few blocks near the beginning of the chain. I suspect 300 // this is an optimization even though the result is slightly wrong for 301 // a few of the first blocks since after the first few blocks, there 302 // will always be an odd number of blocks in the set per the constant. 303 // 304 // This code follows suit to ensure the same rules are used, however, be 305 // aware that should the medianTimeBlocks constant ever be changed to an 306 // even number, this code will be wrong. 307 medianTimestamp := timestamps[numNodes/2] 308 return time.Unix(medianTimestamp, 0) 309 } 310 311 // A compile-time assertion to ensure blockNode implements the HeaderCtx 312 // interface. 313 var _ HeaderCtx = (*blockNode)(nil) 314 315 // blockIndex provides facilities for keeping track of an in-memory index of the 316 // block chain. Although the name block chain suggests a single chain of 317 // blocks, it is actually a tree-shaped structure where any node can have 318 // multiple children. However, there can only be one active branch which does 319 // indeed form a chain from the tip all the way back to the genesis block. 320 type blockIndex struct { 321 // The following fields are set when the instance is created and can't 322 // be changed afterwards, so there is no need to protect them with a 323 // separate mutex. 324 db database.DB 325 chainParams *chaincfg.Params 326 327 sync.RWMutex 328 index map[chainhash.Hash]*blockNode 329 dirty map[*blockNode]struct{} 330 } 331 332 // newBlockIndex returns a new empty instance of a block index. The index will 333 // be dynamically populated as block nodes are loaded from the database and 334 // manually added. 335 func newBlockIndex(db database.DB, chainParams *chaincfg.Params) *blockIndex { 336 return &blockIndex{ 337 db: db, 338 chainParams: chainParams, 339 index: make(map[chainhash.Hash]*blockNode), 340 dirty: make(map[*blockNode]struct{}), 341 } 342 } 343 344 // HaveBlock returns whether or not the block index contains the provided hash. 345 // 346 // This function is safe for concurrent access. 347 func (bi *blockIndex) HaveBlock(hash *chainhash.Hash) bool { 348 bi.RLock() 349 _, hasBlock := bi.index[*hash] 350 bi.RUnlock() 351 return hasBlock 352 } 353 354 // LookupNode returns the block node identified by the provided hash. It will 355 // return nil if there is no entry for the hash. 356 // 357 // This function is safe for concurrent access. 358 func (bi *blockIndex) LookupNode(hash *chainhash.Hash) *blockNode { 359 bi.RLock() 360 node := bi.index[*hash] 361 bi.RUnlock() 362 return node 363 } 364 365 // AddNode adds the provided node to the block index and marks it as dirty. 366 // Duplicate entries are not checked so it is up to caller to avoid adding them. 367 // 368 // This function is safe for concurrent access. 369 func (bi *blockIndex) AddNode(node *blockNode) { 370 bi.Lock() 371 bi.addNode(node) 372 bi.dirty[node] = struct{}{} 373 bi.Unlock() 374 } 375 376 // addNode adds the provided node to the block index, but does not mark it as 377 // dirty. This can be used while initializing the block index. 378 // 379 // This function is NOT safe for concurrent access. 380 func (bi *blockIndex) addNode(node *blockNode) { 381 bi.index[node.hash] = node 382 } 383 384 // NodeStatus provides concurrent-safe access to the status field of a node. 385 // 386 // This function is safe for concurrent access. 387 func (bi *blockIndex) NodeStatus(node *blockNode) blockStatus { 388 bi.RLock() 389 status := node.status 390 bi.RUnlock() 391 return status 392 } 393 394 // SetStatusFlags flips the provided status flags on the block node to on, 395 // regardless of whether they were on or off previously. This does not unset any 396 // flags currently on. 397 // 398 // This function is safe for concurrent access. 399 func (bi *blockIndex) SetStatusFlags(node *blockNode, flags blockStatus) { 400 bi.Lock() 401 node.status |= flags 402 bi.dirty[node] = struct{}{} 403 bi.Unlock() 404 } 405 406 // UnsetStatusFlags flips the provided status flags on the block node to off, 407 // regardless of whether they were on or off previously. 408 // 409 // This function is safe for concurrent access. 410 func (bi *blockIndex) UnsetStatusFlags(node *blockNode, flags blockStatus) { 411 bi.Lock() 412 node.status &^= flags 413 bi.dirty[node] = struct{}{} 414 bi.Unlock() 415 } 416 417 // InactiveTips returns all the block nodes that aren't in the best chain. 418 // 419 // This function is safe for concurrent access. 420 func (bi *blockIndex) InactiveTips(bestChain *chainView) []*blockNode { 421 bi.RLock() 422 defer bi.RUnlock() 423 424 // Look through the entire blockindex and look for nodes that aren't in 425 // the best chain. We're gonna keep track of all the orphans and the parents 426 // of the orphans. 427 orphans := make(map[chainhash.Hash]*blockNode) 428 orphanParent := make(map[chainhash.Hash]*blockNode) 429 for hash, node := range bi.index { 430 found := bestChain.Contains(node) 431 if !found { 432 orphans[hash] = node 433 orphanParent[node.parent.hash] = node.parent 434 } 435 } 436 437 // If an orphan isn't pointed to by another orphan, it is a chain tip. 438 // 439 // We can check this by looking for the orphan in the orphan parent map. 440 // If the orphan exists in the orphan parent map, it means that another 441 // orphan is pointing to it. 442 tips := make([]*blockNode, 0, len(orphans)) 443 for hash, orphan := range orphans { 444 _, found := orphanParent[hash] 445 if !found { 446 tips = append(tips, orphan) 447 } 448 449 delete(orphanParent, hash) 450 } 451 452 return tips 453 } 454 455 // flushToDB writes all dirty block nodes to the database. If all writes 456 // succeed, this clears the dirty set. 457 func (bi *blockIndex) flushToDB() error { 458 bi.Lock() 459 if len(bi.dirty) == 0 { 460 bi.Unlock() 461 return nil 462 } 463 464 err := bi.db.Update(func(dbTx database.Tx) error { 465 for node := range bi.dirty { 466 err := dbStoreBlockNode(dbTx, node) 467 if err != nil { 468 return err 469 } 470 } 471 return nil 472 }) 473 474 // If write was successful, clear the dirty set. 475 if err == nil { 476 bi.dirty = make(map[*blockNode]struct{}) 477 } 478 479 bi.Unlock() 480 return err 481 }