github.com/NebulousLabs/Sia@v1.3.7/modules/consensus/block_rules.go (about)

     1  package consensus
     2  
     3  import (
     4  	"sort"
     5  
     6  	"github.com/NebulousLabs/Sia/encoding"
     7  	"github.com/NebulousLabs/Sia/types"
     8  )
     9  
    10  // blockRuleHelper assists with block validity checks by calculating values
    11  // on blocks that are relevant to validity rules.
    12  type blockRuleHelper interface {
    13  	minimumValidChildTimestamp(dbBucket, *processedBlock) types.Timestamp
    14  }
    15  
    16  // stdBlockRuleHelper is the standard implementation of blockRuleHelper.
    17  type stdBlockRuleHelper struct{}
    18  
    19  // minimumValidChildTimestamp returns the earliest timestamp that a child node
    20  // can have while still being valid. See section 'Block Timestamps' in
    21  // Consensus.md.
    22  //
    23  // To boost performance, minimumValidChildTimestamp is passed a bucket that it
    24  // can use from inside of a boltdb transaction.
    25  func (rh stdBlockRuleHelper) minimumValidChildTimestamp(blockMap dbBucket, pb *processedBlock) types.Timestamp {
    26  	// Get the previous MedianTimestampWindow timestamps.
    27  	windowTimes := make(types.TimestampSlice, types.MedianTimestampWindow)
    28  	windowTimes[0] = pb.Block.Timestamp
    29  	parent := pb.Block.ParentID
    30  	for i := uint64(1); i < types.MedianTimestampWindow; i++ {
    31  		// If the genesis block is 'parent', use the genesis block timestamp
    32  		// for all remaining times.
    33  		if parent == (types.BlockID{}) {
    34  			windowTimes[i] = windowTimes[i-1]
    35  			continue
    36  		}
    37  
    38  		// Get the next parent's bytes. Because the ordering is specific, the
    39  		// parent does not need to be decoded entirely to get the desired
    40  		// information. This provides a performance boost. The id of the next
    41  		// parent lies at the first 32 bytes, and the timestamp of the block
    42  		// lies at bytes 40-48.
    43  		parentBytes := blockMap.Get(parent[:])
    44  		copy(parent[:], parentBytes[:32])
    45  		windowTimes[i] = types.Timestamp(encoding.DecUint64(parentBytes[40:48]))
    46  	}
    47  	sort.Sort(windowTimes)
    48  
    49  	// Return the median of the sorted timestamps.
    50  	return windowTimes[len(windowTimes)/2]
    51  }