Skip to content

Commit

Permalink
Optimize update utxo about batch
Browse files Browse the repository at this point in the history
  • Loading branch information
lochjin committed Oct 11, 2023
1 parent 409dbe0 commit d51b46e
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 3 deletions.
1 change: 1 addition & 0 deletions consensus/model/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type DataBase interface {
PutUtxo(key []byte, data []byte) error
DeleteUtxo(key []byte) error
ForeachUtxo(fn func(key []byte, data []byte) error) error
UpdateUtxo(opts []*common.UtxoOpt) error
GetTokenState(blockID uint) ([]byte, error)
PutTokenState(blockID uint, data []byte) error
DeleteTokenState(blockID uint) error
Expand Down
4 changes: 2 additions & 2 deletions core/blockchain/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ func (b *BlockChain) connectBlock(node meerdag.IBlock, blockNode *BlockNode, vie
// Update the utxo set using the state of the utxo view. This
// entails removing all of the utxos spent and adding the new
// ones created by the block.
err = b.dbPutUtxoView(view)
err = b.dbUpdateUtxoView(view)
if err != nil {
return err
}
Expand Down Expand Up @@ -478,7 +478,7 @@ func (b *BlockChain) disconnectBlock(ib meerdag.IBlock, block *types.SerializedB
// Update the utxo set using the state of the utxo view. This
// entails restoring all of the utxos spent and removing the new
// ones created by the block.
err := b.dbPutUtxoView(view)
err := b.dbUpdateUtxoView(view)
if err != nil {
return err
}
Expand Down
43 changes: 42 additions & 1 deletion core/blockchain/utxo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/Qitmeer/qng/common/hash"
"github.com/Qitmeer/qng/core/blockchain/utxo"
"github.com/Qitmeer/qng/core/types"
"github.com/Qitmeer/qng/database/common"
"github.com/Qitmeer/qng/database/legacydb"
"github.com/Qitmeer/qng/meerdag"
)
Expand Down Expand Up @@ -238,5 +239,45 @@ func (b *BlockChain) dbPutUtxoViewByBlock(block *types.SerializedBlock) error {
for _, tx := range block.Transactions() {
view.AddTxOuts(tx, block.Hash())
}
return b.dbPutUtxoView(view)
return b.dbUpdateUtxoView(view)
}

func (b *BlockChain) dbUpdateUtxoView(view *utxo.UtxoViewpoint) error {
opts := []*common.UtxoOpt{}
for op, en := range view.Entries() {
outpoint := op
entry := en
// No need to update the database if the entry was not modified.
if entry == nil || !entry.IsModified() {
continue
}
// Remove the utxo entry if it is spent.
if entry.IsSpent() {
key := utxo.OutpointKey(outpoint)
opts = append(opts, &common.UtxoOpt{Add: false, Key: *key})
utxo.RecycleOutpointKey(key)
if b.Acct != nil {
err := b.Acct.Apply(false, &outpoint, entry)
if err != nil {
log.Error(err.Error())
}
}
continue
}

// Serialize and store the utxo entry.
serialized, err := utxo.SerializeUtxoEntry(entry)
if err != nil {
return err
}
key := utxo.OutpointKey(outpoint)
opts = append(opts, &common.UtxoOpt{Add: true, Key: *key, Data: serialized})
if b.Acct != nil {
err = b.Acct.Apply(true, &outpoint, entry)
if err != nil {
log.Error(err.Error())
}
}
}
return b.DB().UpdateUtxo(opts)
}
21 changes: 21 additions & 0 deletions database/chaindb/chaindb.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,27 @@ func (cdb *ChainDB) ForeachUtxo(fn func(key []byte, data []byte) error) error {
return rawdb.ForeachUtxo(cdb.db, fn)
}

func (cdb *ChainDB) UpdateUtxo(opts []*common.UtxoOpt) error {
if len(opts) <= 0 {
return nil
}
if cdb.diff != nil {
return cdb.diff.UpdateUtxo(opts)
}
batch := cdb.db.NewBatch()
for _, opt := range opts {
if opt.Add {
err := rawdb.WriteUtxo(batch, opt.Key, opt.Data)
if err != nil {
return err
}
} else {
rawdb.DeleteUtxo(batch, opt.Key)
}
}
return batch.Write()
}

func (cdb *ChainDB) GetTokenState(blockID uint) ([]byte, error) {
if cdb.diff != nil {
return cdb.diff.GetTokenState(blockID)
Expand Down
21 changes: 21 additions & 0 deletions database/chaindb/difflayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/Qitmeer/qng/common/hash"
"github.com/Qitmeer/qng/consensus/model"
"github.com/Qitmeer/qng/core/types"
com "github.com/Qitmeer/qng/database/common"
"github.com/Qitmeer/qng/database/rawdb"
"github.com/Qitmeer/qng/meerdag"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -349,6 +350,26 @@ func (dl *diffLayer) ForeachUtxo(fn func(key []byte, data []byte) error) error {
return rawdb.ForeachUtxo(dl.db, fun)
}

func (dl *diffLayer) UpdateUtxo(opts []*com.UtxoOpt) error {
dl.lock.Lock()
defer dl.lock.Unlock()

if dl.utxo == nil {
dl.utxo = map[string][]byte{}
}

for _, opt := range opts {
if opt.Add {
dl.utxo[string(opt.Key)] = opt.Data
dl.memory.Add(uint64(len(opt.Data) + len(opt.Key)))
} else {
dl.utxo[string(opt.Key)] = nil
dl.memory.Add(uint64(len(opt.Key)))
}
}
return nil
}

func (dl *diffLayer) GetTokenState(blockID uint) ([]byte, error) {
dl.lock.RLock()
defer dl.lock.RUnlock()
Expand Down
7 changes: 7 additions & 0 deletions database/common/utxo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package common

type UtxoOpt struct {
Key []byte
Data []byte
Add bool
}
23 changes: 23 additions & 0 deletions database/legacychaindb/legacychaindb.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/Qitmeer/qng/core/dbnamespace"
"github.com/Qitmeer/qng/core/shutdown"
"github.com/Qitmeer/qng/core/types"
"github.com/Qitmeer/qng/database/common"
"github.com/Qitmeer/qng/database/legacydb"
"github.com/Qitmeer/qng/database/rawdb"
"github.com/Qitmeer/qng/meerdag"
Expand Down Expand Up @@ -249,6 +250,28 @@ func (cdb *LegacyChainDB) ForeachUtxo(fn func(key []byte, data []byte) error) er
})
}

func (cdb *LegacyChainDB) UpdateUtxo(opts []*common.UtxoOpt) error {
if len(opts) <= 0 {
return nil
}

return cdb.db.Update(func(dbTx legacydb.Tx) error {
bucket := dbTx.Metadata().Bucket(dbnamespace.UtxoSetBucketName)
var err error
for _, opt := range opts {
if opt.Add {
err = bucket.Put(opt.Key, opt.Data)
} else {
err = bucket.Delete(opt.Key)
}
if err != nil {
return err
}
}
return err
})
}

func (cdb *LegacyChainDB) GetTokenState(blockID uint) ([]byte, error) {
var data []byte
err := cdb.db.View(func(dbTx legacydb.Tx) error {
Expand Down

0 comments on commit d51b46e

Please sign in to comment.