From d86e79eb79264aeff8c94afc9db1da1d1974b715 Mon Sep 17 00:00:00 2001 From: Calvin Kim Date: Fri, 21 Jul 2023 17:13:49 +0900 Subject: [PATCH] blockchain: Refactor dbPutUtxoView This change is part of the effort to add utxocache support to btcd. dbPutUtxoView handled putting and deleting new/spent utxos from the database. These two functinalities are refactored to their own functions: dbDeleteUtxoEntry and dbPutUtxoEntry. Refactoring these out allows the cache to call these two functions directly instead of having to create a view and saving that view to disk. --- blockchain/chainio.go | 62 +++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/blockchain/chainio.go b/blockchain/chainio.go index 8c9ee283..33ed91f5 100644 --- a/blockchain/chainio.go +++ b/blockchain/chainio.go @@ -799,35 +799,57 @@ func dbPutUtxoView(dbTx database.Tx, view *UtxoViewpoint) error { // Remove the utxo entry if it is spent. if entry.IsSpent() { - key := outpointKey(outpoint) - err := utxoBucket.Delete(*key) - recycleOutpointKey(key) + err := dbDeleteUtxoEntry(utxoBucket, outpoint) + if err != nil { + return err + } + } else { + err := dbPutUtxoEntry(utxoBucket, outpoint, entry) if err != nil { return err } - - continue - } - - // Serialize and store the utxo entry. - serialized, err := serializeUtxoEntry(entry) - if err != nil { - return err - } - key := outpointKey(outpoint) - err = utxoBucket.Put(*key, serialized) - // NOTE: The key is intentionally not recycled here since the - // database interface contract prohibits modifications. It will - // be garbage collected normally when the database is done with - // it. - if err != nil { - return err } } return nil } +// dbDeleteUtxoEntry uses an existing database transaction to delete the utxo +// entry from the database. +func dbDeleteUtxoEntry(utxoBucket database.Bucket, outpoint wire.OutPoint) error { + key := outpointKey(outpoint) + err := utxoBucket.Delete(*key) + recycleOutpointKey(key) + return err +} + +// dbPutUtxoEntry uses an existing database transaction to update the utxo entry +// in the database. +func dbPutUtxoEntry(utxoBucket database.Bucket, outpoint wire.OutPoint, + entry *UtxoEntry) error { + + if entry == nil || entry.IsSpent() { + return AssertError("trying to store nil or spent entry") + } + + // Serialize and store the utxo entry. + serialized, err := serializeUtxoEntry(entry) + if err != nil { + return err + } + key := outpointKey(outpoint) + err = utxoBucket.Put(*key, serialized) + if err != nil { + return err + } + + // NOTE: The key is intentionally not recycled here since the + // database interface contract prohibits modifications. It will + // be garbage collected normally when the database is done with + // it. + return nil +} + // ----------------------------------------------------------------------------- // The block index consists of two buckets with an entry for every block in the // main chain. One bucket is for the hash to height mapping and the other is