mirror of
https://github.com/lightninglabs/pool.git
synced 2026-08-13 12:33:04 +02:00
rpcserver: add Marshaler interface
The Marshaler interface is used to transform internal types to decorated RPC ones. It decouples that functionality form the rpcServer so it is easier to test exhaustively.
This commit is contained in:
parent
65157959b0
commit
1589efe1ea
5 changed files with 191 additions and 78 deletions
5
gen.go
5
gen.go
|
|
@ -5,8 +5,13 @@ package pool
|
|||
// make mock
|
||||
//
|
||||
|
||||
//go:generate mockgen -source=interfaces.go -package=pool -destination=mock_interfaces.go
|
||||
|
||||
//go:generate mockgen -source=sidecar/interfaces.go -package=sidecar -destination=sidecar/mock_interfaces.go
|
||||
|
||||
//go:generate mockgen -source=internal/test/interfaces.go -package=test -destination=internal/test/mock_interfaces.go
|
||||
|
||||
//go:generate mockgen -source=account/interfaces.go -package=account -destination=account/mock_interfaces.go
|
||||
//go:generate mockgen -source=account/watcher/interfaces.go -package=watcher -destination=account/watcher/mock_interface_test.go
|
||||
|
||||
//go:generate mockgen -source=order/interfaces.go -package=order -destination=order/mock_interfaces.go
|
||||
|
|
|
|||
16
interfaces.go
Normal file
16
interfaces.go
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package pool
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/lightninglabs/pool/account"
|
||||
"github.com/lightninglabs/pool/poolrpc"
|
||||
)
|
||||
|
||||
// Marshaler interface to transform internal types to decorated RPC ones.
|
||||
type Marshaler interface {
|
||||
// MarshallAccountsWithAvailableBalance returns the RPC representation
|
||||
// of an account with the account.AvailableBalance value populated.
|
||||
MarshallAccountsWithAvailableBalance(ctx context.Context,
|
||||
accounts []*account.Account) ([]*poolrpc.Account, error)
|
||||
}
|
||||
106
marshaler.go
Normal file
106
marshaler.go
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
package pool
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcutil"
|
||||
"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
|
||||
}
|
||||
|
||||
debitAmt += o.ReservedValue(auctionFeeSchedule)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
52
mock_interfaces.go
Normal file
52
mock_interfaces.go
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: interfaces.go
|
||||
|
||||
// Package pool is a generated GoMock package.
|
||||
package pool
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
account "github.com/lightninglabs/pool/account"
|
||||
poolrpc "github.com/lightninglabs/pool/poolrpc"
|
||||
)
|
||||
|
||||
// MockMarshaler is a mock of Marshaler interface.
|
||||
type MockMarshaler struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockMarshalerMockRecorder
|
||||
}
|
||||
|
||||
// MockMarshalerMockRecorder is the mock recorder for MockMarshaler.
|
||||
type MockMarshalerMockRecorder struct {
|
||||
mock *MockMarshaler
|
||||
}
|
||||
|
||||
// NewMockMarshaler creates a new mock instance.
|
||||
func NewMockMarshaler(ctrl *gomock.Controller) *MockMarshaler {
|
||||
mock := &MockMarshaler{ctrl: ctrl}
|
||||
mock.recorder = &MockMarshalerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockMarshaler) EXPECT() *MockMarshalerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// MarshallAccountsWithAvailableBalance mocks base method.
|
||||
func (m *MockMarshaler) MarshallAccountsWithAvailableBalance(ctx context.Context, accounts []*account.Account) ([]*poolrpc.Account, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "MarshallAccountsWithAvailableBalance", ctx, accounts)
|
||||
ret0, _ := ret[0].([]*poolrpc.Account)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// MarshallAccountsWithAvailableBalance indicates an expected call of MarshallAccountsWithAvailableBalance.
|
||||
func (mr *MockMarshalerMockRecorder) MarshallAccountsWithAvailableBalance(ctx, accounts interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarshallAccountsWithAvailableBalance", reflect.TypeOf((*MockMarshaler)(nil).MarshallAccountsWithAvailableBalance), ctx, accounts)
|
||||
}
|
||||
90
rpcserver.go
90
rpcserver.go
|
|
@ -64,6 +64,7 @@ type rpcServer struct {
|
|||
auctioneer *auctioneer.Client
|
||||
accountManager account.Manager
|
||||
orderManager order.Manager
|
||||
marshaler Marshaler
|
||||
|
||||
quit chan struct{}
|
||||
wg sync.WaitGroup
|
||||
|
|
@ -117,6 +118,10 @@ func newRPCServer(server *Server) *rpcServer {
|
|||
Wallet: lndServices.WalletKit,
|
||||
Signer: lndServices.Signer,
|
||||
}),
|
||||
marshaler: NewMarshaler(&marshalerConfig{
|
||||
GetOrders: server.db.GetOrders,
|
||||
Terms: server.AuctioneerClient.Terms,
|
||||
}),
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
|
@ -589,7 +594,7 @@ func (s *rpcServer) ListAccounts(ctx context.Context,
|
|||
validAccounts = append(validAccounts, acct)
|
||||
}
|
||||
|
||||
rpcAccounts, err := s.MarshallAccountsWithAvailableBalance(
|
||||
rpcAccounts, err := s.marshaler.MarshallAccountsWithAvailableBalance(
|
||||
ctx, validAccounts,
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -602,77 +607,6 @@ func (s *rpcServer) ListAccounts(ctx context.Context,
|
|||
}, nil
|
||||
}
|
||||
|
||||
// MarshallAccountsWithAvailableBalance returns the RPC representation of an account
|
||||
// with the account.AvailableBalance value populated.
|
||||
func (s *rpcServer) 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 := s.server.db.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 := s.auctioneer.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
|
||||
}
|
||||
|
||||
debitAmt += o.ReservedValue(auctionFeeSchedule)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// MarshallAccount returns the RPC representation of an account.
|
||||
func MarshallAccount(a *account.Account) (*poolrpc.Account, error) {
|
||||
var rpcState poolrpc.AccountState
|
||||
|
|
@ -770,7 +704,7 @@ func (s *rpcServer) DepositAccount(ctx context.Context,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
rpcModifiedAccounts, err := s.MarshallAccountsWithAvailableBalance(
|
||||
rpcModAccounts, err := s.marshaler.MarshallAccountsWithAvailableBalance(
|
||||
ctx, []*account.Account{modifiedAccount},
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -779,7 +713,7 @@ func (s *rpcServer) DepositAccount(ctx context.Context,
|
|||
txHash := tx.TxHash()
|
||||
|
||||
return &poolrpc.DepositAccountResponse{
|
||||
Account: rpcModifiedAccounts[0],
|
||||
Account: rpcModAccounts[0],
|
||||
DepositTxid: txHash[:],
|
||||
}, nil
|
||||
}
|
||||
|
|
@ -837,7 +771,7 @@ func (s *rpcServer) WithdrawAccount(ctx context.Context,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
rpcModifiedAccounts, err := s.MarshallAccountsWithAvailableBalance(
|
||||
rpcModAccounts, err := s.marshaler.MarshallAccountsWithAvailableBalance(
|
||||
ctx, []*account.Account{modifiedAccount},
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -846,7 +780,7 @@ func (s *rpcServer) WithdrawAccount(ctx context.Context,
|
|||
txHash := tx.TxHash()
|
||||
|
||||
return &poolrpc.WithdrawAccountResponse{
|
||||
Account: rpcModifiedAccounts[0],
|
||||
Account: rpcModAccounts[0],
|
||||
WithdrawTxid: txHash[:],
|
||||
}, nil
|
||||
}
|
||||
|
|
@ -895,7 +829,7 @@ func (s *rpcServer) RenewAccount(ctx context.Context,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
rpcModifiedAccounts, err := s.MarshallAccountsWithAvailableBalance(
|
||||
rpcModAccounts, err := s.marshaler.MarshallAccountsWithAvailableBalance(
|
||||
ctx, []*account.Account{modifiedAccount},
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -904,7 +838,7 @@ func (s *rpcServer) RenewAccount(ctx context.Context,
|
|||
txHash := tx.TxHash()
|
||||
|
||||
return &poolrpc.RenewAccountResponse{
|
||||
Account: rpcModifiedAccounts[0],
|
||||
Account: rpcModAccounts[0],
|
||||
RenewalTxid: txHash[:],
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue