From fa70990452045684a21e2ed0084db2bb21f3b023 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 19 Sep 2016 11:46:48 -0700 Subject: [PATCH] channeldb: store the invoice counter within the invoice index bucket This commit moves the location of the invoice counter key which is an auto-incrementing primary key for all invoices. Rather than storing the counter in the same top-level invoice bucket, the counter is now stored within the invoiceIndex bucket. With this change, the top-level bucket can now cleanly be scanned in a sequential manner to retrieve all invoices. --- channeldb/error.go | 5 ++-- channeldb/invoices.go | 64 +++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/channeldb/error.go b/channeldb/error.go index 35359864a..cab8a1e19 100644 --- a/channeldb/error.go +++ b/channeldb/error.go @@ -9,6 +9,7 @@ var ( ErrChannelNoExist = fmt.Errorf("this channel does not exist") ErrNoPastDeltas = fmt.Errorf("channel has no recorded deltas") - ErrInvoiceNotFound = fmt.Errorf("unable to locate invoice") - ErrDuplicateInvoice = fmt.Errorf("invoice with payment hash already exists") + ErrInvoiceNotFound = fmt.Errorf("unable to locate invoice") + ErrNoInvoicesCreated = fmt.Errorf("there are no existing invoices") + ErrDuplicateInvoice = fmt.Errorf("invoice with payment hash already exists") ) diff --git a/channeldb/invoices.go b/channeldb/invoices.go index 7d022039c..073568a80 100644 --- a/channeldb/invoices.go +++ b/channeldb/invoices.go @@ -18,19 +18,20 @@ var ( // which is a monotonically increasing uint32. invoiceBucket = []byte("invoices") - // numInvoicesKey is the name of key which houses the auto-incrementing - // invoice ID which is essentially used as a primary key. With each - // invoice inserted, the primary key is incremented by one. Within the - // above bucket invoices are uniquely identified by the invoice ID. - numInvoicesKey = []byte("nik") - // paymentHashIndexBucket is the name of the sub-bucket within the // invoiceBucket which indexes all invoices by their payment hash. The // payment hash is the sha256 of the invoice's payment preimage. This // index is used to detect duplicates, and also to provide a fast path // for looking up incoming HTLC's to determine if we're able to settle // them fully. - paymentHashIndexBucket = []byte("paymenthashes") + invoiceIndexBucket = []byte("paymenthashes") + + // numInvoicesKey is the name of key which houses the auto-incrementing + // invoice ID which is essentially used as a primary key. With each + // invoice inserted, the primary key is incremented by one. This key is + // stored within the invoiceIndexBucket. Within the invoiceBucket + // invoices are uniquely identified by the invoice ID. + numInvoicesKey = []byte("nik") ) const ( @@ -43,6 +44,24 @@ const ( MaxReceiptSize = 1024 ) +// ContractTerm is a companion struct to the Invoice struct. This struct houses +// the necessary conditions required before the invoice can be considered fully +// settled by the payee. +type ContractTerm struct { + // PaymentPreimage is the preimage which is to be revealed in the + // occasion that an HTLC paying to the hash of this preimage is + // extended. + PaymentPreimage [32]byte + + // Value is the expected amount to be payed to an HTLC which can be + // satisfied by the above preimage. + Value btcutil.Amount + + // Settled indicates if this particular contract term has been fully + // settled by the payer. + Settled bool +} + // Invoice is a payment invoice generated by a payee in order to request // payment for some good or service. The inclusion of invoices within Lightning // creates a payment work flow for merchants very similar to that of the @@ -78,24 +97,6 @@ type Invoice struct { Terms ContractTerm } -// ContractTerm is a companion struct to the Invoice struct. This struct houses -// the necessary conditions required before the invoice can be considered fully -// settled by the payee. -type ContractTerm struct { - // PaymentPreimage is the preimage which is to be revealed in the - // occasion that an HTLC paying to the hash of this preimage is - // extended. - PaymentPreimage [32]byte - - // Value is the expected amount to be payed to an HTLC which can be - // satisfied by the above preimage. - Value btcutil.Amount - - // Settled indicates if this particular contract term has been fully - // settled by the payer. - Settled bool -} - // AddInvoice inserts the targeted invoice into the database. If the invoice // has *any* payment hashes which already exists within the database, then the // insertion will be aborted and rejected due to the strict policy banning any @@ -107,7 +108,7 @@ func (d *DB) AddInvoice(i *Invoice) error { return err } - invoiceIndex, err := invoices.CreateBucketIfNotExists(paymentHashIndexBucket) + invoiceIndex, err := invoices.CreateBucketIfNotExists(invoiceIndexBucket) if err != nil { return err } @@ -122,18 +123,17 @@ func (d *DB) AddInvoice(i *Invoice) error { // If the current running payment ID counter hasn't yet been // created, then create it now. var invoiceNum uint32 - invoiceCounter := invoices.Get(numInvoicesKey) + invoiceCounter := invoiceIndex.Get(numInvoicesKey) if invoiceCounter == nil { var scratch [4]byte byteOrder.PutUint32(scratch[:], invoiceNum) - if err := invoices.Put(numInvoicesKey, scratch[:]); err != nil { + if err := invoiceIndex.Put(numInvoicesKey, scratch[:]); err != nil { return nil } } else { invoiceNum = byteOrder.Uint32(invoiceCounter) } - // index from payment hash to ID? return putInvoice(invoices, invoiceIndex, i, invoiceNum) }) } @@ -151,7 +151,7 @@ func (d *DB) LookupInvoice(paymentHash [32]byte) (*Invoice, error) { if invoices == nil { return ErrInvoiceNotFound } - invoiceIndex := invoices.Bucket(paymentHashIndexBucket) + invoiceIndex := invoices.Bucket(invoiceIndexBucket) if invoiceIndex == nil { return ErrInvoiceNotFound } @@ -190,7 +190,7 @@ func (d *DB) SettleInvoice(paymentHash [32]byte) error { if err != nil { return err } - invoiceIndex, err := invoices.CreateBucketIfNotExists(paymentHashIndexBucket) + invoiceIndex, err := invoices.CreateBucketIfNotExists(invoiceIndexBucket) if err != nil { return err } @@ -219,7 +219,7 @@ func putInvoice(invoices *bolt.Bucket, invoiceIndex *bolt.Bucket, var scratch [4]byte invoiceCounter := invoiceNum + 1 byteOrder.PutUint32(scratch[:], invoiceCounter) - if err := invoices.Put(numInvoicesKey, scratch[:]); err != nil { + if err := invoiceIndex.Put(numInvoicesKey, scratch[:]); err != nil { return err }