swarm: Debug API and HasChunks() API endpoint (#18980)
This commit is contained in:
committed by
Anton Evangelatov
parent
33d0a0efa6
commit
41597c2856
@ -267,6 +267,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() {
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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!")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
}
|
||||
|
Reference in New Issue
Block a user