Skip to content

Commit

Permalink
blockchain: Accept parent in blockNode constructor.
Browse files Browse the repository at this point in the history
This modifies the newBlockNode function to accept the parent as an
argument to automatically connect the newly created node.  When it is
not nil, the work sum will automatically be summed and the parent of the
new node will be set accordingly.

This simplifies the block node construction a bit and allows some
redundant code to be removed.  It also paves the way for easier simpler
full block index construction in the future.
  • Loading branch information
davecgh committed Feb 19, 2018
1 parent ca9ff29 commit cb40146
Show file tree
Hide file tree
Showing 10 changed files with 23 additions and 34 deletions.
7 changes: 1 addition & 6 deletions blockchain/accept.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,6 @@ func (b *BlockChain) maybeAcceptBlock(block *dcrutil.Block, flags BehaviorFlags)
return false, ruleError(ErrMissingParent, str)
}

blockHeight := block.Height()

// The block must pass all of the validation rules which depend on the
// position of the block within the block chain.
err = b.checkBlockContext(block, prevNode, flags)
Expand Down Expand Up @@ -160,11 +158,8 @@ func (b *BlockChain) maybeAcceptBlock(block *dcrutil.Block, flags BehaviorFlags)
// Create a new block node for the block and add it to the in-memory
// block chain (could be either a side chain or the main chain).
blockHeader := &block.MsgBlock().Header
newNode := newBlockNode(blockHeader)
newNode := newBlockNode(blockHeader, prevNode)
newNode.populateTicketInfo(stake.FindSpentTicketsInBlock(block.MsgBlock()))
newNode.parent = prevNode
newNode.height = blockHeight
newNode.workSum.Add(prevNode.workSum, newNode.workSum)

// Fetching a stake node could enable a new DoS vector, so restrict
// this only to blocks that are recent in history.
Expand Down
15 changes: 9 additions & 6 deletions blockchain/blockindex.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,10 @@ type blockNode struct {
votes []stake.VoteVersionTuple
}

// newBlockNode returns a new block node for the given block header. It is
// completely disconnected from the chain and the workSum value is just the work
// for the passed block. The work sum is updated accordingly when the node is
// inserted into a chain.
func newBlockNode(blockHeader *wire.BlockHeader) *blockNode {
// newBlockNode returns a new block node for the given block header and parent
// node. The workSum is calculated based on the parent, or, in the case no
// parent is provided, it will just be the work for the passed block.
func newBlockNode(blockHeader *wire.BlockHeader, parent *blockNode) *blockNode {
// Serialize the block header for use in calculating the initialization
// vector for the ticket lottery. The only way this can fail is if the
// process is out of memory in which case it would panic anyways, so
Expand Down Expand Up @@ -132,6 +131,10 @@ func newBlockNode(blockHeader *wire.BlockHeader) *blockNode {
stakeVersion: blockHeader.StakeVersion,
lotteryIV: stake.CalcHash256PRNGIV(hB),
}
if parent != nil {
node.parent = parent
node.workSum = node.workSum.Add(parent.workSum, node.workSum)
}

return &node
}
Expand Down Expand Up @@ -253,7 +256,7 @@ func (bi *blockIndex) loadBlockNode(dbTx database.Tx, hash *chainhash.Hash) (*bl

// Create the new block node for the block.
blockHeader := block.MsgBlock().Header
node := newBlockNode(&blockHeader)
node := newBlockNode(&blockHeader, nil)
node.populateTicketInfo(stake.FindSpentTicketsInBlock(block.MsgBlock()))
node.inMainChain = true

Expand Down
3 changes: 1 addition & 2 deletions blockchain/blockindex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@ func TestBlockNodeHeader(t *testing.T) {
ExtraData: [32]byte{0xbb},
StakeVersion: 5,
}
node := newBlockNode(&testHeader)
node := newBlockNode(&testHeader, bc.bestNode)
bc.index.AddNode(node)
node.parent = bc.bestNode

// Ensure reconstructing the header for the node produces the same header
// used to create the node.
Expand Down
4 changes: 2 additions & 2 deletions blockchain/chainio.go
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ func (b *BlockChain) createChainState() error {
// Create a new node from the genesis block and set it as the best node.
genesisBlock := dcrutil.NewBlock(b.chainParams.GenesisBlock)
header := &genesisBlock.MsgBlock().Header
node := newBlockNode(header)
node := newBlockNode(header, nil)
node.inMainChain = true

// Initialize the state related to the best block. Since it is the
Expand Down Expand Up @@ -1476,7 +1476,7 @@ func (b *BlockChain) initChainState(interrupt <-chan struct{}) error {
// Create a new node and set it as the best node. The preceding
// nodes will be loaded on demand as needed.
header := &block.Header
node := newBlockNode(header)
node := newBlockNode(header, nil)
node.populateTicketInfo(stake.FindSpentTicketsInBlock(&block))
node.inMainChain = true
node.workSum = state.workSum
Expand Down
3 changes: 1 addition & 2 deletions blockchain/difficulty.go
Original file line number Diff line number Diff line change
Expand Up @@ -1087,8 +1087,7 @@ func (b *BlockChain) estimateNextStakeDifficultyV1(curNode *blockNode, ticketsIn
// Connect the header.
emptyHeader.PrevBlock = topNode.hash

thisNode := newBlockNode(&emptyHeader)
thisNode.parent = topNode
thisNode := newBlockNode(&emptyHeader, topNode)
topNode = thisNode
}
}
Expand Down
6 changes: 2 additions & 4 deletions blockchain/difficulty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,7 @@ nextTest:
FreshStake: ticketInfo.newTickets,
PoolSize: poolSize,
}
node := newBlockNode(header)
node.parent = bc.bestNode
node := newBlockNode(header, bc.bestNode)

// Update the pool size for the next header.
// Notice how tickets that mature for this block
Expand Down Expand Up @@ -729,8 +728,7 @@ nextTest:
FreshStake: ticketInfo.newTickets,
PoolSize: poolSize,
}
node := newBlockNode(header)
node.parent = bc.bestNode
node := newBlockNode(header, bc.bestNode)

// Update the pool size for the next header.
// Notice how tickets that mature for this block
Expand Down
4 changes: 2 additions & 2 deletions blockchain/internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ func (b *BlockChain) TstCheckBlockHeaderContext(header *wire.BlockHeader, prevNo

// TstNewBlockNode makes the internal newBlockNode function available to the
// test package.
func TstNewBlockNode(blockHeader *wire.BlockHeader) *blockNode {
return newBlockNode(blockHeader)
func TstNewBlockNode(blockHeader *wire.BlockHeader, parent *blockNode) *blockNode {
return newBlockNode(blockHeader, parent)
}
7 changes: 2 additions & 5 deletions blockchain/stakeversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
func newFakeChain(params *chaincfg.Params) *BlockChain {
// Create a genesis block node and block index populated with it for use
// when creating the fake chain below.
node := newBlockNode(&params.GenesisBlock.Header)
node := newBlockNode(&params.GenesisBlock.Header, nil)
node.inMainChain = true
index := newBlockIndex(nil, params)
index.AddNode(node)
Expand Down Expand Up @@ -53,10 +53,7 @@ func newFakeNode(parent *blockNode, blockVersion int32, stakeVersion uint32, bit
Timestamp: timestamp,
StakeVersion: stakeVersion,
}
node := newBlockNode(header)
node.parent = parent
node.workSum.Add(parent.workSum, node.workSum)
return node
return newBlockNode(header, parent)
}

// appendFakeVotes appends the passed number of votes to the node with the
Expand Down
4 changes: 1 addition & 3 deletions blockchain/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2601,10 +2601,8 @@ func (b *BlockChain) CheckConnectBlock(block *dcrutil.Block, flags BehaviorFlags
return err
}

newNode := newBlockNode(&block.MsgBlock().Header)
newNode := newBlockNode(&block.MsgBlock().Header, prevNode)
newNode.populateTicketInfo(stake.FindSpentTicketsInBlock(block.MsgBlock()))
newNode.parent = prevNode
newNode.workSum.Add(prevNode.workSum, newNode.workSum)

// If we are extending the main (best) chain with a new block, just use
// the ticket database we already have.
Expand Down
4 changes: 2 additions & 2 deletions blockchain/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2110,7 +2110,7 @@ func TestCheckWorklessBlockSanity(t *testing.T) {
}

// TestCheckBlockHeaderContext tests that genesis block passes context headers
// because it's previousNode is nil.
// because its parent is nil.
func TestCheckBlockHeaderContext(t *testing.T) {
// Create a new database for the blocks.
params := &chaincfg.SimNetParams
Expand Down Expand Up @@ -2145,7 +2145,7 @@ func TestCheckBlockHeaderContext(t *testing.T) {
// Test failing checkBlockHeaderContext when calcNextRequiredDifficulty
// fails.
block := dcrutil.NewBlock(&badBlock)
newNode := blockchain.TstNewBlockNode(&block.MsgBlock().Header)
newNode := blockchain.TstNewBlockNode(&block.MsgBlock().Header, nil)
err = chain.TstCheckBlockHeaderContext(&block.MsgBlock().Header, newNode, blockchain.BFNone)
if err == nil {
t.Fatalf("Should fail due to bad diff in newNode\n")
Expand Down

0 comments on commit cb40146

Please sign in to comment.