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