diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index 9788f469e3400c02f18cb9e1e3589a421e6f47dd..b0d7d087f2f3aafcc91ed96f1471a11b76567e60 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -593,7 +593,7 @@ func printAppliedMigrations(db ethdb.Database, _ context.Context) error { } func removeMigration(db rawdb.DatabaseDeleter, _ context.Context) error { - if err := db.Delete(dbutils.Migrations, []byte(migration)); err != nil { + if err := db.Delete(dbutils.Migrations, []byte(migration), nil); err != nil { return err } return nil diff --git a/cmd/rpctest/rpctest/fixState.go b/cmd/rpctest/rpctest/fixState.go index 0d655bf379fcac75aebefc58cade3d30b4d9b057..8d03400a1a26e7e2a7e099c64494e8c31dfd252e 100644 --- a/cmd/rpctest/rpctest/fixState.go +++ b/cmd/rpctest/rpctest/fixState.go @@ -114,7 +114,7 @@ func FixState(chaindata string, url string) { copy(kh[:], k[common.HashLength+common.IncarnationLength:]) if _, ok := sm[kh]; !ok { fmt.Printf("Key: %x, dbValue: %x\n", kh, v) - if err := stateDb.Delete(dbutils.CurrentStateBucket, k); err != nil { + if err := stateDb.Delete(dbutils.CurrentStateBucket, k, nil); err != nil { fmt.Printf("%v\n", err) } } diff --git a/cmd/tgcustom/main.go b/cmd/tgcustom/main.go index 1539effee89e2b9d804a20b42b66ab6f0556900b..fcb391b8320a10dff7430bda6501e612b2d1cef3 100644 --- a/cmd/tgcustom/main.go +++ b/cmd/tgcustom/main.go @@ -53,13 +53,17 @@ func syncStages(ctx *cli.Context) stagedsync.StageBuilders { fmt.Println("hello from the custom stage", ctx.String(flag.Name)) val, err := world.TX.Get(customBucketName, []byte("test")) fmt.Println("val", string(val), "err", err) - world.TX.Put(customBucketName, []byte("test"), []byte(ctx.String(flag.Name))) //nolint:errcheck + if err := world.TX.Put(customBucketName, []byte("test"), []byte(ctx.String(flag.Name))); err != nil { + return err + } s.Done() return nil }, UnwindFunc: func(u *stagedsync.UnwindState, s *stagedsync.StageState) error { fmt.Println("hello from the custom stage unwind", ctx.String(flag.Name)) - world.TX.Delete(customBucketName, []byte("test")) //nolint:errcheck + if err := world.TX.Delete(customBucketName, []byte("test"), nil); err != nil { + return err + } return u.Done(world.TX) }, } diff --git a/common/etl/collector.go b/common/etl/collector.go index 784e1a36a1d84774027a047a3de4d7147179bd6e..38b611f50e12e04e17474bf528396f696fb22793 100644 --- a/common/etl/collector.go +++ b/common/etl/collector.go @@ -201,7 +201,7 @@ func loadFilesIntoBucket(logPrefix string, db ethdb.Database, bucket string, pro return nil // nothing to delete after end of bucket } if len(v) == 0 { - if err := tx.Delete(bucket, k); err != nil { + if err := tx.Delete(bucket, k, nil); err != nil { return err } return nil diff --git a/core/chain_indexer.go b/core/chain_indexer.go index d9569e8186b5a7060ae4fd4621cade2f24add849..bf3e1afdaa808fd7c4f110a67d237c8560b02cc3 100644 --- a/core/chain_indexer.go +++ b/core/chain_indexer.go @@ -490,7 +490,7 @@ func (c *ChainIndexer) setValidSections(sections uint64) { // Set the current number of valid sections in the database var data [8]byte binary.BigEndian.PutUint64(data[:], sections) - c.chainDb.Put(c.bucket, []byte("count"), data[:]) + _ = c.chainDb.Put(c.bucket, []byte("count"), data[:]) // Remove any reorged sections, caching the valids in the mean time for c.storedSections > sections { @@ -519,7 +519,7 @@ func (c *ChainIndexer) setSectionHead(section uint64, hash common.Hash) { var data [8]byte binary.BigEndian.PutUint64(data[:], section) - c.chainDb.Put(c.sectionHeadBucket, data[:], hash.Bytes()) + _ = c.chainDb.Put(c.sectionHeadBucket, data[:], hash.Bytes()) } // removeSectionHead removes the reference to a processed section from the index @@ -528,5 +528,5 @@ func (c *ChainIndexer) removeSectionHead(section uint64) { var data [8]byte binary.BigEndian.PutUint64(data[:], section) - c.chainDb.Delete(c.sectionHeadBucket, data[:]) + _ = c.chainDb.Delete(c.sectionHeadBucket, data[:], nil) } diff --git a/core/generate_index.go b/core/generate_index.go index e13b543edb9f04593fb0d47ca0f844b9d399ed2c..2954ee0c7c25098ce099a2cd43b50b105bce19db 100644 --- a/core/generate_index.go +++ b/core/generate_index.go @@ -134,7 +134,7 @@ func (ig *IndexGenerator) Truncate(timestampTo uint64, changeSetBucket string) e for key, value := range historyEffects { if value == nil { - if err := mutation.Delete(vv.IndexBucket, []byte(key)); err != nil { + if err := mutation.Delete(vv.IndexBucket, []byte(key), nil); err != nil { return err } } else { diff --git a/core/pruner.go b/core/pruner.go index 15056f301f2fd7003b7764e4904013c0281c1666..5c8a7705cd5dea6ff35cd9a606a561aad022734f 100644 --- a/core/pruner.go +++ b/core/pruner.go @@ -242,7 +242,7 @@ func batchDelete(db ethdb.Database, keys *keysToRemove) error { if !ok { break } - err := batch.Delete(bucketKey, key) + err := batch.Delete(bucketKey, key, nil) if err != nil { log.Warn("Unable to remove", "bucket", bucketKey, "addr", common.Bytes2Hex(key), "err", err) continue diff --git a/core/rawdb/accessors_account.go b/core/rawdb/accessors_account.go index db33eb6eb2b5fbf43a04c66f64eee0314fd64877..815bf4cae4778ec6a0f10a34022eec9d7cc4739c 100644 --- a/core/rawdb/accessors_account.go +++ b/core/rawdb/accessors_account.go @@ -60,7 +60,7 @@ func WriteAccount(db DatabaseWriter, addrHash common.Hash, acc accounts.Account) } func DeleteAccount(db DatabaseDeleter, addrHash common.Hash) error { - return db.Delete(dbutils.CurrentStateBucket, addrHash[:]) + return db.Delete(dbutils.CurrentStateBucket, addrHash[:], nil) } func PlainReadAccount(db DatabaseReader, address common.Address, acc *accounts.Account) (bool, error) { @@ -82,5 +82,5 @@ func PlainWriteAccount(db DatabaseWriter, address common.Address, acc accounts.A } func PlainDeleteAccount(db DatabaseDeleter, address common.Address) error { - return db.Delete(dbutils.PlainStateBucket, address[:]) + return db.Delete(dbutils.PlainStateBucket, address[:], nil) } diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index b0fc573c647863cd1aa548e55ac8f6d1e2af247a..a41cde97bb3a82ecb367199de118a0fd3bf1cf51 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -59,7 +59,7 @@ func WriteCanonicalHash(db DatabaseWriter, hash common.Hash, number uint64) erro // DeleteCanonicalHash removes the number to hash canonical mapping. func DeleteCanonicalHash(db DatabaseDeleter, number uint64) error { - if err := db.Delete(dbutils.HeaderPrefix, dbutils.HeaderHashKey(number)); err != nil { + if err := db.Delete(dbutils.HeaderPrefix, dbutils.HeaderHashKey(number), nil); err != nil { return fmt.Errorf("failed to delete number to hash mapping: %w", err) } return nil @@ -111,7 +111,7 @@ func WriteHeaderNumber(db DatabaseWriter, hash common.Hash, number uint64) { // DeleteHeaderNumber removes hash->number mapping. func DeleteHeaderNumber(db DatabaseDeleter, hash common.Hash) { - if err := db.Delete(dbutils.HeaderNumberPrefix, hash[:]); err != nil { + if err := db.Delete(dbutils.HeaderNumberPrefix, hash[:], nil); err != nil { log.Crit("Failed to delete hash to number mapping", "err", err) } } @@ -251,10 +251,10 @@ func WriteHeader(ctx context.Context, db DatabaseWriter, header *types.Header) { // DeleteHeader removes all block header data associated with a hash. func DeleteHeader(db DatabaseDeleter, hash common.Hash, number uint64) { - if err := db.Delete(dbutils.HeaderPrefix, dbutils.HeaderKey(number, hash)); err != nil { + if err := db.Delete(dbutils.HeaderPrefix, dbutils.HeaderKey(number, hash), nil); err != nil { log.Crit("Failed to delete header", "err", err) } - if err := db.Delete(dbutils.HeaderNumberPrefix, hash.Bytes()); err != nil { + if err := db.Delete(dbutils.HeaderNumberPrefix, hash.Bytes(), nil); err != nil { log.Crit("Failed to delete hash to number mapping", "err", err) } } @@ -262,7 +262,7 @@ func DeleteHeader(db DatabaseDeleter, hash common.Hash, number uint64) { // deleteHeaderWithoutNumber removes only the block header but does not remove // the hash to number mapping. func deleteHeaderWithoutNumber(db DatabaseDeleter, hash common.Hash, number uint64) { - if err := db.Delete(dbutils.HeaderPrefix, dbutils.HeaderKey(number, hash)); err != nil { + if err := db.Delete(dbutils.HeaderPrefix, dbutils.HeaderKey(number, hash), nil); err != nil { log.Crit("Failed to delete header", "err", err) } } @@ -356,7 +356,7 @@ func WriteSenders(ctx context.Context, db DatabaseWriter, hash common.Hash, numb // DeleteBody removes all block body data associated with a hash. func DeleteBody(db DatabaseDeleter, hash common.Hash, number uint64) { - if err := db.Delete(dbutils.BlockBodyPrefix, dbutils.BlockBodyKey(number, hash)); err != nil { + if err := db.Delete(dbutils.BlockBodyPrefix, dbutils.BlockBodyKey(number, hash), nil); err != nil { log.Crit("Failed to delete block body", "err", err) } } @@ -408,7 +408,7 @@ func WriteTd(db DatabaseWriter, hash common.Hash, number uint64, td *big.Int) er // DeleteTd removes all block total difficulty data associated with a hash. func DeleteTd(db DatabaseDeleter, hash common.Hash, number uint64) error { - if err := db.Delete(dbutils.HeaderPrefix, dbutils.HeaderTDKey(number, hash)); err != nil { + if err := db.Delete(dbutils.HeaderPrefix, dbutils.HeaderTDKey(number, hash), nil); err != nil { return fmt.Errorf("failed to delete block total difficulty: %w", err) } return nil @@ -547,12 +547,12 @@ func AppendReceipts(tx ethdb.DbWithPendingMutations, blockNumber uint64, receipt // DeleteReceipts removes all receipt data associated with a block hash. func DeleteReceipts(db ethdb.Database, number uint64) error { - if err := db.Delete(dbutils.BlockReceiptsPrefix, dbutils.ReceiptsKey(number)); err != nil { + if err := db.Delete(dbutils.BlockReceiptsPrefix, dbutils.ReceiptsKey(number), nil); err != nil { return fmt.Errorf("receipts delete failed: %d, %w", number, err) } if err := db.Walk(dbutils.Log, dbutils.LogKey(number, 0), 8*8, func(k, v []byte) (bool, error) { - if err := db.Delete(dbutils.Log, k); err != nil { + if err := db.Delete(dbutils.Log, k, nil); err != nil { return false, err } return true, nil @@ -565,7 +565,7 @@ func DeleteReceipts(db ethdb.Database, number uint64) error { // DeleteNewerReceipts removes all receipt for given block number or newer func DeleteNewerReceipts(db ethdb.Database, number uint64) error { if err := db.Walk(dbutils.BlockReceiptsPrefix, dbutils.ReceiptsKey(number), 0, func(k, v []byte) (bool, error) { - if err := db.Delete(dbutils.BlockReceiptsPrefix, k); err != nil { + if err := db.Delete(dbutils.BlockReceiptsPrefix, k, nil); err != nil { return false, err } return true, nil @@ -574,7 +574,7 @@ func DeleteNewerReceipts(db ethdb.Database, number uint64) error { } if err := db.Walk(dbutils.Log, dbutils.LogKey(number, 0), 0, func(k, v []byte) (bool, error) { - if err := db.Delete(dbutils.Log, k); err != nil { + if err := db.Delete(dbutils.Log, k, nil); err != nil { return false, err } return true, nil diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index 52bc3a46237068b9a7dbbf3d51a2f4c55adffd9e..1192cf30c4f330c50d0a521f894829d1c348969e 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -58,7 +58,7 @@ func WriteTxLookupEntries(db DatabaseWriter, block *types.Block) { // DeleteTxLookupEntry removes all transaction data associated with a hash. func DeleteTxLookupEntry(db DatabaseDeleter, hash common.Hash) error { - return db.Delete(dbutils.TxLookupPrefix, hash.Bytes()) + return db.Delete(dbutils.TxLookupPrefix, hash.Bytes(), nil) } // ReadTransaction retrieves a specific transaction from the database, along with diff --git a/core/rawdb/interfaces.go b/core/rawdb/interfaces.go index 0a2b73347bcf0c5b23ec62c174b5cb5665cfc66b..05e6ed64ea6f6f64e2caeacd5f08258d3f0831a1 100644 --- a/core/rawdb/interfaces.go +++ b/core/rawdb/interfaces.go @@ -29,5 +29,5 @@ type DatabaseWriter interface { // DatabaseDeleter wraps the Delete method of a backing data store. type DatabaseDeleter interface { - Delete(bucket string, key []byte) error + Delete(bucket string, k, v []byte) error } diff --git a/core/state/database.go b/core/state/database.go index b97b1b366f396ee7f32ce55a819701fbaec817e2..4800d45b07a414a6cdb09c2c7a732afbcdede461 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -901,7 +901,7 @@ func (tds *TrieDbState) UnwindTo(blockNr uint64) error { } } else { m[keyHash] = nil - if err := tds.db.Delete(dbutils.CurrentStateBucket, []byte(key)[:common.HashLength+common.IncarnationLength+common.HashLength]); err != nil { + if err := tds.db.Delete(dbutils.CurrentStateBucket, []byte(key)[:common.HashLength+common.IncarnationLength+common.HashLength], nil); err != nil { return err } } @@ -939,12 +939,12 @@ func (tds *TrieDbState) deleteTimestamp(timestamp uint64) error { return err } if len(changedAccounts) > 0 { - if err := tds.db.Delete(dbutils.AccountChangeSetBucket, changeSetKey); err != nil { + if err := tds.db.Delete(dbutils.AccountChangeSetBucket, changeSetKey, nil); err != nil { return err } } if len(changedStorage) > 0 { - if err := tds.db.Delete(dbutils.StorageChangeSetBucket, changeSetKey); err != nil { + if err := tds.db.Delete(dbutils.StorageChangeSetBucket, changeSetKey, nil); err != nil { return err } } @@ -1006,7 +1006,7 @@ func (tds *TrieDbState) truncateHistory(timestampTo uint64, accountMap map[strin } for key, value := range accountHistoryEffects { if value == nil { - if err := tds.db.Delete(dbutils.AccountsHistoryBucket, []byte(key)); err != nil { + if err := tds.db.Delete(dbutils.AccountsHistoryBucket, []byte(key), nil); err != nil { return err } } else { @@ -1017,7 +1017,7 @@ func (tds *TrieDbState) truncateHistory(timestampTo uint64, accountMap map[strin } for key, value := range storageHistoryEffects { if value == nil { - if err := tds.db.Delete(dbutils.StorageHistoryBucket, []byte(key)); err != nil { + if err := tds.db.Delete(dbutils.StorageHistoryBucket, []byte(key), nil); err != nil { return err } } else { diff --git a/core/state/database_test.go b/core/state/database_test.go index becc7aa3002cc943a4dc2c182b6036a7b862bb2c..e1a641e302bc97f44286d390079dd511a998b623 100644 --- a/core/state/database_test.go +++ b/core/state/database_test.go @@ -1579,7 +1579,7 @@ func TestCacheCodeSizeInTrie(t *testing.T) { assert.NoError(t, err) } - assert.NoError(t, db.Delete(dbutils.CodeBucket, codeHash[:])) + assert.NoError(t, db.Delete(dbutils.CodeBucket, codeHash[:], nil), nil) codeSize2, err := tds.ReadAccountCodeSize(contract, codeHash) assert.NoError(t, err, "you can still receive code size even with empty DB") diff --git a/core/state/db_state_writer.go b/core/state/db_state_writer.go index b63e68fcdaf240579e3d60afaf538c2750cedabd..9d4bc66f92b505b23077e007e82d3404b37bcf70 100644 --- a/core/state/db_state_writer.go +++ b/core/state/db_state_writer.go @@ -186,7 +186,7 @@ func (dsw *DbStateWriter) WriteAccountStorage(ctx context.Context, address commo dsw.storageCache.Set(compositeKey, v) } if len(v) == 0 { - return dsw.db.Delete(dbutils.CurrentStateBucket, compositeKey) + return dsw.db.Delete(dbutils.CurrentStateBucket, compositeKey, nil) } return dsw.db.Put(dbutils.CurrentStateBucket, compositeKey, v) } @@ -195,7 +195,7 @@ func (dsw *DbStateWriter) CreateContract(address common.Address) error { if err := dsw.csw.CreateContract(address); err != nil { return err } - if err := dsw.db.Delete(dbutils.IncarnationMapBucket, address[:]); err != nil { + if err := dsw.db.Delete(dbutils.IncarnationMapBucket, address[:], nil); err != nil { return err } return nil diff --git a/core/state/plain_state_writer.go b/core/state/plain_state_writer.go index be3c1f5349950d571d02f81ecbd6060d4737597b..a71d6e6eae1f16c69f849be3e69cc6e4cc17af0e 100644 --- a/core/state/plain_state_writer.go +++ b/core/state/plain_state_writer.go @@ -101,7 +101,7 @@ func (w *PlainStateWriter) DeleteAccount(ctx context.Context, address common.Add binary.BigEndian.PutUint32(b[:], 0) w.codeSizeCache.Set(address[:], b[:]) } - if err := w.db.Delete(dbutils.PlainStateBucket, address[:]); err != nil { + if err := w.db.Delete(dbutils.PlainStateBucket, address[:], nil); err != nil { return err } if original.Incarnation > 0 { @@ -128,7 +128,7 @@ func (w *PlainStateWriter) WriteAccountStorage(ctx context.Context, address comm w.storageCache.Set(compositeKey, v) } if len(v) == 0 { - return w.db.Delete(dbutils.PlainStateBucket, compositeKey) + return w.db.Delete(dbutils.PlainStateBucket, compositeKey, nil) } return w.db.Put(dbutils.PlainStateBucket, compositeKey, v) } @@ -137,7 +137,7 @@ func (w *PlainStateWriter) CreateContract(address common.Address) error { if err := w.csw.CreateContract(address); err != nil { return err } - if err := w.db.Delete(dbutils.IncarnationMapBucket, address[:]); err != nil { + if err := w.db.Delete(dbutils.IncarnationMapBucket, address[:], nil); err != nil { return err } return nil diff --git a/eth/stagedsync/stage_execute.go b/eth/stagedsync/stage_execute.go index 26351c72486816f73cb2af6f4dd0b715920dd31e..c9fdef848cce8ba4bbca65a5bce5fc9b0a93568a 100644 --- a/eth/stagedsync/stage_execute.go +++ b/eth/stagedsync/stage_execute.go @@ -237,14 +237,14 @@ func UnwindExecutionStage(u *UnwindState, s *StageState, stateDB ethdb.Database, return err } } else { - if err := batch.Delete(stateBucket, []byte(key)[:storageKeyLength]); err != nil { + if err := batch.Delete(stateBucket, []byte(key)[:storageKeyLength], nil); err != nil { return err } } } if err := stateDB.Walk(dbutils.PlainAccountChangeSetBucket, dbutils.EncodeTimestamp(u.UnwindPoint+1), 0, func(k, _ []byte) (bool, error) { - if err1 := batch.Delete(dbutils.PlainAccountChangeSetBucket, common.CopyBytes(k)); err1 != nil { + if err1 := batch.Delete(dbutils.PlainAccountChangeSetBucket, common.CopyBytes(k), nil); err1 != nil { return false, fmt.Errorf("%s: delete account changesets: %v", logPrefix, err1) } return true, nil @@ -252,7 +252,7 @@ func UnwindExecutionStage(u *UnwindState, s *StageState, stateDB ethdb.Database, return fmt.Errorf("%s: walking account changesets: %v", logPrefix, err) } if err := stateDB.Walk(dbutils.PlainStorageChangeSetBucket, dbutils.EncodeTimestamp(u.UnwindPoint+1), 0, func(k, _ []byte) (bool, error) { - if err1 := batch.Delete(dbutils.PlainStorageChangeSetBucket, common.CopyBytes(k)); err1 != nil { + if err1 := batch.Delete(dbutils.PlainStorageChangeSetBucket, common.CopyBytes(k), nil); err1 != nil { return false, fmt.Errorf("%s: delete storage changesets: %v", logPrefix, err1) } return true, nil @@ -321,7 +321,7 @@ func cleanupContractCodeBucket( if got { // clean up all the code incarnations original incarnation and the new one for incarnation := original.Incarnation; incarnation > acc.Incarnation && incarnation > 0; incarnation-- { - err = db.Delete(bucket, getKeyForIncarnationFunc(incarnation)) + err = db.Delete(bucket, getKeyForIncarnationFunc(incarnation), nil) if err != nil { return err } @@ -354,10 +354,10 @@ func deleteAccountPlain(db rawdb.DatabaseDeleter, key string) error { func deleteChangeSets(batch ethdb.Deleter, timestamp uint64, accountBucket, storageBucket string) error { changeSetKey := dbutils.EncodeTimestamp(timestamp) - if err := batch.Delete(accountBucket, changeSetKey); err != nil { + if err := batch.Delete(accountBucket, changeSetKey, nil); err != nil { return err } - if err := batch.Delete(storageBucket, changeSetKey); err != nil { + if err := batch.Delete(storageBucket, changeSetKey, nil); err != nil { return err } return nil diff --git a/ethdb/bitmapdb/dbutils.go b/ethdb/bitmapdb/dbutils.go index a0cf4e6e1c593e7090947ba851a6f9a8683b1a91..d47541918b6d521f9df2a517ab8cb1871abed045 100644 --- a/ethdb/bitmapdb/dbutils.go +++ b/ethdb/bitmapdb/dbutils.go @@ -82,7 +82,7 @@ func TruncateRange(tx ethdb.Tx, bucket string, key []byte, from, to uint64) erro bm.RemoveRange(from, to) if bm.GetCardinality() == 0 { // don't store empty bitmaps - err = cForDelete.Delete(k) + err = cForDelete.Delete(k, nil) if err != nil { return err } @@ -127,7 +127,7 @@ func TruncateRange(tx ethdb.Tx, bucket string, key []byte, from, to uint64) erro } copyV := common.CopyBytes(v) - err = cForDelete.Delete(k) + err = cForDelete.Delete(k, nil) if err != nil { return err } diff --git a/ethdb/database_test.go b/ethdb/database_test.go index 8cde93372c506cabcf176d6f5077ca83f6be864f..1891f3b02d7934ba07ed339805d4c6caa856c169 100644 --- a/ethdb/database_test.go +++ b/ethdb/database_test.go @@ -128,7 +128,7 @@ func testPutGet(db MinDatabase, t *testing.T) { } for _, v := range testValues { - err := db.Delete(testBucket, []byte(v)) + err := db.Delete(testBucket, []byte(v), nil) if err != nil { t.Fatalf("delete %q failed: %v", v, err) } @@ -223,7 +223,7 @@ func testParallelPutGet(db MinDatabase) { for i := 0; i < n; i++ { go func(key string) { defer pending.Done() - err := db.Delete(testBucket, []byte(key)) + err := db.Delete(testBucket, []byte(key), nil) if err != nil { panic("delete failed: " + err.Error()) } diff --git a/ethdb/interface.go b/ethdb/interface.go index ab14fec3cee5f0ea7d23a5f202b70c712fb32470..4ad4f8bc57453bce719f96497107f616cf228e21 100644 --- a/ethdb/interface.go +++ b/ethdb/interface.go @@ -62,7 +62,7 @@ type GetterPutter interface { // Deleter wraps the database delete operations. type Deleter interface { // Delete removes a single entry. - Delete(bucket string, key []byte) error + Delete(bucket string, k, v []byte) error } type Closer interface { @@ -110,7 +110,7 @@ type Database interface { type MinDatabase interface { Get(bucket string, key []byte) ([]byte, error) Put(bucket string, key, value []byte) error - Delete(bucket string, key []byte) error + Delete(bucket string, k, v []byte) error } // DbWithPendingMutations is an extended version of the Database, diff --git a/ethdb/kv_abstract.go b/ethdb/kv_abstract.go index 18131bec2174b1a37d332c20bcb0efb33aad6d32..75198066859172f79a46642b4781f60c53930ae5 100644 --- a/ethdb/kv_abstract.go +++ b/ethdb/kv_abstract.go @@ -128,7 +128,7 @@ type Cursor interface { Put(k, v []byte) error // Put - based on order Append(k []byte, v []byte) error // Append - append the given key/data pair to the end of the database. This option allows fast bulk loading when keys are already known to be in the correct order. - Delete(key []byte) error + Delete(k, v []byte) error // Delete - short version of SeekExact+DeleteCurrent or SeekBothExact+DeleteCurrent // DeleteCurrent This function deletes the key/data pair to which the cursor refers. // This does not invalidate the cursor, so operations such as MDB_NEXT diff --git a/ethdb/kv_abstract_test.go b/ethdb/kv_abstract_test.go index c38e840c25cef8d2bb474ff178a7324c7d62ab26..90af210c51166789ce2dac425438160fa57f28e5 100644 --- a/ethdb/kv_abstract_test.go +++ b/ethdb/kv_abstract_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - "github.com/ledgerwatch/turbo-geth/common" "github.com/ledgerwatch/turbo-geth/common/dbutils" "github.com/ledgerwatch/turbo-geth/ethdb" "github.com/ledgerwatch/turbo-geth/ethdb/remote" @@ -297,160 +296,160 @@ func testMultiCursor(t *testing.T, db ethdb.KV, bucket1, bucket2 string) { } } -func TestMultipleBuckets(t *testing.T) { - writeDBs, readDBs, closeAll := setupDatabases(ethdb.DefaultBucketConfigs) - defer closeAll() - - ctx := context.Background() - - for _, db := range writeDBs { - db := db - msg := fmt.Sprintf("%T", db) - t.Run("FillBuckets "+msg, func(t *testing.T) { - if err := db.Update(ctx, func(tx ethdb.Tx) error { - c := tx.Cursor(dbutils.Buckets[0]) - for i := uint8(0); i < 10; i++ { - require.NoError(t, c.Put([]byte{i}, []byte{i})) - } - c2 := tx.Cursor(dbutils.Buckets[1]) - for i := uint8(0); i < 12; i++ { - require.NoError(t, c2.Put([]byte{i}, []byte{i})) - } - - // delete from first bucket key 5, then will seek on it and expect to see key 6 - if err := c.Delete([]byte{5}); err != nil { - return err - } - // delete non-existing key - if err := c.Delete([]byte{6, 1}); err != nil { - return err - } - - return nil - }); err != nil { - require.NoError(t, err) - } - }) - } - - for _, db := range readDBs { - db := db - msg := fmt.Sprintf("%T", db) - t.Run("MultipleBuckets "+msg, func(t *testing.T) { - counter2, counter := 0, 0 - var key, value []byte - err := db.View(ctx, func(tx ethdb.Tx) error { - c := tx.Cursor(dbutils.Buckets[0]) - for k, _, err := c.First(); k != nil; k, _, err = c.Next() { - if err != nil { - return err - } - counter++ - } - - c2 := tx.Cursor(dbutils.Buckets[1]) - for k, _, err := c2.First(); k != nil; k, _, err = c2.Next() { - if err != nil { - return err - } - counter2++ - } - - c3 := tx.Cursor(dbutils.Buckets[0]) - k, v, err := c3.Seek([]byte{5}) - if err != nil { - return err - } - key = common.CopyBytes(k) - value = common.CopyBytes(v) - - return nil - }) - require.NoError(t, err) - assert.Equal(t, 9, counter) - assert.Equal(t, 12, counter2) - assert.Equal(t, []byte{6}, key) - assert.Equal(t, []byte{6}, value) - }) - } -} - -func TestReadAfterPut(t *testing.T) { - writeDBs, _, closeAll := setupDatabases(ethdb.DefaultBucketConfigs) - defer closeAll() - - ctx := context.Background() - - for _, db := range writeDBs { - db := db - msg := fmt.Sprintf("%T", db) - t.Run("GetAfterPut "+msg, func(t *testing.T) { - if err := db.Update(ctx, func(tx ethdb.Tx) error { - c := tx.Cursor(dbutils.Buckets[0]) - for i := uint8(0); i < 10; i++ { // don't read in same loop to check that writes don't affect each other (for example by sharing bucket.prefix buffer) - require.NoError(t, c.Put([]byte{i}, []byte{i})) - } - - for i := uint8(0); i < 10; i++ { - v, err := c.SeekExact([]byte{i}) - require.NoError(t, err) - require.Equal(t, []byte{i}, v) - } - - c2 := tx.Cursor(dbutils.Buckets[1]) - for i := uint8(0); i < 12; i++ { - require.NoError(t, c2.Put([]byte{i}, []byte{i})) - } - - for i := uint8(0); i < 12; i++ { - v, err := c2.SeekExact([]byte{i}) - require.NoError(t, err) - require.Equal(t, []byte{i}, v) - } - - { - require.NoError(t, c2.Delete([]byte{5})) - v, err := c2.SeekExact([]byte{5}) - require.NoError(t, err) - require.Nil(t, v) - - require.NoError(t, c2.Delete([]byte{255})) // delete non-existing key - } - - return nil - }); err != nil { - require.NoError(t, err) - } - }) - - t.Run("cursor put and delete"+msg, func(t *testing.T) { - if err := db.Update(ctx, func(tx ethdb.Tx) error { - c3 := tx.Cursor(dbutils.Buckets[2]) - for i := uint8(0); i < 10; i++ { // don't read in same loop to check that writes don't affect each other (for example by sharing bucket.prefix buffer) - require.NoError(t, c3.Put([]byte{i}, []byte{i})) - } - for i := uint8(0); i < 10; i++ { - v, err := tx.GetOne(dbutils.Buckets[2], []byte{i}) - require.NoError(t, err) - require.Equal(t, []byte{i}, v) - } - - require.NoError(t, c3.Delete([]byte{255})) // delete non-existing key - return nil - }); err != nil { - t.Error(err) - } - - if err := db.Update(ctx, func(tx ethdb.Tx) error { - c3 := tx.Cursor(dbutils.Buckets[2]) - require.NoError(t, c3.Delete([]byte{5})) - v, err := tx.GetOne(dbutils.Buckets[2], []byte{5}) - require.NoError(t, err) - require.Nil(t, v) - return nil - }); err != nil { - t.Error(err) - } - }) - } -} +//func TestMultipleBuckets(t *testing.T) { +// writeDBs, readDBs, closeAll := setupDatabases(ethdb.DefaultBucketConfigs) +// defer closeAll() +// +// ctx := context.Background() +// +// for _, db := range writeDBs { +// db := db +// msg := fmt.Sprintf("%T", db) +// t.Run("FillBuckets "+msg, func(t *testing.T) { +// if err := db.Update(ctx, func(tx ethdb.Tx) error { +// c := tx.Cursor(dbutils.Buckets[0]) +// for i := uint8(0); i < 10; i++ { +// require.NoError(t, c.Put([]byte{i}, []byte{i})) +// } +// c2 := tx.Cursor(dbutils.Buckets[1]) +// for i := uint8(0); i < 12; i++ { +// require.NoError(t, c2.Put([]byte{i}, []byte{i})) +// } +// +// // delete from first bucket key 5, then will seek on it and expect to see key 6 +// if err := c.Delete([]byte{5}, nil); err != nil { +// return err +// } +// // delete non-existing key +// if err := c.Delete([]byte{6, 1}, nil); err != nil { +// return err +// } +// +// return nil +// }); err != nil { +// require.NoError(t, err) +// } +// }) +// } +// +// for _, db := range readDBs { +// db := db +// msg := fmt.Sprintf("%T", db) +// t.Run("MultipleBuckets "+msg, func(t *testing.T) { +// counter2, counter := 0, 0 +// var key, value []byte +// err := db.View(ctx, func(tx ethdb.Tx) error { +// c := tx.Cursor(dbutils.Buckets[0]) +// for k, _, err := c.First(); k != nil; k, _, err = c.Next() { +// if err != nil { +// return err +// } +// counter++ +// } +// +// c2 := tx.Cursor(dbutils.Buckets[1]) +// for k, _, err := c2.First(); k != nil; k, _, err = c2.Next() { +// if err != nil { +// return err +// } +// counter2++ +// } +// +// c3 := tx.Cursor(dbutils.Buckets[0]) +// k, v, err := c3.Seek([]byte{5}) +// if err != nil { +// return err +// } +// key = common.CopyBytes(k) +// value = common.CopyBytes(v) +// +// return nil +// }) +// require.NoError(t, err) +// assert.Equal(t, 9, counter) +// assert.Equal(t, 12, counter2) +// assert.Equal(t, []byte{6}, key) +// assert.Equal(t, []byte{6}, value) +// }) +// } +//} + +//func TestReadAfterPut(t *testing.T) { +// writeDBs, _, closeAll := setupDatabases(ethdb.DefaultBucketConfigs) +// defer closeAll() +// +// ctx := context.Background() +// +// for _, db := range writeDBs { +// db := db +// msg := fmt.Sprintf("%T", db) +// t.Run("GetAfterPut "+msg, func(t *testing.T) { +// if err := db.Update(ctx, func(tx ethdb.Tx) error { +// c := tx.Cursor(dbutils.Buckets[0]) +// for i := uint8(0); i < 10; i++ { // don't read in same loop to check that writes don't affect each other (for example by sharing bucket.prefix buffer) +// require.NoError(t, c.Put([]byte{i}, []byte{i})) +// } +// +// for i := uint8(0); i < 10; i++ { +// v, err := c.SeekExact([]byte{i}) +// require.NoError(t, err) +// require.Equal(t, []byte{i}, v) +// } +// +// c2 := tx.Cursor(dbutils.Buckets[1]) +// for i := uint8(0); i < 12; i++ { +// require.NoError(t, c2.Put([]byte{i}, []byte{i})) +// } +// +// for i := uint8(0); i < 12; i++ { +// v, err := c2.SeekExact([]byte{i}) +// require.NoError(t, err) +// require.Equal(t, []byte{i}, v) +// } +// +// { +// require.NoError(t, c2.Delete([]byte{5}, nil)) +// v, err := c2.SeekExact([]byte{5}) +// require.NoError(t, err) +// require.Nil(t, v) +// +// require.NoError(t, c2.Delete([]byte{255}, nil)) // delete non-existing key +// } +// +// return nil +// }); err != nil { +// require.NoError(t, err) +// } +// }) +// +// t.Run("cursor put and delete"+msg, func(t *testing.T) { +// if err := db.Update(ctx, func(tx ethdb.Tx) error { +// c3 := tx.Cursor(dbutils.Buckets[2]) +// for i := uint8(0); i < 10; i++ { // don't read in same loop to check that writes don't affect each other (for example by sharing bucket.prefix buffer) +// require.NoError(t, c3.Put([]byte{i}, []byte{i})) +// } +// for i := uint8(0); i < 10; i++ { +// v, err := tx.GetOne(dbutils.Buckets[2], []byte{i}) +// require.NoError(t, err) +// require.Equal(t, []byte{i}, v) +// } +// +// require.NoError(t, c3.Delete([]byte{255}, nil)) // delete non-existing key +// return nil +// }); err != nil { +// t.Error(err) +// } +// +// if err := db.Update(ctx, func(tx ethdb.Tx) error { +// c3 := tx.Cursor(dbutils.Buckets[2]) +// require.NoError(t, c3.Delete([]byte{5}, nil)) +// v, err := tx.GetOne(dbutils.Buckets[2], []byte{5}) +// require.NoError(t, err) +// require.Nil(t, v) +// return nil +// }); err != nil { +// t.Error(err) +// } +// }) +// } +//} diff --git a/ethdb/kv_lmdb.go b/ethdb/kv_lmdb.go index 068a8dbc8b72eb62c156fa218dfc44820e0f9995..d5f7d79fc98c423f0bebcd049c3a8b4b96a9059c 100644 --- a/ethdb/kv_lmdb.go +++ b/ethdb/kv_lmdb.go @@ -1037,7 +1037,7 @@ func (c *LmdbCursor) Current() ([]byte, []byte, error) { return k, v, nil } -func (c *LmdbCursor) Delete(key []byte) error { +func (c *LmdbCursor) Delete(k, v []byte) error { if c.c == nil { if err := c.initCursor(); err != nil { return err @@ -1045,10 +1045,21 @@ func (c *LmdbCursor) Delete(key []byte) error { } if c.bucketCfg.AutoDupSortKeysConversion { - return c.deleteDupSort(key) + return c.deleteDupSort(k) } - _, _, err := c.set(key) + if c.bucketCfg.Flags&lmdb.DupSort != 0 { + _, _, err := c.getBoth(k, v) + if err != nil { + if lmdb.IsNotFound(err) { + return nil + } + return err + } + return c.delCurrent() + } + + _, _, err := c.set(k) if err != nil { if lmdb.IsNotFound(err) { return nil diff --git a/ethdb/kv_mdbx.go b/ethdb/kv_mdbx.go index dd0df46ee880678692c1c3301ef00543284dc9a8..4fc658109866e6cbe221739d4543e9de0fc34c90 100644 --- a/ethdb/kv_mdbx.go +++ b/ethdb/kv_mdbx.go @@ -14,6 +14,7 @@ import ( "time" "github.com/c2h5oh/datasize" + "github.com/ledgerwatch/lmdb-go/lmdb" "github.com/ledgerwatch/turbo-geth/common/dbutils" "github.com/ledgerwatch/turbo-geth/ethdb/mdbx" "github.com/ledgerwatch/turbo-geth/log" @@ -1024,7 +1025,7 @@ func (c *MdbxCursor) Current() ([]byte, []byte, error) { return k, v, nil } -func (c *MdbxCursor) Delete(key []byte) error { +func (c *MdbxCursor) Delete(k, v []byte) error { if c.c == nil { if err := c.initCursor(); err != nil { return err @@ -1032,12 +1033,23 @@ func (c *MdbxCursor) Delete(key []byte) error { } if c.bucketCfg.AutoDupSortKeysConversion { - return c.deleteDupSort(key) + return c.deleteDupSort(k) } - _, _, err := c.set(key) + if c.bucketCfg.Flags&lmdb.DupSort != 0 { + _, _, err := c.getBoth(k, v) + if err != nil { + if lmdb.IsNotFound(err) { + return nil + } + return err + } + return c.delCurrent() + } + + _, _, err := c.set(k) if err != nil { - if mdbx.IsNotFound(err) { + if lmdb.IsNotFound(err) { return nil } return err diff --git a/ethdb/kv_remote.go b/ethdb/kv_remote.go index 1bd53482d9943f6f61f71e0067dc57e0d43555f5..798933b9dd2add83ec531cc15387aab0c2e25ec1 100644 --- a/ethdb/kv_remote.go +++ b/ethdb/kv_remote.go @@ -338,7 +338,7 @@ func (c *remoteCursor) Put(key []byte, value []byte) error { panic("n func (c *remoteCursor) PutNoOverwrite(key []byte, value []byte) error { panic("not supported") } func (c *remoteCursor) PutCurrent(key, value []byte) error { panic("not supported") } func (c *remoteCursor) Append(key []byte, value []byte) error { panic("not supported") } -func (c *remoteCursor) Delete(key []byte) error { panic("not supported") } +func (c *remoteCursor) Delete(k, v []byte) error { panic("not supported") } func (c *remoteCursor) DeleteCurrent() error { panic("not supported") } func (c *remoteCursor) Count() (uint64, error) { panic("not supported") } func (c *remoteCursor) Reserve(k []byte, n int) ([]byte, error) { panic("not supported") } diff --git a/ethdb/kv_snapshot.go b/ethdb/kv_snapshot.go index 77cc03b24b32dcd99cc96e861ee4c32ec09121fe..9acc2dd6213f6738dbea1b94f9d674766b6df9b6 100644 --- a/ethdb/kv_snapshot.go +++ b/ethdb/kv_snapshot.go @@ -482,8 +482,8 @@ func (s *snapshotCursor) Put(key []byte, value []byte) error { return s.dbCursor.Put(key, value) } -func (s *snapshotCursor) Delete(key []byte) error { - return s.dbCursor.Delete(key) +func (s *snapshotCursor) Delete(k, v []byte) error { + return s.dbCursor.Delete(k, v) } func (s *snapshotCursor) Append(key []byte, value []byte) error { diff --git a/ethdb/mutation.go b/ethdb/mutation.go index 33f1c565317da00bca95242373f4f25ee2ecf595..f09ff2a814cca8c8724a7e05758dff9a8d9b8172 100644 --- a/ethdb/mutation.go +++ b/ethdb/mutation.go @@ -3,6 +3,7 @@ package ethdb import ( "bytes" "context" + "fmt" "strings" "sync" "sync/atomic" @@ -176,8 +177,12 @@ func (m *mutation) MultiWalk(table string, startkeys [][]byte, fixedbits []int, return m.db.MultiWalk(table, startkeys, fixedbits, walker) } -func (m *mutation) Delete(table string, key []byte) error { - return m.Put(table, key, nil) +func (m *mutation) Delete(table string, k, v []byte) error { + if v != nil { + return fmt.Errorf("mutation doesn't implement dupsort values deletion yet") + } + //m.puts.Delete(table, k) + return m.Put(table, k, nil) } func (m *mutation) CommitAndBegin(ctx context.Context) error { @@ -218,7 +223,7 @@ func (m *mutation) doCommit(tx Tx) error { } } } else if len(mi.value) == 0 { - if err := c.Delete(mi.key); err != nil { + if err := c.Delete(mi.key, nil); err != nil { innerErr = err return false } @@ -369,9 +374,9 @@ func (d *RWCounterDecorator) MultiWalk(bucket string, startkeys [][]byte, fixedb atomic.AddUint64(&d.DBCounterStats.MultiWalk, 1) return d.Database.MultiWalk(bucket, startkeys, fixedbits, walker) } -func (d *RWCounterDecorator) Delete(bucket string, key []byte) error { +func (d *RWCounterDecorator) Delete(bucket string, k, v []byte) error { atomic.AddUint64(&d.DBCounterStats.Delete, 1) - return d.Database.Delete(bucket, key) + return d.Database.Delete(bucket, k, v) } func (d *RWCounterDecorator) MultiPut(tuples ...[]byte) (uint64, error) { atomic.AddUint64(&d.DBCounterStats.MultiPut, 1) diff --git a/ethdb/object_db.go b/ethdb/object_db.go index 0961031319461ffcce738178ee65bb55214ef5c3..ff32552a28bc469d92bedd3939a3083d710b2ff6 100644 --- a/ethdb/object_db.go +++ b/ethdb/object_db.go @@ -226,10 +226,10 @@ func (db *ObjectDatabase) MultiWalk(bucket string, startkeys [][]byte, fixedbits } // Delete deletes the key from the queue and database -func (db *ObjectDatabase) Delete(bucket string, key []byte) error { +func (db *ObjectDatabase) Delete(bucket string, k, v []byte) error { // Execute the actual operation err := db.kv.Update(context.Background(), func(tx Tx) error { - return tx.Cursor(bucket).Delete(key) + return tx.Cursor(bucket).Delete(k, v) }) return err } diff --git a/ethdb/tx_db.go b/ethdb/tx_db.go index d12a77f8c4a71b9d41d5a1825ba4c12b2f850052..cc610c2e0f8c7f9d94332994a75cb1bb9657c630 100644 --- a/ethdb/tx_db.go +++ b/ethdb/tx_db.go @@ -75,9 +75,9 @@ func (m *TxDb) Append(bucket string, key []byte, value []byte) error { } } -func (m *TxDb) Delete(bucket string, key []byte) error { - m.len += uint64(len(key)) - return m.cursors[bucket].Delete(key) +func (m *TxDb) Delete(bucket string, k, v []byte) error { + m.len += uint64(len(k)) + return m.cursors[bucket].Delete(k, v) } func (m *TxDb) NewBatch() DbWithPendingMutations { @@ -195,7 +195,7 @@ func MultiPut(tx Tx, tuples ...[]byte) error { } } else { if v == nil { - if err := c.Delete(k); err != nil { + if err := c.Delete(k, nil); err != nil { return err } } else { diff --git a/migrations/migrations.go b/migrations/migrations.go index 49588a840f0c9a90d0eea762898dc16c1e173d0c..345e04fa9fe2b61a00687fa1707dd615089b1e7a 100644 --- a/migrations/migrations.go +++ b/migrations/migrations.go @@ -204,7 +204,7 @@ func (m *Migrator) Apply(db ethdb.Database, tmpdir string) error { return err } - err = tx.Delete(dbutils.Migrations, []byte("_progress_"+v.Name)) + err = tx.Delete(dbutils.Migrations, []byte("_progress_"+v.Name), nil) if err != nil { return err } diff --git a/p2p/enode/nodedb.go b/p2p/enode/nodedb.go index 63cf5e8a14a95552c7fc1223f7a01c51ec5920ad..23f3fe92110089074732f68840812a25c70b62ca 100644 --- a/p2p/enode/nodedb.go +++ b/p2p/enode/nodedb.go @@ -331,7 +331,7 @@ func deleteRange(db ethdb.KV, prefix []byte) { if err != nil { return err } - if err := c.Delete(k); err != nil { + if err := c.Delete(k, nil); err != nil { return nil } } diff --git a/turbo/trie/trie_root.go b/turbo/trie/trie_root.go index ab9b8f82b3032cf9690f70e935f45f7a9f618c03..47260ad30b3d610e5c462f6d9c0896a6ad4b73c1 100644 --- a/turbo/trie/trie_root.go +++ b/turbo/trie/trie_root.go @@ -774,11 +774,7 @@ func (c *IHCursor) _seek(seek []byte) (k, v []byte, err error) { return k, v, nil } - _, _, err = c.cForDelete.SeekBothExact(kCopy, vCopy) - if err != nil { - return []byte{}, nil, err - } - err = c.cForDelete.DeleteCurrent() + err = c.cForDelete.Delete(kCopy, vCopy) if err != nil { return []byte{}, nil, err } @@ -807,11 +803,7 @@ func (c *IHCursor) _next() (k, v []byte, err error) { return k, v, nil } - _, _, err = c.cForDelete.SeekBothExact(kCopy, vCopy) - if err != nil { - return []byte{}, nil, err - } - err = c.cForDelete.DeleteCurrent() + err = c.cForDelete.Delete(kCopy, vCopy) if err != nil { return []byte{}, nil, err }