diff --git a/consensus/model/database.go b/consensus/model/database.go index 12d0cd6c..2950efc0 100644 --- a/consensus/model/database.go +++ b/consensus/model/database.go @@ -19,6 +19,7 @@ type DataBase interface { GetUtxo(key []byte) ([]byte, error) PutUtxo(key []byte, data []byte) error DeleteUtxo(key []byte) error + ForeachUtxo(fn func(key []byte, data []byte) error) error GetTokenState(blockID uint) ([]byte, error) PutTokenState(blockID uint, data []byte) error DeleteTokenState(blockID uint) error diff --git a/database/chaindb/chaindb.go b/database/chaindb/chaindb.go index a351067c..383a6713 100644 --- a/database/chaindb/chaindb.go +++ b/database/chaindb/chaindb.go @@ -167,6 +167,10 @@ func (cdb *ChainDB) DeleteUtxo(key []byte) error { return nil } +func (cdb *ChainDB) ForeachUtxo(fn func(key []byte, data []byte) error) error { + return rawdb.ForeachUtxo(cdb.db, fn) +} + func (cdb *ChainDB) GetTokenState(blockID uint) ([]byte, error) { return rawdb.ReadTokenState(cdb.db, uint64(blockID)), nil } diff --git a/database/legacychaindb/legacychaindb.go b/database/legacychaindb/legacychaindb.go index 3fb5a4e4..b26cfda3 100644 --- a/database/legacychaindb/legacychaindb.go +++ b/database/legacychaindb/legacychaindb.go @@ -204,6 +204,21 @@ func (cdb *LegacyChainDB) DeleteUtxo(key []byte) error { }) } +func (cdb *LegacyChainDB) ForeachUtxo(fn func(key []byte, data []byte) error) error { + return cdb.db.View(func(dbTx legacydb.Tx) error { + meta := dbTx.Metadata() + utxoBucket := meta.Bucket(dbnamespace.UtxoSetBucketName) + cursor := utxoBucket.Cursor() + for ok := cursor.First(); ok; ok = cursor.Next() { + err := fn(cursor.Key(), cursor.Value()) + if err != nil { + return err + } + } + return nil + }) +} + func (cdb *LegacyChainDB) GetTokenState(blockID uint) ([]byte, error) { var data []byte err := cdb.db.View(func(dbTx legacydb.Tx) error { diff --git a/database/rawdb/accessors_chain.go b/database/rawdb/accessors_chain.go index dd3fd3a6..dd68195d 100644 --- a/database/rawdb/accessors_chain.go +++ b/database/rawdb/accessors_chain.go @@ -261,6 +261,19 @@ func DeleteUtxo(db ethdb.KeyValueWriter, opd []byte) { } } +func ForeachUtxo(db ethdb.KeyValueStore, fn func(opd []byte, data []byte) error) error { + it := db.NewIterator(utxoPrefix, nil) + defer it.Release() + + for it.Next() { + err := fn(it.Key(), it.Value()) + if err != nil { + return err + } + } + return nil +} + // tokenState func ReadTokenState(db ethdb.Reader, id uint64) []byte { diff --git a/services/acct/acctmgr.go b/services/acct/acctmgr.go index a34e9625..db59b020 100644 --- a/services/acct/acctmgr.go +++ b/services/acct/acctmgr.go @@ -8,7 +8,6 @@ import ( "github.com/Qitmeer/qng/core/address" "github.com/Qitmeer/qng/core/blockchain" "github.com/Qitmeer/qng/core/blockchain/utxo" - "github.com/Qitmeer/qng/core/dbnamespace" "github.com/Qitmeer/qng/core/types" "github.com/Qitmeer/qng/database/legacydb" "github.com/Qitmeer/qng/engine/txscript" @@ -171,36 +170,31 @@ func (a *AccountManager) rebuild(addrs []string) error { } ops := []*types.TxOutPoint{} entrys := []*utxo.UtxoEntry{} - err := a.chain.Consensus().LegacyDB().View(func(dbTx legacydb.Tx) error { - meta := dbTx.Metadata() - utxoBucket := meta.Bucket(dbnamespace.UtxoSetBucketName) - cursor := utxoBucket.Cursor() - for ok := cursor.First(); ok; ok = cursor.Next() { - op, err := parseOutpoint(cursor.Key()) - if err != nil { - return err - } - serializedUtxo := cursor.Value() - // Deserialize the utxo entry and return it. - entry, err := utxo.DeserializeUtxoEntry(serializedUtxo) + err := a.chain.DB().ForeachUtxo(func(key []byte, data []byte) error { + op, err := parseOutpoint(key) + if err != nil { + return err + } + serializedUtxo := data + // Deserialize the utxo entry and return it. + entry, err := utxo.DeserializeUtxoEntry(serializedUtxo) + if err != nil { + return err + } + if entry.IsSpent() { + return nil + } + if len(addrs) > 0 { + addr, _, err := a.checkUtxoEntry(entry, addrs) if err != nil { return err } - if entry.IsSpent() { - continue - } - if len(addrs) > 0 { - addr, _, err := a.checkUtxoEntry(entry, addrs) - if err != nil { - return err - } - if len(addr) <= 0 { - continue - } + if len(addr) <= 0 { + return nil } - ops = append(ops, op) - entrys = append(entrys, entry) } + ops = append(ops, op) + entrys = append(entrys, entry) return nil }) if err != nil {