func (c *CryptoClient) DecodeMessage(packet sphinx.SphinxPacket) (sphinx.SphinxPacket, error) {
	return packet, nil
}
DecodeMessage decodes the received sphinx packet.
TODO: this function is finished yet.
package clientcore
import (
	"errors"
	"fmt"
	"time"
	"github.com/golang/protobuf/proto"
	"github.com/nymtech/nym-mixnet/config"
	"github.com/nymtech/nym-mixnet/helpers"
	"github.com/nymtech/nym-mixnet/helpers/topology"
	"github.com/nymtech/nym-mixnet/sphinx"
	"github.com/sirupsen/logrus"
)
const (
	maximumTopologyAge = 1 * time.Minute
)
var (
	ErrInvalidMixes = errors.New("insufficient number of mixes provided")
)
type NetworkPKI struct {
	lastUpdated time.Time
	Mixes       topology.LayeredMixes
	Clients     []config.ClientConfig
}
func (n *NetworkPKI) UpdateNetwork(newMixes topology.LayeredMixes, newClients []config.ClientConfig) {
	n.Mixes = newMixes
	n.Clients = newClients
	n.lastUpdated = time.Now()
}
func (n *NetworkPKI) ShouldUpdate() bool {
	return n.lastUpdated.Add(maximumTopologyAge).Before(time.Now())
}
type MixClient interface {
	EncodeIntoSphinxPacket(message string, recipient config.ClientConfig) ([]byte, error)
	DecodeSphinxPacket(packet sphinx.SphinxPacket) (sphinx.SphinxPacket, error)
	GetPublicKey() *sphinx.PublicKey
}
type CryptoClient struct {
	pubKey   *sphinx.PublicKey
	prvKey   *sphinx.PrivateKey
	Provider config.MixConfig
	Network  NetworkPKI
	log      *logrus.Logger
}
const (
	desiredRateParameter = 5
	pathLength           = 3
)
func (c *CryptoClient) createSphinxPacket(message []byte, recipient config.ClientConfig) ([]byte, error) {
	path, err := c.buildPath(recipient)
	if err != nil {
		c.log.Errorf("error in CreateSphinxPacket - generating random path failed: %v", err)
		return nil, err
	}
	delays, err := c.generateDelaySequence(desiredRateParameter, path.Len())
	if err != nil {
		c.log.Errorf("error in CreateSphinxPacket - generating sequence of delays failed: %v", err)
		return nil, err
	}
	sphinxPacket, err := sphinx.PackForwardMessage(path, delays, message)
	if err != nil {
		c.log.Errorf("error in CreateSphinxPacket - the pack procedure failed: %v", err)
		return nil, err
	}
	return proto.Marshal(&sphinxPacket)
}
func (c *CryptoClient) buildPath(recipient config.ClientConfig) (config.E2EPath, error) {
	mixSeq, err := c.getRandomMixSequence(c.Network.Mixes, pathLength)
	if err != nil {
		c.log.Errorf("error in buildPath - generating random mix path failed: %v", err)
		return config.E2EPath{}, err
	}
	if recipient.Provider == nil || len(recipient.Provider.PubKey) == 0 {
		err := fmt.Errorf("error in buildPath - could not create path to the recipient," +
			" the EgressProvider has invalid configuration")
		c.log.Error(err.Error())
		return config.E2EPath{}, err
	}
	path := config.E2EPath{IngressProvider: c.Provider,
		Mixes:          mixSeq,
		EgressProvider: *recipient.Provider,
		Recipient:      recipient,
	}
	return path, nil
}
func (c *CryptoClient) getRandomMixSequence(mixes topology.LayeredMixes, length int) ([]config.MixConfig, error) {
	if mixes == nil || len(mixes) < length {
		return nil, ErrInvalidMixes
	}
	mixSequence := make([]config.MixConfig, length)
	for i := 1; i <= length; i++ {
		if layerMixes, ok := mixes[uint(i)]; ok {
			mixSequence[i-1] = helpers.RandomMix(layerMixes)
		} else {
			return nil, fmt.Errorf("no valid mixes for layer: %v", i)
		}
	}
	return mixSequence, nil
}
func (c *CryptoClient) generateDelaySequence(desiredRateParameter float64, length int) ([]float64, error) {
	var delays []float64
	for i := 0; i < length; i++ {
		d, err := helpers.RandomExponential(desiredRateParameter)
		if err != nil {
			c.log.Errorf("Error in generateDelaySequence - generating random exponential sample failed: %v", err)
			return nil, err
		}
		delays = append(delays, d)
	}
	return delays, nil
}
func (c *CryptoClient) EncodeMessage(message []byte, recipient config.ClientConfig) ([]byte, error) {
	packet, err := c.createSphinxPacket(message, recipient)
	if err != nil {
		c.log.Errorf("Error in EncodeMessage - the pack procedure failed: %v", err)
		return nil, err
	}
	return packet, err
}