Skip to content

Commit f5f9177

Browse files
committed
Squashed commit of the following:
commit 82fbc97 Author: Stephen Buttolph <stephen@avalabs.org> Date: Tue Dec 12 18:30:09 2023 -0500 Add ACP signaling (#2476) commit ac5a00e Author: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue Dec 12 17:42:32 2023 -0500 Refactor p2p unit tests (#2475) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Dan Laine <daniel.laine@avalabs.org> commit 0b2b109 Author: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue Dec 12 16:48:28 2023 -0500 `vms/platformvm`: Verify txs before building a block (#2359) Co-authored-by: Stephen Buttolph <stephen@avalabs.org> commit 4be744e Author: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue Dec 12 15:08:48 2023 -0500 P2P AppError handling (#2248) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph <stephen@avalabs.org> commit 7963115 Author: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue Dec 12 14:37:59 2023 -0500 `vms/platformvm`: Add `TestBuildBlockForceAdvanceTime` test (#2472) Co-authored-by: Stephen Buttolph <stephen@avalabs.org> commit dc472ec Author: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue Dec 12 14:37:43 2023 -0500 `vms/platformvm`: Permit usage of the `Transactions` field in `BanffProposalBlock` (#2451) Co-authored-by: Stephen Buttolph <stephen@avalabs.org> Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com>
1 parent 5c0f12e commit f5f9177

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2019
-1464
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/inbound_msg_builder.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,26 @@ func InboundAppRequest(
284284
}
285285
}
286286

287+
func InboundAppError(
288+
nodeID ids.NodeID,
289+
chainID ids.ID,
290+
requestID uint32,
291+
errorCode int32,
292+
errorMessage string,
293+
) InboundMessage {
294+
return &inboundMessage{
295+
nodeID: nodeID,
296+
op: AppErrorOp,
297+
message: &p2p.AppError{
298+
ChainId: chainID[:],
299+
RequestId: requestID,
300+
ErrorCode: errorCode,
301+
ErrorMessage: errorMessage,
302+
},
303+
expiration: mockable.MaxTime,
304+
}
305+
}
306+
287307
func InboundAppResponse(
288308
chainID ids.ID,
289309
requestID uint32,

message/inbound_msg_builder_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"github.com/ava-labs/avalanchego/ids"
1515
"github.com/ava-labs/avalanchego/proto/pb/p2p"
16+
"github.com/ava-labs/avalanchego/utils/compression"
1617
"github.com/ava-labs/avalanchego/utils/logging"
1718
"github.com/ava-labs/avalanchego/utils/timer/mockable"
1819
)
@@ -396,3 +397,46 @@ func TestInboundMsgBuilder(t *testing.T) {
396397
},
397398
)
398399
}
400+
401+
func TestAppError(t *testing.T) {
402+
require := require.New(t)
403+
404+
mb, err := newMsgBuilder(
405+
logging.NoLog{},
406+
"",
407+
prometheus.NewRegistry(),
408+
time.Second,
409+
)
410+
require.NoError(err)
411+
412+
nodeID := ids.GenerateTestNodeID()
413+
chainID := ids.GenerateTestID()
414+
requestID := uint32(1)
415+
errorCode := int32(2)
416+
errorMessage := "hello world"
417+
418+
want := &p2p.Message{
419+
Message: &p2p.Message_AppError{
420+
AppError: &p2p.AppError{
421+
ChainId: chainID[:],
422+
RequestId: requestID,
423+
ErrorCode: errorCode,
424+
ErrorMessage: errorMessage,
425+
},
426+
},
427+
}
428+
429+
outMsg, err := mb.createOutbound(want, compression.TypeNone, false)
430+
require.NoError(err)
431+
432+
got, err := mb.parseInbound(outMsg.Bytes(), nodeID, func() {})
433+
require.NoError(err)
434+
435+
require.Equal(nodeID, got.NodeID())
436+
require.Equal(AppErrorOp, got.Op())
437+
438+
msg, ok := got.Message().(*p2p.AppError)
439+
require.True(ok)
440+
require.Equal(errorCode, msg.ErrorCode)
441+
require.Equal(errorMessage, msg.ErrorMessage)
442+
}

message/internal_msg_builder.go

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ var (
5252
_ requestIDGetter = (*QueryFailed)(nil)
5353
_ engineTypeGetter = (*QueryFailed)(nil)
5454

55-
_ fmt.Stringer = (*AppRequestFailed)(nil)
56-
_ chainIDGetter = (*AppRequestFailed)(nil)
57-
_ requestIDGetter = (*AppRequestFailed)(nil)
58-
5955
_ fmt.Stringer = (*CrossChainAppRequest)(nil)
6056
_ sourceChainIDGetter = (*CrossChainAppRequest)(nil)
6157
_ chainIDGetter = (*CrossChainAppRequest)(nil)
@@ -365,42 +361,6 @@ func InternalQueryFailed(
365361
}
366362
}
367363

368-
type AppRequestFailed struct {
369-
ChainID ids.ID `json:"chain_id,omitempty"`
370-
RequestID uint32 `json:"request_id,omitempty"`
371-
}
372-
373-
func (m *AppRequestFailed) String() string {
374-
return fmt.Sprintf(
375-
"ChainID: %s RequestID: %d",
376-
m.ChainID, m.RequestID,
377-
)
378-
}
379-
380-
func (m *AppRequestFailed) GetChainId() []byte {
381-
return m.ChainID[:]
382-
}
383-
384-
func (m *AppRequestFailed) GetRequestId() uint32 {
385-
return m.RequestID
386-
}
387-
388-
func InternalAppRequestFailed(
389-
nodeID ids.NodeID,
390-
chainID ids.ID,
391-
requestID uint32,
392-
) InboundMessage {
393-
return &inboundMessage{
394-
nodeID: nodeID,
395-
op: AppRequestFailedOp,
396-
message: &AppRequestFailed{
397-
ChainID: chainID,
398-
RequestID: requestID,
399-
},
400-
expiration: mockable.MaxTime,
401-
}
402-
}
403-
404364
type CrossChainAppRequest struct {
405365
SourceChainID ids.ID `json:"source_chain_id,omitempty"`
406366
DestinationChainID ids.ID `json:"destination_chain_id,omitempty"`
@@ -452,6 +412,8 @@ type CrossChainAppRequestFailed struct {
452412
SourceChainID ids.ID `json:"source_chain_id,omitempty"`
453413
DestinationChainID ids.ID `json:"destination_chain_id,omitempty"`
454414
RequestID uint32 `json:"request_id,omitempty"`
415+
ErrorCode int32 `json:"error_code,omitempty"`
416+
ErrorMessage string `json:"error_message,omitempty"`
455417
}
456418

457419
func (m *CrossChainAppRequestFailed) String() string {
@@ -473,19 +435,23 @@ func (m *CrossChainAppRequestFailed) GetRequestId() uint32 {
473435
return m.RequestID
474436
}
475437

476-
func InternalCrossChainAppRequestFailed(
438+
func InternalCrossChainAppError(
477439
nodeID ids.NodeID,
478440
sourceChainID ids.ID,
479441
destinationChainID ids.ID,
480442
requestID uint32,
443+
errorCode int32,
444+
errorMessage string,
481445
) InboundMessage {
482446
return &inboundMessage{
483447
nodeID: nodeID,
484-
op: CrossChainAppRequestFailedOp,
448+
op: CrossChainAppErrorOp,
485449
message: &CrossChainAppRequestFailed{
486450
SourceChainID: sourceChainID,
487451
DestinationChainID: destinationChainID,
488452
RequestID: requestID,
453+
ErrorCode: errorCode,
454+
ErrorMessage: errorMessage,
489455
},
490456
expiration: mockable.MaxTime,
491457
}

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.

0 commit comments

Comments
 (0)