OSDN Git Service

Merge branch 'master' into key_alias
[bytom/vapor.git] / test / subprotocol_test.go
diff --git a/test/subprotocol_test.go b/test/subprotocol_test.go
new file mode 100644 (file)
index 0000000..36ca3a5
--- /dev/null
@@ -0,0 +1,235 @@
+package test
+
+import (
+       "os"
+       "testing"
+
+       "github.com/bytom/vapor/application/mov"
+       movDatabase "github.com/bytom/vapor/application/mov/database"
+       "github.com/bytom/vapor/database"
+       dbm "github.com/bytom/vapor/database/leveldb"
+       "github.com/bytom/vapor/protocol"
+       "github.com/bytom/vapor/protocol/bc"
+       "github.com/bytom/vapor/protocol/bc/types"
+       "github.com/bytom/vapor/protocol/state"
+       "github.com/bytom/vapor/testutil"
+)
+
+type chainStatus struct {
+       blockHeight uint64
+       blockHash   bc.Hash
+}
+
+type chainBlock struct {
+       block       *types.Block
+       inMainChain bool
+}
+
+var blocks = map[uint64][]*types.Block{
+       0: {
+               {
+                       BlockHeader: types.BlockHeader{
+                               Height:            0,
+                               Timestamp:         1585814309,
+                               PreviousBlockHash: bc.Hash{},
+                       },
+               },
+       },
+       1: {
+               // prev block is [0][0]
+               {
+                       BlockHeader: types.BlockHeader{
+                               Height:            1,
+                               Timestamp:         1585814310,
+                               PreviousBlockHash: testutil.MustDecodeHash("2e5406c82fe34f6ee44fe694b05ffc8fb5918a026415b086df03fb03760b42a9"),
+                       },
+               },
+               // prev block is [0][0]
+               {
+                       BlockHeader: types.BlockHeader{
+                               Height:            1,
+                               Timestamp:         1585814311,
+                               PreviousBlockHash: testutil.MustDecodeHash("2e5406c82fe34f6ee44fe694b05ffc8fb5918a026415b086df03fb03760b42a9"),
+                       },
+               },
+       },
+       2: {
+               // prev block is [1][0]
+               {
+                       BlockHeader: types.BlockHeader{
+                               Height:            2,
+                               Timestamp:         1585814320,
+                               PreviousBlockHash: testutil.MustDecodeHash("5bc198f4c0198e7e8b52173a82836cfd3f124d88bf052f53390948d845bf6fe0"),
+                       },
+               },
+       },
+}
+
+func TestSyncProtocolStatus(t *testing.T) {
+       cases := []struct {
+               desc            string
+               savedBlocks     []*chainBlock
+               startHeight     uint64
+               startHash       *bc.Hash
+               wantChainStatus *chainStatus
+       }{
+               {
+                       desc: "start height from 0, mov is not init",
+                       savedBlocks: []*chainBlock{
+                               {
+                                       block:       blocks[0][0],
+                                       inMainChain: true,
+                               },
+                               {
+                                       block:       blocks[1][0],
+                                       inMainChain: true,
+                               },
+                               {
+                                       block:       blocks[2][0],
+                                       inMainChain: true,
+                               },
+                       },
+                       startHeight: 0,
+                       wantChainStatus: &chainStatus{
+                               blockHeight: 2,
+                               blockHash:   blocks[2][0].Hash(),
+                       },
+               },
+               {
+                       desc: "start height from 1, mov is not init",
+                       savedBlocks: []*chainBlock{
+                               {
+                                       block:       blocks[0][0],
+                                       inMainChain: true,
+                               },
+                               {
+                                       block:       blocks[1][0],
+                                       inMainChain: true,
+                               },
+                               {
+                                       block:       blocks[2][0],
+                                       inMainChain: true,
+                               },
+                       },
+                       startHeight: 1,
+                       wantChainStatus: &chainStatus{
+                               blockHeight: 2,
+                               blockHash:   blocks[2][0].Hash(),
+                       },
+               },
+               {
+                       desc: "start height from 1, state of mov is not sync completed",
+                       savedBlocks: []*chainBlock{
+                               {
+                                       block:       blocks[0][0],
+                                       inMainChain: true,
+                               },
+                               {
+                                       block:       blocks[1][0],
+                                       inMainChain: true,
+                               },
+                               {
+                                       block:       blocks[2][0],
+                                       inMainChain: true,
+                               },
+                       },
+                       startHeight: 1,
+                       startHash:   hashPtr(blocks[1][0].Hash()),
+                       wantChainStatus: &chainStatus{
+                               blockHeight: 2,
+                               blockHash:   blocks[2][0].Hash(),
+                       },
+               },
+               {
+                       desc: "chain status of mov is forked",
+                       savedBlocks: []*chainBlock{
+                               {
+                                       block:       blocks[0][0],
+                                       inMainChain: true,
+                               },
+                               {
+                                       block:       blocks[1][0],
+                                       inMainChain: true,
+                               },
+                               {
+                                       block:       blocks[1][1],
+                                       inMainChain: false,
+                               },
+                               {
+                                       block:       blocks[2][0],
+                                       inMainChain: true,
+                               },
+                       },
+                       startHeight: 1,
+                       startHash:   hashPtr(blocks[1][1].Hash()),
+                       wantChainStatus: &chainStatus{
+                               blockHeight: 2,
+                               blockHash:   blocks[2][0].Hash(),
+                       },
+               },
+       }
+
+       defer os.RemoveAll("temp")
+
+       for i, c := range cases {
+               chainDB := dbm.NewDB("core", "leveldb", "temp")
+               store := database.NewStore(chainDB)
+               if err := initStore(store, c.savedBlocks); err != nil {
+                       t.Fatal(err)
+               }
+
+               movDB := dbm.NewDB("mov", "leveldb", "temp")
+               movCore := mov.NewCoreWithDB(movDatabase.NewLevelDBMovStore(movDB), c.startHeight)
+               if c.startHash != nil {
+                       if err := movCore.InitChainStatus(c.startHash); err != nil {
+                               t.Fatal(err)
+                       }
+               }
+
+               _, err := protocol.NewChain(store, nil, []protocol.SubProtocol{movCore}, nil)
+               if err != nil {
+                       t.Fatal(err)
+               }
+
+               gotHeight, gotHash, err := movCore.ChainStatus()
+               if err != nil {
+                       t.Fatal(err)
+               }
+
+               if gotHeight != c.wantChainStatus.blockHeight || *gotHash != c.wantChainStatus.blockHash {
+                       t.Logf("#%d(%s): got chain status of sub protocol is not equals want chain status", i, c.desc)
+               }
+
+               movDB.Close()
+               chainDB.Close()
+               os.RemoveAll("temp")
+       }
+}
+
+func initStore(store *database.Store, savedBlocks []*chainBlock) error {
+       var mainBlockHeaders []*types.BlockHeader
+       for _, block := range savedBlocks {
+               if err := store.SaveBlock(block.block, bc.NewTransactionStatus()); err != nil {
+                       return err
+               }
+
+               if block.inMainChain {
+                       mainBlockHeaders = append(mainBlockHeaders, &block.block.BlockHeader)
+               }
+
+               last := len(mainBlockHeaders) - 1
+               if err := store.SaveChainStatus(mainBlockHeaders[last], mainBlockHeaders[last], mainBlockHeaders, state.NewUtxoViewpoint(), nil); err != nil {
+                       return err
+               }
+       }
+       return nil
+}
+
+func hashPtr(hash bc.Hash) *bc.Hash {
+       return &hash
+}
+
+func TestBlockHash(t *testing.T) {
+       blockHash := blocks[1][0].Hash()
+       t.Log(blockHash.String())
+}