htlcswitch/control_tower: add strict mode toggling

This commit is contained in:
Conner Fromknecht 2018-08-13 18:46:58 -07:00
parent 971ae3c744
commit 98d2ffbfd0
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7

@ -57,15 +57,17 @@ type ControlTower interface {
// paymentControl is persistent implementation of ControlTower to restrict // paymentControl is persistent implementation of ControlTower to restrict
// double payment sending. // double payment sending.
type paymentControl struct { type paymentControl struct {
mx sync.Mutex strict bool
mx sync.Mutex
db *channeldb.DB db *channeldb.DB
} }
// NewPaymentControl creates a new instance of the paymentControl. // NewPaymentControl creates a new instance of the paymentControl.
func NewPaymentControl(db *channeldb.DB) ControlTower { func NewPaymentControl(strict bool, db *channeldb.DB) ControlTower {
return &paymentControl{ return &paymentControl{
db: db, strict: strict,
db: db,
} }
} }
@ -116,19 +118,25 @@ func (p *paymentControl) Success(paymentHash [32]byte) error {
return err return err
} }
switch paymentStatus { switch {
case channeldb.StatusGrounded:
case paymentStatus == channeldb.StatusGrounded && p.strict:
// Our records show the payment as still being grounded, meaning // Our records show the payment as still being grounded, meaning
// it never should have left the switch. // it never should have left the switch.
return ErrPaymentNotInitiated return ErrPaymentNotInitiated
case channeldb.StatusInFlight: case paymentStatus == channeldb.StatusGrounded && !p.strict:
// Our records show the payment as still being grounded, meaning
// it never should have left the switch.
fallthrough
case paymentStatus == channeldb.StatusInFlight:
// A successful response was received for an InFlight payment, // A successful response was received for an InFlight payment,
// mark it as completed to prevent sending to this payment hash // mark it as completed to prevent sending to this payment hash
// again. // again.
return p.db.UpdatePaymentStatus(paymentHash, channeldb.StatusCompleted) return p.db.UpdatePaymentStatus(paymentHash, channeldb.StatusCompleted)
case channeldb.StatusCompleted: case paymentStatus == channeldb.StatusCompleted:
// The payment was completed previously, alert the caller that // The payment was completed previously, alert the caller that
// this may be a duplicate call. // this may be a duplicate call.
return ErrPaymentAlreadyCompleted return ErrPaymentAlreadyCompleted
@ -150,18 +158,24 @@ func (p *paymentControl) Fail(paymentHash [32]byte) error {
return err return err
} }
switch paymentStatus { switch {
case channeldb.StatusGrounded:
case paymentStatus == channeldb.StatusGrounded && p.strict:
// Our records show the payment as still being grounded, meaning // Our records show the payment as still being grounded, meaning
// it never should have left the switch. // it never should have left the switch.
return ErrPaymentNotInitiated return ErrPaymentNotInitiated
case channeldb.StatusInFlight: case paymentStatus == channeldb.StatusGrounded && !p.strict:
// Our records show the payment as still being grounded, meaning
// it never should have left the switch.
fallthrough
case paymentStatus == channeldb.StatusInFlight:
// A failed response was received for an InFlight payment, mark // A failed response was received for an InFlight payment, mark
// it as Grounded again to allow subsequent attempts. // it as Grounded again to allow subsequent attempts.
return p.db.UpdatePaymentStatus(paymentHash, channeldb.StatusGrounded) return p.db.UpdatePaymentStatus(paymentHash, channeldb.StatusGrounded)
case channeldb.StatusCompleted: case paymentStatus == channeldb.StatusCompleted:
// The payment was completed previously, and we are now // The payment was completed previously, and we are now
// reporting that it has failed. Leave the status as completed, // reporting that it has failed. Leave the status as completed,
// but alert the user that something is wrong. // but alert the user that something is wrong.