Skip to content

Commit

Permalink
[PVM] Forbid to change AddressStateBitConsortium with addressStateTx
Browse files Browse the repository at this point in the history
  • Loading branch information
evlekht committed Nov 13, 2023
1 parent d94fa7e commit 8c99fa2
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 29 deletions.
43 changes: 37 additions & 6 deletions vms/platformvm/camino_vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ func TestRemoveDeferredValidator(t *testing.T) {

nodeKey, nodeID := nodeid.GenerateCaminoNodeKeyAndID()

rootAdminKey := caminoPreFundedKeys[0]
adminProposerKey := caminoPreFundedKeys[0]
consortiumMemberKey, err := testKeyFactory.NewPrivateKey()
require.NoError(err)

Expand Down Expand Up @@ -81,14 +83,28 @@ func TestRemoveDeferredValidator(t *testing.T) {

// Set consortium member
tx, err := vm.txBuilder.NewAddressStateTx(
consortiumMemberKey.Address(),
adminProposerKey.Address(),
false,
as.AddressStateBitConsortium,
[]*secp256k1.PrivateKey{caminoPreFundedKeys[0]},
as.AddressStateBitAdminProposer,

Check failure on line 88 in vms/platformvm/camino_vm_test.go

View workflow job for this annotation

GitHub Actions / build_unit_test

undefined: addrstate.AddressStateBitAdminProposer
[]*secp256k1.PrivateKey{rootAdminKey},
outputOwners,
)
require.NoError(err)
_ = buildAndAcceptBlock(t, vm, tx)
proposalTx := buildAddMemberProposalTx(
t,
vm,
caminoPreFundedKeys[0],
vm.Config.CaminoConfig.DACProposalBondAmount,
defaultTxFee,
adminProposerKey, // AdminProposer
consortiumMemberKey.Address(),
vm.clock.Time(),
true,
)
_, _, _, _ = makeProposalWithTx(t, vm, proposalTx) // add admin proposal
_ = buildAndAcceptBlock(t, vm, nil) // execute admin proposal

// Register node
tx, err = vm.txBuilder.NewRegisterNodeTx(
ids.EmptyNodeID,
Expand Down Expand Up @@ -217,6 +233,8 @@ func TestRemoveReactivatedValidator(t *testing.T) {

nodeKey, nodeID := nodeid.GenerateCaminoNodeKeyAndID()

rootAdminKey := caminoPreFundedKeys[0]
adminProposerKey := caminoPreFundedKeys[0]
consortiumMemberKey, err := testKeyFactory.NewPrivateKey()
require.NoError(err)

Expand Down Expand Up @@ -251,14 +269,27 @@ func TestRemoveReactivatedValidator(t *testing.T) {

// Set consortium member
tx, err := vm.txBuilder.NewAddressStateTx(
consortiumMemberKey.Address(),
adminProposerKey.Address(),
false,
as.AddressStateBitConsortium,
[]*secp256k1.PrivateKey{caminoPreFundedKeys[0]},
as.AddressStateBitAdminProposer,

Check failure on line 274 in vms/platformvm/camino_vm_test.go

View workflow job for this annotation

GitHub Actions / build_unit_test

undefined: addrstate.AddressStateBitAdminProposer
[]*secp256k1.PrivateKey{rootAdminKey},
outputOwners,
)
require.NoError(err)
_ = buildAndAcceptBlock(t, vm, tx)
proposalTx := buildAddMemberProposalTx(
t,
vm,
caminoPreFundedKeys[0],
vm.Config.CaminoConfig.DACProposalBondAmount,
defaultTxFee,
adminProposerKey, // AdminProposer
consortiumMemberKey.Address(),
vm.clock.Time(),
true,
)
_, _, _, _ = makeProposalWithTx(t, vm, proposalTx) // add admin proposal
_ = buildAndAcceptBlock(t, vm, nil) // execute admin proposal

// Register node
tx, err = vm.txBuilder.NewRegisterNodeTx(
Expand Down
17 changes: 13 additions & 4 deletions vms/platformvm/txs/executor/camino_tx_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2149,8 +2149,11 @@ func (e *CaminoStandardTxExecutor) AddressStateTx(tx *txs.AddressStateTx) error
roles := as.AddressStateEmpty
creds := e.Tx.Creds

chainTime := e.State.GetTimestamp()
isAthensPhase := e.Config.IsAthensPhaseActivated(chainTime)

if tx.UpgradeVersionID.Version() > 0 {
if !e.Config.IsAthensPhaseActivated(e.State.GetTimestamp()) {
if !isAthensPhase {
return errNotAthensPhase
}
if err = e.Backend.Fx.VerifyMultisigPermission(
Expand Down Expand Up @@ -2199,9 +2202,15 @@ func (e *CaminoStandardTxExecutor) AddressStateTx(tx *txs.AddressStateTx) error
}
statesBit := as.AddressState(1) << tx.State

// Check for AthensPhase Bits if we time has not passed yet
if (statesBit&as.AddressStateAthensPhaseBits) != 0 &&
!e.Config.IsAthensPhaseActivated(e.State.GetTimestamp()) {
// Check for bits that was affected or introduced in AthensPhase
if !isAthensPhase && statesBit&as.AddressStateAthensPhaseBits != 0 {
return errAddrStateNotPermitted
}

// Check for bits that was affected or introduced in BerlinPhase
isBerlinPhase := e.Config.IsBerlinPhaseActivated(chainTime)
if !isBerlinPhase && statesBit&as.AddressStateBerlinPhaseBits != 0 ||
isBerlinPhase && tx.State == as.AddressStateBitConsortium { // Berlin phase moved consortium handling to admin proposals
return errAddrStateNotPermitted
}

Expand Down
54 changes: 35 additions & 19 deletions vms/platformvm/txs/executor/camino_tx_executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1659,7 +1659,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
targetAddress: bob,
txFlag: as.AddressStateBitRoleKYC,
existingState: as.AddressStateRoleKYC,
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted},
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted, errAddrStateNotPermitted},
remove: false,
},
// Bob has KYC role, and he is trying to give himself Admin role
Expand All @@ -1668,7 +1668,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
targetAddress: bob,
txFlag: as.AddressStateBitRoleAdmin,
existingState: as.AddressStateRoleKYC,
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted},
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted, errAddrStateNotPermitted},
remove: false,
},
// Bob has Admin role, and he is trying to give Alice Admin role
Expand Down Expand Up @@ -1714,7 +1714,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
txFlag: as.AddressStateBitRoleAdmin,
existingState: as.AddressStateRoleAdmin,
expectedState: 0,
expectedErrs: []error{errAdminCannotBeDeleted, errAdminCannotBeDeleted},
expectedErrs: []error{errAdminCannotBeDeleted, errAdminCannotBeDeleted, errAdminCannotBeDeleted},
remove: true,
},
// Bob has Admin role, and he is trying to give Alice the KYC Verified state
Expand Down Expand Up @@ -1743,6 +1743,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
existingState: as.AddressStateRoleAdmin,
expectedState: as.AddressStateConsortiumMember,
remove: false,
expectedErrs: []error{nil, nil, errAddrStateNotPermitted},
},
// Bob has KYC role, and he is trying to give Alice KYC Expired state
"State: KYC, Flag: KYC Expired, Add, Different Address": {
Expand All @@ -1768,7 +1769,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
targetAddress: alice,
txFlag: as.AddressStateBitRoleAdmin,
existingState: as.AddressStateRoleAdmin,
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted},
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted, errAddrStateNotPermitted},
remove: false,
},
// An Empty Address has Admin role, and he is trying to give Alice Admin role
Expand All @@ -1777,7 +1778,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
targetAddress: alice,
txFlag: as.AddressStateBitRoleAdmin,
existingState: as.AddressStateRoleAdmin,
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted},
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted, errAddrStateNotPermitted},
remove: false,
},
// Bob has Admin role, and he is trying to give Admin role to an Empty Address
Expand All @@ -1786,7 +1787,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
targetAddress: ids.ShortEmpty,
txFlag: as.AddressStateBitRoleAdmin,
existingState: as.AddressStateRoleAdmin,
expectedErrs: []error{txs.ErrEmptyAddress, txs.ErrEmptyAddress},
expectedErrs: []error{txs.ErrEmptyAddress, txs.ErrEmptyAddress, txs.ErrEmptyAddress},
remove: false,
},
// Bob has empty addr state, and he is trying to give Alice Admin role
Expand All @@ -1796,7 +1797,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
txFlag: as.AddressStateBitRoleAdmin,
existingState: as.AddressStateEmpty,
remove: false,
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted},
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted, errAddrStateNotPermitted},
},
// Bob has empty addr state, and he is trying to remove Admin role from Alice
"State: none, Flag: Admin role, Remove, Different Address": {
Expand All @@ -1805,7 +1806,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
txFlag: as.AddressStateBitRoleAdmin,
existingState: as.AddressStateEmpty,
remove: true,
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted},
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted, errAddrStateNotPermitted},
},
// Bob has empty addr state, and he is trying to give Alice KYC role
"State: none, Flag: KYC role, Add, Different Address": {
Expand All @@ -1814,7 +1815,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
txFlag: as.AddressStateBitRoleKYC,
existingState: as.AddressStateEmpty,
remove: false,
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted},
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted, errAddrStateNotPermitted},
},
// Bob has empty addr state, and he is trying to remove KYC role from Alice
"State: none, Flag: KYC role, Remove, Different Address": {
Expand All @@ -1823,7 +1824,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
txFlag: as.AddressStateBitRoleKYC,
existingState: as.AddressStateEmpty,
remove: true,
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted},
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted, errAddrStateNotPermitted},
},
// Bob has empty addr state, and he is trying to give Alice KYC Verified state
"State: none, Flag: KYC Verified, Add, Different Address": {
Expand All @@ -1832,7 +1833,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
txFlag: as.AddressStateBitKYCVerified,
existingState: as.AddressStateEmpty,
remove: false,
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted},
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted, errAddrStateNotPermitted},
},
// Bob has empty addr state, and he is trying to remove KYC Verified state from Alice
"State: none, Flag: KYC Verified, Remove, Different Address": {
Expand All @@ -1841,7 +1842,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
txFlag: as.AddressStateBitKYCVerified,
existingState: as.AddressStateEmpty,
remove: true,
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted},
expectedErrs: []error{errAddrStateNotPermitted, errAddrStateNotPermitted, errAddrStateNotPermitted},
},
// Bob has KYC role, and he is trying to give Alice KYC Expired state
"Upgrade: 1, State: KYC, Flag: KYC Expired, Add, Different Address": {
Expand All @@ -1864,7 +1865,7 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
txFlag: as.AddressStateBitKYCExpired,
existingState: as.AddressStateRoleKYC,
expectedState: as.AddressStateKYCExpired,
expectedErrs: []error{errNotAthensPhase, errSignatureMissing},
expectedErrs: []error{errNotAthensPhase, errSignatureMissing, errSignatureMissing},
remove: false,
executor: alice,
executorAuth: &secp256k1fx.Input{SigIndices: []uint32{0}},
Expand All @@ -1882,15 +1883,30 @@ func TestAddAddressStateTxExecutor(t *testing.T) {
},
}}

athensPhaseTimes := []time.Time{
env.state.GetTimestamp().Add(24 * time.Hour), // AthensPhase not yet active (> chainTime)
env.state.GetTimestamp(), // AthensPhase active (<= chainTime)
chainTime := env.state.GetTimestamp()

fnSetPhaseTimes := []func() string{
func() string {
env.config.AthensPhaseTime = chainTime.Add(1 * time.Second) // not yet active
env.config.BerlinPhaseTime = chainTime.Add(2 * time.Second) // not yet active
return "Sunrise"
},
func() string {
env.config.AthensPhaseTime = chainTime // active
env.config.BerlinPhaseTime = chainTime.Add(1 * time.Second) // not yet active
return "Athens"
},
func() string {
env.config.AthensPhaseTime = chainTime.Add(-1 * time.Second) // active
env.config.BerlinPhaseTime = chainTime // active
return "Berlin"
},
}

for phase := 0; phase < 2; phase++ {
env.config.AthensPhaseTime = athensPhaseTimes[phase]
for phase := 0; phase < 3; phase++ {
phaseName := fnSetPhaseTimes[phase]()
for name, tt := range tests {
t.Run(fmt.Sprintf("Phase %d; %s", phase, name), func(t *testing.T) {
t.Run(fmt.Sprintf("%s; %s", phaseName, name), func(t *testing.T) {
addressStateTx := &txs.AddressStateTx{
UpgradeVersionID: codec.BuildUpgradeVersionID(tt.UpgradeVersion),
BaseTx: baseTx,
Expand Down

0 comments on commit 8c99fa2

Please sign in to comment.