github.com/MetalBlockchain/metalgo@v1.11.9/tests/e2e/p/permissionless_subnets.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package p 5 6 import ( 7 "fmt" 8 "time" 9 10 "github.com/stretchr/testify/require" 11 12 "github.com/MetalBlockchain/metalgo/ids" 13 "github.com/MetalBlockchain/metalgo/tests/fixture/e2e" 14 "github.com/MetalBlockchain/metalgo/utils/constants" 15 "github.com/MetalBlockchain/metalgo/utils/units" 16 "github.com/MetalBlockchain/metalgo/vms/components/avax" 17 "github.com/MetalBlockchain/metalgo/vms/components/verify" 18 "github.com/MetalBlockchain/metalgo/vms/platformvm" 19 "github.com/MetalBlockchain/metalgo/vms/platformvm/reward" 20 "github.com/MetalBlockchain/metalgo/vms/platformvm/signer" 21 "github.com/MetalBlockchain/metalgo/vms/platformvm/txs" 22 "github.com/MetalBlockchain/metalgo/vms/secp256k1fx" 23 24 ginkgo "github.com/onsi/ginkgo/v2" 25 ) 26 27 var _ = e2e.DescribePChain("[Permissionless Subnets]", func() { 28 require := require.New(ginkgo.GinkgoT()) 29 30 ginkgo.It("subnets operations", 31 func() { 32 nodeURI := e2e.Env.GetRandomNodeURI() 33 34 keychain := e2e.Env.NewKeychain(1) 35 baseWallet := e2e.NewWallet(keychain, nodeURI) 36 37 pWallet := baseWallet.P() 38 xWallet := baseWallet.X() 39 xBuilder := xWallet.Builder() 40 xContext := xBuilder.Context() 41 xChainID := xContext.BlockchainID 42 43 var validatorID ids.NodeID 44 ginkgo.By("retrieving the node ID of a primary network validator", func() { 45 pChainClient := platformvm.NewClient(nodeURI.URI) 46 validatorIDs, err := pChainClient.SampleValidators(e2e.DefaultContext(), constants.PrimaryNetworkID, 1) 47 require.NoError(err) 48 validatorID = validatorIDs[0] 49 }) 50 51 owner := &secp256k1fx.OutputOwners{ 52 Threshold: 1, 53 Addrs: []ids.ShortID{ 54 keychain.Keys[0].Address(), 55 }, 56 } 57 58 var subnetID ids.ID 59 ginkgo.By("create a permissioned subnet", func() { 60 subnetTx, err := pWallet.IssueCreateSubnetTx( 61 owner, 62 e2e.WithDefaultContext(), 63 ) 64 65 subnetID = subnetTx.ID() 66 require.NoError(err) 67 require.NotEqual(subnetID, constants.PrimaryNetworkID) 68 }) 69 70 var subnetAssetID ids.ID 71 ginkgo.By("create a custom asset for the permissionless subnet", func() { 72 subnetAssetTx, err := xWallet.IssueCreateAssetTx( 73 "RnM", 74 "RNM", 75 9, 76 map[uint32][]verify.State{ 77 0: { 78 &secp256k1fx.TransferOutput{ 79 Amt: 100 * units.MegaAvax, 80 OutputOwners: *owner, 81 }, 82 }, 83 }, 84 e2e.WithDefaultContext(), 85 ) 86 require.NoError(err) 87 subnetAssetID = subnetAssetTx.ID() 88 }) 89 90 ginkgo.By(fmt.Sprintf("Send 100 MegaAvax of asset %s to the P-chain", subnetAssetID), func() { 91 _, err := xWallet.IssueExportTx( 92 constants.PlatformChainID, 93 []*avax.TransferableOutput{ 94 { 95 Asset: avax.Asset{ 96 ID: subnetAssetID, 97 }, 98 Out: &secp256k1fx.TransferOutput{ 99 Amt: 100 * units.MegaAvax, 100 OutputOwners: *owner, 101 }, 102 }, 103 }, 104 e2e.WithDefaultContext(), 105 ) 106 require.NoError(err) 107 }) 108 109 ginkgo.By(fmt.Sprintf("Import the 100 MegaAvax of asset %s from the X-chain into the P-chain", subnetAssetID), func() { 110 _, err := pWallet.IssueImportTx( 111 xChainID, 112 owner, 113 e2e.WithDefaultContext(), 114 ) 115 require.NoError(err) 116 }) 117 118 ginkgo.By("make subnet permissionless", func() { 119 _, err := pWallet.IssueTransformSubnetTx( 120 subnetID, 121 subnetAssetID, 122 50*units.MegaAvax, 123 100*units.MegaAvax, 124 reward.PercentDenominator, 125 reward.PercentDenominator, 126 1, 127 100*units.MegaAvax, 128 time.Second, 129 365*24*time.Hour, 130 0, 131 1, 132 5, 133 .80*reward.PercentDenominator, 134 e2e.WithDefaultContext(), 135 ) 136 require.NoError(err) 137 }) 138 139 endTime := time.Now().Add(time.Minute) 140 ginkgo.By("add permissionless validator", func() { 141 _, err := pWallet.IssueAddPermissionlessValidatorTx( 142 &txs.SubnetValidator{ 143 Validator: txs.Validator{ 144 NodeID: validatorID, 145 End: uint64(endTime.Unix()), 146 Wght: 25 * units.MegaAvax, 147 }, 148 Subnet: subnetID, 149 }, 150 &signer.Empty{}, 151 subnetAssetID, 152 &secp256k1fx.OutputOwners{}, 153 &secp256k1fx.OutputOwners{}, 154 reward.PercentDenominator, 155 e2e.WithDefaultContext(), 156 ) 157 require.NoError(err) 158 }) 159 160 ginkgo.By("add permissionless delegator", func() { 161 _, err := pWallet.IssueAddPermissionlessDelegatorTx( 162 &txs.SubnetValidator{ 163 Validator: txs.Validator{ 164 NodeID: validatorID, 165 End: uint64(endTime.Unix()), 166 Wght: 25 * units.MegaAvax, 167 }, 168 Subnet: subnetID, 169 }, 170 subnetAssetID, 171 &secp256k1fx.OutputOwners{}, 172 e2e.WithDefaultContext(), 173 ) 174 require.NoError(err) 175 }) 176 }) 177 })