func (h *Host) managedLogError(err error) {
	var num uint64
	var probability int  
	switch err.(type) {
	case ErrorCommunication:
		num = atomic.LoadUint64(&h.atomicCommunicationErrors)
		probability = errorCommunicationProbability
	case ErrorConnection:
		num = atomic.LoadUint64(&h.atomicConnectionErrors)
		probability = errorConnectionProbability
	case ErrorConsensus:
		num = atomic.LoadUint64(&h.atomicConsensusErrors)
		probability = errorConsensusProbability
	case ErrorInternal:
		num = atomic.LoadUint64(&h.atomicInternalErrors)
		probability = errorInternalProbability
	default:
		num = atomic.LoadUint64(&h.atomicNormalErrors)
		probability = errorNormalProbability
	}
	if num > logFewLimit {
		probability = probability * 25
	}
	shouldLog := num < logAllLimit || fastrand.Intn(probability+1) == probability
	if shouldLog {
		h.log.Println(err)
	} else {
		h.log.Debugln(err)
		return
	}
	switch err.(type) {
	case ErrorCommunication:
		atomic.AddUint64(&h.atomicCommunicationErrors, 1)
	case ErrorConnection:
		atomic.AddUint64(&h.atomicConnectionErrors, 1)
	case ErrorConsensus:
		atomic.AddUint64(&h.atomicConsensusErrors, 1)
	case ErrorInternal:
		atomic.AddUint64(&h.atomicInternalErrors, 1)
	default:
		atomic.AddUint64(&h.atomicNormalErrors, 1)
	}
}
mangedLogError will take an error and log it to the host, depending on the
type of error and whether or not the DEBUG flag has been set.
package host
import (
	"errors"
	"strings"
	"sync/atomic"
	"github.com/NebulousLabs/fastrand"
)
const (
	errorCommunicationProbability = 5
	errorConnectionProbability    = 20
	errorConsensusProbability     = 1
	errorInternalProbability      = 3
	errorNormalProbability        = 20
)
type (
	ErrorCommunication string
	ErrorConnection string
	ErrorConsensus string
	ErrorInternal string
)
func composeErrors(errs ...error) error {
	var errStrings []string
	for _, err := range errs {
		if err != nil {
			errStrings = append(errStrings, err.Error())
		}
	}
	if len(errStrings) <= 0 {
		return nil
	}
	return errors.New(strings.Join(errStrings, "; "))
}
func extendErr(s string, err error) error {
	if err == nil {
		return nil
	}
	switch v := err.(type) {
	case ErrorCommunication:
		return ErrorCommunication(s) + v
	case ErrorConnection:
		return ErrorConnection(s) + v
	case ErrorConsensus:
		return ErrorConsensus(s) + v
	case ErrorInternal:
		return ErrorInternal(s) + v
	default:
		return errors.New(s + err.Error())
	}
}
func (ec ErrorCommunication) Error() string {
	return "communication error: " + string(ec)
}
func (ec ErrorConnection) Error() string {
	return "connection error: " + string(ec)
}
func (ec ErrorConsensus) Error() string {
	return "consensus error: " + string(ec)
}
func (ec ErrorInternal) Error() string {
	return "internal error: " + string(ec)
}