Skip to content

Commit c944dca

Browse files
committed
firewall: obfuscate BatchOpenChannel
We obfuscate fields from the batch channel open requests and responses.
1 parent 1ce3e14 commit c944dca

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

firewall/privacy_mapper.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,13 @@ func (p *PrivacyMapper) checkers(db firewalldb.PrivacyMapDB,
296296
handleClosedChannelsResponse(db, flags, p.randIntn),
297297
mid.PassThroughErrorHandler,
298298
),
299+
"/lnrpc.Lightning/BatchOpenChannel": mid.NewFullRewriter(
300+
&lnrpc.BatchOpenChannelRequest{},
301+
&lnrpc.BatchOpenChannelResponse{},
302+
handleBatchOpenChannelRequest(db, flags, p.randIntn),
303+
handleBatchOpenChannelResponse(db, flags, p.randIntn),
304+
mid.PassThroughErrorHandler,
305+
),
299306
}
300307
}
301308

@@ -1087,6 +1094,80 @@ func handleClosedChannelsResponse(db firewalldb.PrivacyMapDB,
10871094
}
10881095
}
10891096

1097+
func handleBatchOpenChannelRequest(db firewalldb.PrivacyMapDB,
1098+
flags session.PrivacyFlags,
1099+
_ func(int) (int, error)) func(ctx context.Context,
1100+
r *lnrpc.BatchOpenChannelRequest) (proto.Message, error) {
1101+
1102+
return func(_ context.Context, r *lnrpc.BatchOpenChannelRequest) (
1103+
proto.Message, error) {
1104+
1105+
err := db.Update(func(tx firewalldb.PrivacyMapTx) error {
1106+
// Modify channels in place.
1107+
for _, c := range r.Channels {
1108+
var err error
1109+
1110+
// Note, this only works if the pubkey alias was
1111+
// already created via other calls, e.g. via
1112+
// ListChannels or GetInfo or the like.
1113+
if !flags.Contains(session.ClearPubkeys) {
1114+
c.NodePubkey, err = firewalldb.RevealBytes(
1115+
tx, c.NodePubkey,
1116+
)
1117+
if err != nil {
1118+
return err
1119+
}
1120+
}
1121+
}
1122+
1123+
return nil
1124+
})
1125+
if err != nil {
1126+
return nil, err
1127+
}
1128+
1129+
return r, nil
1130+
}
1131+
}
1132+
1133+
func handleBatchOpenChannelResponse(db firewalldb.PrivacyMapDB,
1134+
flags session.PrivacyFlags,
1135+
randIntn func(int) (int, error)) func(ctx context.Context,
1136+
r *lnrpc.BatchOpenChannelResponse) (proto.Message, error) {
1137+
1138+
return func(_ context.Context, r *lnrpc.BatchOpenChannelResponse) (
1139+
proto.Message, error) {
1140+
1141+
err := db.Update(func(tx firewalldb.PrivacyMapTx) error {
1142+
for _, p := range r.PendingChannels {
1143+
if !flags.Contains(session.ClearChanIDs) {
1144+
txIDStr := hex.EncodeToString(p.Txid)
1145+
txID, hOut, err := firewalldb.HideChanPoint(
1146+
tx, txIDStr, p.OutputIndex,
1147+
)
1148+
if err != nil {
1149+
return err
1150+
}
1151+
1152+
p.OutputIndex = hOut
1153+
txIDBytes, err := hex.DecodeString(txID)
1154+
if err != nil {
1155+
return err
1156+
}
1157+
p.Txid = txIDBytes
1158+
}
1159+
}
1160+
1161+
return nil
1162+
})
1163+
if err != nil {
1164+
return nil, err
1165+
}
1166+
1167+
return r, nil
1168+
}
1169+
}
1170+
10901171
// maybeHideAmount hides an amount if the privacy flag is not set.
10911172
func maybeHideAmount(flags session.PrivacyFlags, randIntn func(int) (int, error),
10921173
a int64) (int64, error) {

firewall/privacy_mapper_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package firewall
22

33
import (
44
"context"
5+
"encoding/hex"
56
"encoding/json"
67
"fmt"
78
"testing"
@@ -27,8 +28,12 @@ func TestPrivacyMapper(t *testing.T) {
2728

2829
// Define some transaction outpoints used for mapping.
2930
clearTxID := "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"
31+
clearTxIDBytes, err := hex.DecodeString(clearTxID)
32+
require.NoError(t, err)
3033

3134
obfusTxID0 := "097ef666a61919ff3413b3b701eae3a5cbac08f70c0ca567806e1fa6acbfe384"
35+
obfusTxID0Bytes, err := hex.DecodeString(obfusTxID0)
36+
require.NoError(t, err)
3237
obfusOut0 := uint32(2161781494)
3338
obfusTxID0Reversed, err := chainhash.NewHashFromStr(obfusTxID0)
3439
require.NoError(t, err)
@@ -468,6 +473,59 @@ func TestPrivacyMapper(t *testing.T) {
468473
},
469474
},
470475
},
476+
{
477+
name: "BatchOpenChannel Request",
478+
uri: "/lnrpc.Lightning/BatchOpenChannel",
479+
msgType: rpcperms.TypeRequest,
480+
msg: &lnrpc.BatchOpenChannelRequest{
481+
TargetConf: 6,
482+
Channels: []*lnrpc.BatchOpenChannel{
483+
{
484+
NodePubkey: []byte{
485+
200, 19, 68, 149,
486+
},
487+
LocalFundingAmount: 1_000_000,
488+
PushSat: 1_000_000,
489+
MinHtlcMsat: 100,
490+
},
491+
},
492+
},
493+
expectedReplacement: &lnrpc.BatchOpenChannelRequest{
494+
TargetConf: 6,
495+
Channels: []*lnrpc.BatchOpenChannel{
496+
{
497+
NodePubkey: []byte{
498+
1, 2, 3, 4,
499+
},
500+
LocalFundingAmount: 1_000_000,
501+
PushSat: 1_000_000,
502+
MinHtlcMsat: 100,
503+
},
504+
},
505+
},
506+
},
507+
{
508+
name: "BatchOpenChannel Response",
509+
uri: "/lnrpc.Lightning/BatchOpenChannel",
510+
msgType: rpcperms.TypeResponse,
511+
msg: &lnrpc.BatchOpenChannelResponse{
512+
PendingChannels: []*lnrpc.PendingUpdate{
513+
{
514+
515+
Txid: clearTxIDBytes,
516+
OutputIndex: 0,
517+
},
518+
},
519+
},
520+
expectedReplacement: &lnrpc.BatchOpenChannelResponse{
521+
PendingChannels: []*lnrpc.PendingUpdate{
522+
{
523+
Txid: obfusTxID0Bytes,
524+
OutputIndex: obfusOut0,
525+
},
526+
},
527+
},
528+
},
471529
}
472530

473531
decodedID := &lnrpc.MacaroonId{

0 commit comments

Comments
 (0)