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 }