diff --git a/tests/e2e/p/permissionless_subnets.go b/tests/e2e/p/elastic_subnets.go similarity index 91% rename from tests/e2e/p/permissionless_subnets.go rename to tests/e2e/p/elastic_subnets.go index 21934ff6c619..b49c3dff1492 100644 --- a/tests/e2e/p/permissionless_subnets.go +++ b/tests/e2e/p/elastic_subnets.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/utils/constants" @@ -24,7 +25,7 @@ import ( ginkgo "github.com/onsi/ginkgo/v2" ) -var _ = e2e.DescribePChain("[Permissionless Subnets]", func() { +var _ = e2e.DescribePChain("[Elastic Subnets]", func() { tc := e2e.NewTestContext() require := require.New(tc) @@ -34,6 +35,17 @@ var _ = e2e.DescribePChain("[Permissionless Subnets]", func() { nodeURI := env.GetRandomNodeURI() + infoClient := info.NewClient(nodeURI.URI) + + tc.By("get upgrade config") + upgrades, err := infoClient.Upgrades(tc.DefaultContext()) + require.NoError(err) + + now := time.Now() + if upgrades.IsEtnaActivated(now) { + ginkgo.Skip("Etna is activated. Elastic Subnets are disabled post-Etna, skipping test.") + } + keychain := env.NewKeychain(1) baseWallet := e2e.NewWallet(tc, keychain, nodeURI) diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 58eeb71e1fea..1204b7d82502 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -28,6 +28,7 @@ var ( errEmptyNodeID = errors.New("validator nodeID cannot be empty") errMaxStakeDurationTooLarge = errors.New("max stake duration must be less than or equal to the global max stake duration") errMissingStartTimePreDurango = errors.New("staker transactions must have a StartTime pre-Durango") + errTransformSubnetTxPostEtna = errors.New("TransformSubnetTx is not permitted post-Etna") ) type StandardTxExecutor struct { @@ -433,14 +434,16 @@ func (e *StandardTxExecutor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidat } func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error { + currentTimestamp := e.State.GetTimestamp() + if e.Config.UpgradeConfig.IsEtnaActivated(currentTimestamp) { + return errTransformSubnetTxPostEtna + } + if err := e.Tx.SyntacticVerify(e.Ctx); err != nil { return err } - var ( - currentTimestamp = e.State.GetTimestamp() - isDurangoActive = e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) - ) + isDurangoActive := e.Config.UpgradeConfig.IsDurangoActivated(currentTimestamp) if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil { return err } diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index f6bd40f7aae3..d57955c08b39 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -1597,6 +1597,29 @@ func TestDurangoMemoField(t *testing.T) { } } +// Verifies that [TransformSubnetTx] is disabled post-Etna +func TestEtnaDisabledTransactions(t *testing.T) { + require := require.New(t) + + env := newEnvironment(t, etna) + env.ctx.Lock.Lock() + defer env.ctx.Lock.Unlock() + + onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) + require.NoError(err) + + tx := &txs.Tx{ + Unsigned: &txs.TransformSubnetTx{}, + } + + err = tx.Unsigned.Visit(&StandardTxExecutor{ + Backend: &env.backend, + State: onAcceptState, + Tx: tx, + }) + require.ErrorIs(err, errTransformSubnetTxPostEtna) +} + // Returns a RemoveSubnetValidatorTx that passes syntactic verification. // Memo field is empty as required post Durango activation func newRemoveSubnetValidatorTx(t *testing.T) (*txs.RemoveSubnetValidatorTx, *txs.Tx) {