예제 #1
0
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
}
예제 #2
0
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
}