channeldb: add payment statuses: ground, in flight, completed

This commit is contained in:
Vadym Popov 2018-08-12 16:12:37 +03:00 committed by Conner Fromknecht
parent f028eaa152
commit 7296cfb425
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7

@ -3,6 +3,7 @@ package channeldb
import (
"bytes"
"encoding/binary"
"errors"
"io"
"github.com/coreos/bbolt"
@ -17,8 +18,64 @@ var (
// which is a monotonically increasing uint64. BoltDB's sequence
// feature is used for generating monotonically increasing id.
paymentBucket = []byte("payments")
// paymentStatusBucket is the name of the bucket within the database that
// stores the status of a payment indexed by the payment's preimage.
paymentStatusBucket = []byte("payment-status")
)
// PaymentStatus represent current status of payment
type PaymentStatus byte
const (
// StatusGrounded is status where payment is initiated and received
// an intermittent failure
StatusGrounded PaymentStatus = 0
// StatusInFlight is status where payment is initiated, but a response
// has not been received
StatusInFlight PaymentStatus = 1
// StatusCompleted is status where payment is initiated and complete
// a payment successfully
StatusCompleted PaymentStatus = 2
)
// Bytes returns status as slice of bytes
func (ps PaymentStatus) Bytes() []byte {
return []byte{byte(ps)}
}
// FromBytes sets status from slice of bytes
func (ps *PaymentStatus) FromBytes(status []byte) error {
if len(status) != 1 {
return errors.New("payment status is empty")
}
switch PaymentStatus(status[0]) {
case StatusGrounded, StatusInFlight, StatusCompleted:
*ps = PaymentStatus(status[0])
default:
return errors.New("unknown payment status")
}
return nil
}
// String returns readable representation of payment status
func (ps PaymentStatus) String() string {
switch ps {
case StatusGrounded:
return "Grounded"
case StatusInFlight:
return "In Flight"
case StatusCompleted:
return "Completed"
default:
return "Unknown"
}
}
// OutgoingPayment represents a successful payment between the daemon and a
// remote node. Details such as the total fee paid, and the time of the payment
// are stored.
@ -129,6 +186,45 @@ func (db *DB) DeleteAllPayments() error {
})
}
// UpdatePaymentStatus sets status for outgoing/finished payment to store status in
// local database.
func (db *DB) UpdatePaymentStatus(paymentHash [32]byte, status PaymentStatus) error {
return db.Batch(func(tx *bolt.Tx) error {
paymentStatuses, err := tx.CreateBucketIfNotExists(paymentStatusBucket)
if err != nil {
return err
}
return paymentStatuses.Put(paymentHash[:], status.Bytes())
})
}
// FetchPaymentStatus returns payment status for outgoing payment
// if status of the payment isn't found it set to default status "StatusGrounded".
func (db *DB) FetchPaymentStatus(paymentHash [32]byte) (PaymentStatus, error) {
// default status for all payments that wasn't recorded in database
paymentStatus := StatusGrounded
err := db.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket(paymentStatusBucket)
if bucket == nil {
return nil
}
paymentStatusBytes := bucket.Get(paymentHash[:])
if paymentStatusBytes == nil {
return nil
}
return paymentStatus.FromBytes(paymentStatusBytes)
})
if err != nil {
return StatusGrounded, err
}
return paymentStatus, nil
}
func serializeOutgoingPayment(w io.Writer, p *OutgoingPayment) error {
var scratch [8]byte