Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict Owner usage after a Subnet manager is set #3147

Merged
merged 39 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1857cb9
[vms/platformvm] Add tracking of a Subnet manager
dhrubabasu Jun 18, 2024
4d11a29
Merge branch 'master' into store-warp-addressed-call-pair
dhrubabasu Jun 18, 2024
90a38ff
Update vms/platformvm/state/diff.go
dhrubabasu Jun 18, 2024
f60e4ea
nit
dhrubabasu Jun 18, 2024
1ca0caf
nit
dhrubabasu Jun 20, 2024
1cd2428
nit
dhrubabasu Jun 20, 2024
3587c32
nit
dhrubabasu Jun 20, 2024
ec16c11
[vms/platformvm] Cleanup execution config tests
dhrubabasu Jun 20, 2024
f52cbbe
Merge branch 'master' into cleanup-execution-config-test
dhrubabasu Jun 20, 2024
076b1f0
nit
dhrubabasu Jun 20, 2024
df5ca64
nit
dhrubabasu Jun 20, 2024
dcc056b
Merge branch 'master' into cleanup-execution-config-test
dhrubabasu Jun 20, 2024
3279764
nit
dhrubabasu Jun 21, 2024
911a167
mark as helper
dhrubabasu Jun 21, 2024
ddf3392
Merge branch 'master' into cleanup-execution-config-test
dhrubabasu Jun 21, 2024
25802a8
merged
dhrubabasu Jun 21, 2024
01b854a
reduce diff
dhrubabasu Jun 21, 2024
f79e0c7
add write
dhrubabasu Jun 24, 2024
1eda29c
merged
dhrubabasu Jun 24, 2024
3fa1306
nits
dhrubabasu Jun 25, 2024
16ffe7b
nit
dhrubabasu Jun 25, 2024
3035064
nits
dhrubabasu Jun 25, 2024
62ece94
Merge branch 'master' into store-warp-addressed-call-pair
dhrubabasu Jun 25, 2024
333a41e
fix UT
dhrubabasu Jun 25, 2024
520ac91
add UTs
dhrubabasu Jun 25, 2024
db5f197
lint
dhrubabasu Jun 25, 2024
9b8aa4a
merged
dhrubabasu Aug 5, 2024
1d72e1b
nits
dhrubabasu Aug 5, 2024
be79d4c
Merge branch 'master' into disable-permissioned-subnet-txs-post-manager
dhrubabasu Aug 11, 2024
367cf42
disable CreateChainTx
dhrubabasu Aug 11, 2024
413a7a9
Merge branch 'master' into disable-permissioned-subnet-txs-post-manager
dhrubabasu Aug 13, 2024
952fd7f
nit
dhrubabasu Aug 14, 2024
db18027
nit
dhrubabasu Aug 14, 2024
e019360
Merge branch 'master' into disable-permissioned-subnet-txs-post-manager
dhrubabasu Aug 14, 2024
ddf94a4
RemoveSubnet
dhrubabasu Aug 14, 2024
643ddbd
fix test
dhrubabasu Aug 14, 2024
6e2660f
nit
dhrubabasu Aug 19, 2024
0ebf806
Merge branch 'master' into disable-permissioned-subnet-txs-post-manager
dhrubabasu Aug 19, 2024
ca1ba73
use upgradetest
dhrubabasu Aug 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions vms/platformvm/txs/executor/create_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,40 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) {
})
}
}

func TestEtnaCreateChainTxInvalidWithManagedSubnet(t *testing.T) {
require := require.New(t)
env := newEnvironment(t, upgradetest.Etna)
env.ctx.Lock.Lock()
defer env.ctx.Lock.Unlock()

builder, signer := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1])
utx, err := builder.NewCreateChainTx(
testSubnet1.ID(),
nil,
constants.AVMID,
nil,
"chain name",
)
require.NoError(err)
tx, err := walletsigner.SignUnsigned(context.Background(), signer, utx)
require.NoError(err)

stateDiff, err := state.NewDiff(lastAcceptedID, env)
require.NoError(err)

builderDiff, err := state.NewDiffOn(stateDiff)
require.NoError(err)

stateDiff.SetSubnetManager(testSubnet1.ID(), ids.GenerateTestID(), []byte{'a', 'd', 'd', 'r', 'e', 's', 's'})

feeCalculator := state.PickFeeCalculator(env.config, builderDiff)
executor := StandardTxExecutor{
Backend: &env.backend,
FeeCalculator: feeCalculator,
State: stateDiff,
Tx: tx,
}
err = tx.Unsigned.Visit(&executor)
require.ErrorIs(err, errIsImmutable)
}
11 changes: 11 additions & 0 deletions vms/platformvm/txs/executor/staker_tx_verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var (
ErrDurangoUpgradeNotActive = errors.New("attempting to use a Durango-upgrade feature prior to activation")
ErrAddValidatorTxPostDurango = errors.New("AddValidatorTx is not permitted post-Durango")
ErrAddDelegatorTxPostDurango = errors.New("AddDelegatorTx is not permitted post-Durango")
ErrRemoveValidatorManagedSubnet = errors.New("RemoveSubnetValidatorTx cannot be used to remove a validator from a Subnet with a manager")
)

// verifySubnetValidatorPrimaryNetworkRequirements verifies the primary
Expand Down Expand Up @@ -306,6 +307,16 @@ func verifyRemoveSubnetValidatorTx(
return nil, false, err
}

if backend.Config.UpgradeConfig.IsEtnaActivated(currentTimestamp) {
_, _, err := chainState.GetSubnetManager(tx.Subnet)
if err == nil {
return nil, false, fmt.Errorf("%w: %q", ErrRemoveValidatorManagedSubnet, tx.Subnet)
}
if err != database.ErrNotFound {
return nil, false, err
}
}

isCurrentValidator := true
vdr, err := chainState.GetCurrentValidator(tx.Subnet, tx.NodeID)
if err == database.ErrNotFound {
Expand Down
101 changes: 101 additions & 0 deletions vms/platformvm/txs/executor/standard_tx_executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,44 @@ func TestApricotStandardTxExecutorAddSubnetValidator(t *testing.T) {
}
}

func TestEtnaStandardTxExecutorAddSubnetValidator(t *testing.T) {
require := require.New(t)
env := newEnvironment(t, upgradetest.Etna)
env.ctx.Lock.Lock()
defer env.ctx.Lock.Unlock()

nodeID := genesisNodeIDs[0]

builder, signer := env.factory.NewWallet(testSubnet1ControlKeys[0], testSubnet1ControlKeys[1])
utx, err := builder.NewAddSubnetValidatorTx(
&txs.SubnetValidator{
Validator: txs.Validator{
NodeID: nodeID,
Start: uint64(defaultValidateStartTime.Unix() + 1),
End: uint64(defaultValidateEndTime.Unix()),
Wght: defaultWeight,
},
Subnet: testSubnet1.ID(),
},
)
require.NoError(err)
tx, err := walletsigner.SignUnsigned(context.Background(), signer, utx)
require.NoError(err)

onAcceptState, err := state.NewDiff(lastAcceptedID, env)
require.NoError(err)

onAcceptState.SetSubnetManager(testSubnet1.ID(), ids.GenerateTestID(), []byte{'a', 'd', 'd', 'r', 'e', 's', 's'})

executor := StandardTxExecutor{
Backend: &env.backend,
State: onAcceptState,
Tx: tx,
}
err = tx.Unsigned.Visit(&executor)
require.ErrorIs(err, errIsImmutable)
}

func TestBanffStandardTxExecutorAddValidator(t *testing.T) {
require := require.New(t)
env := newEnvironment(t, upgradetest.Banff)
Expand Down Expand Up @@ -1984,6 +2022,32 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) {
},
expectedErr: ErrFlowCheckFailed,
},
{
name: "attempted to remove subnet validator after subnet manager is set",
marun marked this conversation as resolved.
Show resolved Hide resolved
newExecutor: func(ctrl *gomock.Controller) (*txs.RemoveSubnetValidatorTx, *StandardTxExecutor) {
env := newValidRemoveSubnetValidatorTxVerifyEnv(t, ctrl)
env.state.EXPECT().GetSubnetManager(env.unsignedTx.Subnet).Return(ids.GenerateTestID(), []byte{'a', 'd', 'd', 'r', 'e', 's', 's'}, nil).AnyTimes()
env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes()

cfg := &config.Config{
UpgradeConfig: upgradetest.GetConfigWithUpgradeTime(upgradetest.Etna, env.latestForkTime),
}
e := &StandardTxExecutor{
Backend: &Backend{
Config: cfg,
Bootstrapped: &utils.Atomic[bool]{},
Fx: env.fx,
FlowChecker: env.flowChecker,
Ctx: &snow.Context{},
},
Tx: env.tx,
State: env.state,
}
e.Bootstrapped.Set(true)
return env.unsignedTx, e
},
expectedErr: ErrRemoveValidatorManagedSubnet,
},
}

for _, tt := range tests {
Expand Down Expand Up @@ -2213,6 +2277,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) {
subnetOwner := fx.NewMockOwner(ctrl)
env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes()
env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil)
env.state.EXPECT().GetSubnetManager(env.unsignedTx.Subnet).Return(ids.Empty, nil, database.ErrNotFound).Times(1)
env.state.EXPECT().GetSubnetTransformation(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound).Times(1)
env.fx.EXPECT().VerifyPermission(gomock.Any(), env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(nil)
env.flowChecker.EXPECT().VerifySpend(
Expand Down Expand Up @@ -2242,6 +2307,41 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) {
},
err: ErrFlowCheckFailed,
},
{
name: "invalid if subnet manager is set",
newExecutor: func(ctrl *gomock.Controller) (*txs.TransformSubnetTx, *StandardTxExecutor) {
env := newValidTransformSubnetTxVerifyEnv(t, ctrl)

// Set dependency expectations.
subnetOwner := fx.NewMockOwner(ctrl)
env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes()
env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil).Times(1)
env.state.EXPECT().GetSubnetManager(env.unsignedTx.Subnet).Return(ids.GenerateTestID(), make([]byte, 20), nil)
env.state.EXPECT().GetSubnetTransformation(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound).Times(1)
env.fx.EXPECT().VerifyPermission(env.unsignedTx, env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(nil).Times(1)

cfg := &config.Config{
UpgradeConfig: upgradetest.GetConfigWithUpgradeTime(upgradetest.Durango, env.latestForkTime),
MaxStakeDuration: math.MaxInt64,
}
feeCalculator := state.PickFeeCalculator(cfg, env.state)
e := &StandardTxExecutor{
Backend: &Backend{
Config: cfg,
Bootstrapped: &utils.Atomic[bool]{},
Fx: env.fx,
FlowChecker: env.flowChecker,
Ctx: &snow.Context{},
},
FeeCalculator: feeCalculator,
Tx: env.tx,
State: env.state,
}
e.Bootstrapped.Set(true)
return env.unsignedTx, e
},
err: errIsImmutable,
},
{
name: "valid tx",
newExecutor: func(ctrl *gomock.Controller) (*txs.TransformSubnetTx, *StandardTxExecutor) {
Expand All @@ -2251,6 +2351,7 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) {
subnetOwner := fx.NewMockOwner(ctrl)
env.state.EXPECT().GetTimestamp().Return(env.latestForkTime).AnyTimes()
env.state.EXPECT().GetSubnetOwner(env.unsignedTx.Subnet).Return(subnetOwner, nil).Times(1)
env.state.EXPECT().GetSubnetManager(env.unsignedTx.Subnet).Return(ids.Empty, nil, database.ErrNotFound).Times(1)
env.state.EXPECT().GetSubnetTransformation(env.unsignedTx.Subnet).Return(nil, database.ErrNotFound).Times(1)
env.fx.EXPECT().VerifyPermission(env.unsignedTx, env.unsignedTx.SubnetAuth, env.tx.Creds[len(env.tx.Creds)-1], subnetOwner).Return(nil).Times(1)
env.flowChecker.EXPECT().VerifySpend(
Expand Down
8 changes: 8 additions & 0 deletions vms/platformvm/txs/executor/subnet_tx_verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ func verifyPoASubnetAuthorization(
return nil, err
}

_, _, err = chainState.GetSubnetManager(subnetID)
if err == nil {
return nil, fmt.Errorf("%q %w", subnetID, errIsImmutable)
}
if err != database.ErrNotFound {
return nil, err
}

dhrubabasu marked this conversation as resolved.
Show resolved Hide resolved
return creds, nil
}

Expand Down
Loading