Skip to content

Commit

Permalink
fix: new neighborhood type and cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
istae committed Oct 9, 2024
1 parent 3368d11 commit ff472fa
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 45 deletions.
11 changes: 9 additions & 2 deletions openapi/SwarmCommon.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -936,11 +936,18 @@ components:
StatusNeighborhoodResponse:
type: object
properties:
address:
type: string
neighborhood:
$ref: "#/components/schemas/Neighborhood"
reserveSizeWithinRadius:
type: integer
proximity:
type: integer

Neighborhood:
type: string
description: Swarm address of a neighborhood in string binary format showing, usually limited to as many bits as the current storage radius.
example: "011010111"

StatusNeighborhoodsResponse:
type: object
properties:
Expand Down
1 change: 1 addition & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ type Storer interface {
storer.LocalStore
storer.RadiusChecker
storer.Debugger
storer.NeighborhoodStats
}

type PinIntegrity interface {
Expand Down
20 changes: 6 additions & 14 deletions pkg/api/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package api

import (
"context"
"fmt"
"net/http"
"sort"
"sync"
Expand Down Expand Up @@ -38,8 +37,9 @@ type statusResponse struct {
}

type statusNeighborhoodResponse struct {
Address string `json:"address"`
Neighborhood string `json:"neighborhood"`
ReserveSizeWithinRadius int `json:"reserveSizeWithinRadius"`
Proximity uint8 `json:"proximity"`
}

type neighborhoodsResponse struct {
Expand Down Expand Up @@ -171,7 +171,7 @@ func (s *Service) statusGetPeersHandler(w http.ResponseWriter, r *http.Request)
}

// statusGetHandler returns the current node status.
func (s *Service) statusGetNeighborhoods(w http.ResponseWriter, _ *http.Request) {
func (s *Service) statusGetNeighborhoods(w http.ResponseWriter, r *http.Request) {
logger := s.logger.WithName("get_status_neighborhoods").Build()

if s.beeMode == DevMode {
Expand All @@ -182,27 +182,19 @@ func (s *Service) statusGetNeighborhoods(w http.ResponseWriter, _ *http.Request)

neighborhoods := make([]statusNeighborhoodResponse, 0)

nhoods, err := s.statusService.NeighborhoodsSnapshot()
nhoods, err := s.storer.NeighborhoodsStat(r.Context())
if err != nil {
logger.Debug("unable to get neighborhoods status", "error", err)
logger.Error(nil, "unable to get neighborhoods status")
jsonhttp.InternalServerError(w, "unable to get neighborhoods status")
return
}

if len(nhoods) == 0 {
jsonhttp.NotFound(w, "neighborhoods not found")
return
}

for _, n := range nhoods {
binaryAddr := ""
for _, b := range n.Address.Bytes() {
binaryAddr += fmt.Sprintf("%08b ", b)
}
neighborhoods = append(neighborhoods, statusNeighborhoodResponse{
Address: binaryAddr,
Neighborhood: n.Neighborhood.String(),
ReserveSizeWithinRadius: n.ReserveSizeWithinRadius,
Proximity: swarm.Proximity(s.overlay.Bytes(), n.Neighborhood.Bytes()),
})
}

Expand Down
15 changes: 0 additions & 15 deletions pkg/status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"github.com/ethersphere/bee/v2/pkg/p2p/protobuf"
"github.com/ethersphere/bee/v2/pkg/postage"
"github.com/ethersphere/bee/v2/pkg/status/internal/pb"
"github.com/ethersphere/bee/v2/pkg/storer"
"github.com/ethersphere/bee/v2/pkg/swarm"
"github.com/ethersphere/bee/v2/pkg/topology"
)
Expand All @@ -40,7 +39,6 @@ type Reserve interface {
ReserveSize() int
ReserveSizeWithinRadius() uint64
StorageRadius() uint8
NeighborhoodsStat(ctx context.Context) ([]*storer.NeighborhoodStat, error)
}

type topologyDriver interface {
Expand Down Expand Up @@ -133,19 +131,6 @@ func (s *Service) LocalSnapshot() (*Snapshot, error) {
}, nil
}

func (s *Service) NeighborhoodsSnapshot() ([]*storer.NeighborhoodStat, error) {
var err error
neighborhoods := make([]*storer.NeighborhoodStat, 0)

if s.reserve != nil {
neighborhoods, err = s.reserve.NeighborhoodsStat(context.Background())
if err != nil {
return neighborhoods, err
}
}
return neighborhoods, err
}

// PeerSnapshot sends request for status snapshot to the peer.
func (s *Service) PeerSnapshot(ctx context.Context, peer swarm.Address) (*Snapshot, error) {
stream, err := s.streamer.NewStream(ctx, peer, nil, protocolName, protocolVersion, streamName)
Expand Down
12 changes: 2 additions & 10 deletions pkg/status/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/ethersphere/bee/v2/pkg/postage"
"github.com/ethersphere/bee/v2/pkg/status"
"github.com/ethersphere/bee/v2/pkg/status/internal/pb"
"github.com/ethersphere/bee/v2/pkg/storer"
"github.com/ethersphere/bee/v2/pkg/swarm"
"github.com/ethersphere/bee/v2/pkg/topology"
"github.com/google/go-cmp/cmp"
Expand All @@ -36,7 +35,7 @@ func TestStatus(t *testing.T) {
LastSyncedBlock: 6092500,
}

sssMock := &statusSnapshotMock{want, nil}
sssMock := &statusSnapshotMock{want}

peersIterMock := new(topologyPeersIterNoopMock)

Expand Down Expand Up @@ -116,9 +115,7 @@ func TestStatusLightNode(t *testing.T) {
StorageRadius: 100, // should be ignored
BatchCommitment: 1024,
LastSyncedBlock: 6092500,
},
nil,
}
}}

peersIterMock := new(topologyPeersIterNoopMock)

Expand Down Expand Up @@ -194,7 +191,6 @@ func (m *topologyPeersIterNoopMock) IsReachable() bool {
// - SyncReporter
type statusSnapshotMock struct {
*pb.Snapshot
neighborhoods []*storer.NeighborhoodStat
}

func (m *statusSnapshotMock) SyncRate() float64 { return m.Snapshot.PullsyncRate }
Expand All @@ -207,7 +203,3 @@ func (m *statusSnapshotMock) GetChainState() *postage.ChainState {
func (m *statusSnapshotMock) ReserveSizeWithinRadius() uint64 {
return m.Snapshot.ReserveSizeWithinRadius
}

func (m *statusSnapshotMock) NeighborhoodsStat(ctx context.Context) ([]*storer.NeighborhoodStat, error) {
return m.neighborhoods, nil
}
4 changes: 4 additions & 0 deletions pkg/storer/mock/mockstorer.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,7 @@ func (m *mockStorer) IsWithinStorageRadius(_ swarm.Address) bool { return true }
func (m *mockStorer) DebugInfo(_ context.Context) (storer.Info, error) {
return m.debugInfo, nil
}

func (m *mockStorer) NeighborhoodsStat(ctx context.Context) ([]*storer.NeighborhoodStat, error) {
return nil, nil
}
6 changes: 3 additions & 3 deletions pkg/storer/reserve.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ func (db *DB) SubscribeBin(ctx context.Context, bin uint8, start uint64) (<-chan
}

type NeighborhoodStat struct {
Address swarm.Address
Neighborhood swarm.Neighborhood
ReserveSizeWithinRadius int
}

Expand All @@ -511,12 +511,12 @@ func (db *DB) NeighborhoodsStat(ctx context.Context) ([]*NeighborhoodStat, error
prefixes := neighborhoodPrefixes(db.baseAddr, int(radius), db.reserveOptions.capacityDoubling)
neighs := make([]*NeighborhoodStat, len(prefixes))
for i, n := range prefixes {
neighs[i] = &NeighborhoodStat{Address: n}
neighs[i] = &NeighborhoodStat{swarm.NewNeighborhood(n, networkRadius), 0}
}

err := db.reserve.IterateChunksItems(0, func(ch *reserve.ChunkBinItem) (bool, error) {
for _, n := range neighs {
if swarm.Proximity(ch.Address.Bytes(), n.Address.Bytes()) >= networkRadius {
if swarm.Proximity(ch.Address.Bytes(), n.Neighborhood.Bytes()) >= networkRadius {
n.ReserveSizeWithinRadius++
break
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/storer/reserve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,10 @@ func TestNeighborhoodStats(t *testing.T) {
}
}

if !neighs[0].Address.Equal(baseAddr) || !neighs[1].Address.Equal(sister1) || !neighs[2].Address.Equal(sister2) || !neighs[3].Address.Equal(sister3) {
if !neighs[0].Neighborhood.Equal(swarm.NewNeighborhood(baseAddr, networkRadius)) ||
!neighs[1].Neighborhood.Equal(swarm.NewNeighborhood(sister1, networkRadius)) ||
!neighs[2].Neighborhood.Equal(swarm.NewNeighborhood(sister2, networkRadius)) ||
!neighs[3].Neighborhood.Equal(swarm.NewNeighborhood(sister3, networkRadius)) {
t.Fatal("chunk addresses do not match")
}
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/storer/storer.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ type Debugger interface {
DebugInfo(context.Context) (Info, error)
}

type NeighborhoodStats interface {
NeighborhoodsStat(ctx context.Context) ([]*NeighborhoodStat, error)
}

type memFS struct {
afero.Fs
}
Expand Down
53 changes: 53 additions & 0 deletions pkg/swarm/swarm.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,56 @@ func bytesToAddr(b []byte) Address {
copy(addr, b)
return NewAddress(addr)
}

type Neighborhood struct {
b []byte
r uint8
}

func NewNeighborhood(a Address, bits uint8) Neighborhood {
return Neighborhood{b: a.b, r: bits}
}

// String returns a bit string of the Neighborhood.
func (n Neighborhood) String() string {
return bitStr(n.b, n.r)
}

// Equal returns true if two neighborhoods are identical.
func (n Neighborhood) Equal(b Neighborhood) bool {
return bytes.Equal(n.b, b.b)
}

// Bytes returns bytes representation of the Neighborhood.
func (n Neighborhood) Bytes() []byte {
return n.b
}

// Bytes returns bytes representation of the Neighborhood.
func (n Neighborhood) Clone() Neighborhood {
if n.b == nil {
return Neighborhood{}
}
return Neighborhood{b: append(make([]byte, 0, len(n.b)), n.Bytes()...), r: n.r}
}

func bitStr(src []byte, bits uint8) string {

ret := ""

for _, b := range src {
for i := 7; i >= 0; i-- {
if b&(1<<i) > 0 {
ret += "1"
} else {
ret += "0"
}
bits--
if bits == 0 {
return ret
}
}
}

return ret
}
38 changes: 38 additions & 0 deletions pkg/swarm/swarm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package swarm_test

import (
"bytes"
"encoding/hex"
"encoding/json"
"errors"
Expand Down Expand Up @@ -191,3 +192,40 @@ func TestParseBitStr(t *testing.T) {
}
}
}

func TestNeighborhood(t *testing.T) {
t.Parallel()

for _, tc := range []struct {
overlay swarm.Address
bitStr string
}{
{
swarm.MustParseHexAddress("5c32a2fe3d217af8c943fa665ebcfbdf7ab9af0cf1b2a1c8e5fc163dad2f5c7b"),
"010111000",
},
{
swarm.MustParseHexAddress("eac0903e59ff1c1a5f1d7d218b33f819b199aa0f68a19fd5fa02b7f84982b55d"),
"111010101",
},
{
swarm.MustParseHexAddress("70143dd2863ae07edfe7c1bfee75daea06226f0678e1117337d274492226bfe0"),
"011100000",
},
} {

n := swarm.NewNeighborhood(tc.overlay, uint8(len(tc.bitStr)))
if n.Equal(swarm.NewNeighborhood(swarm.RandAddress(t), uint8(len(tc.bitStr)))) {
t.Fatal("addresses not should match")
}
if !n.Equal(swarm.NewNeighborhood(tc.overlay, uint8(len(tc.bitStr)))) {
t.Fatal("addresses should match")
}
if !bytes.Equal(n.Bytes(), tc.overlay.Bytes()) {
t.Fatal("bytes should match")
}
if n.String() != tc.bitStr {
t.Fatal("bit str should match")
}
}
}

0 comments on commit ff472fa

Please sign in to comment.