github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/ledger/kvledger/kv_ledger_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package kvledger
    18  
    19  import (
    20  	"fmt"
    21  	"strconv"
    22  	"testing"
    23  
    24  	"github.com/hyperledger/fabric/common/ledger/testutil"
    25  	"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
    26  	ledgertestutil "github.com/hyperledger/fabric/core/ledger/testutil"
    27  	"github.com/hyperledger/fabric/protos/common"
    28  	"github.com/hyperledger/fabric/protos/ledger/queryresult"
    29  	putils "github.com/hyperledger/fabric/protos/utils"
    30  	"github.com/stretchr/testify/assert"
    31  )
    32  
    33  func TestKVLedgerBlockStorage(t *testing.T) {
    34  	env := newTestEnv(t)
    35  	defer env.cleanup()
    36  	provider, _ := NewProvider()
    37  	defer provider.Close()
    38  
    39  	bg, gb := testutil.NewBlockGenerator(t, "testLedger", false)
    40  	gbHash := gb.Header.Hash()
    41  	ledger, _ := provider.Create(gb)
    42  	defer ledger.Close()
    43  
    44  	bcInfo, _ := ledger.GetBlockchainInfo()
    45  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
    46  		Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil})
    47  
    48  	simulator, _ := ledger.NewTxSimulator()
    49  	simulator.SetState("ns1", "key1", []byte("value1"))
    50  	simulator.SetState("ns1", "key2", []byte("value2"))
    51  	simulator.SetState("ns1", "key3", []byte("value3"))
    52  	simulator.Done()
    53  	simRes, _ := simulator.GetTxSimulationResults()
    54  	block1 := bg.NextBlock([][]byte{simRes})
    55  	ledger.Commit(block1)
    56  
    57  	bcInfo, _ = ledger.GetBlockchainInfo()
    58  	block1Hash := block1.Header.Hash()
    59  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
    60  		Height: 2, CurrentBlockHash: block1Hash, PreviousBlockHash: gbHash})
    61  
    62  	simulator, _ = ledger.NewTxSimulator()
    63  	simulator.SetState("ns1", "key1", []byte("value4"))
    64  	simulator.SetState("ns1", "key2", []byte("value5"))
    65  	simulator.SetState("ns1", "key3", []byte("value6"))
    66  	simulator.Done()
    67  	simRes, _ = simulator.GetTxSimulationResults()
    68  	block2 := bg.NextBlock([][]byte{simRes})
    69  	ledger.Commit(block2)
    70  
    71  	bcInfo, _ = ledger.GetBlockchainInfo()
    72  	block2Hash := block2.Header.Hash()
    73  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
    74  		Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash})
    75  
    76  	b0, _ := ledger.GetBlockByHash(gbHash)
    77  	testutil.AssertEquals(t, b0, gb)
    78  
    79  	b1, _ := ledger.GetBlockByHash(block1Hash)
    80  	testutil.AssertEquals(t, b1, block1)
    81  
    82  	b0, _ = ledger.GetBlockByNumber(0)
    83  	testutil.AssertEquals(t, b0, gb)
    84  
    85  	b1, _ = ledger.GetBlockByNumber(1)
    86  	testutil.AssertEquals(t, b1, block1)
    87  
    88  	// get the tran id from the 2nd block, then use it to test GetTransactionByID()
    89  	txEnvBytes2 := block1.Data.Data[0]
    90  	txEnv2, err := putils.GetEnvelopeFromBlock(txEnvBytes2)
    91  	testutil.AssertNoError(t, err, "Error upon GetEnvelopeFromBlock")
    92  	payload2, err := putils.GetPayload(txEnv2)
    93  	testutil.AssertNoError(t, err, "Error upon GetPayload")
    94  	chdr, err := putils.UnmarshalChannelHeader(payload2.Header.ChannelHeader)
    95  	testutil.AssertNoError(t, err, "Error upon GetChannelHeaderFromBytes")
    96  	txID2 := chdr.TxId
    97  	processedTran2, err := ledger.GetTransactionByID(txID2)
    98  	testutil.AssertNoError(t, err, "Error upon GetTransactionByID")
    99  	// get the tran envelope from the retrieved ProcessedTransaction
   100  	retrievedTxEnv2 := processedTran2.TransactionEnvelope
   101  	testutil.AssertEquals(t, retrievedTxEnv2, txEnv2)
   102  
   103  }
   104  
   105  func TestKVLedgerDBRecovery(t *testing.T) {
   106  	ledgertestutil.SetupCoreYAMLConfig()
   107  	env := newTestEnv(t)
   108  	defer env.cleanup()
   109  	provider, _ := NewProvider()
   110  	defer provider.Close()
   111  
   112  	bg, gb := testutil.NewBlockGenerator(t, "testLedger", false)
   113  	ledger, _ := provider.Create(gb)
   114  	defer ledger.Close()
   115  	gbHash := gb.Header.Hash()
   116  	bcInfo, err := ledger.GetBlockchainInfo()
   117  	testutil.AssertNoError(t, err, "")
   118  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
   119  		Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil})
   120  	//creating and committing the first block
   121  	simulator, _ := ledger.NewTxSimulator()
   122  	//simulating a transaction
   123  	simulator.SetState("ns1", "key1", []byte("value1.1"))
   124  	simulator.SetState("ns1", "key2", []byte("value2.1"))
   125  	simulator.SetState("ns1", "key3", []byte("value3.1"))
   126  	simulator.Done()
   127  	simRes, _ := simulator.GetTxSimulationResults()
   128  	//generating a block based on the simulation result
   129  	block1 := bg.NextBlock([][]byte{simRes})
   130  	//performing validation of read and write set to find valid transactions
   131  	ledger.Commit(block1)
   132  	bcInfo, _ = ledger.GetBlockchainInfo()
   133  	block1Hash := block1.Header.Hash()
   134  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
   135  		Height: 2, CurrentBlockHash: block1Hash, PreviousBlockHash: gbHash})
   136  
   137  	//======================================================================================
   138  	//SCENARIO 1: peer fails before committing the second block to state DB
   139  	//and history DB (if exist)
   140  	//======================================================================================
   141  	simulator, _ = ledger.NewTxSimulator()
   142  	//simulating transaction
   143  	simulator.SetState("ns1", "key1", []byte("value1.2"))
   144  	simulator.SetState("ns1", "key2", []byte("value2.2"))
   145  	simulator.SetState("ns1", "key3", []byte("value3.2"))
   146  	simulator.Done()
   147  	simRes, _ = simulator.GetTxSimulationResults()
   148  	//generating a block based on the simulation result
   149  	block2 := bg.NextBlock([][]byte{simRes})
   150  
   151  	//performing validation of read and write set to find valid transactions
   152  	ledger.(*kvLedger).txtmgmt.ValidateAndPrepare(block2, true)
   153  	//writing the validated block to block storage but not committing the transaction
   154  	//to state DB and history DB (if exist)
   155  	err = ledger.(*kvLedger).blockStore.AddBlock(block2)
   156  
   157  	//assume that peer fails here before committing the transaction
   158  	assert.NoError(t, err)
   159  
   160  	bcInfo, _ = ledger.GetBlockchainInfo()
   161  	block2Hash := block2.Header.Hash()
   162  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
   163  		Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash})
   164  
   165  	simulator, _ = ledger.NewTxSimulator()
   166  	value, _ := simulator.GetState("ns1", "key1")
   167  	//value for 'key1' should be 'value1' as the last commit failed
   168  	testutil.AssertEquals(t, value, []byte("value1.1"))
   169  	value, _ = simulator.GetState("ns1", "key2")
   170  	//value for 'key2' should be 'value2' as the last commit failed
   171  	testutil.AssertEquals(t, value, []byte("value2.1"))
   172  	value, _ = simulator.GetState("ns1", "key3")
   173  	//value for 'key3' should be 'value3' as the last commit failed
   174  	testutil.AssertEquals(t, value, []byte("value3.1"))
   175  	//savepoint in state DB should 0 as the last commit failed
   176  	stateDBSavepoint, _ := ledger.(*kvLedger).txtmgmt.GetLastSavepoint()
   177  	testutil.AssertEquals(t, stateDBSavepoint.BlockNum, uint64(1))
   178  
   179  	if ledgerconfig.IsHistoryDBEnabled() == true {
   180  		qhistory, _ := ledger.NewHistoryQueryExecutor()
   181  		itr, _ := qhistory.GetHistoryForKey("ns1", "key1")
   182  		count := 0
   183  		for {
   184  			kmod, err := itr.Next()
   185  			testutil.AssertNoError(t, err, "Error upon Next()")
   186  			if kmod == nil {
   187  				break
   188  			}
   189  			retrievedValue := kmod.(*queryresult.KeyModification).Value
   190  			count++
   191  			expectedValue := []byte("value1." + strconv.Itoa(count))
   192  			testutil.AssertEquals(t, retrievedValue, expectedValue)
   193  		}
   194  		testutil.AssertEquals(t, count, 1)
   195  
   196  		//savepoint in history DB should 0 as the last commit failed
   197  		historyDBSavepoint, _ := ledger.(*kvLedger).historyDB.GetLastSavepoint()
   198  		testutil.AssertEquals(t, historyDBSavepoint.BlockNum, uint64(1))
   199  	}
   200  
   201  	simulator.Done()
   202  	ledger.Close()
   203  	provider.Close()
   204  
   205  	//we assume here that the peer comes online and calls NewKVLedger to get a handler for the ledger
   206  	//State DB should be recovered before returning from NewKVLedger call
   207  	provider, _ = NewProvider()
   208  	ledger, _ = provider.Open("testLedger")
   209  
   210  	simulator, _ = ledger.NewTxSimulator()
   211  	value, _ = simulator.GetState("ns1", "key1")
   212  	//value for 'key1' should be 'value4' after recovery
   213  	testutil.AssertEquals(t, value, []byte("value1.2"))
   214  	value, _ = simulator.GetState("ns1", "key2")
   215  	//value for 'key2' should be 'value5' after recovery
   216  	testutil.AssertEquals(t, value, []byte("value2.2"))
   217  	value, _ = simulator.GetState("ns1", "key3")
   218  	//value for 'key3' should be 'value6' after recovery
   219  	testutil.AssertEquals(t, value, []byte("value3.2"))
   220  	//savepoint in state DB should 2 after recovery
   221  	stateDBSavepoint, _ = ledger.(*kvLedger).txtmgmt.GetLastSavepoint()
   222  	testutil.AssertEquals(t, stateDBSavepoint.BlockNum, uint64(2))
   223  
   224  	if ledgerconfig.IsHistoryDBEnabled() == true {
   225  		qhistory, _ := ledger.NewHistoryQueryExecutor()
   226  		itr, _ := qhistory.GetHistoryForKey("ns1", "key1")
   227  		count := 0
   228  		for {
   229  			kmod, err := itr.Next()
   230  			testutil.AssertNoError(t, err, "Error upon Next()")
   231  			if kmod == nil {
   232  				break
   233  			}
   234  			retrievedValue := kmod.(*queryresult.KeyModification).Value
   235  			count++
   236  			expectedValue := []byte("value1." + strconv.Itoa(count))
   237  			testutil.AssertEquals(t, retrievedValue, expectedValue)
   238  		}
   239  		testutil.AssertEquals(t, count, 2)
   240  
   241  		//savepoint in history DB should 2 after recovery
   242  		historyDBSavepoint, _ := ledger.(*kvLedger).historyDB.GetLastSavepoint()
   243  		testutil.AssertEquals(t, historyDBSavepoint.BlockNum, uint64(2))
   244  	}
   245  
   246  	simulator.Done()
   247  
   248  	//======================================================================================
   249  	//SCENARIO 2: peer fails after committing the third block to state DB
   250  	//but before committing to history DB (if exist)
   251  	//======================================================================================
   252  
   253  	simulator, _ = ledger.NewTxSimulator()
   254  	//simulating transaction
   255  	simulator.SetState("ns1", "key1", []byte("value1.3"))
   256  	simulator.SetState("ns1", "key2", []byte("value2.3"))
   257  	simulator.SetState("ns1", "key3", []byte("value3.3"))
   258  	simulator.Done()
   259  	simRes, _ = simulator.GetTxSimulationResults()
   260  	//generating a block based on the simulation result
   261  	block3 := bg.NextBlock([][]byte{simRes})
   262  	//performing validation of read and write set to find valid transactions
   263  	ledger.(*kvLedger).txtmgmt.ValidateAndPrepare(block3, true)
   264  	//writing the validated block to block storage
   265  	err = ledger.(*kvLedger).blockStore.AddBlock(block3)
   266  	//committing the transaction to state DB
   267  	err = ledger.(*kvLedger).txtmgmt.Commit()
   268  	//assume that peer fails here after committing the transaction to state DB but before
   269  	//history DB
   270  	assert.NoError(t, err)
   271  
   272  	bcInfo, _ = ledger.GetBlockchainInfo()
   273  	block3Hash := block3.Header.Hash()
   274  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
   275  		Height: 4, CurrentBlockHash: block3Hash, PreviousBlockHash: block2Hash})
   276  
   277  	simulator, _ = ledger.NewTxSimulator()
   278  	value, _ = simulator.GetState("ns1", "key1")
   279  	//value for 'key1' should be 'value7'
   280  	testutil.AssertEquals(t, value, []byte("value1.3"))
   281  	value, _ = simulator.GetState("ns1", "key2")
   282  	//value for 'key2' should be 'value8'
   283  	testutil.AssertEquals(t, value, []byte("value2.3"))
   284  	value, _ = simulator.GetState("ns1", "key3")
   285  	//value for 'key3' should be 'value9'
   286  	testutil.AssertEquals(t, value, []byte("value3.3"))
   287  	//savepoint in state DB should 3
   288  	stateDBSavepoint, _ = ledger.(*kvLedger).txtmgmt.GetLastSavepoint()
   289  	testutil.AssertEquals(t, stateDBSavepoint.BlockNum, uint64(3))
   290  
   291  	if ledgerconfig.IsHistoryDBEnabled() == true {
   292  		qhistory, _ := ledger.NewHistoryQueryExecutor()
   293  		itr, _ := qhistory.GetHistoryForKey("ns1", "key1")
   294  		count := 0
   295  		for {
   296  			kmod, err := itr.Next()
   297  			testutil.AssertNoError(t, err, "Error upon Next()")
   298  			if kmod == nil {
   299  				break
   300  			}
   301  			retrievedValue := kmod.(*queryresult.KeyModification).Value
   302  			count++
   303  			expectedValue := []byte("value1." + strconv.Itoa(count))
   304  			testutil.AssertEquals(t, retrievedValue, expectedValue)
   305  		}
   306  		testutil.AssertEquals(t, count, 2)
   307  
   308  		//savepoint in history DB should 2 as the last commit failed
   309  		historyDBSavepoint, _ := ledger.(*kvLedger).historyDB.GetLastSavepoint()
   310  		testutil.AssertEquals(t, historyDBSavepoint.BlockNum, uint64(2))
   311  	}
   312  	simulator.Done()
   313  	ledger.Close()
   314  	provider.Close()
   315  
   316  	//we assume here that the peer comes online and calls NewKVLedger to get a handler for the ledger
   317  	//history DB should be recovered before returning from NewKVLedger call
   318  	provider, _ = NewProvider()
   319  	ledger, _ = provider.Open("testLedger")
   320  	simulator, _ = ledger.NewTxSimulator()
   321  	stateDBSavepoint, _ = ledger.(*kvLedger).txtmgmt.GetLastSavepoint()
   322  	testutil.AssertEquals(t, stateDBSavepoint.BlockNum, uint64(3))
   323  
   324  	if ledgerconfig.IsHistoryDBEnabled() == true {
   325  		qhistory, _ := ledger.NewHistoryQueryExecutor()
   326  		itr, _ := qhistory.GetHistoryForKey("ns1", "key1")
   327  		count := 0
   328  		for {
   329  			kmod, err := itr.Next()
   330  			testutil.AssertNoError(t, err, "Error upon Next()")
   331  			if kmod == nil {
   332  				break
   333  			}
   334  			retrievedValue := kmod.(*queryresult.KeyModification).Value
   335  			count++
   336  			expectedValue := []byte("value1." + strconv.Itoa(count))
   337  			testutil.AssertEquals(t, retrievedValue, expectedValue)
   338  		}
   339  		testutil.AssertEquals(t, count, 3)
   340  
   341  		//savepoint in history DB should 3 after recovery
   342  		historyDBSavepoint, _ := ledger.(*kvLedger).historyDB.GetLastSavepoint()
   343  		testutil.AssertEquals(t, historyDBSavepoint.BlockNum, uint64(3))
   344  	}
   345  	simulator.Done()
   346  
   347  	//Rare scenario
   348  
   349  	//======================================================================================
   350  	//SCENARIO 3: peer fails after committing the fourth block to history DB (if exist)
   351  	//but before committing to state DB
   352  	//======================================================================================
   353  	simulator, _ = ledger.NewTxSimulator()
   354  	//simulating transaction
   355  	simulator.SetState("ns1", "key1", []byte("value1.4"))
   356  	simulator.SetState("ns1", "key2", []byte("value2.4"))
   357  	simulator.SetState("ns1", "key3", []byte("value3.4"))
   358  	simulator.Done()
   359  	simRes, _ = simulator.GetTxSimulationResults()
   360  	//generating a block based on the simulation result
   361  	block4 := bg.NextBlock([][]byte{simRes})
   362  	//performing validation of read and write set to find valid transactions
   363  	ledger.(*kvLedger).txtmgmt.ValidateAndPrepare(block4, true)
   364  	//writing the validated block to block storage but fails to commit to state DB but
   365  	//successfully commits to history DB (if exists)
   366  	err = ledger.(*kvLedger).blockStore.AddBlock(block4)
   367  	if ledgerconfig.IsHistoryDBEnabled() == true {
   368  		err = ledger.(*kvLedger).historyDB.Commit(block4)
   369  	}
   370  	assert.NoError(t, err)
   371  
   372  	bcInfo, _ = ledger.GetBlockchainInfo()
   373  	block4Hash := block4.Header.Hash()
   374  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
   375  		Height: 5, CurrentBlockHash: block4Hash, PreviousBlockHash: block3Hash})
   376  
   377  	simulator, _ = ledger.NewTxSimulator()
   378  	value, _ = simulator.GetState("ns1", "key1")
   379  	//value for 'key1' should be 'value7' as the last commit to State DB failed
   380  	testutil.AssertEquals(t, value, []byte("value1.3"))
   381  	value, _ = simulator.GetState("ns1", "key2")
   382  	//value for 'key2' should be 'value8' as the last commit to State DB failed
   383  	testutil.AssertEquals(t, value, []byte("value2.3"))
   384  	value, _ = simulator.GetState("ns1", "key3")
   385  	//value for 'key3' should be 'value9' as the last commit to State DB failed
   386  	testutil.AssertEquals(t, value, []byte("value3.3"))
   387  	//savepoint in state DB should 3 as the last commit failed
   388  	stateDBSavepoint, _ = ledger.(*kvLedger).txtmgmt.GetLastSavepoint()
   389  	testutil.AssertEquals(t, stateDBSavepoint.BlockNum, uint64(3))
   390  
   391  	if ledgerconfig.IsHistoryDBEnabled() == true {
   392  		qhistory, _ := ledger.NewHistoryQueryExecutor()
   393  		itr, _ := qhistory.GetHistoryForKey("ns1", "key1")
   394  		count := 0
   395  		for {
   396  			kmod, err := itr.Next()
   397  			testutil.AssertNoError(t, err, "Error upon Next()")
   398  			if kmod == nil {
   399  				break
   400  			}
   401  			retrievedValue := kmod.(*queryresult.KeyModification).Value
   402  			count++
   403  			expectedValue := []byte("value1." + strconv.Itoa(count))
   404  			testutil.AssertEquals(t, retrievedValue, expectedValue)
   405  		}
   406  		testutil.AssertEquals(t, count, 4)
   407  		//savepoint in history DB should 4
   408  		historyDBSavepoint, _ := ledger.(*kvLedger).historyDB.GetLastSavepoint()
   409  		testutil.AssertEquals(t, historyDBSavepoint.BlockNum, uint64(4))
   410  	}
   411  	simulator.Done()
   412  	ledger.Close()
   413  	provider.Close()
   414  
   415  	//we assume here that the peer comes online and calls NewKVLedger to get a handler for the ledger
   416  	//state DB should be recovered before returning from NewKVLedger call
   417  	provider, _ = NewProvider()
   418  	ledger, _ = provider.Open("testLedger")
   419  	simulator, _ = ledger.NewTxSimulator()
   420  	value, _ = simulator.GetState("ns1", "key1")
   421  	//value for 'key1' should be 'value10' after state DB recovery
   422  	testutil.AssertEquals(t, value, []byte("value1.4"))
   423  	value, _ = simulator.GetState("ns1", "key2")
   424  	//value for 'key2' should be 'value11' after state DB recovery
   425  	testutil.AssertEquals(t, value, []byte("value2.4"))
   426  	value, _ = simulator.GetState("ns1", "key3")
   427  	//value for 'key3' should be 'value12' after state DB recovery
   428  	testutil.AssertEquals(t, value, []byte("value3.4"))
   429  	//savepoint in state DB should 4 after the recovery
   430  	stateDBSavepoint, _ = ledger.(*kvLedger).txtmgmt.GetLastSavepoint()
   431  	testutil.AssertEquals(t, stateDBSavepoint.BlockNum, uint64(4))
   432  	simulator.Done()
   433  }
   434  
   435  func TestLedgerWithCouchDbEnabledWithBinaryAndJSONData(t *testing.T) {
   436  
   437  	//call a helper method to load the core.yaml
   438  	ledgertestutil.SetupCoreYAMLConfig()
   439  
   440  	logger.Debugf("TestLedgerWithCouchDbEnabledWithBinaryAndJSONData  IsCouchDBEnabled()value: %v , IsHistoryDBEnabled()value: %v\n",
   441  		ledgerconfig.IsCouchDBEnabled(), ledgerconfig.IsHistoryDBEnabled())
   442  
   443  	env := newTestEnv(t)
   444  	defer env.cleanup()
   445  	provider, _ := NewProvider()
   446  	defer provider.Close()
   447  	bg, gb := testutil.NewBlockGenerator(t, "testLedger", false)
   448  	gbHash := gb.Header.Hash()
   449  	ledger, _ := provider.Create(gb)
   450  	defer ledger.Close()
   451  
   452  	bcInfo, _ := ledger.GetBlockchainInfo()
   453  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
   454  		Height: 1, CurrentBlockHash: gbHash, PreviousBlockHash: nil})
   455  
   456  	simulator, _ := ledger.NewTxSimulator()
   457  	simulator.SetState("ns1", "key4", []byte("value1"))
   458  	simulator.SetState("ns1", "key5", []byte("value2"))
   459  	simulator.SetState("ns1", "key6", []byte("{\"shipmentID\":\"161003PKC7300\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091622\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   460  	simulator.SetState("ns1", "key7", []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"AIR MAYBE\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   461  	simulator.Done()
   462  	simRes, _ := simulator.GetTxSimulationResults()
   463  	block1 := bg.NextBlock([][]byte{simRes})
   464  
   465  	ledger.Commit(block1)
   466  
   467  	bcInfo, _ = ledger.GetBlockchainInfo()
   468  	block1Hash := block1.Header.Hash()
   469  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
   470  		Height: 2, CurrentBlockHash: block1Hash, PreviousBlockHash: gbHash})
   471  
   472  	simulationResults := [][]byte{}
   473  	simulator, _ = ledger.NewTxSimulator()
   474  	simulator.SetState("ns1", "key4", []byte("value3"))
   475  	simulator.SetState("ns1", "key5", []byte("{\"shipmentID\":\"161003PKC7500\",\"customsInvoice\":{\"methodOfTransport\":\"AIR FREIGHT\",\"invoiceNumber\":\"00091623\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   476  	simulator.SetState("ns1", "key6", []byte("value4"))
   477  	simulator.SetState("ns1", "key7", []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"GROUND\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   478  	simulator.SetState("ns1", "key8", []byte("{\"shipmentID\":\"161003PKC7700\",\"customsInvoice\":{\"methodOfTransport\":\"SHIP\",\"invoiceNumber\":\"00091625\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   479  	simulator.Done()
   480  	simRes, _ = simulator.GetTxSimulationResults()
   481  	simulationResults = append(simulationResults, simRes)
   482  	//add a 2nd transaction
   483  	simulator2, _ := ledger.NewTxSimulator()
   484  	simulator2.SetState("ns1", "key7", []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"TRAIN\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   485  	simulator2.SetState("ns1", "key9", []byte("value5"))
   486  	simulator2.SetState("ns1", "key10", []byte("{\"shipmentID\":\"261003PKC8000\",\"customsInvoice\":{\"methodOfTransport\":\"DONKEY\",\"invoiceNumber\":\"00091626\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}"))
   487  	simulator2.Done()
   488  	simRes2, _ := simulator2.GetTxSimulationResults()
   489  	simulationResults = append(simulationResults, simRes2)
   490  
   491  	block2 := bg.NextBlock(simulationResults)
   492  	ledger.Commit(block2)
   493  
   494  	bcInfo, _ = ledger.GetBlockchainInfo()
   495  	block2Hash := block2.Header.Hash()
   496  	testutil.AssertEquals(t, bcInfo, &common.BlockchainInfo{
   497  		Height: 3, CurrentBlockHash: block2Hash, PreviousBlockHash: block1Hash})
   498  
   499  	b0, _ := ledger.GetBlockByHash(gbHash)
   500  	testutil.AssertEquals(t, b0, gb)
   501  
   502  	b1, _ := ledger.GetBlockByHash(block1Hash)
   503  	testutil.AssertEquals(t, b1, block1)
   504  
   505  	b2, _ := ledger.GetBlockByHash(block2Hash)
   506  	testutil.AssertEquals(t, b2, block2)
   507  
   508  	b0, _ = ledger.GetBlockByNumber(0)
   509  	testutil.AssertEquals(t, b0, gb)
   510  
   511  	b1, _ = ledger.GetBlockByNumber(1)
   512  	testutil.AssertEquals(t, b1, block1)
   513  
   514  	b2, _ = ledger.GetBlockByNumber(2)
   515  	testutil.AssertEquals(t, b2, block2)
   516  
   517  	//Similar test has been pushed down to historyleveldb_test.go as well
   518  	if ledgerconfig.IsHistoryDBEnabled() == true {
   519  		logger.Debugf("History is enabled\n")
   520  		qhistory, err := ledger.NewHistoryQueryExecutor()
   521  		testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to retrieve history database executor"))
   522  
   523  		itr, err2 := qhistory.GetHistoryForKey("ns1", "key7")
   524  		testutil.AssertNoError(t, err2, fmt.Sprintf("Error upon GetHistoryForKey"))
   525  
   526  		var retrievedValue []byte
   527  		count := 0
   528  		for {
   529  			kmod, _ := itr.Next()
   530  			if kmod == nil {
   531  				break
   532  			}
   533  			retrievedValue = kmod.(*queryresult.KeyModification).Value
   534  			count++
   535  		}
   536  		testutil.AssertEquals(t, count, 3)
   537  		// test the last value in the history matches the last value set for key7
   538  		expectedValue := []byte("{\"shipmentID\":\"161003PKC7600\",\"customsInvoice\":{\"methodOfTransport\":\"TRAIN\",\"invoiceNumber\":\"00091624\"},\"weightUnitOfMeasure\":\"KGM\",\"volumeUnitOfMeasure\": \"CO\",\"dimensionUnitOfMeasure\":\"CM\",\"currency\":\"USD\"}")
   539  		testutil.AssertEquals(t, retrievedValue, expectedValue)
   540  
   541  	}
   542  }