package ethdb import ( "bytes" "context" "github.com/ledgerwatch/turbo-geth/common" "github.com/ledgerwatch/turbo-geth/common/dbutils" "testing" ) func TestSnapshotGet(t *testing.T) { sn1 := NewLMDB().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg { return dbutils.BucketsCfg{ dbutils.HeaderPrefix: dbutils.BucketConfigItem{}, } }).InMem().MustOpen() err := sn1.Update(context.Background(), func(tx Tx) error { bucket := tx.Cursor(dbutils.HeaderPrefix) innerErr := bucket.Put(dbutils.HeaderKey(1, common.Hash{1}), []byte{1}) if innerErr != nil { return innerErr } innerErr = bucket.Put(dbutils.HeaderKey(2, common.Hash{2}), []byte{2}) if innerErr != nil { return innerErr } return nil }) if err != nil { t.Fatal(err) } sn2 := NewLMDB().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg { return dbutils.BucketsCfg{ dbutils.BlockBodyPrefix: dbutils.BucketConfigItem{}, } }).InMem().MustOpen() err = sn2.Update(context.Background(), func(tx Tx) error { bucket := tx.Cursor(dbutils.BlockBodyPrefix) innerErr := bucket.Put(dbutils.BlockBodyKey(1, common.Hash{1}), []byte{1}) if innerErr != nil { return innerErr } innerErr = bucket.Put(dbutils.BlockBodyKey(2, common.Hash{2}), []byte{2}) if innerErr != nil { return innerErr } return nil }) if err != nil { t.Fatal(err) } mainDB := NewLMDB().InMem().MustOpen() err = mainDB.Update(context.Background(), func(tx Tx) error { bucket := tx.Cursor(dbutils.HeaderPrefix) innerErr := bucket.Put(dbutils.HeaderKey(2, common.Hash{2}), []byte{22}) if innerErr != nil { return innerErr } innerErr = bucket.Put(dbutils.HeaderKey(3, common.Hash{3}), []byte{33}) if innerErr != nil { return innerErr } bucket = tx.Cursor(dbutils.BlockBodyPrefix) innerErr = bucket.Put(dbutils.BlockBodyKey(2, common.Hash{2}), []byte{22}) if innerErr != nil { return innerErr } innerErr = bucket.Put(dbutils.BlockBodyKey(3, common.Hash{3}), []byte{33}) if innerErr != nil { return innerErr } return nil }) if err != nil { t.Fatal(err) } kv := NewSnapshotKV().For(dbutils.HeaderPrefix).SnapshotDB(sn1).DB(mainDB).MustOpen() kv = NewSnapshotKV().For(dbutils.BlockBodyPrefix).SnapshotDB(sn2).DB(kv).MustOpen() tx, err := kv.Begin(context.Background(), nil, false) if err != nil { t.Fatal(err) } v, err := tx.Get(dbutils.HeaderPrefix, dbutils.HeaderKey(1, common.Hash{1})) if err != nil { t.Fatal(err) } if !bytes.Equal(v, []byte{1}) { t.Fatal(v) } v, err = tx.Get(dbutils.HeaderPrefix, dbutils.HeaderKey(2, common.Hash{2})) if err != nil { t.Fatal(err) } if !bytes.Equal(v, []byte{22}) { t.Fatal(v) } v, err = tx.Get(dbutils.HeaderPrefix, dbutils.HeaderKey(3, common.Hash{3})) if err != nil { t.Fatal(err) } if !bytes.Equal(v, []byte{33}) { t.Fatal(v) } v, err = tx.Get(dbutils.BlockBodyPrefix, dbutils.BlockBodyKey(1, common.Hash{1})) if err != nil { t.Fatal(err) } if !bytes.Equal(v, []byte{1}) { t.Fatal(v) } v, err = tx.Get(dbutils.BlockBodyPrefix, dbutils.BlockBodyKey(2, common.Hash{2})) if err != nil { t.Fatal(err) } if !bytes.Equal(v, []byte{22}) { t.Fatal(v) } v, err = tx.Get(dbutils.BlockBodyPrefix, dbutils.BlockBodyKey(3, common.Hash{3})) if err != nil { t.Fatal(err) } if !bytes.Equal(v, []byte{33}) { t.Fatal(v) } headerCursor := tx.Cursor(dbutils.HeaderPrefix) k, v, err := headerCursor.Last() if err != nil { t.Fatal(err) } if !(bytes.Equal(dbutils.HeaderKey(3, common.Hash{3}), k) && bytes.Equal(v, []byte{33})) { t.Fatal(k, v) } k, v, err = headerCursor.First() if err != nil { t.Fatal(err) } if !(bytes.Equal(dbutils.HeaderKey(1, common.Hash{1}), k) && bytes.Equal(v, []byte{1})) { t.Fatal(k, v) } k, v, err = headerCursor.Next() if err != nil { t.Fatal(err) } if !(bytes.Equal(dbutils.HeaderKey(2, common.Hash{2}), k) && bytes.Equal(v, []byte{22})) { t.Fatal(k, v) } k, v, err = headerCursor.Next() if err != nil { t.Fatal(err) } if !(bytes.Equal(dbutils.HeaderKey(3, common.Hash{3}), k) && bytes.Equal(v, []byte{33})) { t.Fatal(k, v) } k, v, err = headerCursor.Next() if err != nil { t.Fatal(err) } if !(bytes.Equal([]byte{}, k) && bytes.Equal(v, []byte{})) { t.Fatal(k, v) } } func TestSnapshotWritableTxAndGet(t *testing.T) { sn1 := NewLMDB().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg { return dbutils.BucketsCfg{ dbutils.HeaderPrefix: dbutils.BucketConfigItem{}, } }).InMem().MustOpen() err := sn1.Update(context.Background(), func(tx Tx) error { bucket := tx.Cursor(dbutils.HeaderPrefix) innerErr := bucket.Put(dbutils.HeaderKey(1, common.Hash{1}), []byte{1}) if innerErr != nil { return innerErr } innerErr = bucket.Put(dbutils.HeaderKey(2, common.Hash{2}), []byte{2}) if innerErr != nil { return innerErr } return nil }) if err != nil { t.Fatal(err) } sn2 := NewLMDB().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg { return dbutils.BucketsCfg{ dbutils.BlockBodyPrefix: dbutils.BucketConfigItem{}, } }).InMem().MustOpen() err = sn2.Update(context.Background(), func(tx Tx) error { bucket := tx.Cursor(dbutils.BlockBodyPrefix) innerErr := bucket.Put(dbutils.BlockBodyKey(1, common.Hash{1}), []byte{1}) if innerErr != nil { return innerErr } innerErr = bucket.Put(dbutils.BlockBodyKey(2, common.Hash{2}), []byte{2}) if innerErr != nil { return innerErr } return nil }) if err != nil { t.Fatal(err) } mainDB := NewLMDB().InMem().MustOpen() kv := NewSnapshotKV().For(dbutils.HeaderPrefix).SnapshotDB(sn1).DB(mainDB).MustOpen() kv = NewSnapshotKV().For(dbutils.BlockBodyPrefix).SnapshotDB(sn2).DB(kv).MustOpen() tx, err := kv.Begin(context.Background(), nil, true) if err != nil { t.Fatal(err) } v, err := tx.Get(dbutils.HeaderPrefix, dbutils.HeaderKey(1, common.Hash{1})) if err != nil { t.Fatal(err) } if !bytes.Equal(v, []byte{1}) { t.Fatal(v) } v, err = tx.Get(dbutils.BlockBodyPrefix, dbutils.BlockBodyKey(1, common.Hash{1})) if err != nil { t.Fatal(err) } if !bytes.Equal(v, []byte{1}) { t.Fatal(v) } err = tx.Cursor(dbutils.BlockBodyPrefix).Put(dbutils.BlockBodyKey(4, common.Hash{4}), []byte{2}) if err != nil { t.Fatal(err) } err = tx.Cursor(dbutils.HeaderPrefix).Put(dbutils.HeaderKey(4, common.Hash{4}), []byte{2}) if err != nil { t.Fatal(err) } err = tx.Commit(context.Background()) if err != nil { t.Fatal(err) } tx, err = kv.Begin(context.Background(), nil, false) if err != nil { t.Fatal(err) } c := tx.Cursor(dbutils.HeaderPrefix) t.Log(c.First()) t.Log(c.Next()) t.Log(c.Next()) t.Log(c.Next()) t.Log(c.Next()) t.Log(c.Next()) }