• R/O
  • HTTP
  • SSH
  • HTTPS

vapor: Commit

Golang implemented sidechain for Bytom


Commit MetaInfo

Revisión233b5c6cd4943c1215f93e55530061b3235bb586 (tree)
Tiempo2020-02-27 17:30:29
Autoripqhjjybj <250657661@qq.c...>
Commiteripqhjjybj

Log Message

add rollback test

Cambiar Resumen

Diferencia incremental

--- a/database/store_test.go
+++ b/database/store_test.go
@@ -167,10 +167,12 @@ func TestSaveBlock(t *testing.T) {
167167 }
168168
169169 for i, c := range cases {
170+ trans := []*types.Tx{coinbaseTx}
170171 txs := []*bc.Tx{coinbaseTx.Tx}
171172 for _, tx := range c.txData {
172173 t := types.NewTx(*tx)
173174 txs = append(txs, t.Tx)
175+ trans = append(trans, t)
174176 }
175177 merkleRoot, _ := types.TxMerkleRoot(txs)
176178 txStatusHash, _ := types.TxStatusMerkleRoot(c.txStatus.VerifyStatus)
@@ -184,6 +186,7 @@ func TestSaveBlock(t *testing.T) {
184186 TransactionStatusHash: txStatusHash,
185187 },
186188 },
189+ Transactions: trans,
187190 }
188191
189192 if err := store.SaveBlock(block, c.txStatus); err != nil {
@@ -196,8 +199,16 @@ func TestSaveBlock(t *testing.T) {
196199 t.Fatal(err)
197200 }
198201
199- if !testutil.DeepEqual(gotBlock, block) {
200- t.Errorf("case %v: block mismatch: have %x, want %x", i, gotBlock, block)
202+ for index, tx := range gotBlock.Transactions {
203+ wantTx := types.NewTx(block.Transactions[index].TxData)
204+ if tx.ID != wantTx.ID {
205+ x1, _ := tx.MarshalText()
206+ x2, _ := block.Transactions[index].MarshalText()
207+ a1 := string(x1)
208+ b1 := string(x2)
209+
210+ t.Errorf("case %d: transaction %d: block mismatch: have %s, want %s", i, index, a1, b1)
211+ }
201212 }
202213
203214 gotStatus, err := store.GetTransactionStatus(&blockHash)
--- a/database/utxo_view.go
+++ b/database/utxo_view.go
@@ -1,12 +1,12 @@
11 package database
22
33 import (
4- "github.com/golang/protobuf/proto"
54 dbm "github.com/bytom/vapor/database/leveldb"
65 "github.com/bytom/vapor/database/storage"
76 "github.com/bytom/vapor/errors"
87 "github.com/bytom/vapor/protocol/bc"
98 "github.com/bytom/vapor/protocol/state"
9+ "github.com/golang/protobuf/proto"
1010 )
1111
1212 const utxoPreFix = "UT:"
--- a/protocol/block.go
+++ b/protocol/block.go
@@ -1,6 +1,8 @@
11 package protocol
22
33 import (
4+ "fmt"
5+
46 log "github.com/sirupsen/logrus"
57
68 "github.com/bytom/vapor/errors"
@@ -223,6 +225,11 @@ func (c *Chain) Rollback(targetHeight uint64) error {
223225 }
224226
225227 startSeq := state.CalcVoteSeq(c.bestBlockHeader.Height)
228+ entries := utxoView.Entries
229+ for prevout, entry := range entries {
230+ fmt.Println("final prevout", prevout.String(), entry)
231+ }
232+
226233 if err = c.setState(targetBlockHeader, setIrrBlockHeader, nil, utxoView, []*state.ConsensusResult{consensusResult.Fork()}); err != nil {
227234 return err
228235 }
--- a/test/rollback_test.go
+++ b/test/rollback_test.go
@@ -6,7 +6,6 @@ import (
66 "testing"
77
88 "github.com/bytom/vapor/application/mov"
9- "github.com/bytom/vapor/application/mov/common"
109 movDatabase "github.com/bytom/vapor/application/mov/database"
1110 "github.com/bytom/vapor/consensus"
1211 "github.com/bytom/vapor/database"
@@ -36,7 +35,8 @@ func TestRollback(t *testing.T) {
3635 wantBestBlockHeader *types.BlockHeader
3736 wantLastIrrBlockHeader *types.BlockHeader
3837 wantBestConsensusResult *state.ConsensusResult
39- wantMovOrders []*common.Order
38+ wantUtxoViewPoint *state.UtxoViewpoint
39+ wantStoredConsensusResult []*state.ConsensusResult
4040 rollbackToTargetHeight uint64
4141 }{
4242 {
@@ -56,11 +56,10 @@ func TestRollback(t *testing.T) {
5656 wantLastIrrBlockHeader: &types.BlockHeader{
5757 Height: 0,
5858 },
59- wantMovOrders: []*common.Order{},
6059 beforeUtxoViewPoint: &state.UtxoViewpoint{
6160 Entries: map[bc.Hash]*storage.UtxoEntry{
62- testutil.MustDecodeHash("c094bdfd925b4f357a7cb373f8b9ec001181c9217fd7de8219ea1163a1bee93f"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: false},
63- testutil.MustDecodeHash("82dc360aaee03b2d42f964befdaf8ab36930e1578d14547da9bd7d23062ecf3c"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
61+ testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
62+ testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
6463 },
6564 },
6665 rollbackToTargetHeight: 0,
@@ -70,16 +69,14 @@ func TestRollback(t *testing.T) {
7069 Height: 0,
7170 },
7271 Transactions: []*types.Tx{
73- {
74- TxData: types.TxData{
75- Inputs: []*types.TxInput{
76- types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
77- },
78- Outputs: []*types.TxOutput{
79- types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
80- },
72+ types.NewTx(types.TxData{
73+ Inputs: []*types.TxInput{
74+ types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
8175 },
82- },
76+ Outputs: []*types.TxOutput{
77+ types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
78+ },
79+ }),
8380 },
8481 },
8582 {
@@ -88,16 +85,14 @@ func TestRollback(t *testing.T) {
8885 PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
8986 },
9087 Transactions: []*types.Tx{
91- {
92- TxData: types.TxData{
93- Inputs: []*types.TxInput{
94- types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 2000, 0, []byte{0, 1}),
95- },
96- Outputs: []*types.TxOutput{
97- types.NewVoteOutput(*consensus.BTMAssetID, 2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
98- },
88+ types.NewTx(types.TxData{
89+ Inputs: []*types.TxInput{
90+ types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 2000, 0, []byte{0, 1}),
91+ },
92+ Outputs: []*types.TxOutput{
93+ types.NewVoteOutput(*consensus.BTMAssetID, 2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
9994 },
100- },
95+ }),
10196 },
10297 },
10398 },
@@ -107,16 +102,14 @@ func TestRollback(t *testing.T) {
107102 Height: 0,
108103 },
109104 Transactions: []*types.Tx{
110- {
111- TxData: types.TxData{
112- Inputs: []*types.TxInput{
113- types.NewSpendInput(nil, bc.NewHash([32]byte{0, 1}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
114- },
115- Outputs: []*types.TxOutput{
116- types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
117- },
105+ types.NewTx(types.TxData{
106+ Inputs: []*types.TxInput{
107+ types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
108+ },
109+ Outputs: []*types.TxOutput{
110+ types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
118111 },
119- },
112+ }),
120113 },
121114 },
122115 },
@@ -152,6 +145,23 @@ func TestRollback(t *testing.T) {
152145 BlockHeight: 0,
153146 CoinbaseReward: map[string]uint64{},
154147 },
148+ wantUtxoViewPoint: &state.UtxoViewpoint{
149+ Entries: map[bc.Hash]*storage.UtxoEntry{
150+ testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
151+ },
152+ },
153+ wantStoredConsensusResult: []*state.ConsensusResult{
154+ {
155+ Seq: 0,
156+ NumOfVote: map[string]uint64{
157+ "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
158+ "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
159+ },
160+ BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
161+ BlockHeight: 0,
162+ CoinbaseReward: map[string]uint64{},
163+ },
164+ },
155165 },
156166 }
157167
@@ -165,25 +175,19 @@ func TestRollback(t *testing.T) {
165175
166176 mainChainBlockHeaders := []*types.BlockHeader{}
167177 for _, block := range c.beforeStoredBlocks {
168- newTrans := []*types.Tx{}
169- status := bc.NewTransactionStatus()
170- for index, tx := range block.Transactions {
171- status.SetStatus(index, false)
172- byteData, err := tx.TxData.MarshalText()
173- if err != nil {
174- t.Fatal(err)
178+ trans := block.Transactions
179+ for _, tx := range trans {
180+ for _, prevout := range tx.SpentOutputIDs {
181+ fmt.Println(prevout.String())
175182 }
176- tx.TxData.SerializedSize = uint64(len(byteData))
183+ }
177184
178- tx := &types.Tx{TxData: tx.TxData, Tx: types.MapTx(&tx.TxData)}
179- newTrans = append(newTrans, tx)
185+ status := bc.NewTransactionStatus()
186+ for index := range block.Transactions {
187+ status.SetStatus(index, false)
180188 }
181- block.Transactions = newTrans
182189 store.SaveBlock(block, status)
183190
184- hash := block.Hash()
185- block, _ := store.GetBlock(&hash)
186-
187191 mainChainBlockHeaders = append(mainChainBlockHeaders, &block.BlockHeader)
188192 }
189193
@@ -217,55 +221,35 @@ func TestRollback(t *testing.T) {
217221 t.Fatalf("wantBestConsensusResult is not right!")
218222 }
219223
220- nowBlocks := []*types.Block{}
221- for _, block := range c.beforeStoredBlocks {
222- if block.Height <= c.rollbackToTargetHeight {
223- gotBlock, err := chain.GetBlockByHeight(block.Height)
224- if err != nil {
225- t.Fatal(err)
226- }
227- nowBlocks = append(nowBlocks, gotBlock)
228- } else {
229- hash := block.Hash()
230- nowBlock, _ := store.GetBlock(&hash)
231- if nowBlock != nil {
232- t.Fatalf("this block height %d should not existed!", block.Height)
233- }
234- }
235- }
236-
237- transferBlocks := []*types.Block{}
238- fmt.Println(nowBlocks, len(nowBlocks))
239- fmt.Println(c.wantStoredBlocks, len(c.wantStoredBlocks))
240-
224+ transOldTx := []*bc.Tx{}
241225 for _, block := range c.wantStoredBlocks {
242- newTrans := []*types.Tx{}
226+ hash := block.Hash()
243227 for _, tx := range block.Transactions {
244- byteData, err := tx.TxData.MarshalText()
245- if err != nil {
246- t.Fatal(err)
247- }
248- tx.TxData.SerializedSize = uint64(len(byteData))
228+ transOldTx = append(transOldTx, tx.Tx)
229+ }
230+ gotBlock, err := store.GetBlock(&hash)
231+ if err != nil {
232+ t.Fatal(err)
233+ }
249234
250- tx := &types.Tx{TxData: tx.TxData, Tx: types.MapTx(&tx.TxData)}
251- newTrans = append(newTrans, tx)
235+ if !testutil.DeepEqual(block.BlockHeader, gotBlock.BlockHeader) {
236+ t.Fatalf("this block height %d should existed!", block.Height)
252237 }
253- block.Transactions = newTrans
238+ }
254239
255- transferBlocks = append(transferBlocks, block)
240+ nowUtxoViewPoint := state.NewUtxoViewpoint()
241+ if err = store.GetTransactionsUtxo(nowUtxoViewPoint, transOldTx); err != nil {
242+ t.Fatal(err)
256243 }
257244
258- block1 := nowBlocks[0]
259- block2 := transferBlocks[0]
260- fmt.Println(block1)
261- fmt.Println(block2)
262- if !testutil.DeepEqual(nowBlocks, transferBlocks) {
263- t.Fatalf("blocks is not same")
245+ if !testutil.DeepEqual(nowUtxoViewPoint, c.wantUtxoViewPoint) {
246+ t.Fatal(err)
264247 }
265248
266249 blockDB.Close()
267250 os.RemoveAll("block_db")
268251 movDB.Close()
269252 os.RemoveAll("mov_db")
253+
270254 }
271255 }
--- /dev/null
+++ b/test/rollback_test_bak_a.go
@@ -0,0 +1,363 @@
1+package test
2+
3+import (
4+ "fmt"
5+ "os"
6+ "testing"
7+
8+ "github.com/stretchr/testify/require"
9+
10+ "github.com/bytom/vapor/application/mov"
11+ movDatabase "github.com/bytom/vapor/application/mov/database"
12+ "github.com/bytom/vapor/consensus"
13+ "github.com/bytom/vapor/database"
14+ dbm "github.com/bytom/vapor/database/leveldb"
15+ "github.com/bytom/vapor/database/storage"
16+ "github.com/bytom/vapor/protocol"
17+ "github.com/bytom/vapor/protocol/bc"
18+ "github.com/bytom/vapor/protocol/bc/types"
19+ "github.com/bytom/vapor/protocol/state"
20+ "github.com/bytom/vapor/testutil"
21+)
22+
23+func compareDBSame(t *testing.T, dbA dbm.DB, dbB dbm.DB) bool {
24+ iterA := dbA.Iterator()
25+ iterB := dbB.Iterator()
26+
27+ for iterA.Next() && iterB.Next() {
28+ require.Equal(t, iterA.Key(), iterB.Key())
29+ require.Equal(t, iterA.Value(), iterB.Value())
30+ }
31+
32+ if iterA.Next() || iterB.Next() {
33+ t.Fatalf("why iterator is not finished")
34+ }
35+
36+ return true
37+}
38+
39+func ATestSmall(t *testing.T) {
40+ wantStoredBlocks := []*types.Block{
41+ {
42+ BlockHeader: types.BlockHeader{
43+ Height: 0,
44+ },
45+ Transactions: []*types.Tx{
46+ types.NewTx(types.TxData{
47+ Inputs: []*types.TxInput{
48+ types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
49+ },
50+ Outputs: []*types.TxOutput{
51+ types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
52+ },
53+ }),
54+ },
55+ },
56+ {
57+ BlockHeader: types.BlockHeader{
58+ Height: 1,
59+ },
60+ Transactions: []*types.Tx{
61+ types.NewTx(types.TxData{
62+ Inputs: []*types.TxInput{
63+ types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
64+ },
65+ Outputs: []*types.TxOutput{
66+ types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
67+ },
68+ }),
69+ },
70+ },
71+ }
72+
73+ dbA := dbm.NewDB("dba", "leveldb", "dba")
74+ storeA := database.NewStore(dbA)
75+ status := bc.NewTransactionStatus()
76+ status.SetStatus(0, false)
77+
78+ storeA.SaveBlock(wantStoredBlocks[0], status)
79+
80+ //hash := wantStoredBlocks[0].Hash()
81+ // block, _ := storeA.GetBlock(&hash)
82+ // fmt.Println("!!!!!!!!!!", block)
83+ // fmt.Println("????????", wantStoredBlocks[0])
84+
85+ //fmt.Println("amazing!")
86+
87+ dbB := dbm.NewDB("dbb", "leveldb", "dbb")
88+ storeB := database.NewStore(dbB)
89+ storeB.SaveBlock(wantStoredBlocks[0], status)
90+ storeB.SaveBlock(wantStoredBlocks[1], status)
91+
92+ storeB.DeleteBlock(wantStoredBlocks[1])
93+
94+ compareDBSame(t, dbA, dbB)
95+ dbA.Close()
96+ dbB.Close()
97+ os.RemoveAll("dba")
98+ os.RemoveAll("dbb")
99+}
100+
101+func ATestRollback(t *testing.T) {
102+ // 1-->0
103+ // 2-->0
104+ // 2-->1
105+ // 1200 个区块回滚 , 1201--> 1199 , 1201-->1200, 1200->1199
106+ cases := []struct {
107+ desc string
108+ movStartHeight uint64
109+ beforeBestBlockHeader *types.BlockHeader
110+ beforeLastIrrBlockHeader *types.BlockHeader
111+ beforeUtxoViewPoint *state.UtxoViewpoint
112+ beforeStoredBlocks []*types.Block
113+ beforeStoredConsensusResult []*state.ConsensusResult
114+ wantStoredBlocks []*types.Block
115+ wantBestBlockHeader *types.BlockHeader
116+ wantLastIrrBlockHeader *types.BlockHeader
117+ wantBestConsensusResult *state.ConsensusResult
118+ wantUtxoViewPoint *state.UtxoViewpoint
119+ wantStoredConsensusResult []*state.ConsensusResult
120+ rollbackToTargetHeight uint64
121+ }{
122+ {
123+ desc: "rollback from height 1 to 0",
124+ movStartHeight: 10,
125+ beforeBestBlockHeader: &types.BlockHeader{
126+ Height: 1,
127+ PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
128+ },
129+ wantBestBlockHeader: &types.BlockHeader{
130+ Height: 0,
131+ },
132+ beforeLastIrrBlockHeader: &types.BlockHeader{
133+ Height: 1,
134+ PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
135+ },
136+ wantLastIrrBlockHeader: &types.BlockHeader{
137+ Height: 0,
138+ },
139+ beforeUtxoViewPoint: &state.UtxoViewpoint{
140+ Entries: map[bc.Hash]*storage.UtxoEntry{
141+ testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: true},
142+ testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
143+ },
144+ },
145+ rollbackToTargetHeight: 0,
146+ beforeStoredBlocks: []*types.Block{
147+ {
148+ BlockHeader: types.BlockHeader{
149+ Height: 0,
150+ },
151+ Transactions: []*types.Tx{
152+ types.NewTx(types.TxData{
153+ Inputs: []*types.TxInput{
154+ types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
155+ },
156+ Outputs: []*types.TxOutput{
157+ types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
158+ },
159+ }),
160+ },
161+ },
162+ {
163+ BlockHeader: types.BlockHeader{
164+ Height: 1,
165+ PreviousBlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
166+ },
167+ Transactions: []*types.Tx{
168+ types.NewTx(types.TxData{
169+ Inputs: []*types.TxInput{
170+ types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 2000, 0, []byte{0, 1}),
171+ },
172+ Outputs: []*types.TxOutput{
173+ types.NewVoteOutput(*consensus.BTMAssetID, 2000, []byte{0, 1}, testutil.MustDecodeHexString("b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9")),
174+ },
175+ }),
176+ },
177+ },
178+ },
179+ wantStoredBlocks: []*types.Block{
180+ {
181+ BlockHeader: types.BlockHeader{
182+ Height: 0,
183+ },
184+ Transactions: []*types.Tx{
185+ types.NewTx(types.TxData{
186+ Inputs: []*types.TxInput{
187+ types.NewSpendInput(nil, bc.NewHash([32]byte{8}), *consensus.BTMAssetID, 1000, 0, []byte{0, 1}),
188+ },
189+ Outputs: []*types.TxOutput{
190+ types.NewVoteOutput(*consensus.BTMAssetID, 1000, []byte{0, 1}, testutil.MustDecodeHexString("36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67")),
191+ },
192+ }),
193+ },
194+ },
195+ },
196+ beforeStoredConsensusResult: []*state.ConsensusResult{
197+ {
198+ Seq: 1,
199+ NumOfVote: map[string]uint64{
200+ "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100002000,
201+ "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
202+ },
203+ BlockHash: testutil.MustDecodeHash("52463075c66259098f2a1fa711288cf3b866d7c57b4a7a78cd22a1dcd69a0514"),
204+ BlockHeight: 1,
205+ CoinbaseReward: map[string]uint64{"0001": consensus.BlockSubsidy(1) + 10000000000},
206+ },
207+ {
208+ Seq: 0,
209+ NumOfVote: map[string]uint64{
210+ "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
211+ "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
212+ },
213+ BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
214+ BlockHeight: 0,
215+ CoinbaseReward: map[string]uint64{},
216+ },
217+ },
218+ wantBestConsensusResult: &state.ConsensusResult{
219+ Seq: 0,
220+ NumOfVote: map[string]uint64{
221+ "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
222+ "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
223+ },
224+ BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
225+ BlockHeight: 0,
226+ CoinbaseReward: map[string]uint64{},
227+ },
228+ wantUtxoViewPoint: &state.UtxoViewpoint{
229+ Entries: map[bc.Hash]*storage.UtxoEntry{
230+ testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 1, Spent: false},
231+ testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba"): &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 0, Spent: true},
232+ },
233+ },
234+ wantStoredConsensusResult: []*state.ConsensusResult{
235+ {
236+ Seq: 0,
237+ NumOfVote: map[string]uint64{
238+ "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9": 100000000,
239+ "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67": 100002000,
240+ },
241+ BlockHash: testutil.MustDecodeHash("39dee75363127a2857f554d2ad2706eb876407a2e09fbe0338683ca4ad4c2f90"),
242+ BlockHeight: 0,
243+ CoinbaseReward: map[string]uint64{},
244+ },
245+ },
246+ },
247+ }
248+
249+ for _, c := range cases {
250+ movDB := dbm.NewDB("mov_db", "leveldb", "mov_db")
251+ movStore := movDatabase.NewLevelDBMovStore(movDB)
252+
253+ movCore := mov.NewMovCoreWithDB(movStore, c.movStartHeight)
254+ blockDB := dbm.NewDB("block_db", "leveldb", "block_db")
255+ store := database.NewStore(blockDB)
256+
257+ compareDB := dbm.NewDB("compare_block_db", "leveldb", "compare_block_db")
258+ compareStore := database.NewStore(compareDB)
259+
260+ mainChainBlockHeaders := []*types.BlockHeader{}
261+ for _, block := range c.beforeStoredBlocks {
262+ trans := block.Transactions
263+ for _, tx := range trans {
264+ for _, prevout := range tx.SpentOutputIDs {
265+ fmt.Println(prevout.String())
266+ }
267+ }
268+
269+ status := bc.NewTransactionStatus()
270+ for index := range block.Transactions {
271+ status.SetStatus(index, false)
272+ }
273+ store.SaveBlock(block, status)
274+
275+ mainChainBlockHeaders = append(mainChainBlockHeaders, &block.BlockHeader)
276+ }
277+
278+ wantMainChainBlockHeaders := []*types.BlockHeader{}
279+ for _, block := range c.wantStoredBlocks {
280+ status := bc.NewTransactionStatus()
281+ for index := range block.Transactions {
282+ status.SetStatus(index, false)
283+ }
284+ compareStore.SaveBlock(block, status)
285+
286+ wantMainChainBlockHeaders = append(wantMainChainBlockHeaders, &block.BlockHeader)
287+ }
288+
289+ if err := store.SaveChainStatus(c.beforeBestBlockHeader, c.beforeLastIrrBlockHeader, mainChainBlockHeaders, c.beforeUtxoViewPoint, c.beforeStoredConsensusResult); err != nil {
290+ t.Fatal(err)
291+ }
292+
293+ if err := compareStore.SaveChainStatus(c.wantBestBlockHeader, c.wantLastIrrBlockHeader, wantMainChainBlockHeaders, c.wantUtxoViewPoint, c.wantStoredConsensusResult); err != nil {
294+ t.Fatal(err)
295+ }
296+
297+ chain, err := protocol.NewChain(store, nil, []protocol.Protocoler{movCore}, nil)
298+ if err != nil {
299+ t.Fatal(err)
300+ }
301+
302+ if err := chain.Rollback(c.rollbackToTargetHeight); err != nil {
303+ t.Fatal(err)
304+ }
305+
306+ hash := testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba")
307+ utxo, err := store.GetUtxo(&hash)
308+ fmt.Println("store e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba", utxo, err)
309+
310+ hash = testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06")
311+ utxo, err = store.GetUtxo(&hash)
312+ fmt.Println("store 51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06", utxo, err)
313+
314+ hash = testutil.MustDecodeHash("e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba")
315+ utxo, err = compareStore.GetUtxo(&hash)
316+ fmt.Println("compareStore e2370262a129b90174195a76c298d872a56af042eae17657e154bcc46d41b3ba", utxo, err)
317+
318+ hash = testutil.MustDecodeHash("51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06")
319+ utxo, err = compareStore.GetUtxo(&hash)
320+ fmt.Println("compareStore 51f538be366172bed5359a016dce26b952024c9607caf6af609ad723982c2e06", utxo, err)
321+
322+ if !testutil.DeepEqual(chain.LastIrreversibleHeader(), c.wantLastIrrBlockHeader) {
323+ t.Fatalf("lastIrrBlockHeader is not right!")
324+ }
325+
326+ if !testutil.DeepEqual(chain.BestBlockHeader(), c.wantBestBlockHeader) {
327+ t.Fatalf("wantBestBlockHeader is not right!")
328+ }
329+
330+ nowConsensusResult, err := chain.GetConsensusResultByHash(chain.BestBlockHash())
331+ if err != nil {
332+ t.Fatal(err)
333+ }
334+
335+ if !testutil.DeepEqual(nowConsensusResult, c.wantBestConsensusResult) {
336+ t.Fatalf("wantBestConsensusResult is not right!")
337+ }
338+
339+ if !compareDBSame(t, blockDB, compareDB) {
340+ t.Fatalf("the db is not same")
341+ }
342+
343+ for _, block := range c.wantStoredBlocks {
344+ hash := block.Hash()
345+ gotBlock, err := store.GetBlock(&hash)
346+ if err != nil {
347+ t.Fatal(err)
348+ }
349+
350+ if !testutil.DeepEqual(block.BlockHeader, gotBlock.BlockHeader) {
351+ t.Fatalf("this block height %d should existed!", block.Height)
352+ }
353+ }
354+
355+ blockDB.Close()
356+ os.RemoveAll("block_db")
357+ movDB.Close()
358+ os.RemoveAll("mov_db")
359+
360+ compareDB.Close()
361+ os.RemoveAll("compare_block_db")
362+ }
363+}
Show on old repository browser