Merge pull request #2027 from mrwhythat/no-incoming-push-amounts-option

Option to disable incoming push amounts on channel opening
This commit is contained in:
Olaoluwa Osuntokun 2018-11-02 17:08:05 -07:00 committed by GitHub
commit f60012b3f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 0 deletions

@ -235,6 +235,8 @@ type config struct {
NoChanUpdates bool `long:"nochanupdates" description:"If specified, lnd will not request real-time channel updates from connected peers. This option should be used by routing nodes to save bandwidth."`
RejectPush bool `long:"rejectpush" description:"If true, lnd will not accept channel opening requests with non-zero push amounts. This should prevent accidental pushes to merchant nodes."`
net tor.Net
Routing *routing.Conf `group:"routing" namespace:"routing"`

@ -1032,6 +1032,15 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
return
}
// If request specifies non-zero push amount and 'rejectpush' is set,
// signal an error.
if cfg.RejectPush && msg.PushAmount > 0 {
f.failFundingFlow(
fmsg.peer, fmsg.msg.PendingChannelID,
lnwallet.ErrNonZeroPushAmount())
return
}
fndgLog.Infof("Recv'd fundingRequest(amt=%v, push=%v, delay=%v, "+
"pendingId=%x) from peer(%x)", amt, msg.PushAmount,
msg.CsvDelay, msg.PendingChannelID,

@ -2477,3 +2477,63 @@ func TestFundingManagerMaxPendingChannels(t *testing.T) {
t, bob.msgChan, "AcceptChannel",
).(*lnwire.AcceptChannel)
}
// TestFundingManagerRejectPush checks behaviour of 'rejectpush'
// option, namely that non-zero incoming push amounts are disabled.
func TestFundingManagerRejectPush(t *testing.T) {
// Enable 'rejectpush' option and initialize funding managers.
alice, bob := setupFundingManagers(t, defaultMaxPendingChannels)
rejectPush := cfg.RejectPush
cfg.RejectPush = true
defer func() {
tearDownFundingManagers(t, alice, bob)
cfg.RejectPush = rejectPush
}()
// Create a funding request and start the workflow.
updateChan := make(chan *lnrpc.OpenStatusUpdate)
errChan := make(chan error, 1)
initReq := &openChanReq{
targetPubkey: bob.privKey.PubKey(),
chainHash: *activeNetParams.GenesisHash,
localFundingAmt: 500000,
pushAmt: lnwire.NewMSatFromSatoshis(10),
private: true,
updates: updateChan,
err: errChan,
}
alice.fundingMgr.initFundingWorkflow(bob, initReq)
// Alice should have sent the OpenChannel message to Bob.
var aliceMsg lnwire.Message
select {
case aliceMsg = <-alice.msgChan:
case err := <-initReq.err:
t.Fatalf("error init funding workflow: %v", err)
case <-time.After(time.Second * 5):
t.Fatalf("alice did not send OpenChannel message")
}
openChannelReq, ok := aliceMsg.(*lnwire.OpenChannel)
if !ok {
errorMsg, gotError := aliceMsg.(*lnwire.Error)
if gotError {
t.Fatalf("expected OpenChannel to be sent "+
"from bob, instead got error: %v",
lnwire.ErrorCode(errorMsg.Data[0]))
}
t.Fatalf("expected OpenChannel to be sent from "+
"alice, instead got %T", aliceMsg)
}
// Let Bob handle the init message.
bob.fundingMgr.processFundingOpen(openChannelReq, alice)
// Assert Bob responded with an ErrNonZeroPushAmount error.
err := assertFundingMsgSent(t, bob.msgChan, "Error").(*lnwire.Error)
if "Non-zero push amounts are disabled" != string(err.Data) {
t.Fatalf("expected ErrNonZeroPushAmount error, got \"%v\"",
string(err.Data))
}
}

@ -78,6 +78,13 @@ func ErrChanReserveTooLarge(reserve,
}
}
// ErrNonZeroPushAmount is returned by a remote peer that receives a
// FundingOpen request for a channel with non-zero push amount while
// they have 'rejectpush' enabled.
func ErrNonZeroPushAmount() ReservationError {
return ReservationError{errors.New("Non-zero push amounts are disabled")}
}
// ErrMinHtlcTooLarge returns an error indicating that the MinHTLC value the
// remote required is too large to be accepted.
func ErrMinHtlcTooLarge(minHtlc,