github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/committer/committer_impl.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 committer 18 19 import ( 20 "github.com/hyperledger/fabric/common/flogging" 21 "github.com/hyperledger/fabric/core/committer/txvalidator" 22 "github.com/hyperledger/fabric/core/ledger" 23 "github.com/hyperledger/fabric/events/producer" 24 "github.com/hyperledger/fabric/protos/common" 25 "github.com/op/go-logging" 26 ) 27 28 //--------!!!IMPORTANT!!-!!IMPORTANT!!-!!IMPORTANT!!--------- 29 // This is used merely to complete the loop for the "skeleton" 30 // path so we can reason about and modify committer component 31 // more effectively using code. 32 33 var logger *logging.Logger // package-level logger 34 35 func init() { 36 logger = flogging.MustGetLogger("committer") 37 } 38 39 // LedgerCommitter is the implementation of Committer interface 40 // it keeps the reference to the ledger to commit blocks and retreive 41 // chain information 42 type LedgerCommitter struct { 43 ledger ledger.PeerLedger 44 validator txvalidator.Validator 45 } 46 47 // NewLedgerCommitter is a factory function to create an instance of the committer 48 func NewLedgerCommitter(ledger ledger.PeerLedger, validator txvalidator.Validator) *LedgerCommitter { 49 return &LedgerCommitter{ledger: ledger, validator: validator} 50 } 51 52 // Commit commits block to into the ledger 53 // Note, it is important that this always be called serially 54 func (lc *LedgerCommitter) Commit(block *common.Block) error { 55 // Validate and mark invalid transactions 56 logger.Debug("Validating block") 57 if err := lc.validator.Validate(block); err != nil { 58 return err 59 } 60 61 if err := lc.ledger.Commit(block); err != nil { 62 return err 63 } 64 65 // send block event *after* the block has been committed 66 if err := producer.SendProducerBlockEvent(block); err != nil { 67 logger.Errorf("Error publishing block %d, because: %v", block.Header.Number, err) 68 } 69 70 return nil 71 } 72 73 // LedgerHeight returns recently committed block sequence number 74 func (lc *LedgerCommitter) LedgerHeight() (uint64, error) { 75 var info *common.BlockchainInfo 76 var err error 77 if info, err = lc.ledger.GetBlockchainInfo(); err != nil { 78 logger.Errorf("Cannot get blockchain info, %s\n", info) 79 return uint64(0), err 80 } 81 82 return info.Height, nil 83 } 84 85 // GetBlocks used to retrieve blocks with sequence numbers provided in the slice 86 func (lc *LedgerCommitter) GetBlocks(blockSeqs []uint64) []*common.Block { 87 var blocks []*common.Block 88 89 for _, seqNum := range blockSeqs { 90 if blck, err := lc.ledger.GetBlockByNumber(seqNum); err != nil { 91 logger.Errorf("Not able to acquire block num %d, from the ledger skipping...\n", seqNum) 92 continue 93 } else { 94 logger.Debug("Appending next block with seqNum = ", seqNum, " to the resulting set") 95 blocks = append(blocks, blck) 96 } 97 } 98 99 return blocks 100 } 101 102 // Close the ledger 103 func (lc *LedgerCommitter) Close() { 104 lc.ledger.Close() 105 }