func IsTLSCert(block string) bool {
	var cert tls.Certificate

	pemBlock := []byte(block)

	for {
		var derBlock *pem.Block
		derBlock, pemBlock = pem.Decode(pemBlock)
		if derBlock == nil {
			break
		}

		if derBlock.Type == certificate {
			cert.Certificate =
				append(cert.Certificate, derBlock.Bytes)
		}
	}

	if len(cert.Certificate) == 0 {
		return false
	}

	return true
}

func IsTLSCert ( block string ) bool { var cert tls . Certificate pemBlock := [ ] byte ( block ) for { var derBlock * pem . Block derBlock , pemBlock = pem . Decode ( pemBlock ) if derBlock == nil { break } if derBlock . Type == certificate { cert . Certificate = append ( cert . Certificate , derBlock . Bytes ) } } if len ( cert . Certificate ) == 0 { return false } return true }

// IsTLSCert if block is one or more
// TLS certificates then function returns true

IsTLSCert if block is one or more TLS certificates then function returns true


func ValidateJSON(schema, data []byte) bool {
	sloader := gojsonschema.NewBytesLoader(schema)
	dloader := gojsonschema.NewBytesLoader(data)
	result, err := gojsonschema.Validate(sloader, dloader)
	return err == nil && result.Valid() && len(result.Errors()) == 0
}

func ValidateJSON ( schema , data [ ] byte ) bool { sloader := gojsonschema . NewBytesLoader ( schema ) dloader := gojsonschema . NewBytesLoader ( data ) result , err := gojsonschema . Validate ( sloader , dloader ) return err == nil && result . Valid ( ) && len ( result . Errors ( ) ) == 0 }

// ValidateJSON validates a given JSON against a given schema.

ValidateJSON validates a given JSON against a given schema .


func NewConfig() *Config {
	return &Config{
		CheckTimeout: 20000,
		Timeout:      10000,
		HTTPClient: &httpClientConf{
			DialTimeout:           5,
			TLSHandshakeTimeout:   2,
			ResponseHeaderTimeout: 8,
			RequestTimeout:        10,
			IdleConnTimeout:       30,
			KeepAliveTimeout:      60,
		},
	}
}

func NewConfig ( ) * Config { return & Config { CheckTimeout : 20000 , Timeout : 10000 , HTTPClient : & httpClientConf { DialTimeout : 5 , TLSHandshakeTimeout : 2 , ResponseHeaderTimeout : 8 , RequestTimeout : 10 , IdleConnTimeout : 30 , KeepAliveTimeout : 60 , } , } }

// NewConfig creates a default Ethereum client configuration.

NewConfig creates a default Ethereum client configuration .


func ReadJSONFile(name string, data interface{}) error {
	file, err := os.Open(name)
	if err != nil {
		return err
	}
	defer file.Close()

	return json.NewDecoder(file).Decode(data)
}

func ReadJSONFile ( name string , data interface { } ) error { file , err := os . Open ( name ) if err != nil { return err } defer file . Close ( ) return json . NewDecoder ( file ) . Decode ( data ) }

// ReadJSONFile reads and parses a JSON file filling a given data instance.

ReadJSONFile reads and parses a JSON file filling a given data instance .


func WriteJSONFile(name, prefix, indent string, data interface{}) error {
	file, err := os.Create(name)
	if err != nil {
		return err
	}
	defer file.Close()

	enc := json.NewEncoder(file)
	enc.SetIndent(prefix, indent)
	return enc.Encode(data)
}

func WriteJSONFile ( name , prefix , indent string , data interface { } ) error { file , err := os . Create ( name ) if err != nil { return err } defer file . Close ( ) enc := json . NewEncoder ( file ) enc . SetIndent ( prefix , indent ) return enc . Encode ( data ) }

// WriteJSONFile converts a given data instance to JSON and writes it to file.

WriteJSONFile converts a given data instance to JSON and writes it to file .


func IsUUID(s string) bool {
	_, err := uuid.FromString(s)
	return err == nil
}

func IsUUID ( s string ) bool { _ , err := uuid . FromString ( s ) return err == nil }

// IsUUID checks if a given string is a UUID.

IsUUID checks if a given string is a UUID .


func ExeDirJoin(elem ...string) string {
	exe, err := os.Executable()
	if err != nil {
		panic(err)
	}
	elem = append([]string{filepath.Dir(exe)}, elem...)
	return filepath.Join(elem...)
}

func ExeDirJoin ( elem ... string ) string { exe , err := os . Executable ( ) if err != nil { panic ( err ) } elem = append ( [ ] string { filepath . Dir ( exe ) } , elem ... ) return filepath . Join ( elem ... ) }

// ExeDirJoin composes a file name relative to a running executable.

ExeDirJoin composes a file name relative to a running executable .


func RootPath() string {
	_, file, _, ok := runtime.Caller(0)
	if !ok {
		return "?"
	}
	return filepath.Dir(filepath.Dir(file))
}

func RootPath ( ) string { _ , file , _ , ok := runtime . Caller ( 0 ) if ! ok { return " " } return filepath . Dir ( filepath . Dir ( file ) ) }

// RootPath returns a path of the root package.

RootPath returns a path of the root package .


func Caller() string {
	_, file, line, ok := runtime.Caller(2)
	if !ok {
		return "?"
	}

	rel, err := filepath.Rel(RootPath(), file)
	if err != nil {
		return "?"
	}

	return fmt.Sprintf("%s:%d", rel, line)
}

func Caller ( ) string { _ , file , line , ok := runtime . Caller ( 2 ) if ! ok { return " " } rel , err := filepath . Rel ( RootPath ( ) , file ) if err != nil { return " " } return fmt . Sprintf ( " " , rel , line ) }

// Caller returns a caller's call location. If F1 calls F2 which in its turn
// calls Caller, then this function will return a location within F1 where it
// calls F2.

Caller returns a caller s call location . If F1 calls F2 which in its turn calls Caller then this function will return a location within F1 where it calls F2 .


func CheckConnection(network, ip string, port int, timeout time.Duration) bool {
	conn, _ := net.DialTimeout(network,
		net.JoinHostPort(ip, strconv.Itoa(port)), timeout)
	if conn != nil {
		conn.Close()
		return true
	}
	return false
}

func CheckConnection ( network , ip string , port int , timeout time . Duration ) bool { conn , _ := net . DialTimeout ( network , net . JoinHostPort ( ip , strconv . Itoa ( port ) ) , timeout ) if conn != nil { conn . Close ( ) return true } return false }

// CheckConnection connects to the specified host on the specified port.
// If the connection is successful then return true.

CheckConnection connects to the specified host on the specified port . If the connection is successful then return true .


func (w *Worker) ClientAfterChannelCreate(job *data.Job) error {
	logger := w.logger.Add("method", "ClientAfterChannelCreate", "job", job)

	ch, err := w.relatedChannel(logger, job, data.JobClientAfterChannelCreate)
	if err != nil {
		return err
	}

	ethLog, err := w.ethLog(logger, job)
	if err != nil {
		return err
	}

	logger = logger.Add("channel", ch, "ethLog", ethLog)

	ch.Block = uint32(ethLog.Block)
	ch.ChannelStatus = data.ChannelActive
	if err = w.saveRecord(logger, w.db.Querier, ch); err != nil {
		return err
	}

	key, err := w.keyFromChannelData(logger, ch.ID)
	if err != nil {
		return err
	}

	logger = logger.Add("endpointKey", key)

	var endpointMsgSealed []byte

	offering, err := w.offering(logger, ch.Offering)
	if err != nil {
		return err
	}

	if err == nil {
		client, err := w.somcClientBuilder.NewClient(offering.SOMCType, offering.SOMCData)
		if err != nil {
			logger.Error(err.Error())
			return ErrGetEndpoint
		}
		rawMsg, err := client.Endpoint(key)
		if err != nil {
			logger.Error(err.Error())
			return ErrGetEndpoint
		}
		endpointMsgSealed, err = data.ToBytes(rawMsg)
		if err != nil {
			logger.Error(err.Error())
			return ErrGetEndpoint
		}
	}

	err = w.addJobWithData(logger, nil, data.JobClientEndpointRestore,
		data.JobChannel, ch.ID, &data.JobEndpointCreateData{EndpointSealed: endpointMsgSealed})
	if err != nil {
		return err
	}

	client, err := w.account(logger, ch.Client)
	if err != nil {
		return err
	}

	return w.addJob(logger, nil,
		data.JobAccountUpdateBalances, data.JobAccount, client.ID)
}

func ( w * Worker ) ClientAfterChannelCreate ( job * data . Job ) error { logger := w . logger . Add ( " " , " " , " " , job ) ch , err := w . relatedChannel ( logger , job , data . JobClientAfterChannelCreate ) if err != nil { return err } ethLog , err := w . ethLog ( logger , job ) if err != nil { return err } logger = logger . Add ( " " , ch , " " , ethLog ) ch . Block = uint32 ( ethLog . Block ) ch . ChannelStatus = data . ChannelActive if err = w . saveRecord ( logger , w . db . Querier , ch ) ; err != nil { return err } key , err := w . keyFromChannelData ( logger , ch . ID ) if err != nil { return err } logger = logger . Add ( " " , key ) var endpointMsgSealed [ ] byte offering , err := w . offering ( logger , ch . Offering ) if err != nil { return err } if err == nil { client , err := w . somcClientBuilder . NewClient ( offering . SOMCType , offering . SOMCData ) if err != nil { logger . Error ( err . Error ( ) ) return ErrGetEndpoint } rawMsg , err := client . Endpoint ( key ) if err != nil { logger . Error ( err . Error ( ) ) return ErrGetEndpoint } endpointMsgSealed , err = data . ToBytes ( rawMsg ) if err != nil { logger . Error ( err . Error ( ) ) return ErrGetEndpoint } } err = w . addJobWithData ( logger , nil , data . JobClientEndpointRestore , data . JobChannel , ch . ID , & data . JobEndpointCreateData { EndpointSealed : endpointMsgSealed } ) if err != nil { return err } client , err := w . account ( logger , ch . Client ) if err != nil { return err } return w . addJob ( logger , nil , data . JobAccountUpdateBalances , data . JobAccount , client . ID ) }

// ClientAfterChannelCreate activates channel and triggers endpoint retrieval.

ClientAfterChannelCreate activates channel and triggers endpoint retrieval .


func (w *Worker) ClientEndpointCreate(job *data.Job) error {
	logger := w.logger.Add("method", "ClientEndpointCreate",
		"job", job)

	ch, err := w.relatedChannel(logger, job,
		data.JobClientEndpointRestore)
	if err != nil {
		return err
	}

	var jdata data.JobEndpointCreateData
	if err := w.unmarshalDataTo(logger, job.Data, &jdata); err != nil {
		return err
	}

	msg, err := w.extractEndpointMessage(logger, ch, jdata.EndpointSealed)
	if err != nil {
		return err
	}

	offer, err := w.offering(logger, ch.Offering)
	if err != nil {
		return err
	}

	url := strings.Replace(w.countryConfig.URLTemplate,
		"{{ip}}", msg.ServiceEndpointAddress, 1)

	var countryStatus string

	c, err := country.GetCountry(w.countryConfig.Timeout, url,
		w.countryConfig.Field)
	if err != nil || len(c) != 2 {
		countryStatus = data.CountryStatusUnknown
	} else if c == offer.Country {
		countryStatus = data.CountryStatusValid
	} else {
		countryStatus = data.CountryStatusInvalid
	}

	params, _ := json.Marshal(msg.AdditionalParams)

	return w.db.InTransaction(func(tx *reform.TX) error {
		raddr := pointer.ToString(msg.PaymentReceiverAddress)
		saddr := pointer.ToString(msg.ServiceEndpointAddress)
		endp := data.Endpoint{
			ID:                     util.NewUUID(),
			Template:               offer.Template,
			Channel:                ch.ID,
			Hash:                   msg.TemplateHash,
			RawMsg:                 data.FromBytes(jdata.EndpointSealed),
			PaymentReceiverAddress: raddr,
			ServiceEndpointAddress: saddr,
			Username:               pointer.ToString(msg.Username),
			Password:               pointer.ToString(msg.Password),
			AdditionalParams:       params,
			CountryStatus:          pointer.ToString(countryStatus),
		}
		if err = w.db.Insert(&endp); err != nil {
			logger.Add("endpoint", endp).Error(err.Error())
			return ErrInternal
		}

		ch.ServiceStatus = data.ServiceSuspended
		changedTime := time.Now()
		ch.ServiceChangedTime = &changedTime
		// TODO: Review flow with service_changed_time.
		ch.PreparedAt = changedTime
		err = w.saveRecord(logger, w.db.Querier, ch)
		if err != nil {
			logger.Error(err.Error())
			return ErrInternal
		}

		return nil
	})
}

// ClientEndpointCreate decodes endpoint message, saves it in the DB and
// triggers product configuration.

ClientEndpointCreate decodes endpoint message saves it in the DB and triggers product configuration .


func (w *Worker) ClientAfterUncooperativeClose(job *data.Job) error {
	logger := w.logger.Add("method", "ClientAfterUncooperativeClose",
		"job", job)
	ch, err := w.relatedChannel(logger, job, data.JobClientAfterUncooperativeClose)
	if err != nil {
		return err
	}

	logger = logger.Add("channel", ch)

	ch.ChannelStatus = data.ChannelClosedUncoop
	if err := w.saveRecord(logger, w.db.Querier, ch); err != nil {
		return err
	}

	client, err := w.account(logger, ch.Client)
	if err != nil {
		return err
	}

	return w.addJob(logger, nil,
		data.JobAccountUpdateBalances, data.JobAccount, client.ID)
}

func ( w * Worker ) ClientAfterUncooperativeClose ( job * data . Job ) error { logger := w . logger . Add ( " " , " " , " " , job ) ch , err := w . relatedChannel ( logger , job , data . JobClientAfterUncooperativeClose ) if err != nil { return err } logger = logger . Add ( " " , ch ) ch . ChannelStatus = data . ChannelClosedUncoop if err := w . saveRecord ( logger , w . db . Querier , ch ) ; err != nil { return err } client , err := w . account ( logger , ch . Client ) if err != nil { return err } return w . addJob ( logger , nil , data . JobAccountUpdateBalances , data . JobAccount , client . ID ) }

// ClientAfterUncooperativeClose changed channel status
// to closed uncooperative.

ClientAfterUncooperativeClose changed channel status to closed uncooperative .


func (w *Worker) ClientAfterCooperativeClose(job *data.Job) error {
	logger := w.logger.Add("method", "ClientAfterCooperativeClose",
		"job", job)

	ch, err := w.relatedChannel(logger, job,
		data.JobClientAfterCooperativeClose)
	if err != nil {
		return err
	}

	logger = logger.Add("channel", ch)

	ch.ChannelStatus = data.ChannelClosedCoop
	if err := w.saveRecord(logger, w.db.Querier, ch); err != nil {
		return err
	}

	if ch.ServiceStatus != data.ServiceTerminated {
		_, err = w.processor.TerminateChannel(ch.ID, data.JobTask, false)
		if err != nil {
			logger.Error(err.Error())
			return ErrTerminateChannel
		}
	}

	client, err := w.account(logger, ch.Client)
	if err != nil {
		return err
	}

	return w.addJob(logger, nil,
		data.JobAccountUpdateBalances, data.JobAccount, client.ID)
}

func ( w * Worker ) ClientAfterCooperativeClose ( job * data . Job ) error { logger := w . logger . Add ( " " , " " , " " , job ) ch , err := w . relatedChannel ( logger , job , data . JobClientAfterCooperativeClose ) if err != nil { return err } logger = logger . Add ( " " , ch ) ch . ChannelStatus = data . ChannelClosedCoop if err := w . saveRecord ( logger , w . db . Querier , ch ) ; err != nil { return err } if ch . ServiceStatus != data . ServiceTerminated { _ , err = w . processor . TerminateChannel ( ch . ID , data . JobTask , false ) if err != nil { logger . Error ( err . Error ( ) ) return ErrTerminateChannel } } client , err := w . account ( logger , ch . Client ) if err != nil { return err } return w . addJob ( logger , nil , data . JobAccountUpdateBalances , data . JobAccount , client . ID ) }

// ClientAfterCooperativeClose changed channel status
// to closed cooperative and launches of terminate service procedure.

ClientAfterCooperativeClose changed channel status to closed cooperative and launches of terminate service procedure .


func (w *Worker) ClientPreServiceTerminate(job *data.Job) error {
	logger := w.logger.Add("method", "ClientPreServiceTerminate", "job", job)

	ch, err := w.relatedChannel(logger,
		job, data.JobClientPreServiceTerminate)
	if err != nil {
		return err
	}

	logger = logger.Add("channel", ch)

	if ch.ServiceStatus == data.ServiceActive {
		ch.ServiceStatus = data.ServiceTerminating
	} else {
		ch.ServiceStatus = data.ServiceTerminated
	}

	changedTime := time.Now()
	ch.ServiceChangedTime = &changedTime
	err = w.saveRecord(logger, w.db.Querier, ch)
	if err != nil {
		return err
	}
	return nil
}

func ( w * Worker ) ClientPreServiceTerminate ( job * data . Job ) error { logger := w . logger . Add ( " " , " " , " " , job ) ch , err := w . relatedChannel ( logger , job , data . JobClientPreServiceTerminate ) if err != nil { return err } logger = logger . Add ( " " , ch ) if ch . ServiceStatus == data . ServiceActive { ch . ServiceStatus = data . ServiceTerminating } else { ch . ServiceStatus = data . ServiceTerminated } changedTime := time . Now ( ) ch . ServiceChangedTime = & changedTime err = w . saveRecord ( logger , w . db . Querier , ch ) if err != nil { return err } return nil }

// ClientPreServiceTerminate terminates service.

ClientPreServiceTerminate terminates service .


func (w *Worker) ClientPreServiceSuspend(job *data.Job) error {
	logger := w.logger.Add("method", "ClientPreServiceSuspend", "job", job)

	ch, err := w.relatedChannel(logger, job, data.JobClientPreServiceSuspend)
	if err != nil {
		return err
	}

	logger = logger.Add("channel", ch)

	ch.ServiceStatus = data.ServiceSuspending
	changedTime := time.Now()
	ch.ServiceChangedTime = &changedTime
	err = w.saveRecord(logger, w.db.Querier, ch)
	if err != nil {
		return err
	}
	return nil
}

func ( w * Worker ) ClientPreServiceSuspend ( job * data . Job ) error { logger := w . logger . Add ( " " , " " , " " , job ) ch , err := w . relatedChannel ( logger , job , data . JobClientPreServiceSuspend ) if err != nil { return err } logger = logger . Add ( " " , ch ) ch . ServiceStatus = data . ServiceSuspending changedTime := time . Now ( ) ch . ServiceChangedTime = & changedTime err = w . saveRecord ( logger , w . db . Querier , ch ) if err != nil { return err } return nil }

// ClientPreServiceSuspend suspends service.

ClientPreServiceSuspend suspends service .


func (w *Worker) ClientPreServiceUnsuspend(job *data.Job) error {
	logger := w.logger.Add("method", "ClientPreServiceUnsuspend",
		"job", job)

	ch, err := w.relatedChannel(logger, job, data.JobClientPreServiceUnsuspend)
	if err != nil {
		return err
	}

	logger = logger.Add("channel", ch)

	ch.ServiceStatus = data.ServiceActivating
	changedTime := time.Now()
	ch.ServiceChangedTime = &changedTime
	return w.saveRecord(logger, w.db.Querier, ch)
}

func ( w * Worker ) ClientPreServiceUnsuspend ( job * data . Job ) error { logger := w . logger . Add ( " " , " " , " " , job ) ch , err := w . relatedChannel ( logger , job , data . JobClientPreServiceUnsuspend ) if err != nil { return err } logger = logger . Add ( " " , ch ) ch . ServiceStatus = data . ServiceActivating changedTime := time . Now ( ) ch . ServiceChangedTime = & changedTime return w . saveRecord ( logger , w . db . Querier , ch ) }

// ClientPreServiceUnsuspend activates service.

ClientPreServiceUnsuspend activates service .


func (w *Worker) ClientPreUncooperativeClose(job *data.Job) error {
	logger := w.logger.Add("method", "ClientPreUncooperativeClose",
		"job", job)

	// If cooperative close was created for this channel, skip this job.
	err := w.db.SelectOneTo(&data.Job{},
		"WHERE related_id=$1 AND related_type=$2 AND type=$3",
		job.RelatedID, job.RelatedType, data.JobClientAfterCooperativeClose)
	if err == nil {
		job.Status = data.JobCanceled
		w.db.Save(job)
		return nil
	}

	ch, err := w.relatedChannel(logger, job,
		data.JobClientPreUncooperativeClose)
	if err != nil {
		return err
	}

	if ch.ChannelStatus == data.ChannelClosedCoop {
		logger.Warn("channel closed cooperatively")
		return nil
	}

	logger = logger.Add("channel", ch)

	agent, err := data.HexToAddress(ch.Agent)
	if err != nil {
		logger.Error(err.Error())
		return ErrParseEthAddr
	}

	client, err := data.HexToAddress(ch.Client)
	if err != nil {
		logger.Error(err.Error())
		return ErrParseEthAddr
	}

	acc, err := w.account(logger, ch.Client)
	if err != nil {
		return err
	}

	offer, err := w.offering(logger, ch.Offering)
	if err != nil {
		return err
	}

	offerHash, err := data.HexToHash(offer.Hash)
	if err != nil {
		logger.Error(err.Error())
		return ErrParseOfferingHash
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	blocks, err := w.blocksTillChallangeEnd(ctx, logger, client, agent, ch.Block, offerHash)
	if err != nil {
		return err
	}
	if blocks > 0 {
		logger.Add("blocksTillChallangeEnd", blocks).Warn("in challange period")
		return ErrChallengePeriodIsNotOver
	}

	tx, err := w.settle(ctx, logger, acc, agent, ch.Block, offerHash)
	if err != nil {
		return err
	}

	if err := w.saveEthTX(logger, job, tx, "Settle",
		data.JobChannel, ch.ID, acc.EthAddr,
		data.HexFromBytes(w.pscAddr.Bytes())); err != nil {
		return err
	}

	ch.ChannelStatus = data.ChannelWaitUncoop

	return w.saveRecord(logger, w.db.Querier, ch)
}

// ClientPreUncooperativeClose waiting for until the challenge
// period is over. Then deletes the channel and settles
// by transferring the balance to the Agent and the rest
// of the deposit back to the Client.

ClientPreUncooperativeClose waiting for until the challenge period is over . Then deletes the channel and settles by transferring the balance to the Agent and the rest of the deposit back to the Client .


func (w *Worker) ClientPreChannelTopUp(job *data.Job) error {
	logger := w.logger.Add("method", "ClientPreChannelTopUp", "job", job)

	ch, err := w.relatedChannel(logger, job, data.JobClientPreChannelTopUp)
	if err != nil {
		return err
	}

	offer, err := w.offering(logger, ch.Offering)
	if err != nil {
		return err
	}

	acc, err := w.account(logger, ch.Client)
	if err != nil {
		return err
	}

	logger = logger.Add("channel", ch, "offering", offer)

	var jdata data.JobTopUpChannelData
	if err := w.unmarshalDataTo(logger, job.Data, &jdata); err != nil {
		return err
	}

	if err := w.checkDeposit(logger, acc, offer, jdata.Deposit); err != nil {
		return err
	}

	return w.clientPreChannelTopUpSaveTx(logger, job, ch, acc, offer,
		jdata.GasPrice, uint64(jdata.Deposit))
}

func ( w * Worker ) ClientPreChannelTopUp ( job * data . Job ) error { logger := w . logger . Add ( " " , " " , " " , job ) ch , err := w . relatedChannel ( logger , job , data . JobClientPreChannelTopUp ) if err != nil { return err } offer , err := w . offering ( logger , ch . Offering ) if err != nil { return err } acc , err := w . account ( logger , ch . Client ) if err != nil { return err } logger = logger . Add ( " " , ch , " " , offer ) var jdata data . JobTopUpChannelData if err := w . unmarshalDataTo ( logger , job . Data , & jdata ) ; err != nil { return err } if err := w . checkDeposit ( logger , acc , offer , jdata . Deposit ) ; err != nil { return err } return w . clientPreChannelTopUpSaveTx ( logger , job , ch , acc , offer , jdata . GasPrice , uint64 ( jdata . Deposit ) ) }

// ClientPreChannelTopUp checks client balance and creates transaction
// for increase the channel deposit.

ClientPreChannelTopUp checks client balance and creates transaction for increase the channel deposit .


func (w *Worker) ClientAfterChannelTopUp(job *data.Job) error {
	return w.afterChannelTopUp(job, data.JobClientAfterChannelTopUp)
}

func ( w * Worker ) ClientAfterChannelTopUp ( job * data . Job ) error { return w . afterChannelTopUp ( job , data . JobClientAfterChannelTopUp ) }

// ClientAfterChannelTopUp updates deposit of a channel.

ClientAfterChannelTopUp updates deposit of a channel .


func (w *Worker) ClientPreUncooperativeCloseRequest(job *data.Job) error {
	logger := w.logger.Add("method", "ClientPreUncooperativeCloseRequest",
		"job", job)

	ch, err := w.relatedChannel(logger, job,
		data.JobClientPreUncooperativeCloseRequest)
	if err != nil {
		return err
	}

	jdata, err := w.publishData(logger, job)
	if err != nil {
		return err
	}

	offer, err := w.offering(logger, ch.Offering)
	if err != nil {
		return err
	}

	acc, err := w.account(logger, ch.Client)
	if err != nil {
		return err
	}

	if err := w.clientValidateChannelForClose(ch); err != nil {
		return err
	}

	return w.doClientPreUncooperativeCloseRequestAndSaveTx(logger, job, ch,
		acc, offer, jdata.GasPrice)
}

// ClientPreUncooperativeCloseRequest requests the closing of the channel
// and starts the challenge period.

ClientPreUncooperativeCloseRequest requests the closing of the channel and starts the challenge period .


func (w *Worker) ClientAfterUncooperativeCloseRequest(job *data.Job) error {
	logger := w.logger.Add("method", "ClientAfterUncooperativeCloseRequest",
		"job", job)

	ch, err := w.relatedChannel(logger, job,
		data.JobClientAfterUncooperativeCloseRequest)
	if err != nil {
		return err
	}

	ch.ChannelStatus = data.ChannelInChallenge
	if err = w.db.Update(ch); err != nil {
		logger.Error(err.Error())
		return ErrInternal
	}

	challengePeriod, err := data.ReadUintSetting(w.db.Querier,
		data.SettingsPeriodChallange)
	if err != nil {
		return err
	}

	return w.addJobWithDelay(logger, nil,
		data.JobClientPreUncooperativeClose, data.JobChannel,
		ch.ID, time.Duration(challengePeriod)*eth.BlockDuration)
}

func ( w * Worker ) ClientAfterUncooperativeCloseRequest ( job * data . Job ) error { logger := w . logger . Add ( " " , " " , " " , job ) ch , err := w . relatedChannel ( logger , job , data . JobClientAfterUncooperativeCloseRequest ) if err != nil { return err } ch . ChannelStatus = data . ChannelInChallenge if err = w . db . Update ( ch ) ; err != nil { logger . Error ( err . Error ( ) ) return ErrInternal } challengePeriod , err := data . ReadUintSetting ( w . db . Querier , data . SettingsPeriodChallange ) if err != nil { return err } return w . addJobWithDelay ( logger , nil , data . JobClientPreUncooperativeClose , data . JobChannel , ch . ID , time . Duration ( challengePeriod ) * eth . BlockDuration ) }

// ClientAfterUncooperativeCloseRequest waits for the channel
// to uncooperative close, starts the service termination process.

ClientAfterUncooperativeCloseRequest waits for the channel to uncooperative close starts the service termination process .


func (w *Worker) ClientAfterOfferingMsgBCPublish(job *data.Job) error {
	logger := w.logger.Add("method", "ClientAfterOfferingMsgBCPublish",
		"job", job)

	ethLog, err := w.ethLog(logger, job)
	if err != nil {
		return err
	}

	logOfferingCreated, err := extractLogOfferingCreated(logger, ethLog)
	if err != nil {
		return err
	}

	return w.clientRetrieveAndSaveOffering(logger, job,
		ethLog.Block, logOfferingCreated.somcType,
		logOfferingCreated.somcData, logOfferingCreated.agentAddr,
		logOfferingCreated.offeringHash, logOfferingCreated.currentSupply)
}

func ( w * Worker ) ClientAfterOfferingMsgBCPublish ( job * data . Job ) error { logger := w . logger . Add ( " " , " " , " " , job ) ethLog , err := w . ethLog ( logger , job ) if err != nil { return err } logOfferingCreated , err := extractLogOfferingCreated ( logger , ethLog ) if err != nil { return err } return w . clientRetrieveAndSaveOffering ( logger , job , ethLog . Block , logOfferingCreated . somcType , logOfferingCreated . somcData , logOfferingCreated . agentAddr , logOfferingCreated . offeringHash , logOfferingCreated . currentSupply ) }

// ClientAfterOfferingMsgBCPublish creates offering.

ClientAfterOfferingMsgBCPublish creates offering .


func (w *Worker) ClientAfterOfferingPopUp(job *data.Job) error {
	logger := w.logger.Add("method", "ClientAfterOfferingPopUp", "job", job)

	ethLog, err := w.ethLog(logger, job)
	if err != nil {
		return err
	}

	logger = logger.Add("ethLog", ethLog)

	logOfferingPopUp, err := extractLogOfferingPopUp(logger, ethLog)
	if err != nil {
		return err
	}

	offering := data.Offering{}
	hash := data.HexFromBytes(logOfferingPopUp.offeringHash.Bytes())
	err = w.db.FindOneTo(&offering, "hash", hash)
	if err == sql.ErrNoRows {
		// New offering.
		return w.clientRetrieveAndSaveOffering(logger, job,
			ethLog.Block, logOfferingPopUp.somcType,
			logOfferingPopUp.somcData, logOfferingPopUp.agentAddr,
			logOfferingPopUp.offeringHash, logOfferingPopUp.currentSupply)
	}
	if err != nil {
		logger.Error(err.Error())
		return ErrInternal
	}

	// Existing offering, just update offering status.
	offering.BlockNumberUpdated = ethLog.Block
	offering.Status = data.OfferPoppedUp

	return w.saveRecord(logger, w.db.Querier, &offering)
}

// ClientAfterOfferingPopUp updates offering in db or retrieves from somc
// if new.

ClientAfterOfferingPopUp updates offering in db or retrieves from somc if new .


func (w *Worker) ClientAfterOfferingDelete(job *data.Job) error {
	return w.updateRelatedOffering(
		job, data.JobClientAfterOfferingDelete, data.OfferRemoved)
}

func ( w * Worker ) ClientAfterOfferingDelete ( job * data . Job ) error { return w . updateRelatedOffering ( job , data . JobClientAfterOfferingDelete , data . OfferRemoved ) }

// ClientAfterOfferingDelete sets offer status to `remove`;

ClientAfterOfferingDelete sets offer status to remove ;


func (w *Worker) DecrementCurrentSupply(job *data.Job) error {
	logger := w.logger.Add("method", "DecrementCurrentSupply", "job", job)
	offering, err := w.relatedOffering(logger, job, data.JobDecrementCurrentSupply)
	if err != nil {
		return err
	}

	offering.CurrentSupply--

	err = data.Save(w.db.Querier, offering)
	if err != nil {
		logger.Error(err.Error())
		return ErrInternal
	}

	return nil
}

func ( w * Worker ) DecrementCurrentSupply ( job * data . Job ) error { logger := w . logger . Add ( " " , " " , " " , job ) offering , err := w . relatedOffering ( logger , job , data . JobDecrementCurrentSupply ) if err != nil { return err } offering . CurrentSupply -- err = data . Save ( w . db . Querier , offering ) if err != nil { logger . Error ( err . Error ( ) ) return ErrInternal } return nil }

// DecrementCurrentSupply finds offering and decrements its current supply.

DecrementCurrentSupply finds offering and decrements its current supply .


func (h *Handler) GetEndpoints(
	tkn, channel, template string) ([]data.Endpoint, error) {
	logger := h.logger.Add("method", "GetEndpoints",
		"channel", channel, "template", template)

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return nil, ErrAccessDenied
	}

	tail, args := h.getEndpointsConditions(channel, template)

	result, err := h.selectAllFrom(
		logger, data.EndpointTable, tail, args...)
	if err != nil {
		return nil, err
	}

	endpoints := make([]data.Endpoint, len(result))
	for i, item := range result {
		endpoints[i] = *item.(*data.Endpoint)
	}

	return endpoints, nil
}

func ( h * Handler ) GetEndpoints ( tkn , channel , template string ) ( [ ] data . Endpoint , error ) { logger := h . logger . Add ( " " , " " , " " , channel , " " , template ) if ! h . token . Check ( tkn ) { logger . Warn ( " " ) return nil , ErrAccessDenied } tail , args := h . getEndpointsConditions ( channel , template ) result , err := h . selectAllFrom ( logger , data . EndpointTable , tail , args ... ) if err != nil { return nil , err } endpoints := make ( [ ] data . Endpoint , len ( result ) ) for i , item := range result { endpoints [ i ] = * item . ( * data . Endpoint ) } return endpoints , nil }


func (h *Handler) GetGUISettings(tkn string) (map[string]interface{}, error) {
	logger := h.logger.Add("method", "GetGUISettings")

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return nil, ErrAccessDenied
	}

	retStr, err := data.ReadSetting(h.db.Querier, data.SettingGUI)
	if err != nil {
		logger.Error(err.Error())
		return nil, ErrInternal
	}

	ret := make(map[string]interface{})

	err = json.Unmarshal([]byte(retStr), &ret)
	if err != nil {
		logger.Error(err.Error())
		return nil, ErrInternal
	}

	return ret, nil
}

func ( h * Handler ) GetGUISettings ( tkn string ) ( map [ string ] interface { } , error ) { logger := h . logger . Add ( " " , " " ) if ! h . token . Check ( tkn ) { logger . Warn ( " " ) return nil , ErrAccessDenied } retStr , err := data . ReadSetting ( h . db . Querier , data . SettingGUI ) if err != nil { logger . Error ( err . Error ( ) ) return nil , ErrInternal } ret := make ( map [ string ] interface { } ) err = json . Unmarshal ( [ ] byte ( retStr ) , & ret ) if err != nil { logger . Error ( err . Error ( ) ) return nil , ErrInternal } return ret , nil }


func (h *Handler) SetGUISettings(tkn string, v map[string]interface{}) error {
	logger := h.logger.Add("method", "SetGUISettings")

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return ErrAccessDenied
	}

	d, err := json.Marshal(&v)
	if err != nil {
		logger.Error(err.Error())
		return ErrInternal
	}

	_, err = h.db.Exec(`
		UPDATE settings
		   SET value = $1
		 WHERE key=$2`, string(d), data.SettingGUI)
	if err != nil {
		logger.Error(fmt.Sprintf("failed to set gui settings: %v", err))
		return ErrInternal
	}

	return nil
}


func (s *Server) HandleFunc(pattern string, handler HandlerFunc) {
	s.Mux().HandleFunc(pattern,
		func(w http.ResponseWriter, r *http.Request) {
			handler(w, r, &Context{})
		})
}

func ( s * Server ) HandleFunc ( pattern string , handler HandlerFunc ) { s . Mux ( ) . HandleFunc ( pattern , func ( w http . ResponseWriter , r * http . Request ) { handler ( w , r , & Context { } ) } ) }

// HandleFunc registers a handler function for a given pattern.

HandleFunc registers a handler function for a given pattern .


func (s *Server) RequireHTTPMethods(logger log.Logger,
	handler HandlerFunc, methods ...string) HandlerFunc {
	l := logger.Add("method", "RequireHTTPMethods")
	return func(w http.ResponseWriter, r *http.Request, ctx *Context) {
		for _, v := range methods {
			if v == r.Method {
				handler(w, r, ctx)
				return
			}
		}

		l.Add("sender", r.RemoteAddr).Warn("not allowed HTTP method")
		s.RespondError(logger, w, ErrMethodNotAllowed)
	}
}

func ( s * Server ) RequireHTTPMethods ( logger log . Logger , handler HandlerFunc , methods ... string ) HandlerFunc { l := logger . Add ( " " , " " ) return func ( w http . ResponseWriter , r * http . Request , ctx * Context ) { for _ , v := range methods { if v == r . Method { handler ( w , r , ctx ) return } } l . Add ( " " , r . RemoteAddr ) . Warn ( " " ) s . RespondError ( logger , w , ErrMethodNotAllowed ) } }

// RequireHTTPMethods wraps a given handler function inside an HTTP method
// validating handler.

RequireHTTPMethods wraps a given handler function inside an HTTP method validating handler .


func (s *Server) RequireBasicAuth(logger log.Logger,
	handler HandlerFunc, auth AuthFunc) HandlerFunc {
	l := logger.Add("method", "RequireBasicAuth")
	return func(w http.ResponseWriter, r *http.Request, ctx *Context) {
		name, pass, ok := r.BasicAuth()
		if !ok || !auth(name, pass) {
			l.Add("sender", r.RemoteAddr).Warn("access denied")
			s.RespondError(logger, w, ErrAccessDenied)
			return
		}

		ctx.Username = name
		handler(w, r, ctx)
	}
}

func ( s * Server ) RequireBasicAuth ( logger log . Logger , handler HandlerFunc , auth AuthFunc ) HandlerFunc { l := logger . Add ( " " , " " ) return func ( w http . ResponseWriter , r * http . Request , ctx * Context ) { name , pass , ok := r . BasicAuth ( ) if ! ok || ! auth ( name , pass ) { l . Add ( " " , r . RemoteAddr ) . Warn ( " " ) s . RespondError ( logger , w , ErrAccessDenied ) return } ctx . Username = name handler ( w , r , ctx ) } }

// RequireBasicAuth wraps a given handler function inside a handler with basic
// access authentication.

RequireBasicAuth wraps a given handler function inside a handler with basic access authentication .


func New(db *reform.DB, logger log.Logger, payAddr string,
	timeout uint) (*Service, error) {
	return &Service{
		db:      db,
		msgChan: make(chan *req),
		payAddr: payAddr,
		timeout: time.Duration(timeout) * time.Millisecond,
		logger:  logger.Add("type", "messages/ept.Service"),
	}, nil
}

func New ( db * reform . DB , logger log . Logger , payAddr string , timeout uint ) ( * Service , error ) { return & Service { db : db , msgChan : make ( chan * req ) , payAddr : payAddr , timeout : time . Duration ( timeout ) * time . Millisecond , logger : logger . Add ( " " , " " ) , } , nil }

// New function for initialize the service for generating
// the Endpoint Message.

New function for initialize the service for generating the Endpoint Message .


func (s *Service) EndpointMessage(channelID string) (*Message, error) {
	c := make(chan *result)
	done := make(chan bool)

	req := &req{channelID: channelID, callback: c, done: done}

	go s.processing(req)

	select {
	case result := <-c:
		return result.msg, result.err
	case <-time.After(s.timeout):
		close(done)
		return nil, ErrTimeOut
	}
}

func ( s * Service ) EndpointMessage ( channelID string ) ( * Message , error ) { c := make ( chan * result ) done := make ( chan bool ) req := & req { channelID : channelID , callback : c , done : done } go s . processing ( req ) select { case result := <- c : return result . msg , result . err case <- time . After ( s . timeout ) : close ( done ) return nil , ErrTimeOut } }

// EndpointMessage returns the endpoint message object.

EndpointMessage returns the endpoint message object .


func (h *Handler) ConnChange(ctx context.Context,
	product, productPassword string) (*rpc.Subscription, error) {
	logger := h.logger.Add("method", "ConnChange", "product", product)

	logger.Info("subscribing to adapter connection changes")

	_, err := h.checkProductPassword(logger, product, productPassword)
	if err != nil {
		return nil, err
	}

	ntf, ok := rpc.NotifierFromContext(ctx)
	if !ok {
		logger.Error("no notifier found in context")
		return nil, ErrInternal
	}

	sub := ntf.CreateSubscription()
	cb := func(job *data.Job, result error) {
		if result == nil {
			h.handleConnChange(product, logger, ntf, sub, job)
		}
	}
	jobTypes := []string{
		data.JobClientPreServiceSuspend,
		data.JobClientPreServiceUnsuspend,
		data.JobClientPreServiceTerminate,
	}

	// TODO: testing. fix it later.
	sid := string(sub.ID)
	if err = h.queue.Subscribe(jobTypes, sid, cb); err != nil {
		logger.Error(err.Error())
		return nil, ErrInternal
	}

	go func() {
		for err, ok := <-sub.Err(); ok; {
			if err != nil {
				logger.Warn(err.Error())
			}
		}

		err := h.queue.Unsubscribe(jobTypes, sid)
		if err != nil {
			logger.Error(err.Error())
		}
	}()

	return sub, nil
}

func
(
h
*
Handler
)
ConnChange
(
ctx
context
.
Context
,
product
,
productPassword
string
)
(
*
rpc
.
Subscription
,
error
)
{
logger
:=
h
.
logger
.
Add
(
"
"
,
"
"
,
"
"
,
product
)
logger
.
Info
(
"
"
)
_
,
err
:=
h
.
checkProductPassword
(
logger
,
product
,
productPassword
)
if
err
!=
{
return
,
err
}
ntf
,
ok
:=
rpc
.
NotifierFromContext
(
ctx
)
if
!
ok
{
logger
.
Error
(
"
"
)
return
,
ErrInternal
}
sub
:=
ntf
.
CreateSubscription
(
)
cb
:=
func
(
job
*
data
.
Job
,
result
error
)
{
if
result
==
{
h
.
handleConnChange
(
product
,
logger
,
ntf
,
sub
,
job
)
}
}
jobTypes
:=
[
]
string
{
data
.
JobClientPreServiceSuspend
,
data
.
JobClientPreServiceUnsuspend
,
data
.
JobClientPreServiceTerminate
,
}
// TODO: testing. fix it later.
sid
:=
string
(
sub
.
ID
)
if
err
=
h
.
queue
.
Subscribe
(
jobTypes
,
sid
,
cb
)
;
err
!=
{
logger
.
Error
(
err
.
Error
(
)
)
return
,
ErrInternal
}
go
func
(
)
{
for
err
,
ok
:=
<-
sub
.
Err
(
)
;
ok
;
{
if
err
!=
{
logger
.
Warn
(
err
.
Error
(
)
)
}
}
err
:=
h
.
queue
.
Unsubscribe
(
jobTypes
,
sid
)
if
err
!=
{
logger
.
Error
(
err
.
Error
(
)
)
}
}
(
)
return
sub
,
}

// ConnChange subscribes to changes for adapter connection changes.

ConnChange subscribes to changes for adapter connection changes .


func FromBase64ToHex(s Base64String) (string, error) {
	b, err := ToBytes(s)
	if err != nil {
		return "", err
	}
	return hex.EncodeToString(b), nil
}

func FromBase64ToHex ( s Base64String ) ( string , error ) { b , err := ToBytes ( s ) if err != nil { return " " , err } return hex . EncodeToString ( b ) , nil }

// FromBase64ToHex return hex of base 64 encoded.

FromBase64ToHex return hex of base 64 encoded .


func HexToBytes(s HexString) ([]byte, error) {
	s2 := string(s)
	if strings.HasPrefix(s2, "0x") || strings.HasPrefix(s2, "0X") {
		s2 = s2[2:]
	}
	return hex.DecodeString(s2)
}

func HexToBytes ( s HexString ) ( [ ] byte , error ) { s2 := string ( s ) if strings . HasPrefix ( s2 , " " ) || strings . HasPrefix ( s2 , " " ) { s2 = s2 [ 2 : ] } return hex . DecodeString ( s2 ) }

// HexToBytes reutrns the bytes represented by the hex of string s.

HexToBytes reutrns the bytes represented by the hex of string s .


func ToBytes(s Base64String) ([]byte, error) {
	return base64.URLEncoding.DecodeString(strings.TrimSpace(string(s)))
}

func ToBytes ( s Base64String ) ( [ ] byte , error ) { return base64 . URLEncoding . DecodeString ( strings . TrimSpace ( string ( s ) ) ) }

// ToBytes returns the bytes represented by the base64 string s.

ToBytes returns the bytes represented by the base64 string s .


func ToHash(h Base64String) (common.Hash, error) {
	hashBytes, err := ToBytes(h)
	if err != nil {
		err = fmt.Errorf("unable to parse ethereum hash: %s", err)
	}
	return common.BytesToHash(hashBytes), err
}

func ToHash ( h Base64String ) ( common . Hash , error ) { hashBytes , err := ToBytes ( h ) if err != nil { err = fmt . Errorf ( " " , err ) } return common . BytesToHash ( hashBytes ) , err }

// ToHash returns the ethereum's hash represented by the base64 string s.

ToHash returns the ethereum s hash represented by the base64 string s .


func HexToHash(h HexString) (common.Hash, error) {
	hashBytes, err := HexToBytes(h)
	if err != nil {
		err = fmt.Errorf("unable to parse ethereum hash: %s", err)
	}
	return common.BytesToHash(hashBytes), err
}

func HexToHash ( h HexString ) ( common . Hash , error ) { hashBytes , err := HexToBytes ( h ) if err != nil { err = fmt . Errorf ( " " , err ) } return common . BytesToHash ( hashBytes ) , err }

// HexToHash returns the ethereum's hash represented by the hex of string s.

HexToHash returns the ethereum s hash represented by the hex of string s .


func HexToAddress(addr HexString) (common.Address, error) {
	addrBytes, err := HexToBytes(addr)
	if err != nil {
		err = fmt.Errorf("unable to parse ethereum addr: %s", err)
	}
	return common.BytesToAddress(addrBytes), err
}

func HexToAddress ( addr HexString ) ( common . Address , error ) { addrBytes , err := HexToBytes ( addr ) if err != nil { err = fmt . Errorf ( " " , err ) } return common . BytesToAddress ( addrBytes ) , err }

// HexToAddress returns ethereum's address from base 64 encoded string.

HexToAddress returns ethereum s address from base 64 encoded string .


func BytesToUint32(b []byte) (uint32, error) {
	if len(b) != 4 {
		return 0, fmt.Errorf("wrong len")
	}
	return binary.BigEndian.Uint32(b), nil
}

func BytesToUint32 ( b [ ] byte ) ( uint32 , error ) { if len ( b ) != 4 { return 0 , fmt . Errorf ( " " ) } return binary . BigEndian . Uint32 ( b ) , nil }


func Uint32ToBytes(x uint32) [4]byte {
	var xBytes [4]byte
	binary.BigEndian.PutUint32(xBytes[:], x)
	return xBytes
}

func Uint32ToBytes ( x uint32 ) [ 4 ] byte { var xBytes [ 4 ] byte binary . BigEndian . PutUint32 ( xBytes [ : ] , x ) return xBytes }


func Uint64ToBytes(x uint64) [8]byte {
	var xBytes [8]byte
	binary.BigEndian.PutUint64(xBytes[:], x)
	return xBytes
}

func Uint64ToBytes ( x uint64 ) [ 8 ] byte { var xBytes [ 8 ] byte binary . BigEndian . PutUint64 ( xBytes [ : ] , x ) return xBytes }


func Uint192ToBytes(x *big.Int) [24]byte {
	var ret [24]byte
	xBytes := x.Bytes()
	for i, v := range xBytes {
		ret[24-len(xBytes)+i] = v
	}
	return ret
}

func Uint192ToBytes ( x * big . Int ) [ 24 ] byte { var ret [ 24 ] byte xBytes := x . Bytes ( ) for i , v := range xBytes { ret [ 24 - len ( xBytes ) + i ] = v } return ret }

// Uint192ToBytes using big endian with leading zeros.

Uint192ToBytes using big endian with leading zeros .


func HashPassword(password, salt string) (Base64String, error) {
	salted := []byte(password + salt)
	passwordHash, err := bcrypt.GenerateFromPassword(salted, bcrypt.DefaultCost)
	if err != nil {
		return "", err
	}
	return FromBytes(passwordHash), nil
}

func HashPassword ( password , salt string ) ( Base64String , error ) { salted := [ ] byte ( password + salt ) passwordHash , err := bcrypt . GenerateFromPassword ( salted , bcrypt . DefaultCost ) if err != nil { return " " , err } return FromBytes ( passwordHash ) , nil }

// HashPassword computes encoded hash of the password.

HashPassword computes encoded hash of the password .


func ValidatePassword(hash Base64String, password, salt string) error {
	salted := []byte(fmt.Sprint(password, salt))
	hashB, err := ToBytes(hash)
	if err != nil {
		return err
	}
	return bcrypt.CompareHashAndPassword(hashB, salted)
}

func ValidatePassword ( hash Base64String , password , salt string ) error { salted := [ ] byte ( fmt . Sprint ( password , salt ) ) hashB , err := ToBytes ( hash ) if err != nil { return err } return bcrypt . CompareHashAndPassword ( hashB , salted ) }

// ValidatePassword checks if a given password, hash and salt are matching.

ValidatePassword checks if a given password hash and salt are matching .


func GetUint64Setting(db *reform.DB, key string) (uint64, error) {
	var setting Setting
	err := db.FindByPrimaryKeyTo(&setting, key)
	if err != nil {
		if err == sql.ErrNoRows {
			return 0, fmt.Errorf("key %s is not exist"+
				" in Setting table", key)
		}
		return 0, err
	}

	value, err := strconv.ParseUint(setting.Value, 10, 64)
	if err != nil {
		return 0, fmt.Errorf("failed to parse %s setting: %v",
			key, err)
	}

	return value, nil

}

func GetUint64Setting ( db * reform . DB , key string ) ( uint64 , error ) { var setting Setting err := db . FindByPrimaryKeyTo ( & setting , key ) if err != nil { if err == sql . ErrNoRows { return 0 , fmt . Errorf ( " " + " " , key ) } return 0 , err } value , err := strconv . ParseUint ( setting . Value , 10 , 64 ) if err != nil { return 0 , fmt . Errorf ( " " , key , err ) } return value , nil }

// GetUint64Setting finds the key value in table Setting.
// Checks that the value in the format of uint64

GetUint64Setting finds the key value in table Setting . Checks that the value in the format of uint64


func ChannelKey(client, agent HexString, block uint32,
	offeringHash HexString) ([]byte, error) {
	clientAddr, err := HexToAddress(client)
	if err != nil {
		return nil, err
	}

	agentAddr, err := HexToAddress(agent)
	if err != nil {
		return nil, err
	}

	hash, err := base64.URLEncoding.DecodeString(
		strings.TrimSpace(string(offeringHash)))
	if err != nil {
		return nil, err
	}

	blockBytes := Uint32ToBytes(block)

	return crypto.Keccak256(clientAddr.Bytes(),
		agentAddr.Bytes(), blockBytes[:],
		common.BytesToHash(hash).Bytes()), nil
}

func ChannelKey ( client , agent HexString , block uint32 , offeringHash HexString ) ( [ ] byte , error ) { clientAddr , err := HexToAddress ( client ) if err != nil { return nil , err } agentAddr , err := HexToAddress ( agent ) if err != nil { return nil , err } hash , err := base64 . URLEncoding . DecodeString ( strings . TrimSpace ( string ( offeringHash ) ) ) if err != nil { return nil , err } blockBytes := Uint32ToBytes ( block ) return crypto . Keccak256 ( clientAddr . Bytes ( ) , agentAddr . Bytes ( ) , blockBytes [ : ] , common . BytesToHash ( hash ) . Bytes ( ) ) , nil }

// ChannelKey returns the unique channel identifier
// used in a Privatix Service Contract.

ChannelKey returns the unique channel identifier used in a Privatix Service Contract .


func MinDeposit(offering *Offering) uint64 {
	return offering.MinUnits*offering.UnitPrice + offering.SetupPrice
}

func MinDeposit ( offering * Offering ) uint64 { return offering . MinUnits * offering . UnitPrice + offering . SetupPrice }

// MinDeposit calculates minimal deposit required to accept the offering.

MinDeposit calculates minimal deposit required to accept the offering .


func (h *Handler) AcceptOffering(tkn string, account data.HexString,
	offering string, deposit, gasPrice uint64) (*string, error) {
	logger := h.logger.Add("method", "AcceptOffering",
		"account", account, "offering", offering,
		"deposit", deposit, "gasPrice", gasPrice)

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return nil, ErrAccessDenied
	}

	var acc data.Account
	if err := h.findByColumn(logger, ErrAccountNotFound,
		&acc, "eth_addr", account); err != nil {
		return nil, err
	}

	offer, err := h.findActiveOfferingByID(logger, offering)
	if err != nil {
		return nil, err
	}

	minDeposit := data.MinDeposit(offer)

	if deposit == 0 {
		deposit = minDeposit
	} else if deposit < minDeposit {
		logger.Error(ErrDepositTooSmall.Error())
		return nil, ErrDepositTooSmall
	}

	if err := h.pingOffering(logger, offer); err != nil {
		return nil, err
	}

	rid := util.NewUUID()
	jobData := &worker.ClientPreChannelCreateData{Account: acc.ID,
		Offering: offering, GasPrice: gasPrice, Deposit: deposit}
	if err := job.AddWithData(h.queue, nil, data.JobClientPreChannelCreate,
		data.JobChannel, rid, data.JobUser, jobData); err != nil {
		logger.Error(err.Error())
		return nil, ErrInternal
	}

	return &rid, nil
}

func ( h * Handler ) AcceptOffering ( tkn string , account data . HexString , offering string , deposit , gasPrice uint64 ) ( * string , error ) { logger := h . logger . Add ( " " , " " , " " , account , " " , offering , " " , deposit , " " , gasPrice ) if ! h . token . Check ( tkn ) { logger . Warn ( " " ) return nil , ErrAccessDenied } var acc data . Account if err := h . findByColumn ( logger , ErrAccountNotFound , & acc , " " , account ) ; err != nil { return nil , err } offer , err := h . findActiveOfferingByID ( logger , offering ) if err != nil { return nil , err } minDeposit := data . MinDeposit ( offer ) if deposit == 0 { deposit = minDeposit } else if deposit < minDeposit { logger . Error ( ErrDepositTooSmall . Error ( ) ) return nil , ErrDepositTooSmall } if err := h . pingOffering ( logger , offer ) ; err != nil { return nil , err } rid := util . NewUUID ( ) jobData := & worker . ClientPreChannelCreateData { Account : acc . ID , Offering : offering , GasPrice : gasPrice , Deposit : deposit } if err := job . AddWithData ( h . queue , nil , data . JobClientPreChannelCreate , data . JobChannel , rid , data . JobUser , jobData ) ; err != nil { logger . Error ( err . Error ( ) ) return nil , ErrInternal } return & rid , nil }

// AcceptOffering initiates JobClientPreChannelCreate job.

AcceptOffering initiates JobClientPreChannelCreate job .


func (h *Handler) ChangeOfferingStatus(
	tkn, offering, action string, gasPrice uint64) error {
	logger := h.logger.Add("method", "ChangeOfferingStatus",
		"offering", offering, "action", action, "gasPrice", gasPrice)

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return ErrAccessDenied
	}

	jobType, ok := OfferingChangeActions[action]
	if !ok {
		logger.Warn(ErrBadOfferingStatusAction.Error())
		return ErrBadOfferingStatusAction
	}

	offer := &data.Offering{}
	err := h.findByPrimaryKey(logger, ErrOfferingNotFound, offer, offering)
	if err != nil {
		return err
	}

	jobData := &data.JobPublishData{GasPrice: gasPrice}
	if err := job.AddWithData(h.queue, nil, jobType, data.JobOffering,
		offering, data.JobUser, jobData); err != nil {
		logger.Error(err.Error())
		return ErrInternal
	}

	return nil
}

func ( h * Handler ) ChangeOfferingStatus ( tkn , offering , action string , gasPrice uint64 ) error { logger := h . logger . Add ( " " , " " , " " , offering , " " , action , " " , gasPrice ) if ! h . token . Check ( tkn ) { logger . Warn ( " " ) return ErrAccessDenied } jobType , ok := OfferingChangeActions [ action ] if ! ok { logger . Warn ( ErrBadOfferingStatusAction . Error ( ) ) return ErrBadOfferingStatusAction } offer := & data . Offering { } err := h . findByPrimaryKey ( logger , ErrOfferingNotFound , offer , offering ) if err != nil { return err } jobData := & data . JobPublishData { GasPrice : gasPrice } if err := job . AddWithData ( h . queue , nil , jobType , data . JobOffering , offering , data . JobUser , jobData ) ; err != nil { logger . Error ( err . Error ( ) ) return ErrInternal } return nil }

// ChangeOfferingStatus initiates JobAgentPreOfferingMsgBCPublish,
// JobAgentPreOfferingPopUp or JobAgentPreOfferingDelete job,
// depending on a selected action.

ChangeOfferingStatus initiates JobAgentPreOfferingMsgBCPublish JobAgentPreOfferingPopUp or JobAgentPreOfferingDelete job depending on a selected action .


func (h *Handler) GetClientOfferings(tkn string, agent data.HexString,
	minUnitPrice, maxUnitPrice uint64, countries []string,
	offset, limit uint) (*GetClientOfferingsResult, error) {
	logger := h.logger.Add("method", "GetClientOfferings",
		"agent", agent, "minUnitPrice", minUnitPrice,
		"maxUnitPrice", maxUnitPrice, "countries", countries, "offset", offset,
		"limit", limit)

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return nil, ErrAccessDenied
	}

	if minUnitPrice != 0 && maxUnitPrice != 0 &&
		minUnitPrice > maxUnitPrice {
		logger.Error(ErrBadUnitPriceRange.Error())
		return nil, ErrBadUnitPriceRange
	}

	cond, args := h.getClientOfferingsConditions(agent, minUnitPrice,
		maxUnitPrice, countries)

	count, err := h.numberOfObjects(
		logger, data.OfferingTable.Name(), cond, args)
	if err != nil {
		return nil, err
	}

	offsetLimit := h.offsetLimit(offset, limit)

	tail := fmt.Sprintf("%s %s %s",
		cond, activeOfferingSorting, offsetLimit)

	result, err := h.selectAllFrom(
		logger, data.OfferingTable, tail, args...)
	if err != nil {
		return nil, err
	}

	offerings := make([]data.Offering, len(result))

	for k, v := range result {
		offerings[k] = *v.(*data.Offering)
	}

	return &GetClientOfferingsResult{offerings, count}, nil
}

func ( h * Handler ) GetClientOfferings ( tkn string , agent data . HexString , minUnitPrice , maxUnitPrice uint64 , countries [ ] string , offset , limit uint ) ( * GetClientOfferingsResult , error ) { logger := h . logger . Add ( " " , " " , " " , agent , " " , minUnitPrice , " " , maxUnitPrice , " " , countries , " " , offset , " " , limit ) if ! h . token . Check ( tkn ) { logger . Warn ( " " ) return nil , ErrAccessDenied } if minUnitPrice != 0 && maxUnitPrice != 0 && minUnitPrice > maxUnitPrice { logger . Error ( ErrBadUnitPriceRange . Error ( ) ) return nil , ErrBadUnitPriceRange } cond , args := h . getClientOfferingsConditions ( agent , minUnitPrice , maxUnitPrice , countries ) count , err := h . numberOfObjects ( logger , data . OfferingTable . Name ( ) , cond , args ) if err != nil { return nil , err } offsetLimit := h . offsetLimit ( offset , limit ) tail := fmt . Sprintf ( " " , cond , activeOfferingSorting , offsetLimit ) result , err := h . selectAllFrom ( logger , data . OfferingTable , tail , args ... ) if err != nil { return nil , err } offerings := make ( [ ] data . Offering , len ( result ) ) for k , v := range result { offerings [ k ] = * v . ( * data . Offering ) } return & GetClientOfferingsResult { offerings , count } , nil }

// GetClientOfferings returns active offerings available for a client.

GetClientOfferings returns active offerings available for a client .


func (h *Handler) GetAgentOfferings(tkn, product string, statuses []string,
	offset, limit uint) (*GetAgentOfferingsResult, error) {
	logger := h.logger.Add("method", "GetAgentOfferings",
		"product", product, "status", statuses)

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return nil, ErrAccessDenied
	}

	conditions, args := h.getAgentOfferingsConditions(product, statuses)

	count, err := h.numberOfObjects(
		logger, data.OfferingTable.Name(), conditions, args)
	if err != nil {
		return nil, err
	}

	offsetLimit := h.offsetLimit(offset, limit)

	sorting := `ORDER BY block_number_updated DESC`

	tail := fmt.Sprintf("%s %s %s", conditions, sorting, offsetLimit)

	result, err := h.selectAllFrom(
		logger, data.OfferingTable, tail, args...)
	if err != nil {
		return nil, err
	}

	offerings := make([]data.Offering, len(result))

	for k, v := range result {
		offerings[k] = *v.(*data.Offering)
	}

	return &GetAgentOfferingsResult{offerings, count}, nil
}

func
(
h
*
Handler
)
GetAgentOfferings
(
tkn
,
product
string
,
statuses
[
]
string
,
offset
,
limit
uint
)
(
*
GetAgentOfferingsResult
,
error
)
{
logger
:=
h
.
logger
.
Add
(
"
"
,
"
"
,
"
"
,
product
,
"
"
,
statuses
)
if
!
h
.
token
.
Check
(
tkn
)
{
logger
.
Warn
(
"
"
)
return
,
ErrAccessDenied
}
conditions
,
args
:=
h
.
getAgentOfferingsConditions
(
product
,
statuses
)
count
,
err
:=
h
.
numberOfObjects
(
logger
,
data
.
OfferingTable
.
Name
(
)
,
conditions
,
args
)
if
err
!=
{
return
,
err
}
offsetLimit
:=
h
.
offsetLimit
(
offset
,
limit
)
sorting
:=
`ORDER BY block_number_updated DESC`
tail
:=
fmt
.
Sprintf
(
"
"
,
conditions
,
sorting
,
offsetLimit
)
result
,
err
:=
h
.
selectAllFrom
(
logger
,
data
.
OfferingTable
,
tail
,
args
...
)
if
err
!=
{
return
,
err
}
offerings
:=
make
(
[
]
data
.
Offering
,
len
(
result
)
)
for
k
,
v
:=
range
result
{
offerings
[
k
]
=
*
v
.
(
*
data
.
Offering
)
}
return
&
GetAgentOfferingsResult
{
offerings
,
count
}
,
}

// GetAgentOfferings returns active offerings available for a agent.

GetAgentOfferings returns active offerings available for a agent .


func (h *Handler) setOfferingHash(logger log.Logger, offering *data.Offering,
	template *data.Template, agent *data.Account) error {
	handleErr := func(err error) error {
		logger.Error(err.Error())
		return ErrInternal
	}
	msg := offer.OfferingMessage(agent, template, offering)

	msgBytes, err := json.Marshal(msg)
	if err != nil {
		return handleErr(err)
	}

	agentKey, err := h.decryptKeyFunc(agent.PrivateKey, h.pwdStorage.Get())
	if err != nil {
		return handleErr(err)
	}

	packed, err := messages.PackWithSignature(msgBytes, agentKey)
	if err != nil {
		return handleErr(err)
	}

	offering.RawMsg = data.FromBytes(packed)

	hashBytes := common.BytesToHash(crypto.Keccak256(packed))

	offering.Hash = data.HexFromBytes(hashBytes.Bytes())

	return nil
}

func ( h * Handler ) setOfferingHash ( logger log . Logger , offering * data . Offering , template * data . Template , agent * data . Account ) error { handleErr := func ( err error ) error { logger . Error ( err . Error ( ) ) return ErrInternal } msg := offer . OfferingMessage ( agent , template , offering ) msgBytes , err := json . Marshal ( msg ) if err != nil { return handleErr ( err ) } agentKey , err := h . decryptKeyFunc ( agent . PrivateKey , h . pwdStorage . Get ( ) ) if err != nil { return handleErr ( err ) } packed , err := messages . PackWithSignature ( msgBytes , agentKey ) if err != nil { return handleErr ( err ) } offering . RawMsg = data . FromBytes ( packed ) hashBytes := common . BytesToHash ( crypto . Keccak256 ( packed ) ) offering . Hash = data . HexFromBytes ( hashBytes . Bytes ( ) ) return nil }

// setOfferingHash computes and sets values for raw msg and hash fields.

setOfferingHash computes and sets values for raw msg and hash fields .


func (h *Handler) fillOffering(
	logger log.Logger, offering *data.Offering) error {
	agent := &data.Account{}
	// TODO: This is definitely wrong, should be:
	// `h.findByColumn(..., "eth_addr", offering.Agent)`
	if err := h.findByPrimaryKey(logger,
		ErrAccountNotFound, agent, string(offering.Agent)); err != nil {
		return err
	}

	template := &data.Template{}
	if err := h.findByPrimaryKey(logger,
		ErrTemplateNotFound, template, offering.Template); err != nil {
		return err
	}

	offering.ID = util.NewUUID()
	offering.Status = data.OfferEmpty
	offering.Agent = agent.EthAddr
	offering.BlockNumberUpdated = 1
	offering.CurrentSupply = offering.Supply
	// TODO: remove once prepaid is implemented.
	offering.BillingType = data.BillingPostpaid

	return h.setOfferingHash(logger, offering, template, agent)
}

// fillOffering fills offerings nonce, status, hash and signature.

fillOffering fills offerings nonce status hash and signature .


func (h *Handler) UpdateOffering(tkn string, offering *data.Offering) error {
	logger := h.logger.Add(
		"method", "UpdateOffering", "offering", offering)

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return ErrAccessDenied
	}

	err := h.findByPrimaryKey(
		logger, ErrOfferingNotFound, &data.Offering{}, offering.ID)
	if err != nil {
		return err
	}

	err = update(logger, h.db.Querier, offering)
	if err != nil {
		return err
	}

	return nil
}

func ( h * Handler ) UpdateOffering ( tkn string , offering * data . Offering ) error { logger := h . logger . Add ( " " , " " , " " , offering ) if ! h . token . Check ( tkn ) { logger . Warn ( " " ) return ErrAccessDenied } err := h . findByPrimaryKey ( logger , ErrOfferingNotFound , & data . Offering { } , offering . ID ) if err != nil { return err } err = update ( logger , h . db . Querier , offering ) if err != nil { return err } return nil }


func (h *Handler) CreateOffering(tkn string,
	offering *data.Offering) (*string, error) {
	logger := h.logger.Add(
		"method", "CreateOffering", "offering", offering)

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return nil, ErrAccessDenied
	}

	err := h.prepareOffering(logger, offering)
	if err != nil {
		return nil, err
	}

	err = insert(logger, h.db.Querier, offering)
	if err != nil {
		return nil, err
	}

	return &offering.ID, nil
}

func ( h * Handler ) CreateOffering ( tkn string , offering * data . Offering ) ( * string , error ) { logger := h . logger . Add ( " " , " " , " " , offering ) if ! h . token . Check ( tkn ) { logger . Warn ( " " ) return nil , ErrAccessDenied } err := h . prepareOffering ( logger , offering ) if err != nil { return nil , err } err = insert ( logger , h . db . Querier , offering ) if err != nil { return nil , err } return & offering . ID , nil }


func (h *Handler) GetClientOfferingsFilterParams(
	tkn string) (*GetClientOfferingsFilterParamsResult, error) {
	logger := h.logger.Add("method", "GetClientOfferingsFilterParams")

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return nil, ErrAccessDenied
	}

	countries, err := h.offeringCountries(logger)
	if err != nil {
		return nil, err
	}

	min, max, err := h.offeringsMinMaxPrice(logger)
	if err != nil {
		return nil, err
	}

	return &GetClientOfferingsFilterParamsResult{countries, min, max}, nil
}

func ( h * Handler ) GetClientOfferingsFilterParams ( tkn string ) ( * GetClientOfferingsFilterParamsResult , error ) { logger := h . logger . Add ( " " , " " ) if ! h . token . Check ( tkn ) { logger . Warn ( " " ) return nil , ErrAccessDenied } countries , err := h . offeringCountries ( logger ) if err != nil { return nil , err } min , max , err := h . offeringsMinMaxPrice ( logger ) if err != nil { return nil , err } return & GetClientOfferingsFilterParamsResult { countries , min , max } , nil }

// GetClientOfferingsFilterParams returns offerings filter parameters for client.

GetClientOfferingsFilterParams returns offerings filter parameters for client .


func (h *Handler) PingOfferings(tkn string, ids []string) (map[string]bool, error) {
	logger := h.logger.Add("method", "PingOfferings", "ids", ids)

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return nil, ErrAccessDenied
	}

	now := time.Now()
	ret := make(map[string]bool)

	wg := new(sync.WaitGroup)
	wg.Add(len(ids))
	for _, id := range ids {
		offering, err := h.findActiveOfferingByID(logger, id)
		if err != nil {
			return nil, err
		}
		go func(offering *data.Offering) {
			err := h.pingOffering(logger, offering)
			if err == nil {
				ret[offering.ID] = true
				offering.SOMCSuccessPing = &now
				err = update(logger, h.db.Querier, offering)
				if err != nil {
					logger.Warn(err.Error())
				}
			} else {
				ret[offering.ID] = false
				logger.Debug(err.Error())
			}
			wg.Done()
		}(offering)
	}
	wg.Wait()
	return ret, nil
}

func ( h * Handler ) PingOfferings ( tkn string , ids [ ] string ) ( map [ string ] bool , error ) { logger := h . logger . Add ( " " , " " , " " , ids ) if ! h . token . Check ( tkn ) { logger . Warn ( " " ) return nil , ErrAccessDenied } now := time . Now ( ) ret := make ( map [ string ] bool ) wg := new ( sync . WaitGroup ) wg . Add ( len ( ids ) ) for _ , id := range ids { offering , err := h . findActiveOfferingByID ( logger , id ) if err != nil { return nil , err } go func ( offering * data . Offering ) { err := h . pingOffering ( logger , offering ) if err == nil { ret [ offering . ID ] = true offering . SOMCSuccessPing = & now err = update ( logger , h . db . Querier , offering ) if err != nil { logger . Warn ( err . Error ( ) ) } } else { ret [ offering . ID ] = false logger . Debug ( err . Error ( ) ) } wg . Done ( ) } ( offering ) } wg . Wait ( ) return ret , nil }

// PingOfferings given offerings ids pings each of them and returns result of the test.

PingOfferings given offerings ids pings each of them and returns result of the test .


func NewServer(conf *Config) *Server {
	s := &Server{
		conf: conf,
		srv: http.Server{
			Addr:    conf.Addr,
			Handler: http.NewServeMux(),
		},
	}
	return s
}

func NewServer ( conf * Config ) * Server { s := & Server { conf : conf , srv : http . Server { Addr : conf . Addr , Handler : http . NewServeMux ( ) , } , } return s }


func (s *Server) Mux() *http.ServeMux {
	return s.srv.Handler.(*http.ServeMux)
}

func ( s * Server ) Mux ( ) * http . ServeMux { return s . srv . Handler . ( * http . ServeMux ) }

// Mux is an associated http.ServeMux instance.

Mux is an associated http . ServeMux instance .


func NewLogger(conf *Config) (log.Logger, error) {
	l := &reportLogger{}

	base, err := log.NewLoggerBase(conf.BaseConfig, l.log)
	if err != nil {
		return nil, err
	}

	l.LoggerBase = base
	return l, nil
}

func NewLogger ( conf * Config ) ( log . Logger , error ) { l := & reportLogger { } base , err := log . NewLoggerBase ( conf . BaseConfig , l . log ) if err != nil { return nil , err } l . LoggerBase = base return l , nil }

// NewLogger creates a new reporter logger.

NewLogger creates a new reporter logger .


func (l *reportLogger) Printf(format string, v ...interface{}) {
	if l.logger != nil {
		l.logger.Debug(fmt.Sprintf(format, v...))
	}
}

func ( l * reportLogger ) Printf ( format string , v ... interface { } ) { if l . logger != nil { l . logger . Debug ( fmt . Sprintf ( format , v ... ) ) } }

// Printf logs internal messages from a reporter.

Printf logs internal messages from a reporter .


func GetURL(conf *Config, path string) string {
	var proto = "http"
	if conf.TLS != nil {
		proto += "s"
	}

	return proto + "://" + conf.Addr + path
}

func GetURL ( conf * Config , path string ) string { var proto = " " if conf . TLS != nil { proto += " " } return proto + " " + conf . Addr + path }

// GetURL returns a server URL for a given path.

GetURL returns a server URL for a given path .


func NewHTTPRequest(conf *Config, method,
	path string, req *Request) (*http.Request, error) {
	return NewHTTPRequestWithURL(method, GetURL(conf, path), req)
}

func NewHTTPRequest ( conf * Config , method , path string , req * Request ) ( * http . Request , error ) { return NewHTTPRequestWithURL ( method , GetURL ( conf , path ) , req ) }

// NewHTTPRequest creates a new HTTP request from a given server request.

NewHTTPRequest creates a new HTTP request from a given server request .


func NewHTTPRequestWithURL(method, url string, req *Request) (*http.Request, error) {
	data, err := json.Marshal(req)
	if err != nil {
		return nil, err
	}

	return http.NewRequest(
		method, url, bytes.NewReader(data))
}

func NewHTTPRequestWithURL ( method , url string , req * Request ) ( * http . Request , error ) { data , err := json . Marshal ( req ) if err != nil { return nil , err } return http . NewRequest ( method , url , bytes . NewReader ( data ) ) }

// NewHTTPRequestWithURL creates a new HTTP request for a given url.

NewHTTPRequestWithURL creates a new HTTP request for a given url .


func Send(req *http.Request) (*Response, error) {
	client := &http.Client{}

	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var resp2 Response
	if err = json.NewDecoder(resp.Body).Decode(&resp2); err != nil {
		return nil, err
	}

	return &resp2, nil
}

func Send ( req * http . Request ) ( * Response , error ) { client := & http . Client { } resp , err := client . Do ( req ) if err != nil { return nil , err } defer resp . Body . Close ( ) var resp2 Response if err = json . NewDecoder ( resp . Body ) . Decode ( & resp2 ) ; err != nil { return nil , err } return & resp2 , nil }

// Send sends an HTTP request and returns a server response.

Send sends an HTTP request and returns a server response .


func (t *SimpleToken) Check(s string) bool {
	t.mtx.RLock()
	defer t.mtx.RUnlock()
	return s == t.token
}

func ( t * SimpleToken ) Check ( s string ) bool { t . mtx . RLock ( ) defer t . mtx . RUnlock ( ) return s == t . token }

// Check returns true if given string matches stored.

Check returns true if given string matches stored .


func (t *SimpleToken) Make() (string, error) {
	b := make([]byte, 32)
	_, err := rand.Read(b)
	if err != nil {
		return "", err
	}
	t.mtx.Lock()
	defer t.mtx.Unlock()
	t.token = string(data.FromBytes(b))
	return t.token, nil
}

func ( t * SimpleToken ) Make ( ) ( string , error ) { b := make ( [ ] byte , 32 ) _ , err := rand . Read ( b ) if err != nil { return " " , err } t . mtx . Lock ( ) defer t . mtx . Unlock ( ) t . token = string ( data . FromBytes ( b ) ) return t . token , nil }


func (h *Handler) GetLogs(tkn string, levels []string, searchText,
	dateFrom, dateTo string, offset, limit uint) (*GetLogsResult, error) {
	logger := h.logger.Add("method", "GetLogs", "searchText",
		searchText, "levels", levels, "dateFrom", dateFrom, "dateTo",
		dateTo, "offset", offset, "limit", limit)

	if !h.token.Check(tkn) {
		logger.Warn("access denied")
		return nil, ErrAccessDenied
	}

	args := &getLogsArgs{
		level:      levels,
		dateTo:     dateTo,
		dateFrom:   dateFrom,
		searchText: searchText,
	}

	conditions, arguments := h.getLogsConditions(args)
	totalItems, err := h.getTotalLogEvents(logger, conditions, arguments)
	if err != nil {
		return nil, err
	}

	result, err := h.getLogs(logger, conditions, arguments, offset, limit)
	if err != nil {
		return nil, err
	}

	return &GetLogsResult{result, totalItems}, err
}

func ( h * Handler ) GetLogs ( tkn string , levels [ ] string , searchText , dateFrom , dateTo string , offset , limit uint ) ( * GetLogsResult , error ) { logger := h . logger . Add ( " " , " " , " " , searchText , " " , levels , " " , dateFrom , " " , dateTo , " " , offset , " " , limit ) if ! h . token . Check ( tkn ) { logger . Warn ( " " ) return nil , ErrAccessDenied } args := & getLogsArgs { level : levels , dateTo : dateTo , dateFrom : dateFrom , searchText : searchText , } conditions , arguments := h . getLogsConditions ( args ) totalItems , err := h . getTotalLogEvents ( logger , conditions , arguments ) if err != nil { return nil , err } result , err := h . getLogs ( logger , conditions , arguments , offset , limit ) if err != nil { return nil , err } return & GetLogsResult { result , totalItems } , err }

// GetLogs returns back end log, paginated.

GetLogs returns back end log paginated .


func (h *Handler) AuthClient(product, productPassword,
	clientKey, clientPassword string) error {
	logger := h.logger.Add("method", "AuthClient",
		"product", product, "clientKey", clientKey)

	logger.Info("session auth request")

	prod, err := h.checkProductPassword(logger, product, productPassword)
	if err != nil {
		return err
	}

	ch, err := h.findClientChannel(logger, prod, clientKey, false)
	if err != nil {
		return err
	}

	err = data.ValidatePassword(
		ch.Password, clientPassword, string(ch.Salt))
	if err != nil {
		logger.Warn("failed to validate client password: " +
			err.Error())
		return ErrBadClientPassword
	}

	return nil
}

func ( h * Handler ) AuthClient ( product , productPassword , clientKey , clientPassword string ) error { logger := h . logger . Add ( " " , " " , " " , product , " " , clientKey ) logger . Info ( " " ) prod , err := h . checkProductPassword ( logger , product , productPassword ) if err != nil { return err } ch , err := h . findClientChannel ( logger , prod , clientKey , false ) if err != nil { return err } err = data . ValidatePassword ( ch . Password , clientPassword , string ( ch . Salt ) ) if err != nil { logger . Warn ( " " + err . Error ( ) ) return ErrBadClientPassword } return nil }

// AuthClient verifies password for a given client key.

AuthClient verifies password for a given client key .


func (h *Handler) StartSession(product, productPassword,
	clientKey, ip string, port uint16) (*data.Offering, error) {
	logger := h.logger.Add("method", "StartSession", "product", product,
		"clientKey", clientKey, "ip", ip, "port", port)

	logger.Info("session start request")

	prod, err := h.checkProductPassword(logger, product, productPassword)
	if err != nil {
		return nil, err
	}

	ch, err := h.findClientChannel(logger, prod, clientKey, true)
	if err != nil {
		return nil, err
	}

	var offer data.Offering
	if err := h.db.FindByPrimaryKeyTo(&offer, ch.Offering); err != nil {
		logger.Error(err.Error())
		return nil, ErrInternal
	}

	now := time.Now()

	var ipPtr *string
	if len(ip) != 0 {
		ipPtr = pointer.ToString(ip)
	}

	var portPtr *uint16
	if port != 0 {
		portPtr = pointer.ToUint16(port)
	}

	err = h.db.InTransaction(func(tx *reform.TX) error {
		sess := data.Session{
			ID:            util.NewUUID(),
			Channel:       ch.ID,
			Started:       now,
			LastUsageTime: now,
			ClientIP:      ipPtr,
			ClientPort:    portPtr,
		}
		if err := tx.Insert(&sess); err != nil {
			return err
		}

		if ch.ServiceStatus == data.ServiceActivating {
			err := job.AddWithData(h.queue, tx,
				data.JobClientCompleteServiceTransition,
				data.JobChannel, ch.ID, data.JobSessionServer,
				data.ServiceActive)
			if err != nil && err != job.ErrDuplicatedJob {
				return err
			}
		}

		return nil
	})
	if err != nil {
		logger.Error(err.Error())
		return nil, ErrInternal
	}

	return &offer, nil
}

func ( h * Handler ) StartSession ( product , productPassword , clientKey , ip string , port uint16 ) ( * data . Offering , error ) { logger := h . logger . Add ( " " , " " , " " , product , " " , clientKey , " " , ip , " " , port ) logger . Info ( " " ) prod , err := h . checkProductPassword ( logger , product , productPassword ) if err != nil { return nil , err } ch , err := h . findClientChannel ( logger , prod , clientKey , true ) if err != nil { return nil , err } var offer data . Offering if err := h . db . FindByPrimaryKeyTo ( & offer , ch . Offering ) ; err != nil { logger . Error ( err . Error ( ) ) return nil , ErrInternal } now := time . Now ( ) var ipPtr * string if len ( ip ) != 0 { ipPtr = pointer . ToString ( ip ) } var portPtr * uint16 if port != 0 { portPtr = pointer . ToUint16 ( port ) } err = h . db . InTransaction ( func ( tx * reform . TX ) error { sess := data . Session { ID : util . NewUUID ( ) , Channel : ch . ID , Started : now , LastUsageTime : now , ClientIP : ipPtr , ClientPort : portPtr , } if err := tx . Insert ( & sess ) ; err != nil { return err } if ch . ServiceStatus == data . ServiceActivating { err := job . AddWithData ( h . queue , tx , data . JobClientCompleteServiceTransition , data . JobChannel , ch . ID , data . JobSessionServer , data . ServiceActive ) if err != nil && err != job . ErrDuplicatedJob { return err } } return nil } ) if err != nil { logger . Error ( err . Error ( ) ) return nil , ErrInternal } return & offer , nil }

// StartSession creates a new client session.

StartSession creates a new client session .


func (h *Handler) UpdateSession(product, productPassword, clientKey string,
	units uint64, stopSession bool) error {
	logger := h.logger.Add("method", "UpdateSession", "product", product,
		"clientKey", clientKey, "units", units,
		"stopSession", stopSession)

	if stopSession {
		logger.Info("session stop request")
	} else {
		logger.Info("session update request")
	}

	prod, err := h.checkProductPassword(logger, product, productPassword)
	if err != nil {
		return err
	}

	ch, err := h.findClientChannel(logger, prod, clientKey, true)
	if err != nil {
		return err
	}

	// Make the server adapter to kill the session for non-active channel.
	if prod.IsServer && ch.ServiceStatus != data.ServiceActive {
		logger.Warn("non-active channel")
		return ErrNonActiveChannel
	}

	clientStop := !prod.IsServer && stopSession

	if clientStop {
		if ch.ServiceStatus == data.ServiceTerminated {
			logger.Warn("already terminated channel")
			return nil
		}

		status := data.ServiceSuspended
		if ch.ServiceStatus == data.ServiceTerminating {
			status = data.ServiceTerminated
		}

		err := job.AddWithData(h.queue, nil,
			data.JobClientCompleteServiceTransition,
			data.JobChannel, ch.ID, data.JobSessionServer,
			status)
		if err != nil && err != job.ErrDuplicatedJob {
			logger.Error(err.Error())
			return err
		}
	}

	sess, err := h.findCurrentSession(logger, ch.ID)
	if err != nil {
		// Client adapter can signal failure immediately, when no
		// session is yet created.
		if err == ErrSessionNotFound && clientStop {
			return nil
		}
		return err
	}
	logger = logger.Add("session", sess)

	if units != 0 {
		// TODO: Use unit size instead of this hardcode.
		units /= 1024 * 1024

		switch prod.UsageRepType {
		case data.ProductUsageIncremental:
			sess.UnitsUsed += units
		case data.ProductUsageTotal:
			sess.UnitsUsed = units
		default:
			logger.Fatal("unsupported product usage")
		}
	}

	sess.LastUsageTime = time.Now()
	if stopSession {
		sess.Stopped = pointer.ToTime(sess.LastUsageTime)
	}

	logger.Info("updating session")

	if err := h.db.Save(sess); err != nil {
		logger.Error(err.Error())
		return ErrInternal
	}

	return nil
}

// UpdateSession updates and optionally stops the current client session.

UpdateSession updates and optionally stops the current client session .


func OfferingMessage(agent *data.Account, template *data.Template,
	offering *data.Offering) *Message {
	msg := &Message{
		AgentPubKey:        agent.PublicKey,
		TemplateHash:       template.Hash,
		Country:            offering.Country,
		ServiceSupply:      offering.Supply,
		UnitName:           offering.UnitName,
		UnitType:           offering.UnitType,
		BillingType:        offering.BillingType,
		SetupPrice:         offering.SetupPrice,
		UnitPrice:          offering.UnitPrice,
		MinUnits:           offering.MinUnits,
		MaxUnit:            offering.MaxUnit,
		BillingInterval:    offering.BillingInterval,
		MaxBillingUnitLag:  offering.MaxBillingUnitLag,
		MaxSuspendTime:     offering.MaxSuspendTime,
		MaxInactiveTimeSec: offering.MaxInactiveTimeSec,
		FreeUnits:          offering.FreeUnits,
		Nonce:              offering.ID,
		ServiceSpecificParameters: offering.AdditionalParams,
	}
	return msg
}

func OfferingMessage ( agent * data . Account , template * data . Template , offering * data . Offering ) * Message { msg := & Message { AgentPubKey : agent . PublicKey , TemplateHash : template . Hash , Country : offering . Country , ServiceSupply : offering . Supply , UnitName : offering . UnitName , UnitType : offering . UnitType , BillingType : offering . BillingType , SetupPrice : offering . SetupPrice , UnitPrice : offering . UnitPrice , MinUnits : offering . MinUnits , MaxUnit : offering . MaxUnit , BillingInterval : offering . BillingInterval , MaxBillingUnitLag : offering . MaxBillingUnitLag , MaxSuspendTime : offering . MaxSuspendTime , MaxInactiveTimeSec : offering . MaxInactiveTimeSec , FreeUnits : offering . FreeUnits , Nonce : offering . ID , ServiceSpecificParameters : offering . AdditionalParams , } return msg }

// OfferingMessage returns new Offering message


func ValidMsg(schema json.RawMessage, msg Message) bool {
	sch := gojsonschema.NewBytesLoader(schema)
	loader := gojsonschema.NewGoLoader(msg)

	result, err := gojsonschema.Validate(sch, loader)
	if err != nil || !result.Valid() || len(result.Errors()) != 0 {
		return false
	}
	return true
}

func ValidMsg ( schema json . RawMessage , msg Message ) bool { sch := gojsonschema . NewBytesLoader ( schema ) loader := gojsonschema . NewGoLoader ( msg ) result , err := gojsonschema . Validate ( sch , loader ) if err != nil || ! result . Valid ( ) || len ( result . Errors ( ) ) != 0 { return false } return true }

// ValidMsg if is true then offering message corresponds
// to an offer template scheme.

ValidMsg if is true then offering message corresponds to an offer template scheme .


func NewClient(
	cfg *Config, db *reform.DB, log Log, version string) (*Client, error) {
	if log == nil {
		return nil, fmt.Errorf("no log object specified")
	}

	excludedPackagesMap := make(map[string]bool)

	for _, pkg := range cfg.ExcludedPackages {
		excludedPackagesMap[pkg] = true
	}

	pkgSlice, err := pkgList(excludedPackagesMap)
	if err != nil {
		return nil, err
	}

	bugsnag.Configure(bugsnag.Configuration{
		APIKey:              currentAPIKey,
		Logger:              log,
		PanicHandler:        func() {}, // we use our panic processor
		ProjectPackages:     pkgSlice,
		ReleaseStage:        cfg.ReleaseStage,
		NotifyReleaseStages: []string{production, staging},
		AppVersion:          version,
	})

	cli := new(Client)
	cli.db = db
	cli.logger = log
	cli.notifier = bugsnag.New(user(cfg.UserID))

	//check enable service
	e := cli.allowed()
	cli.enable = e
	enable = e
	notifier = cli.notifier
	return cli, nil
}

func
NewClient
(
cfg
*
Config
,
db
*
reform
.
DB
,
log
Log
,
version
string
)
(
*
Client
,
error
)
{
if
log
==
{
return
,
fmt
.
Errorf
(
"
"
)
}
excludedPackagesMap
:=
make
(
map
[
string
]
bool
)
for
_
,
pkg
:=
range
cfg
.
ExcludedPackages
{
excludedPackagesMap
[
pkg
]
=
true
}
pkgSlice
,
err
:=
pkgList
(
excludedPackagesMap
)
if
err
!=
{
return
,
err
}
bugsnag
.
Configure
(
bugsnag
.
Configuration
{
APIKey
:
currentAPIKey
,
Logger
:
log
,
PanicHandler
:
func
(
)
{
}
,
// we use our panic processor
ProjectPackages
:
pkgSlice
,
ReleaseStage
:
cfg
.
ReleaseStage
,
NotifyReleaseStages
:
[
]
string
{
production
,
staging
}
,
AppVersion
:
version
,
}
)
cli
:=
new
(
Client
)
cli
.
db
=
db
cli
.
logger
=
log
cli
.
notifier
=
bugsnag
.
New
(
user
(
cfg
.
UserID
)
)
//check enable service
e
:=
cli
.
allowed
(
)
cli
.
enable
=
e
enable
=
e
notifier
=
cli
.
notifier
return
cli
,
}

// NewClient initializing Bugsnag client.
// Bugsnag client that automatic error sender to remote server.
// We use this service to collect anonymous information
// about the error and panic.
// Service is activated if exist entry key = "error.sendremote"
// and value = true in the database settings table.

NewClient initializing Bugsnag client . Bugsnag client that automatic error sender to remote server . We use this service to collect anonymous information about the error and panic . Service is activated if exist entry key = error . sendremote and value = true in the database settings table .


func PanicHunter() {
	if panicIgnore {
		return
	}

	if err := recover(); err != nil {
		if enable && notifier != nil {
			notifier.NotifySync(
				errors.New(err, 3), true,
				metadata([]data.HexString{defaultAccEth}))
		}
		panic(err)
	}
}

func PanicHunter ( ) { if panicIgnore { return } if err := recover ( ) ; err != nil { if enable && notifier != nil { notifier . NotifySync ( errors . New ( err , 3 ) , true , metadata ( [ ] data . HexString { defaultAccEth } ) ) } panic ( err ) } }

// PanicHunter catches panic, in case of an enabled reporter.

PanicHunter catches panic in case of an enabled reporter .


func (s *Server) ParseRequest(logger log.Logger,
	w http.ResponseWriter, r *http.Request, args interface{}) bool {
	var req Request
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		logger.Warn("failed to parse request: " + err.Error())
		s.RespondError(logger, w, ErrFailedToParseRequest)
		return false
	}
	r.Body.Close()

	if err := json.Unmarshal(req.Args, args); err != nil {
		logger.Add("arguments", req.Args).Warn(
			"failed to parse request arguments: " + err.Error())
		s.RespondError(logger, w, ErrFailedToParseRequest)
		return false
	}

	return true
}

func ( s * Server ) ParseRequest ( logger log . Logger , w http . ResponseWriter , r * http . Request , args interface { } ) bool { var req Request if err := json . NewDecoder ( r . Body ) . Decode ( & req ) ; err != nil { logger . Warn ( " " + err . Error ( ) ) s . RespondError ( logger , w , ErrFailedToParseRequest ) return false } r . Body . Close ( ) if err := json . Unmarshal ( req . Args , args ) ; err != nil { logger . Add ( " " , req . Args ) . Warn ( " " + err . Error ( ) ) s . RespondError ( logger , w , ErrFailedToParseRequest ) return false } return true }

// ParseRequest parses request handling possible errors.

ParseRequest parses request handling possible errors .


func (i *Ipvs) Save() error {
	out, err := backendRun([]string{"ipvsadm", "-S", "-n"})
	if err != nil {
		return err
	}

	i.Services = make([]Service, 0, 0)
	serviceStrings := strings.Split(string(out), "-A")
	for j := range serviceStrings {
		if serviceStrings[j] == "" {
			continue
		}
		serverStrings := strings.Split(serviceStrings[j], "-a")
		serviceString := serverStrings[0]
		serverStrings = serverStrings[1:]
		// fmt.Println("Service: ", serviceString)
		service := parseService(serviceString)
		for k := range serverStrings {
			// fmt.Println("Server: ", serverStrings[j])
			server := parseServer(serverStrings[k])
			service.Servers = append(service.Servers, server)
		}
		i.Services = append(i.Services, service)
	}
	return nil
}

// save reads the applied ipvsadm rules from the host and saves them as i.Services

save reads the applied ipvsadm rules from the host and saves them as i . Services


func NewClient(httpClient *http.Client, mode, clientID, clientSecret, accessToken string) *Client {
	b := sling.New().Client(httpClient).Base(baseURL)
	b.QueryStruct(struct {
		V            string `url:"v"`
		M            string `url:"m"`
		ClientID     string `url:"client_id"`
		ClientSecret string `url:"client_secret,omitempty"`
		AccessToken  string `url:"access_token,omitempty"`
	}{
		V:            version,
		M:            mode,
		ClientID:     clientID,
		ClientSecret: clientSecret,
		AccessToken:  accessToken,
	})

	return &Client{
		sling:  b,
		Venues: newVenueService(b.New()),
	}
}

func NewClient ( httpClient * http . Client , mode , clientID , clientSecret , accessToken string ) * Client { b := sling . New ( ) . Client ( httpClient ) . Base ( baseURL ) b . QueryStruct ( struct { V string `url:"v"` M string `url:"m"` ClientID string `url:"client_id"` ClientSecret string `url:"client_secret,omitempty"` AccessToken string `url:"access_token,omitempty"` } { V : version , M : mode , ClientID : clientID , ClientSecret : clientSecret , AccessToken : accessToken , } ) return & Client { sling : b , Venues : newVenueService ( b . New ( ) ) , } }


func ParseRate(resp *http.Response) *RateLimit {
	limit := resp.Header.Get(headerRateLimit)
	path := resp.Header.Get(headerRatePath)
	remain := resp.Header.Get(headerRateRemaining)

	l, _ := strconv.Atoi(limit)
	r, _ := strconv.Atoi(remain)

	return &RateLimit{
		Limit:     l,
		Path:      path,
		Remaining: r,
	}
}

func ParseRate ( resp * http . Response ) * RateLimit { limit := resp . Header . Get ( headerRateLimit ) path := resp . Header . Get ( headerRatePath ) remain := resp . Header . Get ( headerRateRemaining ) l , _ := strconv . Atoi ( limit ) r , _ := strconv . Atoi ( remain ) return & RateLimit { Limit : l , Path : path , Remaining : r , } }

// ParseRate is a helper function to get all the Rate info


func (t *BTTracer) SetOutputPath(path string, perm os.FileMode) error {
	return nil
}

func ( t * BTTracer ) SetOutputPath ( path string , perm os . FileMode ) error { return nil }

// Sets the output path for generated snapshots.

Sets the output path for generated snapshots .


func UpdateConfig(c GlobalConfig) {
	state.m.Lock()
	defer state.m.Unlock()

	state.c = c
}

func UpdateConfig ( c GlobalConfig ) { state . m . Lock ( ) defer state . m . Unlock ( ) state . c = c }


func (t *BTTracer) SetTracerPath(path string) {
	t.m.Lock()
	defer t.m.Unlock()

	t.cmd = path
}

func ( t * BTTracer ) SetTracerPath ( path string ) { t . m . Lock ( ) defer t . m . Unlock ( ) t . cmd = path }

// Sets the executable path for the tracer.

Sets the executable path for the tracer .


func (t *BTTracer) SetOutputPath(path string, perm os.FileMode) error {
	if perm == 0 {
		perm = 0755
	}

	if err := os.MkdirAll(path, perm); err != nil {
		t.Logf(LogError, "Failed to create output directory: %v\n", err)
		return err
	}

	t.m.Lock()
	defer t.m.Unlock()

	t.outputDir = path

	return nil
}

func ( t * BTTracer ) SetOutputPath ( path string , perm os . FileMode ) error { if perm == 0 { perm = 0755 } if err := os . MkdirAll ( path , perm ) ; err != nil { t . Logf ( LogError , " \n " , err ) return err } t . m . Lock ( ) defer t . m . Unlock ( ) t . outputDir = path return nil }

// Sets the output path for generated snapshots. The directory will be
// created with the specified permission bits if it does not already
// exist.
//
// If perm is 0, a default of 0755 will be used.

Sets the output path for generated snapshots . The directory will be created with the specified permission bits if it does not already exist . If perm is 0 a default of 0755 will be used .


func (t *BTTracer) SetPipes(stdin io.Reader, stderr io.Writer) {
	t.m.Lock()
	defer t.m.Unlock()

	t.p.stdin = stdin
	t.p.stderr = stderr
}

func ( t * BTTracer ) SetPipes ( stdin io . Reader , stderr io . Writer ) { t . m . Lock ( ) defer t . m . Unlock ( ) t . p . stdin = stdin t . p . stderr = stderr }

// Sets the input and output pipes for the tracer.
// Stdout is not redirected; it is instead passed to the
// tracer's Put command.

Sets the input and output pipes for the tracer . Stdout is not redirected ; it is instead passed to the tracer s Put command .


func AppendOptionWithPrefix(options []string, prefix string, v string) []string {
	for i, opt := range options {
		if strings.HasPrefix(opt, prefix) == true {
			new_opt := opt + "," + v
			options[i] = new_opt
			return options
		}
	}
	return append(options, prefix + v)
}

func AppendOptionWithPrefix ( options [ ] string , prefix string , v string ) [ ] string { for i , opt := range options { if strings . HasPrefix ( opt , prefix ) == true { new_opt := opt + " " + v options [ i ] = new_opt return options } } return append ( options , prefix + v ) }

// Append to an option with given prefix


func (m *Marshaller) MarshalRaw(bs []byte) {
	if m.Error != nil {
		return
	}
	if len(m.Data) < m.offset+len(bs) {
		m.Error = io.ErrShortBuffer
		return
	}

	m.offset += copy(m.Data[m.offset:], bs)
}

func ( m * Marshaller ) MarshalRaw ( bs [ ] byte ) { if m . Error != nil { return } if len ( m . Data ) < m . offset + len ( bs ) { m . Error = io . ErrShortBuffer return } m . offset += copy ( m . Data [ m . offset : ] , bs ) }

// MarshalRaw copies the raw bytes to the buffer, without a size prefix or
// padding. This is suitable for appending data already in XDR format from
// another source.

MarshalRaw copies the raw bytes to the buffer without a size prefix or padding . This is suitable for appending data already in XDR format from another source .


func (m *Marshaller) MarshalString(s string) {
	if m.Error != nil {
		return
	}
	if len(m.Data) < m.offset+4+len(s)+Padding(len(s)) {
		m.Error = io.ErrShortBuffer
		return
	}

	m.MarshalUint32(uint32(len(s)))
	m.offset += copy(m.Data[m.offset:], s)
	m.offset += copy(m.Data[m.offset:], padBytes[:Padding(len(s))])
}

func ( m * Marshaller ) MarshalString ( s string ) { if m . Error != nil { return } if len ( m . Data ) < m . offset + 4 + len ( s ) + Padding ( len ( s ) ) { m . Error = io . ErrShortBuffer return } m . MarshalUint32 ( uint32 ( len ( s ) ) ) m . offset += copy ( m . Data [ m . offset : ] , s ) m . offset += copy ( m . Data [ m . offset : ] , padBytes [ : Padding ( len ( s ) ) ] ) }

// MarshalString appends the string to the buffer, with a size prefix and
// correct padding.

MarshalString appends the string to the buffer with a size prefix and correct padding .


func (m *Marshaller) MarshalBytes(bs []byte) {
	if m.Error != nil {
		return
	}
	if len(m.Data) < m.offset+4+len(bs)+Padding(len(bs)) {
		m.Error = io.ErrShortBuffer
		return
	}

	m.MarshalUint32(uint32(len(bs)))
	m.offset += copy(m.Data[m.offset:], bs)
	m.offset += copy(m.Data[m.offset:], padBytes[:Padding(len(bs))])
}

func ( m * Marshaller ) MarshalBytes ( bs [ ] byte ) { if m . Error != nil { return } if len ( m . Data ) < m . offset + 4 + len ( bs ) + Padding ( len ( bs ) ) { m . Error = io . ErrShortBuffer return } m . MarshalUint32 ( uint32 ( len ( bs ) ) ) m . offset += copy ( m . Data [ m . offset : ] , bs ) m . offset += copy ( m . Data [ m . offset : ] , padBytes [ : Padding ( len ( bs ) ) ] ) }

// MarshalString appends the bytes to the buffer, with a size prefix and
// correct padding.

MarshalString appends the bytes to the buffer with a size prefix and correct padding .


func (m *Marshaller) MarshalBool(v bool) {
	if v {
		m.MarshalUint8(1)
	} else {
		m.MarshalUint8(0)
	}
}

func ( m * Marshaller ) MarshalBool ( v bool ) { if v { m . MarshalUint8 ( 1 ) } else { m . MarshalUint8 ( 0 ) } }

// MarshalString appends the bool to the buffer, as an uint32.

MarshalString appends the bool to the buffer as an uint32 .


func (m *Marshaller) MarshalUint32(v uint32) {
	if m.Error != nil {
		return
	}
	if len(m.Data) < m.offset+4 {
		m.Error = io.ErrShortBuffer
		return
	}

	m.Data[m.offset+0] = byte(v >> 24)
	m.Data[m.offset+1] = byte(v >> 16)
	m.Data[m.offset+2] = byte(v >> 8)
	m.Data[m.offset+3] = byte(v)
	m.offset += 4
}

func ( m * Marshaller ) MarshalUint32 ( v uint32 ) { if m . Error != nil { return } if len ( m . Data ) < m . offset + 4 { m . Error = io . ErrShortBuffer return } m . Data [ m . offset + 0 ] = byte ( v >> 24 ) m . Data [ m . offset + 1 ] = byte ( v >> 16 ) m . Data [ m . offset + 2 ] = byte ( v >> 8 ) m . Data [ m . offset + 3 ] = byte ( v ) m . offset += 4 }

// MarshalString appends the uint32 to the buffer.

MarshalString appends the uint32 to the buffer .


func (m *Marshaller) MarshalUint64(v uint64) {
	if m.Error != nil {
		return
	}
	if len(m.Data) < m.offset+8 {
		m.Error = io.ErrShortBuffer
		return
	}

	m.Data[m.offset+0] = byte(v >> 56)
	m.Data[m.offset+1] = byte(v >> 48)
	m.Data[m.offset+2] = byte(v >> 40)
	m.Data[m.offset+3] = byte(v >> 32)
	m.Data[m.offset+4] = byte(v >> 24)
	m.Data[m.offset+5] = byte(v >> 16)
	m.Data[m.offset+6] = byte(v >> 8)
	m.Data[m.offset+7] = byte(v)
	m.offset += 8
}

func ( m * Marshaller ) MarshalUint64 ( v uint64 ) { if m . Error != nil { return } if len ( m . Data ) < m . offset + 8 { m . Error = io . ErrShortBuffer return } m . Data [ m . offset + 0 ] = byte ( v >> 56 ) m . Data [ m . offset + 1 ] = byte ( v >> 48 ) m . Data [ m . offset + 2 ] = byte ( v >> 40 ) m . Data [ m . offset + 3 ] = byte ( v >> 32 ) m . Data [ m . offset + 4 ] = byte ( v >> 24 ) m . Data [ m . offset + 5 ] = byte ( v >> 16 ) m . Data [ m . offset + 6 ] = byte ( v >> 8 ) m . Data [ m . offset + 7 ] = byte ( v ) m . offset += 8 }

// MarshalString appends the uint64 to the buffer.

MarshalString appends the uint64 to the buffer .


func ElementSizeExceeded(field string, size, limit int) error {
	return fmt.Errorf("%s exceeds size limit; %d > %d", field, size, limit)
}

func ElementSizeExceeded ( field string , size , limit int ) error { return fmt . Errorf ( " " , field , size , limit ) }

// ElementSizeExceeded returns an error describing the violated size
// constraint. This function is used by the generated marshalling code.

ElementSizeExceeded returns an error describing the violated size constraint . This function is used by the generated marshalling code .


func (e *encoder) nextSpecialChar(p []byte) (i int) {
	for i = 0; i < len(p); i++ {
		// ASCII 32-126 (printable) + '\t' - '=' can appear in the qprintable stream
		if !((p[i] >= 32 && p[i] <= 126 && p[i] != byte('=')) || p[i] == byte('\t')) {
			return i
		}
	}
	return i
}

// Return first character position where the character has to be escaped


func (d *decoder) nextSpecialChar(p []byte) (i int) {
	for i = 0; i < len(p); i++ {
		if p[i] == byte('=') || (d.enc.isText && p[i] == byte('\r')) {
			return i
		}
	}
	return i
}

func ( d * decoder ) nextSpecialChar ( p [ ] byte ) ( i int ) { for i = 0 ; i < len ( p ) ; i ++ { if p [ i ] == byte ( '=' ) || ( d . enc . isText && p [ i ] == byte ( '\r' ) ) { return i } } return i }

// Return first character position where the character has to be decoded


func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
	return &decoder{enc: enc, r: r,
		buf:       bytes.NewBuffer(nil),
		leftovers: bytes.NewBuffer(nil)}
}

func NewDecoder ( enc * Encoding , r io . Reader ) io . Reader { return & decoder { enc : enc , r : r , buf : bytes . NewBuffer ( nil ) , leftovers : bytes . NewBuffer ( nil ) } }

// Returns a new decoder. Data will be read from r, and decoded
// according to enc.

Returns a new decoder . Data will be read from r and decoded according to enc .


func (di *dependencyInjector) Register(constructorFunc interface{}) error {
	constructorType := reflect.TypeOf(constructorFunc)

	if (constructorType.Kind() != reflect.Func) || (constructorType.NumOut() != 1) {
		return constructorErr
	}
	outType := constructorType.Out(0)

	// make sure we can resolve the constuctor arguments
	for i := 0; i < constructorType.NumIn(); i++ {
		inType := constructorType.In(i)
		_, ok := di.registry[inType]
		if !ok {
			return fmt.Errorf("Can't resolve function arguments - can't find a %s for a %s\n", inType, outType)
		}
	}

	di.registry[outType] = constructorFunc

	return nil
}

// Register registers a constructor function
// with the DI container

Register registers a constructor function with the DI container


func (di *dependencyInjector) MustRegister(constructorFunc interface{}) {
	err := di.Register(constructorFunc)
	if err != nil {
		panic(err)
	}
}

func ( di * dependencyInjector ) MustRegister ( constructorFunc interface { } ) { err := di . Register ( constructorFunc ) if err != nil { panic ( err ) } }

// MustRegister is a helper that calls Register and panics if it returns an error


func (di *dependencyInjector) Create(avar interface{}) interface{} {
	varType := reflect.TypeOf(avar)

	if di.caching {
		return di.cachedCreateFromType(varType).Interface()
	} else {
		return di.CreateFromType(varType).Interface()
	}
}

func ( di * dependencyInjector ) Create ( avar interface { } ) interface { } { varType := reflect . TypeOf ( avar ) if di . caching { return di . cachedCreateFromType ( varType ) . Interface ( ) } else { return di . CreateFromType ( varType ) . Interface ( ) } }

// Create creates an instance of the type of the given parameter


func (di *dependencyInjector) cachedCreateFromType(atype reflect.Type) reflect.Value {
	_, exists := di.instances[atype]

	if !exists {
		di.instances[atype] = di.createFromType(atype)
	}

	return di.instances[atype]
}

func ( di * dependencyInjector ) cachedCreateFromType ( atype reflect . Type ) reflect . Value { _ , exists := di . instances [ atype ] if ! exists { di . instances [ atype ] = di . createFromType ( atype ) } return di . instances [ atype ] }

// cachedCreateFromType creates an instance of the given type


func NewDependencyInjector() DependencyInjector {
	return &dependencyInjector{
		registry:  make(map[reflect.Type]interface{}),
		instances: make(map[reflect.Type]reflect.Value),
	}
}

func NewDependencyInjector ( ) DependencyInjector { return & dependencyInjector { registry : make ( map [ reflect . Type ] interface { } ) , instances : make ( map [ reflect . Type ] reflect . Value ) , } }

// NewDependencyInjector returns a new DependencyInjector