aboutsummaryrefslogtreecommitdiffstats
path: root/core/test/block-revealer.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/test/block-revealer.go')
-rw-r--r--core/test/block-revealer.go214
1 files changed, 3 insertions, 211 deletions
diff --git a/core/test/block-revealer.go b/core/test/block-revealer.go
index ebd2e35..90b3d3e 100644
--- a/core/test/block-revealer.go
+++ b/core/test/block-revealer.go
@@ -19,9 +19,7 @@ package test
import (
"errors"
- "math/rand"
"sort"
- "time"
"github.com/dexon-foundation/dexon-consensus/common"
"github.com/dexon-foundation/dexon-consensus/core/db"
@@ -65,217 +63,11 @@ func loadAllBlocks(iter db.BlockIterator) (
return
}
-// RandomDAGBlockRevealer implements BlockRevealer interface, which would load
-// all blocks from db, and randomly pick one block to reveal if it still forms
-// a valid DAG in revealed blocks.
-type RandomDAGBlockRevealer struct {
- // blocksByChain group all blocks by chains and sorting
- // them by height.
- blocksByChain map[uint32][]*types.Block
- // tipIndexes store the height of next block from one chain
- // to check if is candidate.
- tipIndexes map[uint32]int
- // candidate are blocks that forms valid DAG with
- // current revealed blocks.
- candidates []*types.Block
- candidateChains map[uint32]struct{}
- // revealed stores block hashes of current revealed blocks.
- revealed map[common.Hash]struct{}
- randGen *rand.Rand
-}
-
-// NewRandomDAGBlockRevealer constructs RandomDAGBlockRevealer.
-func NewRandomDAGBlockRevealer(
- iter db.BlockIterator) (r *RandomDAGBlockRevealer, err error) {
-
- blocks, err := loadAllBlocks(iter)
- if err != nil {
- return
- }
-
- // Rearrange blocks by nodes and height.
- blocksByChain := make(map[uint32][]*types.Block)
- for _, block := range blocks {
- blocksByChain[block.Position.ChainID] =
- append(blocksByChain[block.Position.ChainID], block)
- }
- // Make sure blocks are sorted by block heights, from lower to higher.
- for chainID := range blocksByChain {
- sort.Sort(types.ByPosition(blocksByChain[chainID]))
- }
- r = &RandomDAGBlockRevealer{
- blocksByChain: blocksByChain,
- randGen: rand.New(rand.NewSource(time.Now().UnixNano())),
- candidateChains: make(map[uint32]struct{}),
- }
- // Make sure this revealer is ready to use.
- r.Reset()
- return
-}
-
-// pickCandidates is a helper function to pick candidates from current tips.
-func (r *RandomDAGBlockRevealer) pickCandidates() {
- for chainID, tip := range r.tipIndexes {
- if _, isPicked := r.candidateChains[chainID]; isPicked {
- continue
- }
- blocks, exists := r.blocksByChain[chainID]
- if !exists {
- continue
- }
- if tip >= len(blocks) {
- continue
- }
- block := blocks[tip]
- if isAllAckingBlockRevealed(block, r.revealed) {
- r.tipIndexes[chainID]++
- r.candidates = append(r.candidates, block)
- r.candidateChains[chainID] = struct{}{}
- }
- }
-}
-
-// NextBlock implement Revealer.Next method, which would reveal blocks
-// forming valid DAGs.
-func (r *RandomDAGBlockRevealer) NextBlock() (types.Block, error) {
- if len(r.candidates) == 0 {
- r.pickCandidates()
- if len(r.candidates) == 0 {
- return types.Block{}, db.ErrIterationFinished
- }
- }
-
- // Pick next block to be revealed.
- picked := r.randGen.Intn(len(r.candidates))
- block := r.candidates[picked]
- r.candidates =
- append(r.candidates[:picked], r.candidates[picked+1:]...)
- delete(r.candidateChains, block.Position.ChainID)
- r.revealed[block.Hash] = struct{}{}
- r.pickCandidates()
- return *block, nil
-}
-
-// Reset implement Revealer.Reset method, which would reset the revealing.
-func (r *RandomDAGBlockRevealer) Reset() {
- r.tipIndexes = make(map[uint32]int)
- for chainID := range r.blocksByChain {
- r.tipIndexes[chainID] = 0
- }
- r.revealed = make(map[common.Hash]struct{})
- r.candidates = []*types.Block{}
-}
-
-// RandomBlockRevealer implements BlockRevealer interface, which would load
-// all blocks from db, and randomly pick one block to reveal.
-type RandomBlockRevealer struct {
- blocks map[common.Hash]*types.Block
- remains common.Hashes
- randGen *rand.Rand
-}
-
-// NewRandomBlockRevealer constructs RandomBlockRevealer.
-func NewRandomBlockRevealer(
- iter db.BlockIterator) (r *RandomBlockRevealer, err error) {
-
- blocks, err := loadAllBlocks(iter)
- if err != nil {
- return
- }
- r = &RandomBlockRevealer{
- blocks: blocks,
- randGen: rand.New(rand.NewSource(time.Now().UnixNano())),
- }
- r.Reset()
- return
-}
-
-// NextBlock implements Revealer.NextBlock method, which would reveal blocks
-// randomly.
-func (r *RandomBlockRevealer) NextBlock() (types.Block, error) {
- if len(r.remains) == 0 {
- return types.Block{}, db.ErrIterationFinished
- }
-
- picked := r.randGen.Intn(len(r.remains))
- block := r.blocks[r.remains[picked]]
- r.remains =
- append(r.remains[:picked], r.remains[picked+1:]...)
- return *block, nil
-}
-
-// Reset implement Revealer.Reset method, which would reset revealing.
-func (r *RandomBlockRevealer) Reset() {
- hashes := common.Hashes{}
- for hash := range r.blocks {
- hashes = append(hashes, hash)
- }
- r.remains = hashes
-}
-
-// RandomTipBlockRevealer implements BlockRevealer interface, which would load
-// all blocks from db, and randomly pick one chain's tip to reveal.
-type RandomTipBlockRevealer struct {
- chainsBlock []map[uint64]*types.Block
- chainTip []uint64
- chainRevealSeq []uint32
- revealed int
- randGen *rand.Rand
-}
-
-// NewRandomTipBlockRevealer constructs RandomTipBlockRevealer.
-func NewRandomTipBlockRevealer(
- iter db.BlockIterator) (r *RandomTipBlockRevealer, err error) {
-
- blocks, err := loadAllBlocks(iter)
- if err != nil {
- return
- }
- r = &RandomTipBlockRevealer{
- randGen: rand.New(rand.NewSource(time.Now().UnixNano())),
- }
- for _, b := range blocks {
- for b.Position.ChainID >= uint32(len(r.chainsBlock)) {
- r.chainsBlock = append(r.chainsBlock, make(map[uint64]*types.Block))
- r.chainTip = append(r.chainTip, 0)
- }
- r.chainsBlock[b.Position.ChainID][b.Position.Height] = b
- r.chainRevealSeq = append(r.chainRevealSeq, b.Position.ChainID)
- }
- r.Reset()
- return
-}
-
-// NextBlock implements Revealer.Next method, which would reveal blocks randomly.
-func (r *RandomTipBlockRevealer) NextBlock() (types.Block, error) {
- if len(r.chainRevealSeq) == r.revealed {
- return types.Block{}, db.ErrIterationFinished
- }
-
- picked := r.chainRevealSeq[r.revealed]
- r.revealed++
- block := r.chainsBlock[picked][r.chainTip[picked]]
- r.chainTip[picked]++
- return *block, nil
-}
-
-// Reset implement Revealer.Reset method, which would reset revealing.
-func (r *RandomTipBlockRevealer) Reset() {
- r.revealed = 0
- r.randGen.Shuffle(len(r.chainRevealSeq), func(i, j int) {
- r.chainRevealSeq[i], r.chainRevealSeq[j] =
- r.chainRevealSeq[j], r.chainRevealSeq[i]
- })
- for i := range r.chainTip {
- r.chainTip[i] = 0
- }
-}
-
// CompactionChainBlockRevealer implements BlockRevealer interface, which would
// load all blocks from db, reveal them in the order of compaction chain,
// from the genesis block to the latest one.
type CompactionChainBlockRevealer struct {
- blocks types.ByFinalizationHeight
+ blocks types.BlocksByFinalizationHeight
nextRevealIndex int
}
@@ -290,14 +82,14 @@ func NewCompactionChainBlockRevealer(iter db.BlockIterator,
if startHeight == 0 {
startHeight = 1
}
- blocks := types.ByFinalizationHeight{}
+ blocks := types.BlocksByFinalizationHeight{}
for _, b := range blocksByHash {
if b.Finalization.Height < startHeight {
continue
}
blocks = append(blocks, b)
}
- sort.Sort(types.ByFinalizationHeight(blocks))
+ sort.Sort(types.BlocksByFinalizationHeight(blocks))
// Make sure the finalization height of blocks are incremental with step 1.
for idx, b := range blocks {
if idx == 0 {