Skip to content

Commit 36c8ab1

Browse files
committed
rfq+rpcserver: match event to order
Fixes an issue reported on Slack: 2025-05-01 11:41:02.817 [ERR] RPCS: [/tapchannelrpc.TaprootAssetChannels/SendPayment]: error adding sell order: error marshalling sell order response: unknown AddAssetSellOrder event type: *rfq.PeerAcceptedBuyQuoteEvent This happens when two orders of different types are added at more or less the same time, then we receive the wrong one on the subscriber channel. So we need to filter by type and also by matching the order to the returned quote event.
1 parent 5225722 commit 36c8ab1

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

rfq/manager.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,24 @@ func (q *PeerAcceptedBuyQuoteEvent) Timestamp() time.Time {
11161116
return q.timestamp.UTC()
11171117
}
11181118

1119+
// MatchesOrder checks if the sell quote matches the provided order.
1120+
func (q *PeerAcceptedBuyQuoteEvent) MatchesOrder(order BuyOrder) bool {
1121+
if q.Request.AssetSpecifier != order.AssetSpecifier {
1122+
return false
1123+
}
1124+
1125+
// If the order has no peer, we accept equality just based on the
1126+
// specifier.
1127+
if order.Peer.IsNone() {
1128+
return true
1129+
}
1130+
1131+
// If a peer is specified, ensure it matches the event's peer.
1132+
return fn.MapOptionZ(order.Peer, func(vertex route.Vertex) bool {
1133+
return q.Peer == vertex
1134+
})
1135+
}
1136+
11191137
// Ensure that the PeerAcceptedBuyQuoteEvent struct implements the Event
11201138
// interface.
11211139
var _ fn.Event = (*PeerAcceptedBuyQuoteEvent)(nil)
@@ -1197,6 +1215,24 @@ func (q *PeerAcceptedSellQuoteEvent) Timestamp() time.Time {
11971215
return q.timestamp.UTC()
11981216
}
11991217

1218+
// MatchesOrder checks if the sell quote matches the provided order.
1219+
func (q *PeerAcceptedSellQuoteEvent) MatchesOrder(order SellOrder) bool {
1220+
if q.Request.AssetSpecifier != order.AssetSpecifier {
1221+
return false
1222+
}
1223+
1224+
// If the order has no peer, we accept equality just based on the
1225+
// specifier.
1226+
if order.Peer.IsNone() {
1227+
return true
1228+
}
1229+
1230+
// If a peer is specified, ensure it matches the event's peer.
1231+
return fn.MapOptionZ(order.Peer, func(vertex route.Vertex) bool {
1232+
return q.Peer == vertex
1233+
})
1234+
}
1235+
12001236
// Ensure that the PeerAcceptedSellQuoteEvent struct implements the Event
12011237
// interface.
12021238
var _ fn.Event = (*PeerAcceptedSellQuoteEvent)(nil)

rpcserver.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6799,8 +6799,26 @@ func (r *rpcServer) AddAssetBuyOrder(ctx context.Context,
67996799
timeout := time.After(time.Second * time.Duration(req.TimeoutSeconds))
68006800

68016801
for {
6802+
type targetEventType = *rfq.PeerAcceptedBuyQuoteEvent
68026803
select {
68036804
case event := <-eventSubscriber.NewItemCreated.ChanOut():
6805+
acceptedQuote, ok := event.(targetEventType)
6806+
if !ok {
6807+
rpcsLog.Debugf("Received event of type %T "+
6808+
"but expected accepted sell quote, "+
6809+
"skipping", event)
6810+
6811+
continue
6812+
}
6813+
6814+
if !acceptedQuote.MatchesOrder(*buyOrder) {
6815+
rpcsLog.Debugf("Received event of type %T "+
6816+
"but order doesn't match, skipping",
6817+
event)
6818+
6819+
continue
6820+
}
6821+
68046822
resp, err := rfq.NewAddAssetBuyOrderResponse(event)
68056823
if err != nil {
68066824
return nil, fmt.Errorf("error marshalling "+
@@ -6973,8 +6991,26 @@ func (r *rpcServer) AddAssetSellOrder(ctx context.Context,
69736991
timeout := time.After(time.Second * time.Duration(req.TimeoutSeconds))
69746992

69756993
for {
6994+
type targetEventType = *rfq.PeerAcceptedSellQuoteEvent
69766995
select {
69776996
case event := <-eventSubscriber.NewItemCreated.ChanOut():
6997+
acceptedQuote, ok := event.(targetEventType)
6998+
if !ok {
6999+
rpcsLog.Debugf("Received event of type %T "+
7000+
"but expected accepted sell quote, "+
7001+
"skipping", event)
7002+
7003+
continue
7004+
}
7005+
7006+
if !acceptedQuote.MatchesOrder(*sellOrder) {
7007+
rpcsLog.Debugf("Received event of type %T "+
7008+
"but order doesn't match, skipping",
7009+
event)
7010+
7011+
continue
7012+
}
7013+
69787014
resp, err := rfq.NewAddAssetSellOrderResponse(event)
69797015
if err != nil {
69807016
return nil, fmt.Errorf("error marshalling "+

0 commit comments

Comments
 (0)