mirror of
https://github.com/lightninglabs/lightning-terminal.git
synced 2026-08-13 12:33:36 +02:00
firewall: obfuscate ClosedChannels
For closes we need to know the close type and settle balances to know which peers should be avoided in the future.
This commit is contained in:
parent
a7246e1dae
commit
ef84753f6b
3 changed files with 229 additions and 6 deletions
|
|
@ -284,6 +284,12 @@ func (p *PrivacyMapper) checkers(db firewalldb.PrivacyMapDB,
|
|||
handleWalletBalanceResponse(db, flags, p.randIntn),
|
||||
mid.PassThroughErrorHandler,
|
||||
),
|
||||
"/lnrpc.Lightning/ClosedChannels": mid.NewResponseRewriter(
|
||||
&lnrpc.ClosedChannelsRequest{},
|
||||
&lnrpc.ClosedChannelsResponse{},
|
||||
handleClosedChannelsResponse(db, flags, p.randIntn),
|
||||
mid.PassThroughErrorHandler,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -887,6 +893,119 @@ func handleWalletBalanceResponse(_ firewalldb.PrivacyMapDB,
|
|||
}
|
||||
}
|
||||
|
||||
func handleClosedChannelsResponse(db firewalldb.PrivacyMapDB,
|
||||
flags session.PrivacyFlags,
|
||||
randIntn func(int) (int, error)) func(ctx context.Context,
|
||||
r *lnrpc.ClosedChannelsResponse) (proto.Message, error) {
|
||||
|
||||
return func(_ context.Context, r *lnrpc.ClosedChannelsResponse) (
|
||||
proto.Message, error) {
|
||||
|
||||
closedChannels := make(
|
||||
[]*lnrpc.ChannelCloseSummary,
|
||||
len(r.Channels),
|
||||
)
|
||||
|
||||
err := db.Update(func(tx firewalldb.PrivacyMapTx) error {
|
||||
for i, c := range r.Channels {
|
||||
var err error
|
||||
|
||||
remotePub := c.RemotePubkey
|
||||
if !flags.Contains(session.ClearPubkeys) {
|
||||
remotePub, err = firewalldb.HideString(
|
||||
tx, remotePub,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
capacity, err := maybeHideAmount(
|
||||
flags, randIntn, c.Capacity,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settledBalance, err := maybeHideAmount(
|
||||
flags, randIntn, c.SettledBalance,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if settledBalance > capacity {
|
||||
settledBalance = capacity
|
||||
}
|
||||
|
||||
channelPoint := c.ChannelPoint
|
||||
if !flags.Contains(session.ClearChanIDs) {
|
||||
channelPoint, err = firewalldb.HideChanPointStr(
|
||||
tx, c.ChannelPoint,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
chanID := c.ChanId
|
||||
if !flags.Contains(session.ClearChanIDs) {
|
||||
chanID, err = firewalldb.HideUint64(
|
||||
tx, c.ChanId,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
closingTxid := c.ClosingTxHash
|
||||
if !flags.Contains(session.ClearClosingTxIds) {
|
||||
closingTxid, err = firewalldb.HideString(
|
||||
tx, c.ClosingTxHash,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
channel := lnrpc.ChannelCloseSummary{
|
||||
// Obfuscated fields.
|
||||
RemotePubkey: remotePub,
|
||||
Capacity: capacity,
|
||||
SettledBalance: settledBalance,
|
||||
ChannelPoint: channelPoint,
|
||||
ChanId: chanID,
|
||||
ClosingTxHash: closingTxid,
|
||||
|
||||
// Non-obfuscated fields.
|
||||
ChainHash: c.ChainHash,
|
||||
CloseInitiator: c.CloseInitiator,
|
||||
CloseType: c.CloseType,
|
||||
OpenInitiator: c.OpenInitiator,
|
||||
|
||||
// Omitted fields.
|
||||
// CloseHeight
|
||||
// TimeLockedBalance
|
||||
// Resolutions
|
||||
// AliasScids
|
||||
// ZeroConfConfirmedScid
|
||||
}
|
||||
|
||||
closedChannels[i] = &channel
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &lnrpc.ClosedChannelsResponse{
|
||||
Channels: closedChannels,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// maybeHideAmount hides an amount if the privacy flag is not set.
|
||||
func maybeHideAmount(flags session.PrivacyFlags, randIntn func(int) (int,
|
||||
error), a int64) (int64, error) {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ func TestPrivacyMapper(t *testing.T) {
|
|||
"0000000000000141": "2fd42e84b9ffaaeb",
|
||||
"00000000000002a6": "7859bf41241787c2",
|
||||
"000000000000036c": "1320e5d25b7b5973",
|
||||
clearTxID: obfusTxID0,
|
||||
outPoint(clearTxID, 0): outPoint(obfusTxID0, obfusOut0),
|
||||
outPoint(clearTxID, 1): outPoint(obfusTxID1, obfusOut1),
|
||||
"01020304": "c8134495",
|
||||
|
|
@ -419,6 +420,104 @@ func TestPrivacyMapper(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ClosedChannels Response",
|
||||
uri: "/lnrpc.Lightning/ClosedChannels",
|
||||
msgType: rpcperms.TypeResponse,
|
||||
msg: &lnrpc.ClosedChannelsResponse{
|
||||
Channels: []*lnrpc.ChannelCloseSummary{
|
||||
{
|
||||
ChannelPoint: outPoint(
|
||||
clearTxID, 1,
|
||||
),
|
||||
ChanId: 123,
|
||||
ClosingTxHash: clearTxID,
|
||||
RemotePubkey: "01020304",
|
||||
Capacity: 1_000_000,
|
||||
SettledBalance: 500_000,
|
||||
CloseType: lnrpc.ChannelCloseSummary_LOCAL_FORCE_CLOSE,
|
||||
CloseInitiator: lnrpc.Initiator_INITIATOR_LOCAL,
|
||||
OpenInitiator: lnrpc.Initiator_INITIATOR_LOCAL,
|
||||
CloseHeight: 100_000,
|
||||
Resolutions: []*lnrpc.Resolution{
|
||||
{
|
||||
ResolutionType: lnrpc.ResolutionType_ANCHOR,
|
||||
Outcome: lnrpc.ResolutionOutcome_CLAIMED,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedReplacement: &lnrpc.ClosedChannelsResponse{
|
||||
Channels: []*lnrpc.ChannelCloseSummary{
|
||||
{
|
||||
ChannelPoint: outPoint(
|
||||
obfusTxID1, obfusOut1,
|
||||
),
|
||||
ChanId: 5178778334600911958,
|
||||
ClosingTxHash: obfusTxID0,
|
||||
RemotePubkey: "c8134495",
|
||||
Capacity: 950_100,
|
||||
SettledBalance: 475_100,
|
||||
CloseType: lnrpc.ChannelCloseSummary_LOCAL_FORCE_CLOSE,
|
||||
CloseInitiator: lnrpc.Initiator_INITIATOR_LOCAL,
|
||||
OpenInitiator: lnrpc.Initiator_INITIATOR_LOCAL,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ClosedChannels Response clear",
|
||||
uri: "/lnrpc.Lightning/ClosedChannels",
|
||||
msgType: rpcperms.TypeResponse,
|
||||
msg: &lnrpc.ClosedChannelsResponse{
|
||||
Channels: []*lnrpc.ChannelCloseSummary{
|
||||
{
|
||||
ChannelPoint: outPoint(
|
||||
clearTxID, 1,
|
||||
),
|
||||
ChanId: 123,
|
||||
ClosingTxHash: clearTxID,
|
||||
RemotePubkey: "01020304",
|
||||
Capacity: 1_000_000,
|
||||
SettledBalance: 500_000,
|
||||
CloseType: lnrpc.ChannelCloseSummary_LOCAL_FORCE_CLOSE,
|
||||
CloseInitiator: lnrpc.Initiator_INITIATOR_LOCAL,
|
||||
OpenInitiator: lnrpc.Initiator_INITIATOR_LOCAL,
|
||||
CloseHeight: 100_000,
|
||||
Resolutions: []*lnrpc.Resolution{
|
||||
{
|
||||
ResolutionType: lnrpc.ResolutionType_ANCHOR,
|
||||
Outcome: lnrpc.ResolutionOutcome_CLAIMED,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
privacyFlags: []session.PrivacyFlag{
|
||||
session.ClearPubkeys,
|
||||
session.ClearChanIDs,
|
||||
session.ClearClosingTxIds,
|
||||
session.ClearAmounts,
|
||||
},
|
||||
expectedReplacement: &lnrpc.ClosedChannelsResponse{
|
||||
Channels: []*lnrpc.ChannelCloseSummary{
|
||||
{
|
||||
ChannelPoint: outPoint(
|
||||
clearTxID, 1,
|
||||
),
|
||||
ChanId: 123,
|
||||
ClosingTxHash: clearTxID,
|
||||
RemotePubkey: "01020304",
|
||||
Capacity: 1_000_000,
|
||||
SettledBalance: 500_000,
|
||||
CloseType: lnrpc.ChannelCloseSummary_LOCAL_FORCE_CLOSE,
|
||||
CloseInitiator: lnrpc.Initiator_INITIATOR_LOCAL,
|
||||
OpenInitiator: lnrpc.Initiator_INITIATOR_LOCAL,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
decodedID := &lnrpc.MacaroonId{
|
||||
|
|
|
|||
|
|
@ -41,15 +41,20 @@ const (
|
|||
// ClearHTLCs is a privacy flag that indicates that the HTLCs in the API
|
||||
// should not be obfuscated.
|
||||
ClearHTLCs PrivacyFlag = 5
|
||||
|
||||
// ClearClosingTxIds is a privacy flag that indicates that the channel
|
||||
// closing transaction ids in the API should not be obfuscated.
|
||||
ClearClosingTxIds PrivacyFlag = 6
|
||||
)
|
||||
|
||||
var flagMap = map[PrivacyFlag]string{
|
||||
ClearPubkeys: "ClearPubkeys",
|
||||
ClearAmounts: "ClearAmounts",
|
||||
ClearChanIDs: "ClearChanIDs",
|
||||
ClearTimeStamps: "ClearTimeStamps",
|
||||
ClearChanInitiator: "ClearChanInitiator",
|
||||
ClearHTLCs: "ClearHTLCs",
|
||||
ClearPubkeys: "ClearPubkeys",
|
||||
ClearAmounts: "ClearAmounts",
|
||||
ClearChanIDs: "ClearChanIDs",
|
||||
ClearTimeStamps: "ClearTimeStamps",
|
||||
ClearChanInitiator: "ClearChanInitiator",
|
||||
ClearHTLCs: "ClearHTLCs",
|
||||
ClearClosingTxIds: "ClearClosingTxIds",
|
||||
}
|
||||
|
||||
// String returns a string representation of the privacy flag.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue