github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/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 original 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{})
   123  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockHash})
   124  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockNum})
   125  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrTxID})
   126  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockNumTranNum})
   127  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockHash, blkstorage.IndexableAttrBlockNum})
   128  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrTxID, blkstorage.IndexableAttrBlockNumTranNum})
   129  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrBlockTxID})
   130  	testBlockIndexSelectiveIndexing(t, []blkstorage.IndexableAttr{blkstorage.IndexableAttrTxValidationCode})
   131  }
   132  
   133  func testBlockIndexSelectiveIndexing(t *testing.T, indexItems []blkstorage.IndexableAttr) {
   134  	var testName string
   135  	for _, s := range indexItems {
   136  		testName = testName + string(s)
   137  	}
   138  	t.Run(testName, func(t *testing.T) {
   139  		env := newTestEnvSelectiveIndexing(t, NewConf(testPath(), 0), indexItems)
   140  		defer env.Cleanup()
   141  		blkfileMgrWrapper := newTestBlockfileWrapper(env, "testledger")
   142  		defer blkfileMgrWrapper.close()
   143  
   144  		blocks := testutil.ConstructTestBlocks(t, 3)
   145  		// add test blocks
   146  		blkfileMgrWrapper.addBlocks(blocks)
   147  		blockfileMgr := blkfileMgrWrapper.blockfileMgr
   148  
   149  		// if index has been configured for an indexItem then the item should be indexed else not
   150  		// test 'retrieveBlockByHash'
   151  		block, err := blockfileMgr.retrieveBlockByHash(blocks[0].Header.Hash())
   152  		if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockHash) {
   153  			testutil.AssertNoError(t, err, "Error while retrieving block by hash")
   154  			testutil.AssertEquals(t, block, blocks[0])
   155  		} else {
   156  			testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   157  		}
   158  
   159  		// test 'retrieveBlockByNumber'
   160  		block, err = blockfileMgr.retrieveBlockByNumber(0)
   161  		if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockNum) {
   162  			testutil.AssertNoError(t, err, "Error while retrieving block by number")
   163  			testutil.AssertEquals(t, block, blocks[0])
   164  		} else {
   165  			testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   166  		}
   167  
   168  		// test 'retrieveTransactionByID'
   169  		txid, err := extractTxID(blocks[0].Data.Data[0])
   170  		testutil.AssertNoError(t, err, "")
   171  		txEnvelope, err := blockfileMgr.retrieveTransactionByID(txid)
   172  		if testutil.Contains(indexItems, blkstorage.IndexableAttrTxID) {
   173  			testutil.AssertNoError(t, err, "Error while retrieving tx by id")
   174  			txEnvelopeBytes := blocks[0].Data.Data[0]
   175  			txEnvelopeOrig, err := putil.GetEnvelopeFromBlock(txEnvelopeBytes)
   176  			testutil.AssertNoError(t, err, "")
   177  			testutil.AssertEquals(t, txEnvelope, txEnvelopeOrig)
   178  		} else {
   179  			testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   180  		}
   181  
   182  		//test 'retrieveTrasnactionsByBlockNumTranNum
   183  		txEnvelope2, err := blockfileMgr.retrieveTransactionByBlockNumTranNum(0, 0)
   184  		if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockNumTranNum) {
   185  			testutil.AssertNoError(t, err, "Error while retrieving tx by blockNum and tranNum")
   186  			txEnvelopeBytes2 := blocks[0].Data.Data[0]
   187  			txEnvelopeOrig2, err2 := putil.GetEnvelopeFromBlock(txEnvelopeBytes2)
   188  			testutil.AssertNoError(t, err2, "")
   189  			testutil.AssertEquals(t, txEnvelope2, txEnvelopeOrig2)
   190  		} else {
   191  			testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   192  		}
   193  
   194  		// test 'retrieveBlockByTxID'
   195  		txid, err = extractTxID(blocks[0].Data.Data[0])
   196  		testutil.AssertNoError(t, err, "")
   197  		block, err = blockfileMgr.retrieveBlockByTxID(txid)
   198  		if testutil.Contains(indexItems, blkstorage.IndexableAttrBlockTxID) {
   199  			testutil.AssertNoError(t, err, "Error while retrieving block by txID")
   200  			testutil.AssertEquals(t, blocks[0], block)
   201  		} else {
   202  			testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   203  		}
   204  
   205  		for _, block := range blocks {
   206  			flags := util.TxValidationFlags(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
   207  
   208  			for idx, d := range block.Data.Data {
   209  				txid, err = extractTxID(d)
   210  				testutil.AssertNoError(t, err, "")
   211  
   212  				reason, err := blockfileMgr.retrieveTxValidationCodeByTxID(txid)
   213  
   214  				if testutil.Contains(indexItems, blkstorage.IndexableAttrTxValidationCode) {
   215  					testutil.AssertNoError(t, err, "Error while retrieving tx validation code by txID")
   216  
   217  					reasonFromFlags := flags.Flag(idx)
   218  
   219  					testutil.AssertEquals(t, reason, reasonFromFlags)
   220  				} else {
   221  					testutil.AssertSame(t, err, blkstorage.ErrAttrNotIndexed)
   222  				}
   223  			}
   224  		}
   225  	})
   226  }