"os"
"testing"
- "github.com/vapor/config"
dbm "github.com/vapor/database/leveldb"
"github.com/vapor/database/storage"
"github.com/vapor/protocol"
"github.com/vapor/testutil"
)
-func TestLoadBlockIndex(t *testing.T) {
- config.CommonConfig = config.DefaultConfig()
- testDB := dbm.NewDB("testdb", "leveldb", "temp")
- store := NewStore(testDB)
- defer func() {
- testDB.Close()
- os.RemoveAll("temp")
- }()
-
- block := config.GenesisBlock()
- txStatus := bc.NewTransactionStatus()
-
- if err := store.SaveBlock(block, txStatus); err != nil {
- t.Fatal(err)
- }
-
- for block.Height <= 128 {
- preHash := block.Hash()
- block.PreviousBlockHash = preHash
- block.Height++
- if err := store.SaveBlock(block, txStatus); err != nil {
- t.Fatal(err)
- }
-
- if block.Height%32 != 0 {
- continue
- }
-
- for i := uint64(0); i < block.Height/32; i++ {
- block.Version++
- if err := store.SaveBlock(block, txStatus); err != nil {
- t.Fatal(err)
- }
- }
- }
-
- if _, err := store.LoadBlockIndex(128); err != nil {
- t.Fatal(err)
- }
-}
-
-func TestLoadBlockIndexBestHeight(t *testing.T) {
- cases := []struct {
- blockBestHeight uint64
- stateBestHeight uint64
- }{
- {
- blockBestHeight: 100,
- stateBestHeight: 90,
- },
- {
- blockBestHeight: 100,
- stateBestHeight: 0,
- },
- {
- blockBestHeight: 100,
- stateBestHeight: 100,
- },
- }
-
- testDB := dbm.NewDB("testdb", "leveldb", "temp")
- defer func() {
- testDB.Close()
- os.RemoveAll("temp")
- }()
- store := NewStore(testDB)
- var savedBlocks []types.Block
-
- for _, c := range cases {
- block := config.GenesisBlock()
- txStatus := bc.NewTransactionStatus()
-
- for i := uint64(0); i < c.blockBestHeight; i++ {
- if err := store.SaveBlock(block, txStatus); err != nil {
- t.Fatal(err)
- }
-
- savedBlocks = append(savedBlocks, *block)
- block.PreviousBlockHash = block.Hash()
- block.Height++
- }
-
- index, err := store.LoadBlockIndex(c.stateBestHeight)
- if err != nil {
- t.Fatal(err)
- }
-
- for _, block := range savedBlocks {
- blockHash := block.Hash()
- if block.Height <= c.stateBestHeight != index.BlockExist(&blockHash) {
- t.Errorf("Error in load block index")
- }
- }
- }
-}
-
-func TestLoadBlockIndexEquals(t *testing.T) {
- testDB := dbm.NewDB("testdb", "leveldb", "temp")
- store := NewStore(testDB)
- defer func() {
- testDB.Close()
- os.RemoveAll("temp")
- }()
-
- block := config.GenesisBlock()
- txStatus := bc.NewTransactionStatus()
- expectBlockIndex := state.NewBlockIndex()
- var parent *state.BlockNode
-
- for block.Height <= 100 {
- if err := store.SaveBlock(block, txStatus); err != nil {
- t.Fatal(err)
- }
-
- if block.Height != 0 {
- parent = expectBlockIndex.GetNode(&block.PreviousBlockHash)
- }
-
- node, err := state.NewBlockNode(&block.BlockHeader, parent)
- if err != nil {
- t.Fatal(err)
- }
-
- expectBlockIndex.AddNode(node)
- block.PreviousBlockHash = block.Hash()
- block.Height++
- }
-
- index, err := store.LoadBlockIndex(100)
- if err != nil {
- t.Fatal(err)
- }
-
- if !testutil.DeepEqual(expectBlockIndex, index) {
- t.Errorf("got block index:%v, expect block index:%v", index, expectBlockIndex)
- }
-}
func TestSaveChainStatus(t *testing.T) {
testDB := dbm.NewDB("testdb", "leveldb", "temp")
defer func() {
store := NewStore(testDB)
- node := &state.BlockNode{Height: 100, Hash: bc.Hash{V0: 0, V1: 1, V2: 2, V3: 3}}
+ blockHeader := &types.BlockHeader{Height: 100}
+ blockHash := blockHeader.Hash() //Hash: bc.Hash{V0: 0, V1: 1, V2: 2, V3: 3}
view := &state.UtxoViewpoint{
Entries: map[bc.Hash]*storage.UtxoEntry{
- bc.Hash{V0: 1, V1: 2, V2: 3, V3: 4}: &storage.UtxoEntry{IsCoinBase: false, BlockHeight: 100, Spent: false},
- bc.Hash{V0: 1, V1: 2, V2: 3, V3: 4}: &storage.UtxoEntry{IsCoinBase: true, BlockHeight: 100, Spent: true},
- bc.Hash{V0: 1, V1: 1, V2: 3, V3: 4}: &storage.UtxoEntry{IsCoinBase: false, BlockHeight: 100, Spent: true},
+ bc.Hash{V0: 1, V1: 2, V2: 3, V3: 4}: &storage.UtxoEntry{Type: storage.NormalUTXOType, BlockHeight: 100, Spent: false},
+ bc.Hash{V0: 1, V1: 2, V2: 3, V3: 4}: &storage.UtxoEntry{Type: storage.CoinbaseUTXOType, BlockHeight: 100, Spent: true},
+ bc.Hash{V0: 1, V1: 1, V2: 3, V3: 4}: &storage.UtxoEntry{Type: storage.NormalUTXOType, BlockHeight: 100, Spent: true},
+ bc.Hash{V0: 1, V1: 1, V2: 3, V3: 5}: &storage.UtxoEntry{Type: storage.CrosschainUTXOType, BlockHeight: 100, Spent: false},
+ bc.Hash{V0: 1, V1: 1, V2: 3, V3: 6}: &storage.UtxoEntry{Type: storage.CrosschainUTXOType, BlockHeight: 100, Spent: true},
+ bc.Hash{V0: 1, V1: 3, V2: 3, V3: 7}: &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 100, Spent: false},
+ bc.Hash{V0: 1, V1: 3, V2: 3, V3: 7}: &storage.UtxoEntry{Type: storage.VoteUTXOType, BlockHeight: 100, Spent: true},
},
}
- if err := store.SaveChainStatus(node, node, view, map[uint64]*state.VoteResult{}); err != nil {
+ if err := store.SaveChainStatus(blockHeader, blockHeader, []*types.BlockHeader{blockHeader}, view, []*state.ConsensusResult{}); err != nil {
t.Fatal(err)
}
- expectStatus := &protocol.BlockStoreState{Height: node.Height, Hash: &node.Hash, IrreversibleHeight: node.Height, IrreversibleHash: &node.Hash}
+ expectStatus := &protocol.BlockStoreState{Height: blockHeader.Height, Hash: &blockHash, IrreversibleHeight: blockHeader.Height, IrreversibleHash: &blockHash}
if !testutil.DeepEqual(store.GetStoreStatus(), expectStatus) {
t.Errorf("got block status:%v, expect block status:%v", store.GetStoreStatus(), expectStatus)
}
for hash, utxo := range view.Entries {
- if utxo.Spent && !utxo.IsCoinBase {
+ if (utxo.Type == storage.NormalUTXOType) && utxo.Spent {
+ continue
+ }
+ if (utxo.Type == storage.CrosschainUTXOType) && (!utxo.Spent) {
+ continue
+ }
+ if (utxo.Type == storage.VoteUTXOType) && (utxo.Spent) {
continue
}
}()
store := NewStore(testDB)
-
- block := config.GenesisBlock()
+ block := mockGenesisBlock()
status := &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{{StatusFail: true}}}
if err := store.SaveBlock(block, status); err != nil {
t.Fatal(err)
t.Errorf("got status:%v, expect status:%v", gotStatus, status)
}
- data := store.db.Get(calcBlockHeaderKey(block.Height, &blockHash))
+ data := store.db.Get(calcBlockHeaderKey(&blockHash))
gotBlockHeader := types.BlockHeader{}
if err := gotBlockHeader.UnmarshalText(data); err != nil {
t.Fatal(err)
t.Errorf("got block header:%v, expect block header:%v", gotBlockHeader, block.BlockHeader)
}
}
+
+func mockGenesisBlock() *types.Block {
+ txData := types.TxData{
+ Version: 1,
+ Inputs: []*types.TxInput{
+ types.NewCoinbaseInput([]byte("Information is power. -- Jan/11/2013. Computing is power. -- Apr/24/2018.")),
+ },
+ Outputs: []*types.TxOutput{
+ types.NewVoteOutput(bc.AssetID{V0: 1}, uint64(10000), []byte{0x51}, []byte{0x51}),
+ },
+ }
+ tx := types.NewTx(txData)
+ txStatus := bc.NewTransactionStatus()
+ txStatus.SetStatus(0, false)
+ txStatusHash, _ := types.TxStatusMerkleRoot(txStatus.VerifyStatus)
+ merkleRoot, _ := types.TxMerkleRoot([]*bc.Tx{tx.Tx})
+ block := &types.Block{
+ BlockHeader: types.BlockHeader{
+ Version: 1,
+ Height: 0,
+ Timestamp: 1528945000,
+ BlockCommitment: types.BlockCommitment{
+ TransactionsMerkleRoot: merkleRoot,
+ TransactionStatusHash: txStatusHash,
+ },
+ },
+ Transactions: []*types.Tx{tx},
+ }
+ return block
+}