aboutsummaryrefslogtreecommitdiffstats
path: root/swarm/storage
diff options
context:
space:
mode:
authorholisticode <holistic.computing@gmail.com>2019-02-07 22:49:19 +0800
committerRafael Matias <rafael@skyle.net>2019-02-19 20:06:13 +0800
commitd1ace4f344616fb6fa8643872c1f9cac89f8549e (patch)
tree807c6d7af3875e3aedc5fe6b24c463205cffab19 /swarm/storage
parent637a75d61a13ee8a89a702a2eadb5ace3c79e7da (diff)
downloaddexon-d1ace4f344616fb6fa8643872c1f9cac89f8549e.tar.gz
dexon-d1ace4f344616fb6fa8643872c1f9cac89f8549e.tar.zst
dexon-d1ace4f344616fb6fa8643872c1f9cac89f8549e.zip
swarm: Debug API and HasChunks() API endpoint (#18980)
(cherry picked from commit 41597c2856d6ac7328baca1340c3e36ab0edd382)
Diffstat (limited to 'swarm/storage')
-rw-r--r--swarm/storage/common_test.go9
-rw-r--r--swarm/storage/ldbstore.go12
-rw-r--r--swarm/storage/localstore.go7
-rw-r--r--swarm/storage/localstore_test.go33
-rw-r--r--swarm/storage/memstore.go5
-rw-r--r--swarm/storage/netstore.go7
-rw-r--r--swarm/storage/types.go8
7 files changed, 80 insertions, 1 deletions
diff --git a/swarm/storage/common_test.go b/swarm/storage/common_test.go
index bcc29d8cc..8ad95bfbc 100644
--- a/swarm/storage/common_test.go
+++ b/swarm/storage/common_test.go
@@ -266,6 +266,15 @@ func (m *MapChunkStore) Get(_ context.Context, ref Address) (Chunk, error) {
return chunk, nil
}
+// Need to implement Has from SyncChunkStore
+func (m *MapChunkStore) Has(ctx context.Context, ref Address) bool {
+ m.mu.RLock()
+ defer m.mu.RUnlock()
+
+ _, has := m.chunks[ref.Hex()]
+ return has
+}
+
func (m *MapChunkStore) Close() {
}
diff --git a/swarm/storage/ldbstore.go b/swarm/storage/ldbstore.go
index 635d33429..a2f24eff0 100644
--- a/swarm/storage/ldbstore.go
+++ b/swarm/storage/ldbstore.go
@@ -969,6 +969,18 @@ func (s *LDBStore) Get(_ context.Context, addr Address) (chunk Chunk, err error)
return s.get(addr)
}
+// Has queries the underlying DB if a chunk with the given address is stored
+// Returns true if the chunk is found, false if not
+func (s *LDBStore) Has(_ context.Context, addr Address) bool {
+ s.lock.RLock()
+ defer s.lock.RUnlock()
+
+ ikey := getIndexKey(addr)
+ _, err := s.db.Get(ikey)
+
+ return err == nil
+}
+
// TODO: To conform with other private methods of this object indices should not be updated
func (s *LDBStore) get(addr Address) (chunk *chunk, err error) {
if s.closed {
diff --git a/swarm/storage/localstore.go b/swarm/storage/localstore.go
index 956560902..eefb7565a 100644
--- a/swarm/storage/localstore.go
+++ b/swarm/storage/localstore.go
@@ -132,6 +132,13 @@ func (ls *LocalStore) Put(ctx context.Context, chunk Chunk) error {
return err
}
+// Has queries the underlying DbStore if a chunk with the given address
+// is being stored there.
+// Returns true if it is stored, false if not
+func (ls *LocalStore) Has(ctx context.Context, addr Address) bool {
+ return ls.DbStore.Has(ctx, addr)
+}
+
// Get(chunk *Chunk) looks up a chunk in the local stores
// This method is blocking until the chunk is retrieved
// so additional timeout may be needed to wrap this call if
diff --git a/swarm/storage/localstore_test.go b/swarm/storage/localstore_test.go
index 7a4162a47..ec69951c4 100644
--- a/swarm/storage/localstore_test.go
+++ b/swarm/storage/localstore_test.go
@@ -209,3 +209,36 @@ func setupLocalStore(t *testing.T, ldbCap int) (ls *LocalStore, cleanup func())
return store, cleanup
}
+
+func TestHas(t *testing.T) {
+ ldbCap := defaultGCRatio
+ store, cleanup := setupLocalStore(t, ldbCap)
+ defer cleanup()
+
+ nonStoredAddr := GenerateRandomChunk(128).Address()
+
+ has := store.Has(context.Background(), nonStoredAddr)
+ if has {
+ t.Fatal("Expected Has() to return false, but returned true!")
+ }
+
+ storeChunks := GenerateRandomChunks(128, 3)
+ for _, ch := range storeChunks {
+ err := store.Put(context.Background(), ch)
+ if err != nil {
+ t.Fatalf("Expected store to store chunk, but it failed: %v", err)
+ }
+
+ has := store.Has(context.Background(), ch.Address())
+ if !has {
+ t.Fatal("Expected Has() to return true, but returned false!")
+ }
+ }
+
+ //let's be paranoic and test again that the non-existent chunk returns false
+ has = store.Has(context.Background(), nonStoredAddr)
+ if has {
+ t.Fatal("Expected Has() to return false, but returned true!")
+ }
+
+}
diff --git a/swarm/storage/memstore.go b/swarm/storage/memstore.go
index 86e5813d1..611ac3bc5 100644
--- a/swarm/storage/memstore.go
+++ b/swarm/storage/memstore.go
@@ -48,6 +48,11 @@ func NewMemStore(params *StoreParams, _ *LDBStore) (m *MemStore) {
}
}
+// Has needed to implement SyncChunkStore
+func (m *MemStore) Has(_ context.Context, addr Address) bool {
+ return m.cache.Contains(addr)
+}
+
func (m *MemStore) Get(_ context.Context, addr Address) (Chunk, error) {
if m.disabled {
return nil, ErrChunkNotFound
diff --git a/swarm/storage/netstore.go b/swarm/storage/netstore.go
index 16bc48a9a..b24d08bc2 100644
--- a/swarm/storage/netstore.go
+++ b/swarm/storage/netstore.go
@@ -158,6 +158,13 @@ func (n *NetStore) get(ctx context.Context, ref Address) (Chunk, func(context.Co
return chunk, nil, nil
}
+// Has is the storage layer entry point to query the underlying
+// database to return if it has a chunk or not.
+// Called from the DebugAPI
+func (n *NetStore) Has(ctx context.Context, ref Address) bool {
+ return n.store.Has(ctx, ref)
+}
+
// getOrCreateFetcher attempts at retrieving an existing fetchers
// if none exists, creates one and saves it in the fetchers cache
// caller must hold the lock
diff --git a/swarm/storage/types.go b/swarm/storage/types.go
index d79235225..7ec21328e 100644
--- a/swarm/storage/types.go
+++ b/swarm/storage/types.go
@@ -292,6 +292,7 @@ func (v *ContentAddressValidator) Validate(chunk Chunk) bool {
type ChunkStore interface {
Put(ctx context.Context, ch Chunk) (err error)
Get(rctx context.Context, ref Address) (ch Chunk, err error)
+ Has(rctx context.Context, ref Address) bool
Close()
}
@@ -314,7 +315,12 @@ func (f *FakeChunkStore) Put(_ context.Context, ch Chunk) error {
return nil
}
-// Gut doesn't store anything it is just here to implement ChunkStore
+// Has doesn't do anything it is just here to implement ChunkStore
+func (f *FakeChunkStore) Has(_ context.Context, ref Address) bool {
+ panic("FakeChunkStore doesn't support HasChunk")
+}
+
+// Get doesn't store anything it is just here to implement ChunkStore
func (f *FakeChunkStore) Get(_ context.Context, ref Address) (Chunk, error) {
panic("FakeChunkStore doesn't support Get")
}