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