proc/worker/client.go
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)
}
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.