7 "github.com/bytom/vapor/application/mov"
8 movDatabase "github.com/bytom/vapor/application/mov/database"
9 "github.com/bytom/vapor/consensus"
10 "github.com/bytom/vapor/database"
11 dbm "github.com/bytom/vapor/database/leveldb"
12 "github.com/bytom/vapor/database/storage"
13 "github.com/bytom/vapor/protocol"
14 "github.com/bytom/vapor/protocol/bc"
15 "github.com/bytom/vapor/protocol/bc/types"
16 "github.com/bytom/vapor/protocol/state"
17 "github.com/bytom/vapor/testutil"
20 type chainData struct {
21 bestBlockHeader *types.BlockHeader
22 lastIrrBlockHeader *types.BlockHeader
23 utxoViewPoint *state.UtxoViewpoint
24 storedBlocks []*types.Block
25 consensusResults []*state.ConsensusResult
28 func TestRollback(t *testing.T) {
32 RoundVoteBlockNums uint64
33 beforeChainData *chainData
34 wantChainData *chainData
35 rollbackToTargetHeight uint64
38 desc: "rollback from height 1 to 0",
40 RoundVoteBlockNums: 1200,
41 rollbackToTargetHeight: 0,
42 beforeChainData: &chainData{
43 bestBlockHeader: &types.BlockHeader{
45 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
47 lastIrrBlockHeader: &types.BlockHeader{
49 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
51 utxoViewPoint: &state.UtxoViewpoint{
52 Entries: map[bc.Hash]*storage.UtxoEntry{
53 testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
54 testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
57 storedBlocks: []*types.Block{
59 BlockHeader: types.BlockHeader{
62 Transactions: []*types.Tx{
63 types.NewTx(types.TxData{
64 Inputs: []*types.TxInput{
65 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
67 Outputs: []*types.TxOutput{
68 types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
74 BlockHeader: types.BlockHeader{
76 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
78 Transactions: []*types.Tx{
79 types.NewTx(types.TxData{
80 Inputs: []*types.TxInput{
81 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 2000, 0, []byte{0, 1}),
83 Outputs: []*types.TxOutput{
84 types.NewVoteOutput(*consensus.BTMAssetID, 2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
90 consensusResults: []*state.ConsensusResult{
93 NumOfVote: map[string]uint64{
94 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100002000,
95 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
97 BlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
99 CoinbaseReward: map[string]uint64{"0001": consensus.BlockSubsidy(1) + 10000000000},
103 NumOfVote: map[string]uint64{
104 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
105 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
107 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
109 CoinbaseReward: map[string]uint64{},
113 wantChainData: &chainData{
114 bestBlockHeader: &types.BlockHeader{
117 lastIrrBlockHeader: &types.BlockHeader{
120 storedBlocks: []*types.Block{
122 BlockHeader: types.BlockHeader{
125 Transactions: []*types.Tx{
126 types.NewTx(types.TxData{
127 Inputs: []*types.TxInput{
128 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
130 Outputs: []*types.TxOutput{
131 types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
137 utxoViewPoint: &state.UtxoViewpoint{
138 Entries: map[bc.Hash]*storage.UtxoEntry{
139 testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
142 consensusResults: []*state.ConsensusResult{
145 NumOfVote: map[string]uint64{
146 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
147 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
149 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
151 CoinbaseReward: map[string]uint64{},
157 desc: "rollback from height 2 to 0",
159 RoundVoteBlockNums: 1200,
160 rollbackToTargetHeight: 0,
161 beforeChainData: &chainData{
162 bestBlockHeader: &types.BlockHeader{
164 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
166 lastIrrBlockHeader: &types.BlockHeader{
168 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
170 utxoViewPoint: &state.UtxoViewpoint{
171 Entries: map[bc.Hash]*storage.UtxoEntry{
172 testutil.MustDecodeHash("afee09925bea1695424450a91ad082a378f20534627fa5cb63f036846347ee08"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 2, Spent: true},
173 testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
174 testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
177 storedBlocks: []*types.Block{
179 BlockHeader: types.BlockHeader{
182 Transactions: []*types.Tx{
183 types.NewTx(types.TxData{
184 Inputs: []*types.TxInput{
185 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
187 Outputs: []*types.TxOutput{
188 types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
194 BlockHeader: types.BlockHeader{
196 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
198 Transactions: []*types.Tx{
199 types.NewTx(types.TxData{
200 Inputs: []*types.TxInput{
201 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 2000, 0, []byte{0, 1}),
203 Outputs: []*types.TxOutput{
204 types.NewVoteOutput(*consensus.BTMAssetID, 2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
210 BlockHeader: types.BlockHeader{
212 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
214 Transactions: []*types.Tx{
215 types.NewTx(types.TxData{
216 Inputs: []*types.TxInput{
217 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 3000, 0, []byte{0, 1}),
219 Outputs: []*types.TxOutput{
220 types.NewVoteOutput(*consensus.BTMAssetID, 2500, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
226 consensusResults: []*state.ConsensusResult{
229 NumOfVote: map[string]uint64{
230 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100004500,
231 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
233 BlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
235 CoinbaseReward: map[string]uint64{"0001": consensus.BlockSubsidy(2) + 10000000000},
239 NumOfVote: map[string]uint64{
240 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
241 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
243 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
245 CoinbaseReward: map[string]uint64{},
249 wantChainData: &chainData{
250 bestBlockHeader: &types.BlockHeader{
253 lastIrrBlockHeader: &types.BlockHeader{
256 storedBlocks: []*types.Block{
258 BlockHeader: types.BlockHeader{
261 Transactions: []*types.Tx{
262 types.NewTx(types.TxData{
263 Inputs: []*types.TxInput{
264 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
266 Outputs: []*types.TxOutput{
267 types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
273 utxoViewPoint: &state.UtxoViewpoint{
274 Entries: map[bc.Hash]*storage.UtxoEntry{
275 testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
278 consensusResults: []*state.ConsensusResult{
281 NumOfVote: map[string]uint64{
282 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
283 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
285 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
287 CoinbaseReward: map[string]uint64{},
293 desc: "rollback from height 2 to 1",
295 RoundVoteBlockNums: 1200,
296 rollbackToTargetHeight: 1,
297 beforeChainData: &chainData{
298 bestBlockHeader: &types.BlockHeader{
300 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
302 lastIrrBlockHeader: &types.BlockHeader{
304 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
306 utxoViewPoint: &state.UtxoViewpoint{
307 Entries: map[bc.Hash]*storage.UtxoEntry{
308 testutil.MustDecodeHash("afee09925bea1695424450a91ad082a378f20534627fa5cb63f036846347ee08"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 2, Spent: true},
309 testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
310 testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
313 storedBlocks: []*types.Block{
315 BlockHeader: types.BlockHeader{
318 Transactions: []*types.Tx{
319 types.NewTx(types.TxData{
320 Inputs: []*types.TxInput{
321 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
323 Outputs: []*types.TxOutput{
324 types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
330 BlockHeader: types.BlockHeader{
332 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
334 Transactions: []*types.Tx{
335 types.NewTx(types.TxData{
336 Inputs: []*types.TxInput{
337 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 2000, 0, []byte{0, 1}),
339 Outputs: []*types.TxOutput{
340 types.NewVoteOutput(*consensus.BTMAssetID, 2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
346 BlockHeader: types.BlockHeader{
348 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
350 Transactions: []*types.Tx{
351 types.NewTx(types.TxData{
352 Inputs: []*types.TxInput{
353 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 3000, 0, []byte{0, 1}),
355 Outputs: []*types.TxOutput{
356 types.NewVoteOutput(*consensus.BTMAssetID, 2500, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
362 consensusResults: []*state.ConsensusResult{
365 NumOfVote: map[string]uint64{
366 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100004500,
367 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
369 BlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
371 CoinbaseReward: map[string]uint64{"0001": consensus.BlockSubsidy(1) + consensus.BlockSubsidy(2) + 500},
375 NumOfVote: map[string]uint64{
376 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
377 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
379 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
381 CoinbaseReward: map[string]uint64{},
385 wantChainData: &chainData{
386 bestBlockHeader: &types.BlockHeader{
388 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
390 lastIrrBlockHeader: &types.BlockHeader{
392 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
394 storedBlocks: []*types.Block{
396 BlockHeader: types.BlockHeader{
399 Transactions: []*types.Tx{
400 types.NewTx(types.TxData{
401 Inputs: []*types.TxInput{
402 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
404 Outputs: []*types.TxOutput{
405 types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
411 BlockHeader: types.BlockHeader{
413 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
415 Transactions: []*types.Tx{
416 types.NewTx(types.TxData{
417 Inputs: []*types.TxInput{
418 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 2000, 0, []byte{0, 1}),
420 Outputs: []*types.TxOutput{
421 types.NewVoteOutput(*consensus.BTMAssetID, 2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
427 utxoViewPoint: &state.UtxoViewpoint{
428 Entries: map[bc.Hash]*storage.UtxoEntry{
429 testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
430 testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
433 consensusResults: []*state.ConsensusResult{
436 NumOfVote: map[string]uint64{
437 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100002000,
438 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
440 BlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
442 CoinbaseReward: map[string]uint64{"0001": consensus.BlockSubsidy(1)},
446 NumOfVote: map[string]uint64{
447 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
448 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
450 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
452 CoinbaseReward: map[string]uint64{},
458 desc: "rollback from height 2 to 1, RoundVoteBlockNums is 2",
460 RoundVoteBlockNums: 2,
461 rollbackToTargetHeight: 1,
462 beforeChainData: &chainData{
463 bestBlockHeader: &types.BlockHeader{
465 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
467 lastIrrBlockHeader: &types.BlockHeader{
469 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
471 utxoViewPoint: &state.UtxoViewpoint{
472 Entries: map[bc.Hash]*storage.UtxoEntry{
473 testutil.MustDecodeHash("afee09925bea1695424450a91ad082a378f20534627fa5cb63f036846347ee08"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 2, Spent: true},
474 testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
475 testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
478 storedBlocks: []*types.Block{
480 BlockHeader: types.BlockHeader{
483 Transactions: []*types.Tx{
484 types.NewTx(types.TxData{
485 Inputs: []*types.TxInput{
486 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
488 Outputs: []*types.TxOutput{
489 types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
495 BlockHeader: types.BlockHeader{
497 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
499 Transactions: []*types.Tx{
500 types.NewTx(types.TxData{
501 Inputs: []*types.TxInput{
502 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 2000, 0, []byte{0, 1}),
504 Outputs: []*types.TxOutput{
505 types.NewVoteOutput(*consensus.BTMAssetID, 2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
511 BlockHeader: types.BlockHeader{
513 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
515 Transactions: []*types.Tx{
516 types.NewTx(types.TxData{
517 Inputs: []*types.TxInput{
518 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 3000, 0, []byte{0, 1}),
520 Outputs: []*types.TxOutput{
521 types.NewVoteOutput(*consensus.BTMAssetID, 2500, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
527 consensusResults: []*state.ConsensusResult{
530 NumOfVote: map[string]uint64{
531 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100004500,
532 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
534 BlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
536 CoinbaseReward: map[string]uint64{"0001": consensus.BlockSubsidy(1) + consensus.BlockSubsidy(2) + 500},
540 NumOfVote: map[string]uint64{
541 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
542 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
544 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
546 CoinbaseReward: map[string]uint64{},
550 wantChainData: &chainData{
551 bestBlockHeader: &types.BlockHeader{
553 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
555 lastIrrBlockHeader: &types.BlockHeader{
557 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
559 storedBlocks: []*types.Block{
561 BlockHeader: types.BlockHeader{
564 Transactions: []*types.Tx{
565 types.NewTx(types.TxData{
566 Inputs: []*types.TxInput{
567 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
569 Outputs: []*types.TxOutput{
570 types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
576 BlockHeader: types.BlockHeader{
578 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
580 Transactions: []*types.Tx{
581 types.NewTx(types.TxData{
582 Inputs: []*types.TxInput{
583 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 2000, 0, []byte{0, 1}),
585 Outputs: []*types.TxOutput{
586 types.NewVoteOutput(*consensus.BTMAssetID, 2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
592 utxoViewPoint: &state.UtxoViewpoint{
593 Entries: map[bc.Hash]*storage.UtxoEntry{
594 testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
595 testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
598 consensusResults: []*state.ConsensusResult{
601 NumOfVote: map[string]uint64{
602 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100002000,
603 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
605 BlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
607 CoinbaseReward: map[string]uint64{"0001": consensus.BlockSubsidy(1)},
611 NumOfVote: map[string]uint64{
612 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
613 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
615 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
617 CoinbaseReward: map[string]uint64{},
623 desc: "rollback from height 3 to 1, RoundVoteBlockNums is 2",
625 RoundVoteBlockNums: 2,
626 rollbackToTargetHeight: 1,
627 beforeChainData: &chainData{
628 bestBlockHeader: &types.BlockHeader{
630 PreviousBlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
632 lastIrrBlockHeader: &types.BlockHeader{
634 PreviousBlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
636 utxoViewPoint: &state.UtxoViewpoint{
637 Entries: map[bc.Hash]*storage.UtxoEntry{
638 testutil.MustDecodeHash("5b4d53fbc2a489847f34dd0e0c085797fe7cf0a3a9a2f3231d11bdad16dea2be"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 3, Spent: true},
639 testutil.MustDecodeHash("4c2b719d10fc6b9c2a7c343491ddd8c0d6bd57f9c6680bfda557689c182cf685"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 2, Spent: true},
640 testutil.MustDecodeHash("9fb6f213e3130810e755675707d0e9870c79a91c575638a580fae65568ca9e99"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
641 testutil.MustDecodeHash("3d1617908e624a2042c23be4f671b261d5b8a2a61b8421ee6a702c6e071428a8"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
644 storedBlocks: []*types.Block{
646 BlockHeader: types.BlockHeader{
649 Transactions: []*types.Tx{
650 types.NewTx(types.TxData{
651 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
652 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
654 types.NewTx(types.TxData{
655 Inputs: []*types.TxInput{
656 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 100000000, 0, []byte{0, 1}),
658 Outputs: []*types.TxOutput{
659 types.NewVoteOutput(*consensus.BTMAssetID, 100000000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
665 BlockHeader: types.BlockHeader{
667 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
669 Transactions: []*types.Tx{
670 types.NewTx(types.TxData{
671 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
672 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
674 types.NewTx(types.TxData{
675 Inputs: []*types.TxInput{
676 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 200000000, 0, []byte{0, 1}),
678 Outputs: []*types.TxOutput{
679 types.NewVoteOutput(*consensus.BTMAssetID, 200000000-2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
685 BlockHeader: types.BlockHeader{
687 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
689 Transactions: []*types.Tx{
690 types.NewTx(types.TxData{
691 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
692 Outputs: []*types.TxOutput{
693 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
696 types.NewTx(types.TxData{
697 Inputs: []*types.TxInput{
698 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 300000000, 0, []byte{0, 1}),
700 Outputs: []*types.TxOutput{
701 types.NewVoteOutput(*consensus.BTMAssetID, 250000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
707 BlockHeader: types.BlockHeader{
709 PreviousBlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
711 Transactions: []*types.Tx{
712 types.NewTx(types.TxData{
713 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
714 Outputs: []*types.TxOutput{
715 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
716 types.NewIntraChainOutput(bc.AssetID{}, consensus.BlockSubsidy(1)+consensus.BlockSubsidy(2)+50002000, []byte{0x51}),
719 types.NewTx(types.TxData{
720 Inputs: []*types.TxInput{
721 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 400000000, 0, []byte{0, 1}),
723 Outputs: []*types.TxOutput{
724 types.NewVoteOutput(*consensus.BTMAssetID, 160000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
730 consensusResults: []*state.ConsensusResult{
733 NumOfVote: map[string]uint64{
734 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 609998000,
735 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
737 BlockHash: testutil.MustDecodeHash("0c1cd1c0a6e6161f437c382cca21ce28921234ed7c4f252f7e4bbc9a523b74ac"),
739 CoinbaseReward: map[string]uint64{"51": consensus.BlockSubsidy(3) + 240000000},
743 NumOfVote: map[string]uint64{
744 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 449998000,
745 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
747 BlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
749 CoinbaseReward: map[string]uint64{"51": consensus.BlockSubsidy(1) + consensus.BlockSubsidy(2) + 50002000},
753 NumOfVote: map[string]uint64{
754 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
755 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
757 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
759 CoinbaseReward: map[string]uint64{},
763 wantChainData: &chainData{
764 bestBlockHeader: &types.BlockHeader{
766 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
768 lastIrrBlockHeader: &types.BlockHeader{
770 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
772 storedBlocks: []*types.Block{
774 BlockHeader: types.BlockHeader{
777 Transactions: []*types.Tx{
778 types.NewTx(types.TxData{
779 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
780 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
782 types.NewTx(types.TxData{
783 Inputs: []*types.TxInput{
784 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 100000000, 0, []byte{0, 1}),
786 Outputs: []*types.TxOutput{
787 types.NewVoteOutput(*consensus.BTMAssetID, 100000000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
793 BlockHeader: types.BlockHeader{
795 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
797 Transactions: []*types.Tx{
798 types.NewTx(types.TxData{
799 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
800 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
802 types.NewTx(types.TxData{
803 Inputs: []*types.TxInput{
804 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 200000000, 0, []byte{0, 1}),
806 Outputs: []*types.TxOutput{
807 types.NewVoteOutput(*consensus.BTMAssetID, 200000000-2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
813 utxoViewPoint: &state.UtxoViewpoint{
814 Entries: map[bc.Hash]*storage.UtxoEntry{
815 testutil.MustDecodeHash("9fb6f213e3130810e755675707d0e9870c79a91c575638a580fae65568ca9e99"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
816 testutil.MustDecodeHash("3d1617908e624a2042c23be4f671b261d5b8a2a61b8421ee6a702c6e071428a8"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
819 consensusResults: []*state.ConsensusResult{
822 NumOfVote: map[string]uint64{
823 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000 + 100000000 - 2000,
824 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
826 BlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
828 CoinbaseReward: map[string]uint64{"51": consensus.BlockSubsidy(1) + 2000},
832 NumOfVote: map[string]uint64{
833 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
834 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
836 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
838 CoinbaseReward: map[string]uint64{},
844 desc: "rollback from height 3 to 2, RoundVoteBlockNums is 2",
846 RoundVoteBlockNums: 2,
847 rollbackToTargetHeight: 2,
848 beforeChainData: &chainData{
849 bestBlockHeader: &types.BlockHeader{
851 PreviousBlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
853 lastIrrBlockHeader: &types.BlockHeader{
855 PreviousBlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
857 utxoViewPoint: &state.UtxoViewpoint{
858 Entries: map[bc.Hash]*storage.UtxoEntry{
859 testutil.MustDecodeHash("5b4d53fbc2a489847f34dd0e0c085797fe7cf0a3a9a2f3231d11bdad16dea2be"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 3, Spent: true},
860 testutil.MustDecodeHash("4c2b719d10fc6b9c2a7c343491ddd8c0d6bd57f9c6680bfda557689c182cf685"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 2, Spent: true},
861 testutil.MustDecodeHash("9fb6f213e3130810e755675707d0e9870c79a91c575638a580fae65568ca9e99"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
862 testutil.MustDecodeHash("3d1617908e624a2042c23be4f671b261d5b8a2a61b8421ee6a702c6e071428a8"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
865 storedBlocks: []*types.Block{
867 BlockHeader: types.BlockHeader{
870 Transactions: []*types.Tx{
871 types.NewTx(types.TxData{
872 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
873 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
875 types.NewTx(types.TxData{
876 Inputs: []*types.TxInput{
877 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 100000000, 0, []byte{0, 1}),
879 Outputs: []*types.TxOutput{
880 types.NewVoteOutput(*consensus.BTMAssetID, 100000000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
886 BlockHeader: types.BlockHeader{
888 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
890 Transactions: []*types.Tx{
891 types.NewTx(types.TxData{
892 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
893 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
895 types.NewTx(types.TxData{
896 Inputs: []*types.TxInput{
897 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 200000000, 0, []byte{0, 1}),
899 Outputs: []*types.TxOutput{
900 types.NewVoteOutput(*consensus.BTMAssetID, 200000000-2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
906 BlockHeader: types.BlockHeader{
908 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
910 Transactions: []*types.Tx{
911 types.NewTx(types.TxData{
912 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
913 Outputs: []*types.TxOutput{
914 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
917 types.NewTx(types.TxData{
918 Inputs: []*types.TxInput{
919 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 300000000, 0, []byte{0, 1}),
921 Outputs: []*types.TxOutput{
922 types.NewVoteOutput(*consensus.BTMAssetID, 250000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
928 BlockHeader: types.BlockHeader{
930 PreviousBlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
932 Transactions: []*types.Tx{
933 types.NewTx(types.TxData{
934 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
935 Outputs: []*types.TxOutput{
936 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
937 types.NewIntraChainOutput(bc.AssetID{}, consensus.BlockSubsidy(1)+consensus.BlockSubsidy(2)+50002000, []byte{0x51}),
940 types.NewTx(types.TxData{
941 Inputs: []*types.TxInput{
942 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 400000000, 0, []byte{0, 1}),
944 Outputs: []*types.TxOutput{
945 types.NewVoteOutput(*consensus.BTMAssetID, 160000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
951 consensusResults: []*state.ConsensusResult{
954 NumOfVote: map[string]uint64{
955 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 609998000,
956 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
958 BlockHash: testutil.MustDecodeHash("0c1cd1c0a6e6161f437c382cca21ce28921234ed7c4f252f7e4bbc9a523b74ac"),
960 CoinbaseReward: map[string]uint64{"51": consensus.BlockSubsidy(3) + 240000000},
964 NumOfVote: map[string]uint64{
965 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 449998000,
966 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
968 BlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
970 CoinbaseReward: map[string]uint64{"51": consensus.BlockSubsidy(1) + consensus.BlockSubsidy(2) + 50002000},
974 NumOfVote: map[string]uint64{
975 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
976 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
978 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
980 CoinbaseReward: map[string]uint64{},
984 wantChainData: &chainData{
985 bestBlockHeader: &types.BlockHeader{
987 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
989 lastIrrBlockHeader: &types.BlockHeader{
991 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
993 storedBlocks: []*types.Block{
995 BlockHeader: types.BlockHeader{
998 Transactions: []*types.Tx{
999 types.NewTx(types.TxData{
1000 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1001 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
1003 types.NewTx(types.TxData{
1004 Inputs: []*types.TxInput{
1005 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 100000000, 0, []byte{0, 1}),
1007 Outputs: []*types.TxOutput{
1008 types.NewVoteOutput(*consensus.BTMAssetID, 100000000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
1014 BlockHeader: types.BlockHeader{
1016 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
1018 Transactions: []*types.Tx{
1019 types.NewTx(types.TxData{
1020 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1021 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
1023 types.NewTx(types.TxData{
1024 Inputs: []*types.TxInput{
1025 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 200000000, 0, []byte{0, 1}),
1027 Outputs: []*types.TxOutput{
1028 types.NewVoteOutput(*consensus.BTMAssetID, 200000000-2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1034 BlockHeader: types.BlockHeader{
1036 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
1038 Transactions: []*types.Tx{
1039 types.NewTx(types.TxData{
1040 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1041 Outputs: []*types.TxOutput{
1042 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
1045 types.NewTx(types.TxData{
1046 Inputs: []*types.TxInput{
1047 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 300000000, 0, []byte{0, 1}),
1049 Outputs: []*types.TxOutput{
1050 types.NewVoteOutput(*consensus.BTMAssetID, 250000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1056 utxoViewPoint: &state.UtxoViewpoint{
1057 Entries: map[bc.Hash]*storage.UtxoEntry{
1058 testutil.MustDecodeHash("9fb6f213e3130810e755675707d0e9870c79a91c575638a580fae65568ca9e99"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
1059 testutil.MustDecodeHash("3d1617908e624a2042c23be4f671b261d5b8a2a61b8421ee6a702c6e071428a8"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
1060 testutil.MustDecodeHash("4c2b719d10fc6b9c2a7c343491ddd8c0d6bd57f9c6680bfda557689c182cf685"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 2, Spent: true},
1063 consensusResults: []*state.ConsensusResult{
1066 NumOfVote: map[string]uint64{
1067 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000 + 100000000 - 2000 + 250000000,
1068 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
1070 BlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
1072 CoinbaseReward: map[string]uint64{"51": consensus.BlockSubsidy(1) + consensus.BlockSubsidy(2) + 50002000},
1076 NumOfVote: map[string]uint64{
1077 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
1078 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
1080 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
1082 CoinbaseReward: map[string]uint64{},
1088 desc: "rollback from height 4 to 2, there is two chain , and round vote block nums is 2",
1090 RoundVoteBlockNums: 2,
1091 rollbackToTargetHeight: 2,
1092 beforeChainData: &chainData{
1093 bestBlockHeader: &types.BlockHeader{
1095 Timestamp: uint64(1528945008),
1096 PreviousBlockHash: testutil.MustDecodeHash("64a41230412f26a5c0a1734515d9e177bd3573be2ae1d55c4533509a7c9cce8e"),
1098 lastIrrBlockHeader: &types.BlockHeader{
1100 Timestamp: uint64(1528945008),
1101 PreviousBlockHash: testutil.MustDecodeHash("64a41230412f26a5c0a1734515d9e177bd3573be2ae1d55c4533509a7c9cce8e"),
1103 utxoViewPoint: &state.UtxoViewpoint{
1104 Entries: map[bc.Hash]*storage.UtxoEntry{
1105 testutil.MustDecodeHash("3c07f3159d4e2a0527129d644a8fcd09ce26555e94c9c7f348464120ef463275"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 5, Spent: true},
1106 testutil.MustDecodeHash("927144d2a391e17dc12184f5ae163b994984132ad72c34d854bb9009b68cd4cc"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 4, Spent: true},
1107 testutil.MustDecodeHash("fa43f4ca43bcb0e94d43b52c56d1740dea1329b59a44f6ee045d70446881c514"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 3, Spent: true},
1108 testutil.MustDecodeHash("f081ccd0c97ae34bc5580a0405d9b1ed0b0ed9e1410f1786b7112b348a412e3d"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 4, Spent: true},
1109 testutil.MustDecodeHash("2704fa67c76e020b08ffa3f93a500acebcaf68b45ba43d8b3b08b68c5bb1eff1"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 3, Spent: true},
1110 testutil.MustDecodeHash("4c2b719d10fc6b9c2a7c343491ddd8c0d6bd57f9c6680bfda557689c182cf685"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 2, Spent: true},
1111 testutil.MustDecodeHash("9fb6f213e3130810e755675707d0e9870c79a91c575638a580fae65568ca9e99"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
1112 testutil.MustDecodeHash("3d1617908e624a2042c23be4f671b261d5b8a2a61b8421ee6a702c6e071428a8"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
1115 storedBlocks: []*types.Block{
1117 BlockHeader: types.BlockHeader{
1120 Transactions: []*types.Tx{
1121 types.NewTx(types.TxData{
1122 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1123 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
1125 types.NewTx(types.TxData{
1126 Inputs: []*types.TxInput{
1127 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 100000000, 0, []byte{0, 1}),
1129 Outputs: []*types.TxOutput{
1130 types.NewVoteOutput(*consensus.BTMAssetID, 100000000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
1136 BlockHeader: types.BlockHeader{
1138 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
1140 Transactions: []*types.Tx{
1141 types.NewTx(types.TxData{
1142 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1143 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
1145 types.NewTx(types.TxData{
1146 Inputs: []*types.TxInput{
1147 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 200000000, 0, []byte{0, 1}),
1149 Outputs: []*types.TxOutput{
1150 types.NewVoteOutput(*consensus.BTMAssetID, 200000000-2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1156 BlockHeader: types.BlockHeader{
1158 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
1160 Transactions: []*types.Tx{
1161 types.NewTx(types.TxData{
1162 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1163 Outputs: []*types.TxOutput{
1164 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
1167 types.NewTx(types.TxData{
1168 Inputs: []*types.TxInput{
1169 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 300000000, 0, []byte{0, 1}),
1171 Outputs: []*types.TxOutput{
1172 types.NewVoteOutput(*consensus.BTMAssetID, 250000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1178 BlockHeader: types.BlockHeader{
1180 Timestamp: uint64(1528945000),
1181 PreviousBlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
1183 Transactions: []*types.Tx{
1184 types.NewTx(types.TxData{
1185 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1186 Outputs: []*types.TxOutput{
1187 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
1188 types.NewIntraChainOutput(bc.AssetID{}, consensus.BlockSubsidy(1)+consensus.BlockSubsidy(2)+50002000, []byte{0x51}),
1191 types.NewTx(types.TxData{
1192 Inputs: []*types.TxInput{
1193 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 440000000, 0, []byte{0, 1}),
1195 Outputs: []*types.TxOutput{
1196 types.NewVoteOutput(*consensus.BTMAssetID, 160000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1202 BlockHeader: types.BlockHeader{
1204 Timestamp: uint64(1528945005),
1205 PreviousBlockHash: testutil.MustDecodeHash("bec3dd0d6fecb80a6f3a0373ec2ae676cc1ce72af83546f3d4672231c9b080e6"),
1207 Transactions: []*types.Tx{
1208 types.NewTx(types.TxData{
1209 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1210 Outputs: []*types.TxOutput{
1211 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
1214 types.NewTx(types.TxData{
1215 Inputs: []*types.TxInput{
1216 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 500000000, 0, []byte{0, 1}),
1218 Outputs: []*types.TxOutput{
1219 types.NewVoteOutput(*consensus.BTMAssetID, 160000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1225 BlockHeader: types.BlockHeader{
1227 Timestamp: uint64(1528945001),
1228 PreviousBlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
1230 Transactions: []*types.Tx{
1231 types.NewTx(types.TxData{
1232 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1233 Outputs: []*types.TxOutput{
1234 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
1235 types.NewIntraChainOutput(bc.AssetID{}, consensus.BlockSubsidy(1)+consensus.BlockSubsidy(2)+50002000, []byte{0x51}),
1238 types.NewTx(types.TxData{
1239 Inputs: []*types.TxInput{
1240 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 402000000, 0, []byte{0, 1}),
1242 Outputs: []*types.TxOutput{
1243 types.NewVoteOutput(*consensus.BTMAssetID, 200000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1249 BlockHeader: types.BlockHeader{
1251 Timestamp: uint64(1528945006),
1252 PreviousBlockHash: testutil.MustDecodeHash("1d2d01a97d1239de51b4e7d0fb522f71771d2d4f9a0a559154519859cc44a230"),
1254 Transactions: []*types.Tx{
1255 types.NewTx(types.TxData{
1256 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1257 Outputs: []*types.TxOutput{
1258 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
1261 types.NewTx(types.TxData{
1262 Inputs: []*types.TxInput{
1263 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 410000000, 0, []byte{0, 1}),
1265 Outputs: []*types.TxOutput{
1266 types.NewVoteOutput(*consensus.BTMAssetID, 170000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1272 BlockHeader: types.BlockHeader{
1274 Timestamp: uint64(1528945008),
1275 PreviousBlockHash: testutil.MustDecodeHash("64a41230412f26a5c0a1734515d9e177bd3573be2ae1d55c4533509a7c9cce8e"),
1277 Transactions: []*types.Tx{
1278 types.NewTx(types.TxData{
1279 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1280 Outputs: []*types.TxOutput{
1281 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
1282 types.NewIntraChainOutput(bc.AssetID{}, consensus.BlockSubsidy(3)+consensus.BlockSubsidy(4)+520000000, []byte{0x51}),
1285 types.NewTx(types.TxData{
1286 Inputs: []*types.TxInput{
1287 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 400004000, 0, []byte{0, 1}),
1289 Outputs: []*types.TxOutput{
1290 types.NewVoteOutput(*consensus.BTMAssetID, 160004000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1296 consensusResults: []*state.ConsensusResult{
1299 NumOfVote: map[string]uint64{
1300 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 980002000,
1301 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
1303 BlockHash: testutil.MustDecodeHash("075ce54f7d4c1b524474265219be52238beec98138f0c0a4d21f1a6b0047914a"),
1305 CoinbaseReward: map[string]uint64{"51": consensus.BlockSubsidy(5) + 240000000},
1309 NumOfVote: map[string]uint64{
1310 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 819998000,
1311 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
1313 BlockHash: testutil.MustDecodeHash("64a41230412f26a5c0a1734515d9e177bd3573be2ae1d55c4533509a7c9cce8e"),
1315 CoinbaseReward: map[string]uint64{"51": consensus.BlockSubsidy(3) + consensus.BlockSubsidy(4) + 442000000},
1319 NumOfVote: map[string]uint64{
1320 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 449998000,
1321 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
1323 BlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
1325 CoinbaseReward: map[string]uint64{"51": consensus.BlockSubsidy(1) + consensus.BlockSubsidy(2) + 50002000},
1329 NumOfVote: map[string]uint64{
1330 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
1331 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
1333 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
1335 CoinbaseReward: map[string]uint64{},
1339 wantChainData: &chainData{
1340 bestBlockHeader: &types.BlockHeader{
1342 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
1344 lastIrrBlockHeader: &types.BlockHeader{
1346 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
1348 storedBlocks: []*types.Block{
1350 BlockHeader: types.BlockHeader{
1353 Transactions: []*types.Tx{
1354 types.NewTx(types.TxData{
1355 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1356 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
1358 types.NewTx(types.TxData{
1359 Inputs: []*types.TxInput{
1360 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 100000000, 0, []byte{0, 1}),
1362 Outputs: []*types.TxOutput{
1363 types.NewVoteOutput(*consensus.BTMAssetID, 100000000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
1369 BlockHeader: types.BlockHeader{
1371 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
1373 Transactions: []*types.Tx{
1374 types.NewTx(types.TxData{
1375 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1376 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
1378 types.NewTx(types.TxData{
1379 Inputs: []*types.TxInput{
1380 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 200000000, 0, []byte{0, 1}),
1382 Outputs: []*types.TxOutput{
1383 types.NewVoteOutput(*consensus.BTMAssetID, 200000000-2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1389 BlockHeader: types.BlockHeader{
1391 PreviousBlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
1393 Transactions: []*types.Tx{
1394 types.NewTx(types.TxData{
1395 Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
1396 Outputs: []*types.TxOutput{
1397 types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51}),
1400 types.NewTx(types.TxData{
1401 Inputs: []*types.TxInput{
1402 types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 300000000, 0, []byte{0, 1}),
1404 Outputs: []*types.TxOutput{
1405 types.NewVoteOutput(*consensus.BTMAssetID, 250000000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
1411 consensusResults: []*state.ConsensusResult{
1414 NumOfVote: map[string]uint64{
1415 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000 + 100000000 - 2000 + 250000000,
1416 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
1418 BlockHash: testutil.MustDecodeHash("699d3f59d4afe7eea85df31814628d7d34ace7f5e76d6c9ebf4c54482d2cd333"),
1420 CoinbaseReward: map[string]uint64{"51": consensus.BlockSubsidy(1) + consensus.BlockSubsidy(2) + 50002000},
1424 NumOfVote: map[string]uint64{
1425 "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
1426 "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 200000000,
1428 BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
1430 CoinbaseReward: map[string]uint64{},
1433 utxoViewPoint: &state.UtxoViewpoint{
1434 Entries: map[bc.Hash]*storage.UtxoEntry{
1435 testutil.MustDecodeHash("9fb6f213e3130810e755675707d0e9870c79a91c575638a580fae65568ca9e99"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
1436 testutil.MustDecodeHash("3d1617908e624a2042c23be4f671b261d5b8a2a61b8421ee6a702c6e071428a8"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
1437 testutil.MustDecodeHash("4c2b719d10fc6b9c2a7c343491ddd8c0d6bd57f9c6680bfda557689c182cf685"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 2, Spent: true},
1444 for i, c := range cases {
1445 consensus.ActiveNetParams.RoundVoteBlockNums = c.RoundVoteBlockNums
1447 movDB := dbm.NewDB("mov_db", "leveldb", "mov_db")
1448 movCore := mov.NewCoreWithDB(movDatabase.NewLevelDBMovStore(movDB), c.movStartHeight)
1450 blockDB := dbm.NewDB("block_db", "leveldb", "block_db")
1451 store := database.NewStore(blockDB)
1453 mustSaveBlocks(c.beforeChainData.storedBlocks, store)
1455 var mainChainBlockHeaders []*types.BlockHeader
1456 for _, block := range c.beforeChainData.storedBlocks {
1457 mainChainBlockHeaders = append(mainChainBlockHeaders, &block.BlockHeader)
1459 if err := store.SaveChainStatus(c.beforeChainData.bestBlockHeader, c.beforeChainData.lastIrrBlockHeader, mainChainBlockHeaders, c.beforeChainData.utxoViewPoint, c.beforeChainData.consensusResults); err != nil {
1463 chain, err := protocol.NewChain(store, nil, []protocol.SubProtocol{movCore}, nil)
1468 if err := chain.Rollback(c.rollbackToTargetHeight); err != nil {
1472 if !testutil.DeepEqual(chain.LastIrreversibleHeader(), c.wantChainData.lastIrrBlockHeader) {
1473 t.Errorf("lastIrrBlockHeader is not right!")
1476 if !testutil.DeepEqual(chain.BestBlockHeader(), c.wantChainData.bestBlockHeader) {
1477 t.Errorf("wantBestBlockHeader is not right!")
1480 gotConsensusResults := mustGetConsensusResultFromStore(store, chain)
1481 if !testutil.DeepEqual(gotConsensusResults, c.wantChainData.consensusResults) {
1482 t.Errorf("cases#%d(%s) wantBestConsensusResult is not right!", i, c.desc)
1485 gotBlocks := mustGetBlocksFromStore(chain)
1486 if !blocksEquals(gotBlocks, c.wantChainData.storedBlocks) {
1487 t.Errorf("cases#%d(%s) the blocks is not same!", i, c.desc)
1490 gotTransactions := getBcTransactions(gotBlocks)
1491 gotUtxoViewPoint := state.NewUtxoViewpoint()
1492 if err = store.GetTransactionsUtxo(gotUtxoViewPoint, gotTransactions); err != nil {
1496 if !testutil.DeepEqual(gotUtxoViewPoint, c.wantChainData.utxoViewPoint) {
1501 os.RemoveAll("block_db")
1503 os.RemoveAll("mov_db")
1508 func blocksEquals(blocks1 []*types.Block, blocks2 []*types.Block) bool {
1509 blockHashMap1 := make(map[string]interface{})
1510 for _, block := range blocks1 {
1511 hash := block.Hash()
1512 blockHashMap1[hash.String()] = nil
1515 blockHashMap2 := make(map[string]interface{})
1516 for _, block := range blocks2 {
1517 hash := block.Hash()
1518 blockHashMap2[hash.String()] = nil
1520 return testutil.DeepEqual(blockHashMap1, blockHashMap2)
1523 func getBcTransactions(blocks []*types.Block) []*bc.Tx {
1525 for _, block := range blocks {
1526 for _, tx := range block.Transactions {
1527 txs = append(txs, tx.Tx)
1533 func mustSaveBlocks(blocks []*types.Block, store *database.Store) {
1534 for _, block := range blocks {
1535 status := bc.NewTransactionStatus()
1536 for index := range block.Transactions {
1537 if err := status.SetStatus(index, false); err != nil {
1541 if err := store.SaveBlock(block, status); err != nil {
1547 func mustGetBlocksFromStore(chain *protocol.Chain) []*types.Block {
1548 var blocks []*types.Block
1549 for height := int64(chain.BestBlockHeight()); height >= 0; height-- {
1550 block, err := chain.GetBlockByHeight(uint64(height))
1555 blocks = append(blocks, block)
1560 func mustGetConsensusResultFromStore(store *database.Store, chain *protocol.Chain) []*state.ConsensusResult {
1561 var consensusResults []*state.ConsensusResult
1562 for seq := int64(state.CalcVoteSeq(chain.BestBlockHeight())); seq >= 0; seq-- {
1563 consensusResult, err := store.GetConsensusResult(uint64(seq))
1568 consensusResults = append(consensusResults, consensusResult)
1570 return consensusResults