blockchain: Move check block context func.

This moves the checkBlockContext function to back to validate.go next to
checkBlockHeaderContext where it belongs to help minimize the
differences between the upstream code in order to facilitate easier
syncs due to less merge conflicts as a result of superfluous changes.
This commit is contained in:
Dave Collins 2018-02-01 22:03:16 -06:00
parent a1ee4e5875
commit e6806d578e
No known key found for this signature in database
GPG Key ID: B8904D9D9C93D1F2
2 changed files with 89 additions and 89 deletions

View File

@ -96,95 +96,6 @@ func IsFinalizedTransaction(tx *dcrutil.Tx, blockHeight int64, blockTime time.Ti
return true
}
// checkBlockContext peforms several validation checks on the block which depend
// on its position within the block chain.
//
// The flags modify the behavior of this function as follows:
// - BFFastAdd: The transaction are not checked to see if they are finalized
// and the somewhat expensive duplication transaction check is not performed.
//
// The flags are also passed to checkBlockHeaderContext. See its documentation
// for how the flags modify its behavior.
func (b *BlockChain) checkBlockContext(block *dcrutil.Block, prevNode *blockNode, flags BehaviorFlags) error {
// The genesis block is valid by definition.
if prevNode == nil {
return nil
}
// Perform all block header related validation checks.
header := &block.MsgBlock().Header
err := b.checkBlockHeaderContext(header, prevNode, flags)
if err != nil {
return err
}
fastAdd := flags&BFFastAdd == BFFastAdd
if !fastAdd {
// A block must not exceed the maximum allowed size as defined
// by the network parameters and the current status of any hard
// fork votes to change it when serialized.
maxBlockSize, err := b.maxBlockSize(prevNode)
if err != nil {
return err
}
serializedSize := int64(block.MsgBlock().Header.Size)
if serializedSize > maxBlockSize {
str := fmt.Sprintf("serialized block is too big - "+
"got %d, max %d", serializedSize,
maxBlockSize)
return ruleError(ErrBlockTooBig, str)
}
// Switch to using the past median time of the block prior to
// the block being checked for all checks related to lock times
// once the stake vote for the agenda is active.
blockTime := header.Timestamp
lnFeaturesActive, err := b.isLNFeaturesAgendaActive(prevNode)
if err != nil {
return err
}
if lnFeaturesActive {
medianTime, err := b.index.CalcPastMedianTime(prevNode)
if err != nil {
return err
}
blockTime = medianTime
}
// The height of this block is one more than the referenced
// previous block.
blockHeight := prevNode.height + 1
// Ensure all transactions in the block are finalized.
for _, tx := range block.Transactions() {
if !IsFinalizedTransaction(tx, blockHeight, blockTime) {
str := fmt.Sprintf("block contains unfinalized regular "+
"transaction %v", tx.Hash())
return ruleError(ErrUnfinalizedTx, str)
}
}
for _, stx := range block.STransactions() {
if !IsFinalizedTransaction(stx, blockHeight, blockTime) {
str := fmt.Sprintf("block contains unfinalized stake "+
"transaction %v", stx.Hash())
return ruleError(ErrUnfinalizedTx, str)
}
}
// Check that the coinbase contains at minimum the block
// height in output 1.
if blockHeight > 1 {
err := checkCoinbaseUniqueHeight(blockHeight, block)
if err != nil {
return err
}
}
}
return nil
}
// ticketsSpentInBlock fetches a list of tickets that were spent in the
// block.
func ticketsSpentInBlock(bl *dcrutil.Block) []chainhash.Hash {

View File

@ -852,6 +852,95 @@ func (b *BlockChain) checkBlockHeaderContext(header *wire.BlockHeader, prevNode
return nil
}
// checkBlockContext peforms several validation checks on the block which depend
// on its position within the block chain.
//
// The flags modify the behavior of this function as follows:
// - BFFastAdd: The transactions are not checked to see if they are finalized
// and the somewhat expensive duplication transaction check is not performed.
//
// The flags are also passed to checkBlockHeaderContext. See its documentation
// for how the flags modify its behavior.
func (b *BlockChain) checkBlockContext(block *dcrutil.Block, prevNode *blockNode, flags BehaviorFlags) error {
// The genesis block is valid by definition.
if prevNode == nil {
return nil
}
// Perform all block header related validation checks.
header := &block.MsgBlock().Header
err := b.checkBlockHeaderContext(header, prevNode, flags)
if err != nil {
return err
}
fastAdd := flags&BFFastAdd == BFFastAdd
if !fastAdd {
// A block must not exceed the maximum allowed size as defined
// by the network parameters and the current status of any hard
// fork votes to change it when serialized.
maxBlockSize, err := b.maxBlockSize(prevNode)
if err != nil {
return err
}
serializedSize := int64(block.MsgBlock().Header.Size)
if serializedSize > maxBlockSize {
str := fmt.Sprintf("serialized block is too big - "+
"got %d, max %d", serializedSize,
maxBlockSize)
return ruleError(ErrBlockTooBig, str)
}
// Switch to using the past median time of the block prior to
// the block being checked for all checks related to lock times
// once the stake vote for the agenda is active.
blockTime := header.Timestamp
lnFeaturesActive, err := b.isLNFeaturesAgendaActive(prevNode)
if err != nil {
return err
}
if lnFeaturesActive {
medianTime, err := b.index.CalcPastMedianTime(prevNode)
if err != nil {
return err
}
blockTime = medianTime
}
// The height of this block is one more than the referenced
// previous block.
blockHeight := prevNode.height + 1
// Ensure all transactions in the block are finalized.
for _, tx := range block.Transactions() {
if !IsFinalizedTransaction(tx, blockHeight, blockTime) {
str := fmt.Sprintf("block contains unfinalized regular "+
"transaction %v", tx.Hash())
return ruleError(ErrUnfinalizedTx, str)
}
}
for _, stx := range block.STransactions() {
if !IsFinalizedTransaction(stx, blockHeight, blockTime) {
str := fmt.Sprintf("block contains unfinalized stake "+
"transaction %v", stx.Hash())
return ruleError(ErrUnfinalizedTx, str)
}
}
// Check that the coinbase contains at minimum the block
// height in output 1.
if blockHeight > 1 {
err := checkCoinbaseUniqueHeight(blockHeight, block)
if err != nil {
return err
}
}
}
return nil
}
// checkDupTxs ensures blocks do not contain duplicate transactions which
// 'overwrite' older transactions that are not fully spent. This prevents an
// attack where a coinbase and all of its dependent transactions could be