diff --git a/openapi/SwarmCommon.yaml b/openapi/SwarmCommon.yaml index 6bec5c4f595..3a8fa2b1e14 100644 --- a/openapi/SwarmCommon.yaml +++ b/openapi/SwarmCommon.yaml @@ -849,7 +849,7 @@ components: reserveSize: type: integer reserveSizeWithinRadius: - type: interger + type: integer pullsyncRate: type: number storageRadius: @@ -865,6 +865,8 @@ components: type: integer isReachable: type: boolean + lastSyncedBlock: + type: integer StatusResponse: type: object diff --git a/pkg/api/status.go b/pkg/api/status.go index 38c34fd7d9d..867c7d410e9 100644 --- a/pkg/api/status.go +++ b/pkg/api/status.go @@ -29,6 +29,7 @@ type statusSnapshotResponse struct { RequestFailed bool `json:"requestFailed,omitempty"` BatchCommitment uint64 `json:"batchCommitment"` IsReachable bool `json:"isReachable"` + LastSyncedBlock uint64 `json:"lastSyncedBlock"` } type statusResponse struct { @@ -82,6 +83,7 @@ func (s *Service) statusGetHandler(w http.ResponseWriter, _ *http.Request) { NeighborhoodSize: ss.NeighborhoodSize, BatchCommitment: ss.BatchCommitment, IsReachable: ss.IsReachable, + LastSyncedBlock: ss.LastSyncedBlock, }) } @@ -128,6 +130,7 @@ func (s *Service) statusGetPeersHandler(w http.ResponseWriter, r *http.Request) snapshot.NeighborhoodSize = ss.NeighborhoodSize snapshot.BatchCommitment = ss.BatchCommitment snapshot.IsReachable = ss.IsReachable + snapshot.LastSyncedBlock = ss.LastSyncedBlock } mu.Lock() diff --git a/pkg/api/status_test.go b/pkg/api/status_test.go index 1c404ca9039..31822ce789d 100644 --- a/pkg/api/status_test.go +++ b/pkg/api/status_test.go @@ -12,6 +12,7 @@ import ( "github.com/ethersphere/bee/v2/pkg/jsonhttp" "github.com/ethersphere/bee/v2/pkg/jsonhttp/jsonhttptest" "github.com/ethersphere/bee/v2/pkg/log" + "github.com/ethersphere/bee/v2/pkg/postage" "github.com/ethersphere/bee/v2/pkg/status" "github.com/ethersphere/bee/v2/pkg/topology" ) @@ -36,6 +37,7 @@ func TestGetStatus(t *testing.T) { NeighborhoodSize: 1, BatchCommitment: 1, IsReachable: true, + LastSyncedBlock: 6092500, } ssMock := &statusSnapshotMock{ @@ -44,6 +46,7 @@ func TestGetStatus(t *testing.T) { reserveSizeWithinRadius: ssr.ReserveSizeWithinRadius, storageRadius: ssr.StorageRadius, commitment: ssr.BatchCommitment, + chainState: &postage.ChainState{Block: ssr.LastSyncedBlock}, } statusSvc := status.NewService( @@ -115,12 +118,14 @@ type statusSnapshotMock struct { reserveSizeWithinRadius uint64 storageRadius uint8 commitment uint64 + chainState *postage.ChainState } -func (m *statusSnapshotMock) SyncRate() float64 { return m.syncRate } -func (m *statusSnapshotMock) ReserveSize() int { return m.reserveSize } -func (m *statusSnapshotMock) StorageRadius() uint8 { return m.storageRadius } -func (m *statusSnapshotMock) Commitment() (uint64, error) { return m.commitment, nil } +func (m *statusSnapshotMock) SyncRate() float64 { return m.syncRate } +func (m *statusSnapshotMock) ReserveSize() int { return m.reserveSize } +func (m *statusSnapshotMock) StorageRadius() uint8 { return m.storageRadius } +func (m *statusSnapshotMock) Commitment() (uint64, error) { return m.commitment, nil } +func (m *statusSnapshotMock) GetChainState() *postage.ChainState { return m.chainState } func (m *statusSnapshotMock) ReserveSizeWithinRadius() uint64 { return m.reserveSizeWithinRadius } diff --git a/pkg/postage/interface.go b/pkg/postage/interface.go index 3a420c87475..9d93918307b 100644 --- a/pkg/postage/interface.go +++ b/pkg/postage/interface.go @@ -42,7 +42,6 @@ type ChainSnapshot struct { // on the current (highest available) block. type Storer interface { ChainStateGetter - CommitmentGetter Radius() uint8 @@ -80,6 +79,7 @@ type CommitmentGetter interface { } type ChainStateGetter interface { + CommitmentGetter // GetChainState returns the stored chain state from the store. GetChainState() *ChainState } diff --git a/pkg/status/internal/pb/status.pb.go b/pkg/status/internal/pb/status.pb.go index 868cc0f11e0..fb057b77ae8 100644 --- a/pkg/status/internal/pb/status.pb.go +++ b/pkg/status/internal/pb/status.pb.go @@ -73,6 +73,7 @@ type Snapshot struct { BatchCommitment uint64 `protobuf:"varint,7,opt,name=BatchCommitment,proto3" json:"BatchCommitment,omitempty"` IsReachable bool `protobuf:"varint,8,opt,name=IsReachable,proto3" json:"IsReachable,omitempty"` ReserveSizeWithinRadius uint64 `protobuf:"varint,9,opt,name=ReserveSizeWithinRadius,proto3" json:"ReserveSizeWithinRadius,omitempty"` + LastSyncedBlock uint64 `protobuf:"varint,10,opt,name=LastSyncedBlock,proto3" json:"LastSyncedBlock,omitempty"` } func (m *Snapshot) Reset() { *m = Snapshot{} } @@ -171,6 +172,13 @@ func (m *Snapshot) GetReserveSizeWithinRadius() uint64 { return 0 } +func (m *Snapshot) GetLastSyncedBlock() uint64 { + if m != nil { + return m.LastSyncedBlock + } + return 0 +} + func init() { proto.RegisterType((*Get)(nil), "status.Get") proto.RegisterType((*Snapshot)(nil), "status.Snapshot") @@ -179,26 +187,27 @@ func init() { func init() { proto.RegisterFile("status.proto", fileDescriptor_dfe4fce6682daf5b) } var fileDescriptor_dfe4fce6682daf5b = []byte{ - // 298 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x3f, 0x4b, 0x73, 0x31, - 0x14, 0xc6, 0x9b, 0xfe, 0x6f, 0xde, 0xf6, 0x55, 0xb2, 0x98, 0x41, 0x42, 0x28, 0x22, 0xc1, 0xc1, - 0xc5, 0xc5, 0xb9, 0x1d, 0xc4, 0x41, 0x29, 0xe9, 0x20, 0xb8, 0xe5, 0xde, 0x7b, 0x68, 0x02, 0x6d, - 0x52, 0x6e, 0x4e, 0x05, 0xfd, 0x14, 0x7e, 0x2c, 0xc7, 0x8e, 0x8e, 0xd2, 0x6e, 0x7e, 0x0a, 0x31, - 0x2a, 0xdc, 0x56, 0x1c, 0x9f, 0xdf, 0x39, 0x3c, 0xe7, 0x9c, 0xe7, 0xd0, 0x7e, 0x44, 0x83, 0xab, - 0x78, 0xbe, 0x2c, 0x03, 0x06, 0xd6, 0xfe, 0x52, 0xc3, 0x16, 0x6d, 0x5c, 0x01, 0x0e, 0xdf, 0xeb, - 0xb4, 0x3b, 0xf5, 0x66, 0x19, 0x6d, 0x40, 0x26, 0xe9, 0x3f, 0x0d, 0x11, 0xca, 0x07, 0x98, 0xba, - 0x27, 0xe0, 0x44, 0x12, 0xd5, 0xd4, 0x55, 0xc4, 0x86, 0xb4, 0x3f, 0x59, 0xcd, 0xe7, 0xf1, 0xd1, - 0xe7, 0xda, 0x20, 0xf0, 0xba, 0x24, 0x8a, 0xe8, 0x1d, 0xc6, 0x4e, 0xe8, 0x60, 0x8a, 0xa1, 0x34, - 0x33, 0xd0, 0xa6, 0x70, 0xab, 0xc8, 0x1b, 0x92, 0xa8, 0x81, 0xde, 0x85, 0xec, 0x94, 0xfe, 0x1f, - 0x07, 0xef, 0x21, 0x47, 0x28, 0x26, 0x00, 0x65, 0xe4, 0xcd, 0x34, 0x6e, 0x8f, 0xb2, 0x33, 0x7a, - 0x78, 0x0b, 0x6e, 0x66, 0xb3, 0x50, 0xda, 0x10, 0x8a, 0xb4, 0x58, 0x2b, 0x75, 0xfe, 0xe2, 0x8c, - 0xd3, 0xce, 0x08, 0xe0, 0x26, 0x14, 0xc0, 0xdb, 0x92, 0xa8, 0x9e, 0xfe, 0x91, 0x4c, 0xd1, 0x83, - 0x91, 0xc1, 0xdc, 0x8e, 0xc3, 0x62, 0xe1, 0x70, 0x01, 0x1e, 0x79, 0x27, 0x99, 0xec, 0xe3, 0xcf, - 0x0c, 0xae, 0xa3, 0x06, 0x93, 0x5b, 0x93, 0xcd, 0x81, 0x77, 0x25, 0x51, 0x5d, 0x5d, 0x45, 0xec, - 0x92, 0x1e, 0x55, 0x22, 0xb9, 0x73, 0x68, 0x9d, 0xff, 0xbe, 0xb4, 0x97, 0x3c, 0xff, 0x2a, 0x8f, - 0x8e, 0x5f, 0x36, 0x82, 0xac, 0x37, 0x82, 0xbc, 0x6d, 0x04, 0x79, 0xde, 0x8a, 0xda, 0x7a, 0x2b, - 0x6a, 0xaf, 0x5b, 0x51, 0xbb, 0xaf, 0x2f, 0xb3, 0xac, 0x9d, 0x1e, 0x74, 0xf1, 0x11, 0x00, 0x00, - 0xff, 0xff, 0xb8, 0xde, 0xcb, 0x07, 0xb0, 0x01, 0x00, 0x00, + // 317 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0xd1, 0xbd, 0x4a, 0x03, 0x41, + 0x10, 0x07, 0xf0, 0x6c, 0xbe, 0x33, 0x26, 0x2a, 0xdb, 0xb8, 0x85, 0x1c, 0x47, 0x10, 0x39, 0x2c, + 0x6c, 0x6c, 0xac, 0x2f, 0x85, 0x08, 0x2a, 0x61, 0xaf, 0x10, 0xec, 0xf6, 0xee, 0x86, 0xdc, 0xe1, + 0x65, 0x37, 0xdc, 0x4e, 0x84, 0xf8, 0x14, 0x16, 0x3e, 0x94, 0x65, 0x4a, 0x4b, 0x49, 0x5e, 0x44, + 0xb2, 0x51, 0x48, 0x4e, 0x2c, 0xe7, 0xb7, 0xcb, 0xec, 0x7f, 0x67, 0xa0, 0x6f, 0x49, 0xd1, 0xdc, + 0x5e, 0xce, 0x4a, 0x43, 0x86, 0xb7, 0xb7, 0xd5, 0xb0, 0x05, 0x8d, 0x1b, 0xa4, 0xe1, 0x7b, 0x03, + 0xba, 0x91, 0x56, 0x33, 0x9b, 0x19, 0xe2, 0x3e, 0x1c, 0x48, 0xb4, 0x58, 0xbe, 0x60, 0x94, 0xbf, + 0xa2, 0x60, 0x3e, 0x0b, 0x9a, 0x72, 0x97, 0xf8, 0x10, 0xfa, 0xe3, 0x79, 0x51, 0xd8, 0x85, 0x4e, + 0xa4, 0x22, 0x14, 0x75, 0x9f, 0x05, 0x4c, 0xee, 0x19, 0x3f, 0x83, 0x41, 0x44, 0xa6, 0x54, 0x13, + 0x94, 0x2a, 0xcd, 0xe7, 0x56, 0x34, 0x7c, 0x16, 0x0c, 0xe4, 0x3e, 0xf2, 0x73, 0x38, 0x1c, 0x19, + 0xad, 0x31, 0x21, 0x4c, 0xc7, 0x88, 0xa5, 0x15, 0x4d, 0xf7, 0x5c, 0x45, 0xf9, 0x05, 0x1c, 0x3f, + 0x60, 0x3e, 0xc9, 0x62, 0x53, 0x66, 0xc6, 0xa4, 0x2e, 0x58, 0xcb, 0xdd, 0xfc, 0xe3, 0x5c, 0x40, + 0x27, 0x44, 0xbc, 0x37, 0x29, 0x8a, 0xb6, 0xcf, 0x82, 0x9e, 0xfc, 0x2d, 0x79, 0x00, 0x47, 0xa1, + 0xa2, 0x24, 0x1b, 0x99, 0xe9, 0x34, 0xa7, 0x29, 0x6a, 0x12, 0x1d, 0xd7, 0xa4, 0xca, 0x9b, 0x19, + 0xdc, 0x5a, 0x89, 0x2a, 0xc9, 0x54, 0x5c, 0xa0, 0xe8, 0xfa, 0x2c, 0xe8, 0xca, 0x5d, 0xe2, 0xd7, + 0x70, 0xb2, 0x33, 0x92, 0xc7, 0x9c, 0xb2, 0x5c, 0xff, 0xfc, 0xb4, 0xe7, 0x7a, 0xfe, 0x77, 0xbc, + 0x49, 0x71, 0xa7, 0x2c, 0x45, 0x0b, 0x9d, 0x60, 0x1a, 0x16, 0x26, 0x79, 0x16, 0xb0, 0x4d, 0x51, + 0xe1, 0xf0, 0xf4, 0x63, 0xe5, 0xb1, 0xe5, 0xca, 0x63, 0x5f, 0x2b, 0x8f, 0xbd, 0xad, 0xbd, 0xda, + 0x72, 0xed, 0xd5, 0x3e, 0xd7, 0x5e, 0xed, 0xa9, 0x3e, 0x8b, 0xe3, 0xb6, 0x5b, 0xe5, 0xd5, 0x77, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x92, 0x33, 0xb8, 0x1e, 0xda, 0x01, 0x00, 0x00, } func (m *Get) Marshal() (dAtA []byte, err error) { @@ -244,6 +253,11 @@ func (m *Snapshot) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.LastSyncedBlock != 0 { + i = encodeVarintStatus(dAtA, i, uint64(m.LastSyncedBlock)) + i-- + dAtA[i] = 0x50 + } if m.ReserveSizeWithinRadius != 0 { i = encodeVarintStatus(dAtA, i, uint64(m.ReserveSizeWithinRadius)) i-- @@ -354,6 +368,9 @@ func (m *Snapshot) Size() (n int) { if m.ReserveSizeWithinRadius != 0 { n += 1 + sovStatus(uint64(m.ReserveSizeWithinRadius)) } + if m.LastSyncedBlock != 0 { + n += 1 + sovStatus(uint64(m.LastSyncedBlock)) + } return n } @@ -622,6 +639,25 @@ func (m *Snapshot) Unmarshal(dAtA []byte) error { break } } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastSyncedBlock", wireType) + } + m.LastSyncedBlock = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStatus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LastSyncedBlock |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipStatus(dAtA[iNdEx:]) diff --git a/pkg/status/internal/pb/status.proto b/pkg/status/internal/pb/status.proto index a62eb327433..1cd76212b79 100644 --- a/pkg/status/internal/pb/status.proto +++ b/pkg/status/internal/pb/status.proto @@ -24,4 +24,5 @@ message Snapshot { uint64 BatchCommitment = 7; bool IsReachable = 8; uint64 ReserveSizeWithinRadius = 9; + uint64 LastSyncedBlock = 10; } diff --git a/pkg/status/status.go b/pkg/status/status.go index b6eeef6bd30..d8106b4e4fb 100644 --- a/pkg/status/status.go +++ b/pkg/status/status.go @@ -22,7 +22,7 @@ const loggerName = "status" const ( protocolName = "status" - protocolVersion = "1.1.0" + protocolVersion = "1.1.1" streamName = "status" ) @@ -55,7 +55,7 @@ type Service struct { beeMode string reserve Reserve sync SyncReporter - commitment postage.CommitmentGetter + chainState postage.ChainStateGetter } // NewService creates a new status service. @@ -64,7 +64,7 @@ func NewService( streamer p2p.Streamer, topology topologyDriver, beeMode string, - commitment postage.CommitmentGetter, + chainState postage.ChainStateGetter, reserve Reserve, ) *Service { return &Service{ @@ -72,7 +72,7 @@ func NewService( streamer: streamer, topologyDriver: topology, beeMode: beeMode, - commitment: commitment, + chainState: chainState, reserve: reserve, } } @@ -98,7 +98,7 @@ func (s *Service) LocalSnapshot() (*Snapshot, error) { syncRate = s.sync.SyncRate() } - commitment, err := s.commitment.Commitment() + commitment, err := s.chainState.Commitment() if err != nil { return nil, fmt.Errorf("batchstore commitment: %w", err) } @@ -127,6 +127,7 @@ func (s *Service) LocalSnapshot() (*Snapshot, error) { NeighborhoodSize: neighborhoodSize + 1, // include self BatchCommitment: commitment, IsReachable: s.topologyDriver.IsReachable(), + LastSyncedBlock: s.chainState.GetChainState().Block, }, nil } @@ -150,7 +151,6 @@ func (s *Service) PeerSnapshot(ctx context.Context, peer swarm.Address) (*Snapsh if err := r.ReadMsgWithContext(ctx, ss); err != nil { return nil, fmt.Errorf("read message failed: %w", err) } - return (*Snapshot)(ss), nil } diff --git a/pkg/status/status_test.go b/pkg/status/status_test.go index ff98816226d..019cdae578c 100644 --- a/pkg/status/status_test.go +++ b/pkg/status/status_test.go @@ -13,6 +13,7 @@ import ( "github.com/ethersphere/bee/v2/pkg/log" "github.com/ethersphere/bee/v2/pkg/p2p/protobuf" "github.com/ethersphere/bee/v2/pkg/p2p/streamtest" + "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/swarm" @@ -31,6 +32,7 @@ func TestStatus(t *testing.T) { BatchCommitment: 1024, NeighborhoodSize: 1, IsReachable: true, + LastSyncedBlock: 6092500, } sssMock := &statusSnapshotMock{want} @@ -104,6 +106,7 @@ func TestStatusLightNode(t *testing.T) { BatchCommitment: 1024, IsReachable: true, NeighborhoodSize: 1, + LastSyncedBlock: 6092500, } sssMock := &statusSnapshotMock{&pb.Snapshot{ @@ -111,6 +114,7 @@ func TestStatusLightNode(t *testing.T) { PullsyncRate: 100, // should be ignored StorageRadius: 100, // should be ignored BatchCommitment: 1024, + LastSyncedBlock: 6092500, }} peersIterMock := new(topologyPeersIterNoopMock) @@ -193,6 +197,9 @@ func (m *statusSnapshotMock) SyncRate() float64 { return m.Snapshot.Pu func (m *statusSnapshotMock) ReserveSize() int { return int(m.Snapshot.ReserveSize) } func (m *statusSnapshotMock) StorageRadius() uint8 { return uint8(m.Snapshot.StorageRadius) } func (m *statusSnapshotMock) Commitment() (uint64, error) { return m.Snapshot.BatchCommitment, nil } +func (m *statusSnapshotMock) GetChainState() *postage.ChainState { + return &postage.ChainState{Block: m.Snapshot.LastSyncedBlock} +} func (m *statusSnapshotMock) ReserveSizeWithinRadius() uint64 { return m.Snapshot.ReserveSizeWithinRadius }