2021-12-09 22:52:03 -08:00
|
|
|
package pool
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
|
2022-03-11 14:19:30 -08:00
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
2021-12-09 22:52:03 -08:00
|
|
|
"github.com/lightninglabs/pool/account"
|
|
|
|
|
"github.com/lightninglabs/pool/order"
|
|
|
|
|
"github.com/lightninglabs/pool/poolrpc"
|
|
|
|
|
"github.com/lightninglabs/pool/terms"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// marshalerConfig contains all of the marshaler's dependencies in order to
|
|
|
|
|
// carry out its duties.
|
|
|
|
|
type marshalerConfig struct {
|
|
|
|
|
// GetOrders returns all orders that are currently known to the store.
|
|
|
|
|
GetOrders func() ([]order.Order, error)
|
|
|
|
|
|
|
|
|
|
// Terms returns the current dynamic auctioneer terms like max account
|
|
|
|
|
// size, max order duration in blocks and the auction fee schedule.
|
|
|
|
|
Terms func(ctx context.Context) (*terms.AuctioneerTerms, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// marshaler is an internal struct type that implements the Marshaler interface.
|
|
|
|
|
type marshaler struct {
|
|
|
|
|
cfg *marshalerConfig
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewMarshaler returns an internal type that implements the Marshaler interface.
|
|
|
|
|
func NewMarshaler(cfg *marshalerConfig) *marshaler { // nolint:golint
|
|
|
|
|
return &marshaler{
|
|
|
|
|
cfg: cfg,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MarshallAccountsWithAvailableBalance returns the RPC representation of an account
|
|
|
|
|
// with the account.AvailableBalance value populated.
|
|
|
|
|
func (m *marshaler) MarshallAccountsWithAvailableBalance(ctx context.Context,
|
|
|
|
|
accounts []*account.Account) ([]*poolrpc.Account, error) {
|
|
|
|
|
|
|
|
|
|
rpcAccounts := make([]*poolrpc.Account, 0, len(accounts))
|
|
|
|
|
for _, acct := range accounts {
|
|
|
|
|
rpcAccount, err := MarshallAccount(acct)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
rpcAccounts = append(rpcAccounts, rpcAccount)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For each account, we'll need to compute the available balance, which
|
|
|
|
|
// requires us to sum up all the debits from outstanding orders.
|
|
|
|
|
orders, err := m.cfg.GetOrders()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the current fee schedule so we can compute the worst-case
|
|
|
|
|
// account debit assuming all our standing orders were matched.
|
|
|
|
|
auctionTerms, err := m.cfg.Terms(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("unable to query auctioneer terms: %v",
|
|
|
|
|
err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For each active account, consume the worst-case account delta if the
|
|
|
|
|
// order were to be matched.
|
|
|
|
|
accountDebits := make(map[[33]byte]btcutil.Amount)
|
|
|
|
|
auctionFeeSchedule := auctionTerms.FeeSchedule()
|
|
|
|
|
for _, acct := range accounts {
|
|
|
|
|
var (
|
|
|
|
|
debitAmt btcutil.Amount
|
|
|
|
|
acctKey [33]byte
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
copy(
|
|
|
|
|
acctKey[:],
|
|
|
|
|
acct.TraderKey.PubKey.SerializeCompressed(),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// We'll make sure to accumulate a distinct sum for each
|
|
|
|
|
// outstanding account the user has.
|
|
|
|
|
for _, o := range orders {
|
|
|
|
|
if o.Details().AcctKey != acctKey {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-05 21:49:10 +02:00
|
|
|
debitAmt += o.ReservedValue(
|
|
|
|
|
auctionFeeSchedule, acct.Version,
|
|
|
|
|
)
|
2021-12-09 22:52:03 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
accountDebits[acctKey] = debitAmt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Finally, we'll populate the available balance value for each of the
|
|
|
|
|
// existing accounts.
|
|
|
|
|
for _, rpcAccount := range rpcAccounts {
|
|
|
|
|
var acctKey [33]byte
|
|
|
|
|
copy(acctKey[:], rpcAccount.TraderKey)
|
|
|
|
|
|
|
|
|
|
accountDebit := accountDebits[acctKey]
|
|
|
|
|
availableBalance := rpcAccount.Value - uint64(accountDebit)
|
|
|
|
|
|
|
|
|
|
rpcAccount.AvailableBalance = availableBalance
|
|
|
|
|
}
|
|
|
|
|
return rpcAccounts, nil
|
|
|
|
|
}
|