Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test only current validators api #3404

Draft
wants to merge 17 commits into
base: remove-subnetid-uptime-manager
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
411 changes: 343 additions & 68 deletions proto/pb/validatorstate/validator_state.pb.go

Large diffs are not rendered by default.

49 changes: 45 additions & 4 deletions proto/pb/validatorstate/validator_state_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions proto/validatorstate/validator_state.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ service ValidatorState {
// GetValidatorSet returns the weights of the nodeIDs for the provided
// subnet at the requested P-chain height.
rpc GetValidatorSet(GetValidatorSetRequest) returns (GetValidatorSetResponse);
// GetCurrentValidatorSet returns the weights of the nodeIDs for the provided
// subnet at the current P-chain height.
rpc GetCurrentValidatorSet(GetCurrentValidatorSetRequest) returns (GetCurrentValidatorSetResponse);
}

message GetMinimumHeightResponse {
Expand All @@ -40,12 +43,31 @@ message GetValidatorSetRequest {
bytes subnet_id = 2;
}

message GetCurrentValidatorSetRequest {
bytes subnet_id = 1;
}

message Validator {
bytes node_id = 1;
uint64 weight = 2;
bytes public_key = 3;
}

message CurrentValidator {
bytes node_id = 1;
uint64 weight = 2;
bytes public_key = 3;
uint64 start_time = 4;
uint64 set_weight_nonce = 5;
bool is_active = 6;
bytes validation_id = 7;
}

message GetValidatorSetResponse {
repeated Validator validators = 1;
}

message GetCurrentValidatorSetResponse {
repeated CurrentValidator validators = 1;
uint64 current_height = 2;
}
27 changes: 14 additions & 13 deletions snow/uptime/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Manager interface {
type Tracker interface {
StartTracking(nodeIDs []ids.NodeID) error
StopTracking(nodeIDs []ids.NodeID) error
StartedTracking() bool

Connect(nodeID ids.NodeID) error
IsConnected(nodeID ids.NodeID) bool
Expand Down Expand Up @@ -54,9 +55,12 @@ func NewManager(state State, clk *mockable.Clock) Manager {
}

func (m *manager) StartTracking(nodeIDs []ids.NodeID) error {
if m.startedTracking {
return nil
}
now := m.clock.UnixTime()
for _, nodeID := range nodeIDs {
upDuration, lastUpdated, err := m.state.GetUptime(nodeID)
upDuration, lastUpdated, err := m.CalculateUptime(nodeID)
if err != nil {
return err
}
Expand All @@ -67,9 +71,7 @@ func (m *manager) StartTracking(nodeIDs []ids.NodeID) error {
continue
}

durationOffline := now.Sub(lastUpdated)
newUpDuration := upDuration + durationOffline
if err := m.state.SetUptime(nodeID, newUpDuration, now); err != nil {
if err := m.state.SetUptime(nodeID, upDuration, lastUpdated); err != nil {
return err
}
}
Expand All @@ -78,7 +80,6 @@ func (m *manager) StartTracking(nodeIDs []ids.NodeID) error {
}

func (m *manager) StopTracking(nodeIDs []ids.NodeID) error {
// TODO: this was not here before, should we add it?
if !m.startedTracking {
return nil
}
Expand All @@ -89,8 +90,8 @@ func (m *manager) StopTracking(nodeIDs []ids.NodeID) error {
for _, nodeID := range nodeIDs {
// If the node is already connected, then we can just
// update the uptime in the state and remove the connection
if _, isConnected := m.connections[nodeID]; isConnected {
if err := m.disconnect(nodeID); err != nil {
if m.IsConnected(nodeID) {
if err := m.Disconnect(nodeID); err != nil {
return err
}
continue
Expand All @@ -116,6 +117,10 @@ func (m *manager) StopTracking(nodeIDs []ids.NodeID) error {
return nil
}

func (m *manager) StartedTracking() bool {
return m.startedTracking
}

func (m *manager) Connect(nodeID ids.NodeID) error {
m.connections[nodeID] = m.clock.UnixTime()
return nil
Expand All @@ -127,15 +132,11 @@ func (m *manager) IsConnected(nodeID ids.NodeID) bool {
}

func (m *manager) Disconnect(nodeID ids.NodeID) error {
return m.disconnect(nodeID)
}

func (m *manager) disconnect(nodeID ids.NodeID) error {
defer delete(m.connections, nodeID)
if err := m.updateUptime(nodeID); err != nil {
return err
}
// TODO: shall we delete the connection regardless of the error?
delete(m.connections, nodeID)

return nil
}

Expand Down
46 changes: 46 additions & 0 deletions snow/validators/gvalidators/validator_state_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,49 @@ func (c *Client) GetValidatorSet(
}
return vdrs, nil
}

func (c *Client) GetCurrentValidatorSet(
ctx context.Context,
subnetID ids.ID,
) (map[ids.ID]*validators.GetCurrentValidatorOutput, uint64, error) {
resp, err := c.client.GetCurrentValidatorSet(ctx, &pb.GetCurrentValidatorSetRequest{
SubnetId: subnetID[:],
})
if err != nil {
return nil, 0, err
}

vdrs := make(map[ids.ID]*validators.GetCurrentValidatorOutput, len(resp.Validators))
for _, validator := range resp.Validators {
nodeID, err := ids.ToNodeID(validator.NodeId)
if err != nil {
return nil, 0, err
}
var publicKey *bls.PublicKey
if len(validator.PublicKey) > 0 {
// This is a performance optimization to avoid the cost of
// compression and key re-verification with
// PublicKeyFromCompressedBytes. We can safely assume that the BLS
// Public Keys are verified before being added to the P-Chain and
// served by the gRPC server.
publicKey = bls.PublicKeyFromValidUncompressedBytes(validator.PublicKey)
if publicKey == nil {
return nil, 0, errFailedPublicKeyDeserialize
}
}
validationID, err := ids.ToID(validator.ValidationId)
if err != nil {
return nil, 0, err
}

vdrs[validationID] = &validators.GetCurrentValidatorOutput{
NodeID: nodeID,
PublicKey: publicKey,
Weight: validator.Weight,
StartTime: validator.StartTime,
SetWeightNonce: validator.SetWeightNonce,
IsActive: validator.IsActive,
}
}
return vdrs, resp.GetCurrentHeight(), nil
}
37 changes: 37 additions & 0 deletions snow/validators/gvalidators/validator_state_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,40 @@ func (s *Server) GetValidatorSet(ctx context.Context, req *pb.GetValidatorSetReq
}
return resp, nil
}

func (s *Server) GetCurrentValidatorSet(ctx context.Context, req *pb.GetCurrentValidatorSetRequest) (*pb.GetCurrentValidatorSetResponse, error) {
subnetID, err := ids.ToID(req.SubnetId)
if err != nil {
return nil, err
}

vdrs, currentHeight, err := s.state.GetCurrentValidatorSet(ctx, subnetID)
if err != nil {
return nil, err
}

resp := &pb.GetCurrentValidatorSetResponse{
Validators: make([]*pb.CurrentValidator, len(vdrs)),
CurrentHeight: currentHeight,
}

i := 0
for _, vdr := range vdrs {
vdrPB := &pb.CurrentValidator{
NodeId: vdr.NodeID.Bytes(),
StartTime: vdr.StartTime,
IsActive: vdr.IsActive,
ValidationId: vdr.ValidationID[:],
Weight: vdr.Weight,
SetWeightNonce: vdr.SetWeightNonce,
}
if vdr.PublicKey != nil {
// This is a performance optimization to avoid the cost of compression
// from PublicKeyToCompressedBytes.
vdrPB.PublicKey = bls.PublicKeyToUncompressedBytes(vdr.PublicKey)
}
resp.Validators[i] = vdrPB
i++
}
return resp, nil
}
24 changes: 24 additions & 0 deletions snow/validators/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ type State interface {
height uint64,
subnetID ids.ID,
) (map[ids.NodeID]*GetValidatorOutput, error)

// GetCurrentValidatorSet returns the current validators of the provided subnet
// and the current P-Chain height.
// Map is keyed by ValidationID.
// The returned map should not be modified.
GetCurrentValidatorSet(
ctx context.Context,
subnetID ids.ID,
) (map[ids.ID]*GetCurrentValidatorOutput, uint64, error)
}

type lockedState struct {
Expand Down Expand Up @@ -78,6 +87,16 @@ func (s *lockedState) GetValidatorSet(
return s.s.GetValidatorSet(ctx, height, subnetID)
}

func (s *lockedState) GetCurrentValidatorSet(
ctx context.Context,
subnetID ids.ID,
) (map[ids.ID]*GetCurrentValidatorOutput, uint64, error) {
s.lock.Lock()
defer s.lock.Unlock()

return s.s.GetCurrentValidatorSet(ctx, subnetID)
}

type noValidators struct {
State
}
Expand All @@ -91,3 +110,8 @@ func NewNoValidatorsState(state State) State {
func (*noValidators) GetValidatorSet(context.Context, uint64, ids.ID) (map[ids.NodeID]*GetValidatorOutput, error) {
return nil, nil
}

func (*noValidators) GetCurrentValidatorSet(context.Context, ids.ID) (map[ids.ID]*GetCurrentValidatorOutput, uint64, error) {
// TODO: should we return the actual height?
return nil, 0, nil
}
12 changes: 12 additions & 0 deletions snow/validators/traced_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,15 @@ func (s *tracedState) GetValidatorSet(

return s.s.GetValidatorSet(ctx, height, subnetID)
}

func (s *tracedState) GetCurrentValidatorSet(
ctx context.Context,
subnetID ids.ID,
) (map[ids.ID]*GetCurrentValidatorOutput, uint64, error) {
ctx, span := s.tracer.Start(ctx, s.getValidatorSetTag, oteltrace.WithAttributes(
attribute.Stringer("subnetID", subnetID),
))
defer span.End()

return s.s.GetCurrentValidatorSet(ctx, subnetID)
}
10 changes: 10 additions & 0 deletions snow/validators/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,13 @@ type GetValidatorOutput struct {
PublicKey *bls.PublicKey
Weight uint64
}

type GetCurrentValidatorOutput struct {
ValidationID ids.ID
NodeID ids.NodeID
PublicKey *bls.PublicKey
Weight uint64
StartTime uint64
SetWeightNonce uint64
IsActive bool
}
Loading
Loading