github.com/elastos/Elastos.ELA.SideChain.ETH@v0.2.2/dpos/blockpool_test.go (about)

     1  // Copyright (c) 2017-2019 The Elastos Foundation
     2  // Use of this source code is governed by an MIT
     3  // license that can be found in the LICENSE file.
     4  //
     5  
     6  package dpos
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/binary"
    11  	"io"
    12  	"math/rand"
    13  	"testing"
    14  
    15  	"github.com/elastos/Elastos.ELA/common"
    16  	"github.com/elastos/Elastos.ELA/core/types/payload"
    17  
    18  	"github.com/stretchr/testify/assert"
    19  )
    20  
    21  type BlockNonce [8]byte
    22  // Uint64 returns the integer value of a block nonce.
    23  func (n BlockNonce) Uint64() uint64 {
    24  	return binary.BigEndian.Uint64(n[:])
    25  }
    26  
    27  
    28  type mockHeader struct {
    29  	ParentHash common.Uint256
    30  	Root       common.Uint256
    31  	Timestamp  uint32
    32  	Height     uint64
    33  	Nonce      BlockNonce
    34  }
    35  
    36  func (h *mockHeader) Serialize(w io.Writer) error {
    37  	err := h.ParentHash.Serialize(w)
    38  	if err != nil {
    39  		return err
    40  	}
    41  	err = h.Root.Serialize(w)
    42  	if err != nil {
    43  		return err
    44  	}
    45  	err = common.WriteUint32(w, h.Timestamp)
    46  	if err != nil {
    47  		return err
    48  	}
    49  	err = common.WriteUint64(w, h.Height)
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	return nil
    55  }
    56  
    57  type mockTransaction struct {
    58  	From  common.Uint168
    59  	To    common.Uint168
    60  	Value uint64
    61  	Sign  []byte
    62  }
    63  
    64  type mockBlock struct {
    65  	header *mockHeader
    66  	txs    []*mockTransaction
    67  }
    68  
    69  func (b *mockBlock) Nonce() uint64 {
    70  	return binary.BigEndian.Uint64(b.header.Nonce[:])
    71  }
    72  
    73  func (b *mockBlock) GetHash() common.Uint256 {
    74  	buf := new(bytes.Buffer)
    75  	b.header.Serialize(buf)
    76  	return common.Sha256D(buf.Bytes())
    77  }
    78  
    79  func (b *mockBlock) GetHeight() uint64 {
    80  	return b.header.Height
    81  }
    82  
    83  func verifyConfirm(confirm *payload.Confirm, elaHeight uint64) error {
    84  	return nil
    85  }
    86  
    87  func verifyBlock(block DBlock) error {
    88  	return nil
    89  }
    90  
    91  func sealHash(block DBlock) (common.Uint256, error) {
    92  	return block.GetHash(), nil
    93  }
    94  
    95  func randomUint256() *common.Uint256 {
    96  	randBytes := make([]byte, 32)
    97  	rand.Read(randBytes)
    98  	result, _ := common.Uint256FromBytes(randBytes)
    99  
   100  	return result
   101  }
   102  
   103  func newTestBlock() *mockBlock {
   104  	header := &mockHeader{
   105  		ParentHash: *randomUint256(),
   106  		Root:       *randomUint256(),
   107  		Timestamp:  rand.Uint32(),
   108  		Height:     rand.Uint64(),
   109  	}
   110  
   111  	block := &mockBlock{
   112  		header: header,
   113  	}
   114  	return block
   115  }
   116  
   117  func TestBlockPool_AppendDposBlock(t *testing.T) {
   118  	blockPool := NewBlockPool(verifyConfirm, verifyBlock, sealHash)
   119  	size := rand.Intn(10) + 10
   120  
   121  	blocks := make([]common.Uint256, 0)
   122  	for i := 0; i < size; i++ {
   123  		block := newTestBlock()
   124  		hash, _ := sealHash(block)
   125  		confirm := &payload.Confirm{
   126  			Proposal: payload.DPOSProposal{BlockHash: hash},
   127  		}
   128  
   129  		blockPool.AppendDposBlock(block)
   130  		blockPool.AppendConfirm(confirm)
   131  
   132  		blocks = append(blocks, block.GetHash())
   133  	}
   134  
   135  	for i := 0; i < size; i++ {
   136  		b, ok := blockPool.GetBlock(blocks[i])
   137  		assert.NotNil(t, b)
   138  		assert.True(t, ok)
   139  	}
   140  }