github.com/turingchain2020/turingchain@v1.1.21/blockchain/reduce_test.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package blockchain
     6  
     7  import (
     8  	"fmt"
     9  	"io/ioutil"
    10  	"os"
    11  	"testing"
    12  
    13  	"github.com/turingchain2020/turingchain/types"
    14  	"github.com/turingchain2020/turingchain/util"
    15  
    16  	dbm "github.com/turingchain2020/turingchain/common/db"
    17  	"github.com/stretchr/testify/assert"
    18  )
    19  
    20  func TestInitReduceLocaldb(t *testing.T) {
    21  
    22  	dir, err := ioutil.TempDir("", "example")
    23  	assert.Nil(t, err)
    24  	defer os.RemoveAll(dir) // clean up
    25  	os.RemoveAll(dir)       //删除已存在目录
    26  
    27  	blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100)
    28  
    29  	chain := InitEnv()
    30  	//cfg := chain.client.GetConfig()
    31  	blockStore := NewBlockStore(chain, blockStoreDB, chain.client)
    32  	assert.NotNil(t, blockStore)
    33  	chain.blockStore = blockStore
    34  
    35  	// for test initReduceLocaldb
    36  	flagHeight := int64(0)
    37  	endHeight := int64(80000)
    38  	flag := int64(0)
    39  	if flag == 0 {
    40  		if endHeight > flagHeight {
    41  			chain.walkOver(flagHeight, endHeight, false,
    42  				func(batch dbm.Batch, height int64) {
    43  					batch.Set([]byte(fmt.Sprintf("key-%d", height)), []byte(fmt.Sprintf("value-%d", height)))
    44  				},
    45  				func(batch dbm.Batch, height int64) {
    46  					batch.Set(types.ReduceLocaldbHeight, types.Encode(&types.Int64{Data: height}))
    47  				})
    48  			// CompactRange执行将会阻塞仅仅做一次压缩
    49  			chainlog.Debug("reduceLocaldb start compact db")
    50  			blockStore.db.CompactRange(nil, nil)
    51  			chainlog.Debug("reduceLocaldb end compact db")
    52  		}
    53  		blockStore.saveReduceLocaldbFlag()
    54  	}
    55  
    56  	flag, err = blockStore.loadFlag(types.FlagReduceLocaldb)
    57  	assert.NoError(t, err)
    58  	assert.Equal(t, flag, int64(1))
    59  
    60  	flagHeight, err = blockStore.loadFlag(types.ReduceLocaldbHeight)
    61  	assert.NoError(t, err)
    62  	assert.Equal(t, flagHeight, endHeight)
    63  
    64  }
    65  
    66  func TestInitReduceLocaldb1(t *testing.T) {
    67  
    68  	dir, err := ioutil.TempDir("", "example")
    69  	assert.Nil(t, err)
    70  	defer os.RemoveAll(dir) // clean up
    71  	os.RemoveAll(dir)       //删除已存在目录
    72  
    73  	blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100)
    74  
    75  	chain := InitEnv()
    76  	//cfg := chain.client.GetConfig()
    77  	blockStore := NewBlockStore(chain, blockStoreDB, chain.client)
    78  	assert.NotNil(t, blockStore)
    79  	chain.blockStore = blockStore
    80  
    81  	// for test initReduceLocaldb
    82  	flagHeight := int64(0)
    83  	endHeight := int64(80000)
    84  	flag := int64(0)
    85  	if flag == 0 {
    86  		defer func() {
    87  			if r := recover(); r != nil {
    88  				flag, err = blockStore.loadFlag(types.FlagReduceLocaldb)
    89  				assert.NoError(t, err)
    90  				assert.Equal(t, flag, int64(0))
    91  
    92  				flagHeight, err = blockStore.loadFlag(types.ReduceLocaldbHeight)
    93  				assert.NoError(t, err)
    94  				assert.NotEqual(t, flagHeight, endHeight)
    95  				return
    96  			}
    97  		}()
    98  
    99  		if endHeight > flagHeight {
   100  			chain.walkOver(flagHeight, endHeight, false,
   101  				func(batch dbm.Batch, height int64) {
   102  					batch.Set([]byte(fmt.Sprintf("key-%d", height)), []byte(fmt.Sprintf("value-%d", height)))
   103  				},
   104  				func(batch dbm.Batch, height int64) {
   105  					if height == endHeight {
   106  						panic("for test")
   107  					}
   108  					batch.Set(types.ReduceLocaldbHeight, types.Encode(&types.Int64{Data: height}))
   109  				})
   110  			// CompactRange执行将会阻塞仅仅做一次压缩
   111  			chainlog.Debug("reduceLocaldb start compact db")
   112  			blockStore.db.CompactRange(nil, nil)
   113  			chainlog.Debug("reduceLocaldb end compact db")
   114  		}
   115  		blockStore.saveReduceLocaldbFlag()
   116  	}
   117  }
   118  
   119  func TestReduceBody(t *testing.T) {
   120  	dir, err := ioutil.TempDir("", "example")
   121  	assert.Nil(t, err)
   122  	defer os.RemoveAll(dir) // clean up
   123  	os.RemoveAll(dir)       //删除已存在目录
   124  	blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100)
   125  	chain := InitEnv()
   126  	cfg := chain.client.GetConfig()
   127  	blockStore := NewBlockStore(chain, blockStoreDB, chain.client)
   128  	assert.NotNil(t, blockStore)
   129  	chain.blockStore = blockStore
   130  
   131  	// generate blockdetail
   132  	txs := util.GenCoinsTxs(cfg, util.HexToPrivkey("4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"), 10)
   133  	block := &types.Block{Txs: txs}
   134  	block.MainHash = block.Hash(cfg)
   135  	block.Height = 0
   136  	blockdetail := &types.BlockDetail{
   137  		Block: block,
   138  		Receipts: []*types.ReceiptData{
   139  			{Ty: 0, Logs: []*types.ReceiptLog{{Ty: 0, Log: []byte("000")}, {Ty: 0, Log: []byte("0000")}}},
   140  			{Ty: 1, Logs: []*types.ReceiptLog{{Ty: 111, Log: []byte("111")}, {Ty: 1111, Log: []byte("1111")}}},
   141  			{Ty: 2, Logs: []*types.ReceiptLog{{Ty: 222, Log: []byte("222")}, {Ty: 2222, Log: []byte("2222")}}},
   142  			{Ty: 3, Logs: []*types.ReceiptLog{{Ty: 333, Log: []byte("333")}, {Ty: 3333, Log: []byte("3333")}}},
   143  		},
   144  		KV: []*types.KeyValue{{Key: []byte("000"), Value: []byte("000")}, {Key: []byte("111"), Value: []byte("111")}},
   145  	}
   146  
   147  	// save blockdetail
   148  	newbatch := blockStore.NewBatch(true)
   149  	_, err = blockStore.SaveBlock(newbatch, blockdetail, 0)
   150  	assert.NoError(t, err)
   151  	newbatch.Write()
   152  
   153  	// check
   154  	blockDetail, err := blockStore.LoadBlock(0, nil)
   155  	assert.NoError(t, err)
   156  	for _, recep := range blockDetail.Receipts {
   157  		for _, log := range recep.Logs {
   158  			assert.NotNil(t, log.Log)
   159  		}
   160  	}
   161  
   162  	// reduceBody
   163  	newbatch = blockStore.NewBatch(true)
   164  	chain.reduceBody(newbatch, 0)
   165  	newbatch.Write()
   166  
   167  	// check
   168  	cfg.S("reduceLocaldb", true)
   169  	blockDetail, err = blockStore.LoadBlock(0, nil)
   170  	assert.NoError(t, err)
   171  	for _, recep := range blockDetail.Receipts {
   172  		for _, log := range recep.Logs {
   173  			assert.Nil(t, log.Log)
   174  		}
   175  	}
   176  }
   177  
   178  func TestReduceBodyInit(t *testing.T) {
   179  	dir, err := ioutil.TempDir("", "example")
   180  	assert.Nil(t, err)
   181  	defer os.RemoveAll(dir) // clean up
   182  	os.RemoveAll(dir)       //删除已存在目录
   183  	blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100)
   184  	chain := InitEnv()
   185  	cfg := chain.client.GetConfig()
   186  	blockStore := NewBlockStore(chain, blockStoreDB, chain.client)
   187  	assert.NotNil(t, blockStore)
   188  	chain.blockStore = blockStore
   189  
   190  	// generate blockdetail
   191  	txs := util.GenCoinsTxs(cfg, util.HexToPrivkey("4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"), 10)
   192  	block := &types.Block{Txs: txs}
   193  	block.MainHash = block.Hash(cfg)
   194  	block.Height = 0
   195  	blockdetail := &types.BlockDetail{
   196  		Block: block,
   197  		Receipts: []*types.ReceiptData{
   198  			{Ty: 0, Logs: []*types.ReceiptLog{{Ty: 0, Log: []byte("000")}, {Ty: 0, Log: []byte("0000")}}},
   199  			{Ty: 1, Logs: []*types.ReceiptLog{{Ty: 111, Log: []byte("111")}, {Ty: 1111, Log: []byte("1111")}}},
   200  			{Ty: 2, Logs: []*types.ReceiptLog{{Ty: 222, Log: []byte("222")}, {Ty: 2222, Log: []byte("2222")}}},
   201  			{Ty: 3, Logs: []*types.ReceiptLog{{Ty: 333, Log: []byte("333")}, {Ty: 3333, Log: []byte("3333")}}},
   202  		},
   203  		KV: []*types.KeyValue{{Key: []byte("000"), Value: []byte("000")}, {Key: []byte("111"), Value: []byte("111")}},
   204  	}
   205  
   206  	// save blockdetail
   207  	newbatch := blockStore.NewBatch(true)
   208  	_, err = blockStore.SaveBlock(newbatch, blockdetail, 0)
   209  	assert.NoError(t, err)
   210  	newbatch.Write()
   211  
   212  	// save tx TxResult
   213  	newbatch = blockStore.NewBatch(true)
   214  	for index, tx := range txs {
   215  		var txresult types.TxResult
   216  		txresult.Height = block.Height
   217  		txresult.Index = int32(index)
   218  		txresult.Tx = tx
   219  		txresult.Receiptdate = &types.ReceiptData{Ty: 0, Logs: []*types.ReceiptLog{{Ty: 0, Log: []byte("000")}, {Ty: 0, Log: []byte("0000")}}}
   220  		txresult.Blocktime = 3123131231
   221  		txresult.ActionName = tx.ActionName()
   222  		newbatch.Set(cfg.CalcTxKey(tx.Hash()), cfg.CalcTxKeyValue(&txresult))
   223  	}
   224  	newbatch.Write()
   225  
   226  	// reduceBodyInit
   227  	cfg.S("reduceLocaldb", true)
   228  	newbatch = blockStore.NewBatch(true)
   229  	chain.reduceBodyInit(newbatch, 0)
   230  	newbatch.Write()
   231  
   232  	// check
   233  	// 1 body
   234  	blockDetail, err := blockStore.LoadBlock(0, nil)
   235  	assert.NoError(t, err)
   236  	for _, recep := range blockDetail.Receipts {
   237  		for _, log := range recep.Logs {
   238  			assert.Nil(t, log.Log)
   239  		}
   240  	}
   241  	// 2 tx
   242  	for _, tx := range txs {
   243  		hash := tx.Hash()
   244  		_, err := blockStore.db.Get(hash)
   245  		assert.Error(t, err, types.ErrNotFound)
   246  		v, err := blockStore.db.Get(cfg.CalcTxKey(hash))
   247  		assert.NoError(t, err)
   248  		var txresult types.TxResult
   249  		err = types.Decode(v, &txresult)
   250  		assert.NoError(t, err)
   251  		assert.Nil(t, txresult.Receiptdate)
   252  	}
   253  }
   254  
   255  func TestReduceReceipts(t *testing.T) {
   256  
   257  	var body types.BlockBody
   258  	receipts := []*types.ReceiptData{
   259  		{Ty: 0, Logs: []*types.ReceiptLog{{Ty: 0, Log: []byte("000")}, {Ty: 1, Log: []byte("0000")}}},
   260  		{Ty: 1, Logs: []*types.ReceiptLog{{Ty: 111, Log: []byte("111")}, {Ty: 1111, Log: []byte("1111")}}},
   261  		{Ty: 2, Logs: []*types.ReceiptLog{{Ty: 222, Log: []byte("222")}, {Ty: 2222, Log: []byte("2222")}}},
   262  		{Ty: 3, Logs: []*types.ReceiptLog{{Ty: 333, Log: []byte("333")}, {Ty: 3333, Log: []byte("3333")}}},
   263  	}
   264  	body.Receipts = receipts
   265  	dstReceipts := reduceReceipts(&body)
   266  
   267  	// check
   268  	for _, recpt := range body.Receipts {
   269  		for _, log := range recpt.Logs {
   270  			assert.NotNil(t, log.Log)
   271  		}
   272  	}
   273  
   274  	for _, recpt := range dstReceipts {
   275  		for _, log := range recpt.Logs {
   276  			if log.Ty == types.TyLogErr {
   277  				assert.NotNil(t, log.Log)
   278  			} else {
   279  				assert.Nil(t, log.Log)
   280  			}
   281  		}
   282  	}
   283  }