logoDocumentation

Deploy Custom VM

This page demonstrates how to deploy a custom VM into cloud-based validators using Avalanche-CLI.

Note

Currently, only Fuji network and Devnets are supported.

ALPHA WARNING: This command is currently in experimental mode. Proceed at your own risk.

Prerequisites

Before we begin, you will need to have:

  • Created a cloud server node as described here
  • Created a Custom VM, as described here.
  • (Ignore for Devnet) Set up a key to be able to pay for transaction Fees, as described here.

Currently, only AWS & GCP cloud services are supported.

Deploying the VM

We will be deploying the MorpheusVM example built with the HyperSDK.

The following settings will be used:

  • Repo url: https://github.com/ava-labs/hypersdk/
  • Branch Name: vryx-poc
  • Build Script: examples/morpheusvm/scripts/build.sh
Note

The CLI needs a public repo url in order to be able to download and install the custom VM on cloud.

Genesis File

The following contents will serve as the chain genesis. They were generated using morpheus-cli as shown here.

Save it into a file with path <genesisPath> (for example ~/morpheusvm_genesis.json):

{
  "stateBranchFactor":16,
  "minBlockGap":1000,
  "minUnitPrice":[1,1,1,1,1],
  "maxChunkUnits":[1800000,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615],
  "epochDuration":60000,
  "validityWindow":59000,
  "partitions":8,
  "baseUnits":1,
  "baseWarpUnits":1024,
  "warpUnitsPerSigner":128,
  "outgoingWarpComputeUnits":1024,
  "storageKeyReadUnits":5,
  "storageValueReadUnits":2,
  "storageKeyAllocateUnits":20,
  "storageValueAllocateUnits":5,
  "storageKeyWriteUnits":10,
  "storageValueWriteUnits":3,
  "customAllocation": [
    {
      "address":"morpheus1qrzvk4zlwj9zsacqgtufx7zvapd3quufqpxk5rsdd4633m4wz2fdjk97rwu",
      "balance":3000000000000000000
    },
    {"address":"morpheus1qryyvfut6td0l2vwn8jwae0pmmev7eqxs2vw0fxpd2c4lr37jj7wvrj4vc3",
      "balance":3000000000000000000
    },
    {"address":"morpheus1qp52zjc3ul85309xn9stldfpwkseuth5ytdluyl7c5mvsv7a4fc76g6c4w4",
      "balance":3000000000000000000
    },
    {"address":"morpheus1qzqjp943t0tudpw06jnvakdc0y8w790tzk7suc92aehjw0epvj93s0uzasn",
      "balance":3000000000000000000
    },
    {"address":"morpheus1qz97wx3vl3upjuquvkulp56nk20l3jumm3y4yva7v6nlz5rf8ukty8fh27r",
      "balance":3000000000000000000
    }
  ]
}

Create the Avalanche L1

Let's create an Avalanche L1 called <blockchainName>, with custom VM binary and genesis.

avalanche blockchain create <blockchainName>

Choose custom

Use the arrow keys to navigate:
? Choose your VM:
    Subnet-EVM
 Custom

Provide path to genesis:

 Enter path to custom genesis: <genesisPath>

Provide the source code repo url:

 Source code repository URL: https://github.com/ava-labs/hypersdk/

Set the branch and finally set the build script:

 Build script: examples/morpheusvm/scripts/build.sh

CLI will generate a locally compiled binary, and then create the Avalanche L1.

Cloning into ...
 
Successfully created subnet configuration

Deploy Avalanche L1

For this example, we will deploy the Avalanche L1 and blockchain on Fuji. Run:

avalanche blockchain deploy <blockchainName>

Choose Fuji:

Use the arrow keys to navigate:
? Choose a network to deploy on:
    Local Network
 Fuji
    Mainnet

Use the stored key:

Use the arrow keys to navigate:
? Which key source should be used to pay transaction fees?:
 Use stored key
    Use ledger

Choose <keyName> as the key to use to pay the fees:

Use the arrow keys to navigate:
? Which stored key should be used to pay transaction fees?:
 <keyName>

Use the same key as the control key for the Avalanche L1:

Use the arrow keys to navigate:
? How would you like to set your control keys?:
 Use fee-paying key
    Use all stored keys
    Custom list

The successfully creation of our Avalanche L1 and blockchain is confirmed by the following output:

Your Subnet's control keys: [P-fuji1dlwux652lkflgz79g3nsphjzvl6t35xhmunfk1]
Your subnet auth keys for chain creation: [P-fuji1dlwux652lkflgz79g3nsphjzvl6t35xhmunfk1]
Subnet has been created with ID: RU72cWmBmcXber6ZBPT7R5scFFuVSoFRudcS3vayf3L535ZE3
Now creating blockchain...
+--------------------+----------------------------------------------------+
| DEPLOYMENT RESULTS |                                                    |
+--------------------+----------------------------------------------------+
| Chain Name         | blockchainName                                     |
+--------------------+----------------------------------------------------+
| Subnet ID          | RU72cWmBmcXber6ZBPT7R5scFFuVSoFRudcS3vayf3L535ZE3  |
+--------------------+----------------------------------------------------+
| VM ID              | srEXiWaHq58RK6uZMmUNaMF2FzG7vPzREsiXsptAHk9gsZNvN  |
+--------------------+----------------------------------------------------+
| Blockchain ID      | 2aDgZRYcSBsNoLCsC8qQH6iw3kUSF5DbRHM4sGEqVKwMSfBDRf |
+--------------------+                                                    +
| P-Chain TXID       |                                                    |
+--------------------+----------------------------------------------------+

Set the Config Files

Avalanche-CLI supports uploading the full set of configuration files for a blockchain:

  • Genesis File
  • Blockchain Config
  • Avalanche L1 Config
  • Network Upgrades
  • AvalancheGo Config

The following example uses all of them, but the user can decide to provide a subset of those.

AvalancheGo Flags

Save the following content (as defined here) into a file with path <avagoFlagsPath> (for example ~/morpheusvm_avago.json):

{
  "log-level":"INFO",
  "log-display-level":"INFO",
  "proposervm-use-current-height":true,
  "throttler-inbound-validator-alloc-size":"10737418240",
  "throttler-inbound-at-large-alloc-size":"10737418240",
  "throttler-inbound-node-max-processing-msgs":"1000000",
  "throttler-inbound-node-max-at-large-bytes":"10737418240",
  "throttler-inbound-bandwidth-refill-rate":"1073741824",
  "throttler-inbound-bandwidth-max-burst-size":"1073741824",
  "throttler-inbound-cpu-validator-alloc":"100000",
  "throttler-inbound-cpu-max-non-validator-usage":"100000",
  "throttler-inbound-cpu-max-non-validator-node-usage":"100000",
  "throttler-inbound-disk-validator-alloc":"10737418240000",
  "throttler-outbound-validator-alloc-size":"10737418240",
  "throttler-outbound-at-large-alloc-size":"10737418240",
  "throttler-outbound-node-max-at-large-bytes":"10737418240",
  "consensus-on-accept-gossip-validator-size":"10",
  "consensus-on-accept-gossip-peer-size":"10",
  "network-compression-type":"zstd",
  "consensus-app-concurrency":"128",
  "profile-continuous-enabled":true,
  "profile-continuous-freq":"1m",
  "http-host":"",
  "http-allowed-origins": "*",
  "http-allowed-hosts": "*"
}

Then set the Avalanche L1 to use it by executing:

avalanche blockchain configure blockchainName

Select node-config.json:

Use the arrow keys to navigate:
? Which configuration file would you like to provide?:
 node-config.json
    chain.json
    subnet.json
    per-node-chain.json

Provide the path to the AvalancheGo config file:

 Enter the path to your configuration file: <avagoFlagsPath>

Finally, choose no:

Use the arrow keys to navigate:
? Would you like to provide the chain.json file as well?:
 No
    Yes
File ~/.avalanche-cli/subnets/blockchainName/node-config.json successfully written

Blockchain Config

morpheus-cli as shown here. Save the following content (generated by this script) in a known file path (for example ~/morpheusvm_chain.json):

{
  "chunkBuildFrequency": 250,
  "targetChunkBuildDuration": 250,
  "blockBuildFrequency": 100,
  "mempoolSize": 2147483648,
  "mempoolSponsorSize": 10000000,
  "authExecutionCores": 16,
  "precheckCores": 16,
  "actionExecutionCores": 8,
  "missingChunkFetchers": 48,
  "verifyAuth": true,
  "authRPCCores": 48,
  "authRPCBacklog": 10000000,
  "authGossipCores": 16,
  "authGossipBacklog": 10000000,
  "chunkStorageCores": 16,
  "chunkStorageBacklog": 10000000,
  "streamingBacklogSize": 10000000,
  "continuousProfilerDir":"/home/ubuntu/morpheusvm-profiles",
  "logLevel": "INFO"
}

Then set the Avalanche L1 to use it by executing:

avalanche blockchain configure blockchainName

Select chain.json:

Use the arrow keys to navigate:
? Which configuration file would you like to provide?:
    node-config.json
 chain.json
    subnet.json
    per-node-chain.json

Provide the path to the blockchain config file:

 Enter the path to your configuration file: ~/morpheusvm_chain.json

Finally choose no:

Use the arrow keys to navigate:
? Would you like to provide the subnet.json file as well?:
 No
    Yes
File ~/.avalanche-cli/subnets/blockchainName/chain.json successfully written

Avalanche L1 Config

Save the following content (generated by this script) in a known path (for example ~/morpheusvm_subnet.json):

{
  "proposerMinBlockDelay": 0,
  "proposerNumHistoricalBlocks": 512
}

Then set the Avalanche L1 to use it by executing:

avalanche blockchain configure blockchainName

Select subnet.json:

Use the arrow keys to navigate:
? Which configuration file would you like to provide?:
    node-config.json
    chain.json
 subnet.json
    per-node-chain.json

Provide the path to the Avalanche L1 config file:

 Enter the path to your configuration file: ~/morpheusvm_subnet.json

Choose no:

Use the arrow keys to navigate:
? Would you like to provide the chain.json file as well?:
 No
    Yes
File ~/.avalanche-cli/subnets/blockchainName/subnet.json successfully written

Network Upgrades

Save the following content (currently with no network upgrades) in a known path (for example ~/morpheusvm_upgrades.json):

Then set the Avalanche L1 to use it by executing:

avalanche blockchain upgrade import blockchainName

Provide the path to the network upgrades file:

 Provide the path to the upgrade file to import: ~/morpheusvm_upgrades.json

Deploy Our Custom VM

To deploy our Custom VM, run:

avalanche node sync <clusterName> <blockchainName>
Node(s) successfully started syncing with Subnet!

Your custom VM is successfully deployed!

You can also use avalanche node update blockchain <blockchainName> to reinstall the binary when the branch is updated, or update the config files.

Last updated on

On this page

Edit on Github