Skip to content

Commit

Permalink
blockchain: Refactor to use new chain view.
Browse files Browse the repository at this point in the history
This refactors and simplifies the code in blockchain to use the new more
efficient chain views.

An overview of the logic changes are as follows:

- Remove inMainChain from block nodes since that can now be efficiently
  determined by using the chain view
- Track the best chain via a chain view instead of a single block node
  - Use the tip of the best chain view everywhere bestNode was used
  - Update chain view tip instead of updating best node
- Remove height map and associated lock in favor of chain view
  - Use chain view NodeByHeight everywhere height map was used
- Change reorg logic to use more efficient chain view fork finding logic
- Change block locator code over to use more efficient chain view logic
  - Remove now unused block-index-based block locator code
  - Move BlockLocator definition to chain.go
  - Move BlockLocatorFromHash and LatestBlockLocator to chain.go
    - Update both to use more efficient chain view logic
- Rework several functions to use chain view for main chain detection
  - fetchMainChainBlockByNode
  - BlockByHeight
  - MainChainHasBlock
  - findPreviousCheckpoint
  - IsCheckpointCandidate
  • Loading branch information
davecgh committed Jul 20, 2018
1 parent 6254fea commit 9ef7db9
Show file tree
Hide file tree
Showing 24 changed files with 264 additions and 417 deletions.
4 changes: 2 additions & 2 deletions blockchain/accept.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func (b *BlockChain) maybeAcceptBlock(block *dcrutil.Block, flags BehaviorFlags)

// Fetching a stake node could enable a new DoS vector, so restrict
// this only to blocks that are recent in history.
if newNode.height < b.bestNode.height-minMemoryNodes {
if newNode.height < b.bestChain.Tip().height-minMemoryNodes {
newNode.stakeNode, err = b.fetchStakeNode(newNode)
if err != nil {
return 0, err
Expand All @@ -205,7 +205,7 @@ func (b *BlockChain) maybeAcceptBlock(block *dcrutil.Block, flags BehaviorFlags)
// Notify the caller that the new block was accepted into the block
// chain. The caller would typically want to react by relaying the
// inventory to other peers.
bestHeight := b.bestNode.height
bestHeight := b.bestChain.Tip().height
b.chainLock.Unlock()
b.sendNotification(NTBlockAccepted, &BlockAcceptedNtfnsData{
BestHeight: bestHeight,
Expand Down
4 changes: 2 additions & 2 deletions blockchain/agendas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func testLNFeaturesDeployment(t *testing.T, params *chaincfg.Params, deploymentV

curTimestamp := time.Now()
bc := newFakeChain(params)
node := bc.bestNode
node := bc.bestChain.Tip()
for _, test := range tests {
for i := uint32(0); i < test.numNodes; i++ {
node = newFakeNode(node, int32(deploymentVer),
Expand All @@ -122,7 +122,7 @@ func testLNFeaturesDeployment(t *testing.T, params *chaincfg.Params, deploymentV
Bits: yesChoice.Bits | 0x01,
})
}
bc.bestNode = node
bc.bestChain.SetTip(node)
curTimestamp = curTimestamp.Add(time.Second)
}

Expand Down
5 changes: 0 additions & 5 deletions blockchain/blockindex.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,6 @@ type blockNode struct {
// methods on blockIndex once the node has been added to the index.
status blockStatus

// inMainChain denotes whether the block node is currently on the
// the main chain or not. This is used to help find the common
// ancestor when switching chains.
inMainChain bool

// stakeNode contains all the consensus information required for the
// staking system. The node also caches information required to add or
// remove stake nodes, so that the stake node itself may be pruneable
Expand Down
11 changes: 6 additions & 5 deletions blockchain/blockindex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ func TestBlockNodeHeader(t *testing.T) {
// values.
params := &chaincfg.SimNetParams
bc := newFakeChain(params)
tip := bc.bestChain.Tip()
testHeader := wire.BlockHeader{
Version: 1,
PrevBlock: bc.bestNode.hash,
PrevBlock: tip.hash,
MerkleRoot: *mustParseHash("09876543210987654321"),
StakeRoot: *mustParseHash("43210987654321098765"),
VoteBits: 0x03,
Expand All @@ -54,7 +55,7 @@ func TestBlockNodeHeader(t *testing.T) {
ExtraData: [32]byte{0xbb},
StakeVersion: 5,
}
node := newBlockNode(&testHeader, bc.bestNode)
node := newBlockNode(&testHeader, tip)
bc.index.AddNode(node)

// Ensure reconstructing the header for the node produces the same header
Expand Down Expand Up @@ -154,11 +155,11 @@ func TestCalcPastMedianTime(t *testing.T) {
// Create a synthetic chain with the correct number of nodes and the
// timestamps as specified by the test.
bc := newFakeChain(params)
node := bc.bestNode
node := bc.bestChain.Tip()
for _, timestamp := range test.timestamps {
node = newFakeNode(node, 0, 0, 0, time.Unix(timestamp, 0))
bc.index.AddNode(node)
bc.bestNode = node
bc.bestChain.SetTip(node)
}

// Ensure the median time is the expected value.
Expand All @@ -177,7 +178,7 @@ func TestCalcPastMedianTime(t *testing.T) {
func TestChainTips(t *testing.T) {
params := &chaincfg.SimNetParams
bc := newFakeChain(params)
genesis := bc.bestNode
genesis := bc.bestChain.NodeByHeight(0)

// Construct a synthetic simnet chain consisting of the following structure.
// 0 -> 1 -> 2 -> 3 -> 4
Expand Down
137 changes: 0 additions & 137 deletions blockchain/blocklocator.go

This file was deleted.

Loading

0 comments on commit 9ef7db9

Please sign in to comment.