github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/orderer/sbft/consenter.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 sbft 18 19 import ( 20 "github.com/hyperledger/fabric/orderer/multichain" 21 "github.com/hyperledger/fabric/orderer/sbft/backend" 22 "github.com/hyperledger/fabric/orderer/sbft/connection" 23 "github.com/hyperledger/fabric/orderer/sbft/persist" 24 "github.com/hyperledger/fabric/orderer/sbft/simplebft" 25 cb "github.com/hyperledger/fabric/protos/common" 26 "github.com/op/go-logging" 27 ) 28 29 type consensusStack struct { 30 persist *persist.Persist 31 backend *backend.Backend 32 } 33 34 var logger = logging.MustGetLogger("orderer/main") 35 36 // Consenter interface implementation for new main application 37 type consenter struct { 38 config *ConsensusConfig 39 consensusStack *consensusStack 40 sbftStackConfig *backend.StackConfig 41 sbftPeers map[string]*simplebft.SBFT 42 } 43 44 type chain struct { 45 chainID string 46 consensusStack *consensusStack 47 } 48 49 // New creates a new consenter for the SBFT consensus scheme. 50 // It accepts messages being delivered via Enqueue, orders them, and then uses the blockcutter to form the messages 51 // into blocks before writing to the given ledger. 52 func New(c *ConsensusConfig, sc *backend.StackConfig) multichain.Consenter { 53 return &consenter{config: c, sbftStackConfig: sc} 54 } 55 56 func (sbft *consenter) HandleChain(support multichain.ConsenterSupport, metadata *cb.Metadata) (multichain.Chain, error) { 57 return newChain(sbft, support), nil 58 } 59 60 func newChain(sbft *consenter, support multichain.ConsenterSupport) *chain { 61 logger.Infof("Starting a chain: %d", support.ChainID()) 62 63 if sbft.sbftPeers == nil { 64 sbft.consensusStack = createConsensusStack(sbft) 65 sbft.sbftPeers = make(map[string]*simplebft.SBFT) 66 } 67 sbft.sbftPeers[support.ChainID()] = initSbftPeer(support.ChainID(), sbft, support) 68 69 return &chain{ 70 chainID: support.ChainID(), 71 consensusStack: sbft.consensusStack, 72 } 73 } 74 75 func createConsensusStack(sbft *consenter) *consensusStack { 76 logger.Infof("%v %v %v", sbft.sbftStackConfig.ListenAddr, sbft.sbftStackConfig.CertFile, sbft.sbftStackConfig.KeyFile) 77 conn, err := connection.New(sbft.sbftStackConfig.ListenAddr, sbft.sbftStackConfig.CertFile, sbft.sbftStackConfig.KeyFile) 78 if err != nil { 79 logger.Errorf("Error when trying to connect: %s", err) 80 panic(err) 81 } 82 persist := persist.New(sbft.sbftStackConfig.DataDir) 83 backend, err := backend.NewBackend(sbft.config.Peers, conn, persist) 84 if err != nil { 85 logger.Errorf("Backend instantiation error.") 86 panic(err) 87 } 88 return &consensusStack{ 89 backend: backend, 90 persist: persist, 91 } 92 } 93 94 func initSbftPeer(chainID string, sbft *consenter, support multichain.ConsenterSupport) *simplebft.SBFT { 95 sbftPeer, err := sbft.consensusStack.backend.AddSbftPeer(support.ChainID(), support, sbft.config.Consensus) 96 if err != nil { 97 logger.Errorf("SBFT peer instantiation error.") 98 panic(err) 99 } 100 return sbftPeer 101 } 102 103 // Chain interface implementation: 104 105 // Start allocates the necessary resources for staying up to date with this Chain. 106 // It implements the multichain.Chain interface. It is called by multichain.NewManagerImpl() 107 // which is invoked when the ordering process is launched, before the call to NewServer(). 108 func (ch *chain) Start() { 109 110 } 111 112 // Halt frees the resources which were allocated for this Chain 113 func (ch *chain) Halt() { 114 panic("There is no way to halt SBFT") 115 } 116 117 // Enqueue accepts a message and returns true on acceptance, or false on shutdown 118 func (ch *chain) Enqueue(env *cb.Envelope) bool { 119 return ch.consensusStack.backend.Enqueue(ch.chainID, env) 120 }