feat: use ethdb to store data

part1: impl simple get and put method
This commit is contained in:
fearlseefe 2024-11-20 16:39:57 +08:00 committed by Chen Kai
parent b1ae92d3cf
commit cb91f65056
3 changed files with 156 additions and 0 deletions

View file

@ -12,6 +12,9 @@ var MaxDistance = uint256.MustFromHex("0xfffffffffffffffffffffffffffffffffffffff
type ContentType byte
var RadisuKey = []byte("radius")
var SizeKey = []byte("size")
type ContentKey struct {
selector ContentType
data []byte

View file

@ -0,0 +1,79 @@
package ethpepple
import (
"sync/atomic"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb/pebble"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/portalnetwork/storage"
"github.com/holiman/uint256"
)
var _ storage.ContentStorage = &ContentStorage{}
type PeppleStorageConfig struct {
StorageCapacityMB uint64
DB ethdb.KeyValueStore
NodeId enode.ID
NetworkName string
}
func NewPeppleDB(dataDir string, cache, handles int, namespace string) (ethdb.KeyValueStore, error) {
db, err := pebble.New(dataDir + "/" + namespace, cache, handles, namespace, false)
return db, err
}
type ContentStorage struct {
nodeId enode.ID
storageCapacityInBytes uint64
radius atomic.Value
// size uint64
log log.Logger
db ethdb.KeyValueStore
}
func NewPeppleStorage(config PeppleStorageConfig) (storage.ContentStorage, error) {
cs := &ContentStorage{
nodeId: config.NodeId,
db: config.DB,
storageCapacityInBytes: config.StorageCapacityMB * 1000_000,
log: log.New("storage", config.NetworkName),
}
cs.radius.Store(storage.MaxDistance)
exist, err := cs.db.Has(storage.RadisuKey);
if err != nil {
return nil, err
}
if exist {
radius, err := cs.db.Get(storage.RadisuKey)
if err != nil {
return nil, err
}
dis := uint256.NewInt(0)
err = dis.UnmarshalSSZ(radius)
if err != nil {
return nil, err
}
cs.radius.Store(dis)
}
return cs, nil
}
// Get implements storage.ContentStorage.
func (c *ContentStorage) Get(contentKey []byte, contentId []byte) ([]byte, error) {
return c.db.Get(contentId)
}
// Put implements storage.ContentStorage.
func (c *ContentStorage) Put(contentKey []byte, contentId []byte, content []byte) error {
return c.db.Put(contentId, content)
}
// Radius implements storage.ContentStorage.
func (p *ContentStorage) Radius() *uint256.Int {
radius := p.radius.Load()
val := radius.(*uint256.Int)
return val
}

View file

@ -0,0 +1,74 @@
package ethpepple
import (
"os"
"testing"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/portalnetwork/storage"
"github.com/holiman/uint256"
"github.com/stretchr/testify/assert"
)
const dataDir = "./node1"
var testRadius = uint256.NewInt(100000)
func clearNodeData() {
_ = os.RemoveAll(dataDir)
}
func getTestDb() (storage.ContentStorage, error) {
db, err := NewPeppleDB(dataDir, 100, 100, "history")
if err != nil {
return nil, err
}
config := PeppleStorageConfig{
DB: db,
StorageCapacityMB: 100,
NodeId: enode.ID{},
NetworkName: "history",
}
return NewPeppleStorage(config)
}
func TestReadRadius(t *testing.T) {
db, err := getTestDb()
assert.NoError(t, err)
defer clearNodeData()
assert.True(t, db.Radius().Eq(storage.MaxDistance))
data, err := testRadius.MarshalSSZ()
assert.NoError(t, err)
db.Put(nil, storage.RadisuKey, data)
store := db.(*ContentStorage)
err = store.db.Close()
assert.NoError(t, err)
db, err = getTestDb()
assert.NoError(t, err)
assert.True(t, db.Radius().Eq(testRadius))
}
func TestStorage(t *testing.T) {
db, err := getTestDb()
assert.NoError(t, err)
defer clearNodeData()
testcases := map[string][]byte{
"test1": []byte("test1"),
"test2": []byte("test2"),
"test3": []byte("test3"),
"test4": []byte("test4"),
}
for key, value := range testcases {
db.Put(nil, []byte(key), value)
}
for key, value := range testcases {
val, err := db.Get(nil, []byte(key))
assert.NoError(t, err)
assert.Equal(t, value, val)
}
}