diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 54edaca9c3b..0b860f7b311 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -274,8 +274,7 @@ func removeSubnetValidatorValidation( ) } - if vdr.Priority != txs.SubnetPermissionedValidatorCurrentPriority && - vdr.Priority != txs.SubnetPermissionedValidatorPendingPriority { + if !vdr.Priority.IsPermissionedValidator() { return nil, false, errRemovePermissionlessValidator } @@ -696,8 +695,7 @@ func verifyAddPermissionlessDelegatorTx( // AddSubnetValidatorTx. AddSubnetValidatorTx is the only // permissioned validator, so we verify this delegator is // pointing to a permissionless validator. - if validator.Priority == txs.SubnetPermissionedValidatorCurrentPriority || - validator.Priority == txs.SubnetPermissionedValidatorPendingPriority { + if validator.Priority.IsPermissionedValidator() { return errDelegateToPermissionedValidator } diff --git a/vms/platformvm/txs/priorities.go b/vms/platformvm/txs/priorities.go index fdd65d74a92..6a4fb4dc10a 100644 --- a/vms/platformvm/txs/priorities.go +++ b/vms/platformvm/txs/priorities.go @@ -44,3 +44,47 @@ var PendingToCurrentPriorities = []Priority{ } type Priority byte + +func (p Priority) IsCurrent() bool { + return p.IsCurrentValidator() || p.IsCurrentDelegator() +} + +func (p Priority) IsPending() bool { + return p.IsPendingValidator() || p.IsPendingDelegator() +} + +func (p Priority) IsValidator() bool { + return p.IsCurrentValidator() || p.IsPendingValidator() +} + +func (p Priority) IsPermissionedValidator() bool { + return p == SubnetPermissionedValidatorCurrentPriority || + p == SubnetPermissionedValidatorPendingPriority +} + +func (p Priority) IsDelegator() bool { + return p.IsCurrentDelegator() || p.IsPendingDelegator() +} + +func (p Priority) IsCurrentValidator() bool { + return p == PrimaryNetworkValidatorCurrentPriority || + p == SubnetPermissionedValidatorCurrentPriority || + p == SubnetPermissionlessValidatorCurrentPriority +} + +func (p Priority) IsCurrentDelegator() bool { + return p == PrimaryNetworkDelegatorCurrentPriority || + p == SubnetPermissionlessDelegatorCurrentPriority +} + +func (p Priority) IsPendingValidator() bool { + return p == PrimaryNetworkValidatorPendingPriority || + p == SubnetPermissionedValidatorPendingPriority || + p == SubnetPermissionlessValidatorPendingPriority +} + +func (p Priority) IsPendingDelegator() bool { + return p == PrimaryNetworkDelegatorBanffPendingPriority || + p == PrimaryNetworkDelegatorApricotPendingPriority || + p == SubnetPermissionlessDelegatorPendingPriority +} diff --git a/vms/platformvm/txs/priorities_test.go b/vms/platformvm/txs/priorities_test.go new file mode 100644 index 00000000000..ce266d5d7ad --- /dev/null +++ b/vms/platformvm/txs/priorities_test.go @@ -0,0 +1,524 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package txs + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestPriorityIsCurrent(t *testing.T) { + tests := []struct { + priority Priority + expected bool + }{ + { + priority: PrimaryNetworkDelegatorApricotPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorBanffPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorCurrentPriority, + expected: true, + }, + { + priority: SubnetPermissionlessDelegatorCurrentPriority, + expected: true, + }, + { + priority: SubnetPermissionlessValidatorCurrentPriority, + expected: true, + }, + { + priority: PrimaryNetworkDelegatorCurrentPriority, + expected: true, + }, + { + priority: PrimaryNetworkValidatorCurrentPriority, + expected: true, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d", test.priority), func(t *testing.T) { + require.Equal(t, test.expected, test.priority.IsCurrent()) + }) + } +} + +func TestPriorityIsPending(t *testing.T) { + tests := []struct { + priority Priority + expected bool + }{ + { + priority: PrimaryNetworkDelegatorApricotPendingPriority, + expected: true, + }, + { + priority: PrimaryNetworkValidatorPendingPriority, + expected: true, + }, + { + priority: PrimaryNetworkDelegatorBanffPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionlessValidatorPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionlessDelegatorPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionedValidatorPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionedValidatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorCurrentPriority, + expected: false, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d", test.priority), func(t *testing.T) { + require.Equal(t, test.expected, test.priority.IsPending()) + }) + } +} + +func TestPriorityIsValidator(t *testing.T) { + tests := []struct { + priority Priority + expected bool + }{ + { + priority: PrimaryNetworkDelegatorApricotPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorPendingPriority, + expected: true, + }, + { + priority: PrimaryNetworkDelegatorBanffPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionlessDelegatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionedValidatorCurrentPriority, + expected: true, + }, + { + priority: SubnetPermissionlessDelegatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorCurrentPriority, + expected: true, + }, + { + priority: PrimaryNetworkDelegatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorCurrentPriority, + expected: true, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d", test.priority), func(t *testing.T) { + require.Equal(t, test.expected, test.priority.IsValidator()) + }) + } +} + +func TestPriorityIsPermissionedValidator(t *testing.T) { + tests := []struct { + priority Priority + expected bool + }{ + { + priority: PrimaryNetworkDelegatorApricotPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorBanffPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionedValidatorCurrentPriority, + expected: true, + }, + { + priority: SubnetPermissionlessDelegatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorCurrentPriority, + expected: false, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d", test.priority), func(t *testing.T) { + require.Equal(t, test.expected, test.priority.IsPermissionedValidator()) + }) + } +} + +func TestPriorityIsDelegator(t *testing.T) { + tests := []struct { + priority Priority + expected bool + }{ + { + priority: PrimaryNetworkDelegatorApricotPendingPriority, + expected: true, + }, + { + priority: PrimaryNetworkValidatorPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorBanffPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionlessValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionedValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorCurrentPriority, + expected: true, + }, + { + priority: SubnetPermissionlessValidatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorCurrentPriority, + expected: true, + }, + { + priority: PrimaryNetworkValidatorCurrentPriority, + expected: false, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d", test.priority), func(t *testing.T) { + require.Equal(t, test.expected, test.priority.IsDelegator()) + }) + } +} + +func TestPriorityIsCurrentValidator(t *testing.T) { + tests := []struct { + priority Priority + expected bool + }{ + { + priority: PrimaryNetworkDelegatorApricotPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorBanffPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorCurrentPriority, + expected: true, + }, + { + priority: SubnetPermissionlessDelegatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorCurrentPriority, + expected: true, + }, + { + priority: PrimaryNetworkDelegatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorCurrentPriority, + expected: true, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d", test.priority), func(t *testing.T) { + require.Equal(t, test.expected, test.priority.IsCurrentValidator()) + }) + } +} + +func TestPriorityIsCurrentDelegator(t *testing.T) { + tests := []struct { + priority Priority + expected bool + }{ + { + priority: PrimaryNetworkDelegatorApricotPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorBanffPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorCurrentPriority, + expected: true, + }, + { + priority: SubnetPermissionlessValidatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorCurrentPriority, + expected: true, + }, + { + priority: PrimaryNetworkValidatorCurrentPriority, + expected: false, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d", test.priority), func(t *testing.T) { + require.Equal(t, test.expected, test.priority.IsCurrentDelegator()) + }) + } +} + +func TestPriorityIsPendingValidator(t *testing.T) { + tests := []struct { + priority Priority + expected bool + }{ + { + priority: PrimaryNetworkDelegatorApricotPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorPendingPriority, + expected: true, + }, + { + priority: PrimaryNetworkDelegatorBanffPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionlessDelegatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionedValidatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorCurrentPriority, + expected: false, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d", test.priority), func(t *testing.T) { + require.Equal(t, test.expected, test.priority.IsPendingValidator()) + }) + } +} + +func TestPriorityIsPendingDelegator(t *testing.T) { + tests := []struct { + priority Priority + expected bool + }{ + { + priority: PrimaryNetworkDelegatorApricotPendingPriority, + expected: true, + }, + { + priority: PrimaryNetworkValidatorPendingPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorBanffPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionlessValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorPendingPriority, + expected: true, + }, + { + priority: SubnetPermissionedValidatorPendingPriority, + expected: false, + }, + { + priority: SubnetPermissionedValidatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessDelegatorCurrentPriority, + expected: false, + }, + { + priority: SubnetPermissionlessValidatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkDelegatorCurrentPriority, + expected: false, + }, + { + priority: PrimaryNetworkValidatorCurrentPriority, + expected: false, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d", test.priority), func(t *testing.T) { + require.Equal(t, test.expected, test.priority.IsPendingDelegator()) + }) + } +}