7 "github.com/vapor/consensus"
8 dbm "github.com/vapor/database/leveldb"
9 "github.com/vapor/database/storage"
10 "github.com/vapor/protocol"
11 "github.com/vapor/protocol/bc"
12 "github.com/vapor/protocol/bc/types"
13 "github.com/vapor/protocol/state"
14 "github.com/vapor/testutil"
17 func TestSaveChainStatus(t *testing.T) {
18 testDB := dbm.NewDB("testdb", "leveldb", "temp")
24 store := NewStore(testDB)
26 blockHeader := &types.BlockHeader{Height: 100}
27 blockHash := blockHeader.Hash() //Hash: bc.Hash{V0: 0, V1: 1, V2: 2, V3: 3}
28 view := &state.UtxoViewpoint{
29 Entries: map[bc.Hash]*storage.UtxoEntry{
30 bc.Hash{V0: 1, V1: 2, V2: 3, V3: 4}: &storage.UtxoEntry{Type: storage.NormalUTXOType, BlockHeight: 100, Spent: false},
31 bc.Hash{V0: 1, V1: 2, V2: 3, V3: 4}: &storage.UtxoEntry{Type: storage.CoinbaseUTXOType, BlockHeight: 100, Spent: true},
32 bc.Hash{V0: 1, V1: 1, V2: 3, V3: 4}: &storage.UtxoEntry{Type: storage.NormalUTXOType, BlockHeight: 100, Spent: true},
33 bc.Hash{V0: 1, V1: 1, V2: 3, V3: 5}: &storage.UtxoEntry{Type: storage.CrosschainUTXOType, BlockHeight: 100, Spent: false},
34 bc.Hash{V0: 1, V1: 1, V2: 3, V3: 6}: &storage.UtxoEntry{Type: storage.CrosschainUTXOType, BlockHeight: 100, Spent: true},
35 bc.Hash{V0: 1, V1: 3, V2: 3, V3: 7}: &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 100, Spent: false},
36 bc.Hash{V0: 1, V1: 3, V2: 3, V3: 7}: &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 100, Spent: true},
40 if err := store.SaveChainStatus(blockHeader, blockHeader, []*types.BlockHeader{blockHeader}, view, []*state.ConsensusResult{}); err != nil {
44 expectStatus := &protocol.BlockStoreState{Height: blockHeader.Height, Hash: &blockHash, IrreversibleHeight: blockHeader.Height, IrreversibleHash: &blockHash}
45 if !testutil.DeepEqual(store.GetStoreStatus(), expectStatus) {
46 t.Errorf("got block status:%v, expect block status:%v", store.GetStoreStatus(), expectStatus)
49 for hash, utxo := range view.Entries {
50 if (utxo.Type == storage.NormalUTXOType) && utxo.Spent {
53 if (utxo.Type == storage.CrosschainUTXOType) && (!utxo.Spent) {
56 if (utxo.Type == storage.VoteUTXOType) && (utxo.Spent) {
60 gotUtxo, err := store.GetUtxo(&hash)
65 if !testutil.DeepEqual(utxo, gotUtxo) {
66 t.Errorf("got utxo entry:%v, expect utxo entry:%v", gotUtxo, utxo)
71 func TestSaveBlock(t *testing.T) {
72 testDB := dbm.NewDB("testdb", "leveldb", "temp")
78 store := NewStore(testDB)
79 coinbaseTxData := &types.TxData{
81 Inputs: []*types.TxInput{
82 types.NewCoinbaseInput([]byte("Information is power. -- Jan/11/2013. Computing is power. -- Apr/24/2018.")),
84 Outputs: []*types.TxOutput{
85 types.NewVoteOutput(*consensus.BTMAssetID, uint64(10000), []byte{0x51}, []byte{0x51}),
88 coinbaseTx := types.NewTx(*coinbaseTxData)
91 txData []*types.TxData
92 txStatus *bc.TransactionStatus
93 blockHeader *types.BlockHeader
96 txStatus: &bc.TransactionStatus{
97 VerifyStatus: []*bc.TxVerifyResult{
101 blockHeader: &types.BlockHeader{
103 Height: uint64(1111),
104 Timestamp: uint64(1528945000),
108 txStatus: &bc.TransactionStatus{
109 VerifyStatus: []*bc.TxVerifyResult{
113 blockHeader: &types.BlockHeader{
115 Height: uint64(1111),
116 Timestamp: uint64(1528945000),
120 txData: []*types.TxData{
123 Inputs: []*types.TxInput{
124 types.NewSpendInput([][]byte{}, bc.NewHash([32]byte{}), *consensus.BTMAssetID, 100000000, 0, []byte{0x51}),
126 Outputs: []*types.TxOutput{
127 types.NewVoteOutput(*consensus.BTMAssetID, uint64(10000), []byte{0x51}, []byte{0x51}),
131 txStatus: &bc.TransactionStatus{
132 VerifyStatus: []*bc.TxVerifyResult{
136 blockHeader: &types.BlockHeader{
138 Height: uint64(1111),
139 Timestamp: uint64(1528945000),
143 txData: []*types.TxData{
146 Inputs: []*types.TxInput{
147 types.NewSpendInput([][]byte{}, bc.NewHash([32]byte{}), *consensus.BTMAssetID, 100000000, 0, []byte{0x51}),
149 Outputs: []*types.TxOutput{
150 types.NewVoteOutput(*consensus.BTMAssetID, uint64(88888), []byte{0x51}, []byte{0x51}),
154 txStatus: &bc.TransactionStatus{
155 VerifyStatus: []*bc.TxVerifyResult{
159 blockHeader: &types.BlockHeader{
162 Timestamp: uint64(152894500000),
167 for i, c := range cases {
168 txs := []*bc.Tx{coinbaseTx.Tx}
169 for _, tx := range c.txData {
170 t := types.NewTx(*tx)
171 txs = append(txs, t.Tx)
173 merkleRoot, _ := types.TxMerkleRoot(txs)
174 txStatusHash, _ := types.TxStatusMerkleRoot(c.txStatus.VerifyStatus)
175 block := &types.Block{
176 BlockHeader: types.BlockHeader{
177 Version: c.blockHeader.Version,
178 Height: c.blockHeader.Height,
179 Timestamp: c.blockHeader.Timestamp,
180 BlockCommitment: types.BlockCommitment{
181 TransactionsMerkleRoot: merkleRoot,
182 TransactionStatusHash: txStatusHash,
187 if err := store.SaveBlock(block, c.txStatus); err != nil {
191 blockHash := block.Hash()
192 gotBlock, err := store.GetBlock(&blockHash)
197 if !testutil.DeepEqual(gotBlock, block) {
198 t.Errorf("case %v: block mismatch: have %x, want %x", i, gotBlock, block)
201 gotStatus, err := store.GetTransactionStatus(&blockHash)
206 if !testutil.DeepEqual(gotStatus.VerifyStatus, c.txStatus.VerifyStatus) {
207 t.Errorf("case %v: VerifyStatus mismatch: have %x, want %x", i, gotStatus.VerifyStatus, c.txStatus.VerifyStatus)
210 gotBlockHeader, err := store.GetBlockHeader(&blockHash)
215 if !testutil.DeepEqual(block.BlockHeader, *gotBlockHeader) {
216 t.Errorf("got block header:%v, expect block header:%v", gotBlockHeader, block.BlockHeader)
221 func TestSaveBlockHeader(t *testing.T) {
222 testDB := dbm.NewDB("testdb", "leveldb", "temp")
228 store := NewStore(testDB)
231 blockHeader *types.BlockHeader
234 blockHeader: &types.BlockHeader{
236 Height: uint64(1111),
237 Timestamp: uint64(1528945000),
241 blockHeader: &types.BlockHeader{
244 PreviousBlockHash: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
245 Timestamp: uint64(1563186936),
246 BlockCommitment: types.BlockCommitment{
247 TransactionsMerkleRoot: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
248 TransactionStatusHash: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
250 BlockWitness: types.BlockWitness{
251 Witness: [][]byte{[]byte{0x3e, 0x94, 0x5d, 0x35}, []byte{0x3e, 0x94, 0x5d, 0x35}},
256 blockHeader: &types.BlockHeader{
258 Height: uint64(8848),
259 PreviousBlockHash: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
260 Timestamp: uint64(156318693600),
261 BlockCommitment: types.BlockCommitment{
262 TransactionsMerkleRoot: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
263 TransactionStatusHash: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
265 BlockWitness: types.BlockWitness{
267 []byte{0x3e, 0x94, 0x5d, 0x35},
268 []byte{0xdd, 0x80, 0x67, 0x29},
269 []byte{0xff, 0xff, 0xff, 0xff},
270 []byte{0x00, 0x01, 0x02, 0x03},
277 for i, c := range cases {
278 if err := store.SaveBlockHeader(c.blockHeader); err != nil {
282 blockHash := c.blockHeader.Hash()
283 gotBlockHeader, err := store.GetBlockHeader(&blockHash)
288 if !testutil.DeepEqual(gotBlockHeader, c.blockHeader) {
289 t.Errorf("case %v: block header mismatch: have %x, want %x", i, gotBlockHeader, c.blockHeader)