forked from cerc-io/plugeth
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:
parent
ad7c90c198
commit
9055cc14ec
@ -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.
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user