From 9c8835bd790732c61d0da189f65ea7f2fc50f808 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 24 Jul 2024 16:42:09 +0300 Subject: [PATCH 01/21] remove subnet IDs from uptime pkg --- snow/uptime/locked_calculator.go | 12 +- snow/uptime/locked_calculator_test.go | 19 +- snow/uptime/manager.go | 109 ++++------ snow/uptime/manager_test.go | 291 +++++++++++--------------- snow/uptime/no_op_calculator.go | 6 +- snow/uptime/state.go | 21 +- snow/uptime/test_state.go | 25 +-- 7 files changed, 200 insertions(+), 283 deletions(-) diff --git a/snow/uptime/locked_calculator.go b/snow/uptime/locked_calculator.go index 884878ab24f6..a1e9537a5e2f 100644 --- a/snow/uptime/locked_calculator.go +++ b/snow/uptime/locked_calculator.go @@ -35,7 +35,7 @@ func NewLockedCalculator() LockedCalculator { return &lockedCalculator{} } -func (c *lockedCalculator) CalculateUptime(nodeID ids.NodeID, subnetID ids.ID) (time.Duration, time.Time, error) { +func (c *lockedCalculator) CalculateUptime(nodeID ids.NodeID) (time.Duration, time.Time, error) { c.lock.RLock() defer c.lock.RUnlock() @@ -46,10 +46,10 @@ func (c *lockedCalculator) CalculateUptime(nodeID ids.NodeID, subnetID ids.ID) ( c.calculatorLock.Lock() defer c.calculatorLock.Unlock() - return c.c.CalculateUptime(nodeID, subnetID) + return c.c.CalculateUptime(nodeID) } -func (c *lockedCalculator) CalculateUptimePercent(nodeID ids.NodeID, subnetID ids.ID) (float64, error) { +func (c *lockedCalculator) CalculateUptimePercent(nodeID ids.NodeID) (float64, error) { c.lock.RLock() defer c.lock.RUnlock() @@ -60,10 +60,10 @@ func (c *lockedCalculator) CalculateUptimePercent(nodeID ids.NodeID, subnetID id c.calculatorLock.Lock() defer c.calculatorLock.Unlock() - return c.c.CalculateUptimePercent(nodeID, subnetID) + return c.c.CalculateUptimePercent(nodeID) } -func (c *lockedCalculator) CalculateUptimePercentFrom(nodeID ids.NodeID, subnetID ids.ID, startTime time.Time) (float64, error) { +func (c *lockedCalculator) CalculateUptimePercentFrom(nodeID ids.NodeID, startTime time.Time) (float64, error) { c.lock.RLock() defer c.lock.RUnlock() @@ -74,7 +74,7 @@ func (c *lockedCalculator) CalculateUptimePercentFrom(nodeID ids.NodeID, subnetI c.calculatorLock.Lock() defer c.calculatorLock.Unlock() - return c.c.CalculateUptimePercentFrom(nodeID, subnetID, startTime) + return c.c.CalculateUptimePercentFrom(nodeID, startTime) } func (c *lockedCalculator) SetCalculator(isBootstrapped *utils.Atomic[bool], lock sync.Locker, newC Calculator) { diff --git a/snow/uptime/locked_calculator_test.go b/snow/uptime/locked_calculator_test.go index 966722f6457d..9e5edaad8c63 100644 --- a/snow/uptime/locked_calculator_test.go +++ b/snow/uptime/locked_calculator_test.go @@ -24,14 +24,13 @@ func TestLockedCalculator(t *testing.T) { // Should still error because ctx is nil nodeID := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() - _, _, err := lc.CalculateUptime(nodeID, subnetID) + _, _, err := lc.CalculateUptime(nodeID) require.ErrorIs(err, errStillBootstrapping) - _, err = lc.CalculateUptimePercent(nodeID, subnetID) + _, err = lc.CalculateUptimePercent(nodeID) require.ErrorIs(err, errStillBootstrapping) - _, err = lc.CalculateUptimePercentFrom(nodeID, subnetID, time.Now()) + _, err = lc.CalculateUptimePercentFrom(nodeID, time.Now()) require.ErrorIs(err, errStillBootstrapping) var isBootstrapped utils.Atomic[bool] @@ -39,27 +38,27 @@ func TestLockedCalculator(t *testing.T) { // Should still error because ctx is not bootstrapped lc.SetCalculator(&isBootstrapped, &sync.Mutex{}, mockCalc) - _, _, err = lc.CalculateUptime(nodeID, subnetID) + _, _, err = lc.CalculateUptime(nodeID) require.ErrorIs(err, errStillBootstrapping) - _, err = lc.CalculateUptimePercent(nodeID, subnetID) + _, err = lc.CalculateUptimePercent(nodeID) require.ErrorIs(err, errStillBootstrapping) - _, err = lc.CalculateUptimePercentFrom(nodeID, subnetID, time.Now()) + _, err = lc.CalculateUptimePercentFrom(nodeID, time.Now()) require.ErrorIs(err, errStillBootstrapping) isBootstrapped.Set(true) // Should return the value from the mocked inner calculator mockCalc.EXPECT().CalculateUptime(gomock.Any(), gomock.Any()).AnyTimes().Return(time.Duration(0), time.Time{}, errTest) - _, _, err = lc.CalculateUptime(nodeID, subnetID) + _, _, err = lc.CalculateUptime(nodeID) require.ErrorIs(err, errTest) mockCalc.EXPECT().CalculateUptimePercent(gomock.Any(), gomock.Any()).AnyTimes().Return(float64(0), errTest) - _, err = lc.CalculateUptimePercent(nodeID, subnetID) + _, err = lc.CalculateUptimePercent(nodeID) require.ErrorIs(err, errTest) mockCalc.EXPECT().CalculateUptimePercentFrom(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(float64(0), errTest) - _, err = lc.CalculateUptimePercentFrom(nodeID, subnetID, time.Now()) + _, err = lc.CalculateUptimePercentFrom(nodeID, time.Now()) require.ErrorIs(err, errTest) } diff --git a/snow/uptime/manager.go b/snow/uptime/manager.go index a64b71ca62de..2a915da3fb6c 100644 --- a/snow/uptime/manager.go +++ b/snow/uptime/manager.go @@ -8,7 +8,6 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer/mockable" ) @@ -20,42 +19,41 @@ type Manager interface { } type Tracker interface { - StartTracking(nodeIDs []ids.NodeID, subnetID ids.ID) error - StopTracking(nodeIDs []ids.NodeID, subnetID ids.ID) error + StartTracking(nodeIDs []ids.NodeID) error + StopTracking(nodeIDs []ids.NodeID) error - Connect(nodeID ids.NodeID, subnetID ids.ID) error - IsConnected(nodeID ids.NodeID, subnetID ids.ID) bool + Connect(nodeID ids.NodeID) error + IsConnected(nodeID ids.NodeID) bool Disconnect(nodeID ids.NodeID) error } type Calculator interface { - CalculateUptime(nodeID ids.NodeID, subnetID ids.ID) (time.Duration, time.Time, error) - CalculateUptimePercent(nodeID ids.NodeID, subnetID ids.ID) (float64, error) + CalculateUptime(nodeID ids.NodeID) (time.Duration, time.Time, error) + CalculateUptimePercent(nodeID ids.NodeID) (float64, error) // CalculateUptimePercentFrom expects [startTime] to be truncated (floored) to the nearest second - CalculateUptimePercentFrom(nodeID ids.NodeID, subnetID ids.ID, startTime time.Time) (float64, error) + CalculateUptimePercentFrom(nodeID ids.NodeID, startTime time.Time) (float64, error) } type manager struct { // Used to get time. Useful for faking time during tests. clock *mockable.Clock - state State - connections map[ids.NodeID]map[ids.ID]time.Time // nodeID -> subnetID -> time - trackedSubnets set.Set[ids.ID] + state State + connections map[ids.NodeID]time.Time // nodeID -> time } func NewManager(state State, clk *mockable.Clock) Manager { return &manager{ clock: clk, state: state, - connections: make(map[ids.NodeID]map[ids.ID]time.Time), + connections: make(map[ids.NodeID]time.Time), } } -func (m *manager) StartTracking(nodeIDs []ids.NodeID, subnetID ids.ID) error { +func (m *manager) StartTracking(nodeIDs []ids.NodeID) error { now := m.clock.UnixTime() for _, nodeID := range nodeIDs { - upDuration, lastUpdated, err := m.state.GetUptime(nodeID, subnetID) + upDuration, lastUpdated, err := m.state.GetUptime(nodeID) if err != nil { return err } @@ -68,33 +66,30 @@ func (m *manager) StartTracking(nodeIDs []ids.NodeID, subnetID ids.ID) error { durationOffline := now.Sub(lastUpdated) newUpDuration := upDuration + durationOffline - if err := m.state.SetUptime(nodeID, subnetID, newUpDuration, now); err != nil { + if err := m.state.SetUptime(nodeID, newUpDuration, now); err != nil { return err } } - m.trackedSubnets.Add(subnetID) return nil } -func (m *manager) StopTracking(nodeIDs []ids.NodeID, subnetID ids.ID) error { +func (m *manager) StopTracking(nodeIDs []ids.NodeID) error { now := m.clock.UnixTime() for _, nodeID := range nodeIDs { - connectedSubnets := m.connections[nodeID] - // If the node is already connected to this subnet, then we can just + // If the node is already connected, then we can just // update the uptime in the state and remove the connection - if _, isConnected := connectedSubnets[subnetID]; isConnected { - if err := m.updateSubnetUptime(nodeID, subnetID); err != nil { - delete(connectedSubnets, subnetID) + if _, isConnected := m.connections[nodeID]; isConnected { + err := m.updateUptime(nodeID) + delete(m.connections, nodeID) + if err != nil { return err } - delete(connectedSubnets, subnetID) continue } - // if the node is not connected to this subnet, then we need to update - // the uptime in the state from the last time the node was connected to - // this subnet to now. - upDuration, lastUpdated, err := m.state.GetUptime(nodeID, subnetID) + // if the node is not connected, then we need to update + // the uptime in the state from the last time the node was connected to current time. + upDuration, lastUpdated, err := m.state.GetUptime(nodeID) if err != nil { return err } @@ -105,41 +100,34 @@ func (m *manager) StopTracking(nodeIDs []ids.NodeID, subnetID ids.ID) error { continue } - if err := m.state.SetUptime(nodeID, subnetID, upDuration, now); err != nil { + if err := m.state.SetUptime(nodeID, upDuration, now); err != nil { return err } } return nil } -func (m *manager) Connect(nodeID ids.NodeID, subnetID ids.ID) error { - subnetConnections, ok := m.connections[nodeID] - if !ok { - subnetConnections = make(map[ids.ID]time.Time) - m.connections[nodeID] = subnetConnections - } - subnetConnections[subnetID] = m.clock.UnixTime() +func (m *manager) Connect(nodeID ids.NodeID) error { + m.connections[nodeID] = m.clock.UnixTime() return nil } -func (m *manager) IsConnected(nodeID ids.NodeID, subnetID ids.ID) bool { - _, connected := m.connections[nodeID][subnetID] +func (m *manager) IsConnected(nodeID ids.NodeID) bool { + _, connected := m.connections[nodeID] return connected } func (m *manager) Disconnect(nodeID ids.NodeID) error { - // Update every subnet that this node was connected to - for subnetID := range m.connections[nodeID] { - if err := m.updateSubnetUptime(nodeID, subnetID); err != nil { - return err - } + 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 } -func (m *manager) CalculateUptime(nodeID ids.NodeID, subnetID ids.ID) (time.Duration, time.Time, error) { - upDuration, lastUpdated, err := m.state.GetUptime(nodeID, subnetID) +func (m *manager) CalculateUptime(nodeID ids.NodeID) (time.Duration, time.Time, error) { + upDuration, lastUpdated, err := m.state.GetUptime(nodeID) if err != nil { return 0, time.Time{}, err } @@ -151,13 +139,7 @@ func (m *manager) CalculateUptime(nodeID ids.NodeID, subnetID ids.ID) (time.Dura return upDuration, lastUpdated, nil } - if !m.trackedSubnets.Contains(subnetID) { - durationOffline := now.Sub(lastUpdated) - newUpDuration := upDuration + durationOffline - return newUpDuration, now, nil - } - - timeConnected, isConnected := m.connections[nodeID][subnetID] + timeConnected, isConnected := m.connections[nodeID] if !isConnected { return upDuration, now, nil } @@ -181,16 +163,16 @@ func (m *manager) CalculateUptime(nodeID ids.NodeID, subnetID ids.ID) (time.Dura return newUpDuration, now, nil } -func (m *manager) CalculateUptimePercent(nodeID ids.NodeID, subnetID ids.ID) (float64, error) { - startTime, err := m.state.GetStartTime(nodeID, subnetID) +func (m *manager) CalculateUptimePercent(nodeID ids.NodeID) (float64, error) { + startTime, err := m.state.GetStartTime(nodeID) if err != nil { return 0, err } - return m.CalculateUptimePercentFrom(nodeID, subnetID, startTime) + return m.CalculateUptimePercentFrom(nodeID, startTime) } -func (m *manager) CalculateUptimePercentFrom(nodeID ids.NodeID, subnetID ids.ID, startTime time.Time) (float64, error) { - upDuration, now, err := m.CalculateUptime(nodeID, subnetID) +func (m *manager) CalculateUptimePercentFrom(nodeID ids.NodeID, startTime time.Time) (float64, error) { + upDuration, now, err := m.CalculateUptime(nodeID) if err != nil { return 0, err } @@ -202,15 +184,10 @@ func (m *manager) CalculateUptimePercentFrom(nodeID ids.NodeID, subnetID ids.ID, return uptime, nil } -// updateSubnetUptime updates the subnet uptime of the node on the state by the amount -// of time that the node has been connected to the subnet. -func (m *manager) updateSubnetUptime(nodeID ids.NodeID, subnetID ids.ID) error { - // we're not tracking this subnet, skip updating it. - if !m.trackedSubnets.Contains(subnetID) { - return nil - } - - newDuration, newLastUpdated, err := m.CalculateUptime(nodeID, subnetID) +// updateUptime updates the uptime of the node on the state by the amount +// of time that the node has been connected. +func (m *manager) updateUptime(nodeID ids.NodeID) error { + newDuration, newLastUpdated, err := m.CalculateUptime(nodeID) if err == database.ErrNotFound { // If a non-validator disconnects, we don't care return nil @@ -219,5 +196,5 @@ func (m *manager) updateSubnetUptime(nodeID ids.NodeID, subnetID ids.ID) error { return err } - return m.state.SetUptime(nodeID, subnetID, newDuration, newLastUpdated) + return m.state.SetUptime(nodeID, newDuration, newLastUpdated) } diff --git a/snow/uptime/manager_test.go b/snow/uptime/manager_test.go index e04fcc3a9fbe..ef3de35070b9 100644 --- a/snow/uptime/manager_test.go +++ b/snow/uptime/manager_test.go @@ -21,11 +21,10 @@ func TestStartTracking(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() startTime := time.Now() s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) @@ -33,9 +32,9 @@ func TestStartTracking(t *testing.T) { currentTime := startTime.Add(time.Second) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err := up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(time.Second, duration) require.Equal(clk.UnixTime(), lastUpdated) @@ -45,12 +44,11 @@ func TestStartTrackingDBError(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() startTime := time.Now() s := NewTestState() s.dbWriteError = errTest - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) @@ -58,7 +56,7 @@ func TestStartTrackingDBError(t *testing.T) { currentTime := startTime.Add(time.Second) clk.Set(currentTime) - err := up.StartTracking([]ids.NodeID{nodeID0}, subnetID) + err := up.StartTracking([]ids.NodeID{nodeID0}) require.ErrorIs(err, errTest) } @@ -70,9 +68,8 @@ func TestStartTrackingNonValidator(t *testing.T) { up := NewManager(s, &clk) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() - err := up.StartTracking([]ids.NodeID{nodeID0}, subnetID) + err := up.StartTracking([]ids.NodeID{nodeID0}) require.ErrorIs(err, database.ErrNotFound) } @@ -80,11 +77,10 @@ func TestStartTrackingInThePast(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() startTime := time.Now() s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) @@ -92,9 +88,9 @@ func TestStartTrackingInThePast(t *testing.T) { currentTime := startTime.Add(-time.Second) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err := up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(time.Duration(0), duration) require.Equal(startTime.Truncate(time.Second), lastUpdated) @@ -104,29 +100,28 @@ func TestStopTrackingDecreasesUptime(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() currentTime := time.Now() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) currentTime = startTime.Add(time.Second) clk.Set(currentTime) - require.NoError(up.StopTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StopTracking([]ids.NodeID{nodeID0})) up = NewManager(s, &clk) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err := up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(time.Duration(0), duration) require.Equal(clk.UnixTime(), lastUpdated) @@ -136,31 +131,30 @@ func TestStopTrackingIncreasesUptime(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() currentTime := time.Now() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) - require.NoError(up.Connect(nodeID0, subnetID)) + require.NoError(up.Connect(nodeID0)) currentTime = startTime.Add(time.Second) clk.Set(currentTime) - require.NoError(up.StopTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StopTracking([]ids.NodeID{nodeID0})) up = NewManager(s, &clk) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err := up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(time.Second, duration) require.Equal(clk.UnixTime(), lastUpdated) @@ -170,15 +164,14 @@ func TestStopTrackingDisconnectedNonValidator(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() s := NewTestState() clk := mockable.Clock{} up := NewManager(s, &clk) - require.NoError(up.StartTracking(nil, subnetID)) + require.NoError(up.StartTracking(nil)) - err := up.StopTracking([]ids.NodeID{nodeID0}, subnetID) + err := up.StopTracking([]ids.NodeID{nodeID0}) require.ErrorIs(err, database.ErrNotFound) } @@ -186,20 +179,19 @@ func TestStopTrackingConnectedDBError(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() startTime := time.Now() s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) - require.NoError(up.StartTracking(nil, subnetID)) + require.NoError(up.StartTracking(nil)) - require.NoError(up.Connect(nodeID0, subnetID)) + require.NoError(up.Connect(nodeID0)) s.dbReadError = errTest - err := up.StopTracking([]ids.NodeID{nodeID0}, subnetID) + err := up.StopTracking([]ids.NodeID{nodeID0}) require.ErrorIs(err, errTest) } @@ -207,24 +199,23 @@ func TestStopTrackingNonConnectedPast(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() currentTime := time.Now() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) currentTime = currentTime.Add(-time.Second) clk.Set(currentTime) - require.NoError(up.StopTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StopTracking([]ids.NodeID{nodeID0})) - duration, lastUpdated, err := s.GetUptime(nodeID0, subnetID) + duration, lastUpdated, err := s.GetUptime(nodeID0) require.NoError(err) require.Equal(time.Duration(0), duration) require.Equal(startTime.Truncate(time.Second), lastUpdated) @@ -234,131 +225,104 @@ func TestStopTrackingNonConnectedDBError(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() currentTime := time.Now() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) currentTime = currentTime.Add(time.Second) clk.Set(currentTime) s.dbWriteError = errTest - err := up.StopTracking([]ids.NodeID{nodeID0}, subnetID) + err := up.StopTracking([]ids.NodeID{nodeID0}) require.ErrorIs(err, errTest) } func TestConnectAndDisconnect(t *testing.T) { - tests := []struct { - name string - subnetIDs []ids.ID - }{ - { - name: "Single Subnet", - subnetIDs: []ids.ID{ids.GenerateTestID()}, - }, - { - name: "Multiple Subnets", - subnetIDs: []ids.ID{ids.GenerateTestID(), ids.GenerateTestID()}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require := require.New(t) - - nodeID0 := ids.GenerateTestNodeID() - currentTime := time.Now() - startTime := currentTime - - s := NewTestState() - clk := mockable.Clock{} - up := NewManager(s, &clk) - clk.Set(currentTime) - - for _, subnetID := range tt.subnetIDs { - s.AddNode(nodeID0, subnetID, startTime) - - connected := up.IsConnected(nodeID0, subnetID) - require.False(connected) - - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) - - connected = up.IsConnected(nodeID0, subnetID) - require.False(connected) - - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) - require.NoError(err) - require.Equal(time.Duration(0), duration) - require.Equal(clk.UnixTime(), lastUpdated) - - require.NoError(up.Connect(nodeID0, subnetID)) - - connected = up.IsConnected(nodeID0, subnetID) - require.True(connected) - } - - currentTime = currentTime.Add(time.Second) - clk.Set(currentTime) - - for _, subnetID := range tt.subnetIDs { - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) - require.NoError(err) - require.Equal(time.Second, duration) - require.Equal(clk.UnixTime(), lastUpdated) - } - - require.NoError(up.Disconnect(nodeID0)) - - for _, subnetID := range tt.subnetIDs { - connected := up.IsConnected(nodeID0, subnetID) - require.False(connected) - } - - currentTime = currentTime.Add(time.Second) - clk.Set(currentTime) - - for _, subnetID := range tt.subnetIDs { - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) - require.NoError(err) - require.Equal(time.Second, duration) - require.Equal(clk.UnixTime(), lastUpdated) - } - }) - } + require := require.New(t) + + nodeID0 := ids.GenerateTestNodeID() + currentTime := time.Now() + startTime := currentTime + + s := NewTestState() + clk := mockable.Clock{} + up := NewManager(s, &clk) + clk.Set(currentTime) + + s.AddNode(nodeID0, startTime) + + connected := up.IsConnected(nodeID0) + require.False(connected) + + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) + + connected = up.IsConnected(nodeID0) + require.False(connected) + + duration, lastUpdated, err := up.CalculateUptime(nodeID0) + require.NoError(err) + require.Equal(time.Duration(0), duration) + require.Equal(clk.UnixTime(), lastUpdated) + + require.NoError(up.Connect(nodeID0)) + + connected = up.IsConnected(nodeID0) + require.True(connected) + + currentTime = currentTime.Add(time.Second) + clk.Set(currentTime) + + duration, lastUpdated, err = up.CalculateUptime(nodeID0) + require.NoError(err) + require.Equal(time.Second, duration) + require.Equal(clk.UnixTime(), lastUpdated) + + require.NoError(up.Disconnect(nodeID0)) + + connected = up.IsConnected(nodeID0) + require.False(connected) + + currentTime = currentTime.Add(time.Second) + clk.Set(currentTime) + + duration, lastUpdated, err = up.CalculateUptime(nodeID0) + require.NoError(err) + require.Equal(time.Second, duration) + require.Equal(clk.UnixTime(), lastUpdated) } func TestConnectAndDisconnectBeforeTracking(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() currentTime := time.Now() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) currentTime = currentTime.Add(time.Second) clk.Set(currentTime) - require.NoError(up.Connect(nodeID0, subnetID)) + require.NoError(up.Connect(nodeID0)) currentTime = currentTime.Add(time.Second) clk.Set(currentTime) require.NoError(up.Disconnect(nodeID0)) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err := up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(2*time.Second, duration) require.Equal(clk.UnixTime(), lastUpdated) @@ -368,33 +332,32 @@ func TestUnrelatedNodeDisconnect(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() nodeID1 := ids.GenerateTestNodeID() currentTime := time.Now() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err := up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(time.Duration(0), duration) require.Equal(clk.UnixTime(), lastUpdated) - require.NoError(up.Connect(nodeID0, subnetID)) + require.NoError(up.Connect(nodeID0)) - require.NoError(up.Connect(nodeID1, subnetID)) + require.NoError(up.Connect(nodeID1)) currentTime = currentTime.Add(time.Second) clk.Set(currentTime) - duration, lastUpdated, err = up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err = up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(time.Second, duration) require.Equal(clk.UnixTime(), lastUpdated) @@ -404,7 +367,7 @@ func TestUnrelatedNodeDisconnect(t *testing.T) { currentTime = currentTime.Add(time.Second) clk.Set(currentTime) - duration, lastUpdated, err = up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err = up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(2*time.Second, duration) require.Equal(clk.UnixTime(), lastUpdated) @@ -414,11 +377,10 @@ func TestCalculateUptimeWhenNeverTracked(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() startTime := time.Now() s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) @@ -426,12 +388,12 @@ func TestCalculateUptimeWhenNeverTracked(t *testing.T) { currentTime := startTime.Add(time.Second) clk.Set(currentTime) - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err := up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(time.Second, duration) require.Equal(clk.UnixTime(), lastUpdated) - uptime, err := up.CalculateUptimePercentFrom(nodeID0, subnetID, startTime.Truncate(time.Second)) + uptime, err := up.CalculateUptimePercentFrom(nodeID0, startTime.Truncate(time.Second)) require.NoError(err) require.Equal(float64(1), uptime) } @@ -440,7 +402,6 @@ func TestCalculateUptimeWhenNeverConnected(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() startTime := time.Now() s := NewTestState() @@ -448,19 +409,19 @@ func TestCalculateUptimeWhenNeverConnected(t *testing.T) { clk := mockable.Clock{} up := NewManager(s, &clk) - require.NoError(up.StartTracking([]ids.NodeID{}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{})) - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) currentTime := startTime.Add(time.Second) clk.Set(currentTime) - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err := up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(time.Duration(0), duration) require.Equal(clk.UnixTime(), lastUpdated) - uptime, err := up.CalculateUptimePercentFrom(nodeID0, subnetID, startTime) + uptime, err := up.CalculateUptimePercentFrom(nodeID0, startTime) require.NoError(err) require.Equal(float64(0), uptime) } @@ -469,28 +430,27 @@ func TestCalculateUptimeWhenConnectedBeforeTracking(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() currentTime := time.Now() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) clk.Set(currentTime) - require.NoError(up.Connect(nodeID0, subnetID)) + require.NoError(up.Connect(nodeID0)) currentTime = currentTime.Add(time.Second) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) currentTime = currentTime.Add(time.Second) clk.Set(currentTime) - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err := up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(2*time.Second, duration) require.Equal(clk.UnixTime(), lastUpdated) @@ -500,28 +460,27 @@ func TestCalculateUptimeWhenConnectedInFuture(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() currentTime := time.Now() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) currentTime = currentTime.Add(2 * time.Second) clk.Set(currentTime) - require.NoError(up.Connect(nodeID0, subnetID)) + require.NoError(up.Connect(nodeID0)) currentTime = currentTime.Add(-time.Second) clk.Set(currentTime) - duration, lastUpdated, err := up.CalculateUptime(nodeID0, subnetID) + duration, lastUpdated, err := up.CalculateUptime(nodeID0) require.NoError(err) require.Equal(time.Duration(0), duration) require.Equal(clk.UnixTime(), lastUpdated) @@ -531,7 +490,6 @@ func TestCalculateUptimeNonValidator(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() startTime := time.Now() s := NewTestState() @@ -539,7 +497,7 @@ func TestCalculateUptimeNonValidator(t *testing.T) { clk := mockable.Clock{} up := NewManager(s, &clk) - _, err := up.CalculateUptimePercentFrom(nodeID0, subnetID, startTime) + _, err := up.CalculateUptimePercentFrom(nodeID0, startTime) require.ErrorIs(err, database.ErrNotFound) } @@ -547,18 +505,17 @@ func TestCalculateUptimePercentageDivBy0(t *testing.T) { require := require.New(t) nodeID0 := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() currentTime := time.Now() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) clk.Set(currentTime) - uptime, err := up.CalculateUptimePercentFrom(nodeID0, subnetID, startTime.Truncate(time.Second)) + uptime, err := up.CalculateUptimePercentFrom(nodeID0, startTime.Truncate(time.Second)) require.NoError(err) require.Equal(float64(1), uptime) } @@ -568,21 +525,20 @@ func TestCalculateUptimePercentage(t *testing.T) { nodeID0 := ids.GenerateTestNodeID() currentTime := time.Now() - subnetID := ids.GenerateTestID() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) currentTime = currentTime.Add(time.Second) clk.Set(currentTime) - uptime, err := up.CalculateUptimePercentFrom(nodeID0, subnetID, startTime.Truncate(time.Second)) + uptime, err := up.CalculateUptimePercentFrom(nodeID0, startTime.Truncate(time.Second)) require.NoError(err) require.Equal(float64(0), uptime) } @@ -592,24 +548,23 @@ func TestStopTrackingUnixTimeRegression(t *testing.T) { nodeID0 := ids.GenerateTestNodeID() currentTime := time.Now() - subnetID := ids.GenerateTestID() startTime := currentTime s := NewTestState() - s.AddNode(nodeID0, subnetID, startTime) + s.AddNode(nodeID0, startTime) clk := mockable.Clock{} up := NewManager(s, &clk) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) - require.NoError(up.Connect(nodeID0, subnetID)) + require.NoError(up.Connect(nodeID0)) currentTime = startTime.Add(time.Second) clk.Set(currentTime) - require.NoError(up.StopTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StopTracking([]ids.NodeID{nodeID0})) currentTime = startTime.Add(time.Second) clk.Set(currentTime) @@ -619,14 +574,14 @@ func TestStopTrackingUnixTimeRegression(t *testing.T) { currentTime = startTime.Add(time.Second) clk.Set(currentTime) - require.NoError(up.StartTracking([]ids.NodeID{nodeID0}, subnetID)) + require.NoError(up.StartTracking([]ids.NodeID{nodeID0})) - require.NoError(up.Connect(nodeID0, subnetID)) + require.NoError(up.Connect(nodeID0)) currentTime = startTime.Add(time.Second) clk.Set(currentTime) - perc, err := up.CalculateUptimePercent(nodeID0, subnetID) + perc, err := up.CalculateUptimePercent(nodeID0) require.NoError(err) require.GreaterOrEqual(float64(1), perc) } diff --git a/snow/uptime/no_op_calculator.go b/snow/uptime/no_op_calculator.go index fb308f4f6030..2f715d799e70 100644 --- a/snow/uptime/no_op_calculator.go +++ b/snow/uptime/no_op_calculator.go @@ -13,14 +13,14 @@ var NoOpCalculator Calculator = noOpCalculator{} type noOpCalculator struct{} -func (noOpCalculator) CalculateUptime(ids.NodeID, ids.ID) (time.Duration, time.Time, error) { +func (noOpCalculator) CalculateUptime(ids.NodeID) (time.Duration, time.Time, error) { return 0, time.Time{}, nil } -func (noOpCalculator) CalculateUptimePercent(ids.NodeID, ids.ID) (float64, error) { +func (noOpCalculator) CalculateUptimePercent(ids.NodeID) (float64, error) { return 0, nil } -func (noOpCalculator) CalculateUptimePercentFrom(ids.NodeID, ids.ID, time.Time) (float64, error) { +func (noOpCalculator) CalculateUptimePercentFrom(ids.NodeID, time.Time) (float64, error) { return 0, nil } diff --git a/snow/uptime/state.go b/snow/uptime/state.go index f9edeb76a3ee..59a720c897b2 100644 --- a/snow/uptime/state.go +++ b/snow/uptime/state.go @@ -10,34 +10,25 @@ import ( ) type State interface { - // GetUptime returns [upDuration] and [lastUpdated] of [nodeID] on - // [subnetID]. - // Returns [database.ErrNotFound] if [nodeID] isn't currently a validator of - // the subnet. + // GetUptime returns [upDuration] and [lastUpdated] of [nodeID] + // Returns [database.ErrNotFound] if [nodeID] isn't currently a validator. GetUptime( nodeID ids.NodeID, - subnetID ids.ID, ) (upDuration time.Duration, lastUpdated time.Time, err error) - // SetUptime updates [upDuration] and [lastUpdated] of [nodeID] on - // [subnetID]. - // Returns [database.ErrNotFound] if [nodeID] isn't currently a validator of - // the subnet. + // SetUptime updates [upDuration] and [lastUpdated] of [nodeID] + // Returns [database.ErrNotFound] if [nodeID] isn't currently a validator // Invariant: expects [lastUpdated] to be truncated (floored) to the nearest // second. SetUptime( nodeID ids.NodeID, - subnetID ids.ID, upDuration time.Duration, lastUpdated time.Time, ) error - // GetStartTime returns the time that [nodeID] started validating - // [subnetID]. - // Returns [database.ErrNotFound] if [nodeID] isn't currently a validator of - // the subnet. + // GetStartTime returns the time that [nodeID] started validating. + // Returns [database.ErrNotFound] if [nodeID] isn't currently a validator. GetStartTime( nodeID ids.NodeID, - subnetID ids.ID, ) (startTime time.Time, err error) } diff --git a/snow/uptime/test_state.go b/snow/uptime/test_state.go index 23879b5cb3a9..213b591bc71c 100644 --- a/snow/uptime/test_state.go +++ b/snow/uptime/test_state.go @@ -21,38 +21,33 @@ type uptime struct { type TestState struct { dbReadError error dbWriteError error - nodes map[ids.NodeID]map[ids.ID]*uptime + nodes map[ids.NodeID]*uptime } func NewTestState() *TestState { return &TestState{ - nodes: make(map[ids.NodeID]map[ids.ID]*uptime), + nodes: make(map[ids.NodeID]*uptime), } } -func (s *TestState) AddNode(nodeID ids.NodeID, subnetID ids.ID, startTime time.Time) { - subnetUptimes, ok := s.nodes[nodeID] - if !ok { - subnetUptimes = make(map[ids.ID]*uptime) - s.nodes[nodeID] = subnetUptimes - } +func (s *TestState) AddNode(nodeID ids.NodeID, startTime time.Time) { st := time.Unix(startTime.Unix(), 0) - subnetUptimes[subnetID] = &uptime{ + s.nodes[nodeID] = &uptime{ lastUpdated: st, startTime: st, } } -func (s *TestState) GetUptime(nodeID ids.NodeID, subnetID ids.ID) (time.Duration, time.Time, error) { - up, exists := s.nodes[nodeID][subnetID] +func (s *TestState) GetUptime(nodeID ids.NodeID) (time.Duration, time.Time, error) { + up, exists := s.nodes[nodeID] if !exists { return 0, time.Time{}, database.ErrNotFound } return up.upDuration, up.lastUpdated, s.dbReadError } -func (s *TestState) SetUptime(nodeID ids.NodeID, subnetID ids.ID, upDuration time.Duration, lastUpdated time.Time) error { - up, exists := s.nodes[nodeID][subnetID] +func (s *TestState) SetUptime(nodeID ids.NodeID, upDuration time.Duration, lastUpdated time.Time) error { + up, exists := s.nodes[nodeID] if !exists { return database.ErrNotFound } @@ -61,8 +56,8 @@ func (s *TestState) SetUptime(nodeID ids.NodeID, subnetID ids.ID, upDuration tim return s.dbWriteError } -func (s *TestState) GetStartTime(nodeID ids.NodeID, subnetID ids.ID) (time.Time, error) { - up, exists := s.nodes[nodeID][subnetID] +func (s *TestState) GetStartTime(nodeID ids.NodeID) (time.Time, error) { + up, exists := s.nodes[nodeID] if !exists { return time.Time{}, database.ErrNotFound } From 733d5fd3370d3c6ad736df488404cd5c3b024508 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 25 Jul 2024 21:04:58 +0300 Subject: [PATCH 02/21] remove subnet uptimes from platforvm --- vms/platformvm/api/static_service.go | 4 +- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/block_test.go | 6 +-- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/block/executor/options.go | 2 - .../block/executor/proposal_block_test.go | 4 +- .../client_permissionless_validator.go | 2 +- vms/platformvm/service.go | 45 ++++++++++--------- vms/platformvm/state/mock_state.go | 24 +++++----- vms/platformvm/state/state.go | 12 ++++- vms/platformvm/state/state_test.go | 33 +------------- vms/platformvm/txs/executor/helpers_test.go | 4 +- vms/platformvm/vm.go | 20 ++------- 13 files changed, 63 insertions(+), 97 deletions(-) diff --git a/vms/platformvm/api/static_service.go b/vms/platformvm/api/static_service.go index 418b447114c7..326e5fb5e8a8 100644 --- a/vms/platformvm/api/static_service.go +++ b/vms/platformvm/api/static_service.go @@ -121,7 +121,7 @@ type PermissionlessValidator struct { DelegationFee json.Float32 `json:"delegationFee"` ExactDelegationFee *json.Uint32 `json:"exactDelegationFee,omitempty"` Uptime *json.Float32 `json:"uptime,omitempty"` - Connected bool `json:"connected"` + Connected *bool `json:"connected,omitempty"` Staked []UTXO `json:"staked,omitempty"` Signer *signer.ProofOfPossession `json:"signer,omitempty"` @@ -145,7 +145,7 @@ type GenesisPermissionlessValidator struct { type PermissionedValidator struct { Staker // The owner the staking reward, if applicable, will go to - Connected bool `json:"connected"` + Connected *bool `json:"connected,omitempty"` Uptime *json.Float32 `json:"uptime,omitempty"` } diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index df2d620c6eed..b492a8fdac13 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -221,7 +221,7 @@ func newEnvironment(t *testing.T, f fork) *environment { //nolint:unparam if res.isBootstrapped.Get() { validatorIDs := res.config.Validators.GetValidatorIDs(constants.PrimaryNetworkID) - require.NoError(res.uptimes.StopTracking(validatorIDs, constants.PrimaryNetworkID)) + require.NoError(res.uptimes.StopTracking(validatorIDs)) require.NoError(res.state.Commit()) } diff --git a/vms/platformvm/block/executor/block_test.go b/vms/platformvm/block/executor/block_test.go index dfccc413e29b..bf020e164629 100644 --- a/vms/platformvm/block/executor/block_test.go +++ b/vms/platformvm/block/executor/block_test.go @@ -287,7 +287,7 @@ func TestBlockOptions(t *testing.T) { state.EXPECT().GetCurrentValidator(constants.PrimaryNetworkID, nodeID).Return(staker, nil) uptimes := uptime.NewMockCalculator(ctrl) - uptimes.EXPECT().CalculateUptimePercentFrom(nodeID, constants.PrimaryNetworkID, primaryNetworkValidatorStartTime).Return(0.0, database.ErrNotFound) + uptimes.EXPECT().CalculateUptimePercentFrom(nodeID, primaryNetworkValidatorStartTime).Return(0.0, database.ErrNotFound) manager := &manager{ backend: &backend{ @@ -405,7 +405,7 @@ func TestBlockOptions(t *testing.T) { state.EXPECT().GetSubnetTransformation(subnetID).Return(transformSubnetTx, nil) uptimes := uptime.NewMockCalculator(ctrl) - uptimes.EXPECT().CalculateUptimePercentFrom(nodeID, constants.PrimaryNetworkID, primaryNetworkValidatorStartTime).Return(.5, nil) + uptimes.EXPECT().CalculateUptimePercentFrom(nodeID, primaryNetworkValidatorStartTime).Return(.5, nil) manager := &manager{ backend: &backend{ @@ -467,7 +467,7 @@ func TestBlockOptions(t *testing.T) { state.EXPECT().GetSubnetTransformation(subnetID).Return(transformSubnetTx, nil) uptimes := uptime.NewMockCalculator(ctrl) - uptimes.EXPECT().CalculateUptimePercentFrom(nodeID, constants.PrimaryNetworkID, primaryNetworkValidatorStartTime).Return(.5, nil) + uptimes.EXPECT().CalculateUptimePercentFrom(nodeID, primaryNetworkValidatorStartTime).Return(.5, nil) manager := &manager{ backend: &backend{ diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 80dca6745fcc..b23a34b8264b 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -237,7 +237,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f fork) *environment if res.isBootstrapped.Get() { validatorIDs := res.config.Validators.GetValidatorIDs(constants.PrimaryNetworkID) - require.NoError(res.uptimes.StopTracking(validatorIDs, constants.PrimaryNetworkID)) + require.NoError(res.uptimes.StopTracking(validatorIDs)) require.NoError(res.state.Commit()) } diff --git a/vms/platformvm/block/executor/options.go b/vms/platformvm/block/executor/options.go index f2071c8e13cb..7487ea449335 100644 --- a/vms/platformvm/block/executor/options.go +++ b/vms/platformvm/block/executor/options.go @@ -175,10 +175,8 @@ func (o *options) prefersCommit(tx *txs.Tx) (bool, error) { expectedUptimePercentage = float64(transformSubnet.UptimeRequirement) / reward.PercentDenominator } - // TODO: calculate subnet uptimes uptime, err := o.uptimes.CalculateUptimePercentFrom( nodeID, - constants.PrimaryNetworkID, primaryNetworkValidator.StartTime, ) if err != nil { diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index f0037754d06a..0b914aff4c98 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -105,7 +105,7 @@ func TestApricotProposalBlockTimeVerification(t *testing.T) { onParentAccept.EXPECT().GetCurrentSupply(constants.PrimaryNetworkID).Return(uint64(1000), nil).AnyTimes() onParentAccept.EXPECT().GetDelegateeReward(constants.PrimaryNetworkID, utx.NodeID()).Return(uint64(0), nil).AnyTimes() - env.mockedState.EXPECT().GetUptime(gomock.Any(), constants.PrimaryNetworkID).Return( + env.mockedState.EXPECT().GetUptime(gomock.Any()).Return( time.Microsecond, /*upDuration*/ time.Time{}, /*lastUpdated*/ nil, /*err*/ @@ -219,7 +219,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { pendingStakersIt.EXPECT().Release().AnyTimes() onParentAccept.EXPECT().GetPendingStakerIterator().Return(pendingStakersIt, nil).AnyTimes() - env.mockedState.EXPECT().GetUptime(gomock.Any(), gomock.Any()).Return( + env.mockedState.EXPECT().GetUptime(gomock.Any).Return( time.Microsecond, /*upDuration*/ time.Time{}, /*lastUpdated*/ nil, /*err*/ diff --git a/vms/platformvm/client_permissionless_validator.go b/vms/platformvm/client_permissionless_validator.go index 3974f770658d..e9cdfa6ccbeb 100644 --- a/vms/platformvm/client_permissionless_validator.go +++ b/vms/platformvm/client_permissionless_validator.go @@ -133,7 +133,7 @@ func getClientPermissionlessValidators(validatorsSliceIntf []interface{}) ([]Cli AccruedDelegateeReward: (*uint64)(apiValidator.AccruedDelegateeReward), DelegationFee: float32(apiValidator.DelegationFee), Uptime: (*float32)(apiValidator.Uptime), - Connected: &apiValidator.Connected, + Connected: apiValidator.Connected, Signer: apiValidator.Signer, DelegatorCount: (*uint64)(apiValidator.DelegatorCount), DelegatorWeight: (*uint64)(apiValidator.DelegatorWeight), diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 0299192b6677..1bb82e1a1203 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -830,13 +830,20 @@ func (s *Service) GetCurrentValidators(_ *http.Request, args *GetCurrentValidato shares := attr.shares delegationFee := avajson.Float32(100 * float32(shares) / float32(reward.PercentDenominator)) - - uptime, err := s.getAPIUptime(currentStaker) - if err != nil { - return err + var uptime *avajson.Float32 + var connected *bool + // Only calculate uptime for primary network validators + // TODO: decide whether we want to keep connected for subnet validators + // it should be available at this point + if args.SubnetID == constants.PrimaryNetworkID { + currentUptime, isConnected, err := s.getAPIUptime(currentStaker) + if err != nil { + return err + } + connected = &isConnected + uptime = ¤tUptime } - connected := s.vm.uptimeManager.IsConnected(nodeID, args.SubnetID) var ( validationRewardOwner *platformapi.Owner delegationRewardOwner *platformapi.Owner @@ -896,15 +903,8 @@ func (s *Service) GetCurrentValidators(_ *http.Request, args *GetCurrentValidato vdrToDelegators[delegator.NodeID] = append(vdrToDelegators[delegator.NodeID], delegator) case txs.SubnetPermissionedValidatorCurrentPriority: - uptime, err := s.getAPIUptime(currentStaker) - if err != nil { - return err - } - connected := s.vm.uptimeManager.IsConnected(nodeID, args.SubnetID) reply.Validators = append(reply.Validators, platformapi.PermissionedValidator{ - Staker: apiStaker, - Connected: connected, - Uptime: uptime, + Staker: apiStaker, }) default: @@ -1828,20 +1828,21 @@ func (s *Service) GetBlockByHeight(_ *http.Request, args *api.GetBlockByHeightAr return err } -func (s *Service) getAPIUptime(staker *state.Staker) (*avajson.Float32, error) { - // Only report uptimes that we have been actively tracking. - if constants.PrimaryNetworkID != staker.SubnetID && !s.vm.TrackedSubnets.Contains(staker.SubnetID) { - return nil, nil - } - - rawUptime, err := s.vm.uptimeManager.CalculateUptimePercentFrom(staker.NodeID, staker.SubnetID, staker.StartTime) +// Returns: +// 1) the uptime of a validator in the API format +// 2) whether the validator is currently connected +// 3) an error if one occurred +func (s *Service) getAPIUptime(staker *state.Staker) (avajson.Float32, bool, error) { + rawUptime, err := s.vm.uptimeManager.CalculateUptimePercentFrom(staker.NodeID, staker.StartTime) if err != nil { - return nil, err + return 0, false, err } + connected := s.vm.uptimeManager.IsConnected(staker.NodeID) + // Transform this to a percentage (0-100) to make it consistent // with observedUptime in info.peers API uptime := avajson.Float32(rawUptime * 100) - return &uptime, nil + return uptime, connected, nil } func (s *Service) getAPIOwner(owner *secp256k1fx.OutputOwners) (*platformapi.Owner, error) { diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index c1321567e6a9..36087cd934e6 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -1381,18 +1381,18 @@ func (mr *MockStateMockRecorder) GetRewardUTXOs(arg0 any) *gomock.Call { } // GetStartTime mocks base method. -func (m *MockState) GetStartTime(arg0 ids.NodeID, arg1 ids.ID) (time.Time, error) { +func (m *MockState) GetStartTime(arg0 ids.NodeID) (time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStartTime", arg0, arg1) + ret := m.ctrl.Call(m, "GetStartTime", arg0) ret0, _ := ret[0].(time.Time) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStartTime indicates an expected call of GetStartTime. -func (mr *MockStateMockRecorder) GetStartTime(arg0, arg1 any) *gomock.Call { +func (mr *MockStateMockRecorder) GetStartTime(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStartTime", reflect.TypeOf((*MockState)(nil).GetStartTime), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStartTime", reflect.TypeOf((*MockState)(nil).GetStartTime), arg0) } // GetStatelessBlock mocks base method. @@ -1501,9 +1501,9 @@ func (mr *MockStateMockRecorder) GetUTXO(arg0 any) *gomock.Call { } // GetUptime mocks base method. -func (m *MockState) GetUptime(arg0 ids.NodeID, arg1 ids.ID) (time.Duration, time.Time, error) { +func (m *MockState) GetUptime(arg0 ids.NodeID) (time.Duration, time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUptime", arg0, arg1) + ret := m.ctrl.Call(m, "GetUptime", arg0) ret0, _ := ret[0].(time.Duration) ret1, _ := ret[1].(time.Time) ret2, _ := ret[2].(error) @@ -1511,9 +1511,9 @@ func (m *MockState) GetUptime(arg0 ids.NodeID, arg1 ids.ID) (time.Duration, time } // GetUptime indicates an expected call of GetUptime. -func (mr *MockStateMockRecorder) GetUptime(arg0, arg1 any) *gomock.Call { +func (mr *MockStateMockRecorder) GetUptime(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUptime", reflect.TypeOf((*MockState)(nil).GetUptime), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUptime", reflect.TypeOf((*MockState)(nil).GetUptime), arg0) } // PutCurrentDelegator mocks base method. @@ -1653,17 +1653,17 @@ func (mr *MockStateMockRecorder) SetTimestamp(arg0 any) *gomock.Call { } // SetUptime mocks base method. -func (m *MockState) SetUptime(arg0 ids.NodeID, arg1 ids.ID, arg2 time.Duration, arg3 time.Time) error { +func (m *MockState) SetUptime(arg0 ids.NodeID, arg1 time.Duration, arg2 time.Time) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetUptime", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "SetUptime", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // SetUptime indicates an expected call of SetUptime. -func (mr *MockStateMockRecorder) SetUptime(arg0, arg1, arg2, arg3 any) *gomock.Call { +func (mr *MockStateMockRecorder) SetUptime(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetUptime", reflect.TypeOf((*MockState)(nil).SetUptime), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetUptime", reflect.TypeOf((*MockState)(nil).SetUptime), arg0, arg1, arg2) } // UTXOIDs mocks base method. diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index a6266a480858..d8e9ed3ea3bc 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -989,8 +989,8 @@ func (s *state) DeleteUTXO(utxoID ids.ID) { s.modifiedUTXOs[utxoID] = nil } -func (s *state) GetStartTime(nodeID ids.NodeID, subnetID ids.ID) (time.Time, error) { - staker, err := s.currentStakers.GetValidator(subnetID, nodeID) +func (s *state) GetStartTime(nodeID ids.NodeID) (time.Time, error) { + staker, err := s.currentStakers.GetValidator(constants.PrimaryNetworkID, nodeID) if err != nil { return time.Time{}, err } @@ -2440,3 +2440,11 @@ func (s *state) ReindexBlocks(lock sync.Locker, log logging.Logger) error { return s.Commit() } + +func (s *state) GetUptime(vdrID ids.NodeID) (time.Duration, time.Time, error) { + return s.validatorState.GetUptime(vdrID, constants.PrimaryNetworkID) +} + +func (s *state) SetUptime(vdrID ids.NodeID, upDuration time.Duration, lastUpdated time.Time) error { + return s.validatorState.SetUptime(vdrID, constants.PrimaryNetworkID, upDuration, lastUpdated) +} diff --git a/vms/platformvm/state/state_test.go b/vms/platformvm/state/state_test.go index c6241ddc8cc4..517981552042 100644 --- a/vms/platformvm/state/state_test.go +++ b/vms/platformvm/state/state_test.go @@ -106,9 +106,6 @@ func TestPersistStakers(t *testing.T) { // with the right weight and showing the BLS key checkValidatorsSet func(*require.Assertions, *state, *Staker) - // Check that node duly track stakers uptimes - checkValidatorUptimes func(*require.Assertions, *state, *Staker) - // Check whether weight/bls keys diffs are duly stored checkDiffs func(*require.Assertions, *state, *Staker, uint64) }{ @@ -159,12 +156,6 @@ func TestPersistStakers(t *testing.T) { Weight: staker.Weight, }, valOut) }, - checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { - upDuration, lastUpdated, err := s.GetUptime(staker.NodeID, staker.SubnetID) - r.NoError(err) - r.Equal(upDuration, time.Duration(0)) - r.Equal(lastUpdated, staker.StartTime) - }, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { weightDiffBytes, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) r.NoError(err) @@ -261,7 +252,6 @@ func TestPersistStakers(t *testing.T) { r.Equal(valOut.NodeID, staker.NodeID) r.Equal(valOut.Weight, val.Weight+staker.Weight) }, - checkValidatorUptimes: func(*require.Assertions, *state, *Staker) {}, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { // validator's weight must increase of delegator's weight amount weightDiffBytes, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) @@ -313,11 +303,6 @@ func TestPersistStakers(t *testing.T) { valsMap := s.cfg.Validators.GetMap(staker.SubnetID) r.Empty(valsMap) }, - checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { - // pending validators uptime is not tracked - _, _, err := s.GetUptime(staker.NodeID, staker.SubnetID) - r.ErrorIs(err, database.ErrNotFound) - }, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { // pending validators weight diff and bls diffs are not stored _, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) @@ -388,8 +373,7 @@ func TestPersistStakers(t *testing.T) { valsMap := s.cfg.Validators.GetMap(staker.SubnetID) r.Empty(valsMap) }, - checkValidatorUptimes: func(*require.Assertions, *state, *Staker) {}, - checkDiffs: func(*require.Assertions, *state, *Staker, uint64) {}, + checkDiffs: func(*require.Assertions, *state, *Staker, uint64) {}, }, "delete current validator": { storeStaker: func(r *require.Assertions, subnetID ids.ID, s *state) *Staker { @@ -435,11 +419,6 @@ func TestPersistStakers(t *testing.T) { valsMap := s.cfg.Validators.GetMap(staker.SubnetID) r.Empty(valsMap) }, - checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { - // uptimes of delete validators are dropped - _, _, err := s.GetUptime(staker.NodeID, staker.SubnetID) - r.ErrorIs(err, database.ErrNotFound) - }, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { weightDiffBytes, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) r.NoError(err) @@ -536,7 +515,6 @@ func TestPersistStakers(t *testing.T) { r.Equal(valOut.NodeID, staker.NodeID) r.Equal(valOut.Weight, val.Weight) }, - checkValidatorUptimes: func(*require.Assertions, *state, *Staker) {}, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { // validator's weight must decrease of delegator's weight amount weightDiffBytes, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) @@ -590,10 +568,6 @@ func TestPersistStakers(t *testing.T) { valsMap := s.cfg.Validators.GetMap(staker.SubnetID) r.Empty(valsMap) }, - checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { - _, _, err := s.GetUptime(staker.NodeID, staker.SubnetID) - r.ErrorIs(err, database.ErrNotFound) - }, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { _, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) r.ErrorIs(err, database.ErrNotFound) @@ -661,8 +635,7 @@ func TestPersistStakers(t *testing.T) { valsMap := s.cfg.Validators.GetMap(staker.SubnetID) r.Empty(valsMap) }, - checkValidatorUptimes: func(*require.Assertions, *state, *Staker) {}, - checkDiffs: func(*require.Assertions, *state, *Staker, uint64) {}, + checkDiffs: func(*require.Assertions, *state, *Staker, uint64) {}, }, } @@ -680,7 +653,6 @@ func TestPersistStakers(t *testing.T) { // check all relevant data are stored test.checkStakerInState(require, state, staker) test.checkValidatorsSet(require, state, staker) - test.checkValidatorUptimes(require, state, staker) test.checkDiffs(require, state, staker, 0 /*height*/) // rebuild the state @@ -694,7 +666,6 @@ func TestPersistStakers(t *testing.T) { // check again that all relevant data are still available in rebuilt state test.checkStakerInState(require, state, staker) test.checkValidatorsSet(require, state, staker) - test.checkValidatorUptimes(require, state, staker) test.checkDiffs(require, state, staker, 0 /*height*/) }) } diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index a3b3033df44a..69321d539a65 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -187,12 +187,12 @@ func newEnvironment(t *testing.T, f fork) *environment { if env.isBootstrapped.Get() { validatorIDs := env.config.Validators.GetValidatorIDs(constants.PrimaryNetworkID) - require.NoError(env.uptimes.StopTracking(validatorIDs, constants.PrimaryNetworkID)) + require.NoError(env.uptimes.StopTracking(validatorIDs)) for subnetID := range env.config.TrackedSubnets { validatorIDs := env.config.Validators.GetValidatorIDs(subnetID) - require.NoError(env.uptimes.StopTracking(validatorIDs, subnetID)) + require.NoError(env.uptimes.StopTracking(validatorIDs)) } env.state.SetHeight(math.MaxUint64) require.NoError(env.state.Commit()) diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 203688d23136..6690488ef291 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -349,7 +349,7 @@ func (vm *VM) onNormalOperationsStarted() error { } primaryVdrIDs := vm.Validators.GetValidatorIDs(constants.PrimaryNetworkID) - if err := vm.uptimeManager.StartTracking(primaryVdrIDs, constants.PrimaryNetworkID); err != nil { + if err := vm.uptimeManager.StartTracking(primaryVdrIDs); err != nil { return err } @@ -357,11 +357,6 @@ func (vm *VM) onNormalOperationsStarted() error { vm.Validators.RegisterSetCallbackListener(constants.PrimaryNetworkID, vl) for subnetID := range vm.TrackedSubnets { - vdrIDs := vm.Validators.GetValidatorIDs(subnetID) - if err := vm.uptimeManager.StartTracking(vdrIDs, subnetID); err != nil { - return err - } - vl := validators.NewLogger(vm.ctx.Log, subnetID, vm.ctx.NodeID) vm.Validators.RegisterSetCallbackListener(subnetID, vl) } @@ -397,17 +392,10 @@ func (vm *VM) Shutdown(context.Context) error { if vm.bootstrapped.Get() { primaryVdrIDs := vm.Validators.GetValidatorIDs(constants.PrimaryNetworkID) - if err := vm.uptimeManager.StopTracking(primaryVdrIDs, constants.PrimaryNetworkID); err != nil { + if err := vm.uptimeManager.StopTracking(primaryVdrIDs); err != nil { return err } - for subnetID := range vm.TrackedSubnets { - vdrIDs := vm.Validators.GetValidatorIDs(subnetID) - if err := vm.uptimeManager.StopTracking(vdrIDs, subnetID); err != nil { - return err - } - } - if err := vm.state.Commit(); err != nil { return err } @@ -473,14 +461,14 @@ func (vm *VM) CreateHandlers(context.Context) (map[string]http.Handler, error) { } func (vm *VM) Connected(ctx context.Context, nodeID ids.NodeID, version *version.Application) error { - if err := vm.uptimeManager.Connect(nodeID, constants.PrimaryNetworkID); err != nil { + if err := vm.uptimeManager.Connect(nodeID); err != nil { return err } return vm.Network.Connected(ctx, nodeID, version) } func (vm *VM) ConnectedSubnet(_ context.Context, nodeID ids.NodeID, subnetID ids.ID) error { - return vm.uptimeManager.Connect(nodeID, subnetID) + return nil } func (vm *VM) Disconnected(ctx context.Context, nodeID ids.NodeID) error { From 10d8e868affdac0a0f5319718975a74d817ccc7e Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 25 Jul 2024 21:05:35 +0300 Subject: [PATCH 03/21] remove subnet uptimes from p2p --- message/messages_test.go | 11 +- message/mock_outbound_message_builder.go | 8 +- message/outbound_msg_builder.go | 5 +- network/metrics.go | 52 +- network/network.go | 39 +- network/peer/info.go | 21 +- network/peer/message_queue_test.go | 11 +- network/peer/peer.go | 136 +--- network/peer/peer_test.go | 126 +--- network/peer/set_test.go | 22 +- proto/p2p/p2p.proto | 11 +- proto/pb/p2p/p2p.pb.go | 833 ++++++++++------------- 12 files changed, 469 insertions(+), 806 deletions(-) diff --git a/message/messages_test.go b/message/messages_test.go index 8314fa805e38..7d4ace78b5bc 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -54,7 +54,7 @@ func TestMessage(t *testing.T) { bytesSaved bool // if true, outbound message saved bytes must be non-zero }{ { - desc: "ping message with no compression no subnet uptimes", + desc: "ping message with no compression no uptime", op: PingOp, msg: &p2p.Message{ Message: &p2p.Message_Ping{ @@ -78,17 +78,12 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "ping message with no compression and subnet uptimes", + desc: "ping message with no compression and uptime", op: PingOp, msg: &p2p.Message{ Message: &p2p.Message_Ping{ Ping: &p2p.Ping{ - SubnetUptimes: []*p2p.SubnetUptime{ - { - SubnetId: testID[:], - Uptime: 100, - }, - }, + Uptime: 100, }, }, }, diff --git a/message/mock_outbound_message_builder.go b/message/mock_outbound_message_builder.go index 917d764028fe..c480ca1d1c65 100644 --- a/message/mock_outbound_message_builder.go +++ b/message/mock_outbound_message_builder.go @@ -314,18 +314,18 @@ func (mr *MockOutboundMsgBuilderMockRecorder) PeerList(arg0, arg1 any) *gomock.C } // Ping mocks base method. -func (m *MockOutboundMsgBuilder) Ping(arg0 uint32, arg1 []*p2p.SubnetUptime) (OutboundMessage, error) { +func (m *MockOutboundMsgBuilder) Ping(arg0 uint32) (OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Ping", arg0, arg1) + ret := m.ctrl.Call(m, "Ping", arg0) ret0, _ := ret[0].(OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Ping indicates an expected call of Ping. -func (mr *MockOutboundMsgBuilderMockRecorder) Ping(arg0, arg1 any) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Ping(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Ping), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Ping), arg0) } // Pong mocks base method. diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index 78aacdce3e08..208b04902ae1 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -49,7 +49,6 @@ type OutboundMsgBuilder interface { Ping( primaryUptime uint32, - subnetUptimes []*p2p.SubnetUptime, ) (OutboundMessage, error) Pong() (OutboundMessage, error) @@ -198,14 +197,12 @@ func newOutboundBuilder(compressionType compression.Type, builder *msgBuilder) O func (b *outMsgBuilder) Ping( primaryUptime uint32, - subnetUptimes []*p2p.SubnetUptime, ) (OutboundMessage, error) { return b.builder.createOutbound( &p2p.Message{ Message: &p2p.Message_Ping{ Ping: &p2p.Ping{ - Uptime: primaryUptime, - SubnetUptimes: subnetUptimes, + Uptime: primaryUptime, }, }, }, diff --git a/network/metrics.go b/network/metrics.go index 9702e821b246..fda3c0bf5f85 100644 --- a/network/metrics.go +++ b/network/metrics.go @@ -19,24 +19,22 @@ type metrics struct { // trackedSubnets does not include the primary network ID trackedSubnets set.Set[ids.ID] - numTracked prometheus.Gauge - numPeers prometheus.Gauge - numSubnetPeers *prometheus.GaugeVec - timeSinceLastMsgSent prometheus.Gauge - timeSinceLastMsgReceived prometheus.Gauge - sendFailRate prometheus.Gauge - connected prometheus.Counter - disconnected prometheus.Counter - acceptFailed prometheus.Counter - inboundConnRateLimited prometheus.Counter - inboundConnAllowed prometheus.Counter - tlsConnRejected prometheus.Counter - numUselessPeerListBytes prometheus.Counter - nodeUptimeWeightedAverage prometheus.Gauge - nodeUptimeRewardingStake prometheus.Gauge - nodeSubnetUptimeWeightedAverage *prometheus.GaugeVec - nodeSubnetUptimeRewardingStake *prometheus.GaugeVec - peerConnectedLifetimeAverage prometheus.Gauge + numTracked prometheus.Gauge + numPeers prometheus.Gauge + numSubnetPeers *prometheus.GaugeVec + timeSinceLastMsgSent prometheus.Gauge + timeSinceLastMsgReceived prometheus.Gauge + sendFailRate prometheus.Gauge + connected prometheus.Counter + disconnected prometheus.Counter + acceptFailed prometheus.Counter + inboundConnRateLimited prometheus.Counter + inboundConnAllowed prometheus.Counter + tlsConnRejected prometheus.Counter + numUselessPeerListBytes prometheus.Counter + nodeUptimeWeightedAverage prometheus.Gauge + nodeUptimeRewardingStake prometheus.Gauge + peerConnectedLifetimeAverage prometheus.Gauge lock sync.RWMutex peerConnectedStartTimes map[ids.NodeID]float64 @@ -112,20 +110,6 @@ func newMetrics( Name: "node_uptime_rewarding_stake", Help: "The percentage of total stake which thinks this node is eligible for rewards", }), - nodeSubnetUptimeWeightedAverage: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "node_subnet_uptime_weighted_average", - Help: "This node's subnet uptime averages weighted by observing subnet peer stakes", - }, - []string{"subnetID"}, - ), - nodeSubnetUptimeRewardingStake: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "node_subnet_uptime_rewarding_stake", - Help: "The percentage of subnet's total stake which thinks this node is eligible for subnet's rewards", - }, - []string{"subnetID"}, - ), peerConnectedLifetimeAverage: prometheus.NewGauge( prometheus.GaugeOpts{ Name: "peer_connected_duration_average", @@ -151,8 +135,6 @@ func newMetrics( registerer.Register(m.inboundConnRateLimited), registerer.Register(m.nodeUptimeWeightedAverage), registerer.Register(m.nodeUptimeRewardingStake), - registerer.Register(m.nodeSubnetUptimeWeightedAverage), - registerer.Register(m.nodeSubnetUptimeRewardingStake), registerer.Register(m.peerConnectedLifetimeAverage), ) @@ -161,8 +143,6 @@ func newMetrics( // initialize to 0 subnetIDStr := subnetID.String() m.numSubnetPeers.WithLabelValues(subnetIDStr).Set(0) - m.nodeSubnetUptimeWeightedAverage.WithLabelValues(subnetIDStr).Set(0) - m.nodeSubnetUptimeRewardingStake.WithLabelValues(subnetIDStr).Set(0) } return m, err diff --git a/network/network.go b/network/network.go index 2aee13a910d9..e92bc248a218 100644 --- a/network/network.go +++ b/network/network.go @@ -85,9 +85,9 @@ type Network interface { // info about the peers in [nodeIDs] that have finished the handshake. PeerInfo(nodeIDs []ids.NodeID) []peer.Info - // NodeUptime returns given node's [subnetID] UptimeResults in the view of + // NodeUptime returns given node's primary network UptimeResults in the view of // this node's peer validators. - NodeUptime(subnetID ids.ID) (UptimeResult, error) + NodeUptime() (UptimeResult, error) } type UptimeResult struct { @@ -1098,19 +1098,15 @@ func (n *network) StartClose() { }) } -func (n *network) NodeUptime(subnetID ids.ID) (UptimeResult, error) { - if subnetID != constants.PrimaryNetworkID && !n.config.TrackedSubnets.Contains(subnetID) { - return UptimeResult{}, errNotTracked - } - - myStake := n.config.Validators.GetWeight(subnetID, n.config.MyNodeID) +func (n *network) NodeUptime() (UptimeResult, error) { + myStake := n.config.Validators.GetWeight(constants.PrimaryNetworkID, n.config.MyNodeID) if myStake == 0 { return UptimeResult{}, errNotValidator } - totalWeightInt, err := n.config.Validators.TotalWeight(subnetID) + totalWeightInt, err := n.config.Validators.TotalWeight(constants.PrimaryNetworkID) if err != nil { - return UptimeResult{}, fmt.Errorf("error while fetching weight for subnet %s: %w", subnetID, err) + return UptimeResult{}, fmt.Errorf("error while fetching weight for primary network %w", err) } var ( @@ -1126,22 +1122,18 @@ func (n *network) NodeUptime(subnetID ids.ID) (UptimeResult, error) { peer, _ := n.connectedPeers.GetByIndex(i) nodeID := peer.ID() - weight := n.config.Validators.GetWeight(subnetID, nodeID) + weight := n.config.Validators.GetWeight(constants.PrimaryNetworkID, nodeID) if weight == 0 { // this is not a validator skip it. continue } - observedUptime, exist := peer.ObservedUptime(subnetID) - if !exist { - observedUptime = 0 - } + observedUptime := peer.ObservedUptime() percent := float64(observedUptime) weightFloat := float64(weight) totalWeightedPercent += percent * weightFloat // if this peer thinks we're above requirement add the weight - // TODO: use subnet-specific uptime requirements if percent/100 >= n.config.UptimeRequirement { rewardingStake += weightFloat } @@ -1177,7 +1169,7 @@ func (n *network) runTimers() { n.peerConfig.Log.Debug("reset ip tracker bloom filter") } case <-updateUptimes.C: - primaryUptime, err := n.NodeUptime(constants.PrimaryNetworkID) + primaryUptime, err := n.NodeUptime() if err != nil { n.peerConfig.Log.Debug("failed to get primary network uptime", zap.Error(err), @@ -1185,19 +1177,6 @@ func (n *network) runTimers() { } n.metrics.nodeUptimeWeightedAverage.Set(primaryUptime.WeightedAveragePercentage) n.metrics.nodeUptimeRewardingStake.Set(primaryUptime.RewardingStakePercentage) - - for subnetID := range n.config.TrackedSubnets { - result, err := n.NodeUptime(subnetID) - if err != nil { - n.peerConfig.Log.Debug("failed to get subnet uptime", - zap.Stringer("subnetID", subnetID), - zap.Error(err), - ) - } - subnetIDStr := subnetID.String() - n.metrics.nodeSubnetUptimeWeightedAverage.WithLabelValues(subnetIDStr).Set(result.WeightedAveragePercentage) - n.metrics.nodeSubnetUptimeRewardingStake.WithLabelValues(subnetIDStr).Set(result.RewardingStakePercentage) - } } } } diff --git a/network/peer/info.go b/network/peer/info.go index 928c47ff26ee..71d2c78420f9 100644 --- a/network/peer/info.go +++ b/network/peer/info.go @@ -13,15 +13,14 @@ import ( ) type Info struct { - IP netip.AddrPort `json:"ip"` - PublicIP netip.AddrPort `json:"publicIP,omitempty"` - ID ids.NodeID `json:"nodeID"` - Version string `json:"version"` - LastSent time.Time `json:"lastSent"` - LastReceived time.Time `json:"lastReceived"` - ObservedUptime json.Uint32 `json:"observedUptime"` - ObservedSubnetUptimes map[ids.ID]json.Uint32 `json:"observedSubnetUptimes"` - TrackedSubnets set.Set[ids.ID] `json:"trackedSubnets"` - SupportedACPs set.Set[uint32] `json:"supportedACPs"` - ObjectedACPs set.Set[uint32] `json:"objectedACPs"` + IP netip.AddrPort `json:"ip"` + PublicIP netip.AddrPort `json:"publicIP,omitempty"` + ID ids.NodeID `json:"nodeID"` + Version string `json:"version"` + LastSent time.Time `json:"lastSent"` + LastReceived time.Time `json:"lastReceived"` + ObservedUptime json.Uint32 `json:"observedUptime"` + TrackedSubnets set.Set[ids.ID] `json:"trackedSubnets"` + SupportedACPs set.Set[uint32] `json:"supportedACPs"` + ObjectedACPs set.Set[uint32] `json:"objectedACPs"` } diff --git a/network/peer/message_queue_test.go b/network/peer/message_queue_test.go index 4b9b63f4c449..a4cce461abab 100644 --- a/network/peer/message_queue_test.go +++ b/network/peer/message_queue_test.go @@ -9,9 +9,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" - "github.com/ava-labs/avalanchego/proto/pb/p2p" "github.com/ava-labs/avalanchego/utils/logging" ) @@ -33,14 +31,7 @@ func TestMessageQueue(t *testing.T) { // Assert that the messages are popped in the same order they were pushed for i := 0; i < numToSend; i++ { - testID := ids.GenerateTestID() - testID2 := ids.GenerateTestID() - m, err := mc.Ping( - uint32(i), - []*p2p.SubnetUptime{ - {SubnetId: testID[:], Uptime: uint32(i)}, - {SubnetId: testID2[:], Uptime: uint32(i)}, - }) + m, err := mc.Ping(uint32(i)) require.NoError(err) msgs = append(msgs, m) } diff --git a/network/peer/peer.go b/network/peer/peer.go index a92791ff72ee..e3161cfc0eab 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -94,10 +94,10 @@ type Peer interface { // be called after [Ready] returns true. TrackedSubnets() set.Set[ids.ID] - // ObservedUptime returns the local node's subnet uptime according to the + // ObservedUptime returns the local node's primary network uptime according to the // peer. The value ranges from [0, 100]. It should only be called after // [Ready] returns true. - ObservedUptime(subnetID ids.ID) (uint32, bool) + ObservedUptime() uint32 // Send attempts to send [msg] to the peer. The peer takes ownership of // [msg] for reference counting. This returns false if the message is @@ -158,10 +158,8 @@ type peer struct { // this can only be accessed by the message sender goroutine. txIDOfVerifiedBLSKey ids.ID - observedUptimesLock sync.RWMutex - // [observedUptimesLock] must be held while accessing [observedUptime] - // Subnet ID --> Our uptime for the given subnet as perceived by the peer - observedUptimes map[ids.ID]uint32 + // Our primary network uptime perceived by the peer + observedUptime utils.Atomic[uint32] // True if this peer has sent us a valid Handshake message and // is running a compatible version. @@ -221,7 +219,6 @@ func Start( onClosingCtx: onClosingCtx, onClosingCtxCancel: onClosingCtxCancel, onClosed: make(chan struct{}), - observedUptimes: make(map[ids.ID]uint32), getPeerListChan: make(chan struct{}, 1), } @@ -270,33 +267,20 @@ func (p *peer) AwaitReady(ctx context.Context) error { } func (p *peer) Info() Info { - uptimes := make(map[ids.ID]json.Uint32, p.MySubnets.Len()) - for subnetID := range p.MySubnets { - uptime, exist := p.ObservedUptime(subnetID) - if !exist { - continue - } - uptimes[subnetID] = json.Uint32(uptime) - } - - primaryUptime, exist := p.ObservedUptime(constants.PrimaryNetworkID) - if !exist { - primaryUptime = 0 - } + primaryUptime := p.ObservedUptime() ip, _ := ips.ParseAddrPort(p.conn.RemoteAddr().String()) return Info{ - IP: ip, - PublicIP: p.ip.AddrPort, - ID: p.id, - Version: p.version.String(), - LastSent: p.LastSent(), - LastReceived: p.LastReceived(), - ObservedUptime: json.Uint32(primaryUptime), - ObservedSubnetUptimes: uptimes, - TrackedSubnets: p.trackedSubnets, - SupportedACPs: p.supportedACPs, - ObjectedACPs: p.objectedACPs, + IP: ip, + PublicIP: p.ip.AddrPort, + ID: p.id, + Version: p.version.String(), + LastSent: p.LastSent(), + LastReceived: p.LastReceived(), + ObservedUptime: json.Uint32(primaryUptime), + TrackedSubnets: p.trackedSubnets, + SupportedACPs: p.supportedACPs, + ObjectedACPs: p.objectedACPs, } } @@ -312,12 +296,8 @@ func (p *peer) TrackedSubnets() set.Set[ids.ID] { return p.trackedSubnets } -func (p *peer) ObservedUptime(subnetID ids.ID) (uint32, bool) { - p.observedUptimesLock.RLock() - defer p.observedUptimesLock.RUnlock() - - uptime, exist := p.observedUptimes[subnetID] - return uptime, exist +func (p *peer) ObservedUptime() uint32 { + return p.observedUptime.Get() } func (p *peer) Send(ctx context.Context, msg message.OutboundMessage) bool { @@ -670,8 +650,8 @@ func (p *peer) sendNetworkMessages() { return } - primaryUptime, subnetUptimes := p.getUptimes() - pingMessage, err := p.MessageCreator.Ping(primaryUptime, subnetUptimes) + primaryUptime := p.getUptime() + pingMessage, err := p.MessageCreator.Ping(primaryUptime) if err != nil { p.Log.Error(failedToCreateMessageLog, zap.Stringer("nodeID", p.id), @@ -782,45 +762,7 @@ func (p *peer) handlePing(msg *p2p.Ping) { p.StartClose() return } - p.observeUptime(constants.PrimaryNetworkID, msg.Uptime) - - for _, subnetUptime := range msg.SubnetUptimes { - subnetID, err := ids.ToID(subnetUptime.SubnetId) - if err != nil { - p.Log.Debug(malformedMessageLog, - zap.Stringer("nodeID", p.id), - zap.Stringer("messageOp", message.PingOp), - zap.String("field", "subnetID"), - zap.Error(err), - ) - p.StartClose() - return - } - - if !p.MySubnets.Contains(subnetID) { - p.Log.Debug(malformedMessageLog, - zap.Stringer("nodeID", p.id), - zap.Stringer("messageOp", message.PingOp), - zap.Stringer("subnetID", subnetID), - zap.String("reason", "not tracking subnet"), - ) - p.StartClose() - return - } - - uptime := subnetUptime.Uptime - if uptime > 100 { - p.Log.Debug(malformedMessageLog, - zap.Stringer("nodeID", p.id), - zap.Stringer("messageOp", message.PingOp), - zap.Stringer("subnetID", subnetID), - zap.Uint32("uptime", uptime), - ) - p.StartClose() - return - } - p.observeUptime(subnetID, uptime) - } + p.observedUptime.Set(msg.Uptime) pongMessage, err := p.MessageCreator.Pong() if err != nil { @@ -836,10 +778,9 @@ func (p *peer) handlePing(msg *p2p.Ping) { p.Send(p.onClosingCtx, pongMessage) } -func (p *peer) getUptimes() (uint32, []*p2p.SubnetUptime) { +func (p *peer) getUptime() uint32 { primaryUptime, err := p.UptimeCalculator.CalculateUptimePercent( p.id, - constants.PrimaryNetworkID, ) if err != nil { p.Log.Debug(failedToGetUptimeLog, @@ -850,45 +791,12 @@ func (p *peer) getUptimes() (uint32, []*p2p.SubnetUptime) { primaryUptime = 0 } - subnetUptimes := make([]*p2p.SubnetUptime, 0, p.MySubnets.Len()) - for subnetID := range p.MySubnets { - if !p.trackedSubnets.Contains(subnetID) { - continue - } - - subnetUptime, err := p.UptimeCalculator.CalculateUptimePercent(p.id, subnetID) - if err != nil { - p.Log.Debug(failedToGetUptimeLog, - zap.Stringer("nodeID", p.id), - zap.Stringer("subnetID", subnetID), - zap.Error(err), - ) - continue - } - - subnetID := subnetID - subnetUptimes = append(subnetUptimes, &p2p.SubnetUptime{ - SubnetId: subnetID[:], - Uptime: uint32(subnetUptime * 100), - }) - } - primaryUptimePercent := uint32(primaryUptime * 100) - return primaryUptimePercent, subnetUptimes + return primaryUptimePercent } func (*peer) handlePong(*p2p.Pong) {} -// Record that the given peer perceives our uptime for the given [subnetID] -// to be [uptime]. -// Assumes [uptime] is in the range [0, 100] and [subnetID] is a valid ID of a -// subnet this peer tracks. -func (p *peer) observeUptime(subnetID ids.ID, uptime uint32) { - p.observedUptimesLock.Lock() - p.observedUptimes[subnetID] = uptime // [0, 100] percentage - p.observedUptimesLock.Unlock() -} - func (p *peer) handleHandshake(msg *p2p.Handshake) { if p.gotHandshake.Get() { p.Log.Debug(malformedMessageLog, diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index e29edbe17ba6..ae2f86a74fc1 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/network/throttling" - "github.com/ava-labs/avalanchego/proto/pb/p2p" "github.com/ava-labs/avalanchego/snow/networking/router" "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/uptime" @@ -211,122 +210,35 @@ func TestSend(t *testing.T) { } func TestPingUptimes(t *testing.T) { - trackedSubnetID := ids.GenerateTestID() - untrackedSubnetID := ids.GenerateTestID() - sharedConfig := newConfig(t) - sharedConfig.MySubnets = set.Of(trackedSubnetID) - - testCases := []struct { - name string - msg message.OutboundMessage - shouldClose bool - assertFn func(*require.Assertions, *testPeer) - }{ - { - name: "primary network only", - msg: func() message.OutboundMessage { - pingMsg, err := sharedConfig.MessageCreator.Ping(1, nil) - require.NoError(t, err) - return pingMsg - }(), - shouldClose: false, - assertFn: func(require *require.Assertions, peer *testPeer) { - uptime, ok := peer.ObservedUptime(constants.PrimaryNetworkID) - require.True(ok) - require.Equal(uint32(1), uptime) - - uptime, ok = peer.ObservedUptime(trackedSubnetID) - require.False(ok) - require.Zero(uptime) - }, - }, - { - name: "primary network and subnet", - msg: func() message.OutboundMessage { - pingMsg, err := sharedConfig.MessageCreator.Ping( - 1, - []*p2p.SubnetUptime{ - { - SubnetId: trackedSubnetID[:], - Uptime: 1, - }, - }, - ) - require.NoError(t, err) - return pingMsg - }(), - shouldClose: false, - assertFn: func(require *require.Assertions, peer *testPeer) { - uptime, ok := peer.ObservedUptime(constants.PrimaryNetworkID) - require.True(ok) - require.Equal(uint32(1), uptime) - - uptime, ok = peer.ObservedUptime(trackedSubnetID) - require.True(ok) - require.Equal(uint32(1), uptime) - }, - }, - { - name: "primary network and non tracked subnet", - msg: func() message.OutboundMessage { - pingMsg, err := sharedConfig.MessageCreator.Ping( - 1, - []*p2p.SubnetUptime{ - { - // Providing the untrackedSubnetID here should cause - // the remote peer to disconnect from us. - SubnetId: untrackedSubnetID[:], - Uptime: 1, - }, - { - SubnetId: trackedSubnetID[:], - Uptime: 1, - }, - }, - ) - require.NoError(t, err) - return pingMsg - }(), - shouldClose: true, - assertFn: nil, - }, - } // The raw peers are generated outside of the test cases to avoid generating // many TLS keys. rawPeer0 := newRawTestPeer(t, sharedConfig) rawPeer1 := newRawTestPeer(t, sharedConfig) - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - require := require.New(t) - - peer0, peer1 := startTestPeers(rawPeer0, rawPeer1) - awaitReady(t, peer0, peer1) - defer func() { - peer1.StartClose() - peer0.StartClose() - require.NoError(peer0.AwaitClosed(context.Background())) - require.NoError(peer1.AwaitClosed(context.Background())) - }() - - require.True(peer0.Send(context.Background(), tc.msg)) + require := require.New(t) - if tc.shouldClose { - require.NoError(peer1.AwaitClosed(context.Background())) - return - } + peer0, peer1 := startTestPeers(rawPeer0, rawPeer1) + awaitReady(t, peer0, peer1) + defer func() { + peer1.StartClose() + peer0.StartClose() + require.NoError(peer0.AwaitClosed(context.Background())) + require.NoError(peer1.AwaitClosed(context.Background())) + }() + pingMsg, err := sharedConfig.MessageCreator.Ping(0) + require.NoError(err) + require.True(peer0.Send(context.Background(), pingMsg)) - // we send Get message after ping to ensure Ping is handled by the - // time Get is handled. This is because Get is routed to the handler - // whereas Ping is handled by the peer directly. We have no way to - // know when the peer has handled the Ping message. - sendAndFlush(t, peer0, peer1) + // we send Get message after ping to ensure Ping is handled by the + // time Get is handled. This is because Get is routed to the handler + // whereas Ping is handled by the peer directly. We have no way to + // know when the peer has handled the Ping message. + sendAndFlush(t, peer0, peer1) - tc.assertFn(require, peer1) - }) - } + uptime := peer1.ObservedUptime() + require.Equal(uint32(0), uptime) } func TestTrackedSubnets(t *testing.T) { diff --git a/network/peer/set_test.go b/network/peer/set_test.go index c28c1ce7ea98..fb84b5e67d74 100644 --- a/network/peer/set_test.go +++ b/network/peer/set_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils" ) func TestSet(t *testing.T) { @@ -18,12 +18,12 @@ func TestSet(t *testing.T) { set := NewSet() peer1 := &peer{ - id: ids.BuildTestNodeID([]byte{0x01}), - observedUptimes: map[ids.ID]uint32{constants.PrimaryNetworkID: 0}, + id: ids.BuildTestNodeID([]byte{0x01}), + observedUptime: *utils.NewAtomic[uint32](0), } updatedPeer1 := &peer{ - id: ids.BuildTestNodeID([]byte{0x01}), - observedUptimes: map[ids.ID]uint32{constants.PrimaryNetworkID: 1}, + id: ids.BuildTestNodeID([]byte{0x01}), + observedUptime: *utils.NewAtomic[uint32](1), } peer2 := &peer{ id: ids.BuildTestNodeID([]byte{0x02}), @@ -42,8 +42,8 @@ func TestSet(t *testing.T) { set.Add(peer1) retrievedPeer1, peer1Found := set.GetByID(peer1.id) require.True(peer1Found) - observed1, _ := peer1.ObservedUptime(constants.PrimaryNetworkID) - observed2, _ := retrievedPeer1.ObservedUptime(constants.PrimaryNetworkID) + observed1 := peer1.ObservedUptime() + observed2 := retrievedPeer1.ObservedUptime() require.Equal(observed1, observed2) require.Equal(1, set.Len()) @@ -51,8 +51,8 @@ func TestSet(t *testing.T) { set.Add(updatedPeer1) retrievedPeer1, peer1Found = set.GetByID(peer1.id) require.True(peer1Found) - observed1, _ = updatedPeer1.ObservedUptime(constants.PrimaryNetworkID) - observed2, _ = retrievedPeer1.ObservedUptime(constants.PrimaryNetworkID) + observed1 = updatedPeer1.ObservedUptime() + observed2 = retrievedPeer1.ObservedUptime() require.Equal(observed1, observed2) require.Equal(1, set.Len()) @@ -60,8 +60,8 @@ func TestSet(t *testing.T) { set.Add(peer2) retrievedPeer2, peer2Found := set.GetByID(peer2.id) require.True(peer2Found) - observed1, _ = peer2.ObservedUptime(constants.PrimaryNetworkID) - observed2, _ = retrievedPeer2.ObservedUptime(constants.PrimaryNetworkID) + observed1 = peer2.ObservedUptime() + observed2 = retrievedPeer2.ObservedUptime() require.Equal(observed1, observed2) require.Equal(2, set.Len()) diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index 53c0c84de303..5d0a3a31a1eb 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -64,16 +64,7 @@ message Message { message Ping { // Uptime percentage on the primary network [0, 100] uint32 uptime = 1; - // Uptime percentage on subnets - repeated SubnetUptime subnet_uptimes = 2; -} - -// SubnetUptime is a descriptor for a peer's perceived uptime on a subnet. -message SubnetUptime { - // Subnet the peer is validating - bytes subnet_id = 1; - // Uptime percentage on the subnet [0, 100] - uint32 uptime = 2; + reserved 2; // Until E upgrade is activated. } // Pong is sent in response to a Ping. diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index bd55ad703546..ecb33f05a920 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -498,8 +498,6 @@ type Ping struct { // Uptime percentage on the primary network [0, 100] Uptime uint32 `protobuf:"varint,1,opt,name=uptime,proto3" json:"uptime,omitempty"` - // Uptime percentage on subnets - SubnetUptimes []*SubnetUptime `protobuf:"bytes,2,rep,name=subnet_uptimes,json=subnetUptimes,proto3" json:"subnet_uptimes,omitempty"` } func (x *Ping) Reset() { @@ -541,71 +539,6 @@ func (x *Ping) GetUptime() uint32 { return 0 } -func (x *Ping) GetSubnetUptimes() []*SubnetUptime { - if x != nil { - return x.SubnetUptimes - } - return nil -} - -// SubnetUptime is a descriptor for a peer's perceived uptime on a subnet. -type SubnetUptime struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Subnet the peer is validating - SubnetId []byte `protobuf:"bytes,1,opt,name=subnet_id,json=subnetId,proto3" json:"subnet_id,omitempty"` - // Uptime percentage on the subnet [0, 100] - Uptime uint32 `protobuf:"varint,2,opt,name=uptime,proto3" json:"uptime,omitempty"` -} - -func (x *SubnetUptime) Reset() { - *x = SubnetUptime{} - if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SubnetUptime) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SubnetUptime) ProtoMessage() {} - -func (x *SubnetUptime) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SubnetUptime.ProtoReflect.Descriptor instead. -func (*SubnetUptime) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{2} -} - -func (x *SubnetUptime) GetSubnetId() []byte { - if x != nil { - return x.SubnetId - } - return nil -} - -func (x *SubnetUptime) GetUptime() uint32 { - if x != nil { - return x.Uptime - } - return 0 -} - // Pong is sent in response to a Ping. type Pong struct { state protoimpl.MessageState @@ -616,7 +549,7 @@ type Pong struct { func (x *Pong) Reset() { *x = Pong{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[3] + mi := &file_p2p_p2p_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -629,7 +562,7 @@ func (x *Pong) String() string { func (*Pong) ProtoMessage() {} func (x *Pong) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[3] + mi := &file_p2p_p2p_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -642,7 +575,7 @@ func (x *Pong) ProtoReflect() protoreflect.Message { // Deprecated: Use Pong.ProtoReflect.Descriptor instead. func (*Pong) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{3} + return file_p2p_p2p_proto_rawDescGZIP(), []int{2} } // Handshake is the first outbound message sent to a peer when a connection is @@ -684,7 +617,7 @@ type Handshake struct { func (x *Handshake) Reset() { *x = Handshake{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[4] + mi := &file_p2p_p2p_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -697,7 +630,7 @@ func (x *Handshake) String() string { func (*Handshake) ProtoMessage() {} func (x *Handshake) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[4] + mi := &file_p2p_p2p_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -710,7 +643,7 @@ func (x *Handshake) ProtoReflect() protoreflect.Message { // Deprecated: Use Handshake.ProtoReflect.Descriptor instead. func (*Handshake) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{4} + return file_p2p_p2p_proto_rawDescGZIP(), []int{3} } func (x *Handshake) GetNetworkId() uint32 { @@ -814,7 +747,7 @@ type Client struct { func (x *Client) Reset() { *x = Client{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[5] + mi := &file_p2p_p2p_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -827,7 +760,7 @@ func (x *Client) String() string { func (*Client) ProtoMessage() {} func (x *Client) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[5] + mi := &file_p2p_p2p_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -840,7 +773,7 @@ func (x *Client) ProtoReflect() protoreflect.Message { // Deprecated: Use Client.ProtoReflect.Descriptor instead. func (*Client) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{5} + return file_p2p_p2p_proto_rawDescGZIP(), []int{4} } func (x *Client) GetName() string { @@ -884,7 +817,7 @@ type BloomFilter struct { func (x *BloomFilter) Reset() { *x = BloomFilter{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[6] + mi := &file_p2p_p2p_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -897,7 +830,7 @@ func (x *BloomFilter) String() string { func (*BloomFilter) ProtoMessage() {} func (x *BloomFilter) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[6] + mi := &file_p2p_p2p_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -910,7 +843,7 @@ func (x *BloomFilter) ProtoReflect() protoreflect.Message { // Deprecated: Use BloomFilter.ProtoReflect.Descriptor instead. func (*BloomFilter) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{6} + return file_p2p_p2p_proto_rawDescGZIP(), []int{5} } func (x *BloomFilter) GetFilter() []byte { @@ -950,7 +883,7 @@ type ClaimedIpPort struct { func (x *ClaimedIpPort) Reset() { *x = ClaimedIpPort{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[7] + mi := &file_p2p_p2p_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -963,7 +896,7 @@ func (x *ClaimedIpPort) String() string { func (*ClaimedIpPort) ProtoMessage() {} func (x *ClaimedIpPort) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[7] + mi := &file_p2p_p2p_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -976,7 +909,7 @@ func (x *ClaimedIpPort) ProtoReflect() protoreflect.Message { // Deprecated: Use ClaimedIpPort.ProtoReflect.Descriptor instead. func (*ClaimedIpPort) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{7} + return file_p2p_p2p_proto_rawDescGZIP(), []int{6} } func (x *ClaimedIpPort) GetX509Certificate() []byte { @@ -1038,7 +971,7 @@ type GetPeerList struct { func (x *GetPeerList) Reset() { *x = GetPeerList{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[8] + mi := &file_p2p_p2p_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1051,7 +984,7 @@ func (x *GetPeerList) String() string { func (*GetPeerList) ProtoMessage() {} func (x *GetPeerList) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[8] + mi := &file_p2p_p2p_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1064,7 +997,7 @@ func (x *GetPeerList) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPeerList.ProtoReflect.Descriptor instead. func (*GetPeerList) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{8} + return file_p2p_p2p_proto_rawDescGZIP(), []int{7} } func (x *GetPeerList) GetKnownPeers() *BloomFilter { @@ -1094,7 +1027,7 @@ type PeerList struct { func (x *PeerList) Reset() { *x = PeerList{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[9] + mi := &file_p2p_p2p_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1107,7 +1040,7 @@ func (x *PeerList) String() string { func (*PeerList) ProtoMessage() {} func (x *PeerList) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[9] + mi := &file_p2p_p2p_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1120,7 +1053,7 @@ func (x *PeerList) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerList.ProtoReflect.Descriptor instead. func (*PeerList) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{9} + return file_p2p_p2p_proto_rawDescGZIP(), []int{8} } func (x *PeerList) GetClaimedIpPorts() []*ClaimedIpPort { @@ -1148,7 +1081,7 @@ type GetStateSummaryFrontier struct { func (x *GetStateSummaryFrontier) Reset() { *x = GetStateSummaryFrontier{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[10] + mi := &file_p2p_p2p_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1161,7 +1094,7 @@ func (x *GetStateSummaryFrontier) String() string { func (*GetStateSummaryFrontier) ProtoMessage() {} func (x *GetStateSummaryFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[10] + mi := &file_p2p_p2p_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1174,7 +1107,7 @@ func (x *GetStateSummaryFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use GetStateSummaryFrontier.ProtoReflect.Descriptor instead. func (*GetStateSummaryFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{10} + return file_p2p_p2p_proto_rawDescGZIP(), []int{9} } func (x *GetStateSummaryFrontier) GetChainId() []byte { @@ -1215,7 +1148,7 @@ type StateSummaryFrontier struct { func (x *StateSummaryFrontier) Reset() { *x = StateSummaryFrontier{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[11] + mi := &file_p2p_p2p_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1228,7 +1161,7 @@ func (x *StateSummaryFrontier) String() string { func (*StateSummaryFrontier) ProtoMessage() {} func (x *StateSummaryFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[11] + mi := &file_p2p_p2p_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1241,7 +1174,7 @@ func (x *StateSummaryFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSummaryFrontier.ProtoReflect.Descriptor instead. func (*StateSummaryFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{11} + return file_p2p_p2p_proto_rawDescGZIP(), []int{10} } func (x *StateSummaryFrontier) GetChainId() []byte { @@ -1285,7 +1218,7 @@ type GetAcceptedStateSummary struct { func (x *GetAcceptedStateSummary) Reset() { *x = GetAcceptedStateSummary{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[12] + mi := &file_p2p_p2p_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1298,7 +1231,7 @@ func (x *GetAcceptedStateSummary) String() string { func (*GetAcceptedStateSummary) ProtoMessage() {} func (x *GetAcceptedStateSummary) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[12] + mi := &file_p2p_p2p_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1311,7 +1244,7 @@ func (x *GetAcceptedStateSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAcceptedStateSummary.ProtoReflect.Descriptor instead. func (*GetAcceptedStateSummary) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{12} + return file_p2p_p2p_proto_rawDescGZIP(), []int{11} } func (x *GetAcceptedStateSummary) GetChainId() []byte { @@ -1359,7 +1292,7 @@ type AcceptedStateSummary struct { func (x *AcceptedStateSummary) Reset() { *x = AcceptedStateSummary{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[13] + mi := &file_p2p_p2p_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1372,7 +1305,7 @@ func (x *AcceptedStateSummary) String() string { func (*AcceptedStateSummary) ProtoMessage() {} func (x *AcceptedStateSummary) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[13] + mi := &file_p2p_p2p_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1385,7 +1318,7 @@ func (x *AcceptedStateSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use AcceptedStateSummary.ProtoReflect.Descriptor instead. func (*AcceptedStateSummary) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{13} + return file_p2p_p2p_proto_rawDescGZIP(), []int{12} } func (x *AcceptedStateSummary) GetChainId() []byte { @@ -1428,7 +1361,7 @@ type GetAcceptedFrontier struct { func (x *GetAcceptedFrontier) Reset() { *x = GetAcceptedFrontier{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[14] + mi := &file_p2p_p2p_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1441,7 +1374,7 @@ func (x *GetAcceptedFrontier) String() string { func (*GetAcceptedFrontier) ProtoMessage() {} func (x *GetAcceptedFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[14] + mi := &file_p2p_p2p_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1454,7 +1387,7 @@ func (x *GetAcceptedFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAcceptedFrontier.ProtoReflect.Descriptor instead. func (*GetAcceptedFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{14} + return file_p2p_p2p_proto_rawDescGZIP(), []int{13} } func (x *GetAcceptedFrontier) GetChainId() []byte { @@ -1497,7 +1430,7 @@ type AcceptedFrontier struct { func (x *AcceptedFrontier) Reset() { *x = AcceptedFrontier{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[15] + mi := &file_p2p_p2p_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1510,7 +1443,7 @@ func (x *AcceptedFrontier) String() string { func (*AcceptedFrontier) ProtoMessage() {} func (x *AcceptedFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[15] + mi := &file_p2p_p2p_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1523,7 +1456,7 @@ func (x *AcceptedFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use AcceptedFrontier.ProtoReflect.Descriptor instead. func (*AcceptedFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{15} + return file_p2p_p2p_proto_rawDescGZIP(), []int{14} } func (x *AcceptedFrontier) GetChainId() []byte { @@ -1569,7 +1502,7 @@ type GetAccepted struct { func (x *GetAccepted) Reset() { *x = GetAccepted{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[16] + mi := &file_p2p_p2p_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1582,7 +1515,7 @@ func (x *GetAccepted) String() string { func (*GetAccepted) ProtoMessage() {} func (x *GetAccepted) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[16] + mi := &file_p2p_p2p_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1595,7 +1528,7 @@ func (x *GetAccepted) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAccepted.ProtoReflect.Descriptor instead. func (*GetAccepted) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{16} + return file_p2p_p2p_proto_rawDescGZIP(), []int{15} } func (x *GetAccepted) GetChainId() []byte { @@ -1646,7 +1579,7 @@ type Accepted struct { func (x *Accepted) Reset() { *x = Accepted{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[17] + mi := &file_p2p_p2p_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1659,7 +1592,7 @@ func (x *Accepted) String() string { func (*Accepted) ProtoMessage() {} func (x *Accepted) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[17] + mi := &file_p2p_p2p_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1672,7 +1605,7 @@ func (x *Accepted) ProtoReflect() protoreflect.Message { // Deprecated: Use Accepted.ProtoReflect.Descriptor instead. func (*Accepted) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{17} + return file_p2p_p2p_proto_rawDescGZIP(), []int{16} } func (x *Accepted) GetChainId() []byte { @@ -1719,7 +1652,7 @@ type GetAncestors struct { func (x *GetAncestors) Reset() { *x = GetAncestors{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[18] + mi := &file_p2p_p2p_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1732,7 +1665,7 @@ func (x *GetAncestors) String() string { func (*GetAncestors) ProtoMessage() {} func (x *GetAncestors) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[18] + mi := &file_p2p_p2p_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1745,7 +1678,7 @@ func (x *GetAncestors) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAncestors.ProtoReflect.Descriptor instead. func (*GetAncestors) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{18} + return file_p2p_p2p_proto_rawDescGZIP(), []int{17} } func (x *GetAncestors) GetChainId() []byte { @@ -1803,7 +1736,7 @@ type Ancestors struct { func (x *Ancestors) Reset() { *x = Ancestors{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[19] + mi := &file_p2p_p2p_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1816,7 +1749,7 @@ func (x *Ancestors) String() string { func (*Ancestors) ProtoMessage() {} func (x *Ancestors) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[19] + mi := &file_p2p_p2p_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1829,7 +1762,7 @@ func (x *Ancestors) ProtoReflect() protoreflect.Message { // Deprecated: Use Ancestors.ProtoReflect.Descriptor instead. func (*Ancestors) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{19} + return file_p2p_p2p_proto_rawDescGZIP(), []int{18} } func (x *Ancestors) GetChainId() []byte { @@ -1874,7 +1807,7 @@ type Get struct { func (x *Get) Reset() { *x = Get{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[20] + mi := &file_p2p_p2p_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1887,7 +1820,7 @@ func (x *Get) String() string { func (*Get) ProtoMessage() {} func (x *Get) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[20] + mi := &file_p2p_p2p_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1900,7 +1833,7 @@ func (x *Get) ProtoReflect() protoreflect.Message { // Deprecated: Use Get.ProtoReflect.Descriptor instead. func (*Get) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{20} + return file_p2p_p2p_proto_rawDescGZIP(), []int{19} } func (x *Get) GetChainId() []byte { @@ -1948,7 +1881,7 @@ type Put struct { func (x *Put) Reset() { *x = Put{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[21] + mi := &file_p2p_p2p_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1961,7 +1894,7 @@ func (x *Put) String() string { func (*Put) ProtoMessage() {} func (x *Put) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[21] + mi := &file_p2p_p2p_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1974,7 +1907,7 @@ func (x *Put) ProtoReflect() protoreflect.Message { // Deprecated: Use Put.ProtoReflect.Descriptor instead. func (*Put) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{21} + return file_p2p_p2p_proto_rawDescGZIP(), []int{20} } func (x *Put) GetChainId() []byte { @@ -2021,7 +1954,7 @@ type PushQuery struct { func (x *PushQuery) Reset() { *x = PushQuery{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[22] + mi := &file_p2p_p2p_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2034,7 +1967,7 @@ func (x *PushQuery) String() string { func (*PushQuery) ProtoMessage() {} func (x *PushQuery) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[22] + mi := &file_p2p_p2p_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2047,7 +1980,7 @@ func (x *PushQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PushQuery.ProtoReflect.Descriptor instead. func (*PushQuery) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{22} + return file_p2p_p2p_proto_rawDescGZIP(), []int{21} } func (x *PushQuery) GetChainId() []byte { @@ -2108,7 +2041,7 @@ type PullQuery struct { func (x *PullQuery) Reset() { *x = PullQuery{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[23] + mi := &file_p2p_p2p_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2121,7 +2054,7 @@ func (x *PullQuery) String() string { func (*PullQuery) ProtoMessage() {} func (x *PullQuery) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[23] + mi := &file_p2p_p2p_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2134,7 +2067,7 @@ func (x *PullQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PullQuery.ProtoReflect.Descriptor instead. func (*PullQuery) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{23} + return file_p2p_p2p_proto_rawDescGZIP(), []int{22} } func (x *PullQuery) GetChainId() []byte { @@ -2194,7 +2127,7 @@ type Chits struct { func (x *Chits) Reset() { *x = Chits{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[24] + mi := &file_p2p_p2p_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2207,7 +2140,7 @@ func (x *Chits) String() string { func (*Chits) ProtoMessage() {} func (x *Chits) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[24] + mi := &file_p2p_p2p_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2220,7 +2153,7 @@ func (x *Chits) ProtoReflect() protoreflect.Message { // Deprecated: Use Chits.ProtoReflect.Descriptor instead. func (*Chits) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{24} + return file_p2p_p2p_proto_rawDescGZIP(), []int{23} } func (x *Chits) GetChainId() []byte { @@ -2280,7 +2213,7 @@ type AppRequest struct { func (x *AppRequest) Reset() { *x = AppRequest{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[25] + mi := &file_p2p_p2p_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2293,7 +2226,7 @@ func (x *AppRequest) String() string { func (*AppRequest) ProtoMessage() {} func (x *AppRequest) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[25] + mi := &file_p2p_p2p_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2306,7 +2239,7 @@ func (x *AppRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AppRequest.ProtoReflect.Descriptor instead. func (*AppRequest) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{25} + return file_p2p_p2p_proto_rawDescGZIP(), []int{24} } func (x *AppRequest) GetChainId() []byte { @@ -2354,7 +2287,7 @@ type AppResponse struct { func (x *AppResponse) Reset() { *x = AppResponse{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[26] + mi := &file_p2p_p2p_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2367,7 +2300,7 @@ func (x *AppResponse) String() string { func (*AppResponse) ProtoMessage() {} func (x *AppResponse) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[26] + mi := &file_p2p_p2p_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2380,7 +2313,7 @@ func (x *AppResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AppResponse.ProtoReflect.Descriptor instead. func (*AppResponse) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{26} + return file_p2p_p2p_proto_rawDescGZIP(), []int{25} } func (x *AppResponse) GetChainId() []byte { @@ -2423,7 +2356,7 @@ type AppError struct { func (x *AppError) Reset() { *x = AppError{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[27] + mi := &file_p2p_p2p_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2436,7 +2369,7 @@ func (x *AppError) String() string { func (*AppError) ProtoMessage() {} func (x *AppError) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[27] + mi := &file_p2p_p2p_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2449,7 +2382,7 @@ func (x *AppError) ProtoReflect() protoreflect.Message { // Deprecated: Use AppError.ProtoReflect.Descriptor instead. func (*AppError) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{27} + return file_p2p_p2p_proto_rawDescGZIP(), []int{26} } func (x *AppError) GetChainId() []byte { @@ -2495,7 +2428,7 @@ type AppGossip struct { func (x *AppGossip) Reset() { *x = AppGossip{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[28] + mi := &file_p2p_p2p_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2508,7 +2441,7 @@ func (x *AppGossip) String() string { func (*AppGossip) ProtoMessage() {} func (x *AppGossip) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[28] + mi := &file_p2p_p2p_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2521,7 +2454,7 @@ func (x *AppGossip) ProtoReflect() protoreflect.Message { // Deprecated: Use AppGossip.ProtoReflect.Descriptor instead. func (*AppGossip) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{28} + return file_p2p_p2p_proto_rawDescGZIP(), []int{27} } func (x *AppGossip) GetChainId() []byte { @@ -2629,240 +2562,232 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x6f, 0x72, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x08, 0x61, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4a, 0x04, - 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x24, 0x10, 0x25, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x69, + 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x24, 0x10, 0x25, 0x22, 0x24, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, - 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, - 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, - 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, - 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x6e, - 0x67, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0xb3, 0x03, - 0x0a, 0x09, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x79, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x79, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, - 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, - 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x70, 0x5f, 0x73, 0x69, 0x67, 0x6e, - 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, - 0x69, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, 0x0a, - 0x0e, 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x69, 0x70, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x53, - 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, 0x75, - 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, 0x61, - 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, - 0x70, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x12, 0x31, 0x0a, 0x0b, - 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, - 0x1c, 0x0a, 0x0a, 0x69, 0x70, 0x5f, 0x62, 0x6c, 0x73, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x69, 0x70, 0x42, 0x6c, 0x73, 0x53, 0x69, 0x67, 0x4a, 0x04, 0x08, - 0x05, 0x10, 0x06, 0x22, 0x5e, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, - 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, - 0x74, 0x63, 0x68, 0x22, 0x39, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x61, - 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x61, 0x6c, 0x74, 0x22, 0xbd, - 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, - 0x12, 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, - 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, - 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, - 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x40, - 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x31, 0x0a, - 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x73, - 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x10, - 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x61, - 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6c, 0x61, 0x69, - 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, - 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, - 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, - 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, - 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x71, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, - 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, - 0x69, 0x6e, 0x65, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0x6f, 0x0a, 0x10, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x22, 0x8e, 0x01, 0x0a, 0x0b, 0x47, - 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, + 0x22, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, + 0x08, 0x02, 0x10, 0x03, 0x22, 0xb3, 0x03, 0x0a, 0x09, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, + 0x6b, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, + 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x06, 0x6d, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, + 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0f, + 0x69, 0x70, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x69, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0e, 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, + 0x69, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x69, 0x70, + 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x53, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, + 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, + 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, + 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0d, 0x52, + 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x12, 0x23, + 0x0a, 0x0d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, + 0x0b, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, + 0x63, 0x70, 0x73, 0x12, 0x31, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, 0x65, 0x65, + 0x72, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, + 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x0a, 0x69, 0x70, 0x5f, 0x62, 0x6c, 0x73, + 0x5f, 0x73, 0x69, 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x69, 0x70, 0x42, 0x6c, + 0x73, 0x53, 0x69, 0x67, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x5e, 0x0a, 0x06, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, + 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, + 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x39, 0x0a, 0x0b, 0x42, 0x6c, + 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x73, 0x61, 0x6c, 0x74, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, + 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, + 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, + 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, + 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x40, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, 0x65, + 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, + 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, + 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, + 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, + 0x74, 0x52, 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, + 0x73, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, + 0x6e, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, + 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, - 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x69, 0x0a, 0x08, 0x41, - 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, - 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x22, 0x65, 0x0a, 0x09, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, - 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x03, 0x47, 0x65, - 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x04, 0x52, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, + 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x71, 0x0a, + 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, + 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, + 0x22, 0x6f, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, + 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, + 0x64, 0x22, 0x8e, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, + 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, - 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, - 0x22, 0x5d, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, - 0xb0, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, - 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, - 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4a, 0x04, 0x08, 0x05, - 0x10, 0x06, 0x22, 0xb5, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, - 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, - 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xba, 0x01, 0x0a, 0x05, 0x43, - 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x05, + 0x10, 0x06, 0x22, 0x69, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, + 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x22, 0xb9, 0x01, + 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, + 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x65, 0x0a, 0x09, 0x41, 0x6e, 0x63, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, + 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, + 0x22, 0x84, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, + 0x64, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x5d, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0xb0, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, - 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, - 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, - 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, - 0x69, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x41, - 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, - 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, - 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, - 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, - 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, + 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xb5, 0x01, 0x0a, 0x09, 0x50, 0x75, + 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x88, - 0x01, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4a, 0x04, 0x08, 0x05, 0x10, + 0x06, 0x22, 0xba, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, 0x0a, 0x09, 0x41, 0x70, 0x70, - 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, - 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x5d, - 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, - 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x47, - 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, 0x41, 0x4c, 0x41, 0x4e, 0x43, - 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, 0x10, 0x02, 0x42, 0x2e, 0x5a, - 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, - 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x32, 0x70, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, + 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x7f, + 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, + 0x6e, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, + 0x64, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, + 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x43, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, + 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x41, 0x56, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, + 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, + 0x41, 0x4e, 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, + 0x2f, 0x70, 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2878,75 +2803,73 @@ func file_p2p_p2p_proto_rawDescGZIP() []byte { } var file_p2p_p2p_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_p2p_p2p_proto_msgTypes = make([]protoimpl.MessageInfo, 29) +var file_p2p_p2p_proto_msgTypes = make([]protoimpl.MessageInfo, 28) var file_p2p_p2p_proto_goTypes = []interface{}{ (EngineType)(0), // 0: p2p.EngineType (*Message)(nil), // 1: p2p.Message (*Ping)(nil), // 2: p2p.Ping - (*SubnetUptime)(nil), // 3: p2p.SubnetUptime - (*Pong)(nil), // 4: p2p.Pong - (*Handshake)(nil), // 5: p2p.Handshake - (*Client)(nil), // 6: p2p.Client - (*BloomFilter)(nil), // 7: p2p.BloomFilter - (*ClaimedIpPort)(nil), // 8: p2p.ClaimedIpPort - (*GetPeerList)(nil), // 9: p2p.GetPeerList - (*PeerList)(nil), // 10: p2p.PeerList - (*GetStateSummaryFrontier)(nil), // 11: p2p.GetStateSummaryFrontier - (*StateSummaryFrontier)(nil), // 12: p2p.StateSummaryFrontier - (*GetAcceptedStateSummary)(nil), // 13: p2p.GetAcceptedStateSummary - (*AcceptedStateSummary)(nil), // 14: p2p.AcceptedStateSummary - (*GetAcceptedFrontier)(nil), // 15: p2p.GetAcceptedFrontier - (*AcceptedFrontier)(nil), // 16: p2p.AcceptedFrontier - (*GetAccepted)(nil), // 17: p2p.GetAccepted - (*Accepted)(nil), // 18: p2p.Accepted - (*GetAncestors)(nil), // 19: p2p.GetAncestors - (*Ancestors)(nil), // 20: p2p.Ancestors - (*Get)(nil), // 21: p2p.Get - (*Put)(nil), // 22: p2p.Put - (*PushQuery)(nil), // 23: p2p.PushQuery - (*PullQuery)(nil), // 24: p2p.PullQuery - (*Chits)(nil), // 25: p2p.Chits - (*AppRequest)(nil), // 26: p2p.AppRequest - (*AppResponse)(nil), // 27: p2p.AppResponse - (*AppError)(nil), // 28: p2p.AppError - (*AppGossip)(nil), // 29: p2p.AppGossip + (*Pong)(nil), // 3: p2p.Pong + (*Handshake)(nil), // 4: p2p.Handshake + (*Client)(nil), // 5: p2p.Client + (*BloomFilter)(nil), // 6: p2p.BloomFilter + (*ClaimedIpPort)(nil), // 7: p2p.ClaimedIpPort + (*GetPeerList)(nil), // 8: p2p.GetPeerList + (*PeerList)(nil), // 9: p2p.PeerList + (*GetStateSummaryFrontier)(nil), // 10: p2p.GetStateSummaryFrontier + (*StateSummaryFrontier)(nil), // 11: p2p.StateSummaryFrontier + (*GetAcceptedStateSummary)(nil), // 12: p2p.GetAcceptedStateSummary + (*AcceptedStateSummary)(nil), // 13: p2p.AcceptedStateSummary + (*GetAcceptedFrontier)(nil), // 14: p2p.GetAcceptedFrontier + (*AcceptedFrontier)(nil), // 15: p2p.AcceptedFrontier + (*GetAccepted)(nil), // 16: p2p.GetAccepted + (*Accepted)(nil), // 17: p2p.Accepted + (*GetAncestors)(nil), // 18: p2p.GetAncestors + (*Ancestors)(nil), // 19: p2p.Ancestors + (*Get)(nil), // 20: p2p.Get + (*Put)(nil), // 21: p2p.Put + (*PushQuery)(nil), // 22: p2p.PushQuery + (*PullQuery)(nil), // 23: p2p.PullQuery + (*Chits)(nil), // 24: p2p.Chits + (*AppRequest)(nil), // 25: p2p.AppRequest + (*AppResponse)(nil), // 26: p2p.AppResponse + (*AppError)(nil), // 27: p2p.AppError + (*AppGossip)(nil), // 28: p2p.AppGossip } var file_p2p_p2p_proto_depIdxs = []int32{ 2, // 0: p2p.Message.ping:type_name -> p2p.Ping - 4, // 1: p2p.Message.pong:type_name -> p2p.Pong - 5, // 2: p2p.Message.handshake:type_name -> p2p.Handshake - 9, // 3: p2p.Message.get_peer_list:type_name -> p2p.GetPeerList - 10, // 4: p2p.Message.peer_list:type_name -> p2p.PeerList - 11, // 5: p2p.Message.get_state_summary_frontier:type_name -> p2p.GetStateSummaryFrontier - 12, // 6: p2p.Message.state_summary_frontier:type_name -> p2p.StateSummaryFrontier - 13, // 7: p2p.Message.get_accepted_state_summary:type_name -> p2p.GetAcceptedStateSummary - 14, // 8: p2p.Message.accepted_state_summary:type_name -> p2p.AcceptedStateSummary - 15, // 9: p2p.Message.get_accepted_frontier:type_name -> p2p.GetAcceptedFrontier - 16, // 10: p2p.Message.accepted_frontier:type_name -> p2p.AcceptedFrontier - 17, // 11: p2p.Message.get_accepted:type_name -> p2p.GetAccepted - 18, // 12: p2p.Message.accepted:type_name -> p2p.Accepted - 19, // 13: p2p.Message.get_ancestors:type_name -> p2p.GetAncestors - 20, // 14: p2p.Message.ancestors:type_name -> p2p.Ancestors - 21, // 15: p2p.Message.get:type_name -> p2p.Get - 22, // 16: p2p.Message.put:type_name -> p2p.Put - 23, // 17: p2p.Message.push_query:type_name -> p2p.PushQuery - 24, // 18: p2p.Message.pull_query:type_name -> p2p.PullQuery - 25, // 19: p2p.Message.chits:type_name -> p2p.Chits - 26, // 20: p2p.Message.app_request:type_name -> p2p.AppRequest - 27, // 21: p2p.Message.app_response:type_name -> p2p.AppResponse - 29, // 22: p2p.Message.app_gossip:type_name -> p2p.AppGossip - 28, // 23: p2p.Message.app_error:type_name -> p2p.AppError - 3, // 24: p2p.Ping.subnet_uptimes:type_name -> p2p.SubnetUptime - 6, // 25: p2p.Handshake.client:type_name -> p2p.Client - 7, // 26: p2p.Handshake.known_peers:type_name -> p2p.BloomFilter - 7, // 27: p2p.GetPeerList.known_peers:type_name -> p2p.BloomFilter - 8, // 28: p2p.PeerList.claimed_ip_ports:type_name -> p2p.ClaimedIpPort - 0, // 29: p2p.GetAncestors.engine_type:type_name -> p2p.EngineType - 30, // [30:30] is the sub-list for method output_type - 30, // [30:30] is the sub-list for method input_type - 30, // [30:30] is the sub-list for extension type_name - 30, // [30:30] is the sub-list for extension extendee - 0, // [0:30] is the sub-list for field type_name + 3, // 1: p2p.Message.pong:type_name -> p2p.Pong + 4, // 2: p2p.Message.handshake:type_name -> p2p.Handshake + 8, // 3: p2p.Message.get_peer_list:type_name -> p2p.GetPeerList + 9, // 4: p2p.Message.peer_list:type_name -> p2p.PeerList + 10, // 5: p2p.Message.get_state_summary_frontier:type_name -> p2p.GetStateSummaryFrontier + 11, // 6: p2p.Message.state_summary_frontier:type_name -> p2p.StateSummaryFrontier + 12, // 7: p2p.Message.get_accepted_state_summary:type_name -> p2p.GetAcceptedStateSummary + 13, // 8: p2p.Message.accepted_state_summary:type_name -> p2p.AcceptedStateSummary + 14, // 9: p2p.Message.get_accepted_frontier:type_name -> p2p.GetAcceptedFrontier + 15, // 10: p2p.Message.accepted_frontier:type_name -> p2p.AcceptedFrontier + 16, // 11: p2p.Message.get_accepted:type_name -> p2p.GetAccepted + 17, // 12: p2p.Message.accepted:type_name -> p2p.Accepted + 18, // 13: p2p.Message.get_ancestors:type_name -> p2p.GetAncestors + 19, // 14: p2p.Message.ancestors:type_name -> p2p.Ancestors + 20, // 15: p2p.Message.get:type_name -> p2p.Get + 21, // 16: p2p.Message.put:type_name -> p2p.Put + 22, // 17: p2p.Message.push_query:type_name -> p2p.PushQuery + 23, // 18: p2p.Message.pull_query:type_name -> p2p.PullQuery + 24, // 19: p2p.Message.chits:type_name -> p2p.Chits + 25, // 20: p2p.Message.app_request:type_name -> p2p.AppRequest + 26, // 21: p2p.Message.app_response:type_name -> p2p.AppResponse + 28, // 22: p2p.Message.app_gossip:type_name -> p2p.AppGossip + 27, // 23: p2p.Message.app_error:type_name -> p2p.AppError + 5, // 24: p2p.Handshake.client:type_name -> p2p.Client + 6, // 25: p2p.Handshake.known_peers:type_name -> p2p.BloomFilter + 6, // 26: p2p.GetPeerList.known_peers:type_name -> p2p.BloomFilter + 7, // 27: p2p.PeerList.claimed_ip_ports:type_name -> p2p.ClaimedIpPort + 0, // 28: p2p.GetAncestors.engine_type:type_name -> p2p.EngineType + 29, // [29:29] is the sub-list for method output_type + 29, // [29:29] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 29, // [29:29] is the sub-list for extension extendee + 0, // [0:29] is the sub-list for field type_name } func init() { file_p2p_p2p_proto_init() } @@ -2980,18 +2903,6 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SubnetUptime); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_p2p_p2p_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Pong); i { case 0: return &v.state @@ -3003,7 +2914,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Handshake); i { case 0: return &v.state @@ -3015,7 +2926,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Client); i { case 0: return &v.state @@ -3027,7 +2938,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BloomFilter); i { case 0: return &v.state @@ -3039,7 +2950,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ClaimedIpPort); i { case 0: return &v.state @@ -3051,7 +2962,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetPeerList); i { case 0: return &v.state @@ -3063,7 +2974,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PeerList); i { case 0: return &v.state @@ -3075,7 +2986,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetStateSummaryFrontier); i { case 0: return &v.state @@ -3087,7 +2998,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StateSummaryFrontier); i { case 0: return &v.state @@ -3099,7 +3010,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetAcceptedStateSummary); i { case 0: return &v.state @@ -3111,7 +3022,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AcceptedStateSummary); i { case 0: return &v.state @@ -3123,7 +3034,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetAcceptedFrontier); i { case 0: return &v.state @@ -3135,7 +3046,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AcceptedFrontier); i { case 0: return &v.state @@ -3147,7 +3058,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetAccepted); i { case 0: return &v.state @@ -3159,7 +3070,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Accepted); i { case 0: return &v.state @@ -3171,7 +3082,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetAncestors); i { case 0: return &v.state @@ -3183,7 +3094,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Ancestors); i { case 0: return &v.state @@ -3195,7 +3106,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Get); i { case 0: return &v.state @@ -3207,7 +3118,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Put); i { case 0: return &v.state @@ -3219,7 +3130,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PushQuery); i { case 0: return &v.state @@ -3231,7 +3142,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PullQuery); i { case 0: return &v.state @@ -3243,7 +3154,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Chits); i { case 0: return &v.state @@ -3255,7 +3166,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AppRequest); i { case 0: return &v.state @@ -3267,7 +3178,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AppResponse); i { case 0: return &v.state @@ -3279,7 +3190,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AppError); i { case 0: return &v.state @@ -3291,7 +3202,7 @@ func file_p2p_p2p_proto_init() { return nil } } - file_p2p_p2p_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + file_p2p_p2p_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AppGossip); i { case 0: return &v.state @@ -3337,7 +3248,7 @@ func file_p2p_p2p_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_p2p_p2p_proto_rawDesc, NumEnums: 1, - NumMessages: 29, + NumMessages: 28, NumExtensions: 0, NumServices: 0, }, From a2f69d07c143400add24c2fc8ebc04e914e96769 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 25 Jul 2024 21:06:06 +0300 Subject: [PATCH 04/21] remove subnet uptimes from api --- api/info/client.go | 8 +++----- api/info/service.go | 9 ++------- api/info/service.md | 14 +------------- 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/api/info/client.go b/api/info/client.go index 15812cd5c213..b4c6c58d31c6 100644 --- a/api/info/client.go +++ b/api/info/client.go @@ -27,7 +27,7 @@ type Client interface { Peers(context.Context, ...rpc.Option) ([]Peer, error) IsBootstrapped(context.Context, string, ...rpc.Option) (bool, error) GetTxFee(context.Context, ...rpc.Option) (*GetTxFeeResponse, error) - Uptime(context.Context, ids.ID, ...rpc.Option) (*UptimeResponse, error) + Uptime(context.Context, ...rpc.Option) (*UptimeResponse, error) GetVMs(context.Context, ...rpc.Option) (map[ids.ID][]string, error) } @@ -101,11 +101,9 @@ func (c *client) GetTxFee(ctx context.Context, options ...rpc.Option) (*GetTxFee return res, err } -func (c *client) Uptime(ctx context.Context, subnetID ids.ID, options ...rpc.Option) (*UptimeResponse, error) { +func (c *client) Uptime(ctx context.Context, options ...rpc.Option) (*UptimeResponse, error) { res := &UptimeResponse{} - err := c.requester.SendRequest(ctx, "info.uptime", &UptimeRequest{ - SubnetID: subnetID, - }, res, options...) + err := c.requester.SendRequest(ctx, "info.uptime", struct{}{}, res, options...) return res, err } diff --git a/api/info/service.go b/api/info/service.go index fd0117c5a088..5f9e4b73934d 100644 --- a/api/info/service.go +++ b/api/info/service.go @@ -307,18 +307,13 @@ type UptimeResponse struct { WeightedAveragePercentage json.Float64 `json:"weightedAveragePercentage"` } -type UptimeRequest struct { - // if omitted, defaults to primary network - SubnetID ids.ID `json:"subnetID"` -} - -func (i *Info) Uptime(_ *http.Request, args *UptimeRequest, reply *UptimeResponse) error { +func (i *Info) Uptime(_ *http.Request, _ *struct{}, reply *UptimeResponse) error { i.log.Debug("API called", zap.String("service", "info"), zap.String("method", "uptime"), ) - result, err := i.networking.NodeUptime(args.SubnetID) + result, err := i.networking.NodeUptime() if err != nil { return fmt.Errorf("couldn't get node uptime: %w", err) } diff --git a/api/info/service.md b/api/info/service.md index d7e70e269dff..f3d56bdf1061 100644 --- a/api/info/service.md +++ b/api/info/service.md @@ -526,7 +526,6 @@ info.peers({ lastReceived: string, benched: string[], observedUptime: int, - observedSubnetUptime: map[string]int, } } ``` @@ -542,7 +541,6 @@ info.peers({ - `lastReceived` is the timestamp of last message received from the peer. - `benched` shows chain IDs that the peer is being benched. - `observedUptime` is this node's primary network uptime, observed by the peer. -- `observedSubnetUptime` is a map of Subnet IDs to this node's Subnet uptimes, observed by the peer. **Example Call:** @@ -575,7 +573,6 @@ curl -X POST --data '{ "lastReceived": "2020-06-01T15:22:57Z", "benched": [], "observedUptime": "99", - "observedSubnetUptimes": {}, "trackedSubnets": [], "benched": [] }, @@ -588,9 +585,6 @@ curl -X POST --data '{ "lastReceived": "2020-06-01T15:22:34Z", "benched": [], "observedUptime": "75", - "observedSubnetUptimes": { - "29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL": "100" - }, "trackedSubnets": [ "29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL" ], @@ -605,7 +599,6 @@ curl -X POST --data '{ "lastReceived": "2020-06-01T15:22:55Z", "benched": [], "observedUptime": "95", - "observedSubnetUptimes": {}, "trackedSubnets": [], "benched": [] } @@ -623,18 +616,13 @@ Other sources may be using data gathered with incomplete (limited) information. **Signature:** ```sh -info.uptime({ - subnetID: string // optional -}) -> +info.uptime() -> { rewardingStakePercentage: float64, weightedAveragePercentage: float64 } ``` -- `subnetID` is the Subnet to get the uptime of. If not provided, returns the uptime of the node on - the primary network. - - `rewardingStakePercentage` is the percent of stake which thinks this node is above the uptime requirement. - `weightedAveragePercentage` is the stake-weighted average of all observed uptimes for this node. From ee287c6d0868df860b9542fc3a40f5512ffb6f4b Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 25 Jul 2024 21:06:16 +0300 Subject: [PATCH 05/21] add tracked bool --- snow/uptime/locked_calculator_test.go | 6 +++--- snow/uptime/manager.go | 18 ++++++++++++++++++ snow/uptime/mock_calculator.go | 24 ++++++++++++------------ 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/snow/uptime/locked_calculator_test.go b/snow/uptime/locked_calculator_test.go index 9e5edaad8c63..c65fb084cddb 100644 --- a/snow/uptime/locked_calculator_test.go +++ b/snow/uptime/locked_calculator_test.go @@ -50,15 +50,15 @@ func TestLockedCalculator(t *testing.T) { isBootstrapped.Set(true) // Should return the value from the mocked inner calculator - mockCalc.EXPECT().CalculateUptime(gomock.Any(), gomock.Any()).AnyTimes().Return(time.Duration(0), time.Time{}, errTest) + mockCalc.EXPECT().CalculateUptime(gomock.Any()).AnyTimes().Return(time.Duration(0), time.Time{}, errTest) _, _, err = lc.CalculateUptime(nodeID) require.ErrorIs(err, errTest) - mockCalc.EXPECT().CalculateUptimePercent(gomock.Any(), gomock.Any()).AnyTimes().Return(float64(0), errTest) + mockCalc.EXPECT().CalculateUptimePercent(gomock.Any()).AnyTimes().Return(float64(0), errTest) _, err = lc.CalculateUptimePercent(nodeID) require.ErrorIs(err, errTest) - mockCalc.EXPECT().CalculateUptimePercentFrom(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(float64(0), errTest) + mockCalc.EXPECT().CalculateUptimePercentFrom(gomock.Any(), gomock.Any()).AnyTimes().Return(float64(0), errTest) _, err = lc.CalculateUptimePercentFrom(nodeID, time.Now()) require.ErrorIs(err, errTest) } diff --git a/snow/uptime/manager.go b/snow/uptime/manager.go index 2a915da3fb6c..93aaa4a1b139 100644 --- a/snow/uptime/manager.go +++ b/snow/uptime/manager.go @@ -40,6 +40,7 @@ type manager struct { state State connections map[ids.NodeID]time.Time // nodeID -> time + tracked bool } func NewManager(state State, clk *mockable.Clock) Manager { @@ -70,10 +71,18 @@ func (m *manager) StartTracking(nodeIDs []ids.NodeID) error { return err } } + m.tracked = true return nil } func (m *manager) StopTracking(nodeIDs []ids.NodeID) error { + // TODO: this was not here before, should we add it? + if !m.tracked { + return nil + } + defer func() { + m.tracked = false + }() now := m.clock.UnixTime() for _, nodeID := range nodeIDs { // If the node is already connected, then we can just @@ -139,6 +148,12 @@ func (m *manager) CalculateUptime(nodeID ids.NodeID) (time.Duration, time.Time, return upDuration, lastUpdated, nil } + if !m.tracked { + durationOffline := now.Sub(lastUpdated) + newUpDuration := upDuration + durationOffline + return newUpDuration, now, nil + } + timeConnected, isConnected := m.connections[nodeID] if !isConnected { return upDuration, now, nil @@ -187,6 +202,9 @@ func (m *manager) CalculateUptimePercentFrom(nodeID ids.NodeID, startTime time.T // updateUptime updates the uptime of the node on the state by the amount // of time that the node has been connected. func (m *manager) updateUptime(nodeID ids.NodeID) error { + if !m.tracked { + return nil + } newDuration, newLastUpdated, err := m.CalculateUptime(nodeID) if err == database.ErrNotFound { // If a non-validator disconnects, we don't care diff --git a/snow/uptime/mock_calculator.go b/snow/uptime/mock_calculator.go index cc5b5942e639..5e2485cc6ddb 100644 --- a/snow/uptime/mock_calculator.go +++ b/snow/uptime/mock_calculator.go @@ -41,9 +41,9 @@ func (m *MockCalculator) EXPECT() *MockCalculatorMockRecorder { } // CalculateUptime mocks base method. -func (m *MockCalculator) CalculateUptime(arg0 ids.NodeID, arg1 ids.ID) (time.Duration, time.Time, error) { +func (m *MockCalculator) CalculateUptime(arg0 ids.NodeID) (time.Duration, time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CalculateUptime", arg0, arg1) + ret := m.ctrl.Call(m, "CalculateUptime", arg0) ret0, _ := ret[0].(time.Duration) ret1, _ := ret[1].(time.Time) ret2, _ := ret[2].(error) @@ -51,37 +51,37 @@ func (m *MockCalculator) CalculateUptime(arg0 ids.NodeID, arg1 ids.ID) (time.Dur } // CalculateUptime indicates an expected call of CalculateUptime. -func (mr *MockCalculatorMockRecorder) CalculateUptime(arg0, arg1 any) *gomock.Call { +func (mr *MockCalculatorMockRecorder) CalculateUptime(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateUptime", reflect.TypeOf((*MockCalculator)(nil).CalculateUptime), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateUptime", reflect.TypeOf((*MockCalculator)(nil).CalculateUptime), arg0) } // CalculateUptimePercent mocks base method. -func (m *MockCalculator) CalculateUptimePercent(arg0 ids.NodeID, arg1 ids.ID) (float64, error) { +func (m *MockCalculator) CalculateUptimePercent(arg0 ids.NodeID) (float64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CalculateUptimePercent", arg0, arg1) + ret := m.ctrl.Call(m, "CalculateUptimePercent", arg0) ret0, _ := ret[0].(float64) ret1, _ := ret[1].(error) return ret0, ret1 } // CalculateUptimePercent indicates an expected call of CalculateUptimePercent. -func (mr *MockCalculatorMockRecorder) CalculateUptimePercent(arg0, arg1 any) *gomock.Call { +func (mr *MockCalculatorMockRecorder) CalculateUptimePercent(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateUptimePercent", reflect.TypeOf((*MockCalculator)(nil).CalculateUptimePercent), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateUptimePercent", reflect.TypeOf((*MockCalculator)(nil).CalculateUptimePercent), arg0) } // CalculateUptimePercentFrom mocks base method. -func (m *MockCalculator) CalculateUptimePercentFrom(arg0 ids.NodeID, arg1 ids.ID, arg2 time.Time) (float64, error) { +func (m *MockCalculator) CalculateUptimePercentFrom(arg0 ids.NodeID, arg1 time.Time) (float64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CalculateUptimePercentFrom", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "CalculateUptimePercentFrom", arg0, arg1) ret0, _ := ret[0].(float64) ret1, _ := ret[1].(error) return ret0, ret1 } // CalculateUptimePercentFrom indicates an expected call of CalculateUptimePercentFrom. -func (mr *MockCalculatorMockRecorder) CalculateUptimePercentFrom(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockCalculatorMockRecorder) CalculateUptimePercentFrom(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateUptimePercentFrom", reflect.TypeOf((*MockCalculator)(nil).CalculateUptimePercentFrom), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateUptimePercentFrom", reflect.TypeOf((*MockCalculator)(nil).CalculateUptimePercentFrom), arg0, arg1) } From a42e48cff65d5538fd535ddda18591f4702a787b Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Fri, 26 Jul 2024 16:10:18 +0300 Subject: [PATCH 06/21] remove unnecessary err --- network/network.go | 1 - 1 file changed, 1 deletion(-) diff --git a/network/network.go b/network/network.go index e92bc248a218..6567454cf6c2 100644 --- a/network/network.go +++ b/network/network.go @@ -52,7 +52,6 @@ var ( _ Network = (*network)(nil) errNotValidator = errors.New("node is not a validator") - errNotTracked = errors.New("subnet is not tracked") errExpectedProxy = errors.New("expected proxy") errExpectedTCPProtocol = errors.New("expected TCP protocol") ) From 4c542af29714708692f2ca8342e89a26ba25c90e Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Sat, 27 Jul 2024 00:02:49 +0300 Subject: [PATCH 07/21] remove connected subnet msg --- chains/manager.go | 11 +- message/internal_msg_builder.go | 26 ---- message/ops.go | 5 - snow/networking/handler/handler.go | 7 - snow/networking/handler/handler_test.go | 99 -------------- snow/networking/handler/health_test.go | 1 - snow/networking/handler/message_queue.go | 2 +- snow/networking/router/chain_router.go | 61 --------- snow/networking/router/chain_router_test.go | 123 ------------------ snow/networking/sender/sender_test.go | 3 - snow/validators/mock_subnet_connector.go | 55 -------- snow/validators/subnet_connector.go | 16 --- snow/validators/unhandled_subnet_connector.go | 23 ---- vms/platformvm/vm.go | 11 +- vms/platformvm/vm_test.go | 1 - 15 files changed, 5 insertions(+), 439 deletions(-) delete mode 100644 snow/validators/mock_subnet_connector.go delete mode 100644 snow/validators/subnet_connector.go delete mode 100644 snow/validators/unhandled_subnet_connector.go diff --git a/chains/manager.go b/chains/manager.go index bdc6d0ef0180..a87396d1b65e 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -897,7 +897,6 @@ func (m *manager) createAvalancheChain( m.FrontierPollFrequency, m.ConsensusAppConcurrency, m.ResourceTracker, - validators.UnhandledSubnetConnector, // avalanche chains don't use subnet connector sb, connectedValidators, peerTracker, @@ -1108,8 +1107,7 @@ func (m *manager) createSnowmanChain( } var ( - bootstrapFunc func() - subnetConnector = validators.UnhandledSubnetConnector + bootstrapFunc func() ) // If [m.validatorState] is nil then we are creating the P-Chain. Since the // P-Chain is the first chain to be created, we can use it to initialize @@ -1147,12 +1145,6 @@ func (m *manager) createSnowmanChain( bootstrapFunc = func() { close(m.unblockChainCreatorCh) } - - // Set up the subnet connector for the P-Chain - subnetConnector, ok = vm.(validators.SubnetConnector) - if !ok { - return nil, fmt.Errorf("expected validators.SubnetConnector but got %T", vm) - } } // Initialize the ProposerVM and the vm wrapped inside it @@ -1295,7 +1287,6 @@ func (m *manager) createSnowmanChain( m.FrontierPollFrequency, m.ConsensusAppConcurrency, m.ResourceTracker, - subnetConnector, sb, connectedValidators, peerTracker, diff --git a/message/internal_msg_builder.go b/message/internal_msg_builder.go index 141dabaae414..bd71b60bf4ca 100644 --- a/message/internal_msg_builder.go +++ b/message/internal_msg_builder.go @@ -493,32 +493,6 @@ func InternalConnected(nodeID ids.NodeID, nodeVersion *version.Application) Inbo } } -// ConnectedSubnet contains the subnet ID of the subnet that the node is -// connected to. -type ConnectedSubnet struct { - SubnetID ids.ID `json:"subnet_id,omitempty"` -} - -func (m *ConnectedSubnet) String() string { - return fmt.Sprintf( - "SubnetID: %s", - m.SubnetID, - ) -} - -// InternalConnectedSubnet returns a message that indicates the node with [nodeID] is -// connected to the subnet with the given [subnetID]. -func InternalConnectedSubnet(nodeID ids.NodeID, subnetID ids.ID) InboundMessage { - return &inboundMessage{ - nodeID: nodeID, - op: ConnectedSubnetOp, - message: &ConnectedSubnet{ - SubnetID: subnetID, - }, - expiration: mockable.MaxTime, - } -} - type Disconnected struct{} func (Disconnected) String() string { diff --git a/message/ops.go b/message/ops.go index 11c69087b5f8..4e6fff95426a 100644 --- a/message/ops.go +++ b/message/ops.go @@ -60,7 +60,6 @@ const ( CrossChainAppResponseOp // Internal: ConnectedOp - ConnectedSubnetOp DisconnectedOp NotifyOp GossipRequestOp @@ -120,7 +119,6 @@ var ( CrossChainAppErrorOp, CrossChainAppResponseOp, ConnectedOp, - ConnectedSubnetOp, DisconnectedOp, NotifyOp, GossipRequestOp, @@ -158,7 +156,6 @@ var ( ChitsOp, // Internal ConnectedOp, - ConnectedSubnetOp, DisconnectedOp, } @@ -281,8 +278,6 @@ func (op Op) String() string { // Internal case ConnectedOp: return "connected" - case ConnectedSubnetOp: - return "connected_subnet" case DisconnectedOp: return "disconnected" case NotifyOp: diff --git a/snow/networking/handler/handler.go b/snow/networking/handler/handler.go index 1eb42ca0dcdc..c9176ef92343 100644 --- a/snow/networking/handler/handler.go +++ b/snow/networking/handler/handler.go @@ -118,8 +118,6 @@ type handler struct { // Closed when this handler and [engine] are done shutting down closed chan struct{} - subnetConnector validators.SubnetConnector - subnet subnets.Subnet // Tracks the peers that are currently connected to this subnet @@ -136,7 +134,6 @@ func New( gossipFrequency time.Duration, threadPoolSize int, resourceTracker tracker.ResourceTracker, - subnetConnector validators.SubnetConnector, subnet subnets.Subnet, peerTracker commontracker.Peers, p2pTracker *p2p.PeerTracker, @@ -152,7 +149,6 @@ func New( closingChan: make(chan struct{}), closed: make(chan struct{}), resourceTracker: resourceTracker, - subnetConnector: subnetConnector, subnet: subnet, peerTracker: peerTracker, p2pTracker: p2pTracker, @@ -769,9 +765,6 @@ func (h *handler) handleSyncMsg(ctx context.Context, msg Message) error { h.p2pTracker.Connected(nodeID, msg.NodeVersion) return engine.Connected(ctx, nodeID, msg.NodeVersion) - case *message.ConnectedSubnet: - return h.subnetConnector.ConnectedSubnet(ctx, nodeID, msg.SubnetID) - case *message.Disconnected: err := h.peerTracker.Disconnected(ctx, nodeID) if err != nil { diff --git a/snow/networking/handler/handler_test.go b/snow/networking/handler/handler_test.go index 929c51780c24..095d09592cec 100644 --- a/snow/networking/handler/handler_test.go +++ b/snow/networking/handler/handler_test.go @@ -12,7 +12,6 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" @@ -73,7 +72,6 @@ func TestHandlerDropsTimedOutMessages(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), peerTracker, @@ -180,7 +178,6 @@ func TestHandlerClosesOnError(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), peerTracker, @@ -283,7 +280,6 @@ func TestHandlerDropsGossipDuringBootstrapping(t *testing.T) { 1, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), peerTracker, @@ -374,7 +370,6 @@ func TestHandlerDispatchInternal(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), peerTracker, @@ -423,98 +418,6 @@ func TestHandlerDispatchInternal(t *testing.T) { wg.Wait() } -func TestHandlerSubnetConnector(t *testing.T) { - require := require.New(t) - - snowCtx := snowtest.Context(t, snowtest.CChainID) - ctx := snowtest.ConsensusContext(snowCtx) - vdrs := validators.NewManager() - require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) - - resourceTracker, err := tracker.NewResourceTracker( - prometheus.NewRegistry(), - resource.NoUsage, - meter.ContinuousFactory{}, - time.Second, - ) - require.NoError(err) - ctrl := gomock.NewController(t) - connector := validators.NewMockSubnetConnector(ctrl) - - nodeID := ids.GenerateTestNodeID() - subnetID := ids.GenerateTestID() - - peerTracker, err := p2p.NewPeerTracker( - logging.NoLog{}, - "", - prometheus.NewRegistry(), - nil, - version.CurrentApp, - ) - require.NoError(err) - - handler, err := New( - ctx, - vdrs, - nil, - time.Second, - testThreadPoolSize, - resourceTracker, - connector, - subnets.New(ctx.NodeID, subnets.Config{}), - commontracker.NewPeers(), - peerTracker, - prometheus.NewRegistry(), - ) - require.NoError(err) - - bootstrapper := &common.BootstrapperTest{ - EngineTest: common.EngineTest{ - T: t, - }, - } - bootstrapper.Default(false) - - engine := &common.EngineTest{T: t} - engine.Default(false) - engine.ContextF = func() *snow.ConsensusContext { - return ctx - } - - handler.SetEngineManager(&EngineManager{ - Snowman: &Engine{ - Bootstrapper: bootstrapper, - Consensus: engine, - }, - }) - ctx.State.Set(snow.EngineState{ - Type: p2ppb.EngineType_ENGINE_TYPE_SNOWMAN, - State: snow.NormalOp, // assumed bootstrap is done - }) - - bootstrapper.StartF = func(context.Context, uint32) error { - return nil - } - - handler.Start(context.Background(), false) - - // Handler should call subnet connector when ConnectedSubnet message is received - var wg sync.WaitGroup - connector.EXPECT().ConnectedSubnet(gomock.Any(), nodeID, subnetID).Do( - func(context.Context, ids.NodeID, ids.ID) { - wg.Done() - }) - - wg.Add(1) - defer wg.Wait() - - subnetInboundMessage := Message{ - InboundMessage: message.InternalConnectedSubnet(nodeID, subnetID), - EngineType: p2ppb.EngineType_ENGINE_TYPE_UNSPECIFIED, - } - handler.Push(context.Background(), subnetInboundMessage) -} - // Tests that messages are routed to the correct engine type func TestDynamicEngineTypeDispatch(t *testing.T) { tests := []struct { @@ -642,7 +545,6 @@ func TestDynamicEngineTypeDispatch(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ids.EmptyNodeID, subnets.Config{}), commontracker.NewPeers(), peerTracker, @@ -725,7 +627,6 @@ func TestHandlerStartError(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - nil, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), peerTracker, diff --git a/snow/networking/handler/health_test.go b/snow/networking/handler/health_test.go index 789d3464187e..a1cce533beee 100644 --- a/snow/networking/handler/health_test.go +++ b/snow/networking/handler/health_test.go @@ -89,7 +89,6 @@ func TestHealthCheckSubnet(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, sb, peerTracker, p2pTracker, diff --git a/snow/networking/handler/message_queue.go b/snow/networking/handler/message_queue.go index 4d632c62d77e..fbf362c86f73 100644 --- a/snow/networking/handler/message_queue.go +++ b/snow/networking/handler/message_queue.go @@ -203,7 +203,7 @@ func (m *messageQueue) Shutdown() { // canPop will return true for at least one message in [m.msgs] func (m *messageQueue) canPop(msg message.InboundMessage) bool { // Always pop connected and disconnected messages. - if op := msg.Op(); op == message.ConnectedOp || op == message.DisconnectedOp || op == message.ConnectedSubnetOp { + if op := msg.Op(); op == message.ConnectedOp || op == message.DisconnectedOp { return true } diff --git a/snow/networking/router/chain_router.go b/snow/networking/router/chain_router.go index 6af0984afc3f..b125800d5ff8 100644 --- a/snow/networking/router/chain_router.go +++ b/snow/networking/router/chain_router.go @@ -50,9 +50,6 @@ type peer struct { version *version.Application // The subnets that this peer is currently tracking trackedSubnets set.Set[ids.ID] - // The subnets that this peer actually has a connection to. - // This is a subset of trackedSubnets. - connectedSubnets set.Set[ids.ID] } // ChainRouter routes incoming messages from the validator network @@ -467,11 +464,6 @@ func (cr *ChainRouter) AddChain(ctx context.Context, chain handler.Handler) { if _, benched := cr.benched[cr.myNodeID]; benched { return } - - myself := cr.peers[cr.myNodeID] - for subnetID := range myself.trackedSubnets { - cr.connectedSubnet(myself, cr.myNodeID, subnetID) - } } // Connected routes an incoming notification that a validator was just connected @@ -526,7 +518,6 @@ func (cr *ChainRouter) Connected(nodeID ids.NodeID, nodeVersion *version.Applica } } - cr.connectedSubnet(connectedPeer, nodeID, subnetID) } // Disconnected routes an incoming notification that a validator was connected @@ -603,8 +594,6 @@ func (cr *ChainRouter) Benched(chainID ids.ID, nodeID ids.NodeID) { }) } } - - peer.connectedSubnets.Clear() } // Unbenched routes an incoming notification that a validator was just unbenched @@ -647,13 +636,6 @@ func (cr *ChainRouter) Unbenched(chainID ids.ID, nodeID ids.NodeID) { }) } } - - // This will unbench the node from all its subnets. - // We handle this case separately because the node may have been benched on - // a subnet that has no chains. - for subnetID := range peer.trackedSubnets { - cr.connectedSubnet(peer, nodeID, subnetID) - } } // HealthCheck returns results of router health checks. Returns: @@ -758,46 +740,3 @@ func (cr *ChainRouter) clearRequest( cr.metrics.outstandingRequests.Set(float64(cr.timedRequests.Len())) return uniqueRequestID, &request } - -// connectedSubnet pushes an InternalSubnetConnected message with [nodeID] and -// [subnetID] to the P-chain. This should be called when a node is either first -// connecting to [subnetID] or when a node that was already connected is -// unbenched on [subnetID]. This is a noop if [subnetID] is the Primary Network -// or if the peer is already marked as connected to the subnet. -// Invariant: should be called after *message.Connected is pushed to the P-chain -// Invariant: should be called after the P-chain was provided in [AddChain] -func (cr *ChainRouter) connectedSubnet(peer *peer, nodeID ids.NodeID, subnetID ids.ID) { - // if connected to primary network, we can skip this - // because Connected has its own internal message - if subnetID == constants.PrimaryNetworkID { - return - } - - // peer already connected to this subnet - if peer.connectedSubnets.Contains(subnetID) { - return - } - - msg := message.InternalConnectedSubnet(nodeID, subnetID) - // We only push this message to the P-chain because it is the only chain - // that cares about the connectivity of all subnets. Others chains learn - // about the connectivity of their own subnet when they receive a - // *message.Connected. - platformChain, ok := cr.chainHandlers[constants.PlatformChainID] - if !ok { - cr.log.Error("trying to issue InternalConnectedSubnet message, but platform chain is not registered", - zap.Stringer("nodeID", nodeID), - zap.Stringer("subnetID", subnetID), - ) - return - } - platformChain.Push( - context.TODO(), - handler.Message{ - InboundMessage: msg, - EngineType: p2p.EngineType_ENGINE_TYPE_UNSPECIFIED, - }, - ) - - peer.connectedSubnets.Add(subnetID) -} diff --git a/snow/networking/router/chain_router_test.go b/snow/networking/router/chain_router_test.go index 7472de1fc016..2039fa46c52c 100644 --- a/snow/networking/router/chain_router_test.go +++ b/snow/networking/router/chain_router_test.go @@ -25,7 +25,6 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" - "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/math/meter" "github.com/ava-labs/avalanchego/utils/resource" @@ -109,7 +108,6 @@ func TestShutdown(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(chainCtx.NodeID, subnets.Config{}), commontracker.NewPeers(), p2pTracker, @@ -235,7 +233,6 @@ func TestConnectedAfterShutdownErrorLogRegression(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(chainCtx.NodeID, subnets.Config{}), commontracker.NewPeers(), p2pTracker, @@ -368,7 +365,6 @@ func TestShutdownTimesOut(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), p2pTracker, @@ -538,7 +534,6 @@ func TestRouterTimeout(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), p2pTracker, @@ -1121,7 +1116,6 @@ func TestValidatorOnlyMessageDrops(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, sb, commontracker.NewPeers(), p2pTracker, @@ -1211,121 +1205,6 @@ func TestValidatorOnlyMessageDrops(t *testing.T) { require.True(calledF) // should be called since this is a validator request } -func TestConnectedSubnet(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) - - tm, err := timeout.NewManager( - &timer.AdaptiveTimeoutConfig{ - InitialTimeout: 3 * time.Second, - MinimumTimeout: 3 * time.Second, - MaximumTimeout: 5 * time.Minute, - TimeoutCoefficient: 1, - TimeoutHalflife: 5 * time.Minute, - }, - benchlist.NewNoBenchlist(), - prometheus.NewRegistry(), - prometheus.NewRegistry(), - ) - require.NoError(err) - - go tm.Dispatch() - defer tm.Stop() - - // Create chain router - myNodeID := ids.GenerateTestNodeID() - peerNodeID := ids.GenerateTestNodeID() - subnetID0 := ids.GenerateTestID() - subnetID1 := ids.GenerateTestID() - trackedSubnets := set.Of(subnetID0, subnetID1) - chainRouter := ChainRouter{} - require.NoError(chainRouter.Initialize( - myNodeID, - logging.NoLog{}, - tm, - time.Millisecond, - set.Set[ids.ID]{}, - true, - trackedSubnets, - nil, - HealthConfig{}, - prometheus.NewRegistry(), - )) - - // Create bootstrapper, engine and handler - snowCtx := snowtest.Context(t, snowtest.PChainID) - ctx := snowtest.ConsensusContext(snowCtx) - ctx.Executing.Set(false) - ctx.State.Set(snow.EngineState{ - Type: engineType, - State: snow.NormalOp, - }) - - myConnectedMsg := handler.Message{ - InboundMessage: message.InternalConnected(myNodeID, version.CurrentApp), - EngineType: p2ppb.EngineType_ENGINE_TYPE_UNSPECIFIED, - } - mySubnetConnectedMsg0 := handler.Message{ - InboundMessage: message.InternalConnectedSubnet(myNodeID, subnetID0), - EngineType: p2ppb.EngineType_ENGINE_TYPE_UNSPECIFIED, - } - mySubnetConnectedMsg1 := handler.Message{ - InboundMessage: message.InternalConnectedSubnet(myNodeID, subnetID1), - EngineType: p2ppb.EngineType_ENGINE_TYPE_UNSPECIFIED, - } - - platformHandler := handler.NewMockHandler(ctrl) - platformHandler.EXPECT().Context().Return(ctx).AnyTimes() - platformHandler.EXPECT().SetOnStopped(gomock.Any()).AnyTimes() - platformHandler.EXPECT().Push(gomock.Any(), myConnectedMsg).Times(1) - platformHandler.EXPECT().Push(gomock.Any(), mySubnetConnectedMsg0).Times(1) - platformHandler.EXPECT().Push(gomock.Any(), mySubnetConnectedMsg1).Times(1) - - chainRouter.AddChain(context.Background(), platformHandler) - - peerConnectedMsg := handler.Message{ - InboundMessage: message.InternalConnected(peerNodeID, version.CurrentApp), - EngineType: p2ppb.EngineType_ENGINE_TYPE_UNSPECIFIED, - } - platformHandler.EXPECT().Push(gomock.Any(), peerConnectedMsg).Times(1) - chainRouter.Connected(peerNodeID, version.CurrentApp, constants.PrimaryNetworkID) - - peerSubnetConnectedMsg0 := handler.Message{ - InboundMessage: message.InternalConnectedSubnet(peerNodeID, subnetID0), - EngineType: p2ppb.EngineType_ENGINE_TYPE_UNSPECIFIED, - } - platformHandler.EXPECT().Push(gomock.Any(), peerSubnetConnectedMsg0).Times(1) - chainRouter.Connected(peerNodeID, version.CurrentApp, subnetID0) - - myDisconnectedMsg := handler.Message{ - InboundMessage: message.InternalDisconnected(myNodeID), - EngineType: p2ppb.EngineType_ENGINE_TYPE_UNSPECIFIED, - } - platformHandler.EXPECT().Push(gomock.Any(), myDisconnectedMsg).Times(1) - chainRouter.Benched(constants.PlatformChainID, myNodeID) - - peerDisconnectedMsg := handler.Message{ - InboundMessage: message.InternalDisconnected(peerNodeID), - EngineType: p2ppb.EngineType_ENGINE_TYPE_UNSPECIFIED, - } - platformHandler.EXPECT().Push(gomock.Any(), peerDisconnectedMsg).Times(1) - chainRouter.Benched(constants.PlatformChainID, peerNodeID) - - platformHandler.EXPECT().Push(gomock.Any(), myConnectedMsg).Times(1) - platformHandler.EXPECT().Push(gomock.Any(), mySubnetConnectedMsg0).Times(1) - platformHandler.EXPECT().Push(gomock.Any(), mySubnetConnectedMsg1).Times(1) - - chainRouter.Unbenched(constants.PlatformChainID, myNodeID) - - platformHandler.EXPECT().Push(gomock.Any(), peerConnectedMsg).Times(1) - platformHandler.EXPECT().Push(gomock.Any(), peerSubnetConnectedMsg0).Times(1) - - chainRouter.Unbenched(constants.PlatformChainID, peerNodeID) - - platformHandler.EXPECT().Push(gomock.Any(), peerDisconnectedMsg).Times(1) - chainRouter.Disconnected(peerNodeID) -} - func TestValidatorOnlyAllowedNodeMessageDrops(t *testing.T) { require := require.New(t) @@ -1402,7 +1281,6 @@ func TestValidatorOnlyAllowedNodeMessageDrops(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, sb, commontracker.NewPeers(), p2pTracker, @@ -1742,7 +1620,6 @@ func newChainRouterTest(t *testing.T) (*ChainRouter, *common.EngineTest) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), p2pTracker, diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index 34f138f6db21..0402bb636505 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -128,7 +128,6 @@ func TestTimeout(t *testing.T) { time.Hour, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), p2pTracker, @@ -405,7 +404,6 @@ func TestReliableMessages(t *testing.T) { 1, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), p2pTracker, @@ -562,7 +560,6 @@ func TestReliableMessagesToMyself(t *testing.T) { time.Second, testThreadPoolSize, resourceTracker, - validators.UnhandledSubnetConnector, subnets.New(ctx.NodeID, subnets.Config{}), commontracker.NewPeers(), p2pTracker, diff --git a/snow/validators/mock_subnet_connector.go b/snow/validators/mock_subnet_connector.go deleted file mode 100644 index b9f3ee0519b8..000000000000 --- a/snow/validators/mock_subnet_connector.go +++ /dev/null @@ -1,55 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/snow/validators (interfaces: SubnetConnector) -// -// Generated by this command: -// -// mockgen -package=validators -destination=snow/validators/mock_subnet_connector.go github.com/ava-labs/avalanchego/snow/validators SubnetConnector -// - -// Package validators is a generated GoMock package. -package validators - -import ( - context "context" - reflect "reflect" - - ids "github.com/ava-labs/avalanchego/ids" - gomock "go.uber.org/mock/gomock" -) - -// MockSubnetConnector is a mock of SubnetConnector interface. -type MockSubnetConnector struct { - ctrl *gomock.Controller - recorder *MockSubnetConnectorMockRecorder -} - -// MockSubnetConnectorMockRecorder is the mock recorder for MockSubnetConnector. -type MockSubnetConnectorMockRecorder struct { - mock *MockSubnetConnector -} - -// NewMockSubnetConnector creates a new mock instance. -func NewMockSubnetConnector(ctrl *gomock.Controller) *MockSubnetConnector { - mock := &MockSubnetConnector{ctrl: ctrl} - mock.recorder = &MockSubnetConnectorMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockSubnetConnector) EXPECT() *MockSubnetConnectorMockRecorder { - return m.recorder -} - -// ConnectedSubnet mocks base method. -func (m *MockSubnetConnector) ConnectedSubnet(arg0 context.Context, arg1 ids.NodeID, arg2 ids.ID) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ConnectedSubnet", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// ConnectedSubnet indicates an expected call of ConnectedSubnet. -func (mr *MockSubnetConnectorMockRecorder) ConnectedSubnet(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectedSubnet", reflect.TypeOf((*MockSubnetConnector)(nil).ConnectedSubnet), arg0, arg1, arg2) -} diff --git a/snow/validators/subnet_connector.go b/snow/validators/subnet_connector.go deleted file mode 100644 index 06b02ff90820..000000000000 --- a/snow/validators/subnet_connector.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package validators - -import ( - "context" - - "github.com/ava-labs/avalanchego/ids" -) - -// SubnetConnector represents a handler that is called when a connection is -// marked as connected to a subnet -type SubnetConnector interface { - ConnectedSubnet(ctx context.Context, nodeID ids.NodeID, subnetID ids.ID) error -} diff --git a/snow/validators/unhandled_subnet_connector.go b/snow/validators/unhandled_subnet_connector.go deleted file mode 100644 index 08447c4582ad..000000000000 --- a/snow/validators/unhandled_subnet_connector.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package validators - -import ( - "context" - "fmt" - - "github.com/ava-labs/avalanchego/ids" -) - -var UnhandledSubnetConnector SubnetConnector = &unhandledSubnetConnector{} - -type unhandledSubnetConnector struct{} - -func (unhandledSubnetConnector) ConnectedSubnet(_ context.Context, nodeID ids.NodeID, subnetID ids.ID) error { - return fmt.Errorf( - "unhandled ConnectedSubnet with nodeID=%q and subnetID=%q", - nodeID, - subnetID, - ) -} diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 6690488ef291..8244afe97e42 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -53,10 +53,9 @@ import ( ) var ( - _ snowmanblock.ChainVM = (*VM)(nil) - _ secp256k1fx.VM = (*VM)(nil) - _ validators.State = (*VM)(nil) - _ validators.SubnetConnector = (*VM)(nil) + _ snowmanblock.ChainVM = (*VM)(nil) + _ secp256k1fx.VM = (*VM)(nil) + _ validators.State = (*VM)(nil) ) type VM struct { @@ -467,10 +466,6 @@ func (vm *VM) Connected(ctx context.Context, nodeID ids.NodeID, version *version return vm.Network.Connected(ctx, nodeID, version) } -func (vm *VM) ConnectedSubnet(_ context.Context, nodeID ids.NodeID, subnetID ids.ID) error { - return nil -} - func (vm *VM) Disconnected(ctx context.Context, nodeID ids.NodeID) error { if err := vm.uptimeManager.Disconnect(nodeID); err != nil { return err diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 277eed268013..5732b095e9f6 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1542,7 +1542,6 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { time.Hour, 2, cpuTracker, - vm, subnets.New(ctx.NodeID, subnets.Config{}), tracker.NewPeers(), peerTracker, From 9161864c3d83f76c16d2bbe70d09ec017b44ef49 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Sat, 27 Jul 2024 00:42:52 +0300 Subject: [PATCH 08/21] fix linter --- chains/manager.go | 4 +--- scripts/mocks.mockgen.txt | 1 - snow/networking/router/chain_router.go | 15 --------------- 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index a87396d1b65e..590a88ae5ac9 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -1106,9 +1106,7 @@ func (m *manager) createSnowmanChain( messageSender = sender.Trace(messageSender, m.Tracer) } - var ( - bootstrapFunc func() - ) + var bootstrapFunc func() // If [m.validatorState] is nil then we are creating the P-Chain. Since the // P-Chain is the first chain to be created, we can use it to initialize // required interfaces for the other chains diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 139252666ab0..fb370aebff96 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -17,7 +17,6 @@ github.com/ava-labs/avalanchego/snow/networking/tracker=Targeter=snow/networking github.com/ava-labs/avalanchego/snow/networking/tracker=Tracker=snow/networking/tracker/mock_resource_tracker.go github.com/ava-labs/avalanchego/snow/uptime=Calculator=snow/uptime/mock_calculator.go github.com/ava-labs/avalanchego/snow/validators=State=snow/validators/mock_state.go -github.com/ava-labs/avalanchego/snow/validators=SubnetConnector=snow/validators/mock_subnet_connector.go github.com/ava-labs/avalanchego/utils/crypto/keychain=Ledger=utils/crypto/keychain/mock_ledger.go github.com/ava-labs/avalanchego/utils/filesystem=Reader=utils/filesystem/mock_io.go github.com/ava-labs/avalanchego/utils/hashing=Hasher=utils/hashing/mock_hasher.go diff --git a/snow/networking/router/chain_router.go b/snow/networking/router/chain_router.go index b125800d5ff8..01b0137407c4 100644 --- a/snow/networking/router/chain_router.go +++ b/snow/networking/router/chain_router.go @@ -450,20 +450,6 @@ func (cr *ChainRouter) AddChain(ctx context.Context, chain handler.Handler) { }, ) } - - // When we register the P-chain, we mark ourselves as connected on all of - // the subnets that we have tracked. - if chainID != constants.PlatformChainID { - return - } - - // If we have currently benched ourselves, we will mark ourselves as - // connected when we unbench. So skip connecting now. - // This is not "theoretically" possible, but keeping this here prevents us - // from keeping an invariant that we never bench ourselves. - if _, benched := cr.benched[cr.myNodeID]; benched { - return - } } // Connected routes an incoming notification that a validator was just connected @@ -517,7 +503,6 @@ func (cr *ChainRouter) Connected(nodeID ids.NodeID, nodeVersion *version.Applica } } } - } // Disconnected routes an incoming notification that a validator was connected From f275c15575ebbcd97c9507205b272ed91f6d65d2 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 31 Jul 2024 17:23:33 +0300 Subject: [PATCH 09/21] rework on tests and reviews --- network/peer/peer_test.go | 4 +-- snow/uptime/manager.go | 14 ++++---- vms/platformvm/service.go | 26 +++++--------- vms/platformvm/service_test.go | 10 ++++++ vms/platformvm/state/state_test.go | 38 +++++++++++++++++++-- vms/platformvm/txs/executor/helpers_test.go | 5 --- 6 files changed, 64 insertions(+), 33 deletions(-) diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index ae2f86a74fc1..11b7b5590565 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -227,7 +227,7 @@ func TestPingUptimes(t *testing.T) { require.NoError(peer0.AwaitClosed(context.Background())) require.NoError(peer1.AwaitClosed(context.Background())) }() - pingMsg, err := sharedConfig.MessageCreator.Ping(0) + pingMsg, err := sharedConfig.MessageCreator.Ping(1) require.NoError(err) require.True(peer0.Send(context.Background(), pingMsg)) @@ -238,7 +238,7 @@ func TestPingUptimes(t *testing.T) { sendAndFlush(t, peer0, peer1) uptime := peer1.ObservedUptime() - require.Equal(uint32(0), uptime) + require.Equal(uint32(1), uptime) } func TestTrackedSubnets(t *testing.T) { diff --git a/snow/uptime/manager.go b/snow/uptime/manager.go index 93aaa4a1b139..52d4b4c7a088 100644 --- a/snow/uptime/manager.go +++ b/snow/uptime/manager.go @@ -40,7 +40,9 @@ type manager struct { state State connections map[ids.NodeID]time.Time // nodeID -> time - tracked bool + // Whether we have started tracking the uptime of the nodes + // This is used to avoid setting the uptime before we have started tracking + startedTracking bool } func NewManager(state State, clk *mockable.Clock) Manager { @@ -71,17 +73,17 @@ func (m *manager) StartTracking(nodeIDs []ids.NodeID) error { return err } } - m.tracked = true + m.startedTracking = true return nil } func (m *manager) StopTracking(nodeIDs []ids.NodeID) error { // TODO: this was not here before, should we add it? - if !m.tracked { + if !m.startedTracking { return nil } defer func() { - m.tracked = false + m.startedTracking = false }() now := m.clock.UnixTime() for _, nodeID := range nodeIDs { @@ -148,7 +150,7 @@ func (m *manager) CalculateUptime(nodeID ids.NodeID) (time.Duration, time.Time, return upDuration, lastUpdated, nil } - if !m.tracked { + if !m.startedTracking { durationOffline := now.Sub(lastUpdated) newUpDuration := upDuration + durationOffline return newUpDuration, now, nil @@ -202,7 +204,7 @@ func (m *manager) CalculateUptimePercentFrom(nodeID ids.NodeID, startTime time.T // updateUptime updates the uptime of the node on the state by the amount // of time that the node has been connected. func (m *manager) updateUptime(nodeID ids.NodeID) error { - if !m.tracked { + if !m.startedTracking { return nil } newDuration, newLastUpdated, err := m.CalculateUptime(nodeID) diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 1bb82e1a1203..501cb743fc6b 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -836,10 +836,17 @@ func (s *Service) GetCurrentValidators(_ *http.Request, args *GetCurrentValidato // TODO: decide whether we want to keep connected for subnet validators // it should be available at this point if args.SubnetID == constants.PrimaryNetworkID { - currentUptime, isConnected, err := s.getAPIUptime(currentStaker) + rawUptime, err := s.vm.uptimeManager.CalculateUptimePercentFrom(currentStaker.NodeID, currentStaker.StartTime) if err != nil { return err } + // Transform this to a percentage (0-100) to make it consistent + // with observedUptime in info.peers API + currentUptime := avajson.Float32(rawUptime * 100) + if err != nil { + return err + } + isConnected := s.vm.uptimeManager.IsConnected(currentStaker.NodeID) connected = &isConnected uptime = ¤tUptime } @@ -1828,23 +1835,6 @@ func (s *Service) GetBlockByHeight(_ *http.Request, args *api.GetBlockByHeightAr return err } -// Returns: -// 1) the uptime of a validator in the API format -// 2) whether the validator is currently connected -// 3) an error if one occurred -func (s *Service) getAPIUptime(staker *state.Staker) (avajson.Float32, bool, error) { - rawUptime, err := s.vm.uptimeManager.CalculateUptimePercentFrom(staker.NodeID, staker.StartTime) - if err != nil { - return 0, false, err - } - connected := s.vm.uptimeManager.IsConnected(staker.NodeID) - - // Transform this to a percentage (0-100) to make it consistent - // with observedUptime in info.peers API - uptime := avajson.Float32(rawUptime * 100) - return uptime, connected, nil -} - func (s *Service) getAPIOwner(owner *secp256k1fx.OutputOwners) (*platformapi.Owner, error) { apiOwner := &platformapi.Owner{ Locktime: avajson.Uint64(owner.Locktime), diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index a3b2e743c9bc..1a688579b736 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -32,6 +32,8 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/formatting" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/signer" @@ -602,6 +604,12 @@ func TestGetCurrentValidators(t *testing.T) { args := GetCurrentValidatorsArgs{SubnetID: constants.PrimaryNetworkID} response := GetCurrentValidatorsReply{} + connectedIDs := set.NewSet[ids.NodeID](len(genesis.Validators) - 1) + for _, vdr := range genesis.Validators[:len(genesis.Validators)-1] { + connectedIDs.Add(vdr.NodeID) + require.NoError(service.vm.Connected(context.Background(), vdr.NodeID, version.CurrentApp)) + } + require.NoError(service.GetCurrentValidators(nil, &args, &response)) require.Len(response.Validators, len(genesis.Validators)) @@ -615,6 +623,8 @@ func TestGetCurrentValidators(t *testing.T) { require.Equal(vdr.EndTime, gotVdr.EndTime) require.Equal(vdr.StartTime, gotVdr.StartTime) + require.Equal(connectedIDs.Contains(vdr.NodeID), *gotVdr.Connected) + require.EqualValues(100, *gotVdr.Uptime) found = true } require.True(found, "expected validators to contain %s but didn't", vdr.NodeID) diff --git a/vms/platformvm/state/state_test.go b/vms/platformvm/state/state_test.go index 517981552042..c5243c63bf10 100644 --- a/vms/platformvm/state/state_test.go +++ b/vms/platformvm/state/state_test.go @@ -106,6 +106,9 @@ func TestPersistStakers(t *testing.T) { // with the right weight and showing the BLS key checkValidatorsSet func(*require.Assertions, *state, *Staker) + // Check that node duly track stakers uptimes + checkValidatorUptimes func(*require.Assertions, *state, *Staker) + // Check whether weight/bls keys diffs are duly stored checkDiffs func(*require.Assertions, *state, *Staker, uint64) }{ @@ -156,6 +159,17 @@ func TestPersistStakers(t *testing.T) { Weight: staker.Weight, }, valOut) }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + upDuration, lastUpdated, err := s.GetUptime(staker.NodeID) + if staker.SubnetID != constants.PrimaryNetworkID { + // only primary network validators have uptimes + r.ErrorIs(err, database.ErrNotFound) + } else { + r.NoError(err) + r.Equal(upDuration, time.Duration(0)) + r.Equal(lastUpdated, staker.StartTime) + } + }, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { weightDiffBytes, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) r.NoError(err) @@ -252,6 +266,7 @@ func TestPersistStakers(t *testing.T) { r.Equal(valOut.NodeID, staker.NodeID) r.Equal(valOut.Weight, val.Weight+staker.Weight) }, + checkValidatorUptimes: func(*require.Assertions, *state, *Staker) {}, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { // validator's weight must increase of delegator's weight amount weightDiffBytes, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) @@ -303,6 +318,11 @@ func TestPersistStakers(t *testing.T) { valsMap := s.cfg.Validators.GetMap(staker.SubnetID) r.Empty(valsMap) }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + // pending validators uptime is not tracked + _, _, err := s.GetUptime(staker.NodeID) + r.ErrorIs(err, database.ErrNotFound) + }, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { // pending validators weight diff and bls diffs are not stored _, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) @@ -373,7 +393,8 @@ func TestPersistStakers(t *testing.T) { valsMap := s.cfg.Validators.GetMap(staker.SubnetID) r.Empty(valsMap) }, - checkDiffs: func(*require.Assertions, *state, *Staker, uint64) {}, + checkValidatorUptimes: func(*require.Assertions, *state, *Staker) {}, + checkDiffs: func(*require.Assertions, *state, *Staker, uint64) {}, }, "delete current validator": { storeStaker: func(r *require.Assertions, subnetID ids.ID, s *state) *Staker { @@ -419,6 +440,11 @@ func TestPersistStakers(t *testing.T) { valsMap := s.cfg.Validators.GetMap(staker.SubnetID) r.Empty(valsMap) }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + // uptimes of delete validators are dropped + _, _, err := s.GetUptime(staker.NodeID) + r.ErrorIs(err, database.ErrNotFound) + }, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { weightDiffBytes, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) r.NoError(err) @@ -515,6 +541,7 @@ func TestPersistStakers(t *testing.T) { r.Equal(valOut.NodeID, staker.NodeID) r.Equal(valOut.Weight, val.Weight) }, + checkValidatorUptimes: func(*require.Assertions, *state, *Staker) {}, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { // validator's weight must decrease of delegator's weight amount weightDiffBytes, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) @@ -568,6 +595,10 @@ func TestPersistStakers(t *testing.T) { valsMap := s.cfg.Validators.GetMap(staker.SubnetID) r.Empty(valsMap) }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + _, _, err := s.GetUptime(staker.NodeID) + r.ErrorIs(err, database.ErrNotFound) + }, checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { _, err := s.validatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) r.ErrorIs(err, database.ErrNotFound) @@ -635,7 +666,8 @@ func TestPersistStakers(t *testing.T) { valsMap := s.cfg.Validators.GetMap(staker.SubnetID) r.Empty(valsMap) }, - checkDiffs: func(*require.Assertions, *state, *Staker, uint64) {}, + checkValidatorUptimes: func(*require.Assertions, *state, *Staker) {}, + checkDiffs: func(*require.Assertions, *state, *Staker, uint64) {}, }, } @@ -653,6 +685,7 @@ func TestPersistStakers(t *testing.T) { // check all relevant data are stored test.checkStakerInState(require, state, staker) test.checkValidatorsSet(require, state, staker) + test.checkValidatorUptimes(require, state, staker) test.checkDiffs(require, state, staker, 0 /*height*/) // rebuild the state @@ -666,6 +699,7 @@ func TestPersistStakers(t *testing.T) { // check again that all relevant data are still available in rebuilt state test.checkStakerInState(require, state, staker) test.checkValidatorsSet(require, state, staker) + test.checkValidatorUptimes(require, state, staker) test.checkDiffs(require, state, staker, 0 /*height*/) }) } diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index a5f2d6fcca59..430644571ae2 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -189,11 +189,6 @@ func newEnvironment(t *testing.T, f fork) *environment { require.NoError(env.uptimes.StopTracking(validatorIDs)) - for subnetID := range env.config.TrackedSubnets { - validatorIDs := env.config.Validators.GetValidatorIDs(subnetID) - - require.NoError(env.uptimes.StopTracking(validatorIDs)) - } env.state.SetHeight(math.MaxUint64) require.NoError(env.state.Commit()) } From d9355cc0f5a634738272228a564c6ac85addbf75 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Wed, 31 Jul 2024 17:45:07 +0300 Subject: [PATCH 10/21] fix linter --- vms/platformvm/service_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 1a688579b736..447e21bcb901 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -624,7 +624,7 @@ func TestGetCurrentValidators(t *testing.T) { require.Equal(vdr.EndTime, gotVdr.EndTime) require.Equal(vdr.StartTime, gotVdr.StartTime) require.Equal(connectedIDs.Contains(vdr.NodeID), *gotVdr.Connected) - require.EqualValues(100, *gotVdr.Uptime) + require.Equal(avajson.Float32(100), *gotVdr.Uptime) found = true } require.True(found, "expected validators to contain %s but didn't", vdr.NodeID) From 46501ad6a3778ce636059dd3b0a8236494b07eec Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 6 Aug 2024 11:00:08 +0300 Subject: [PATCH 11/21] Update proto/p2p/p2p.proto Co-authored-by: Darioush Jalali Signed-off-by: Ceyhun Onur --- proto/p2p/p2p.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index 5d0a3a31a1eb..a309226973ee 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -64,7 +64,7 @@ message Message { message Ping { // Uptime percentage on the primary network [0, 100] uint32 uptime = 1; - reserved 2; // Until E upgrade is activated. + reserved 2; // Until Etna upgrade is activated. } // Pong is sent in response to a Ping. From b7459bdf40e5042a52a869fbfc8cf93c15038793 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 6 Aug 2024 11:01:35 +0300 Subject: [PATCH 12/21] fix comment Signed-off-by: Ceyhun Onur --- snow/uptime/manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snow/uptime/manager.go b/snow/uptime/manager.go index 52d4b4c7a088..284fcdea7614 100644 --- a/snow/uptime/manager.go +++ b/snow/uptime/manager.go @@ -39,7 +39,7 @@ type manager struct { clock *mockable.Clock state State - connections map[ids.NodeID]time.Time // nodeID -> time + connections map[ids.NodeID]time.Time // nodeID -> connected at // Whether we have started tracking the uptime of the nodes // This is used to avoid setting the uptime before we have started tracking startedTracking bool From b81b73719cbe9b9fa6a70beb665cf9837447dce8 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 6 Aug 2024 11:20:05 +0300 Subject: [PATCH 13/21] Update vms/platformvm/service_test.go Co-authored-by: Darioush Jalali Signed-off-by: Ceyhun Onur --- vms/platformvm/service_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 447e21bcb901..588d15b3e72c 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -604,6 +604,7 @@ func TestGetCurrentValidators(t *testing.T) { args := GetCurrentValidatorsArgs{SubnetID: constants.PrimaryNetworkID} response := GetCurrentValidatorsReply{} + // Connect to nodes other than the last node in genesis.Validators, which is the node being tested. connectedIDs := set.NewSet[ids.NodeID](len(genesis.Validators) - 1) for _, vdr := range genesis.Validators[:len(genesis.Validators)-1] { connectedIDs.Add(vdr.NodeID) From f6bb38368b729cf4ba5ef17ec69b799ea8d27c1c Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 6 Aug 2024 11:20:38 +0300 Subject: [PATCH 14/21] use disconnect in stop tracking --- snow/uptime/manager.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/snow/uptime/manager.go b/snow/uptime/manager.go index 284fcdea7614..413a660ec172 100644 --- a/snow/uptime/manager.go +++ b/snow/uptime/manager.go @@ -90,9 +90,7 @@ func (m *manager) StopTracking(nodeIDs []ids.NodeID) error { // 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 { - err := m.updateUptime(nodeID) - delete(m.connections, nodeID) - if err != nil { + if err := m.disconnect(nodeID); err != nil { return err } continue @@ -129,6 +127,10 @@ 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 { if err := m.updateUptime(nodeID); err != nil { return err } From 7a6f7eb8a44372c1f15341433b487e0b480a4f45 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 6 Aug 2024 12:14:41 +0300 Subject: [PATCH 15/21] remove todo comment --- vms/platformvm/service.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 501cb743fc6b..4fb48eddb941 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -832,9 +832,6 @@ func (s *Service) GetCurrentValidators(_ *http.Request, args *GetCurrentValidato delegationFee := avajson.Float32(100 * float32(shares) / float32(reward.PercentDenominator)) var uptime *avajson.Float32 var connected *bool - // Only calculate uptime for primary network validators - // TODO: decide whether we want to keep connected for subnet validators - // it should be available at this point if args.SubnetID == constants.PrimaryNetworkID { rawUptime, err := s.vm.uptimeManager.CalculateUptimePercentFrom(currentStaker.NodeID, currentStaker.StartTime) if err != nil { From cba7a50cc4c4e77088d5e18eab3f0090dfd94cfd Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Sun, 8 Sep 2024 16:33:16 +0300 Subject: [PATCH 16/21] remove unused err --- network/network.go | 1 - 1 file changed, 1 deletion(-) diff --git a/network/network.go b/network/network.go index 63f8c1f035b3..eab4ecca085e 100644 --- a/network/network.go +++ b/network/network.go @@ -52,7 +52,6 @@ var ( _ Network = (*network)(nil) errNotValidator = errors.New("node is not a validator") - errNotTracked = errors.New("subnet is not tracked") errExpectedProxy = errors.New("expected proxy") errExpectedTCPProtocol = errors.New("expected TCP protocol") errTrackingPrimaryNetwork = errors.New("cannot track primary network") From b4955d6f492929a85bdf3e40a45396a62aeecd99 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Sun, 8 Sep 2024 16:36:53 +0300 Subject: [PATCH 17/21] remove subnet connector mock --- .../validatorsmock/subnet_connector.go | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 snow/validators/validatorsmock/subnet_connector.go diff --git a/snow/validators/validatorsmock/subnet_connector.go b/snow/validators/validatorsmock/subnet_connector.go deleted file mode 100644 index 118a287ac68a..000000000000 --- a/snow/validators/validatorsmock/subnet_connector.go +++ /dev/null @@ -1,55 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/snow/validators (interfaces: SubnetConnector) -// -// Generated by this command: -// -// mockgen -package=validatorsmock -destination=snow/validators/validatorsmock/subnet_connector.go -mock_names=SubnetConnector=SubnetConnector github.com/ava-labs/avalanchego/snow/validators SubnetConnector -// - -// Package validatorsmock is a generated GoMock package. -package validatorsmock - -import ( - context "context" - reflect "reflect" - - ids "github.com/ava-labs/avalanchego/ids" - gomock "go.uber.org/mock/gomock" -) - -// SubnetConnector is a mock of SubnetConnector interface. -type SubnetConnector struct { - ctrl *gomock.Controller - recorder *SubnetConnectorMockRecorder -} - -// SubnetConnectorMockRecorder is the mock recorder for SubnetConnector. -type SubnetConnectorMockRecorder struct { - mock *SubnetConnector -} - -// NewSubnetConnector creates a new mock instance. -func NewSubnetConnector(ctrl *gomock.Controller) *SubnetConnector { - mock := &SubnetConnector{ctrl: ctrl} - mock.recorder = &SubnetConnectorMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *SubnetConnector) EXPECT() *SubnetConnectorMockRecorder { - return m.recorder -} - -// ConnectedSubnet mocks base method. -func (m *SubnetConnector) ConnectedSubnet(arg0 context.Context, arg1 ids.NodeID, arg2 ids.ID) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ConnectedSubnet", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// ConnectedSubnet indicates an expected call of ConnectedSubnet. -func (mr *SubnetConnectorMockRecorder) ConnectedSubnet(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectedSubnet", reflect.TypeOf((*SubnetConnector)(nil).ConnectedSubnet), arg0, arg1, arg2) -} From 0daacc66b15bdac496ad8862fc6ef21594335f9a Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Mon, 23 Sep 2024 07:07:25 -0400 Subject: [PATCH 18/21] uptime manager small refactor (#3346) --- snow/uptime/manager.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/snow/uptime/manager.go b/snow/uptime/manager.go index 413a660ec172..70f576060aa0 100644 --- a/snow/uptime/manager.go +++ b/snow/uptime/manager.go @@ -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 @@ -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 } @@ -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 } } @@ -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 } @@ -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 @@ -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 @@ -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 } From f3261aa789b3cd2f52fdaefe5608a8b7a012ab0f Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Mon, 23 Sep 2024 14:17:35 +0300 Subject: [PATCH 19/21] use var block --- vms/platformvm/service.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 2e9bb346a8e9..91b7810d30df 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -847,8 +847,10 @@ func (s *Service) GetCurrentValidators(_ *http.Request, args *GetCurrentValidato shares := attr.shares delegationFee := avajson.Float32(100 * float32(shares) / float32(reward.PercentDenominator)) - var uptime *avajson.Float32 - var connected *bool + var ( + uptime *avajson.Float32 + connected *bool + ) if args.SubnetID == constants.PrimaryNetworkID { rawUptime, err := s.vm.uptimeManager.CalculateUptimePercentFrom(currentStaker.NodeID, currentStaker.StartTime) if err != nil { From 8f8285e2ae29738d743c387e48ef20012d331cc9 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Mon, 23 Sep 2024 15:23:38 +0300 Subject: [PATCH 20/21] return err trackeds --- snow/uptime/manager.go | 10 ++++++++-- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 7 ++++--- vms/platformvm/vm.go | 10 ++++++---- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/snow/uptime/manager.go b/snow/uptime/manager.go index 70f576060aa0..999ac8937a49 100644 --- a/snow/uptime/manager.go +++ b/snow/uptime/manager.go @@ -4,6 +4,7 @@ package uptime import ( + "errors" "time" "github.com/ava-labs/avalanchego/database" @@ -13,6 +14,11 @@ import ( var _ Manager = (*manager)(nil) +var ( + errAlreadyStartedTracking = errors.New("already started tracking") + errNotStartedTracking = errors.New("not started tracking") +) + type Manager interface { Tracker Calculator @@ -56,7 +62,7 @@ func NewManager(state State, clk *mockable.Clock) Manager { func (m *manager) StartTracking(nodeIDs []ids.NodeID) error { if m.startedTracking { - return nil + return errAlreadyStartedTracking } now := m.clock.UnixTime() for _, nodeID := range nodeIDs { @@ -81,7 +87,7 @@ func (m *manager) StartTracking(nodeIDs []ids.NodeID) error { func (m *manager) StopTracking(nodeIDs []ids.NodeID) error { if !m.startedTracking { - return nil + return errNotStartedTracking } defer func() { m.startedTracking = false diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index f1f22960c230..471f7030840b 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -187,7 +187,7 @@ func newEnvironment(t *testing.T, f upgradetest.Fork) *environment { //nolint:un res.Builder.ShutdownBlockTimer() - if res.isBootstrapped.Get() { + if res.uptimes.StartedTracking() { validatorIDs := res.config.Validators.GetValidatorIDs(constants.PrimaryNetworkID) require.NoError(res.uptimes.StopTracking(validatorIDs)) diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 61df509156ea..ce5038a2881f 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -192,7 +192,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f upgradetest.Fork) * require := require.New(t) - if res.isBootstrapped.Get() { + if res.uptimes.StartedTracking() { validatorIDs := res.config.Validators.GetValidatorIDs(constants.PrimaryNetworkID) require.NoError(res.uptimes.StopTracking(validatorIDs)) diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 90828174b82b..129e0d351f38 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -155,9 +155,10 @@ func newEnvironment(t *testing.T, f upgradetest.Fork) *environment { require := require.New(t) if env.isBootstrapped.Get() { - validatorIDs := env.config.Validators.GetValidatorIDs(constants.PrimaryNetworkID) - - require.NoError(env.uptimes.StopTracking(validatorIDs)) + if env.uptimes.StartedTracking() { + validatorIDs := env.config.Validators.GetValidatorIDs(constants.PrimaryNetworkID) + require.NoError(env.uptimes.StopTracking(validatorIDs)) + } env.state.SetHeight(math.MaxUint64) require.NoError(env.state.Commit()) diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 405f9faeba33..975e13f7ebd5 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -347,9 +347,11 @@ func (vm *VM) onNormalOperationsStarted() error { return err } - primaryVdrIDs := vm.Validators.GetValidatorIDs(constants.PrimaryNetworkID) - if err := vm.uptimeManager.StartTracking(primaryVdrIDs); err != nil { - return err + if !vm.uptimeManager.StartedTracking() { + primaryVdrIDs := vm.Validators.GetValidatorIDs(constants.PrimaryNetworkID) + if err := vm.uptimeManager.StartTracking(primaryVdrIDs); err != nil { + return err + } } vl := validators.NewLogger(vm.ctx.Log, constants.PrimaryNetworkID, vm.ctx.NodeID) @@ -389,7 +391,7 @@ func (vm *VM) Shutdown(context.Context) error { vm.onShutdownCtxCancel() vm.Builder.ShutdownBlockTimer() - if vm.bootstrapped.Get() { + if vm.uptimeManager.StartedTracking() { primaryVdrIDs := vm.Validators.GetValidatorIDs(constants.PrimaryNetworkID) if err := vm.uptimeManager.StopTracking(primaryVdrIDs); err != nil { return err From 23bc5f7764e7bd9d95e78a0ed50ae1fde281e61b Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 23 Sep 2024 18:14:38 -0400 Subject: [PATCH 21/21] Simplify uptime tracking --- snow/uptime/manager.go | 67 ++++++++++--------------------------- snow/uptime/manager_test.go | 28 ---------------- 2 files changed, 18 insertions(+), 77 deletions(-) diff --git a/snow/uptime/manager.go b/snow/uptime/manager.go index 999ac8937a49..fbace19eaab8 100644 --- a/snow/uptime/manager.go +++ b/snow/uptime/manager.go @@ -64,23 +64,13 @@ func (m *manager) StartTracking(nodeIDs []ids.NodeID) error { if m.startedTracking { return errAlreadyStartedTracking } - now := m.clock.UnixTime() - for _, nodeID := range nodeIDs { - upDuration, lastUpdated, err := m.CalculateUptime(nodeID) - if err != nil { - return err - } - // If we are in a weird reality where time has moved backwards, then we - // shouldn't modify the validator's uptime. - if now.Before(lastUpdated) { - continue - } - - if err := m.state.SetUptime(nodeID, upDuration, lastUpdated); err != nil { + for _, nodeID := range nodeIDs { + if err := m.updateUptime(nodeID); err != nil { return err } } + m.startedTracking = true return nil } @@ -89,37 +79,14 @@ func (m *manager) StopTracking(nodeIDs []ids.NodeID) error { if !m.startedTracking { return errNotStartedTracking } - defer func() { - m.startedTracking = false - }() - now := m.clock.UnixTime() - 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 m.IsConnected(nodeID) { - if err := m.Disconnect(nodeID); err != nil { - return err - } - continue - } - - // if the node is not connected, then we need to update - // the uptime in the state from the last time the node was connected to current time. - upDuration, lastUpdated, err := m.state.GetUptime(nodeID) - if err != nil { - return err - } - - // If we are in a weird reality where time has moved backwards, then we - // shouldn't modify the validator's uptime. - if now.Before(lastUpdated) { - continue - } - if err := m.state.SetUptime(nodeID, upDuration, now); err != nil { + for _, nodeID := range nodeIDs { + if err := m.updateUptime(nodeID); err != nil { return err } } + + m.startedTracking = false return nil } @@ -139,11 +106,12 @@ func (m *manager) IsConnected(nodeID ids.NodeID) bool { func (m *manager) Disconnect(nodeID ids.NodeID) error { defer delete(m.connections, nodeID) - if err := m.updateUptime(nodeID); err != nil { - return err + + if !m.startedTracking { + return nil } - return nil + return m.updateUptime(nodeID) } func (m *manager) CalculateUptime(nodeID ids.NodeID) (time.Duration, time.Time, error) { @@ -159,12 +127,16 @@ func (m *manager) CalculateUptime(nodeID ids.NodeID) (time.Duration, time.Time, return upDuration, lastUpdated, nil } + // If we haven't started tracking, then we assume that the node has been + // online since their last update. if !m.startedTracking { durationOffline := now.Sub(lastUpdated) newUpDuration := upDuration + durationOffline return newUpDuration, now, nil } + // If we are tracking and they aren't connected, they have been offline + // since their last update. timeConnected, isConnected := m.connections[nodeID] if !isConnected { return upDuration, now, nil @@ -210,15 +182,12 @@ func (m *manager) CalculateUptimePercentFrom(nodeID ids.NodeID, startTime time.T return uptime, nil } -// updateUptime updates the uptime of the node on the state by the amount -// of time that the node has been connected. +// updateUptime updates the uptime of the node on the state by the amount of +// time that the node has been connected. func (m *manager) updateUptime(nodeID ids.NodeID) error { - if !m.startedTracking { - return nil - } newDuration, newLastUpdated, err := m.CalculateUptime(nodeID) if err == database.ErrNotFound { - // If a non-validator disconnects, we don't care + // We don't track the uptimes of non-validators. return nil } if err != nil { diff --git a/snow/uptime/manager_test.go b/snow/uptime/manager_test.go index ef3de35070b9..95669f663599 100644 --- a/snow/uptime/manager_test.go +++ b/snow/uptime/manager_test.go @@ -60,19 +60,6 @@ func TestStartTrackingDBError(t *testing.T) { require.ErrorIs(err, errTest) } -func TestStartTrackingNonValidator(t *testing.T) { - require := require.New(t) - - s := NewTestState() - clk := mockable.Clock{} - up := NewManager(s, &clk) - - nodeID0 := ids.GenerateTestNodeID() - - err := up.StartTracking([]ids.NodeID{nodeID0}) - require.ErrorIs(err, database.ErrNotFound) -} - func TestStartTrackingInThePast(t *testing.T) { require := require.New(t) @@ -160,21 +147,6 @@ func TestStopTrackingIncreasesUptime(t *testing.T) { require.Equal(clk.UnixTime(), lastUpdated) } -func TestStopTrackingDisconnectedNonValidator(t *testing.T) { - require := require.New(t) - - nodeID0 := ids.GenerateTestNodeID() - - s := NewTestState() - clk := mockable.Clock{} - up := NewManager(s, &clk) - - require.NoError(up.StartTracking(nil)) - - err := up.StopTracking([]ids.NodeID{nodeID0}) - require.ErrorIs(err, database.ErrNotFound) -} - func TestStopTrackingConnectedDBError(t *testing.T) { require := require.New(t)