Skip to content

Commit

Permalink
add poa setup to blockchain deploy (#2219)
Browse files Browse the repository at this point in the history
* add setup poa to blockchain deploy

* add command

* add proposervm update

* proposervm flag for nodes

* nit

* nit

* fixed dynamic fees params calculation

* only adding tracked apis to apis in sidecar

* improve prompts

* fixing various stuff

* add upgrade file

* use anr etna enabled

* keep upgrade on sync

* workin

* almost working

* working1

* Update cmd/keycmd/transfer.go

Co-authored-by: Meaghan FitzGerald <meag.fitz@avalabs.org>
Signed-off-by: felipemadero <felipe.madero@gmail.com>

* fix some lint

* address PR comments

* missing file

* nit

---------

Signed-off-by: felipemadero <felipe.madero@gmail.com>
Signed-off-by: sukantoraymond <rsukanto@umich.edu>
Co-authored-by: Meaghan FitzGerald <meag.fitz@avalabs.org>
Co-authored-by: sukantoraymond <rsukanto@umich.edu>
  • Loading branch information
3 people authored Oct 8, 2024
1 parent ae81087 commit 971693f
Show file tree
Hide file tree
Showing 36 changed files with 791 additions and 115 deletions.
105 changes: 102 additions & 3 deletions cmd/blockchaincmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/ava-labs/avalanchego/vms/platformvm/warp/message"
"github.com/ethereum/go-ethereum/common"

"github.com/ava-labs/avalanche-cli/pkg/contract"
"github.com/ava-labs/avalanche-cli/pkg/utils"
"github.com/ava-labs/avalanchego/utils/formatting/address"
"github.com/ava-labs/avalanchego/vms/platformvm/fx"
Expand All @@ -29,6 +32,7 @@ import (
"github.com/ava-labs/avalanche-cli/pkg/subnet"
"github.com/ava-labs/avalanche-cli/pkg/txutils"
"github.com/ava-labs/avalanche-cli/pkg/ux"
"github.com/ava-labs/avalanche-cli/pkg/validatormanager"
"github.com/ava-labs/avalanche-cli/pkg/vm"
anrutils "github.com/ava-labs/avalanche-network-runner/utils"
"github.com/ava-labs/avalanchego/ids"
Expand Down Expand Up @@ -67,6 +71,7 @@ var (
icmSpec subnet.ICMSpec
generateNodeID bool
bootstrapValidatorsJSONFilePath string
privateKeyFlags contract.PrivateKeyFlags

errMutuallyExlusiveControlKeys = errors.New("--control-keys and --same-control-key are mutually exclusive")
ErrMutuallyExlusiveKeyLedger = errors.New("key source flags --key, --ledger/--ledger-addrs are mutually exclusive")
Expand Down Expand Up @@ -94,6 +99,8 @@ so you can take your locally tested Subnet and deploy it on Fuji or Mainnet.`,
Args: cobrautils.ExactArgs(1),
}
networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, true, deploySupportedNetworkOptions)
privateKeyFlags.SetFlagNames("blockchain-private-key", "blockchain-key", "blockchain-genesis-key")
privateKeyFlags.AddToCmd(cmd, "to fund validator manager initialization")
cmd.Flags().StringVar(&userProvidedAvagoVersion, "avalanchego-version", "latest", "use this version of avalanchego (ex: v1.17.12)")
cmd.Flags().StringVarP(&keyName, "key", "k", "", "select the key to use [fuji/devnet deploy only]")
cmd.Flags().BoolVarP(&sameControlKey, "same-control-key", "s", false, "use the fee-paying key as control key")
Expand Down Expand Up @@ -559,6 +566,7 @@ func deployBlockchain(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
deployer.CleanCacheWallet()
// get the control keys in the same order as the tx
_, controlKeys, threshold, err = txutils.GetOwners(network, subnetID)
if err != nil {
Expand Down Expand Up @@ -610,21 +618,25 @@ func deployBlockchain(cmd *cobra.Command, args []string) error {
}

if sidecar.Sovereign {
avaGoBootstrapValidators, err := convertToAvalancheGoSubnetValidator(bootstrapValidators)
avaGoBootstrapValidators, err := ConvertToAvalancheGoSubnetValidator(bootstrapValidators)
if err != nil {
return err
}
deployer.CleanCacheWallet()
managerAddress := common.HexToAddress(validatormanager.ValidatorContractAddress)
isFullySigned, ConvertL1TxID, tx, remainingSubnetAuthKeys, err := deployer.ConvertL1(
controlKeys,
subnetAuthKeys,
subnetID,
blockchainID,
managerAddress,
avaGoBootstrapValidators,
)
if err != nil {
ux.Logger.PrintToUser(logging.Red.Wrap(
fmt.Sprintf("error converting blockchain: %s. fix the issue and try again with a new convert cmd", err),
))
return err
}

savePartialTx = !isFullySigned && err == nil
Expand All @@ -643,6 +655,93 @@ func deployBlockchain(cmd *cobra.Command, args []string) error {
return err
}
}

bar, err := ux.TimedProgressBar(
30*time.Second,
"Waiting for Blockchain to be converted into Subnet Only Validator (SOV) Blockchain ...",
2,
)
if err != nil {
return err
}

// Issue random transaction >30s after ConverSubnetTx to evict its block from the block map
_, _, err = deployer.PChainTransfer(kc.Addresses().List()[0], 1)
if err != nil {
return err
}
if err := ux.ExtraStepExecuted(bar); err != nil {
return err
}
// Issue random transaction to advance the p-chain height now that the
// ConvertSubnetTx block isn't in the block map
_, _, err = deployer.PChainTransfer(kc.Addresses().List()[0], 1)
if err != nil {
return err
}
if err := ux.ExtraStepExecuted(bar); err != nil {
return err
}
fmt.Println()

if err := app.UpdateSidecarNetworks(&sidecar, network, subnetID, blockchainID, "", "", bootstrapValidators); err != nil {
return err
}

if false {
chainSpec := contract.ChainSpec{
BlockchainName: blockchainName,
}
genesisAddress, genesisPrivateKey, err := contract.GetEVMSubnetPrefundedKey(
app,
network,
chainSpec,
)
if err != nil {
return err
}
privateKey, err := privateKeyFlags.GetPrivateKey(app, genesisPrivateKey)
if err != nil {
return err
}
if privateKey == "" {
privateKey, err = prompts.PromptPrivateKey(
app.Prompt,
"Which key to you want to use to pay for initializing Validator Manager contract? (Uses Blockchain gas token)",
app.GetKeyDir(),
app.GetKey,
genesisAddress,
genesisPrivateKey,
)
if err != nil {
return err
}
}
rpcURL, _, err := contract.GetBlockchainEndpoints(
app,
network,
chainSpec,
true,
false,
)
if err != nil {
return err
}
if err := validatormanager.SetupPoA(
app,
network,
rpcURL,
contract.ChainSpec{
BlockchainName: blockchainName,
},
privateKey,
common.HexToAddress(sidecar.PoAValidatorManagerOwner),
avaGoBootstrapValidators,
); err != nil {
return err
}
ux.Logger.GreenCheckmarkToUser("Subnet is successfully converted into Subnet Only Validator")
}
}

flags := make(map[string]string)
Expand All @@ -651,7 +750,7 @@ func deployBlockchain(cmd *cobra.Command, args []string) error {

// update sidecar
// TODO: need to do something for backwards compatibility?
return app.UpdateSidecarNetworks(&sidecar, network, subnetID, blockchainID, "", "", bootstrapValidators)
return nil
}

func getBLSInfo(publicKey, proofOfPossesion string) (signer.ProofOfPossession, error) {
Expand All @@ -676,7 +775,7 @@ func getBLSInfo(publicKey, proofOfPossesion string) (signer.ProofOfPossession, e
}

// TODO: add deactivation owner?
func convertToAvalancheGoSubnetValidator(subnetValidators []models.SubnetValidator) ([]*txs.ConvertSubnetValidator, error) {
func ConvertToAvalancheGoSubnetValidator(subnetValidators []models.SubnetValidator) ([]*txs.ConvertSubnetValidator, error) {
bootstrapValidators := []*txs.ConvertSubnetValidator{}
for _, validator := range subnetValidators {
nodeID, err := ids.NodeIDFromString(validator.NodeID)
Expand Down
13 changes: 13 additions & 0 deletions cmd/blockchaincmd/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,19 @@ func PrintSubnetInfo(blockchainName string, onlyLocalnetInfo bool) error {
t.AppendRow(table.Row{net, "BlockchainID (CB58)", data.BlockchainID.String()})
t.AppendRow(table.Row{net, "BlockchainID (HEX)", hexEncoding})
}
endpoint, _, err := contract.GetBlockchainEndpoints(
app,
network,
contract.ChainSpec{
BlockchainName: sc.Name,
},
false,
false,
)
if err != nil {
return err
}
t.AppendRow(table.Row{net, "RPC Endpoint", endpoint})
}
ux.Logger.PrintToUser(t.Render())

Expand Down
1 change: 1 addition & 0 deletions cmd/blockchaincmd/prompt_genesis_input.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func promptBootstrapValidators(network models.Network) ([]models.SubnetValidator
var subnetValidators []models.SubnetValidator
numBootstrapValidators, err := app.Prompt.CaptureInt(
"How many bootstrap validators do you want to set up?",
prompts.ValidatePositiveInt,
)
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion cmd/blockchaincmd/upgradecmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ func applyPublicNetworkUpgrade(blockchainName, networkKey string, sc *models.Sid

ux.Logger.PrintToUser("Trying to install the upgrade files at the provided %s path", avalanchegoChainConfigDir)
chainDir := filepath.Join(avalanchegoChainConfigDir, sc.Networks[networkKey].BlockchainID.String())
destPath := filepath.Join(chainDir, constants.UpgradeBytesFileName)
destPath := filepath.Join(chainDir, constants.UpgradeFileName)
if err = os.Mkdir(chainDir, constants.DefaultPerms755); err != nil && !os.IsExist(err) {
return fmt.Errorf("failed to create blockchain directory: %w", err)
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/contractcmd/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ and interacting with smart contracts.`,
app = injectedApp
// contract deploy
cmd.AddCommand(newDeployCmd())
// contract initpoamanager
cmd.AddCommand(newInitPOAManagerCmd())
return cmd
}
132 changes: 132 additions & 0 deletions cmd/contractcmd/init_poa_validator_manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright (C) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package contractcmd

import (
"fmt"

"github.com/ava-labs/avalanche-cli/cmd/blockchaincmd"
"github.com/ava-labs/avalanche-cli/pkg/cobrautils"
"github.com/ava-labs/avalanche-cli/pkg/contract"
"github.com/ava-labs/avalanche-cli/pkg/networkoptions"
"github.com/ava-labs/avalanche-cli/pkg/prompts"
"github.com/ava-labs/avalanche-cli/pkg/ux"
"github.com/ava-labs/avalanche-cli/pkg/validatormanager"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ethereum/go-ethereum/common"

"github.com/spf13/cobra"
)

type InitPOAManagerFlags struct {
Network networkoptions.NetworkFlags
PrivateKeyFlags contract.PrivateKeyFlags
rpcEndpoint string
}

var (
initPOAManagerSupportedNetworkOptions = []networkoptions.NetworkOption{
networkoptions.Local,
networkoptions.Devnet,
networkoptions.Fuji,
}
initPOAManagerFlags InitPOAManagerFlags
)

// avalanche contract initpoamanager
func newInitPOAManagerCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "initPoaManager",
Short: "Initializes a Proof of Authority Validator Manager on a given Network and Blockchain",
Long: "Initializes Proof of Authority Validator Manager contract on a Blockchain and sets up initial validator set on the Blockchain. For more info on Validator Manager, please head to https://github.com/ava-labs/teleporter/tree/staking-contract/contracts/validator-manager",
RunE: initPOAManager,
Args: cobrautils.ExactArgs(1),
}
networkoptions.AddNetworkFlagsToCmd(cmd, &initPOAManagerFlags.Network, true, initPOAManagerSupportedNetworkOptions)
initPOAManagerFlags.PrivateKeyFlags.AddToCmd(cmd, "as contract deployer")
cmd.Flags().StringVar(&initPOAManagerFlags.rpcEndpoint, "rpc", "", "deploy the contract into the given rpc endpoint")
return cmd
}

func initPOAManager(_ *cobra.Command, args []string) error {
blockchainName := args[0]
chainSpec := contract.ChainSpec{
BlockchainName: blockchainName,
}
network, err := networkoptions.GetNetworkFromCmdLineFlags(
app,
"",
initPOAManagerFlags.Network,
true,
false,
initPOAManagerSupportedNetworkOptions,
"",
)
if err != nil {
return err
}
if initPOAManagerFlags.rpcEndpoint == "" {
initPOAManagerFlags.rpcEndpoint, _, err = contract.GetBlockchainEndpoints(
app,
network,
chainSpec,
true,
false,
)
if err != nil {
return err
}
}
ux.Logger.PrintToUser(logging.Yellow.Wrap("RPC Endpoint: %s"), initPOAManagerFlags.rpcEndpoint)
genesisAddress, genesisPrivateKey, err := contract.GetEVMSubnetPrefundedKey(
app,
network,
chainSpec,
)
if err != nil {
return err
}
privateKey, err := initPOAManagerFlags.PrivateKeyFlags.GetPrivateKey(app, genesisPrivateKey)
if err != nil {
return err
}
if privateKey == "" {
privateKey, err = prompts.PromptPrivateKey(
app.Prompt,
"Which key to you want to use to pay for initializing Proof of Authority Validator Manager contract? (Uses Blockchain gas token)",
app.GetKeyDir(),
app.GetKey,
genesisAddress,
genesisPrivateKey,
)
if err != nil {
return err
}
}
sc, err := app.LoadSidecar(chainSpec.BlockchainName)
if err != nil {
return fmt.Errorf("failed to load sidecar: %w", err)
}
if sc.Networks[network.Name()].BlockchainID == ids.Empty {
return fmt.Errorf("blockchain has not been deployed to %s", network.Name())
}
bootstrapValidators := sc.Networks[network.Name()].BootstrapValidators
avaGoBootstrapValidators, err := blockchaincmd.ConvertToAvalancheGoSubnetValidator(bootstrapValidators)
if err != nil {
return err
}
if err := validatormanager.SetupPoA(
app,
network,
initPOAManagerFlags.rpcEndpoint,
chainSpec,
privateKey,
common.HexToAddress(sc.PoAValidatorManagerOwner),
avaGoBootstrapValidators,
); err != nil {
return err
}
ux.Logger.GreenCheckmarkToUser("Proof of Authority Validator Manager contract successfully initialized on blockchain %s", blockchainName)
return nil
}
Loading

0 comments on commit 971693f

Please sign in to comment.