github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/btcutil/blockchain/chain.go (about) 1 // Copyright (c) 2013-2016 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 "container/list" 9 "fmt" 10 "math/big" 11 "sort" 12 "sync" 13 "time" 14 15 "github.com/mit-dci/lit/btcutil" 16 "github.com/mit-dci/lit/btcutil/chaincfg/chainhash" 17 "github.com/mit-dci/lit/btcutil/database" 18 "github.com/mit-dci/lit/btcutil/txscript" 19 "github.com/mit-dci/lit/coinparam" 20 "github.com/mit-dci/lit/wire" 21 ) 22 23 const ( 24 // maxOrphanBlocks is the maximum number of orphan blocks that can be 25 // queued. 26 maxOrphanBlocks = 100 27 ) 28 29 // blockNode represents a block within the block chain and is primarily used to 30 // aid in selecting the best chain to be the main chain. The main chain is 31 // stored into the block database. 32 type blockNode struct { 33 // parent is the parent block for this node. 34 parent *blockNode 35 36 // children contains the child nodes for this node. Typically there 37 // will only be one, but sometimes there can be more than one and that 38 // is when the best chain selection algorithm is used. 39 children []*blockNode 40 41 // hash is the double sha 256 of the block. 42 hash *chainhash.Hash 43 44 // parentHash is the double sha 256 of the parent block. This is kept 45 // here over simply relying on parent.hash directly since block nodes 46 // are sparse and the parent node might not be in memory when its hash 47 // is needed. 48 parentHash *chainhash.Hash 49 50 // height is the position in the block chain. 51 height int32 52 53 // workSum is the total amount of work in the chain up to and including 54 // this node. 55 workSum *big.Int 56 57 // inMainChain denotes whether the block node is currently on the 58 // the main chain or not. This is used to help find the common 59 // ancestor when switching chains. 60 inMainChain bool 61 62 // Some fields from block headers to aid in best chain selection. 63 version int32 64 bits uint32 65 timestamp time.Time 66 } 67 68 // newBlockNode returns a new block node for the given block header. It is 69 // completely disconnected from the chain and the workSum value is just the work 70 // for the passed block. The work sum is updated accordingly when the node is 71 // inserted into a chain. 72 func newBlockNode(blockHeader *wire.BlockHeader, blockHash *chainhash.Hash, height int32) *blockNode { 73 // Make a copy of the hash so the node doesn't keep a reference to part 74 // of the full block/block header preventing it from being garbage 75 // collected. 76 prevHash := blockHeader.PrevBlock 77 node := blockNode{ 78 hash: blockHash, 79 parentHash: &prevHash, 80 workSum: CalcWork(blockHeader.Bits), 81 height: height, 82 version: blockHeader.Version, 83 bits: blockHeader.Bits, 84 timestamp: blockHeader.Timestamp, 85 } 86 return &node 87 } 88 89 // orphanBlock represents a block that we don't yet have the parent for. It 90 // is a normal block plus an expiration time to prevent caching the orphan 91 // forever. 92 type orphanBlock struct { 93 block *btcutil.Block 94 expiration time.Time 95 } 96 97 // removeChildNode deletes node from the provided slice of child block 98 // nodes. It ensures the final pointer reference is set to nil to prevent 99 // potential memory leaks. The original slice is returned unmodified if node 100 // is invalid or not in the slice. 101 // 102 // This function MUST be called with the chain state lock held (for writes). 103 func removeChildNode(children []*blockNode, node *blockNode) []*blockNode { 104 if node == nil { 105 return children 106 } 107 108 // An indexing for loop is intentionally used over a range here as range 109 // does not reevaluate the slice on each iteration nor does it adjust 110 // the index for the modified slice. 111 for i := 0; i < len(children); i++ { 112 if children[i].hash.IsEqual(node.hash) { 113 copy(children[i:], children[i+1:]) 114 children[len(children)-1] = nil 115 return children[:len(children)-1] 116 } 117 } 118 return children 119 } 120 121 // BestState houses information about the current best block and other info 122 // related to the state of the main chain as it exists from the point of view of 123 // the current best block. 124 // 125 // The BestSnapshot method can be used to obtain access to this information 126 // in a concurrent safe manner and the data will not be changed out from under 127 // the caller when chain state changes occur as the function name implies. 128 // However, the returned snapshot must be treated as immutable since it is 129 // shared by all callers. 130 type BestState struct { 131 Hash *chainhash.Hash // The hash of the block. 132 Height int32 // The height of the block. 133 Bits uint32 // The difficulty bits of the block. 134 BlockSize uint64 // The size of the block. 135 BlockWeight uint64 // The weight of the block. 136 NumTxns uint64 // The number of txns in the block. 137 TotalTxns uint64 // The total number of txns in the chain. 138 MedianTime time.Time // Median time as per CalcPastMedianTime. 139 } 140 141 // newBestState returns a new best stats instance for the given parameters. 142 func newBestState(node *blockNode, blockSize, blockWeight, numTxns, 143 totalTxns uint64, medianTime time.Time) *BestState { 144 145 return &BestState{ 146 Hash: node.hash, 147 Height: node.height, 148 Bits: node.bits, 149 BlockSize: blockSize, 150 BlockWeight: blockWeight, 151 NumTxns: numTxns, 152 TotalTxns: totalTxns, 153 MedianTime: medianTime, 154 } 155 } 156 157 // BlockChain provides functions for working with the bitcoin block chain. 158 // It includes functionality such as rejecting duplicate blocks, ensuring blocks 159 // follow all rules, orphan handling, checkpoint handling, and best chain 160 // selection with reorganization. 161 type BlockChain struct { 162 // The following fields are set when the instance is created and can't 163 // be changed afterwards, so there is no need to protect them with a 164 // separate mutex. 165 checkpointsByHeight map[int32]*coinparam.Checkpoint 166 db database.DB 167 chainParams *coinparam.Params 168 timeSource MedianTimeSource 169 notifications NotificationCallback 170 sigCache *txscript.SigCache 171 indexManager IndexManager 172 hashCache *txscript.HashCache 173 174 // The following fields are calculated based upon the provided chain 175 // parameters. They are also set when the instance is created and 176 // can't be changed afterwards, so there is no need to protect them with 177 // a separate mutex. 178 // 179 // minMemoryNodes is the minimum number of consecutive nodes needed 180 // in memory in order to perform all necessary validation. It is used 181 // to determine when it's safe to prune nodes from memory without 182 // causing constant dynamic reloading. This is typically the same value 183 // as blocksPerRetarget, but it is separated here for tweakability and 184 // testability. 185 minRetargetTimespan int64 // target timespan / adjustment factor 186 maxRetargetTimespan int64 // target timespan * adjustment factor 187 blocksPerRetarget int32 // target timespan / target time per block 188 minMemoryNodes int32 189 190 // chainLock protects concurrent access to the vast majority of the 191 // fields in this struct below this point. 192 chainLock sync.RWMutex 193 194 // These fields are configuration parameters that can be toggled at 195 // runtime. They are protected by the chain lock. 196 noVerify bool 197 noCheckpoints bool 198 199 // These fields are related to the memory block index. They are 200 // protected by the chain lock. 201 bestNode *blockNode 202 index map[chainhash.Hash]*blockNode 203 depNodes map[chainhash.Hash][]*blockNode 204 205 // These fields are related to handling of orphan blocks. They are 206 // protected by a combination of the chain lock and the orphan lock. 207 orphanLock sync.RWMutex 208 orphans map[chainhash.Hash]*orphanBlock 209 prevOrphans map[chainhash.Hash][]*orphanBlock 210 oldestOrphan *orphanBlock 211 blockCache map[chainhash.Hash]*btcutil.Block 212 213 // These fields are related to checkpoint handling. They are protected 214 // by the chain lock. 215 nextCheckpoint *coinparam.Checkpoint 216 checkpointBlock *btcutil.Block 217 218 // The state is used as a fairly efficient way to cache information 219 // about the current best chain state that is returned to callers when 220 // requested. It operates on the principle of MVCC such that any time a 221 // new block becomes the best block, the state pointer is replaced with 222 // a new struct and the old state is left untouched. In this way, 223 // multiple callers can be pointing to different best chain states. 224 // This is acceptable for most callers because the state is only being 225 // queried at a specific point in time. 226 // 227 // In addition, some of the fields are stored in the database so the 228 // chain state can be quickly reconstructed on load. 229 stateLock sync.RWMutex 230 stateSnapshot *BestState 231 } 232 233 // DisableVerify provides a mechanism to disable transaction script validation 234 // which you DO NOT want to do in production as it could allow double spends 235 // and other undesirable things. It is provided only for debug purposes since 236 // script validation is extremely intensive and when debugging it is sometimes 237 // nice to quickly get the chain. 238 // 239 // This function is safe for concurrent access. 240 func (b *BlockChain) DisableVerify(disable bool) { 241 b.chainLock.Lock() 242 b.noVerify = disable 243 b.chainLock.Unlock() 244 } 245 246 // HaveBlock returns whether or not the chain instance has the block represented 247 // by the passed hash. This includes checking the various places a block can 248 // be like part of the main chain, on a side chain, or in the orphan pool. 249 // 250 // This function is safe for concurrent access. 251 func (b *BlockChain) HaveBlock(hash *chainhash.Hash) (bool, error) { 252 b.chainLock.RLock() 253 defer b.chainLock.RUnlock() 254 255 exists, err := b.blockExists(hash) 256 if err != nil { 257 return false, err 258 } 259 return exists || b.IsKnownOrphan(hash), nil 260 } 261 262 // IsKnownOrphan returns whether the passed hash is currently a known orphan. 263 // Keep in mind that only a limited number of orphans are held onto for a 264 // limited amount of time, so this function must not be used as an absolute 265 // way to test if a block is an orphan block. A full block (as opposed to just 266 // its hash) must be passed to ProcessBlock for that purpose. However, calling 267 // ProcessBlock with an orphan that already exists results in an error, so this 268 // function provides a mechanism for a caller to intelligently detect *recent* 269 // duplicate orphans and react accordingly. 270 // 271 // This function is safe for concurrent access. 272 func (b *BlockChain) IsKnownOrphan(hash *chainhash.Hash) bool { 273 // Protect concurrent access. Using a read lock only so multiple 274 // readers can query without blocking each other. 275 b.orphanLock.RLock() 276 defer b.orphanLock.RUnlock() 277 278 if _, exists := b.orphans[*hash]; exists { 279 return true 280 } 281 282 return false 283 } 284 285 // GetOrphanRoot returns the head of the chain for the provided hash from the 286 // map of orphan blocks. 287 // 288 // This function is safe for concurrent access. 289 func (b *BlockChain) GetOrphanRoot(hash *chainhash.Hash) *chainhash.Hash { 290 // Protect concurrent access. Using a read lock only so multiple 291 // readers can query without blocking each other. 292 b.orphanLock.RLock() 293 defer b.orphanLock.RUnlock() 294 295 // Keep looping while the parent of each orphaned block is 296 // known and is an orphan itself. 297 orphanRoot := hash 298 prevHash := hash 299 for { 300 orphan, exists := b.orphans[*prevHash] 301 if !exists { 302 break 303 } 304 orphanRoot = prevHash 305 prevHash = &orphan.block.MsgBlock().Header.PrevBlock 306 } 307 308 return orphanRoot 309 } 310 311 // removeOrphanBlock removes the passed orphan block from the orphan pool and 312 // previous orphan index. 313 func (b *BlockChain) removeOrphanBlock(orphan *orphanBlock) { 314 // Protect concurrent access. 315 b.orphanLock.Lock() 316 defer b.orphanLock.Unlock() 317 318 // Remove the orphan block from the orphan pool. 319 orphanHash := orphan.block.Hash() 320 delete(b.orphans, *orphanHash) 321 322 // Remove the reference from the previous orphan index too. An indexing 323 // for loop is intentionally used over a range here as range does not 324 // reevaluate the slice on each iteration nor does it adjust the index 325 // for the modified slice. 326 prevHash := &orphan.block.MsgBlock().Header.PrevBlock 327 orphans := b.prevOrphans[*prevHash] 328 for i := 0; i < len(orphans); i++ { 329 hash := orphans[i].block.Hash() 330 if hash.IsEqual(orphanHash) { 331 copy(orphans[i:], orphans[i+1:]) 332 orphans[len(orphans)-1] = nil 333 orphans = orphans[:len(orphans)-1] 334 i-- 335 } 336 } 337 b.prevOrphans[*prevHash] = orphans 338 339 // Remove the map entry altogether if there are no longer any orphans 340 // which depend on the parent hash. 341 if len(b.prevOrphans[*prevHash]) == 0 { 342 delete(b.prevOrphans, *prevHash) 343 } 344 } 345 346 // addOrphanBlock adds the passed block (which is already determined to be 347 // an orphan prior calling this function) to the orphan pool. It lazily cleans 348 // up any expired blocks so a separate cleanup poller doesn't need to be run. 349 // It also imposes a maximum limit on the number of outstanding orphan 350 // blocks and will remove the oldest received orphan block if the limit is 351 // exceeded. 352 func (b *BlockChain) addOrphanBlock(block *btcutil.Block) { 353 // Remove expired orphan blocks. 354 for _, oBlock := range b.orphans { 355 if time.Now().After(oBlock.expiration) { 356 b.removeOrphanBlock(oBlock) 357 continue 358 } 359 360 // Update the oldest orphan block pointer so it can be discarded 361 // in case the orphan pool fills up. 362 if b.oldestOrphan == nil || oBlock.expiration.Before(b.oldestOrphan.expiration) { 363 b.oldestOrphan = oBlock 364 } 365 } 366 367 // Limit orphan blocks to prevent memory exhaustion. 368 if len(b.orphans)+1 > maxOrphanBlocks { 369 // Remove the oldest orphan to make room for the new one. 370 b.removeOrphanBlock(b.oldestOrphan) 371 b.oldestOrphan = nil 372 } 373 374 // Protect concurrent access. This is intentionally done here instead 375 // of near the top since removeOrphanBlock does its own locking and 376 // the range iterator is not invalidated by removing map entries. 377 b.orphanLock.Lock() 378 defer b.orphanLock.Unlock() 379 380 // Insert the block into the orphan map with an expiration time 381 // 1 hour from now. 382 expiration := time.Now().Add(time.Hour) 383 oBlock := &orphanBlock{ 384 block: block, 385 expiration: expiration, 386 } 387 b.orphans[*block.Hash()] = oBlock 388 389 // Add to previous hash lookup index for faster dependency lookups. 390 prevHash := &block.MsgBlock().Header.PrevBlock 391 b.prevOrphans[*prevHash] = append(b.prevOrphans[*prevHash], oBlock) 392 393 return 394 } 395 396 // loadBlockNode loads the block identified by hash from the block database, 397 // creates a block node from it, and updates the memory block chain accordingly. 398 // It is used mainly to dynamically load previous blocks from the database as 399 // they are needed to avoid needing to put the entire block chain in memory. 400 // 401 // This function MUST be called with the chain state lock held (for writes). 402 // The database transaction may be read-only. 403 func (b *BlockChain) loadBlockNode(dbTx database.Tx, hash *chainhash.Hash) (*blockNode, error) { 404 // Load the block header and height from the db. 405 blockHeader, err := dbFetchHeaderByHash(dbTx, hash) 406 if err != nil { 407 return nil, err 408 } 409 blockHeight, err := dbFetchHeightByHash(dbTx, hash) 410 if err != nil { 411 return nil, err 412 } 413 414 // Create the new block node for the block and set the work. 415 node := newBlockNode(blockHeader, hash, blockHeight) 416 node.inMainChain = true 417 418 // Add the node to the chain. 419 // There are a few possibilities here: 420 // 1) This node is a child of an existing block node 421 // 2) This node is the parent of one or more nodes 422 // 3) Neither 1 or 2 is true which implies it's an orphan block and 423 // therefore is an error to insert into the chain 424 prevHash := &blockHeader.PrevBlock 425 if parentNode, ok := b.index[*prevHash]; ok { 426 // Case 1 -- This node is a child of an existing block node. 427 // Update the node's work sum with the sum of the parent node's 428 // work sum and this node's work, append the node as a child of 429 // the parent node and set this node's parent to the parent 430 // node. 431 node.workSum = node.workSum.Add(parentNode.workSum, node.workSum) 432 parentNode.children = append(parentNode.children, node) 433 node.parent = parentNode 434 435 } else if childNodes, ok := b.depNodes[*hash]; ok { 436 // Case 2 -- This node is the parent of one or more nodes. 437 // Update the node's work sum by subtracting this node's work 438 // from the sum of its first child, and connect the node to all 439 // of its children. 440 node.workSum.Sub(childNodes[0].workSum, node.workSum) 441 for _, childNode := range childNodes { 442 childNode.parent = node 443 node.children = append(node.children, childNode) 444 } 445 446 } else { 447 // Case 3 -- The node doesn't have a parent and is not the 448 // parent of another node. This means an arbitrary orphan block 449 // is trying to be loaded which is not allowed. 450 str := "loadBlockNode: attempt to insert orphan block %v" 451 return nil, AssertError(fmt.Sprintf(str, hash)) 452 } 453 454 // Add the new node to the indices for faster lookups. 455 b.index[*hash] = node 456 b.depNodes[*prevHash] = append(b.depNodes[*prevHash], node) 457 458 return node, nil 459 } 460 461 // getPrevNodeFromBlock returns a block node for the block previous to the 462 // passed block (the passed block's parent). When it is already in the memory 463 // block chain, it simply returns it. Otherwise, it loads the previous block 464 // header from the block database, creates a new block node from it, and returns 465 // it. The returned node will be nil if the genesis block is passed. 466 // 467 // This function MUST be called with the chain state lock held (for writes). 468 func (b *BlockChain) getPrevNodeFromBlock(block *btcutil.Block) (*blockNode, error) { 469 // Genesis block. 470 prevHash := &block.MsgBlock().Header.PrevBlock 471 if prevHash.IsEqual(zeroHash) { 472 return nil, nil 473 } 474 475 // Return the existing previous block node if it's already there. 476 if bn, ok := b.index[*prevHash]; ok { 477 return bn, nil 478 } 479 480 // Dynamically load the previous block from the block database, create 481 // a new block node for it, and update the memory chain accordingly. 482 var prevBlockNode *blockNode 483 err := b.db.View(func(dbTx database.Tx) error { 484 var err error 485 prevBlockNode, err = b.loadBlockNode(dbTx, prevHash) 486 return err 487 }) 488 return prevBlockNode, err 489 } 490 491 // getPrevNodeFromNode returns a block node for the block previous to the 492 // passed block node (the passed block node's parent). When the node is already 493 // connected to a parent, it simply returns it. Otherwise, it loads the 494 // associated block from the database to obtain the previous hash and uses that 495 // to dynamically create a new block node and return it. The memory block 496 // chain is updated accordingly. The returned node will be nil if the genesis 497 // block is passed. 498 // 499 // This function MUST be called with the chain state lock held (for writes). 500 func (b *BlockChain) getPrevNodeFromNode(node *blockNode) (*blockNode, error) { 501 // Return the existing previous block node if it's already there. 502 if node.parent != nil { 503 return node.parent, nil 504 } 505 506 // Genesis block. 507 if node.hash.IsEqual(b.chainParams.GenesisHash) { 508 return nil, nil 509 } 510 511 // Dynamically load the previous block from the block database, create 512 // a new block node for it, and update the memory chain accordingly. 513 var prevBlockNode *blockNode 514 err := b.db.View(func(dbTx database.Tx) error { 515 var err error 516 prevBlockNode, err = b.loadBlockNode(dbTx, node.parentHash) 517 return err 518 }) 519 return prevBlockNode, err 520 } 521 522 // removeBlockNode removes the passed block node from the memory chain by 523 // unlinking all of its children and removing it from the the node and 524 // dependency indices. 525 // 526 // This function MUST be called with the chain state lock held (for writes). 527 func (b *BlockChain) removeBlockNode(node *blockNode) error { 528 if node.parent != nil { 529 return AssertError(fmt.Sprintf("removeBlockNode must be "+ 530 "called with a node at the front of the chain - node %v", 531 node.hash)) 532 } 533 534 // Remove the node from the node index. 535 delete(b.index, *node.hash) 536 537 // Unlink all of the node's children. 538 for _, child := range node.children { 539 child.parent = nil 540 } 541 node.children = nil 542 543 // Remove the reference from the dependency index. 544 prevHash := node.parentHash 545 if children, ok := b.depNodes[*prevHash]; ok { 546 // Find the node amongst the children of the 547 // dependencies for the parent hash and remove it. 548 b.depNodes[*prevHash] = removeChildNode(children, node) 549 550 // Remove the map entry altogether if there are no 551 // longer any nodes which depend on the parent hash. 552 if len(b.depNodes[*prevHash]) == 0 { 553 delete(b.depNodes, *prevHash) 554 } 555 } 556 557 return nil 558 } 559 560 // pruneBlockNodes removes references to old block nodes which are no longer 561 // needed so they may be garbage collected. In order to validate block rules 562 // and choose the best chain, only a portion of the nodes which form the block 563 // chain are needed in memory. This function walks the chain backwards from the 564 // current best chain to find any nodes before the first needed block node. 565 // 566 // This function MUST be called with the chain state lock held (for writes). 567 func (b *BlockChain) pruneBlockNodes() error { 568 // Walk the chain backwards to find what should be the new root node. 569 // Intentionally use node.parent instead of getPrevNodeFromNode since 570 // the latter loads the node and the goal is to find nodes still in 571 // memory that can be pruned. 572 newRootNode := b.bestNode 573 for i := int32(0); i < b.minMemoryNodes-1 && newRootNode != nil; i++ { 574 newRootNode = newRootNode.parent 575 } 576 577 // Nothing to do if there are not enough nodes. 578 if newRootNode == nil || newRootNode.parent == nil { 579 return nil 580 } 581 582 // Push the nodes to delete on a list in reverse order since it's easier 583 // to prune them going forwards than it is backwards. This will 584 // typically end up being a single node since pruning is currently done 585 // just before each new node is created. However, that might be tuned 586 // later to only prune at intervals, so the code needs to account for 587 // the possibility of multiple nodes. 588 deleteNodes := list.New() 589 for node := newRootNode.parent; node != nil; node = node.parent { 590 deleteNodes.PushFront(node) 591 } 592 593 // Loop through each node to prune, unlink its children, remove it from 594 // the dependency index, and remove it from the node index. 595 for e := deleteNodes.Front(); e != nil; e = e.Next() { 596 node := e.Value.(*blockNode) 597 err := b.removeBlockNode(node) 598 if err != nil { 599 return err 600 } 601 } 602 603 return nil 604 } 605 606 // isMajorityVersion determines if a previous number of blocks in the chain 607 // starting with startNode are at least the minimum passed version. 608 // 609 // This function MUST be called with the chain state lock held (for writes). 610 func (b *BlockChain) isMajorityVersion(minVer int32, startNode *blockNode, numRequired uint64) bool { 611 numFound := uint64(0) 612 iterNode := startNode 613 for i := uint64(0); i < b.chainParams.BlockUpgradeNumToCheck && 614 numFound < numRequired && iterNode != nil; i++ { 615 // This node has a version that is at least the minimum version. 616 if iterNode.version >= minVer { 617 numFound++ 618 } 619 620 // Get the previous block node. This function is used over 621 // simply accessing iterNode.parent directly as it will 622 // dynamically create previous block nodes as needed. This 623 // helps allow only the pieces of the chain that are needed 624 // to remain in memory. 625 var err error 626 iterNode, err = b.getPrevNodeFromNode(iterNode) 627 if err != nil { 628 break 629 } 630 } 631 632 return numFound >= numRequired 633 } 634 635 // calcPastMedianTime calculates the median time of the previous few blocks 636 // prior to, and including, the passed block node. It is primarily used to 637 // validate new blocks have sane timestamps. 638 // 639 // This function MUST be called with the chain state lock held (for writes). 640 func (b *BlockChain) calcPastMedianTime(startNode *blockNode) (time.Time, error) { 641 // Genesis block. 642 if startNode == nil { 643 return b.chainParams.GenesisBlock.Header.Timestamp, nil 644 } 645 646 // Create a slice of the previous few block timestamps used to calculate 647 // the median per the number defined by the constant medianTimeBlocks. 648 timestamps := make([]time.Time, medianTimeBlocks) 649 numNodes := 0 650 iterNode := startNode 651 for i := 0; i < medianTimeBlocks && iterNode != nil; i++ { 652 timestamps[i] = iterNode.timestamp 653 numNodes++ 654 655 // Get the previous block node. This function is used over 656 // simply accessing iterNode.parent directly as it will 657 // dynamically create previous block nodes as needed. This 658 // helps allow only the pieces of the chain that are needed 659 // to remain in memory. 660 var err error 661 iterNode, err = b.getPrevNodeFromNode(iterNode) 662 if err != nil { 663 return time.Time{}, err 664 } 665 } 666 667 // Prune the slice to the actual number of available timestamps which 668 // will be fewer than desired near the beginning of the block chain 669 // and sort them. 670 timestamps = timestamps[:numNodes] 671 sort.Sort(timeSorter(timestamps)) 672 673 // NOTE: bitcoind incorrectly calculates the median for even numbers of 674 // blocks. A true median averages the middle two elements for a set 675 // with an even number of elements in it. Since the constant for the 676 // previous number of blocks to be used is odd, this is only an issue 677 // for a few blocks near the beginning of the chain. I suspect this is 678 // an optimization even though the result is slightly wrong for a few 679 // of the first blocks since after the first few blocks, there will 680 // always be an odd number of blocks in the set per the constant. 681 // 682 // This code follows suit to ensure the same rules are used as bitcoind 683 // however, be aware that should the medianTimeBlocks constant ever be 684 // changed to an even number, this code will be wrong. 685 medianTimestamp := timestamps[numNodes/2] 686 return medianTimestamp, nil 687 } 688 689 // CalcPastMedianTime calculates the median time of the previous few blocks 690 // prior to, and including, the end of the current best chain. It is primarily 691 // used to ensure new blocks have sane timestamps. 692 // 693 // This function is safe for concurrent access. 694 func (b *BlockChain) CalcPastMedianTime() (time.Time, error) { 695 b.chainLock.Lock() 696 defer b.chainLock.Unlock() 697 698 return b.calcPastMedianTime(b.bestNode) 699 } 700 701 // getReorganizeNodes finds the fork point between the main chain and the passed 702 // node and returns a list of block nodes that would need to be detached from 703 // the main chain and a list of block nodes that would need to be attached to 704 // the fork point (which will be the end of the main chain after detaching the 705 // returned list of block nodes) in order to reorganize the chain such that the 706 // passed node is the new end of the main chain. The lists will be empty if the 707 // passed node is not on a side chain. 708 // 709 // This function MUST be called with the chain state lock held (for reads). 710 func (b *BlockChain) getReorganizeNodes(node *blockNode) (*list.List, *list.List) { 711 // Nothing to detach or attach if there is no node. 712 attachNodes := list.New() 713 detachNodes := list.New() 714 if node == nil { 715 return detachNodes, attachNodes 716 } 717 718 // Find the fork point (if any) adding each block to the list of nodes 719 // to attach to the main tree. Push them onto the list in reverse order 720 // so they are attached in the appropriate order when iterating the list 721 // later. 722 ancestor := node 723 for ; ancestor.parent != nil; ancestor = ancestor.parent { 724 if ancestor.inMainChain { 725 break 726 } 727 attachNodes.PushFront(ancestor) 728 } 729 730 // TODO(davec): Use prevNodeFromNode function in case the requested 731 // node is further back than the what is in memory. This shouldn't 732 // happen in the normal course of operation, but the ability to fetch 733 // input transactions of arbitrary blocks will likely to be exposed at 734 // some point and that could lead to an issue here. 735 736 // Start from the end of the main chain and work backwards until the 737 // common ancestor adding each block to the list of nodes to detach from 738 // the main chain. 739 for n := b.bestNode; n != nil && n.parent != nil; n = n.parent { 740 if n.hash.IsEqual(ancestor.hash) { 741 break 742 } 743 detachNodes.PushBack(n) 744 } 745 746 return detachNodes, attachNodes 747 } 748 749 // dbMaybeStoreBlock stores the provided block in the database if it's not 750 // already there. 751 func dbMaybeStoreBlock(dbTx database.Tx, block *btcutil.Block) error { 752 hasBlock, err := dbTx.HasBlock(block.Hash()) 753 if err != nil { 754 return err 755 } 756 if hasBlock { 757 return nil 758 } 759 760 return dbTx.StoreBlock(block) 761 } 762 763 // connectBlock handles connecting the passed node/block to the end of the main 764 // (best) chain. 765 // 766 // This passed utxo view must have all referenced txos the block spends marked 767 // as spent and all of the new txos the block creates added to it. In addition, 768 // the passed stxos slice must be populated with all of the information for the 769 // spent txos. This approach is used because the connection validation that 770 // must happen prior to calling this function requires the same details, so 771 // it would be inefficient to repeat it. 772 // 773 // This function MUST be called with the chain state lock held (for writes). 774 func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block, view *UtxoViewpoint, stxos []spentTxOut) error { 775 // Make sure it's extending the end of the best chain. 776 prevHash := &block.MsgBlock().Header.PrevBlock 777 if !prevHash.IsEqual(b.bestNode.hash) { 778 return AssertError("connectBlock must be called with a block " + 779 "that extends the main chain") 780 } 781 782 // Sanity check the correct number of stxos are provided. 783 if len(stxos) != countSpentOutputs(block) { 784 return AssertError("connectBlock called with inconsistent " + 785 "spent transaction out information") 786 } 787 788 // Calculate the median time for the block. 789 medianTime, err := b.calcPastMedianTime(node) 790 if err != nil { 791 return err 792 } 793 794 // Generate a new best state snapshot that will be used to update the 795 // database and later memory if all database updates are successful. 796 b.stateLock.RLock() 797 curTotalTxns := b.stateSnapshot.TotalTxns 798 b.stateLock.RUnlock() 799 numTxns := uint64(len(block.MsgBlock().Transactions)) 800 blockSize := uint64(block.MsgBlock().SerializeSize()) 801 blockWeight := uint64(GetBlockWeight(block)) 802 state := newBestState(node, blockSize, blockWeight, numTxns, 803 curTotalTxns+numTxns, medianTime) 804 805 // Atomically insert info into the database. 806 err = b.db.Update(func(dbTx database.Tx) error { 807 // Update best block state. 808 err := dbPutBestState(dbTx, state, node.workSum) 809 if err != nil { 810 return err 811 } 812 813 // Add the block hash and height to the block index which tracks 814 // the main chain. 815 err = dbPutBlockIndex(dbTx, block.Hash(), node.height) 816 if err != nil { 817 return err 818 } 819 820 // Update the utxo set using the state of the utxo view. This 821 // entails removing all of the utxos spent and adding the new 822 // ones created by the block. 823 err = dbPutUtxoView(dbTx, view) 824 if err != nil { 825 return err 826 } 827 828 // Update the transaction spend journal by adding a record for 829 // the block that contains all txos spent by it. 830 err = dbPutSpendJournalEntry(dbTx, block.Hash(), stxos) 831 if err != nil { 832 return err 833 } 834 835 // Insert the block into the database if it's not already there. 836 err = dbMaybeStoreBlock(dbTx, block) 837 if err != nil { 838 return err 839 } 840 841 // Allow the index manager to call each of the currently active 842 // optional indexes with the block being connected so they can 843 // update themselves accordingly. 844 if b.indexManager != nil { 845 err := b.indexManager.ConnectBlock(dbTx, block, view) 846 if err != nil { 847 return err 848 } 849 } 850 851 return nil 852 }) 853 if err != nil { 854 return err 855 } 856 857 // Prune fully spent entries and mark all entries in the view unmodified 858 // now that the modifications have been committed to the database. 859 view.commit() 860 861 // Add the new node to the memory main chain indices for faster 862 // lookups. 863 node.inMainChain = true 864 b.index[*node.hash] = node 865 b.depNodes[*prevHash] = append(b.depNodes[*prevHash], node) 866 867 // This node is now the end of the best chain. 868 b.bestNode = node 869 870 // Update the state for the best block. Notice how this replaces the 871 // entire struct instead of updating the existing one. This effectively 872 // allows the old version to act as a snapshot which callers can use 873 // freely without needing to hold a lock for the duration. See the 874 // comments on the state variable for more details. 875 b.stateLock.Lock() 876 b.stateSnapshot = state 877 b.stateLock.Unlock() 878 879 // Notify the caller that the block was connected to the main chain. 880 // The caller would typically want to react with actions such as 881 // updating wallets. 882 b.chainLock.Unlock() 883 b.sendNotification(NTBlockConnected, block) 884 b.chainLock.Lock() 885 886 return nil 887 } 888 889 // disconnectBlock handles disconnecting the passed node/block from the end of 890 // the main (best) chain. 891 // 892 // This function MUST be called with the chain state lock held (for writes). 893 func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block, view *UtxoViewpoint) error { 894 // Make sure the node being disconnected is the end of the best chain. 895 if !node.hash.IsEqual(b.bestNode.hash) { 896 return AssertError("disconnectBlock must be called with the " + 897 "block at the end of the main chain") 898 } 899 900 // Get the previous block node. This function is used over simply 901 // accessing node.parent directly as it will dynamically create previous 902 // block nodes as needed. This helps allow only the pieces of the chain 903 // that are needed to remain in memory. 904 prevNode, err := b.getPrevNodeFromNode(node) 905 if err != nil { 906 return err 907 } 908 909 // Calculate the median time for the previous block. 910 medianTime, err := b.calcPastMedianTime(prevNode) 911 if err != nil { 912 return err 913 } 914 915 // Load the previous block since some details for it are needed below. 916 var prevBlock *btcutil.Block 917 err = b.db.View(func(dbTx database.Tx) error { 918 var err error 919 prevBlock, err = dbFetchBlockByHash(dbTx, prevNode.hash) 920 return err 921 }) 922 if err != nil { 923 return err 924 } 925 926 // Generate a new best state snapshot that will be used to update the 927 // database and later memory if all database updates are successful. 928 b.stateLock.RLock() 929 curTotalTxns := b.stateSnapshot.TotalTxns 930 b.stateLock.RUnlock() 931 numTxns := uint64(len(prevBlock.MsgBlock().Transactions)) 932 blockSize := uint64(prevBlock.MsgBlock().SerializeSize()) 933 blockWeight := uint64(GetBlockWeight(prevBlock)) 934 newTotalTxns := curTotalTxns - uint64(len(block.MsgBlock().Transactions)) 935 state := newBestState(prevNode, blockSize, blockWeight, numTxns, 936 newTotalTxns, medianTime) 937 938 err = b.db.Update(func(dbTx database.Tx) error { 939 // Update best block state. 940 err := dbPutBestState(dbTx, state, node.workSum) 941 if err != nil { 942 return err 943 } 944 945 // Remove the block hash and height from the block index which 946 // tracks the main chain. 947 err = dbRemoveBlockIndex(dbTx, block.Hash(), node.height) 948 if err != nil { 949 return err 950 } 951 952 // Update the utxo set using the state of the utxo view. This 953 // entails restoring all of the utxos spent and removing the new 954 // ones created by the block. 955 err = dbPutUtxoView(dbTx, view) 956 if err != nil { 957 return err 958 } 959 960 // Update the transaction spend journal by removing the record 961 // that contains all txos spent by the block . 962 err = dbRemoveSpendJournalEntry(dbTx, block.Hash()) 963 if err != nil { 964 return err 965 } 966 967 // Allow the index manager to call each of the currently active 968 // optional indexes with the block being disconnected so they 969 // can update themselves accordingly. 970 if b.indexManager != nil { 971 err := b.indexManager.DisconnectBlock(dbTx, block, view) 972 if err != nil { 973 return err 974 } 975 } 976 977 return nil 978 }) 979 if err != nil { 980 return err 981 } 982 983 // Prune fully spent entries and mark all entries in the view unmodified 984 // now that the modifications have been committed to the database. 985 view.commit() 986 987 // Put block in the side chain cache. 988 node.inMainChain = false 989 b.blockCache[*node.hash] = block 990 991 // This node's parent is now the end of the best chain. 992 b.bestNode = node.parent 993 994 // Update the state for the best block. Notice how this replaces the 995 // entire struct instead of updating the existing one. This effectively 996 // allows the old version to act as a snapshot which callers can use 997 // freely without needing to hold a lock for the duration. See the 998 // comments on the state variable for more details. 999 b.stateLock.Lock() 1000 b.stateSnapshot = state 1001 b.stateLock.Unlock() 1002 1003 // Notify the caller that the block was disconnected from the main 1004 // chain. The caller would typically want to react with actions such as 1005 // updating wallets. 1006 b.chainLock.Unlock() 1007 b.sendNotification(NTBlockDisconnected, block) 1008 b.chainLock.Lock() 1009 1010 return nil 1011 } 1012 1013 // countSpentOutputs returns the number of utxos the passed block spends. 1014 func countSpentOutputs(block *btcutil.Block) int { 1015 // Exclude the coinbase transaction since it can't spend anything. 1016 var numSpent int 1017 for _, tx := range block.Transactions()[1:] { 1018 numSpent += len(tx.MsgTx().TxIn) 1019 } 1020 return numSpent 1021 } 1022 1023 // reorganizeChain reorganizes the block chain by disconnecting the nodes in the 1024 // detachNodes list and connecting the nodes in the attach list. It expects 1025 // that the lists are already in the correct order and are in sync with the 1026 // end of the current best chain. Specifically, nodes that are being 1027 // disconnected must be in reverse order (think of popping them off the end of 1028 // the chain) and nodes the are being attached must be in forwards order 1029 // (think pushing them onto the end of the chain). 1030 // 1031 // The flags modify the behavior of this function as follows: 1032 // - BFDryRun: Only the checks which ensure the reorganize can be completed 1033 // successfully are performed. The chain is not reorganized. 1034 // 1035 // This function MUST be called with the chain state lock held (for writes). 1036 func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List, flags BehaviorFlags) error { 1037 // Ensure all of the needed side chain blocks are in the cache. 1038 for e := attachNodes.Front(); e != nil; e = e.Next() { 1039 n := e.Value.(*blockNode) 1040 if _, exists := b.blockCache[*n.hash]; !exists { 1041 return AssertError(fmt.Sprintf("block %v is missing "+ 1042 "from the side chain block cache", n.hash)) 1043 } 1044 } 1045 1046 // All of the blocks to detach and related spend journal entries needed 1047 // to unspend transaction outputs in the blocks being disconnected must 1048 // be loaded from the database during the reorg check phase below and 1049 // then they are needed again when doing the actual database updates. 1050 // Rather than doing two loads, cache the loaded data into these slices. 1051 detachBlocks := make([]*btcutil.Block, 0, detachNodes.Len()) 1052 detachSpentTxOuts := make([][]spentTxOut, 0, detachNodes.Len()) 1053 1054 // Disconnect all of the blocks back to the point of the fork. This 1055 // entails loading the blocks and their associated spent txos from the 1056 // database and using that information to unspend all of the spent txos 1057 // and remove the utxos created by the blocks. 1058 view := NewUtxoViewpoint() 1059 view.SetBestHash(b.bestNode.hash) 1060 for e := detachNodes.Front(); e != nil; e = e.Next() { 1061 n := e.Value.(*blockNode) 1062 var block *btcutil.Block 1063 err := b.db.View(func(dbTx database.Tx) error { 1064 var err error 1065 block, err = dbFetchBlockByHash(dbTx, n.hash) 1066 return err 1067 }) 1068 1069 // Load all of the utxos referenced by the block that aren't 1070 // already in the view. 1071 err = view.fetchInputUtxos(b.db, block) 1072 if err != nil { 1073 return err 1074 } 1075 1076 // Load all of the spent txos for the block from the spend 1077 // journal. 1078 var stxos []spentTxOut 1079 err = b.db.View(func(dbTx database.Tx) error { 1080 stxos, err = dbFetchSpendJournalEntry(dbTx, block, view) 1081 return err 1082 }) 1083 if err != nil { 1084 return err 1085 } 1086 1087 // Store the loaded block and spend journal entry for later. 1088 detachBlocks = append(detachBlocks, block) 1089 detachSpentTxOuts = append(detachSpentTxOuts, stxos) 1090 1091 err = view.disconnectTransactions(block, stxos) 1092 if err != nil { 1093 return err 1094 } 1095 } 1096 1097 // Perform several checks to verify each block that needs to be attached 1098 // to the main chain can be connected without violating any rules and 1099 // without actually connecting the block. 1100 // 1101 // NOTE: These checks could be done directly when connecting a block, 1102 // however the downside to that approach is that if any of these checks 1103 // fail after disconnecting some blocks or attaching others, all of the 1104 // operations have to be rolled back to get the chain back into the 1105 // state it was before the rule violation (or other failure). There are 1106 // at least a couple of ways accomplish that rollback, but both involve 1107 // tweaking the chain and/or database. This approach catches these 1108 // issues before ever modifying the chain. 1109 for e := attachNodes.Front(); e != nil; e = e.Next() { 1110 n := e.Value.(*blockNode) 1111 block := b.blockCache[*n.hash] 1112 1113 // Notice the spent txout details are not requested here and 1114 // thus will not be generated. This is done because the state 1115 // is not being immediately written to the database, so it is 1116 // not needed. 1117 err := b.checkConnectBlock(n, block, view, nil) 1118 if err != nil { 1119 return err 1120 } 1121 } 1122 1123 // Skip disconnecting and connecting the blocks when running with the 1124 // dry run flag set. 1125 if flags&BFDryRun == BFDryRun { 1126 return nil 1127 } 1128 1129 // Reset the view for the actual connection code below. This is 1130 // required because the view was previously modified when checking if 1131 // the reorg would be successful and the connection code requires the 1132 // view to be valid from the viewpoint of each block being connected or 1133 // disconnected. 1134 view = NewUtxoViewpoint() 1135 view.SetBestHash(b.bestNode.hash) 1136 1137 // Disconnect blocks from the main chain. 1138 for i, e := 0, detachNodes.Front(); e != nil; i, e = i+1, e.Next() { 1139 n := e.Value.(*blockNode) 1140 block := detachBlocks[i] 1141 1142 // Load all of the utxos referenced by the block that aren't 1143 // already in the view. 1144 err := view.fetchInputUtxos(b.db, block) 1145 if err != nil { 1146 return err 1147 } 1148 1149 // Update the view to unspend all of the spent txos and remove 1150 // the utxos created by the block. 1151 err = view.disconnectTransactions(block, detachSpentTxOuts[i]) 1152 if err != nil { 1153 return err 1154 } 1155 1156 // Update the database and chain state. 1157 err = b.disconnectBlock(n, block, view) 1158 if err != nil { 1159 return err 1160 } 1161 } 1162 1163 // Connect the new best chain blocks. 1164 for e := attachNodes.Front(); e != nil; e = e.Next() { 1165 n := e.Value.(*blockNode) 1166 block := b.blockCache[*n.hash] 1167 1168 // Load all of the utxos referenced by the block that aren't 1169 // already in the view. 1170 err := view.fetchInputUtxos(b.db, block) 1171 if err != nil { 1172 return err 1173 } 1174 1175 // Update the view to mark all utxos referenced by the block 1176 // as spent and add all transactions being created by this block 1177 // to it. Also, provide an stxo slice so the spent txout 1178 // details are generated. 1179 stxos := make([]spentTxOut, 0, countSpentOutputs(block)) 1180 err = view.connectTransactions(block, &stxos) 1181 if err != nil { 1182 return err 1183 } 1184 1185 // Update the database and chain state. 1186 err = b.connectBlock(n, block, view, stxos) 1187 if err != nil { 1188 return err 1189 } 1190 delete(b.blockCache, *n.hash) 1191 } 1192 1193 return nil 1194 } 1195 1196 // connectBestChain handles connecting the passed block to the chain while 1197 // respecting proper chain selection according to the chain with the most 1198 // proof of work. In the typical case, the new block simply extends the main 1199 // chain. However, it may also be extending (or creating) a side chain (fork) 1200 // which may or may not end up becoming the main chain depending on which fork 1201 // cumulatively has the most proof of work. It returns whether or not the block 1202 // ended up on the main chain (either due to extending the main chain or causing 1203 // a reorganization to become the main chain). 1204 // 1205 // The flags modify the behavior of this function as follows: 1206 // - BFFastAdd: Avoids several expensive transaction validation operations. 1207 // This is useful when using checkpoints. 1208 // - BFDryRun: Prevents the block from being connected and avoids modifying the 1209 // state of the memory chain index. Also, any (don't) log messages related 1210 // to modifying the state are avoided. 1211 // 1212 // This function MUST be called with the chain state lock held (for writes). 1213 func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, flags BehaviorFlags) (bool, error) { 1214 fastAdd := flags&BFFastAdd == BFFastAdd 1215 dryRun := flags&BFDryRun == BFDryRun 1216 1217 // We are extending the main (best) chain with a new block. This is the 1218 // most common case. 1219 if node.parentHash.IsEqual(b.bestNode.hash) { 1220 // Perform several checks to verify the block can be connected 1221 // to the main chain without violating any rules and without 1222 // actually connecting the block. 1223 view := NewUtxoViewpoint() 1224 view.SetBestHash(node.parentHash) 1225 stxos := make([]spentTxOut, 0, countSpentOutputs(block)) 1226 if !fastAdd { 1227 err := b.checkConnectBlock(node, block, view, &stxos) 1228 if err != nil { 1229 return false, err 1230 } 1231 } 1232 1233 // Don't connect the block if performing a dry run. 1234 if dryRun { 1235 return true, nil 1236 } 1237 1238 // In the fast add case the code to check the block connection 1239 // was skipped, so the utxo view needs to load the referenced 1240 // utxos, spend them, and add the new utxos being created by 1241 // this block. 1242 if fastAdd { 1243 err := view.fetchInputUtxos(b.db, block) 1244 if err != nil { 1245 return false, err 1246 } 1247 err = view.connectTransactions(block, &stxos) 1248 if err != nil { 1249 return false, err 1250 } 1251 } 1252 1253 // Connect the block to the main chain. 1254 err := b.connectBlock(node, block, view, stxos) 1255 if err != nil { 1256 return false, err 1257 } 1258 1259 // Connect the parent node to this node. 1260 if node.parent != nil { 1261 node.parent.children = append(node.parent.children, node) 1262 } 1263 1264 return true, nil 1265 } 1266 1267 // We're extending (or creating) a side chain which may or may not 1268 // become the main chain, but in either case we need the block stored 1269 // for future processing, so add the block to the side chain holding 1270 // cache. 1271 b.blockCache[*node.hash] = block 1272 b.index[*node.hash] = node 1273 1274 // Connect the parent node to this node. 1275 node.inMainChain = false 1276 node.parent.children = append(node.parent.children, node) 1277 1278 // Remove the block from the side chain cache and disconnect it from the 1279 // parent node when the function returns when running in dry run mode. 1280 if dryRun { 1281 defer func() { 1282 children := node.parent.children 1283 children = removeChildNode(children, node) 1284 node.parent.children = children 1285 1286 delete(b.index, *node.hash) 1287 delete(b.blockCache, *node.hash) 1288 }() 1289 } 1290 1291 // We're extending (or creating) a side chain, but the cumulative 1292 // work for this new side chain is not enough to make it the new chain. 1293 if node.workSum.Cmp(b.bestNode.workSum) <= 0 { 1294 // Skip Logging info when the dry run flag is set. 1295 if dryRun { 1296 return false, nil 1297 } 1298 1299 // Find the fork point. 1300 fork := node 1301 for ; fork.parent != nil; fork = fork.parent { 1302 if fork.inMainChain { 1303 break 1304 } 1305 } 1306 1307 return false, nil 1308 } 1309 1310 // We're extending (or creating) a side chain and the cumulative work 1311 // for this new side chain is more than the old best chain, so this side 1312 // chain needs to become the main chain. In order to accomplish that, 1313 // find the common ancestor of both sides of the fork, disconnect the 1314 // blocks that form the (now) old fork from the main chain, and attach 1315 // the blocks that form the new chain to the main chain starting at the 1316 // common ancenstor (the point where the chain forked). 1317 detachNodes, attachNodes := b.getReorganizeNodes(node) 1318 1319 // Reorganize the chain. 1320 err := b.reorganizeChain(detachNodes, attachNodes, flags) 1321 if err != nil { 1322 return false, err 1323 } 1324 1325 return true, nil 1326 } 1327 1328 // IsCurrent returns whether or not the chain believes it is current. Several 1329 // factors are used to guess, but the key factors that allow the chain to 1330 // believe it is current are: 1331 // - Latest block height is after the latest checkpoint (if enabled) 1332 // - Latest block has a timestamp newer than 24 hours ago 1333 // 1334 // This function is safe for concurrent access. 1335 func (b *BlockChain) IsCurrent() bool { 1336 b.chainLock.RLock() 1337 defer b.chainLock.RUnlock() 1338 1339 // Not current if the latest main (best) chain height is before the 1340 // latest known good checkpoint (when checkpoints are enabled). 1341 checkpoint := b.latestCheckpoint() 1342 if checkpoint != nil && b.bestNode.height < checkpoint.Height { 1343 return false 1344 } 1345 1346 // Not current if the latest best block has a timestamp before 24 hours 1347 // ago. 1348 minus24Hours := b.timeSource.AdjustedTime().Add(-24 * time.Hour) 1349 if b.bestNode.timestamp.Before(minus24Hours) { 1350 return false 1351 } 1352 1353 // The chain appears to be current if the above checks did not report 1354 // otherwise. 1355 return true 1356 } 1357 1358 // BestSnapshot returns information about the current best chain block and 1359 // related state as of the current point in time. The returned instance must be 1360 // treated as immutable since it is shared by all callers. 1361 // 1362 // This function is safe for concurrent access. 1363 func (b *BlockChain) BestSnapshot() *BestState { 1364 b.stateLock.RLock() 1365 snapshot := b.stateSnapshot 1366 b.stateLock.RUnlock() 1367 return snapshot 1368 } 1369 1370 // IndexManager provides a generic interface that the is called when blocks are 1371 // connected and disconnected to and from the tip of the main chain for the 1372 // purpose of supporting optional indexes. 1373 type IndexManager interface { 1374 // Init is invoked during chain initialize in order to allow the index 1375 // manager to initialize itself and any indexes it is managing. 1376 Init(*BlockChain) error 1377 1378 // ConnectBlock is invoked when a new block has been connected to the 1379 // main chain. 1380 ConnectBlock(database.Tx, *btcutil.Block, *UtxoViewpoint) error 1381 1382 // DisconnectBlock is invoked when a block has been disconnected from 1383 // the main chain. 1384 DisconnectBlock(database.Tx, *btcutil.Block, *UtxoViewpoint) error 1385 } 1386 1387 // Config is a descriptor which specifies the blockchain instance configuration. 1388 type Config struct { 1389 // DB defines the database which houses the blocks and will be used to 1390 // store all metadata created by this package such as the utxo set. 1391 // 1392 // This field is required. 1393 DB database.DB 1394 1395 // ChainParams identifies which chain parameters the chain is associated 1396 // with. 1397 // 1398 // This field is required. 1399 ChainParams *coinparam.Params 1400 1401 // TimeSource defines the median time source to use for things such as 1402 // block processing and determining whether or not the chain is current. 1403 // 1404 // The caller is expected to keep a reference to the time source as well 1405 // and add time samples from other peers on the network so the local 1406 // time is adjusted to be in agreement with other peers. 1407 TimeSource MedianTimeSource 1408 1409 // Notifications defines a callback to which notifications will be sent 1410 // when various events take place. See the documentation for 1411 // Notification and NotificationType for details on the types and 1412 // contents of notifications. 1413 // 1414 // This field can be nil if the caller is not interested in receiving 1415 // notifications. 1416 Notifications NotificationCallback 1417 1418 // SigCache defines a signature cache to use when when validating 1419 // signatures. This is typically most useful when individual 1420 // transactions are already being validated prior to their inclusion in 1421 // a block such as what is usually done via a transaction memory pool. 1422 // 1423 // This field can be nil if the caller is not interested in using a 1424 // signature cache. 1425 SigCache *txscript.SigCache 1426 1427 // IndexManager defines an index manager to use when initializing the 1428 // chain and connecting and disconnecting blocks. 1429 // 1430 // This field can be nil if the caller does not wish to make use of an 1431 // index manager. 1432 IndexManager IndexManager 1433 1434 // HashCache defines a transaction hash mid-state cache to use when 1435 // validating transactions. This cache has the potentil to greatly 1436 // speed up transaction validation as re-using the pre-calculated 1437 // mid-state eliminates the O(N^2) validation complexity due to the 1438 // SigHashAll flag. 1439 // 1440 // This field can be nil if the caller is not interested in using a 1441 // signature cache. 1442 HashCache *txscript.HashCache 1443 } 1444 1445 // New returns a BlockChain instance using the provided configuration details. 1446 func New(config *Config) (*BlockChain, error) { 1447 // Enforce required config fields. 1448 if config.DB == nil { 1449 return nil, AssertError("blockchain.New database is nil") 1450 } 1451 if config.ChainParams == nil { 1452 return nil, AssertError("blockchain.New chain parameters nil") 1453 } 1454 1455 // Generate a checkpoint by height map from the provided checkpoints. 1456 params := config.ChainParams 1457 var checkpointsByHeight map[int32]*coinparam.Checkpoint 1458 if len(params.Checkpoints) > 0 { 1459 checkpointsByHeight = make(map[int32]*coinparam.Checkpoint) 1460 for i := range params.Checkpoints { 1461 checkpoint := ¶ms.Checkpoints[i] 1462 checkpointsByHeight[checkpoint.Height] = checkpoint 1463 } 1464 } 1465 1466 targetTimespan := int64(params.TargetTimespan) 1467 targetTimePerBlock := int64(params.TargetTimePerBlock) 1468 adjustmentFactor := params.RetargetAdjustmentFactor 1469 b := BlockChain{ 1470 checkpointsByHeight: checkpointsByHeight, 1471 db: config.DB, 1472 chainParams: params, 1473 timeSource: config.TimeSource, 1474 notifications: config.Notifications, 1475 sigCache: config.SigCache, 1476 indexManager: config.IndexManager, 1477 minRetargetTimespan: targetTimespan / adjustmentFactor, 1478 maxRetargetTimespan: targetTimespan * adjustmentFactor, 1479 blocksPerRetarget: int32(targetTimespan / targetTimePerBlock), 1480 minMemoryNodes: int32(targetTimespan / targetTimePerBlock), 1481 hashCache: config.HashCache, 1482 bestNode: nil, 1483 index: make(map[chainhash.Hash]*blockNode), 1484 depNodes: make(map[chainhash.Hash][]*blockNode), 1485 orphans: make(map[chainhash.Hash]*orphanBlock), 1486 prevOrphans: make(map[chainhash.Hash][]*orphanBlock), 1487 blockCache: make(map[chainhash.Hash]*btcutil.Block), 1488 } 1489 1490 // Initialize the chain state from the passed database. When the db 1491 // does not yet contain any chain state, both it and the chain state 1492 // will be initialized to contain only the genesis block. 1493 if err := b.initChainState(); err != nil { 1494 return nil, err 1495 } 1496 1497 // Initialize and catch up all of the currently active optional indexes 1498 // as needed. 1499 if config.IndexManager != nil { 1500 if err := config.IndexManager.Init(&b); err != nil { 1501 return nil, err 1502 } 1503 } 1504 1505 return &b, nil 1506 }