Skip to content

Commit

Permalink
Merge pull request lightninglabs#285 from guggero/sidecar-submit
Browse files Browse the repository at this point in the history
sidecar channels 2/3: Allow sidecar tickets to be specified on bid orders
  • Loading branch information
Roasbeef authored Apr 1, 2021
2 parents 6742d8e + a1d2e93 commit 2b2cc6c
Show file tree
Hide file tree
Showing 17 changed files with 1,020 additions and 857 deletions.
1 change: 1 addition & 0 deletions admin_rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ func (s *adminRPCServer) ListOrders(ctx context.Context,
),
UserAgent: o.UserAgent,
SelfChanBalance: uint64(o.SelfChanBalance),
IsSidecar: o.IsSidecar,
})
}
}
Expand Down
846 changes: 429 additions & 417 deletions adminrpc/admin.pb.go

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions adminrpc/admin.proto
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ message ServerBid {
The initial self balance that was chosen by the user for this bid.
*/
uint64 self_chan_balance = 7;

/*
Whether this bid was submitted as a sidecar order.
*/
bool is_sidecar = 8;
}

message AccountDetailsRequest {
Expand Down
854 changes: 435 additions & 419 deletions auctioneerrpc/auctioneer.pb.go

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions auctioneerrpc/auctioneer.proto
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,14 @@ message ServerBid {
amount.
*/
uint64 self_chan_balance = 6;

/*
If this bid order is meant to lease a channel for another node (which is
dubbed a "sidecar channel") then this boolean needs to be set to true. The
multi_sig_key, node_pub and node_addr fields of the order details must then
correspond to the recipient node's details.
*/
bool is_sidecar_channel = 7;
}

message ServerAsk {
Expand Down
5 changes: 5 additions & 0 deletions auctioneerrpc/auctioneer.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,11 @@
"type": "string",
"format": "uint64",
"description": "Give the incoming channel that results from this bid being matched an\ninitial outbound balance by adding additional funds from the taker's account\ninto the channel. As a simplification for the execution protocol and the\nchannel reserve calculations, the self_chan_balance can be at most the same\nas the order amount and the min_chan_amt must be set to the full order\namount."
},
"is_sidecar_channel": {
"type": "boolean",
"format": "boolean",
"description": "If this bid order is meant to lease a channel for another node (which is\ndubbed a \"sidecar channel\") then this boolean needs to be set to true. The\nmulti_sig_key, node_pub and node_addr fields of the order details must then\ncorrespond to the recipient node's details."
}
}
},
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ replace go.etcd.io/etcd => go.etcd.io/etcd v0.0.0-20200520232829-54ba9589114f
// it in the client binary as well. We need to import it with its declared name
// everywhere too, otherwise the replace won't work properly.
replace github.com/lightninglabs/pool/auctioneerrpc => ./auctioneerrpc

replace github.com/lightninglabs/pool => github.com/guggero/pool v0.3.2-alpha.0.20210316143446-492559c94857
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtg
github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0=
github.com/grpc-ecosystem/grpc-gateway v1.14.6 h1:8ERzHx8aj1Sc47mu9n/AksaKCSWrMchFtkdrS4BIj5o=
github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw=
github.com/guggero/pool v0.3.2-alpha.0.20210316143446-492559c94857 h1:CsJPy4TWO8tn9dT0Kd6ksqpu5aMF9/90+HCMcX8hI2o=
github.com/guggero/pool v0.3.2-alpha.0.20210316143446-492559c94857/go.mod h1:KeTN3RQ8Yw5ZUaxkcOqzfeybsb4ev4zhtfnUrNrS2Ok=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
Expand Down Expand Up @@ -280,8 +282,6 @@ github.com/lightninglabs/neutrino v0.11.1-0.20200316235139-bffc52e8f200 h1:j4iZ1
github.com/lightninglabs/neutrino v0.11.1-0.20200316235139-bffc52e8f200/go.mod h1:MlZmoKa7CJP3eR1s5yB7Rm5aSyadpKkxqAwLQmog7N0=
github.com/lightninglabs/neutrino v0.11.1-0.20201210023533-e1978372d15e h1:K5LCCnSAk3NVT/aCy8wNPv0I5JfyLgijg1VX8Gz306E=
github.com/lightninglabs/neutrino v0.11.1-0.20201210023533-e1978372d15e/go.mod h1:KDWfQDKp+CFBxO1t2NRmWuagTY2sYIjpHB1k5vrojTI=
github.com/lightninglabs/pool v0.4.4-alpha.0.20210316143314-9fb2862fede4 h1:2QKwlN2pletWFBsDp2dAjs1nncnfa1YUZXJ5jQEPL1M=
github.com/lightninglabs/pool v0.4.4-alpha.0.20210316143314-9fb2862fede4/go.mod h1:KeTN3RQ8Yw5ZUaxkcOqzfeybsb4ev4zhtfnUrNrS2Ok=
github.com/lightninglabs/protobuf-hex-display v1.3.3-0.20191212020323-b444784ce75d/go.mod h1:KDb67YMzoh4eudnzClmvs2FbiLG9vxISmLApUkCa4uI=
github.com/lightninglabs/protobuf-hex-display v1.4.3-hex-display h1:RZJ8H4ueU/aQ9pFtx5wqsuD3B/DezrewJeVwDKKYY8E=
github.com/lightninglabs/protobuf-hex-display v1.4.3-hex-display/go.mod h1:2oKOBU042GKFHrdbgGiKax4xVrFiZu51lhacUZQ9MnE=
Expand Down
50 changes: 50 additions & 0 deletions order/book.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,14 @@ func (b *Book) validateOrder(ctx context.Context, srvOrder ServerOrder) error {
return err
}
}

// Check the sidecar parameters if the flag is set on the order.
if o.IsSidecar {
if err := b.validateSidecarOrder(ctx, o); err != nil {
return fmt.Errorf("error validating sidecar "+
"order: %v", err)
}
}
}

// Only clients that understand multiple lease buckets are allowed to
Expand Down Expand Up @@ -387,6 +395,48 @@ func (b *Book) validateOrder(ctx context.Context, srvOrder ServerOrder) error {
return nil
}

// validateSidecarOrder makes sure all order parameters are set correctly for
// a sidecar order.
func (b *Book) validateSidecarOrder(ctx context.Context, bid *Bid) error {
// A sidecar order must have its version set accordingly.
if bid.Version < order.VersionSidecarChannel {
return fmt.Errorf("invalid order version %d for order with "+
"sidecar ticket attached", bid.Version)
}

// Sidecar channels with a self channel balance need to have the minimum
// matched units set to the bid size to avoid an overly complicated
// execution protocol. We also check the size of the self channel
// balance in the process.
if err := bid.ValidateSelfChanBalance(); err != nil {
return fmt.Errorf("invalid self balance for sidecar order: %v",
err)
}

dbOrders, err := b.cfg.Store.GetOrders(ctx)
if err != nil {
return fmt.Errorf("error validating sidecar order against "+
"existing orders: %v", err)
}

for _, dbOrder := range dbOrders {
dbBid, isBid := dbOrder.(*Bid)
if !isBid {
continue
}

if dbBid.MultiSigKey == bid.MultiSigKey {
return fmt.Errorf("an active order for the multisig " +
"pubkey of the sidecar recipient already " +
"exists, cancel it first before submitting a " +
"new one")
}
}

// As far as we can tell everything is in order with the order.
return nil
}

// Subscribe returns a new subscription to the order book. Client will receive
// events each time an order is added, or cancelled.
func (b *Book) Subscribe() (*subscribe.Client, error) {
Expand Down
52 changes: 39 additions & 13 deletions order/book_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/hex"
"fmt"
"strings"
"testing"

"github.com/btcsuite/btcd/btcec"
Expand Down Expand Up @@ -394,6 +393,40 @@ func TestBookPrepareOrder(t *testing.T) {

return err
},
}, {
name: "invalid version for sidecar",
expectedErr: "invalid order version 0 for order with sidecar",
run: func() error {
o := bid(orderT.Kit{
Amt: 100_000,
Units: orderT.NewSupplyFromSats(100_000),
UnitsUnfulfilled: orderT.NewSupplyFromSats(100_000),
AcctKey: toRawKey(testTraderKey),
MaxBatchFeeRate: chainfee.FeePerKwFloor,
LeaseDuration: orderT.LegacyLeaseDurationBucket,
MinUnitsMatch: 1,
})
o.IsSidecar = true
return book.PrepareOrder(ctxb, o, feeSchedule, bestHeight)
},
}, {
name: "invalid min units match for sidecar",
expectedErr: "to use self chan balance the min units match " +
"must be equal to the order amount in units",
run: func() error {
o := bid(orderT.Kit{
Amt: 500_000,
Units: orderT.NewSupplyFromSats(500_000),
UnitsUnfulfilled: orderT.NewSupplyFromSats(500_000),
AcctKey: toRawKey(testTraderKey),
MaxBatchFeeRate: chainfee.FeePerKwFloor,
LeaseDuration: orderT.LegacyLeaseDurationBucket,
MinUnitsMatch: 1,
})
o.Version = orderT.VersionSidecarChannel
o.IsSidecar = true
return book.PrepareOrder(ctxb, o, feeSchedule, bestHeight)
},
}, {
name: "successful order submission",
expectedErr: "",
Expand Down Expand Up @@ -448,18 +481,11 @@ func TestBookPrepareOrder(t *testing.T) {
err := tc.run()

// Make sure the error is what we expected.
if err == nil && tc.expectedErr != "" {
t.Fatalf("expected error '%s' but got nil",
tc.expectedErr)
}
if err != nil && tc.expectedErr == "" {
t.Fatalf("expected nil error but got '%v'", err)
}
if err != nil &&
!strings.Contains(err.Error(), tc.expectedErr) {

t.Fatalf("expected error '%s' but got '%v'",
tc.expectedErr, err)
if tc.expectedErr == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expectedErr)
}
})
}
Expand Down
3 changes: 3 additions & 0 deletions order/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ type Bid struct {

// Kit contains all the common order parameters.
Kit

// IsSidecar denotes whether this bid was submitted as a sidecar order.
IsSidecar bool
}

// LeaseDuration is the minimal duration the channel resulting from this bid
Expand Down
16 changes: 14 additions & 2 deletions rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/lightninglabs/pool/chaninfo"
orderT "github.com/lightninglabs/pool/order"
"github.com/lightninglabs/pool/poolscript"
"github.com/lightninglabs/pool/sidecar"
"github.com/lightninglabs/pool/terms"
"github.com/lightninglabs/subasta/account"
"github.com/lightninglabs/subasta/feebump"
Expand Down Expand Up @@ -549,9 +550,20 @@ func (s *rpcServer) SubmitOrder(ctx context.Context,
MinNodeTier: nodeTier,
SelfChanBalance: btcutil.Amount(b.SelfChanBalance),
}

// The order signature digest includes the IsSidecar flag but
// it's calculated based on whether the sidecar ticket in the
// client struct is nil or not. So we need to add an empty
// ticket if the flag is true, otherwise we'd get a different
// digest.
if b.IsSidecarChannel {
clientBid.SidecarTicket = &sidecar.Ticket{}
}

o = &order.Bid{
Bid: *clientBid,
Kit: *serverKit,
Bid: *clientBid,
Kit: *serverKit,
IsSidecar: b.IsSidecarChannel,
}

default:
Expand Down
4 changes: 4 additions & 0 deletions subastadb/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ const (
// bidSelfChanBalanceType is the tlv type we use to store the self
// channel balance on bid orders.
bidSelfChanBalanceType tlv.Type = 2

// bidIsSidecarType is the tlv record type for the sidecar flag of a bid
// order.
bidIsSidecarType tlv.Type = 3
)

// WriteElements is writes each element in the elements slice to the passed
Expand Down
18 changes: 17 additions & 1 deletion subastadb/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -771,13 +771,15 @@ func deserializeOrderTlvData(r io.Reader, o order.ServerOrder) error {
var (
userAgent []byte
selfChanBalance uint64
isSidecar uint8
)

tlvStream, err := tlv.NewStream(
tlv.MakePrimitiveRecord(userAgentType, &userAgent),
tlv.MakePrimitiveRecord(
bidSelfChanBalanceType, &selfChanBalance,
),
tlv.MakePrimitiveRecord(bidIsSidecarType, &isSidecar),
)
if err != nil {
return err
Expand All @@ -798,15 +800,22 @@ func deserializeOrderTlvData(r io.Reader, o order.ServerOrder) error {
bid.SelfChanBalance = btcutil.Amount(selfChanBalance)
}

if t, ok := parsedTypes[bidIsSidecarType]; isBid && ok && t == nil {
bid.IsSidecar = isSidecar == 1
}

return nil
}

// serializeOrderTlvData encodes all additional data of an order as a single tlv
// stream.
func serializeOrderTlvData(w io.Writer, o order.ServerOrder) error {
userAgent := []byte(o.ServerDetails().UserAgent)
isSidecar := uint8(0)

var tlvRecords []tlv.Record
var (
tlvRecords []tlv.Record
)

// No need adding an empty record.
if len(userAgent) > 0 {
Expand All @@ -823,6 +832,13 @@ func serializeOrderTlvData(w io.Writer, o order.ServerOrder) error {
))
}

if isBid && bid.IsSidecar {
isSidecar = 1
tlvRecords = append(tlvRecords, tlv.MakePrimitiveRecord(
bidIsSidecarType, &isSidecar,
))
}

tlvStream, err := tlv.NewStream(tlvRecords...)
if err != nil {
return err
Expand Down
3 changes: 2 additions & 1 deletion subastadb/order_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ func TestSubmitOrder(t *testing.T) {
MinNodeTier: 9,
SelfChanBalance: 12345,
},
Kit: *dummyOrder(t),
Kit: *dummyOrder(t),
IsSidecar: true,
}
_, err := store.GetOrder(ctxb, bid.Nonce())
if err != ErrNoOrder {
Expand Down
5 changes: 3 additions & 2 deletions venue/matching/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ func copyMatchedOrder(original *MatchedOrder) MatchedOrder {
Kit: original.Details.Ask.Kit,
},
Bid: &order.Bid{
Bid: original.Details.Bid.Bid,
Kit: original.Details.Bid.Kit,
Bid: original.Details.Bid.Bid,
Kit: original.Details.Bid.Kit,
IsSidecar: original.Details.Bid.IsSidecar,
},
Quote: original.Details.Quote,
},
Expand Down
1 change: 1 addition & 0 deletions venue/matching/match_predicate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ var (
Kit: order.Kit{
NodeKey: node2Key,
},
IsSidecar: true,
}
node4Bid = &order.Bid{
Bid: orderT.Bid{
Expand Down

0 comments on commit 2b2cc6c

Please sign in to comment.