github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/consensus/dpos/dpos_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  package dpos
    10  
    11  import (
    12  	"testing"
    13  
    14  	"encoding/binary"
    15  
    16  	"github.com/ethereum/go-ethereum/common"
    17  	"github.com/ethereum/go-ethereum/core/types"
    18  	"github.com/ethereum/go-ethereum/ethdb"
    19  	"github.com/ethereum/go-ethereum/trie"
    20  	"github.com/stretchr/testify/assert"
    21  )
    22  
    23  var (
    24  	MockEpoch = []string{
    25  		"0x44d1ce0b7cb3588bca96151fe1bc05af38f91b6e",
    26  		"0xa60a3886b552ff9992cfcd208ec1152079e046c2",
    27  		"0x4e080e49f62694554871e669aeb4ebe17c4a9670",
    28  		"0xb040353ec0f2c113d5639444f7253681aecda1f8",
    29  		"0x14432e15f21237013017fa6ee90fc99433dec82c",
    30  		"0x9f30d0e5c9c88cade54cd1adecf6bc2c7e0e5af6",
    31  		"0xd83b44a3719720ec54cdb9f54c0202de68f1ebcb",
    32  		"0x56cc452e450551b7b9cffe25084a069e8c1e9441",
    33  		"0xbcfcb3fa8250be4f2bf2b1e70e1da500c668377b",
    34  		"0x9d9667c71bb09d6ca7c3ed12bfe5e7be24e2ffe1",
    35  		"0xabde197e97398864ba74511f02832726edad5967",
    36  		"0x6f99d97a394fa7a623fdf84fdc7446b99c3cb335",
    37  		"0xf78b011e639ce6d8b76f97712118f3fe4a12dd95",
    38  		"0x8db3b6c801dddd624d6ddc2088aa64b5a2493661",
    39  		"0x751b484bd5296f8d267a8537d33f25a848f7f7af",
    40  		"0x646ba1fa42eb940aac67103a71e9a908ef484ec3",
    41  		"0x34d4a8d9f6b53a8f5e674516cb8ad66c843b2801",
    42  		"0x5b76fff970bf8a351c1c9ebfb5e5a9493e956ddd",
    43  		"0x8da3c5aedaf106c61cfee6d8483e1f255fdd60c0",
    44  		"0x2cdbe87a1bd7ee60dd6fe97f7b2d1efbacd5d95d",
    45  		"0x743415d0e979dc6e426bc8189e40beb65bf5ac1d",
    46  	}
    47  )
    48  
    49  func mockNewDposContext(db ethdb.Database) *types.DposContext {
    50  	trieDB := trie.NewDatabase(db)
    51  	dposContext, err := types.NewDposContextFromProto(trieDB, &types.DposContextProto{})
    52  	if err != nil {
    53  		return nil
    54  	}
    55  	delegator := []byte{}
    56  	candidate := []byte{}
    57  	addresses := []common.Address{}
    58  	for i := 0; i < maxValidatorSize; i++ {
    59  		addresses = append(addresses, common.HexToAddress(MockEpoch[i]))
    60  	}
    61  	dposContext.SetValidators(addresses)
    62  	for j := 0; j < len(MockEpoch); j++ {
    63  		delegator = common.HexToAddress(MockEpoch[j]).Bytes()
    64  		candidate = common.HexToAddress(MockEpoch[j]).Bytes()
    65  		dposContext.DelegateTrie().TryUpdate(append(candidate, delegator...), candidate)
    66  		dposContext.CandidateTrie().TryUpdate(candidate, candidate)
    67  		dposContext.VoteTrie().TryUpdate(candidate, candidate)
    68  	}
    69  	return dposContext
    70  }
    71  
    72  func setMintCntTrie(epochID int64, candidate common.Address, mintCntTrie *trie.Trie, count int64) {
    73  	key := make([]byte, 8)
    74  	binary.BigEndian.PutUint64(key, uint64(epochID))
    75  	cntBytes := make([]byte, 8)
    76  	binary.BigEndian.PutUint64(cntBytes, uint64(count))
    77  	mintCntTrie.TryUpdate(append(key, candidate.Bytes()...), cntBytes)
    78  }
    79  
    80  func getMintCnt(epochID int64, candidate common.Address, mintCntTrie *trie.Trie) int64 {
    81  	key := make([]byte, 8)
    82  	binary.BigEndian.PutUint64(key, uint64(epochID))
    83  	cntBytes := mintCntTrie.Get(append(key, candidate.Bytes()...))
    84  	if cntBytes == nil {
    85  		return 0
    86  	} else {
    87  		return int64(binary.BigEndian.Uint64(cntBytes))
    88  	}
    89  }
    90  
    91  func TestUpdateMintCnt(t *testing.T) {
    92  	db := ethdb.NewMemDatabase()
    93  	dposContext := mockNewDposContext(db)
    94  
    95  //新块仍与当前块处于同一时代,但新矿工是该时代首次造币。
    96  	lastTime := int64(epochInterval)
    97  
    98  	miner := common.HexToAddress("0xa60a3886b552ff9992cfcd208ec1152079e046c2")
    99  	blockTime := int64(epochInterval + blockInterval)
   100  
   101  	beforeUpdateCnt := getMintCnt(blockTime/epochInterval, miner, dposContext.MintCntTrie())
   102  	updateMintCnt(lastTime, blockTime, miner, dposContext)
   103  	afterUpdateCnt := getMintCnt(blockTime/epochInterval, miner, dposContext.MintCntTrie())
   104  	assert.Equal(t, int64(0), beforeUpdateCnt)
   105  	assert.Equal(t, int64(1), afterUpdateCnt)
   106  
   107  //新块体仍与当前块体处于同一时代,新矿工在该时代之前也有铸币块体。
   108  	setMintCntTrie(blockTime/epochInterval, miner, dposContext.MintCntTrie(), int64(1))
   109  
   110  	blockTime = epochInterval + blockInterval*4
   111  
   112  //
   113  	beforeUpdateCnt = getMintCnt(blockTime/epochInterval, miner, dposContext.MintCntTrie())
   114  	updateMintCnt(lastTime, blockTime, miner, dposContext)
   115  	afterUpdateCnt = getMintCnt(blockTime/epochInterval, miner, dposContext.MintCntTrie())
   116  	assert.Equal(t, int64(1), beforeUpdateCnt)
   117  	assert.Equal(t, int64(2), afterUpdateCnt)
   118  
   119  //新街区进入新时代
   120  	blockTime = epochInterval * 2
   121  
   122  	beforeUpdateCnt = getMintCnt(blockTime/epochInterval, miner, dposContext.MintCntTrie())
   123  	updateMintCnt(lastTime, blockTime, miner, dposContext)
   124  	afterUpdateCnt = getMintCnt(blockTime/epochInterval, miner, dposContext.MintCntTrie())
   125  	assert.Equal(t, int64(0), beforeUpdateCnt)
   126  	assert.Equal(t, int64(1), afterUpdateCnt)
   127  }