core/vm, core/state/snapshot: remove unused code (#23956)

* core/state/snapshot: remove wiper functionality

* core/vm: remove unused 'unofficial' opcodes
This commit is contained in:
Martin Holst Swende 2021-11-25 09:37:47 +01:00 committed by GitHub
parent ad7c90c198
commit 9055cc14ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 141 deletions

View File

@ -21,67 +21,11 @@ import (
"time" "time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics"
) )
// wipeSnapshot starts a goroutine to iterate over the entire key-value database
// and delete all the data associated with the snapshot (accounts, storage,
// metadata). After all is done, the snapshot range of the database is compacted
// to free up unused data blocks.
func wipeSnapshot(db ethdb.KeyValueStore, full bool) chan struct{} {
// Wipe the snapshot root marker synchronously
if full {
rawdb.DeleteSnapshotRoot(db)
}
// Wipe everything else asynchronously
wiper := make(chan struct{}, 1)
go func() {
if err := wipeContent(db); err != nil {
log.Error("Failed to wipe state snapshot", "err", err) // Database close will trigger this
return
}
close(wiper)
}()
return wiper
}
// wipeContent iterates over the entire key-value database and deletes all the
// data associated with the snapshot (accounts, storage), but not the root hash
// as the wiper is meant to run on a background thread but the root needs to be
// removed in sync to avoid data races. After all is done, the snapshot range of
// the database is compacted to free up unused data blocks.
func wipeContent(db ethdb.KeyValueStore) error {
if err := wipeKeyRange(db, "accounts", rawdb.SnapshotAccountPrefix, nil, nil, len(rawdb.SnapshotAccountPrefix)+common.HashLength, snapWipedAccountMeter, true); err != nil {
return err
}
if err := wipeKeyRange(db, "storage", rawdb.SnapshotStoragePrefix, nil, nil, len(rawdb.SnapshotStoragePrefix)+2*common.HashLength, snapWipedStorageMeter, true); err != nil {
return err
}
// Compact the snapshot section of the database to get rid of unused space
start := time.Now()
log.Info("Compacting snapshot account area ")
end := common.CopyBytes(rawdb.SnapshotAccountPrefix)
end[len(end)-1]++
if err := db.Compact(rawdb.SnapshotAccountPrefix, end); err != nil {
return err
}
log.Info("Compacting snapshot storage area ")
end = common.CopyBytes(rawdb.SnapshotStoragePrefix)
end[len(end)-1]++
if err := db.Compact(rawdb.SnapshotStoragePrefix, end); err != nil {
return err
}
log.Info("Compacted snapshot area in database", "elapsed", common.PrettyDuration(time.Since(start)))
return nil
}
// wipeKeyRange deletes a range of keys from the database starting with prefix // wipeKeyRange deletes a range of keys from the database starting with prefix
// and having a specific total key length. The start and limit is optional for // and having a specific total key length. The start and limit is optional for
// specifying a particular key range for deletion. // specifying a particular key range for deletion.

View File

@ -30,95 +30,50 @@ import (
func TestWipe(t *testing.T) { func TestWipe(t *testing.T) {
// Create a database with some random snapshot data // Create a database with some random snapshot data
db := memorydb.New() db := memorydb.New()
for i := 0; i < 128; i++ { for i := 0; i < 128; i++ {
account := randomHash() rawdb.WriteAccountSnapshot(db, randomHash(), randomHash().Bytes())
rawdb.WriteAccountSnapshot(db, account, randomHash().Bytes())
for j := 0; j < 1024; j++ {
rawdb.WriteStorageSnapshot(db, account, randomHash(), randomHash().Bytes())
}
} }
rawdb.WriteSnapshotRoot(db, randomHash())
// Add some random non-snapshot data too to make wiping harder // Add some random non-snapshot data too to make wiping harder
for i := 0; i < 65536; i++ { for i := 0; i < 500; i++ {
// Generate a key that's the wrong length for a state snapshot item // Generate keys with wrong length for a state snapshot item
var keysize int keysuffix := make([]byte, 31)
for keysize == 0 || keysize == 32 || keysize == 64 {
keysize = 8 + rand.Intn(64) // +8 to ensure we will "never" randomize duplicates
}
// Randomize the suffix, dedup and inject it under the snapshot namespace
keysuffix := make([]byte, keysize)
rand.Read(keysuffix) rand.Read(keysuffix)
db.Put(append(rawdb.SnapshotAccountPrefix, keysuffix...), randomHash().Bytes())
if rand.Int31n(2) == 0 { keysuffix = make([]byte, 33)
db.Put(append(rawdb.SnapshotAccountPrefix, keysuffix...), randomHash().Bytes()) rand.Read(keysuffix)
} else { db.Put(append(rawdb.SnapshotAccountPrefix, keysuffix...), randomHash().Bytes())
db.Put(append(rawdb.SnapshotStoragePrefix, keysuffix...), randomHash().Bytes()) }
count := func() (items int) {
it := db.NewIterator(rawdb.SnapshotAccountPrefix, nil)
defer it.Release()
for it.Next() {
if len(it.Key()) == len(rawdb.SnapshotAccountPrefix)+common.HashLength {
items++
}
} }
return items
} }
// Sanity check that all the keys are present // Sanity check that all the keys are present
var items int if items := count(); items != 128 {
t.Fatalf("snapshot size mismatch: have %d, want %d", items, 128)
it := db.NewIterator(rawdb.SnapshotAccountPrefix, nil)
defer it.Release()
for it.Next() {
key := it.Key()
if len(key) == len(rawdb.SnapshotAccountPrefix)+common.HashLength {
items++
}
} }
it = db.NewIterator(rawdb.SnapshotStoragePrefix, nil) // Wipe the accounts
defer it.Release() if err := wipeKeyRange(db, "accounts", rawdb.SnapshotAccountPrefix, nil, nil,
len(rawdb.SnapshotAccountPrefix)+common.HashLength, snapWipedAccountMeter, true); err != nil {
for it.Next() { t.Fatal(err)
key := it.Key()
if len(key) == len(rawdb.SnapshotStoragePrefix)+2*common.HashLength {
items++
}
} }
if items != 128+128*1024 {
t.Fatalf("snapshot size mismatch: have %d, want %d", items, 128+128*1024)
}
if hash := rawdb.ReadSnapshotRoot(db); hash == (common.Hash{}) {
t.Errorf("snapshot block marker mismatch: have %#x, want <not-nil>", hash)
}
// Wipe all snapshot entries from the database
<-wipeSnapshot(db, true)
// Iterate over the database end ensure no snapshot information remains // Iterate over the database end ensure no snapshot information remains
it = db.NewIterator(rawdb.SnapshotAccountPrefix, nil) if items := count(); items != 0 {
defer it.Release() t.Fatalf("snapshot size mismatch: have %d, want %d", items, 0)
for it.Next() {
key := it.Key()
if len(key) == len(rawdb.SnapshotAccountPrefix)+common.HashLength {
t.Errorf("snapshot entry remained after wipe: %x", key)
}
}
it = db.NewIterator(rawdb.SnapshotStoragePrefix, nil)
defer it.Release()
for it.Next() {
key := it.Key()
if len(key) == len(rawdb.SnapshotStoragePrefix)+2*common.HashLength {
t.Errorf("snapshot entry remained after wipe: %x", key)
}
}
if hash := rawdb.ReadSnapshotRoot(db); hash != (common.Hash{}) {
t.Errorf("snapshot block marker remained after wipe: %#x", hash)
} }
// Iterate over the database and ensure miscellaneous items are present // Iterate over the database and ensure miscellaneous items are present
items = 0 items := 0
it := db.NewIterator(nil, nil)
it = db.NewIterator(nil, nil)
defer it.Release() defer it.Release()
for it.Next() { for it.Next() {
items++ items++
} }
if items != 65536 { if items != 1000 {
t.Fatalf("misc item count mismatch: have %d, want %d", items, 65536) t.Fatalf("misc item count mismatch: have %d, want %d", items, 1000)
} }
} }

View File

@ -207,13 +207,6 @@ const (
LOG4 LOG4
) )
// unofficial opcodes used for parsing.
const (
PUSH OpCode = 0xb0 + iota
DUP
SWAP
)
// 0xf0 range - closures. // 0xf0 range - closures.
const ( const (
CREATE OpCode = 0xf0 CREATE OpCode = 0xf0
@ -391,10 +384,6 @@ var opCodeToString = map[OpCode]string{
STATICCALL: "STATICCALL", STATICCALL: "STATICCALL",
REVERT: "REVERT", REVERT: "REVERT",
SELFDESTRUCT: "SELFDESTRUCT", SELFDESTRUCT: "SELFDESTRUCT",
PUSH: "PUSH",
DUP: "DUP",
SWAP: "SWAP",
} }
func (op OpCode) String() string { func (op OpCode) String() string {