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 }