This updates the blockchain module dependencies, the copyright year in the files modified since the previous release, and serves as a base for blockchain/v3.0.0. The updated direct dependencies in this commit are as follows: - github.com/decred/dcrd/blockchain/stake/v3@v3.0.0 - github.com/decred/dcrd/blockchain/standalone/v2@v2.0.0 - github.com/decred/dcrd/chaincfg/v3@v3.0.0 - github.com/decred/dcrd/dcrec/secp256k1/v3@v3.0.0 - github.com/decred/dcrd/dcrutil/v3 v3.0.0 - github.com/decred/dcrd/gcs/v2@v2.1.0 - github.com/decred/dcrd/txscript/v3@v3.0.0 The full list of updated direct dependencies since the previous blockchain/v2.1.0 release are as follows: - github.com/decred/dcrd/blockchain/stake/v3@v3.0.0 - github.com/decred/dcrd/blockchain/standalone/v2@v2.0.0 - github.com/decred/dcrd/chaincfg/v3@v3.0.0 - github.com/decred/dcrd/database/v2@v2.0.2 - github.com/decred/dcrd/dcrec/secp256k1/v3@v3.0.0 - github.com/decred/dcrd/dcrutil/v3 v3.0.0 - github.com/decred/dcrd/gcs/v2@v2.1.0 - github.com/decred/dcrd/txscript/v3@v3.0.0 - github.com/decred/dcrd/wire@v1.4.0 - github.com/decred/slog@v1.1.0 Finally, all modules in the repository are tidied to ensure they are updated to use the latest versions hoisted forward as a result.
101 lines
3.3 KiB
Go
101 lines
3.3 KiB
Go
// Copyright (c) 2013-2016 The btcsuite developers
|
|
// Copyright (c) 2015-2020 The Decred developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package blockchain
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/decred/dcrd/dcrutil/v3"
|
|
)
|
|
|
|
// BehaviorFlags is a bitmask defining tweaks to the normal behavior when
|
|
// performing chain processing and consensus rules checks.
|
|
type BehaviorFlags uint32
|
|
|
|
const (
|
|
// BFFastAdd may be set to indicate that several checks can be avoided
|
|
// for the block since it is already known to fit into the chain due to
|
|
// already proving it correct links into the chain up to a known
|
|
// checkpoint. This is primarily used for headers-first mode.
|
|
BFFastAdd BehaviorFlags = 1 << iota
|
|
|
|
// BFNoPoWCheck may be set to indicate the proof of work check which
|
|
// ensures a block hashes to a value less than the required target will
|
|
// not be performed.
|
|
BFNoPoWCheck
|
|
|
|
// BFNone is a convenience value to specifically indicate no flags.
|
|
BFNone BehaviorFlags = 0
|
|
)
|
|
|
|
// ProcessBlock is the main workhorse for handling insertion of new blocks into
|
|
// the block chain. It includes functionality such as rejecting duplicate
|
|
// blocks, ensuring blocks follow all rules, and insertion into the block chain
|
|
// along with best chain selection and reorganization.
|
|
//
|
|
// It is up to the caller to ensure the blocks are processed in order since
|
|
// orphans are rejected.
|
|
//
|
|
// When no errors occurred during processing, the first return value indicates
|
|
// the length of the fork the block extended. In the case it either extended
|
|
// the best chain or is now the tip of the best chain due to causing a
|
|
// reorganize, the fork length will be 0.
|
|
//
|
|
// This function is safe for concurrent access.
|
|
func (b *BlockChain) ProcessBlock(block *dcrutil.Block, flags BehaviorFlags) (int64, error) {
|
|
b.chainLock.Lock()
|
|
defer b.chainLock.Unlock()
|
|
|
|
blockHash := block.Hash()
|
|
log.Tracef("Processing block %v", blockHash)
|
|
currentTime := time.Now()
|
|
defer func() {
|
|
elapsedTime := time.Since(currentTime)
|
|
log.Debugf("Block %v (height %v) finished processing in %s",
|
|
blockHash, block.Height(), elapsedTime)
|
|
}()
|
|
|
|
// The block must not already exist in the main chain or side chains.
|
|
if b.index.HaveBlock(blockHash) {
|
|
str := fmt.Sprintf("already have block %v", blockHash)
|
|
return 0, ruleError(ErrDuplicateBlock, str)
|
|
}
|
|
|
|
blockHeader := &block.MsgBlock().Header
|
|
prevHash := &blockHeader.PrevBlock
|
|
isTreasuryEnabled, err := b.isTreasuryAgendaActiveByHash(prevHash)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
// Perform preliminary sanity checks on the block and its transactions.
|
|
err = checkBlockSanity(block, b.timeSource, flags, b.chainParams,
|
|
isTreasuryEnabled)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
// This function should never be called with orphans or the genesis block.
|
|
if !b.index.HaveBlock(prevHash) {
|
|
// The fork length of orphans is unknown since they, by definition, do
|
|
// not connect to the best chain.
|
|
str := fmt.Sprintf("previous block %s is not known", prevHash)
|
|
return 0, ruleError(ErrMissingParent, str)
|
|
}
|
|
|
|
// The block has passed all context independent checks and appears sane
|
|
// enough to potentially accept it into the block chain.
|
|
forkLen, err := b.maybeAcceptBlock(block, flags)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
log.Debugf("Accepted block %v", blockHash)
|
|
|
|
return forkLen, nil
|
|
}
|