func (b *BlockChain) computeNextStakeModifier(node *blockNode) (uint64, bool, error) {
	if node.height == 0 || node.height == 1 {
		return blockOneStakeModifier, true, nil
	}

	lastStakeModifierBlock := node
	for lastStakeModifierBlock != nil && !b.index.GeneratedStakeModifier(lastStakeModifierBlock) {
		lastStakeModifierBlock = lastStakeModifierBlock.parent
	}

	stakeModifier := lastStakeModifierBlock.stakeModifier

	modifierTime := lastStakeModifierBlock.timestamp

	if modifierTime/60 >= node.timestamp/60 {
		return b.index.GetStakeModifier(lastStakeModifierBlock), false, nil
	}

	selectionIntervalStart := (node.timestamp/60)*60 - int64(stakeModifierSelectionInterval.Seconds())

	var nodesSortedByTimestamp []timeAndBlockNode

	for node != nil && node.timestamp >= selectionIntervalStart {
		nodesSortedByTimestamp = append([]timeAndBlockNode{
			{time: time.Unix(node.timestamp, 0), node: node},
		}, nodesSortedByTimestamp...)
		node = node.parent
	}

	sort.Slice(nodesSortedByTimestamp, func(a, b int) bool {
		if nodesSortedByTimestamp[a].time.Unix() == nodesSortedByTimestamp[b].time.Unix() {
			return HashToBig(&nodesSortedByTimestamp[a].node.hash).Cmp(HashToBig(&nodesSortedByTimestamp[b].node.hash)) < 0
		}
		return nodesSortedByTimestamp[a].time.Before(nodesSortedByTimestamp[b].time)
	})

	stakeModifierNew := uint64(0)
	selectionIntervalStop := selectionIntervalStart
	selectedBlocks := make(map[chainhash.Hash]*blockNode)

	for round := 0; round < min(64, len(nodesSortedByTimestamp)); round++ {
		selectionIntervalStop += int64(3780 / (189 - round*2))

		selection, err := b.selectBlockFromCandidates(nodesSortedByTimestamp, selectedBlocks, selectionIntervalStop, stakeModifier)

		if err != nil {
			return 0, false, err
		}

		stakeModifierNew |= uint64(selection.GetStakeEntropyBit()) << uint(round)

		selectedBlocks[selection.hash] = selection
	}

	return stakeModifierNew, true, nil
}
// computeNextStakeModifier gets the next block's stake modifier and returns whether one
// was generated and if so, what the stake modifier is
// For the genesis block, the stake modifier is 0.
computeNextStakeModifier gets the next block's stake modifier and returns whether one
was generated and if so, what the stake modifier is
For the genesis block, the stake modifier is 0.
// computeNextStakeModifier gets the next block ' s stake modifier and returns whether one // was generated and if so what the stake modifier is // For the genesis block the stake modifier is 0 .
func (b *BlockChain) computeNextStakeModifier(node *blockNode) (uint64, bool, error) {
	if node.height == 0 || node.height == 1 {
		return blockOneStakeModifier, true, nil
	}
	lastStakeModifierBlock := node
	for lastStakeModifierBlock != nil && !b.index.GeneratedStakeModifier(lastStakeModifierBlock) {
		lastStakeModifierBlock = lastStakeModifierBlock.parent
	}
	stakeModifier := lastStakeModifierBlock.stakeModifier
	modifierTime := lastStakeModifierBlock.timestamp
	if modifierTime/60 >= node.timestamp/60 {
		return b.index.GetStakeModifier(lastStakeModifierBlock), false, nil
	}
	selectionIntervalStart := (node.timestamp/60)*60 - int64(stakeModifierSelectionInterval.Seconds())
	var nodesSortedByTimestamp []timeAndBlockNode
	for node != nil && node.timestamp >= selectionIntervalStart {
		nodesSortedByTimestamp = append([]timeAndBlockNode{
			{time: time.Unix(node.timestamp, 0), node: node},
		}, nodesSortedByTimestamp...)
		node = node.parent
	}
	sort.Slice(nodesSortedByTimestamp, func(a, b int) bool {
		if nodesSortedByTimestamp[a].time.Unix() == nodesSortedByTimestamp[b].time.Unix() {
			return HashToBig(&nodesSortedByTimestamp[a].node.hash).Cmp(HashToBig(&nodesSortedByTimestamp[b].node.hash)) < 0
		}
		return nodesSortedByTimestamp[a].time.Before(nodesSortedByTimestamp[b].time)
	})
	stakeModifierNew := uint64(0)
	selectionIntervalStop := selectionIntervalStart
	selectedBlocks := make(map[chainhash.Hash]*blockNode)
	for round := 0; round < min(64, len(nodesSortedByTimestamp)); round++ {
		selectionIntervalStop += int64(3780 / (189 - round*2))
		selection, err := b.selectBlockFromCandidates(nodesSortedByTimestamp, selectedBlocks, selectionIntervalStop, stakeModifier)
		if err != nil {
			return 0, false, err
		}
		stakeModifierNew |= uint64(selection.GetStakeEntropyBit()) << uint(round)
		selectedBlocks[selection.hash] = selection
	}
	return stakeModifierNew, true, nil
}
func ( b * BlockChain ) computeNextStakeModifier ( node * blockNode ) ( uint64 , bool , error ) { if node . height == 0 || node . height == 1 { return blockOneStakeModifier , true , nil } lastStakeModifierBlock := node for lastStakeModifierBlock != nil && ! b . index . GeneratedStakeModifier ( lastStakeModifierBlock ) { lastStakeModifierBlock = lastStakeModifierBlock . parent } stakeModifier := lastStakeModifierBlock . stakeModifier modifierTime := lastStakeModifierBlock . timestamp if modifierTime / 60 >= node . timestamp / 60 { return b . index . GetStakeModifier ( lastStakeModifierBlock ) , false , nil } selectionIntervalStart := ( node . timestamp / 60 ) * 60 - int64 ( stakeModifierSelectionInterval . Seconds ( ) ) var nodesSortedByTimestamp [ ] timeAndBlockNode for node != nil && node . timestamp >= selectionIntervalStart { nodesSortedByTimestamp = append ( [ ] timeAndBlockNode { { time : time . Unix ( node . timestamp , 0 ) , node : node } , } , nodesSortedByTimestamp ... ) node = node . parent } sort . Slice ( nodesSortedByTimestamp , func ( a , b int ) bool { if nodesSortedByTimestamp [ a ] . time . Unix ( ) == nodesSortedByTimestamp [ b ] . time . Unix ( ) { return HashToBig ( & nodesSortedByTimestamp [ a ] . node . hash ) . Cmp ( HashToBig ( & nodesSortedByTimestamp [ b ] . node . hash ) ) < 0 } return nodesSortedByTimestamp [ a ] . time . Before ( nodesSortedByTimestamp [ b ] . time ) } ) stakeModifierNew := uint64 ( 0 ) selectionIntervalStop := selectionIntervalStart selectedBlocks := make ( map [ chainhash . Hash ] * blockNode ) for round := 0 ; round < min ( 64 , len ( nodesSortedByTimestamp ) ) ; round ++ { selectionIntervalStop += int64 ( 3780 / ( 189 - round * 2 ) ) selection , err := b . selectBlockFromCandidates ( nodesSortedByTimestamp , selectedBlocks , selectionIntervalStop , stakeModifier ) if err != nil { return 0 , false , err } stakeModifierNew |= uint64 ( selection . GetStakeEntropyBit ( ) ) << uint ( round ) selectedBlocks [ selection . hash ] = selection } return stakeModifierNew , true , nil }
computeNextStakeModifier gets the next block's stake modifier and returns whether one
was generated and if so, what the stake modifier is
For the genesis block, the stake modifier is 0.
computeNextStakeModifier gets the next block ' s stake modifier and returns whether one was generated and if so what the stake modifier is For the genesis block the stake modifier is 0 .