diff --git a/core/state/snapshot/wipe.go b/core/state/snapshot/wipe.go index 2cab57393..b774c37a4 100644 --- a/core/state/snapshot/wipe.go +++ b/core/state/snapshot/wipe.go @@ -21,67 +21,11 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "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 // and having a specific total key length. The start and limit is optional for // specifying a particular key range for deletion. diff --git a/core/state/snapshot/wipe_test.go b/core/state/snapshot/wipe_test.go index 2c45652a9..c5b340136 100644 --- a/core/state/snapshot/wipe_test.go +++ b/core/state/snapshot/wipe_test.go @@ -30,95 +30,50 @@ import ( func TestWipe(t *testing.T) { // Create a database with some random snapshot data db := memorydb.New() - for i := 0; i < 128; i++ { - account := randomHash() - rawdb.WriteAccountSnapshot(db, account, randomHash().Bytes()) - for j := 0; j < 1024; j++ { - rawdb.WriteStorageSnapshot(db, account, randomHash(), randomHash().Bytes()) - } + rawdb.WriteAccountSnapshot(db, randomHash(), randomHash().Bytes()) } - rawdb.WriteSnapshotRoot(db, randomHash()) - // Add some random non-snapshot data too to make wiping harder - for i := 0; i < 65536; i++ { - // Generate a key that's the wrong length for a state snapshot item - var keysize int - 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) + for i := 0; i < 500; i++ { + // Generate keys with wrong length for a state snapshot item + keysuffix := make([]byte, 31) rand.Read(keysuffix) - - if rand.Int31n(2) == 0 { - db.Put(append(rawdb.SnapshotAccountPrefix, keysuffix...), randomHash().Bytes()) - } else { - db.Put(append(rawdb.SnapshotStoragePrefix, keysuffix...), randomHash().Bytes()) + db.Put(append(rawdb.SnapshotAccountPrefix, keysuffix...), randomHash().Bytes()) + keysuffix = make([]byte, 33) + rand.Read(keysuffix) + db.Put(append(rawdb.SnapshotAccountPrefix, 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 - var items int - - it := db.NewIterator(rawdb.SnapshotAccountPrefix, nil) - defer it.Release() - - for it.Next() { - key := it.Key() - if len(key) == len(rawdb.SnapshotAccountPrefix)+common.HashLength { - items++ - } + if items := count(); items != 128 { + t.Fatalf("snapshot size mismatch: have %d, want %d", items, 128) } - it = db.NewIterator(rawdb.SnapshotStoragePrefix, nil) - defer it.Release() - - for it.Next() { - key := it.Key() - if len(key) == len(rawdb.SnapshotStoragePrefix)+2*common.HashLength { - items++ - } + // Wipe the accounts + if err := wipeKeyRange(db, "accounts", rawdb.SnapshotAccountPrefix, nil, nil, + len(rawdb.SnapshotAccountPrefix)+common.HashLength, snapWipedAccountMeter, true); err != nil { + t.Fatal(err) } - 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 ", hash) - } - // Wipe all snapshot entries from the database - <-wipeSnapshot(db, true) - // Iterate over the database end ensure no snapshot information remains - it = db.NewIterator(rawdb.SnapshotAccountPrefix, nil) - defer it.Release() - - 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) + if items := count(); items != 0 { + t.Fatalf("snapshot size mismatch: have %d, want %d", items, 0) } // Iterate over the database and ensure miscellaneous items are present - items = 0 - - it = db.NewIterator(nil, nil) + items := 0 + it := db.NewIterator(nil, nil) defer it.Release() - for it.Next() { items++ } - if items != 65536 { - t.Fatalf("misc item count mismatch: have %d, want %d", items, 65536) + if items != 1000 { + t.Fatalf("misc item count mismatch: have %d, want %d", items, 1000) } } diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index a6c89d833..6659ec401 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -207,13 +207,6 @@ const ( LOG4 ) -// unofficial opcodes used for parsing. -const ( - PUSH OpCode = 0xb0 + iota - DUP - SWAP -) - // 0xf0 range - closures. const ( CREATE OpCode = 0xf0 @@ -391,10 +384,6 @@ var opCodeToString = map[OpCode]string{ STATICCALL: "STATICCALL", REVERT: "REVERT", SELFDESTRUCT: "SELFDESTRUCT", - - PUSH: "PUSH", - DUP: "DUP", - SWAP: "SWAP", } func (op OpCode) String() string {