github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/common/ledger/blkstorage/fsblkstorage/blockindex_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 fsblkstorage
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"github.com/hyperledger/fabric/common/ledger/blkstorage"
    24  	"github.com/hyperledger/fabric/common/ledger/testutil"
    25  	"github.com/hyperledger/fabric/core/ledger/util"
    26  	"github.com/hyperledger/fabric/protos/common"
    27  	"github.com/hyperledger/fabric/protos/peer"
    28  	putil "github.com/hyperledger/fabric/protos/utils"
    29  )
    30  
    31  type noopIndex struct {
    32  }
    33  
    34  func (i *noopIndex) getLastBlockIndexed() (uint64, error) {
    35  	return 0, nil
    36  }
    37  func (i *noopIndex) indexBlock(blockIdxInfo *blockIdxInfo) error {
    38  	return nil
    39  }
    40  func (i *noopIndex) getBlockLocByHash(blockHash []byte) (*fileLocPointer, error) {
    41  	return nil, nil
    42  }
    43  func (i *noopIndex) getBlockLocByBlockNum(blockNum uint64) (*fileLocPointer, error) {
    44  	return nil, nil
    45  }
    46  func (i *noopIndex) getTxLoc(txID string) (*fileLocPointer, error) {
    47  	return nil, nil
    48  }
    49  func (i *noopIndex) getTXLocByBlockNumTranNum(blockNum uint64, tranNum uint64) (*fileLocPointer, error) {
    50  	return nil, nil
    51  }
    52  
    53  func (i *noopIndex) getBlockLocByTxID(txID string) (*fileLocPointer, error) {
    54  	return nil, nil
    55  }
    56  
    57  func (i *noopIndex) getTxValidationCodeByTxID(txID string) (peer.TxValidationCode, error) {
    58  	return peer.TxValidationCode(-1), nil
    59  }
    60  
    61  func TestBlockIndexSync(t *testing.T) {
    62  	testBlockIndexSync(t, 10, 5, false)
    63  	testBlockIndexSync(t, 10, 5, true)
    64  	testBlockIndexSync(t, 10, 0, true)
    65  	testBlockIndexSync(t, 10, 10, true)
    66  }
    67  
    68  func testBlockIndexSync(t *testing.T, numBlocks int, numBlocksToIndex int, syncByRestart bool) {
    69  	testName := fmt.Sprintf("%v/%v/%v", numBlocks, numBlocksToIndex, syncByRestart)
    70  	t.Run(testName, func(t *testing.T) {
    71  		env := newTestEnv(t, NewConf(testPath(), 0))
    72  		defer env.Cleanup()
    73  		ledgerid := "testledger"
    74  		blkfileMgrWrapper := newTestBlockfileWrapper(env, ledgerid)
    75  		defer blkfileMgrWrapper.close()
    76  		blkfileMgr := blkfileMgrWrapper.blockfileMgr
    77  		origIndex := blkfileMgr.index
    78  		// construct blocks for testing
    79  		blocks := testutil.ConstructTestBlocks(t, numBlocks)
    80  		// add a few blocks
    81  		blkfileMgrWrapper.addBlocks(blocks[:numBlocksToIndex])
    82  
    83  		// Plug-in a noop index and add remaining blocks
    84  		blkfileMgr.index = &noopIndex{}
    85  		blkfileMgrWrapper.addBlocks(blocks[numBlocksToIndex:])
    86  
    87  		// Plug-in back the original index
    88  		blkfileMgr.index = origIndex
    89  		// The first set of blocks should be present in the orginal index
    90  		for i := 0; i < numBlocksToIndex; i++ {
    91  			block, err := blkfileMgr.retrieveBlockByNumber(uint64(i))
    92  			testutil.AssertNoError(t, err, fmt.Sprintf("block [%d] should have been present in the index", i))
    93  			testutil.AssertEquals(t, block, blocks[i])
    94  		}
    95  
    96  		// The last set of blocks should not be present in the original index
    97  		for i := numBlocksToIndex + 1; i <= numBlocks; i++ {
    98  			_, err := blkfileMgr.retrieveBlockByNumber(uint64(i))
    99  			testutil.AssertSame(t, err, blkstorage.ErrNotFoundInIndex)
   100  		}
   101  
   102  		// perform index sync
   103  		if syncByRestart {
   104  			blkfileMgrWrapper.close()
   105  			blkfileMgrWrapper = newTestBlockfileWrapper(env, ledgerid)
   106  			defer blkfileMgrWrapper.close()
   107  			blkfileMgr = blkfileMgrWrapper.blockfileMgr
   108  		} else {
   109  			blkfileMgr.syncIndex()
   110  		}
   111  
   112  		// Now, last set of blocks should also be present in original index
   113  		for i := numBlocksToIndex; i < numBlocks; i++ {
   114  			block, err := blkfileMgr.retrieveBlockByNumber(uint64(i))
   115  			testutil.AssertNoError(t, err, fmt.Sprintf("block [%d] should have been present in the index", i))
   116  			testutil.AssertEquals(t, block, blocks[i])
   117  		}
   118  	})
   119  }
   120  
   121  func TestBlockIndexSelectiveIndexing(t *testing.T) {
   122  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockHash})
   123  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockNum})
   124  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrTxID})
   125  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockNumTranNum})
   126  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockHash, blkstorage.IndexableAttrBlockNum})
   127  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrTxID, blkstorage.IndexableAttrBlockNumTranNum})
   128  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockTxID})
   129  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrTxValidationCode})
   130  }
   131  
   132  func testBlockIndexSelectiveIndexing(t *testing.T, indexItems []blkstorage.IndexableAttr) {
   133  	var testName string
   134  	for _, s := range indexItems {
   135  		testName = testName + string(s)
   136  	}
   137  	t.Run(testName, func(t *testing.T) {
   138  		env := newTestEnvSelectiveIndexing(t, NewConf(testPath(), 0), indexItems)
   139  		defer env.Cleanup()
   140  		blkfileMgrWrapper := newTestBlockfileWrapper(env, "testledger")
   141  		defer blkfileMgrWrapper.close()
   142  
   143  		blocks := testutil.ConstructTestBlocks(t, 3)
   144  		// add test blocks
   145  		blkfileMgrWrapper.addBlocks(blocks)
   146  		blockfileMgr := blkfileMgrWrapper.blockfileMgr
   147  
   148  		// if index has been configured for an indexItem then the item should be indexed else not
   149  		// test 'retrieveBlockByHash'
   150  		block, err := blockfileMgr.retrieveBlockByHash(blocks[0].Header.Hash())
   151  		if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockHash) {
   152  			testutil.AssertNoError(t, err, "Error while retrieving block by hash")
   153  			testutil.AssertEquals(t, block, blocks[0])
   154  		} else {
   155  			testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   156  		}
   157  
   158  		// test 'retrieveBlockByNumber'
   159  		block, err = blockfileMgr.retrieveBlockByNumber(0)
   160  		if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockNum) {
   161  			testutil.AssertNoError(t, err, "Error while retrieving block by number")
   162  			testutil.AssertEquals(t, block, blocks[0])
   163  		} else {
   164  			testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   165  		}
   166  
   167  		// test 'retrieveTransactionByID'
   168  		txid, err := extractTxID(blocks[0].Data.Data[0])
   169  		testutil.AssertNoError(t, err, "")
   170  		txEnvelope, err := blockfileMgr.retrieveTransactionByID(txid)
   171  		if testutil.Contains(indexItems, blkstorage.IndexableAttrTxID) {
   172  			testutil.AssertNoError(t, err, "Error while retrieving tx by id")
   173  			txEnvelopeBytes := blocks[0].Data.Data[0]
   174  			txEnvelopeOrig, err := putil.GetEnvelopeFromBlock(txEnvelopeBytes)
   175  			testutil.AssertNoError(t, err, "")
   176  			testutil.AssertEquals(t, txEnvelope, txEnvelopeOrig)
   177  		} else {
   178  			testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   179  		}
   180  
   181  		//test 'retrieveTrasnactionsByBlockNumTranNum
   182  		txEnvelope2, err := blockfileMgr.retrieveTransactionByBlockNumTranNum(0, 0)
   183  		if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockNumTranNum) {
   184  			testutil.AssertNoError(t, err, "Error while retrieving tx by blockNum and tranNum")
   185  			txEnvelopeBytes2 := blocks[0].Data.Data[0]
   186  			txEnvelopeOrig2, err2 := putil.GetEnvelopeFromBlock(txEnvelopeBytes2)
   187  			testutil.AssertNoError(t, err2, "")
   188  			testutil.AssertEquals(t, txEnvelope2, txEnvelopeOrig2)
   189  		} else {
   190  			testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   191  		}
   192  
   193  		// test 'retrieveBlockByTxID'
   194  		txid, err = extractTxID(blocks[0].Data.Data[0])
   195  		testutil.AssertNoError(t, err, "")
   196  		block, err = blockfileMgr.retrieveBlockByTxID(txid)
   197  		if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockTxID) {
   198  			testutil.AssertNoError(t, err, "Error while retrieving block by txID")
   199  			testutil.AssertEquals(t, blocks[0], block)
   200  		} else {
   201  			testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   202  		}
   203  
   204  		for _, block := range blocks {
   205  			flags := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
   206  
   207  			for idx, d := range block.Data.Data {
   208  				txid, err = extractTxID(d)
   209  				testutil.AssertNoError(t, err, "")
   210  
   211  				reason, err := blockfileMgr.retrieveTxValidationCodeByTxID(txid)
   212  
   213  				if testutil.Contains(indexItems, blkstorage.IndexableAttrTxValidationCode) {
   214  					testutil.AssertNoError(t, err, "Error while retrieving tx validation code by txID")
   215  
   216  					reasonFromFlags := flags.Flag(idx)
   217  
   218  					testutil.AssertEquals(t, reason, reasonFromFlags)
   219  				} else {
   220  					testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   221  				}
   222  			}
   223  		}
   224  	})
   225  }