github.com/true-sqn/fabric@v2.1.1+incompatible/core/ledger/kvledger/kv_ledger_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package kvledger
     8  
     9  import (
    10  	"os"
    11  	"testing"
    12  
    13  	"github.com/golang/protobuf/proto"
    14  	"github.com/hyperledger/fabric-protos-go/common"
    15  	"github.com/hyperledger/fabric-protos-go/ledger/queryresult"
    16  	"github.com/hyperledger/fabric-protos-go/peer"
    17  	"github.com/hyperledger/fabric/common/flogging"
    18  	"github.com/hyperledger/fabric/common/ledger/testutil"
    19  	"github.com/hyperledger/fabric/common/util"
    20  	lgr "github.com/hyperledger/fabric/core/ledger"
    21  	"github.com/hyperledger/fabric/protoutil"
    22  	"github.com/stretchr/testify/assert"
    23  )
    24  
    25  func TestMain(m *testing.M) {
    26  	flogging.ActivateSpec("lockbasedtxmgr,statevalidator,valimpl,confighistory,pvtstatepurgemgmt=debug")
    27  	os.Exit(m.Run())
    28  }
    29  
    30  func TestKVLedgerNilHistoryDBProvider(t *testing.T) {
    31  	kvl := &kvLedger{}
    32  	qe, err := kvl.NewHistoryQueryExecutor()
    33  	assert.Nil(
    34  		t,
    35  		qe,
    36  		"NewHistoryQueryExecutor should return nil when history db provider is nil",
    37  	)
    38  	assert.NoError(
    39  		t,
    40  		err,
    41  		"NewHistoryQueryExecutor should return an error when history db provider is nil",
    42  	)
    43  }
    44  
    45  func TestKVLedgerBlockStorage(t *testing.T) {
    46  	conf, cleanup := testConfig(t)
    47  	defer cleanup()
    48  	provider := testutilNewProvider(conf, t)
    49  	defer provider.Close()
    50  
    51  	bg, gb := testutil.NewBlockGenerator(t, "testLedger", false)
    52  	gbHash := protoutil.BlockHeaderHash(gb.Header)
    53  	ledger, err := provider.Create(gb)
    54  	assert.NoError(t, err)
    55  	defer ledger.Close()
    56  
    57  	bcInfo, _ := ledger.GetBlockchainInfo()
    58  	assert.Equal(t, &common.BlockchainInfo{
    59  		Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil,
    60  	}, bcInfo)
    61  
    62  	txid := util.GenerateUUID()
    63  	simulator, _ := ledger.NewTxSimulator(txid)
    64  	simulator.SetState("ns1", "key1", []byte("value1"))
    65  	simulator.SetState("ns1", "key2", []byte("value2"))
    66  	simulator.SetState("ns1", "key3", []byte("value3"))
    67  	simulator.Done()
    68  	simRes, _ := simulator.GetTxSimulationResults()
    69  	pubSimBytes, _ := simRes.GetPubSimulationBytes()
    70  	block1 := bg.NextBlock([][]byte{pubSimBytes})
    71  	ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block1}, &lgr.CommitOptions{})
    72  
    73  	bcInfo, _ = ledger.GetBlockchainInfo()
    74  	block1Hash := protoutil.BlockHeaderHash(block1.Header)
    75  	assert.Equal(t, &common.BlockchainInfo{
    76  		Height: 2, CurrentBlockHash: block1Hash, PreviousBlockHash: gbHash,
    77  	}, bcInfo)
    78  
    79  	txid = util.GenerateUUID()
    80  	simulator, _ = ledger.NewTxSimulator(txid)
    81  	simulator.SetState("ns1", "key1", []byte("value4"))
    82  	simulator.SetState("ns1", "key2", []byte("value5"))
    83  	simulator.SetState("ns1", "key3", []byte("value6"))
    84  	simulator.Done()
    85  	simRes, _ = simulator.GetTxSimulationResults()
    86  	pubSimBytes, _ = simRes.GetPubSimulationBytes()
    87  	block2 := bg.NextBlock([][]byte{pubSimBytes})
    88  	ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block2}, &lgr.CommitOptions{})
    89  
    90  	bcInfo, _ = ledger.GetBlockchainInfo()
    91  	block2Hash := protoutil.BlockHeaderHash(block2.Header)
    92  	assert.Equal(t, &common.BlockchainInfo{
    93  		Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash}, bcInfo)
    94  
    95  	b0, _ := ledger.GetBlockByHash(gbHash)
    96  	assert.True(t, proto.Equal(b0, gb), "proto messages are not equal")
    97  
    98  	b1, _ := ledger.GetBlockByHash(block1Hash)
    99  	assert.True(t, proto.Equal(b1, block1), "proto messages are not equal")
   100  
   101  	b0, _ = ledger.GetBlockByNumber(0)
   102  	assert.True(t, proto.Equal(b0, gb), "proto messages are not equal")
   103  
   104  	b1, _ = ledger.GetBlockByNumber(1)
   105  	assert.Equal(t, block1, b1)
   106  
   107  	// get the tran id from the 2nd block, then use it to test GetTransactionByID()
   108  	txEnvBytes2 := block1.Data.Data[0]
   109  	txEnv2, err := protoutil.GetEnvelopeFromBlock(txEnvBytes2)
   110  	assert.NoError(t, err, "Error upon GetEnvelopeFromBlock")
   111  	payload2, err := protoutil.UnmarshalPayload(txEnv2.Payload)
   112  	assert.NoError(t, err, "Error upon GetPayload")
   113  	chdr, err := protoutil.UnmarshalChannelHeader(payload2.Header.ChannelHeader)
   114  	assert.NoError(t, err, "Error upon GetChannelHeaderFromBytes")
   115  	txID2 := chdr.TxId
   116  	processedTran2, err := ledger.GetTransactionByID(txID2)
   117  	assert.NoError(t, err, "Error upon GetTransactionByID")
   118  	// get the tran envelope from the retrieved ProcessedTransaction
   119  	retrievedTxEnv2 := processedTran2.TransactionEnvelope
   120  	assert.Equal(t, txEnv2, retrievedTxEnv2)
   121  
   122  	//  get the tran id from the 2nd block, then use it to test GetBlockByTxID
   123  	b1, _ = ledger.GetBlockByTxID(txID2)
   124  	assert.True(t, proto.Equal(b1, block1), "proto messages are not equal")
   125  
   126  	// get the transaction validation code for this transaction id
   127  	validCode, _ := ledger.GetTxValidationCodeByTxID(txID2)
   128  	assert.Equal(t, peer.TxValidationCode_VALID, validCode)
   129  }
   130  
   131  func TestAddCommitHash(t *testing.T) {
   132  	conf, cleanup := testConfig(t)
   133  	defer cleanup()
   134  	provider := testutilNewProvider(conf, t)
   135  	defer provider.Close()
   136  
   137  	bg, gb := testutil.NewBlockGenerator(t, "testLedger", false)
   138  	gbHash := protoutil.BlockHeaderHash(gb.Header)
   139  	ledger, err := provider.Create(gb)
   140  	assert.NoError(t, err)
   141  	defer ledger.Close()
   142  
   143  	// metadata associated with the above created geneis block is
   144  	// empty. Hence, no commitHash would be empty.
   145  	commitHash, err := ledger.(*kvLedger).lastPersistedCommitHash()
   146  	assert.NoError(t, err)
   147  	assert.Equal(t, commitHash, ledger.(*kvLedger).commitHash)
   148  	assert.Equal(t, len(commitHash), 0)
   149  
   150  	bcInfo, _ := ledger.GetBlockchainInfo()
   151  	assert.Equal(t, &common.BlockchainInfo{
   152  		Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil,
   153  	}, bcInfo)
   154  
   155  	txid := util.GenerateUUID()
   156  	simulator, _ := ledger.NewTxSimulator(txid)
   157  	simulator.SetState("ns1", "key1", []byte("value1"))
   158  	simulator.SetState("ns1", "key2", []byte("value2"))
   159  	simulator.SetState("ns1", "key3", []byte("value3"))
   160  	simulator.Done()
   161  	simRes, _ := simulator.GetTxSimulationResults()
   162  	pubSimBytes, _ := simRes.GetPubSimulationBytes()
   163  	block1 := bg.NextBlock([][]byte{pubSimBytes})
   164  	ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block1}, &lgr.CommitOptions{})
   165  
   166  	commitHash, err = ledger.(*kvLedger).lastPersistedCommitHash()
   167  	assert.NoError(t, err)
   168  	assert.Equal(t, commitHash, ledger.(*kvLedger).commitHash)
   169  	assert.Equal(t, len(commitHash), 32)
   170  
   171  	// if the kvledger.commitHash is nil and the block number is > 1, the
   172  	// commitHash should not be added to the block
   173  	block2 := bg.NextBlock([][]byte{pubSimBytes})
   174  	ledger.(*kvLedger).commitHash = nil
   175  	ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block2}, &lgr.CommitOptions{})
   176  
   177  	commitHash, err = ledger.(*kvLedger).lastPersistedCommitHash()
   178  	assert.NoError(t, err)
   179  	assert.Equal(t, commitHash, ledger.(*kvLedger).commitHash)
   180  	assert.Equal(t, len(commitHash), 0)
   181  
   182  }
   183  
   184  func TestKVLedgerBlockStorageWithPvtdata(t *testing.T) {
   185  	t.Skip()
   186  	conf, cleanup := testConfig(t)
   187  	defer cleanup()
   188  	provider := testutilNewProvider(conf, t)
   189  	defer provider.Close()
   190  
   191  	bg, gb := testutil.NewBlockGenerator(t, "testLedger", false)
   192  	gbHash := protoutil.BlockHeaderHash(gb.Header)
   193  	ledger, err := provider.Create(gb)
   194  	assert.NoError(t, err)
   195  	defer ledger.Close()
   196  
   197  	bcInfo, _ := ledger.GetBlockchainInfo()
   198  	assert.Equal(t, &common.BlockchainInfo{
   199  		Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil,
   200  	}, bcInfo)
   201  
   202  	txid := util.GenerateUUID()
   203  	simulator, _ := ledger.NewTxSimulator(txid)
   204  	simulator.SetState("ns1", "key1", []byte("value1"))
   205  	simulator.SetPrivateData("ns1", "coll1", "key2", []byte("value2"))
   206  	simulator.SetPrivateData("ns1", "coll2", "key2", []byte("value3"))
   207  	simulator.Done()
   208  	simRes, _ := simulator.GetTxSimulationResults()
   209  	pubSimBytes, _ := simRes.GetPubSimulationBytes()
   210  	block1 := bg.NextBlockWithTxid([][]byte{pubSimBytes}, []string{txid})
   211  	assert.NoError(t, ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block1}, &lgr.CommitOptions{}))
   212  
   213  	bcInfo, _ = ledger.GetBlockchainInfo()
   214  	block1Hash := protoutil.BlockHeaderHash(block1.Header)
   215  	assert.Equal(t, &common.BlockchainInfo{
   216  		Height: 2, CurrentBlockHash: block1Hash, PreviousBlockHash: gbHash,
   217  	}, bcInfo)
   218  
   219  	txid = util.GenerateUUID()
   220  	simulator, _ = ledger.NewTxSimulator(txid)
   221  	simulator.SetState("ns1", "key1", []byte("value4"))
   222  	simulator.SetState("ns1", "key2", []byte("value5"))
   223  	simulator.SetState("ns1", "key3", []byte("value6"))
   224  	simulator.Done()
   225  	simRes, _ = simulator.GetTxSimulationResults()
   226  	pubSimBytes, _ = simRes.GetPubSimulationBytes()
   227  	block2 := bg.NextBlock([][]byte{pubSimBytes})
   228  	ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block2}, &lgr.CommitOptions{})
   229  
   230  	bcInfo, _ = ledger.GetBlockchainInfo()
   231  	block2Hash := protoutil.BlockHeaderHash(block2.Header)
   232  	assert.Equal(t, &common.BlockchainInfo{
   233  		Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash,
   234  	}, bcInfo)
   235  
   236  	pvtdataAndBlock, _ := ledger.GetPvtDataAndBlockByNum(0, nil)
   237  	assert.Equal(t, gb, pvtdataAndBlock.Block)
   238  	assert.Nil(t, pvtdataAndBlock.PvtData)
   239  
   240  	pvtdataAndBlock, _ = ledger.GetPvtDataAndBlockByNum(1, nil)
   241  	assert.Equal(t, block1, pvtdataAndBlock.Block)
   242  	assert.NotNil(t, pvtdataAndBlock.PvtData)
   243  	assert.True(t, pvtdataAndBlock.PvtData[0].Has("ns1", "coll1"))
   244  	assert.True(t, pvtdataAndBlock.PvtData[0].Has("ns1", "coll2"))
   245  
   246  	pvtdataAndBlock, _ = ledger.GetPvtDataAndBlockByNum(2, nil)
   247  	assert.Equal(t, block2, pvtdataAndBlock.Block)
   248  	assert.Nil(t, pvtdataAndBlock.PvtData)
   249  }
   250  
   251  func TestKVLedgerDBRecovery(t *testing.T) {
   252  	conf, cleanup := testConfig(t)
   253  	defer cleanup()
   254  	provider1 := testutilNewProviderWithCollectionConfig(
   255  		t,
   256  		"ns",
   257  		map[string]uint64{"coll": 0},
   258  		conf,
   259  	)
   260  	defer provider1.Close()
   261  
   262  	testLedgerid := "testLedger"
   263  	bg, gb := testutil.NewBlockGenerator(t, testLedgerid, false)
   264  	ledger1, err := provider1.Create(gb)
   265  	assert.NoError(t, err)
   266  	defer ledger1.Close()
   267  
   268  	gbHash := protoutil.BlockHeaderHash(gb.Header)
   269  	checkBCSummaryForTest(t, ledger1,
   270  		&bcSummary{
   271  			bcInfo: &common.BlockchainInfo{Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil},
   272  		},
   273  	)
   274  
   275  	// creating and committing the second data block
   276  	blockAndPvtdata1 := prepareNextBlockForTest(t, ledger1, bg, "SimulateForBlk1",
   277  		map[string]string{"key1": "value1.1", "key2": "value2.1", "key3": "value3.1"},
   278  		map[string]string{"key1": "pvtValue1.1", "key2": "pvtValue2.1", "key3": "pvtValue3.1"})
   279  	assert.NoError(t, ledger1.CommitLegacy(blockAndPvtdata1, &lgr.CommitOptions{}))
   280  	checkBCSummaryForTest(t, ledger1,
   281  		&bcSummary{
   282  			bcInfo: &common.BlockchainInfo{Height: 2,
   283  				CurrentBlockHash:  protoutil.BlockHeaderHash(blockAndPvtdata1.Block.Header),
   284  				PreviousBlockHash: gbHash},
   285  		},
   286  	)
   287  
   288  	//======================================================================================
   289  	// SCENARIO 1: peer writes the second block to the block storage and fails
   290  	// before committing the block to state DB and history DB
   291  	//======================================================================================
   292  	blockAndPvtdata2 := prepareNextBlockForTest(t, ledger1, bg, "SimulateForBlk2",
   293  		map[string]string{"key1": "value1.2", "key2": "value2.2", "key3": "value3.2"},
   294  		map[string]string{"key1": "pvtValue1.2", "key2": "pvtValue2.2", "key3": "pvtValue3.2"})
   295  
   296  	_, _, err = ledger1.(*kvLedger).txtmgmt.ValidateAndPrepare(blockAndPvtdata2, true)
   297  	assert.NoError(t, err)
   298  	assert.NoError(t, ledger1.(*kvLedger).blockStore.CommitWithPvtData(blockAndPvtdata2))
   299  
   300  	// block storage should be as of block-2 but the state and history db should be as of block-1
   301  	checkBCSummaryForTest(t, ledger1,
   302  		&bcSummary{
   303  			bcInfo: &common.BlockchainInfo{Height: 3,
   304  				CurrentBlockHash:  protoutil.BlockHeaderHash(blockAndPvtdata2.Block.Header),
   305  				PreviousBlockHash: protoutil.BlockHeaderHash(blockAndPvtdata1.Block.Header)},
   306  
   307  			stateDBSavePoint: uint64(1),
   308  			stateDBKVs:       map[string]string{"key1": "value1.1", "key2": "value2.1", "key3": "value3.1"},
   309  			stateDBPvtKVs:    map[string]string{"key1": "pvtValue1.1", "key2": "pvtValue2.1", "key3": "pvtValue3.1"},
   310  
   311  			historyDBSavePoint: uint64(1),
   312  			historyKey:         "key1",
   313  			historyVals:        []string{"value1.1"},
   314  		},
   315  	)
   316  	// Now, assume that peer fails here before committing the transaction to the statedb and historydb
   317  	ledger1.Close()
   318  	provider1.Close()
   319  
   320  	// Here the peer comes online and calls NewKVLedger to get a handler for the ledger
   321  	// StateDB and HistoryDB should be recovered before returning from NewKVLedger call
   322  	provider2 := testutilNewProviderWithCollectionConfig(
   323  		t,
   324  		"ns",
   325  		map[string]uint64{"coll": 0},
   326  		conf,
   327  	)
   328  	defer provider2.Close()
   329  	ledger2, err := provider2.Open(testLedgerid)
   330  	assert.NoError(t, err)
   331  	defer ledger2.Close()
   332  	checkBCSummaryForTest(t, ledger2,
   333  		&bcSummary{
   334  			stateDBSavePoint: uint64(2),
   335  			stateDBKVs:       map[string]string{"key1": "value1.2", "key2": "value2.2", "key3": "value3.2"},
   336  			stateDBPvtKVs:    map[string]string{"key1": "pvtValue1.2", "key2": "pvtValue2.2", "key3": "pvtValue3.2"},
   337  
   338  			historyDBSavePoint: uint64(2),
   339  			historyKey:         "key1",
   340  			historyVals:        []string{"value1.2", "value1.1"},
   341  		},
   342  	)
   343  
   344  	//======================================================================================
   345  	// SCENARIO 2: peer fails after committing the third block to the block storage and state DB
   346  	// but before committing to history DB
   347  	//======================================================================================
   348  	blockAndPvtdata3 := prepareNextBlockForTest(t, ledger2, bg, "SimulateForBlk3",
   349  		map[string]string{"key1": "value1.3", "key2": "value2.3", "key3": "value3.3"},
   350  		map[string]string{"key1": "pvtValue1.3", "key2": "pvtValue2.3", "key3": "pvtValue3.3"},
   351  	)
   352  	_, _, err = ledger2.(*kvLedger).txtmgmt.ValidateAndPrepare(blockAndPvtdata3, true)
   353  	assert.NoError(t, err)
   354  	assert.NoError(t, ledger2.(*kvLedger).blockStore.CommitWithPvtData(blockAndPvtdata3))
   355  	// committing the transaction to state DB
   356  	assert.NoError(t, ledger2.(*kvLedger).txtmgmt.Commit())
   357  
   358  	// assume that peer fails here after committing the transaction to state DB but before history DB
   359  	checkBCSummaryForTest(t, ledger2,
   360  		&bcSummary{
   361  			bcInfo: &common.BlockchainInfo{Height: 4,
   362  				CurrentBlockHash:  protoutil.BlockHeaderHash(blockAndPvtdata3.Block.Header),
   363  				PreviousBlockHash: protoutil.BlockHeaderHash(blockAndPvtdata2.Block.Header)},
   364  
   365  			stateDBSavePoint: uint64(3),
   366  			stateDBKVs:       map[string]string{"key1": "value1.3", "key2": "value2.3", "key3": "value3.3"},
   367  			stateDBPvtKVs:    map[string]string{"key1": "pvtValue1.3", "key2": "pvtValue2.3", "key3": "pvtValue3.3"},
   368  
   369  			historyDBSavePoint: uint64(2),
   370  			historyKey:         "key1",
   371  			historyVals:        []string{"value1.2", "value1.1"},
   372  		},
   373  	)
   374  	ledger2.Close()
   375  	provider2.Close()
   376  
   377  	// we assume here that the peer comes online and calls NewKVLedger to get a handler for the ledger
   378  	// history DB should be recovered before returning from NewKVLedger call
   379  	provider3 := testutilNewProviderWithCollectionConfig(
   380  		t,
   381  		"ns",
   382  		map[string]uint64{"coll": 0},
   383  		conf,
   384  	)
   385  	defer provider3.Close()
   386  	ledger3, err := provider3.Open(testLedgerid)
   387  	assert.NoError(t, err)
   388  	defer ledger3.Close()
   389  
   390  	checkBCSummaryForTest(t, ledger3,
   391  		&bcSummary{
   392  			stateDBSavePoint: uint64(3),
   393  			stateDBKVs:       map[string]string{"key1": "value1.3", "key2": "value2.3", "key3": "value3.3"},
   394  			stateDBPvtKVs:    map[string]string{"key1": "pvtValue1.3", "key2": "pvtValue2.3", "key3": "pvtValue3.3"},
   395  
   396  			historyDBSavePoint: uint64(3),
   397  			historyKey:         "key1",
   398  			historyVals:        []string{"value1.3", "value1.2", "value1.1"},
   399  		},
   400  	)
   401  
   402  	// Rare scenario
   403  	//======================================================================================
   404  	// SCENARIO 3: peer fails after committing the fourth block to the block storgae
   405  	// and history DB but before committing to state DB
   406  	//======================================================================================
   407  	blockAndPvtdata4 := prepareNextBlockForTest(t, ledger3, bg, "SimulateForBlk4",
   408  		map[string]string{"key1": "value1.4", "key2": "value2.4", "key3": "value3.4"},
   409  		map[string]string{"key1": "pvtValue1.4", "key2": "pvtValue2.4", "key3": "pvtValue3.4"},
   410  	)
   411  
   412  	_, _, err = ledger3.(*kvLedger).txtmgmt.ValidateAndPrepare(blockAndPvtdata4, true)
   413  	assert.NoError(t, err)
   414  	assert.NoError(t, ledger3.(*kvLedger).blockStore.CommitWithPvtData(blockAndPvtdata4))
   415  	assert.NoError(t, ledger3.(*kvLedger).historyDB.Commit(blockAndPvtdata4.Block))
   416  
   417  	checkBCSummaryForTest(t, ledger3,
   418  		&bcSummary{
   419  			bcInfo: &common.BlockchainInfo{Height: 5,
   420  				CurrentBlockHash:  protoutil.BlockHeaderHash(blockAndPvtdata4.Block.Header),
   421  				PreviousBlockHash: protoutil.BlockHeaderHash(blockAndPvtdata3.Block.Header)},
   422  
   423  			stateDBSavePoint: uint64(3),
   424  			stateDBKVs:       map[string]string{"key1": "value1.3", "key2": "value2.3", "key3": "value3.3"},
   425  			stateDBPvtKVs:    map[string]string{"key1": "pvtValue1.3", "key2": "pvtValue2.3", "key3": "pvtValue3.3"},
   426  
   427  			historyDBSavePoint: uint64(4),
   428  			historyKey:         "key1",
   429  			historyVals:        []string{"value1.4", "value1.3", "value1.2", "value1.1"},
   430  		},
   431  	)
   432  	ledger3.Close()
   433  	provider3.Close()
   434  
   435  	// we assume here that the peer comes online and calls NewKVLedger to get a handler for the ledger
   436  	// state DB should be recovered before returning from NewKVLedger call
   437  	provider4 := testutilNewProviderWithCollectionConfig(
   438  		t,
   439  		"ns",
   440  		map[string]uint64{"coll": 0},
   441  		conf,
   442  	)
   443  	defer provider4.Close()
   444  	ledger4, err := provider4.Open(testLedgerid)
   445  	assert.NoError(t, err)
   446  	defer ledger4.Close()
   447  	checkBCSummaryForTest(t, ledger4,
   448  		&bcSummary{
   449  			stateDBSavePoint: uint64(4),
   450  			stateDBKVs:       map[string]string{"key1": "value1.4", "key2": "value2.4", "key3": "value3.4"},
   451  			stateDBPvtKVs:    map[string]string{"key1": "pvtValue1.4", "key2": "pvtValue2.4", "key3": "pvtValue3.4"},
   452  
   453  			historyDBSavePoint: uint64(4),
   454  			historyKey:         "key1",
   455  			historyVals:        []string{"value1.4", "value1.3", "value1.2", "value1.1"},
   456  		},
   457  	)
   458  }
   459  
   460  func TestLedgerWithCouchDbEnabledWithBinaryAndJSONData(t *testing.T) {
   461  	conf, cleanup := testConfig(t)
   462  	defer cleanup()
   463  	provider := testutilNewProvider(conf, t)
   464  	defer provider.Close()
   465  	bg, gb := testutil.NewBlockGenerator(t, "testLedger", false)
   466  	gbHash := protoutil.BlockHeaderHash(gb.Header)
   467  	ledger, err := provider.Create(gb)
   468  	assert.NoError(t, err)
   469  	defer ledger.Close()
   470  
   471  	bcInfo, _ := ledger.GetBlockchainInfo()
   472  	assert.Equal(t, &common.BlockchainInfo{
   473  		Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil}, bcInfo)
   474  
   475  	txid := util.GenerateUUID()
   476  	simulator, _ := ledger.NewTxSimulator(txid)
   477  	simulator.SetState("ns1", "key4", []byte("value1"))
   478  	simulator.SetState("ns1", "key5", []byte("value2"))
   479  	simulator.SetState("ns1", "key6", []byte("{\"shipmentID\":\"161003PKC7300\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091622\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   480  	simulator.SetState("ns1", "key7", []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"AIR MAYBE\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   481  	simulator.Done()
   482  	simRes, _ := simulator.GetTxSimulationResults()
   483  	pubSimBytes, _ := simRes.GetPubSimulationBytes()
   484  	block1 := bg.NextBlock([][]byte{pubSimBytes})
   485  
   486  	ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block1}, &lgr.CommitOptions{})
   487  
   488  	bcInfo, _ = ledger.GetBlockchainInfo()
   489  	block1Hash := protoutil.BlockHeaderHash(block1.Header)
   490  	assert.Equal(t, &common.BlockchainInfo{
   491  		Height: 2, CurrentBlockHash: block1Hash, PreviousBlockHash: gbHash}, bcInfo)
   492  
   493  	simulationResults := [][]byte{}
   494  	txid = util.GenerateUUID()
   495  	simulator, _ = ledger.NewTxSimulator(txid)
   496  	simulator.SetState("ns1", "key4", []byte("value3"))
   497  	simulator.SetState("ns1", "key5", []byte("{\"shipmentID\":\"161003PKC7500\",\"customsInvoice\":{\"methodOfTransport\":\"AIR FREIGHT\",\"invoiceNumber\":\"00091623\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   498  	simulator.SetState("ns1", "key6", []byte("value4"))
   499  	simulator.SetState("ns1", "key7", []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   500  	simulator.SetState("ns1", "key8", []byte("{\"shipmentID\":\"161003PKC7700\",\"customsInvoice\":{\"methodOfTransport\":\"SHIP\",\"invoiceNumber\":\"00091625\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   501  	simulator.Done()
   502  	simRes, _ = simulator.GetTxSimulationResults()
   503  	pubSimBytes, _ = simRes.GetPubSimulationBytes()
   504  	simulationResults = append(simulationResults, pubSimBytes)
   505  	//add a 2nd transaction
   506  	txid2 := util.GenerateUUID()
   507  	simulator2, _ := ledger.NewTxSimulator(txid2)
   508  	simulator2.SetState("ns1", "key7", []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"TRAIN\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   509  	simulator2.SetState("ns1", "key9", []byte("value5"))
   510  	simulator2.SetState("ns1", "key10", []byte("{\"shipmentID\":\"261003PKC8000\",\"customsInvoice\":{\"methodOfTransport\":\"DONKEY\",\"invoiceNumber\":\"00091626\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   511  	simulator2.Done()
   512  	simRes2, _ := simulator2.GetTxSimulationResults()
   513  	pubSimBytes2, _ := simRes2.GetPubSimulationBytes()
   514  	simulationResults = append(simulationResults, pubSimBytes2)
   515  
   516  	block2 := bg.NextBlock(simulationResults)
   517  	ledger.CommitLegacy(&lgr.BlockAndPvtData{Block: block2}, &lgr.CommitOptions{})
   518  
   519  	bcInfo, _ = ledger.GetBlockchainInfo()
   520  	block2Hash := protoutil.BlockHeaderHash(block2.Header)
   521  	assert.Equal(t, &common.BlockchainInfo{
   522  		Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash,
   523  	}, bcInfo)
   524  
   525  	b0, _ := ledger.GetBlockByHash(gbHash)
   526  	assert.True(t, proto.Equal(b0, gb), "proto messages are not equal")
   527  
   528  	b1, _ := ledger.GetBlockByHash(block1Hash)
   529  	assert.True(t, proto.Equal(b1, block1), "proto messages are not equal")
   530  
   531  	b2, _ := ledger.GetBlockByHash(block2Hash)
   532  	assert.True(t, proto.Equal(b2, block2), "proto messages are not equal")
   533  
   534  	b0, _ = ledger.GetBlockByNumber(0)
   535  	assert.True(t, proto.Equal(b0, gb), "proto messages are not equal")
   536  
   537  	b1, _ = ledger.GetBlockByNumber(1)
   538  	assert.True(t, proto.Equal(b1, block1), "proto messages are not equal")
   539  
   540  	b2, _ = ledger.GetBlockByNumber(2)
   541  	assert.True(t, proto.Equal(b2, block2), "proto messages are not equal")
   542  
   543  	//Similar test has been pushed down to historyleveldb_test.go as well
   544  	if conf.HistoryDBConfig.Enabled {
   545  		logger.Debugf("History is enabled\n")
   546  		qhistory, err := ledger.NewHistoryQueryExecutor()
   547  		assert.NoError(t, err, "Error when trying to retrieve history database executor")
   548  
   549  		itr, err2 := qhistory.GetHistoryForKey("ns1", "key7")
   550  		assert.NoError(t, err2, "Error upon GetHistoryForKey")
   551  
   552  		var retrievedValue []byte
   553  		count := 0
   554  		for {
   555  			kmod, _ := itr.Next()
   556  			if kmod == nil {
   557  				break
   558  			}
   559  			retrievedValue = kmod.(*queryresult.KeyModification).Value
   560  			count++
   561  		}
   562  		assert.Equal(t, 3, count)
   563  		// test the last value in the history matches the first value set for key7
   564  		expectedValue := []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"AIR MAYBE\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")
   565  		assert.Equal(t, expectedValue, retrievedValue)
   566  
   567  	}
   568  }
   569  
   570  func prepareNextBlockWithMissingPvtDataForTest(t *testing.T, l lgr.PeerLedger, bg *testutil.BlockGenerator,
   571  	txid string, pubKVs map[string]string, pvtKVs map[string]string) (*lgr.BlockAndPvtData, *lgr.TxPvtData) {
   572  
   573  	blockAndPvtData := prepareNextBlockForTest(t, l, bg, txid, pubKVs, pvtKVs)
   574  
   575  	blkMissingDataInfo := make(lgr.TxMissingPvtDataMap)
   576  	blkMissingDataInfo.Add(0, "ns", "coll", true)
   577  	blockAndPvtData.MissingPvtData = blkMissingDataInfo
   578  
   579  	pvtData := blockAndPvtData.PvtData[0]
   580  	delete(blockAndPvtData.PvtData, 0)
   581  
   582  	return blockAndPvtData, pvtData
   583  }
   584  
   585  func prepareNextBlockForTest(t *testing.T, l lgr.PeerLedger, bg *testutil.BlockGenerator,
   586  	txid string, pubKVs map[string]string, pvtKVs map[string]string) *lgr.BlockAndPvtData {
   587  	simulator, _ := l.NewTxSimulator(txid)
   588  	//simulating transaction
   589  	for k, v := range pubKVs {
   590  		simulator.SetState("ns", k, []byte(v))
   591  	}
   592  	for k, v := range pvtKVs {
   593  		simulator.SetPrivateData("ns", "coll", k, []byte(v))
   594  	}
   595  	simulator.Done()
   596  	simRes, _ := simulator.GetTxSimulationResults()
   597  	pubSimBytes, _ := simRes.GetPubSimulationBytes()
   598  	block := bg.NextBlock([][]byte{pubSimBytes})
   599  	return &lgr.BlockAndPvtData{Block: block,
   600  		PvtData: lgr.TxPvtDataMap{0: {SeqInBlock: 0, WriteSet: simRes.PvtSimulationResults}},
   601  	}
   602  }
   603  
   604  func checkBCSummaryForTest(t *testing.T, l lgr.PeerLedger, expectedBCSummary *bcSummary) {
   605  	if expectedBCSummary.bcInfo != nil {
   606  		actualBCInfo, _ := l.GetBlockchainInfo()
   607  		assert.Equal(t, expectedBCSummary.bcInfo, actualBCInfo)
   608  	}
   609  
   610  	if expectedBCSummary.stateDBSavePoint != 0 {
   611  		actualStateDBSavepoint, _ := l.(*kvLedger).txtmgmt.GetLastSavepoint()
   612  		assert.Equal(t, expectedBCSummary.stateDBSavePoint, actualStateDBSavepoint.BlockNum)
   613  	}
   614  
   615  	if !(expectedBCSummary.stateDBKVs == nil && expectedBCSummary.stateDBPvtKVs == nil) {
   616  		checkStateDBForTest(t, l, expectedBCSummary.stateDBKVs, expectedBCSummary.stateDBPvtKVs)
   617  	}
   618  
   619  	if expectedBCSummary.historyDBSavePoint != 0 {
   620  		actualHistoryDBSavepoint, _ := l.(*kvLedger).historyDB.GetLastSavepoint()
   621  		assert.Equal(t, expectedBCSummary.historyDBSavePoint, actualHistoryDBSavepoint.BlockNum)
   622  	}
   623  
   624  	if expectedBCSummary.historyKey != "" {
   625  		checkHistoryDBForTest(t, l, expectedBCSummary.historyKey, expectedBCSummary.historyVals)
   626  	}
   627  }
   628  
   629  func checkStateDBForTest(t *testing.T, l lgr.PeerLedger, expectedKVs map[string]string, expectedPvtKVs map[string]string) {
   630  	simulator, _ := l.NewTxSimulator("checkStateDBForTest")
   631  	defer simulator.Done()
   632  	for expectedKey, expectedVal := range expectedKVs {
   633  		actualVal, _ := simulator.GetState("ns", expectedKey)
   634  		assert.Equal(t, []byte(expectedVal), actualVal)
   635  	}
   636  
   637  	for expectedPvtKey, expectedPvtVal := range expectedPvtKVs {
   638  		actualPvtVal, _ := simulator.GetPrivateData("ns", "coll", expectedPvtKey)
   639  		assert.Equal(t, []byte(expectedPvtVal), actualPvtVal)
   640  	}
   641  }
   642  
   643  func checkHistoryDBForTest(t *testing.T, l lgr.PeerLedger, key string, expectedVals []string) {
   644  	qhistory, _ := l.NewHistoryQueryExecutor()
   645  	itr, _ := qhistory.GetHistoryForKey("ns", key)
   646  	var actualVals []string
   647  	for {
   648  		kmod, err := itr.Next()
   649  		assert.NoError(t, err, "Error upon Next()")
   650  		if kmod == nil {
   651  			break
   652  		}
   653  		retrievedValue := kmod.(*queryresult.KeyModification).Value
   654  		actualVals = append(actualVals, string(retrievedValue))
   655  	}
   656  	assert.Equal(t, expectedVals, actualVals)
   657  }
   658  
   659  type bcSummary struct {
   660  	bcInfo             *common.BlockchainInfo
   661  	stateDBSavePoint   uint64
   662  	stateDBKVs         map[string]string
   663  	stateDBPvtKVs      map[string]string
   664  	historyDBSavePoint uint64
   665  	historyKey         string
   666  	historyVals        []string
   667  }