OSDN Git Service

72511967c86329e11534803827588813a9497130
[bytom/vapor.git] / protocol / consensus_node_manager_test.go
1 package protocol
2
3 import (
4         "testing"
5
6         "github.com/vapor/consensus"
7         "github.com/vapor/crypto/ed25519/chainkd"
8         "github.com/vapor/database/storage"
9         "github.com/vapor/protocol/bc"
10         "github.com/vapor/protocol/bc/types"
11         "github.com/vapor/protocol/state"
12         "github.com/vapor/testutil"
13 )
14
15 func TestGetConsensusNodes(t *testing.T) {
16         cases := []struct {
17                 desc                   string
18                 prevSeqConsensusResult *state.ConsensusResult
19                 storedBlockHeaders     []*types.BlockHeader
20                 storedBlocks           []*types.Block
21                 prevBlockHash          bc.Hash
22                 bestBlockHeight        uint64
23                 wantConsensusNodes     []*state.ConsensusNode
24         }{
25                 {
26                         desc: "block hash in main chain",
27                         prevSeqConsensusResult: &state.ConsensusResult{
28                                 Seq: 1,
29                                 NumOfVote: map[string]uint64{
30                                         "0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825": 838063475500000,
31                                         "e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093": 474794800000000,
32                                         "1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842": 833812985000000,
33                                         "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 285918061999999,
34                                         "b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef": 1228455289930297,
35                                         "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 274387690000000,
36                                 },
37                                 BlockHash:   testutil.MustDecodeHash("65a92adc3c17657e4f0f032f1de83597dbbc6c29c24626d1533c8215f81c99e6"),
38                                 BlockHeight: 1200,
39                         },
40                         storedBlockHeaders: []*types.BlockHeader{
41                                 {
42                                         Height:            1200,
43                                         PreviousBlockHash: testutil.MustDecodeHash("7f5d567f2ad9de9af4af6e6cc81943abcd042e5a6329c83708e3578be3b5fc7d"),
44                                 },
45                                 {
46                                         Height:            1201,
47                                         PreviousBlockHash: testutil.MustDecodeHash("65a92adc3c17657e4f0f032f1de83597dbbc6c29c24626d1533c8215f81c99e6"),
48                                 },
49                                 {
50                                         Height:            1202,
51                                         PreviousBlockHash: testutil.MustDecodeHash("9ff85d12c91ad5500b3dfe80bb0b4d4496ab29aec37f71e839fdd0a1c92a614f"),
52                                 },
53                                 {
54                                         Height:            1203,
55                                         PreviousBlockHash: testutil.MustDecodeHash("559b02b183e275e79dcfab23c66004264127f461ff8b90b3a336b2f958bf96e2"),
56                                 },
57                         },
58                         prevBlockHash:   testutil.MustDecodeHash("f77d1330abc1a58ce5909581e6f2059153e116e9044e284609e07efd5f0b239e"),
59                         bestBlockHeight: 1230,
60                         wantConsensusNodes: []*state.ConsensusNode{
61                                 {
62                                         XPub:    mustDecodeXPub("b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef"),
63                                         VoteNum: 1228455289930297,
64                                         Order:   0,
65                                 },
66                                 {
67                                         XPub:    mustDecodeXPub("0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825"),
68                                         VoteNum: 838063475500000,
69                                         Order:   1,
70                                 },
71                                 {
72                                         XPub:    mustDecodeXPub("1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842"),
73                                         VoteNum: 833812985000000,
74                                         Order:   2,
75                                 },
76                                 {
77                                         XPub:    mustDecodeXPub("e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093"),
78                                         VoteNum: 474794800000000,
79                                         Order:   3,
80                                 },
81                                 {
82                                         XPub:    mustDecodeXPub("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9"),
83                                         VoteNum: 285918061999999,
84                                         Order:   4,
85                                 },
86                                 {
87                                         XPub:    mustDecodeXPub("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67"),
88                                         VoteNum: 274387690000000,
89                                         Order:   5,
90                                 },
91                         },
92                 },
93                 {
94                         desc: "block hash in main chain, block height in the begin of round",
95                         prevSeqConsensusResult: &state.ConsensusResult{
96                                 Seq: 1,
97                                 NumOfVote: map[string]uint64{
98                                         "0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825": 838063475500000,
99                                         "e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093": 474794800000000,
100                                         "1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842": 833812985000000,
101                                         "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 285918061999999,
102                                         "b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef": 1228455289930297,
103                                         "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 274387690000000,
104                                 },
105                                 BlockHash:   testutil.MustDecodeHash("65a92adc3c17657e4f0f032f1de83597dbbc6c29c24626d1533c8215f81c99e6"),
106                                 BlockHeight: 1200,
107                         },
108                         storedBlockHeaders: []*types.BlockHeader{
109                                 {
110                                         Height:            1200,
111                                         PreviousBlockHash: testutil.MustDecodeHash("7f5d567f2ad9de9af4af6e6cc81943abcd042e5a6329c83708e3578be3b5fc7d"),
112                                 },
113                                 {
114                                         Height:            1201,
115                                         PreviousBlockHash: testutil.MustDecodeHash("65a92adc3c17657e4f0f032f1de83597dbbc6c29c24626d1533c8215f81c99e6"),
116                                 },
117                         },
118                         prevBlockHash:   testutil.MustDecodeHash("65a92adc3c17657e4f0f032f1de83597dbbc6c29c24626d1533c8215f81c99e6"),
119                         bestBlockHeight: 1230,
120                         wantConsensusNodes: []*state.ConsensusNode{
121                                 {
122                                         XPub:    mustDecodeXPub("b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef"),
123                                         VoteNum: 1228455289930297,
124                                         Order:   0,
125                                 },
126                                 {
127                                         XPub:    mustDecodeXPub("0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825"),
128                                         VoteNum: 838063475500000,
129                                         Order:   1,
130                                 },
131                                 {
132                                         XPub:    mustDecodeXPub("1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842"),
133                                         VoteNum: 833812985000000,
134                                         Order:   2,
135                                 },
136                                 {
137                                         XPub:    mustDecodeXPub("e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093"),
138                                         VoteNum: 474794800000000,
139                                         Order:   3,
140                                 },
141                                 {
142                                         XPub:    mustDecodeXPub("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9"),
143                                         VoteNum: 285918061999999,
144                                         Order:   4,
145                                 },
146                                 {
147                                         XPub:    mustDecodeXPub("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67"),
148                                         VoteNum: 274387690000000,
149                                         Order:   5,
150                                 },
151                         },
152                 },
153                 {
154                         desc: "block hash in main chain, the consensus result is incomplete",
155                         prevSeqConsensusResult: &state.ConsensusResult{
156                                 Seq: 1,
157                                 NumOfVote: map[string]uint64{
158                                         "0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825": 838063475500000,
159                                         "e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093": 474794800000000,
160                                         "1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842": 833812985000000,
161                                         "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 285918061999999,
162                                         "b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef": 1228455289930297,
163                                         "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 274387690000000,
164                                 },
165                                 BlockHash:      testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
166                                 BlockHeight:    1198,
167                                 CoinbaseReward: make(map[string]uint64),
168                         },
169                         storedBlockHeaders: []*types.BlockHeader{
170                                 {
171                                         Height:            1198,
172                                         PreviousBlockHash: testutil.MustDecodeHash("4d3ecf28f3045df23764792f41af17fc20518cc8e83673dc2d0ce07bbf084d7d"),
173                                 },
174                                 {
175                                         Height:            1199,
176                                         PreviousBlockHash: testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
177                                 },
178                                 {
179                                         Height:            1200,
180                                         PreviousBlockHash: testutil.MustDecodeHash("608d82b3660255186fb2b035cfb2ca86e986433218cd2eca2e79611e855a87d3"),
181                                 },
182                                 {
183                                         Height:            1201,
184                                         PreviousBlockHash: testutil.MustDecodeHash("73a2a6a098727877e288a4520f2d8076d700b561277ed7c3f533e3f176496888"),
185                                 },
186                         },
187                         storedBlocks: []*types.Block{
188                                 {
189                                         BlockHeader: types.BlockHeader{
190                                                 Height:            1199,
191                                                 PreviousBlockHash: testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
192                                         },
193                                         Transactions: []*types.Tx{
194                                                 {
195                                                         TxData: types.TxData{
196                                                                 Inputs: []*types.TxInput{
197                                                                         types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 1E14, 0, []byte{0, 1}),
198                                                                 },
199                                                                 Outputs: []*types.TxOutput{
200                                                                         types.NewVoteOutput(*consensus.BTMAssetID, 1E14, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
201                                                                 },
202                                                         },
203                                                 },
204                                         },
205                                 },
206                                 {
207                                         BlockHeader: types.BlockHeader{
208                                                 Height:            1200,
209                                                 PreviousBlockHash: testutil.MustDecodeHash("608d82b3660255186fb2b035cfb2ca86e986433218cd2eca2e79611e855a87d3"),
210                                         },
211                                         Transactions: []*types.Tx{
212                                                 {
213                                                         TxData: types.TxData{
214                                                                 Inputs: []*types.TxInput{
215                                                                         types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 3E14, 0, []byte{0, 1}),
216                                                                 },
217                                                                 Outputs: []*types.TxOutput{
218                                                                         types.NewVoteOutput(*consensus.BTMAssetID, 3E14, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
219                                                                 },
220                                                         },
221                                                 },
222                                         },
223                                 },
224                         },
225                         prevBlockHash:   testutil.MustDecodeHash("73a2a6a098727877e288a4520f2d8076d700b561277ed7c3f533e3f176496888"),
226                         bestBlockHeight: 1230,
227                         wantConsensusNodes: []*state.ConsensusNode{
228                                 {
229                                         XPub:    mustDecodeXPub("b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef"),
230                                         VoteNum: 1228455289930297,
231                                         Order:   0,
232                                 },
233                                 {
234                                         XPub:    mustDecodeXPub("0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825"),
235                                         VoteNum: 838063475500000,
236                                         Order:   1,
237                                 },
238                                 {
239                                         XPub:    mustDecodeXPub("1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842"),
240                                         VoteNum: 833812985000000,
241                                         Order:   2,
242                                 },
243                                 {
244                                         XPub:    mustDecodeXPub("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9"),
245                                         VoteNum: 585918061999999,
246                                         Order:   3,
247                                 },
248                                 {
249                                         XPub:    mustDecodeXPub("e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093"),
250                                         VoteNum: 474794800000000,
251                                         Order:   4,
252                                 },
253                                 {
254                                         XPub:    mustDecodeXPub("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67"),
255                                         VoteNum: 374387690000000,
256                                         Order:   5,
257                                 },
258                         },
259                 },
260                 {
261                         desc: "block hash in fork chain",
262                         prevSeqConsensusResult: &state.ConsensusResult{
263                                 Seq: 1,
264                                 NumOfVote: map[string]uint64{
265                                         "0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825": 838063475500000,
266                                         "e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093": 474794800000000,
267                                         "1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842": 833812985000000,
268                                         "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 285918061999999,
269                                         "b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef": 1228455289930297,
270                                         "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 274387690000000,
271                                 },
272                                 BlockHash:      testutil.MustDecodeHash("73a2a6a098727877e288a4520f2d8076d700b561277ed7c3f533e3f176496888"),
273                                 BlockHeight:    1200,
274                                 CoinbaseReward: map[string]uint64{"0001": 1E8},
275                         },
276                         storedBlockHeaders: []*types.BlockHeader{
277                                 // main chain
278                                 {
279                                         Height:            1198,
280                                         PreviousBlockHash: testutil.MustDecodeHash("4d3ecf28f3045df23764792f41af17fc20518cc8e83673dc2d0ce07bbf084d7d"),
281                                 },
282                                 {
283                                         Height:            1199,
284                                         PreviousBlockHash: testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
285                                 },
286                                 {
287                                         Height:            1200,
288                                         PreviousBlockHash: testutil.MustDecodeHash("608d82b3660255186fb2b035cfb2ca86e986433218cd2eca2e79611e855a87d3"),
289                                 },
290                                 {
291                                         Height:            1201,
292                                         PreviousBlockHash: testutil.MustDecodeHash("73a2a6a098727877e288a4520f2d8076d700b561277ed7c3f533e3f176496888"),
293                                 },
294                                 {
295                                         Height:            1202,
296                                         PreviousBlockHash: testutil.MustDecodeHash("a5be1d1177eb027327baedb869f902f74850476d0b9432a30391a3165d3af7cc"),
297                                 },
298                                 // fork chain
299                                 {
300                                         Height:            1199,
301                                         PreviousBlockHash: testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
302                                         Timestamp:         1, // in order to make different hash
303                                 },
304                                 {
305                                         Height:            1200,
306                                         PreviousBlockHash: testutil.MustDecodeHash("cde3d8a99dee1cd44fb37f499c1980338a49ac1b9d5e6f693bd0a6f87c74e4d2"),
307                                 },
308                                 {
309                                         Height:            1201,
310                                         PreviousBlockHash: testutil.MustDecodeHash("f819efb4baecbeb63aff6d4b14b549f1bd35955d461abaa0058a26f74c4f62da"),
311                                 },
312                         },
313                         storedBlocks: []*types.Block{
314                                 // main chain
315                                 {
316                                         BlockHeader: types.BlockHeader{
317                                                 Height:            1199,
318                                                 PreviousBlockHash: testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
319                                         },
320                                         Transactions: []*types.Tx{
321                                                 {
322                                                         TxData: types.TxData{
323                                                                 Inputs: []*types.TxInput{
324                                                                         types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 1E14, 0, []byte{0, 1}),
325                                                                 },
326                                                                 Outputs: []*types.TxOutput{
327                                                                         types.NewVoteOutput(*consensus.BTMAssetID, 1E14, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
328                                                                 },
329                                                         },
330                                                 },
331                                         },
332                                 },
333                                 {
334                                         BlockHeader: types.BlockHeader{
335                                                 Height:            1200,
336                                                 PreviousBlockHash: testutil.MustDecodeHash("608d82b3660255186fb2b035cfb2ca86e986433218cd2eca2e79611e855a87d3"),
337                                         },
338                                         Transactions: []*types.Tx{
339                                                 {
340                                                         TxData: types.TxData{
341                                                                 Inputs: []*types.TxInput{
342                                                                         types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 2E14, 0, []byte{0, 1}),
343                                                                 },
344                                                                 Outputs: []*types.TxOutput{
345                                                                         types.NewVoteOutput(*consensus.BTMAssetID, 2E14, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
346                                                                 },
347                                                         },
348                                                 },
349                                         },
350                                 },
351                                 // fork chain
352                                 {
353                                         BlockHeader: types.BlockHeader{
354                                                 Height:            1199,
355                                                 PreviousBlockHash: testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
356                                                 Timestamp:         1, // in order to make different hash
357                                         },
358                                         Transactions: []*types.Tx{
359                                                 {
360                                                         TxData: types.TxData{
361                                                                 Inputs: []*types.TxInput{
362                                                                         types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 2E14, 0, []byte{0, 1}),
363                                                                 },
364                                                                 Outputs: []*types.TxOutput{
365                                                                         types.NewVoteOutput(*consensus.BTMAssetID, 2E14, []byte{0, 1}, testutil.MustDecodeHexString("0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825")),
366                                                                 },
367                                                         },
368                                                 },
369                                         },
370                                 },
371                                 {
372                                         BlockHeader: types.BlockHeader{
373                                                 Height:            1200,
374                                                 PreviousBlockHash: testutil.MustDecodeHash("cde3d8a99dee1cd44fb37f499c1980338a49ac1b9d5e6f693bd0a6f87c74e4d2"),
375                                         },
376                                         Transactions: []*types.Tx{
377                                                 {
378                                                         TxData: types.TxData{
379                                                                 Inputs: []*types.TxInput{
380                                                                         types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 5E14, 0, []byte{0, 1}),
381                                                                 },
382                                                                 Outputs: []*types.TxOutput{
383                                                                         types.NewVoteOutput(*consensus.BTMAssetID, 5E14, []byte{0, 1}, testutil.MustDecodeHexString("b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef")),
384                                                                 },
385                                                         },
386                                                 },
387                                         },
388                                 },
389                         },
390                         prevBlockHash:   testutil.MustDecodeHash("f819efb4baecbeb63aff6d4b14b549f1bd35955d461abaa0058a26f74c4f62da"),
391                         bestBlockHeight: 1230,
392                         wantConsensusNodes: []*state.ConsensusNode{
393                                 {
394                                         XPub:    mustDecodeXPub("b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef"),
395                                         VoteNum: 1728455289930297,
396                                         Order:   0,
397                                 },
398                                 {
399                                         XPub:    mustDecodeXPub("0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825"),
400                                         VoteNum: 1038063475500000,
401                                         Order:   1,
402                                 },
403                                 {
404                                         XPub:    mustDecodeXPub("1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842"),
405                                         VoteNum: 833812985000000,
406                                         Order:   2,
407                                 },
408                                 {
409                                         XPub:    mustDecodeXPub("e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093"),
410                                         VoteNum: 474794800000000,
411                                         Order:   3,
412                                 },
413                                 {
414                                         XPub:    mustDecodeXPub("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67"),
415                                         VoteNum: 174387690000000,
416                                         Order:   4,
417                                 },
418                         },
419                 },
420                 {
421                         desc: "block hash in fork chain, the consensus result is incomplete",
422                         prevSeqConsensusResult: &state.ConsensusResult{
423                                 Seq: 1,
424                                 NumOfVote: map[string]uint64{
425                                         "0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825": 838063475500000,
426                                         "e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093": 474794800000000,
427                                         "1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842": 833812985000000,
428                                         "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 285918061999999,
429                                         "b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef": 1228455289930297,
430                                         "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 274387690000000,
431                                 },
432                                 BlockHash:      testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
433                                 BlockHeight:    1198,
434                                 CoinbaseReward: map[string]uint64{"0001": 1E8},
435                         },
436                         storedBlockHeaders: []*types.BlockHeader{
437                                 // main chain
438                                 {
439                                         Height:            1198,
440                                         PreviousBlockHash: testutil.MustDecodeHash("4d3ecf28f3045df23764792f41af17fc20518cc8e83673dc2d0ce07bbf084d7d"),
441                                 },
442                                 {
443                                         Height:            1199,
444                                         PreviousBlockHash: testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
445                                 },
446                                 {
447                                         Height:            1200,
448                                         PreviousBlockHash: testutil.MustDecodeHash("608d82b3660255186fb2b035cfb2ca86e986433218cd2eca2e79611e855a87d3"),
449                                 },
450                                 {
451                                         Height:            1201,
452                                         PreviousBlockHash: testutil.MustDecodeHash("73a2a6a098727877e288a4520f2d8076d700b561277ed7c3f533e3f176496888"),
453                                 },
454                                 {
455                                         Height:            1202,
456                                         PreviousBlockHash: testutil.MustDecodeHash("a5be1d1177eb027327baedb869f902f74850476d0b9432a30391a3165d3af7cc"),
457                                 },
458                                 // fork chain
459                                 {
460                                         Height:            1200,
461                                         PreviousBlockHash: testutil.MustDecodeHash("608d82b3660255186fb2b035cfb2ca86e986433218cd2eca2e79611e855a87d3"),
462                                         Timestamp:         1, // in order to make different hash
463                                 },
464                                 {
465                                         Height:            1201,
466                                         PreviousBlockHash: testutil.MustDecodeHash("d630737ca79f70826946f29e7cad3612662edda01c28b9471ec5b04917cdbf3e"),
467                                 },
468                         },
469                         storedBlocks: []*types.Block{
470                                 // main chain
471                                 {
472                                         BlockHeader: types.BlockHeader{
473                                                 Height:            1198,
474                                                 PreviousBlockHash: testutil.MustDecodeHash("4d3ecf28f3045df23764792f41af17fc20518cc8e83673dc2d0ce07bbf084d7d"),
475                                         },
476                                         Transactions: []*types.Tx{
477                                                 {
478                                                         TxData: types.TxData{
479                                                                 Inputs: []*types.TxInput{
480                                                                         types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 1E14, 0, []byte{0, 1}),
481                                                                 },
482                                                                 Outputs: []*types.TxOutput{
483                                                                         types.NewVoteOutput(*consensus.BTMAssetID, 1E14, []byte{0, 1}, testutil.MustDecodeHexString("1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842")),
484                                                                 },
485                                                         },
486                                                 },
487                                         },
488                                 },
489                                 {
490                                         BlockHeader: types.BlockHeader{
491                                                 Height:            1199,
492                                                 PreviousBlockHash: testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
493                                         },
494                                         Transactions: []*types.Tx{
495                                                 {
496                                                         TxData: types.TxData{
497                                                                 Inputs: []*types.TxInput{
498                                                                         types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 1E14, 0, []byte{0, 1}),
499                                                                 },
500                                                                 Outputs: []*types.TxOutput{
501                                                                         types.NewVoteOutput(*consensus.BTMAssetID, 1E14, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
502                                                                 },
503                                                         },
504                                                 },
505                                         },
506                                 },
507                                 {
508                                         BlockHeader: types.BlockHeader{
509                                                 Height:            1200,
510                                                 PreviousBlockHash: testutil.MustDecodeHash("608d82b3660255186fb2b035cfb2ca86e986433218cd2eca2e79611e855a87d3"),
511                                         },
512                                         Transactions: []*types.Tx{
513                                                 {
514                                                         TxData: types.TxData{
515                                                                 Inputs: []*types.TxInput{
516                                                                         types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 2E14, 0, []byte{0, 1}),
517                                                                 },
518                                                                 Outputs: []*types.TxOutput{
519                                                                         types.NewVoteOutput(*consensus.BTMAssetID, 2E14, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
520                                                                 },
521                                                         },
522                                                 },
523                                         },
524                                 },
525                                 // fork chain
526                                 {
527                                         BlockHeader: types.BlockHeader{
528                                                 Height:            1200,
529                                                 PreviousBlockHash: testutil.MustDecodeHash("608d82b3660255186fb2b035cfb2ca86e986433218cd2eca2e79611e855a87d3"),
530                                                 Timestamp:         1, // in order to make different hash
531                                         },
532                                         Transactions: []*types.Tx{
533                                                 {
534                                                         TxData: types.TxData{
535                                                                 Inputs: []*types.TxInput{
536                                                                         types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 5E14, 0, []byte{0, 1}),
537                                                                 },
538                                                                 Outputs: []*types.TxOutput{
539                                                                         types.NewVoteOutput(*consensus.BTMAssetID, 5E14, []byte{0, 1}, testutil.MustDecodeHexString("b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef")),
540                                                                 },
541                                                         },
542                                                 },
543                                         },
544                                 },
545                         },
546                         prevBlockHash:   testutil.MustDecodeHash("d630737ca79f70826946f29e7cad3612662edda01c28b9471ec5b04917cdbf3e"),
547                         bestBlockHeight: 1230,
548                         wantConsensusNodes: []*state.ConsensusNode{
549                                 {
550                                         XPub:    mustDecodeXPub("b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef"),
551                                         VoteNum: 1728455289930297,
552                                         Order:   0,
553                                 },
554                                 {
555                                         XPub:    mustDecodeXPub("0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825"),
556                                         VoteNum: 838063475500000,
557                                         Order:   1,
558                                 },
559                                 {
560                                         XPub:    mustDecodeXPub("1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842"),
561                                         VoteNum: 833812985000000,
562                                         Order:   2,
563                                 },
564                                 {
565                                         XPub:    mustDecodeXPub("e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093"),
566                                         VoteNum: 474794800000000,
567                                         Order:   3,
568                                 },
569                                 {
570                                         XPub:    mustDecodeXPub("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67"),
571                                         VoteNum: 374387690000000,
572                                         Order:   4,
573                                 },
574                                 {
575                                         XPub:    mustDecodeXPub("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9"),
576                                         VoteNum: 285918061999999,
577                                         Order:   5,
578                                 },
579                         },
580                 },
581         }
582
583         for i, c := range cases {
584                 store := newDummyStore()
585                 for _, header := range c.storedBlockHeaders {
586                         store.SaveBlockHeader(header)
587                 }
588
589                 for _, block := range c.storedBlocks {
590                         store.SaveBlock(block, nil)
591                 }
592
593                 store.SetConsensusResult(c.prevSeqConsensusResult)
594
595                 chain := &Chain{
596                         store:           store,
597                         bestBlockHeader: &types.BlockHeader{Height: c.bestBlockHeight},
598                 }
599                 gotConsensusNodes, err := chain.getConsensusNodes(&c.prevBlockHash)
600                 if err != nil {
601                         t.Fatal(err)
602                 }
603
604                 wantConsensusNodes := make(map[string]*state.ConsensusNode)
605                 for _, node := range c.wantConsensusNodes {
606                         wantConsensusNodes[node.XPub.String()] = node
607                 }
608
609                 if !testutil.DeepEqual(gotConsensusNodes, wantConsensusNodes) {
610                         t.Errorf("#%d (%s) got consensus nodes:%v, want consensus nodes:%v", i, c.desc, gotConsensusNodes, wantConsensusNodes)
611                 }
612         }
613 }
614
615 func mustDecodeXPub(xpub string) chainkd.XPub {
616         bytes := testutil.MustDecodeHexString(xpub)
617         var result [64]byte
618         copy(result[:], bytes)
619         return result
620 }
621
622 type dummyStore struct {
623         blockHeaders     map[string]*types.BlockHeader
624         blocks           map[string]*types.Block
625         consensusResults map[uint64]*state.ConsensusResult
626 }
627
628 func newDummyStore() *dummyStore {
629         return &dummyStore{
630                 blockHeaders:     make(map[string]*types.BlockHeader),
631                 consensusResults: make(map[uint64]*state.ConsensusResult),
632                 blocks:           make(map[string]*types.Block),
633         }
634 }
635
636 func (s *dummyStore) BlockExist(*bc.Hash) bool {
637         return false
638 }
639
640 func (s *dummyStore) GetBlock(hash *bc.Hash) (*types.Block, error) {
641         return s.blocks[hash.String()], nil
642 }
643
644 func (s *dummyStore) GetBlockHeader(hash *bc.Hash) (*types.BlockHeader, error) {
645         return s.blockHeaders[hash.String()], nil
646 }
647
648 func (s *dummyStore) GetStoreStatus() *BlockStoreState {
649         return nil
650 }
651
652 func (s *dummyStore) GetTransactionStatus(*bc.Hash) (*bc.TransactionStatus, error) {
653         return nil, nil
654 }
655
656 func (s *dummyStore) GetTransactionsUtxo(*state.UtxoViewpoint, []*bc.Tx) error {
657         return nil
658 }
659
660 func (s *dummyStore) GetUtxo(*bc.Hash) (*storage.UtxoEntry, error) {
661         return nil, nil
662 }
663
664 func (s *dummyStore) GetConsensusResult(seq uint64) (*state.ConsensusResult, error) {
665         return s.consensusResults[seq], nil
666 }
667
668 func (s *dummyStore) SetConsensusResult(consensusResult *state.ConsensusResult) {
669         s.consensusResults[consensusResult.Seq] = consensusResult
670 }
671
672 func (s *dummyStore) GetMainChainHash(uint64) (*bc.Hash, error) {
673         return nil, nil
674 }
675
676 func (s *dummyStore) GetBlockHashesByHeight(uint64) ([]*bc.Hash, error) {
677         return nil, nil
678 }
679
680 func (s *dummyStore) SaveBlock(block *types.Block, _ *bc.TransactionStatus) error {
681         hash := block.Hash()
682         s.blocks[hash.String()] = block
683         return nil
684 }
685
686 func (s *dummyStore) SaveBlockHeader(header *types.BlockHeader) error {
687         hash := header.Hash()
688         s.blockHeaders[hash.String()] = header
689         return nil
690 }
691
692 func (s *dummyStore) SaveChainStatus(*types.BlockHeader, *types.BlockHeader, []*types.BlockHeader, *state.UtxoViewpoint, []*state.ConsensusResult) error {
693         return nil
694 }