Skip to content

Commit

Permalink
Merge pull request #7 from ava-labs/deploy-subnet
Browse files Browse the repository at this point in the history
Deploy subnet
  • Loading branch information
sukantoraymond authored May 23, 2024
2 parents 3662d67 + b86a667 commit b8ffeeb
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 1 deletion.
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
}
14 changes: 14 additions & 0 deletions avalanche/network.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package avalanche

type NetworkKind int64

type Network struct {
Kind NetworkKind

ID uint32

Endpoint 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"
}
}
82 changes: 82 additions & 0 deletions multisig/multisig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (C) 2022, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package multisig

import (
"github.com/ava-labs/avalanche-tooling-sdk-go/network"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
"github.com/ava-labs/avalanchego/wallet/subnet/primary"
)

type PChainTxKind int

const (
Invalid = iota
CreateBlockchain
TransferSubnetOwnership
)

type PChainMultisig struct {
_ *txs.Tx
}

func New(_ *txs.Tx) *PChainMultisig {
return nil
}

func (*PChainMultisig) ToBytes() ([]byte, error) {
return nil, nil
}

func (*PChainMultisig) FromBytes(_ []byte) error {
return nil
}

func (*PChainMultisig) ToFile(_ string) error {
return nil
}

func (*PChainMultisig) FromFile(_ string) error {
return nil
}

func (*PChainMultisig) Sign(_ *primary.Wallet) error {
return nil
}

func (*PChainMultisig) Commit() error {
return nil
}

func (*PChainMultisig) IsReadyToCommit() error {
return nil
}

func (*PChainMultisig) GetRemainingSigners() ([]ids.ID, error) {
return nil, nil
}

func (*PChainMultisig) GetAuthSigners() ([]ids.ID, error) {
return nil, nil
}

func (*PChainMultisig) GetFeeSigners() ([]ids.ID, error) {
return nil, nil
}

func (*PChainMultisig) GetKind() PChainTxKind {
return Invalid
}

func (*PChainMultisig) GetNetwork() (network.Network, error) {
return nil, nil
}

func (*PChainMultisig) GetSubnetID() (ids.ID, error) {
return ids.Empty, nil
}

func (*PChainMultisig) GetSubnetOwners() ([]ids.ID, int, error) {
return nil, 0, nil
}
86 changes: 86 additions & 0 deletions subnet/deploy_subnet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package subnet

import (
"context"
"fmt"

"avalanche-tooling-sdk-go/avalanche"

"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, keyChain avalanche.Keychain) (*txs.Tx, error) {
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
}
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 b8ffeeb

Please sign in to comment.