Skip to content

Commit 82fbc97

Browse files
Add ACP signaling (#2476)
1 parent ac5a00e commit 82fbc97

File tree

15 files changed

+406
-206
lines changed

15 files changed

+406
-206
lines changed

api/info/service.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ import (
1717
"github.com/ava-labs/avalanchego/network"
1818
"github.com/ava-labs/avalanchego/network/peer"
1919
"github.com/ava-labs/avalanchego/snow/networking/benchlist"
20+
"github.com/ava-labs/avalanchego/snow/validators"
2021
"github.com/ava-labs/avalanchego/utils/constants"
2122
"github.com/ava-labs/avalanchego/utils/ips"
2223
"github.com/ava-labs/avalanchego/utils/json"
2324
"github.com/ava-labs/avalanchego/utils/logging"
25+
"github.com/ava-labs/avalanchego/utils/set"
2426
"github.com/ava-labs/avalanchego/version"
2527
"github.com/ava-labs/avalanchego/vms"
2628
"github.com/ava-labs/avalanchego/vms/platformvm/signer"
@@ -32,6 +34,7 @@ var errNoChainProvided = errors.New("argument 'chain' not given")
3234
type Info struct {
3335
Parameters
3436
log logging.Logger
37+
validators validators.Manager
3538
myIP ips.DynamicIPPort
3639
networking network.Network
3740
chainManager chains.Manager
@@ -59,6 +62,7 @@ type Parameters struct {
5962
func NewService(
6063
parameters Parameters,
6164
log logging.Logger,
65+
validators validators.Manager,
6266
chainManager chains.Manager,
6367
vmManager vms.Manager,
6468
myIP ips.DynamicIPPort,
@@ -73,6 +77,7 @@ func NewService(
7377
&Info{
7478
Parameters: parameters,
7579
log: log,
80+
validators: validators,
7681
chainManager: chainManager,
7782
vmManager: vmManager,
7883
myIP: myIP,
@@ -319,6 +324,64 @@ func (i *Info) Uptime(_ *http.Request, args *UptimeRequest, reply *UptimeRespons
319324
return nil
320325
}
321326

327+
type ACP struct {
328+
SupportWeight json.Uint64 `json:"supportWeight"`
329+
Supporters set.Set[ids.NodeID] `json:"supporters"`
330+
ObjectWeight json.Uint64 `json:"objectWeight"`
331+
Objectors set.Set[ids.NodeID] `json:"objectors"`
332+
AbstainWeight json.Uint64 `json:"abstainWeight"`
333+
}
334+
335+
type ACPsReply struct {
336+
ACPs map[uint32]*ACP `json:"acps"`
337+
}
338+
339+
func (a *ACPsReply) getACP(acpNum uint32) *ACP {
340+
acp, ok := a.ACPs[acpNum]
341+
if !ok {
342+
acp = &ACP{}
343+
a.ACPs[acpNum] = acp
344+
}
345+
return acp
346+
}
347+
348+
func (i *Info) Acps(_ *http.Request, _ *struct{}, reply *ACPsReply) error {
349+
i.log.Debug("API called",
350+
zap.String("service", "info"),
351+
zap.String("method", "acps"),
352+
)
353+
354+
reply.ACPs = make(map[uint32]*ACP, constants.CurrentACPs.Len())
355+
peers := i.networking.PeerInfo(nil)
356+
for _, peer := range peers {
357+
weight := json.Uint64(i.validators.GetWeight(constants.PrimaryNetworkID, peer.ID))
358+
if weight == 0 {
359+
continue
360+
}
361+
362+
for acpNum := range peer.SupportedACPs {
363+
acp := reply.getACP(acpNum)
364+
acp.Supporters.Add(peer.ID)
365+
acp.SupportWeight += weight
366+
}
367+
for acpNum := range peer.ObjectedACPs {
368+
acp := reply.getACP(acpNum)
369+
acp.Objectors.Add(peer.ID)
370+
acp.ObjectWeight += weight
371+
}
372+
}
373+
374+
totalWeight, err := i.validators.TotalWeight(constants.PrimaryNetworkID)
375+
if err != nil {
376+
return err
377+
}
378+
for acpNum := range constants.CurrentACPs {
379+
acp := reply.getACP(acpNum)
380+
acp.AbstainWeight = json.Uint64(totalWeight) - acp.SupportWeight - acp.ObjectWeight
381+
}
382+
return nil
383+
}
384+
322385
type GetTxFeeResponse struct {
323386
TxFee json.Uint64 `json:"txFee"`
324387
CreateAssetTxFee json.Uint64 `json:"createAssetTxFee"`

config/config.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ var (
8181
ConsensusGossipOnAcceptPeerSizeKey: acceptedFrontierGossipDeprecationMsg,
8282
}
8383

84+
errConflictingACPOpinion = errors.New("supporting and objecting to the same ACP")
8485
errSybilProtectionDisabledStakerWeights = errors.New("sybil protection disabled weights must be positive")
8586
errSybilProtectionDisabledOnPublicNetwork = errors.New("sybil protection disabled on public network")
8687
errAuthPasswordTooWeak = errors.New("API auth password is not strong enough")
@@ -346,6 +347,25 @@ func getNetworkConfig(
346347
allowPrivateIPs = v.GetBool(NetworkAllowPrivateIPsKey)
347348
}
348349

350+
var supportedACPs set.Set[uint32]
351+
for _, acp := range v.GetIntSlice(ACPSupportKey) {
352+
if acp < 0 || acp > math.MaxInt32 {
353+
return network.Config{}, fmt.Errorf("invalid ACP: %d", acp)
354+
}
355+
supportedACPs.Add(uint32(acp))
356+
}
357+
358+
var objectedACPs set.Set[uint32]
359+
for _, acp := range v.GetIntSlice(ACPObjectKey) {
360+
if acp < 0 || acp > math.MaxInt32 {
361+
return network.Config{}, fmt.Errorf("invalid ACP: %d", acp)
362+
}
363+
objectedACPs.Add(uint32(acp))
364+
}
365+
if supportedACPs.Overlaps(objectedACPs) {
366+
return network.Config{}, errConflictingACPOpinion
367+
}
368+
349369
config := network.Config{
350370
ThrottlerConfig: network.ThrottlerConfig{
351371
MaxInboundConnsPerSec: maxInboundConnsPerSec,
@@ -425,6 +445,9 @@ func getNetworkConfig(
425445
UptimeMetricFreq: v.GetDuration(UptimeMetricFreqKey),
426446
MaximumInboundMessageTimeout: v.GetDuration(NetworkMaximumInboundTimeoutKey),
427447

448+
SupportedACPs: supportedACPs,
449+
ObjectedACPs: objectedACPs,
450+
428451
RequireValidatorToConnect: v.GetBool(NetworkRequireValidatorToConnectKey),
429452
PeerReadBufferSize: int(v.GetUint(NetworkPeerReadBufferSizeKey)),
430453
PeerWriteBufferSize: int(v.GetUint(NetworkPeerWriteBufferSizeKey)),

config/flags.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ func addNodeFlags(fs *pflag.FlagSet) {
9292
// Network ID
9393
fs.String(NetworkNameKey, constants.MainnetName, "Network ID this node will connect to")
9494

95+
// ACP flagging
96+
fs.IntSlice(ACPSupportKey, nil, "ACPs to support adoption")
97+
fs.IntSlice(ACPObjectKey, nil, "ACPs to object adoption")
98+
9599
// AVAX fees
96100
fs.Uint64(TxFeeKey, genesis.LocalParams.TxFee, "Transaction fee, in nAVAX")
97101
fs.Uint64(CreateAssetTxFeeKey, genesis.LocalParams.CreateAssetTxFee, "Transaction fee, in nAVAX, for transactions that create new assets")

config/keys.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const (
1313
GenesisFileKey = "genesis-file"
1414
GenesisFileContentKey = "genesis-file-content"
1515
NetworkNameKey = "network-id"
16+
ACPSupportKey = "acp-support"
17+
ACPObjectKey = "acp-object"
1618
TxFeeKey = "tx-fee"
1719
CreateAssetTxFeeKey = "create-asset-tx-fee"
1820
CreateSubnetTxFeeKey = "create-subnet-tx-fee"

message/mock_outbound_message_builder.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

message/outbound_msg_builder.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ type OutboundMsgBuilder interface {
3030
myVersionTime uint64,
3131
sig []byte,
3232
trackedSubnets []ids.ID,
33+
supportedACPs []uint32,
34+
objectedACPs []uint32,
3335
) (OutboundMessage, error)
3436

3537
PeerList(
@@ -240,6 +242,8 @@ func (b *outMsgBuilder) Version(
240242
myVersionTime uint64,
241243
sig []byte,
242244
trackedSubnets []ids.ID,
245+
supportedACPs []uint32,
246+
objectedACPs []uint32,
243247
) (OutboundMessage, error) {
244248
subnetIDBytes := make([][]byte, len(trackedSubnets))
245249
encodeIDs(trackedSubnets, subnetIDBytes)
@@ -261,6 +265,8 @@ func (b *outMsgBuilder) Version(
261265
Minor: minor,
262266
Patch: patch,
263267
},
268+
SupportedAcps: supportedACPs,
269+
ObjectedAcps: objectedACPs,
264270
},
265271
},
266272
},

network/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ type Config struct {
126126
PingFrequency time.Duration `json:"pingFrequency"`
127127
AllowPrivateIPs bool `json:"allowPrivateIPs"`
128128

129+
SupportedACPs set.Set[uint32] `json:"supportedACPs"`
130+
ObjectedACPs set.Set[uint32] `json:"objectedACPs"`
131+
129132
// The compression type to use when compressing outbound messages.
130133
// Assumes all peers support this compression type.
131134
CompressionType compression.Type `json:"compressionType"`

network/network.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ func NewNetwork(
271271
PingFrequency: config.PingFrequency,
272272
PongTimeout: config.PingPongTimeout,
273273
MaxClockDifference: config.MaxClockDifference,
274+
SupportedACPs: config.SupportedACPs.List(),
275+
ObjectedACPs: config.ObjectedACPs.List(),
274276
ResourceTracker: config.ResourceTracker,
275277
UptimeCalculator: config.UptimeCalculator,
276278
IPSigner: peer.NewIPSigner(config.MyIPPort, config.TLSKey),

network/peer/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ type Config struct {
4040
PongTimeout time.Duration
4141
MaxClockDifference time.Duration
4242

43+
SupportedACPs []uint32
44+
ObjectedACPs []uint32
45+
4346
// Unix time of the last message sent and received respectively
4447
// Must only be accessed atomically
4548
LastSent, LastReceived int64

network/peer/info.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/ava-labs/avalanchego/ids"
1010
"github.com/ava-labs/avalanchego/utils/json"
11+
"github.com/ava-labs/avalanchego/utils/set"
1112
)
1213

1314
type Info struct {
@@ -19,5 +20,7 @@ type Info struct {
1920
LastReceived time.Time `json:"lastReceived"`
2021
ObservedUptime json.Uint32 `json:"observedUptime"`
2122
ObservedSubnetUptimes map[ids.ID]json.Uint32 `json:"observedSubnetUptimes"`
22-
TrackedSubnets []ids.ID `json:"trackedSubnets"`
23+
TrackedSubnets set.Set[ids.ID] `json:"trackedSubnets"`
24+
SupportedACPs set.Set[uint32] `json:"supportedACPs"`
25+
ObjectedACPs set.Set[uint32] `json:"objectedACPs"`
2326
}

0 commit comments

Comments
 (0)