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 }