Skip to content

Commit

Permalink
blockchain: update BestState.
Browse files Browse the repository at this point in the history
This adds PrevHash, PoolSize, NextStakeDiff, WinningTickets, MissedTickets and FinalState fields to BestState and updates newBestState accordingly. This is in preparation of the removal of chainState.
  • Loading branch information
dnldd committed Aug 22, 2018
1 parent a1985a4 commit 992e591
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 26 deletions.
79 changes: 55 additions & 24 deletions blockchain/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,27 +86,52 @@ type orphanBlock struct {
// However, the returned snapshot must be treated as immutable since it is
// shared by all callers.
type BestState struct {
Hash chainhash.Hash // The hash of the block.
Height int64 // The height of the block.
Bits uint32 // The difficulty bits of the block.
BlockSize uint64 // The size of the block.
NumTxns uint64 // The number of txns in the block.
TotalTxns uint64 // The total number of txns in the chain.
MedianTime time.Time // Median time as per CalcPastMedianTime.
TotalSubsidy int64 // The total subsidy for the chain.
Hash chainhash.Hash // The hash of the block.
PrevHash chainhash.Hash // The previous block hash.
Height int64 // The height of the block.
Bits uint32 // The difficulty bits of the block.
PoolSize uint32 // The ticket pool size.
NextStakeDiff int64 // The next stake difficulty.
BlockSize uint64 // The size of the block.
NumTxns uint64 // The number of txns in the block.
TotalTxns uint64 // The total number of txns in the chain.
MedianTime time.Time // Median time as per CalcPastMedianTime.
TotalSubsidy int64 // The total subsidy for the chain.
WinningTickets []chainhash.Hash // The eligigle tickets to vote on the next block.
MissedTickets []chainhash.Hash // The missed tickets set to be revoked.
FinalState [6]byte // The calculated state of the lottery.
}

// newBestState returns a new best stats instance for the given parameters.
func newBestState(node *blockNode, blockSize, numTxns, totalTxns uint64, medianTime time.Time, totalSubsidy int64) *BestState {
func newBestState(node *blockNode, blockSize, numTxns, totalTxns uint64, medianTime time.Time, totalSubsidy int64, nextStakeDiff int64) *BestState {
prevHash := *zeroHash
if node.parent != nil {
prevHash = node.parent.hash
}

winners := make([]chainhash.Hash, 0)
if node.stakeNode != nil {
winners = node.stakeNode.Winners()
}

missed := make([]chainhash.Hash, 0)
if node.parent != nil {
missed = node.stakeNode.MissedTickets()
}
return &BestState{
Hash: node.hash,
Height: node.height,
Bits: node.bits,
BlockSize: blockSize,
NumTxns: numTxns,
TotalTxns: totalTxns,
MedianTime: medianTime,
TotalSubsidy: totalSubsidy,
Hash: node.hash,
PrevHash: prevHash,
Height: node.height,
Bits: node.bits,
PoolSize: node.poolSize,
NextStakeDiff: nextStakeDiff,
BlockSize: blockSize,
NumTxns: numTxns,
TotalTxns: totalTxns,
MedianTime: medianTime,
TotalSubsidy: totalSubsidy,
WinningTickets: winners,
MissedTickets: missed,
}
}

Expand Down Expand Up @@ -761,9 +786,11 @@ func (b *BlockChain) connectBlock(node *blockNode, block, parent *dcrutil.Block,
// Calculate the exact subsidy produced by adding the block.
subsidy := CalculateAddedSubsidy(block, parent)

blockSize := uint64(block.MsgBlock().Header.Size)
state := newBestState(node, blockSize, numTxns, curTotalTxns+numTxns,
node.CalcPastMedianTime(), curTotalSubsidy+subsidy)
// Calcultate the next stake difficulty.
nextStakeDiff, err := b.calcNextRequiredStakeDifficulty(node)
if err != nil {
return err
}

// Get the stake node for this node, filling in any data that
// may have yet to have been filled in. In all cases this
Expand All @@ -774,6 +801,10 @@ func (b *BlockChain) connectBlock(node *blockNode, block, parent *dcrutil.Block,
return err
}

blockSize := uint64(block.MsgBlock().Header.Size)
state := newBestState(node, blockSize, numTxns, curTotalTxns+numTxns,
node.CalcPastMedianTime(), curTotalSubsidy+subsidy, nextStakeDiff)

// Atomically insert info into the database.
err = b.db.Update(func(dbTx database.Tx) error {
// Update best block state.
Expand Down Expand Up @@ -934,10 +965,6 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block, parent *dcrutil.Blo
subsidy := CalculateAddedSubsidy(block, parent)
newTotalSubsidy := curTotalSubsidy - subsidy

prevNode := node.parent
state := newBestState(prevNode, parentBlockSize, numTxns, newTotalTxns,
prevNode.CalcPastMedianTime(), newTotalSubsidy)

// Prepare the information required to update the stake database
// contents.
childStakeNode, err := b.fetchStakeNode(node)
Expand All @@ -949,6 +976,10 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block, parent *dcrutil.Blo
return err
}

prevNode := node.parent
state := newBestState(prevNode, parentBlockSize, numTxns, newTotalTxns,
prevNode.CalcPastMedianTime(), newTotalSubsidy, node.sbits)

err = b.db.Update(func(dbTx database.Tx) error {
// Update best block state.
err := dbPutBestState(dbTx, state, node.workSum)
Expand Down
12 changes: 10 additions & 2 deletions blockchain/chainio.go
Original file line number Diff line number Diff line change
Expand Up @@ -1463,8 +1463,9 @@ func (b *BlockChain) createChainState() error {
// genesis block, use its timestamp for the median time.
numTxns := uint64(len(genesisBlock.MsgBlock().Transactions))
blockSize := uint64(genesisBlock.MsgBlock().SerializeSize())

stateSnapshot := newBestState(node, blockSize, numTxns, numTxns,
time.Unix(node.timestamp, 0), 0)
time.Unix(node.timestamp, 0), 0, b.chainParams.MinimumStakeDiff)

// Create the initial the database chain state including creating the
// necessary index buckets and inserting the genesis block.
Expand Down Expand Up @@ -1770,9 +1771,16 @@ func (b *BlockChain) initChainState(interrupt <-chan struct{}) error {
block := utilBlock.MsgBlock()
blockSize := uint64(block.SerializeSize())
numTxns := uint64(len(block.Transactions))

// Calculate the next stake difficulty.
nextStakeDiff, err := b.calcNextRequiredStakeDifficulty(tip)
if err != nil {
return err
}

b.stateSnapshot = newBestState(tip, blockSize, numTxns,
state.totalTxns, tip.CalcPastMedianTime(),
state.totalSubsidy)
state.totalSubsidy, nextStakeDiff)

return nil
})
Expand Down

0 comments on commit 992e591

Please sign in to comment.