Skip to content

Commit

Permalink
deploy subnet
Browse files Browse the repository at this point in the history
  • Loading branch information
sukantoraymond committed May 22, 2024
1 parent 3662d67 commit 8fd699c
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 1 deletion.
28 changes: 28 additions & 0 deletions avalanche/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package avalanche

import "github.com/ava-labs/avalanchego/utils/logging"

type Avalanche struct {
Log logging.Logger
//baseDir string
//Conf *config.Config
//Prompt prompts.Prompter
//Apm *apm.APM
//ApmDir string
//Downloader Downloader
}

func New() *Avalanche {
return &Avalanche{}
}

func (app *Avalanche) Setup(log logging.Logger) {
//app.baseDir = baseDir
app.Log = log
//app.Conf = conf
//app.Prompt = prompt
//app.Downloader = downloader
}
8 changes: 8 additions & 0 deletions avalanche/avalanche.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package avalanche

const (
SubnetEVMRepoName = "subnet-evm"
)
18 changes: 18 additions & 0 deletions avalanche/keychain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package avalanche

import "github.com/ava-labs/avalanchego/utils/crypto/keychain"

type Keychain struct {
Network Network

Keychain keychain.Keychain

Ledger keychain.Ledger

UsesLedger bool

LedgerIndices []uint32
}
24 changes: 24 additions & 0 deletions avalanche/network.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package avalanche

type NetworkKind int64

const (
Undefined NetworkKind = iota
Mainnet
Fuji
LocalNetwork
Devnet
)

type Network struct {
Kind NetworkKind

ID uint32

Endpoint string

ClusterName string
}
29 changes: 29 additions & 0 deletions avalanche/vm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package avalanche

type VMType string

const (
SubnetEvm = "Subnet-EVM"
CustomVM = "Custom"
)

func VMTypeFromString(s string) VMType {
switch s {
case SubnetEvm:
return SubnetEvm
default:
return CustomVM
}
}

func (v VMType) RepoName() string {
switch v {
case SubnetEvm:
return SubnetEVMRepoName
default:
return "unknown"
}
}
116 changes: 116 additions & 0 deletions subnet/deploy_subnet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package subnet

import (
"avalanche-tooling-sdk-go/avalanche"
"avalanche-tooling-sdk-go/utils"
"context"
"fmt"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/crypto/keychain"
"github.com/ava-labs/avalanchego/utils/formatting/address"
"github.com/ava-labs/avalanchego/utils/set"
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
"github.com/ava-labs/avalanchego/wallet/subnet/primary"
"github.com/ava-labs/avalanchego/wallet/subnet/primary/common"
)

// createSubnetTx creates uncommitted createSubnet transaction
func createSubnetTx(subnet Subnet, wallet primary.Wallet) (*txs.Tx, error) {
addrs, err := address.ParseToIDs(subnet.ControlKeys)
if err != nil {
return nil, fmt.Errorf("failure parsing control keys: %w", err)
}
owners := &secp256k1fx.OutputOwners{
Addrs: addrs,
Threshold: subnet.Threshold,
Locktime: 0,
}
unsignedTx, err := wallet.P().Builder().NewCreateSubnetTx(
owners,
)
if err != nil {
return nil, fmt.Errorf("error building tx: %w", err)
}
tx := txs.Tx{Unsigned: unsignedTx}
if err := wallet.P().Signer().Sign(context.Background(), &tx); err != nil {
return nil, fmt.Errorf("error signing tx: %w", err)
}
return &tx, nil
}

// createBlockchainTx creates uncommitted createBlockchain transaction
func createBlockchainTx(subnet Subnet, wallet primary.Wallet, network avalanche.Network, keyChain avalanche.Keychain) (*txs.Tx, error) {
wallet, err := loadCacheWallet(network, keyChain, wallet, subnet.SubnetID, subnet.TransferSubnetOwnershipTxID)
if err != nil {
return nil, err
}
fxIDs := make([]ids.ID, 0)
options := getMultisigTxOptions(keyChain.Keychain, subnet.SubnetAuthKeys)
// create tx
unsignedTx, err := wallet.P().Builder().NewCreateChainTx(
subnet.SubnetID,
subnet.Genesis,
subnet.VMID,
fxIDs,
subnet.Name,
options...,
)
if err != nil {
return nil, fmt.Errorf("error building tx: %w", err)
}
tx := txs.Tx{Unsigned: unsignedTx}
// sign with current wallet
if err := wallet.P().Signer().Sign(context.Background(), &tx); err != nil {
return nil, fmt.Errorf("error signing tx: %w", err)
}
return &tx, nil
}

func getMultisigTxOptions(keychain keychain.Keychain, subnetAuthKeys []ids.ShortID) []common.Option {
options := []common.Option{}
walletAddrs := keychain.Addresses().List()
changeAddr := walletAddrs[0]
// addrs to use for signing
customAddrsSet := set.Set[ids.ShortID]{}
customAddrsSet.Add(walletAddrs...)
customAddrsSet.Add(subnetAuthKeys...)
options = append(options, common.WithCustomAddresses(customAddrsSet))
// set change to go to wallet addr (instead of any other subnet auth key)
changeOwner := &secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{changeAddr},
}
options = append(options, common.WithChangeOwner(changeOwner))
return options
}

func loadCacheWallet(network avalanche.Network, keyChain avalanche.Keychain, wallet primary.Wallet, preloadTxs ...ids.ID) (primary.Wallet, error) {
var err error
if wallet == nil {
wallet, err = loadWallet(network, keyChain, preloadTxs...)
}
return wallet, err
}

func loadWallet(network avalanche.Network, keyChain avalanche.Keychain, preloadTxs ...ids.ID) (primary.Wallet, error) {
ctx := context.Background()
// filter out ids.Empty txs
filteredTxs := utils.Filter(preloadTxs, func(e ids.ID) bool { return e != ids.Empty })
wallet, err := primary.MakeWallet(
ctx,
&primary.WalletConfig{
URI: network.Endpoint,
AVAXKeychain: keyChain.Keychain,
EthKeychain: secp256k1fx.NewKeychain(),
PChainTxsToFetch: set.Of(filteredTxs...),
},
)
if err != nil {
return nil, err
}
return wallet, nil
}
12 changes: 11 additions & 1 deletion subnet/subnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type SubnetParams struct {
// Custom VM parameters to use
// Do not set CustomVM value if you are using Subnet-EVM
CustomVM CustomVMParams

Name string
}

type SubnetEVMParams struct {
Expand Down Expand Up @@ -86,11 +88,13 @@ type CustomVMParams struct {
}

type Subnet struct {
Name string

Genesis []byte

ControlKeys []string

SubnetAuthKeys []string
SubnetAuthKeys []ids.ShortID

SubnetID ids.ID

Expand All @@ -101,4 +105,10 @@ type Subnet struct {
Threshold uint32

VMID ids.ID

RPCVersion int

TokenName string

TokenSymbol string
}
13 changes: 13 additions & 0 deletions utils/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package utils

func Filter[T any](input []T, f func(T) bool) []T {
output := make([]T, 0, len(input))
for _, e := range input {
if f(e) {
output = append(output, e)
}
}
return output
}

0 comments on commit 8fd699c

Please sign in to comment.