func NewOBCExecutor(config *viper.Viper, orderer Orderer, stack statetransfer.PartialStack) (obcex *obcExecutor) { var err error obcex = &obcExecutor{} queueSize := config.GetInt("executor.queuesize") if queueSize <= 0 { panic("Queue size must be positive") } obcex.executionQueue = make(chan *transaction, queueSize) obcex.syncTargets = make(chan *syncTarget) obcex.completeSync = make(chan *syncTarget) obcex.threadIdle = make(chan struct{}) obcex.threadExit = make(chan struct{}) obcex.orderer = orderer obcex.executorStack = stack obcex.id, _, err = stack.GetNetworkHandles() if nil != err { logger.Error("Could not resolve our own PeerID, assigning dummy") obcex.id = &pb.PeerID{"Dummy"} } logger.Info("Executor for %v using queue size of %d", obcex.id, queueSize) obcex.sts = statetransfer.NewStateTransferState(config, stack) listener := struct{ statetransfer.ProtoListener }{} listener.CompletedImpl = obcex.stateTransferCompleted obcex.sts.RegisterListener(&listener) go obcex.queueThread() return }
func newPbftCore(id uint64, config *viper.Viper, consumer innerStack, ledger consensus.LedgerStack) *pbftCore { var err error instance := &pbftCore{} instance.id = id instance.consumer = consumer instance.ledger = ledger instance.closed = make(chan bool) instance.notifyCommit = make(chan bool, 1) instance.notifyExec = sync.NewCond(&instance.internalLock) instance.N = config.GetInt("general.N") instance.f = config.GetInt("general.f") if instance.f*3+1 > instance.N { panic(fmt.Sprintf("need at least %d enough replicas to tolerate %d byzantine faults, but only %d replicas configured", instance.f*3+1, instance.f, instance.N)) } instance.K = uint64(config.GetInt("general.K")) instance.byzantine = config.GetBool("general.byzantine") instance.requestTimeout, err = time.ParseDuration(config.GetString("general.timeout.request")) if err != nil { panic(fmt.Errorf("Cannot parse request timeout: %s", err)) } instance.newViewTimeout, err = time.ParseDuration(config.GetString("general.timeout.viewchange")) if err != nil { panic(fmt.Errorf("Cannot parse new view timeout: %s", err)) } instance.activeView = true instance.L = 2 * instance.K // log size instance.replicaCount = instance.N // init the logs instance.certStore = make(map[msgID]*msgCert) instance.reqStore = make(map[string]*Request) instance.checkpointStore = make(map[Checkpoint]bool) instance.chkpts = make(map[uint64]*blockState) instance.viewChangeStore = make(map[vcidx]*ViewChange) instance.pset = make(map[uint64]*ViewChange_PQ) instance.qset = make(map[qidx]*ViewChange_PQ) instance.newViewStore = make(map[uint64]*NewView) // initialize state transfer instance.hChkpts = make(map[uint64]uint64) defaultPeerIDs := make([]*protos.PeerID, instance.replicaCount-1) if instance.replicaCount > 1 { // For some tests, only 1 replica will be present, and defaultPeerIDs makes no sense for i := uint64(0); i < uint64(instance.replicaCount); i++ { handle, err := getValidatorHandle(i) if err != nil { panic(fmt.Errorf("Cannot retrieve handle for peer which must exist : %s", err)) } if i < instance.id { logger.Debug("Replica %d assigning %v to index %d for replicaCount %d and id %d", instance.id, handle, i, instance.replicaCount, instance.id) defaultPeerIDs[i] = handle } else if i > instance.id { logger.Debug("Replica %d assigning %v to index %d for replicaCount %d and id %d", instance.id, handle, i-1, instance.replicaCount, instance.id) defaultPeerIDs[i-1] = handle } else { // This is our ID, do not add it to the list of default peers } } } else { logger.Debug("Replica %d not initializing defaultPeerIDs, as replicaCount is %d", instance.id, instance.replicaCount) } if myHandle, err := getValidatorHandle(instance.id); err != nil { panic("Could not retrieve own handle") } else { instance.sts = statetransfer.NewStateTransferState(myHandle, config, ledger, defaultPeerIDs) } listener := struct{ statetransfer.ProtoListener }{} listener.CompletedImpl = instance.stateTransferCompleted instance.sts.RegisterListener(&listener) // load genesis checkpoint genesisBlock, err := instance.ledger.GetBlock(0) if err != nil { panic(fmt.Errorf("Cannot load genesis block: %s", err)) } genesisHash, err := ledger.HashBlock(genesisBlock) if err != nil { panic(fmt.Errorf("Cannot hash genesis block: %s", err)) } instance.chkpts[0] = &blockState{ blockNumber: 0, blockHash: base64.StdEncoding.EncodeToString(genesisHash), } // create non-running timer XXX ugly instance.newViewTimer = time.NewTimer(100 * time.Hour) instance.newViewTimer.Stop() instance.timerResetCount = 1 instance.lastNewViewTimeout = instance.newViewTimeout instance.outstandingReqs = make(map[string]*Request) instance.missingReqs = make(map[string]bool) go instance.timerHander() go instance.executeRoutine() return instance }