swarm: add database abstractions (shed package) (#18183)
This commit is contained in:
committed by
Anton Evangelatov
parent
4f0d978eaa
commit
c207edf2a3
@ -86,6 +86,13 @@ func (s *GlobalStore) Put(addr common.Address, key []byte, data []byte) error {
|
||||
return s.db.Write(batch, nil)
|
||||
}
|
||||
|
||||
// Delete removes the chunk reference to node with address addr.
|
||||
func (s *GlobalStore) Delete(addr common.Address, key []byte) error {
|
||||
batch := new(leveldb.Batch)
|
||||
batch.Delete(nodeDBKey(addr, key))
|
||||
return s.db.Write(batch, nil)
|
||||
}
|
||||
|
||||
// HasKey returns whether a node with addr contains the key.
|
||||
func (s *GlobalStore) HasKey(addr common.Address, key []byte) bool {
|
||||
has, err := s.db.Has(nodeDBKey(addr, key), nil)
|
||||
|
@ -83,6 +83,22 @@ func (s *GlobalStore) Put(addr common.Address, key []byte, data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete removes the chunk data for node with address addr.
|
||||
func (s *GlobalStore) Delete(addr common.Address, key []byte) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
var count int
|
||||
if _, ok := s.nodes[string(key)]; ok {
|
||||
delete(s.nodes[string(key)], addr)
|
||||
count = len(s.nodes[string(key)])
|
||||
}
|
||||
if count == 0 {
|
||||
delete(s.data, string(key))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasKey returns whether a node with addr contains the key.
|
||||
func (s *GlobalStore) HasKey(addr common.Address, key []byte) bool {
|
||||
s.mu.Lock()
|
||||
|
@ -70,6 +70,12 @@ func (n *NodeStore) Put(key []byte, data []byte) error {
|
||||
return n.store.Put(n.addr, key, data)
|
||||
}
|
||||
|
||||
// Delete removes chunk data for a key for a node that has the address
|
||||
// provided on NodeStore initialization.
|
||||
func (n *NodeStore) Delete(key []byte) error {
|
||||
return n.store.Delete(n.addr, key)
|
||||
}
|
||||
|
||||
// GlobalStorer defines methods for mock db store
|
||||
// that stores chunk data for all swarm nodes.
|
||||
// It is used in tests to construct mock NodeStores
|
||||
@ -77,6 +83,7 @@ func (n *NodeStore) Put(key []byte, data []byte) error {
|
||||
type GlobalStorer interface {
|
||||
Get(addr common.Address, key []byte) (data []byte, err error)
|
||||
Put(addr common.Address, key []byte, data []byte) error
|
||||
Delete(addr common.Address, key []byte) error
|
||||
HasKey(addr common.Address, key []byte) bool
|
||||
// NewNodeStore creates an instance of NodeStore
|
||||
// to be used by a single swarm node with
|
||||
|
@ -73,6 +73,12 @@ func (s *GlobalStore) Put(addr common.Address, key []byte, data []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete calls a Delete method to RPC server.
|
||||
func (s *GlobalStore) Delete(addr common.Address, key []byte) error {
|
||||
err := s.client.Call(nil, "mockStore_delete", addr, key)
|
||||
return err
|
||||
}
|
||||
|
||||
// HasKey calls a HasKey method to RPC server.
|
||||
func (s *GlobalStore) HasKey(addr common.Address, key []byte) bool {
|
||||
var has bool
|
||||
|
@ -72,6 +72,31 @@ func MockStore(t *testing.T, globalStore mock.GlobalStorer, n int) {
|
||||
}
|
||||
}
|
||||
}
|
||||
t.Run("delete", func(t *testing.T) {
|
||||
chunkAddr := storage.Address([]byte("1234567890abcd"))
|
||||
for _, addr := range addrs {
|
||||
err := globalStore.Put(addr, chunkAddr, []byte("data"))
|
||||
if err != nil {
|
||||
t.Fatalf("put data to store %s key %s: %v", addr.Hex(), chunkAddr.Hex(), err)
|
||||
}
|
||||
}
|
||||
firstNodeAddr := addrs[0]
|
||||
if err := globalStore.Delete(firstNodeAddr, chunkAddr); err != nil {
|
||||
t.Fatalf("delete from store %s key %s: %v", firstNodeAddr.Hex(), chunkAddr.Hex(), err)
|
||||
}
|
||||
for i, addr := range addrs {
|
||||
_, err := globalStore.Get(addr, chunkAddr)
|
||||
if i == 0 {
|
||||
if err != mock.ErrNotFound {
|
||||
t.Errorf("get data from store %s key %s: expected mock.ErrNotFound error, got %v", addr.Hex(), chunkAddr.Hex(), err)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("get data from store %s key %s: %v", addr.Hex(), chunkAddr.Hex(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("NodeStore", func(t *testing.T) {
|
||||
@ -114,6 +139,34 @@ func MockStore(t *testing.T, globalStore mock.GlobalStorer, n int) {
|
||||
}
|
||||
}
|
||||
}
|
||||
t.Run("delete", func(t *testing.T) {
|
||||
chunkAddr := storage.Address([]byte("1234567890abcd"))
|
||||
var chosenStore *mock.NodeStore
|
||||
for addr, store := range nodes {
|
||||
if chosenStore == nil {
|
||||
chosenStore = store
|
||||
}
|
||||
err := store.Put(chunkAddr, []byte("data"))
|
||||
if err != nil {
|
||||
t.Fatalf("put data to store %s key %s: %v", addr.Hex(), chunkAddr.Hex(), err)
|
||||
}
|
||||
}
|
||||
if err := chosenStore.Delete(chunkAddr); err != nil {
|
||||
t.Fatalf("delete key %s: %v", chunkAddr.Hex(), err)
|
||||
}
|
||||
for addr, store := range nodes {
|
||||
_, err := store.Get(chunkAddr)
|
||||
if store == chosenStore {
|
||||
if err != mock.ErrNotFound {
|
||||
t.Errorf("get data from store %s key %s: expected mock.ErrNotFound error, got %v", addr.Hex(), chunkAddr.Hex(), err)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("get data from store %s key %s: %v", addr.Hex(), chunkAddr.Hex(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user