Skip to content

Commit

Permalink
Restrict ClearPrefix by key size (ava-labs#265)
Browse files Browse the repository at this point in the history
  • Loading branch information
darioush authored Jun 20, 2023
1 parent 0d02ea7 commit c08a7c1
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
9 changes: 4 additions & 5 deletions core/rawdb/accessors_state_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,12 @@ func ClearSyncSegments(db ethdb.KeyValueStore, root common.Hash) error {
segmentsPrefix := make([]byte, len(syncSegmentsPrefix)+common.HashLength)
copy(segmentsPrefix, syncSegmentsPrefix)
copy(segmentsPrefix[len(syncSegmentsPrefix):], root[:])

return ClearPrefix(db, segmentsPrefix)
return ClearPrefix(db, segmentsPrefix, syncSegmentsKeyLength)
}

// ClearAllSyncSegments removes all segment markers from db
func ClearAllSyncSegments(db ethdb.KeyValueStore) error {
return ClearPrefix(db, syncSegmentsPrefix)
return ClearPrefix(db, syncSegmentsPrefix, syncSegmentsKeyLength)
}

// UnpackSyncSegmentKey returns the root and start position for a trie segment
Expand Down Expand Up @@ -131,12 +130,12 @@ func ClearSyncStorageTrie(db ethdb.KeyValueStore, root common.Hash) error {
accountsPrefix := make([]byte, len(syncStorageTriesPrefix)+common.HashLength)
copy(accountsPrefix, syncStorageTriesPrefix)
copy(accountsPrefix[len(syncStorageTriesPrefix):], root[:])
return ClearPrefix(db, accountsPrefix)
return ClearPrefix(db, accountsPrefix, syncStorageTriesKeyLength)
}

// ClearAllSyncStorageTries removes all storage tries added for syncing from db
func ClearAllSyncStorageTries(db ethdb.KeyValueStore) error {
return ClearPrefix(db, syncStorageTriesPrefix)
return ClearPrefix(db, syncStorageTriesPrefix, syncStorageTriesKeyLength)
}

// UnpackSyncStorageTrieKey returns the root and account for a storage trie
Expand Down
33 changes: 33 additions & 0 deletions core/rawdb/accessors_state_sync_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// (c) 2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package rawdb

import (
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)

func TestClearPrefix(t *testing.T) {
require := require.New(t)
db := NewMemoryDatabase()
// add a key that should be cleared
require.NoError(WriteSyncSegment(db, common.Hash{1}, common.Hash{}.Bytes()))

// add a key that should not be cleared
key := append(syncSegmentsPrefix, []byte("foo")...)
require.NoError(db.Put(key, []byte("bar")))

require.NoError(ClearAllSyncSegments(db))

count := 0
it := db.NewIterator(syncSegmentsPrefix, nil)
defer it.Release()
for it.Next() {
count++
}
require.NoError(it.Error())
require.Equal(1, count)
}
9 changes: 7 additions & 2 deletions core/rawdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,14 +324,19 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
return nil
}

// ClearPrefix removes all keys in db that begin with prefix
func ClearPrefix(db ethdb.KeyValueStore, prefix []byte) error {
// ClearPrefix removes all keys in db that begin with prefix and match an
// expected key length. [keyLen] should include the length of the prefix.
func ClearPrefix(db ethdb.KeyValueStore, prefix []byte, keyLen int) error {
it := db.NewIterator(prefix, nil)
defer it.Release()

batch := db.NewBatch()
for it.Next() {
key := common.CopyBytes(it.Key())
if len(key) != keyLen {
// avoid deleting keys that do not match the expected length
continue
}
if err := batch.Delete(key); err != nil {
return err
}
Expand Down

0 comments on commit c08a7c1

Please sign in to comment.