func (b *Bid) ReservedValue(feeSchedule terms.FeeSchedule) btcutil.Amount {
	clearingPrice := FixedRatePremium(b.FixedRate)
	return reservedValue(b, func(amt btcutil.Amount) btcutil.Amount {
		delta, _, _ := takerDelta(
			feeSchedule, clearingPrice, amt, b.SelfChanBalance,
			b.LeaseDuration,
		)
		return delta
	})
}
ReservedValue returns the maximum value that could be deducted from a single
account if the bid is is matched under the worst case fee conditions.
package order
import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"fmt"
	"net"
	"github.com/btcsuite/btcutil"
	"github.com/lightninglabs/pool/account"
	"github.com/lightninglabs/pool/auctioneerrpc"
	"github.com/lightninglabs/pool/sidecar"
	"github.com/lightninglabs/pool/terms"
	"github.com/lightningnetwork/lnd/keychain"
	"github.com/lightningnetwork/lnd/lntypes"
	"github.com/lightningnetwork/lnd/lnwallet/chainfee"
	"github.com/lightningnetwork/lnd/lnwire"
)
type Nonce [32]byte
func (n Nonce) String() string {
	return hex.EncodeToString(n[:])
}
type Version uint32
const (
	VersionDefault Version = 0
	VersionNodeTierMinMatch Version = 1
	VersionLeaseDurationBuckets Version = 2
	VersionSelfChanBalance Version = 3
	VersionSidecarChannel Version = 4
)
type Type uint8
const (
	TypeAsk Type = 0
	TypeBid Type = 1
)
func (t Type) String() string {
	switch t {
	case TypeAsk:
		return "Ask"
	case TypeBid:
		return "Bid"
	default:
		return "<unknown>"
	}
}
type State uint8
const (
	StateSubmitted State = 0
	StateCleared State = 1
	StatePartiallyFilled State = 2
	StateExecuted State = 3
	StateCanceled State = 4
	StateExpired State = 5
	StateFailed State = 6
)
func (s State) String() string {
	switch s {
	case StateSubmitted:
		return "submitted"
	case StateCleared:
		return "cleared"
	case StatePartiallyFilled:
		return "partially_filled"
	case StateExecuted:
		return "executed"
	case StateCanceled:
		return "canceled"
	case StateExpired:
		return "expired"
	case StateFailed:
		return "failed"
	default:
		return fmt.Sprintf("unknown<%d>", s)
	}
}
func (s State) Archived() bool {
	switch s {
	case StateExecuted, StateCanceled, StateExpired, StateFailed:
		return true
	default:
		return false
	}
}
type MatchState uint8
const (
	MatchStatePrepare MatchState = 0
	MatchStateAccepted MatchState = 1
	MatchStateRejected MatchState = 2
	MatchStateSigned MatchState = 3
	MatchStateFinalized MatchState = 4
)
func (s MatchState) String() string {
	switch s {
	case MatchStatePrepare:
		return "prepare"
	case MatchStateAccepted:
		return "accepted"
	case MatchStateSigned:
		return "signed"
	case MatchStateFinalized:
		return "finalized"
	case MatchStateRejected:
		return "rejected"
	default:
		return fmt.Sprintf("unknown<%d>", s)
	}
}
var (
	ErrInsufficientBalance = errors.New("insufficient account balance")
	ZeroNonce Nonce
)
type Order interface {
	Nonce() Nonce
	Details() *Kit
	Type() Type
	Digest() ([sha256.Size]byte, error)
	ReservedValue(feeSchedule terms.FeeSchedule) btcutil.Amount
}
type Kit struct {
	nonce Nonce
	Preimage lntypes.Preimage
	Version Version
	State State
	FixedRate uint32
	Amt btcutil.Amount
	Units SupplyUnit
	UnitsUnfulfilled SupplyUnit
	MultiSigKeyLocator keychain.KeyLocator
	MaxBatchFeeRate chainfee.SatPerKWeight
	AcctKey [33]byte
	LeaseDuration uint32
	MinUnitsMatch SupplyUnit
}
func (k *Kit) Nonce() Nonce {
	return k.nonce
}
func (k *Kit) Details() *Kit {
	return k
}
func NewKitWithPreimage(preimage lntypes.Preimage) *Kit {
	var nonce Nonce
	hash := preimage.Hash()
	copy(nonce[:], hash[:])
	return &Kit{
		nonce:    nonce,
		Preimage: preimage,
		Version:  VersionLeaseDurationBuckets,
	}
}
func NewKit(nonce Nonce) *Kit {
	return &Kit{
		nonce:   nonce,
		Version: VersionLeaseDurationBuckets,
	}
}
type Ask struct {
	Kit
}
func (a *Ask) Type() Type {
	return TypeAsk
}
func (a *Ask) Digest() ([sha256.Size]byte, error) {
	var (
		msg    bytes.Buffer
		result [sha256.Size]byte
	)
	switch a.Kit.Version {
	case VersionDefault:
		err := lnwire.WriteElements(
			&msg, a.nonce[:], uint32(a.Version), a.FixedRate,
			a.Amt, a.LeaseDuration, uint64(a.MaxBatchFeeRate),
		)
		if err != nil {
			return result, err
		}
	case VersionNodeTierMinMatch, VersionLeaseDurationBuckets,
		VersionSelfChanBalance, VersionSidecarChannel:
		err := lnwire.WriteElements(
			&msg, a.nonce[:], uint32(a.Version), a.FixedRate,
			a.Amt, a.LeaseDuration, uint64(a.MaxBatchFeeRate),
			uint32(a.MinUnitsMatch),
		)
		if err != nil {
			return result, err
		}
	default:
		return result, fmt.Errorf("unknown version %d", a.Kit.Version)
	}
	return sha256.Sum256(msg.Bytes()), nil
}
func reservedValue(o Order,
	perMatchDelta func(btcutil.Amount) btcutil.Amount) btcutil.Amount {
	if o.Details().State.Archived() {
		return 0
	}
	totalSats := o.Details().UnitsUnfulfilled.ToSatoshis()
	minMatchSize := o.Details().MinUnitsMatch.ToSatoshis()
	maxNumMatches := totalSats / minMatchSize
	rem := btcutil.Amount(0)
	if maxNumMatches*minMatchSize < totalSats {
		maxNumMatches--
		rem = totalSats - maxNumMatches*minMatchSize
	}
	balanceDelta := maxNumMatches * perMatchDelta(minMatchSize)
	if rem > 0 {
		balanceDelta += perMatchDelta(rem)
	}
	maxFeeRate := o.Details().MaxBatchFeeRate
	balanceDelta -= maxNumMatches * EstimateTraderFee(1, maxFeeRate)
	if rem > 0 {
		balanceDelta -= EstimateTraderFee(1, maxFeeRate)
	}
	if balanceDelta < 0 {
		return -balanceDelta
	}
	return 0
}
func (a *Ask) ReservedValue(feeSchedule terms.FeeSchedule) btcutil.Amount {
	clearingPrice := FixedRatePremium(a.FixedRate)
	return reservedValue(a, func(amt btcutil.Amount) btcutil.Amount {
		delta, _, _ := makerDelta(
			feeSchedule, clearingPrice, amt, a.LeaseDuration,
		)
		return delta
	})
}
type NodeTier uint32
const (
	NodeTierDefault NodeTier = 0
	NodeTier0 NodeTier = 1
	NodeTier1 NodeTier = 2
)
const DefaultMinNodeTier = NodeTier1
func (n NodeTier) String() string {
	switch n {
	case NodeTier0:
		return "NodeTier0"
	case NodeTier1:
		return "NodeTier1"
	case NodeTierDefault:
		return "NodeTierDefault"
	default:
		return fmt.Sprintf("UnknownNodeTier(%v)", uint32(n))
	}
}
type Bid struct {
	Kit
	MinNodeTier NodeTier
	SelfChanBalance btcutil.Amount
	SidecarTicket *sidecar.Ticket
}
func (b *Bid) Type() Type {
	return TypeBid
}
func (b *Bid) Digest() ([sha256.Size]byte, error) {
	var (
		msg    bytes.Buffer
		result [sha256.Size]byte
	)
	switch b.Kit.Version {
	case VersionDefault:
		err := lnwire.WriteElements(
			&msg, b.nonce[:], uint32(b.Version), b.FixedRate,
			b.Amt, b.LeaseDuration, uint64(b.MaxBatchFeeRate),
		)
		if err != nil {
			return result, err
		}
	case VersionNodeTierMinMatch, VersionLeaseDurationBuckets:
		err := lnwire.WriteElements(
			&msg, b.nonce[:], uint32(b.Version), b.FixedRate,
			b.Amt, b.LeaseDuration, uint64(b.MaxBatchFeeRate),
			uint32(b.MinNodeTier), uint32(b.MinUnitsMatch),
		)
		if err != nil {
			return result, err
		}
	case VersionSelfChanBalance:
		err := lnwire.WriteElements(
			&msg, b.nonce[:], uint32(b.Version), b.FixedRate,
			b.Amt, b.LeaseDuration, uint64(b.MaxBatchFeeRate),
			uint32(b.MinNodeTier), uint32(b.MinUnitsMatch),
			uint64(b.SelfChanBalance),
		)
		if err != nil {
			return result, err
		}
	case VersionSidecarChannel:
		var isSidecar uint8
		if b.SidecarTicket != nil {
			isSidecar = 1
		}
		err := lnwire.WriteElements(
			&msg, b.nonce[:], uint32(b.Version), b.FixedRate,
			b.Amt, b.LeaseDuration, uint64(b.MaxBatchFeeRate),
			uint32(b.MinNodeTier), uint32(b.MinUnitsMatch),
			uint64(b.SelfChanBalance), isSidecar,
		)
		if err != nil {
			return result, err
		}
	default:
		return result, fmt.Errorf("unknown version %d", b.Kit.Version)
	}
	return sha256.Sum256(msg.Bytes()), nil
}