Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node local PoC #2216

Merged
merged 46 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
bc89a4d
node local init
arturrez Oct 2, 2024
37da482
hardcode etna devnet config
arturrez Oct 2, 2024
9459b43
wip
arturrez Oct 3, 2024
3ddc12c
rm not needed utils
arturrez Oct 3, 2024
34f9382
Merge branch 'acp-77' into node-create-local
arturrez Oct 3, 2024
035cb92
ready for draft PR
arturrez Oct 3, 2024
3b1e676
nits
arturrez Oct 3, 2024
495d59c
refactor - wip
arturrez Oct 4, 2024
1d52dd5
make sure we can resume without prompts
arturrez Oct 5, 2024
1c1d061
add custom network and local cluster
arturrez Oct 5, 2024
ac37dce
devnet instead of custom network, rm custom
arturrez Oct 5, 2024
9acca2e
Merge branch 'acp-77' into node-create-local
arturrez Oct 8, 2024
64ba256
go mod tidy
arturrez Oct 8, 2024
71e313b
upgrade.json for etna devnet
arturrez Oct 8, 2024
884043e
more local cluster
arturrez Oct 9, 2024
74b9a7c
separate between local network and local cluster
felipemadero Oct 10, 2024
dce0e98
Merge branch 'acp-77' into node-create-local
felipemadero Oct 10, 2024
23b4e86
working
felipemadero Oct 10, 2024
b8f20ca
nit
felipemadero Oct 10, 2024
e225ed5
fix plugin
felipemadero Oct 10, 2024
7a12d78
nit
felipemadero Oct 10, 2024
93a3cfe
improve snapshot management
felipemadero Oct 10, 2024
c617154
fix bug
felipemadero Oct 10, 2024
c6ed553
nit
felipemadero Oct 10, 2024
afb44a1
proper etna devnet boostrappers
arturrez Oct 10, 2024
f2653d8
fix bug with local rootdir
arturrez Oct 11, 2024
3b3d699
remove global node config stuff
felipemadero Oct 11, 2024
3b4cdfe
destroy node data and processes if bad start
felipemadero Oct 11, 2024
61eb94d
nit
felipemadero Oct 11, 2024
46fa068
always use fresh staking keys
felipemadero Oct 11, 2024
ac2bdc3
nit
felipemadero Oct 11, 2024
ea9d1b9
so less flags
felipemadero Oct 11, 2024
02f02ab
add back fast boot time
felipemadero Oct 11, 2024
c788f4a
Merge branch 'node-create-local-fix' into node-create-local
felipemadero Oct 11, 2024
27ecc41
add checks for local cluster. minor refactor (#2239)
arturrez Oct 12, 2024
046ccb6
bump anr
felipemadero Oct 12, 2024
f134935
fixes for convert flow
felipemadero Oct 12, 2024
719aea1
add check for already initialized error on PoA init
felipemadero Oct 13, 2024
2aa05d1
nit
felipemadero Oct 13, 2024
72c1464
use anr main
felipemadero Oct 14, 2024
f22c1fd
Merge branch 'acp-77' into node-create-local
sukantoraymond Oct 15, 2024
c44c41b
fix merge
sukantoraymond Oct 15, 2024
de1a9f5
Local mkdir rootdir (#2245)
arturrez Oct 15, 2024
05c5218
update anr
sukantoraymond Oct 15, 2024
7d483ba
Merge branch 'acp-77' into node-create-local
sukantoraymond Oct 16, 2024
6ff16d8
Integrate local devnet (#2254)
sukantoraymond Oct 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions cmd/backendcmd/spawn_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,35 @@ import (
"github.com/spf13/cobra"
)

var app *application.Avalanche
var (
app *application.Avalanche
serverPort string
gatewayPort string
snapshotsDir string
)

// backendCmd is the command to run the backend gRPC process
func NewCmd(injectedApp *application.Avalanche) *cobra.Command {
app = injectedApp
return &cobra.Command{
cmd := &cobra.Command{
Use: constants.BackendCmd,
Short: "Run the backend server",
Long: "This tool requires a backend process to run; this command starts it",
RunE: startBackend,
Args: cobrautils.ExactArgs(0),
Hidden: true,
}
cmd.Flags().StringVar(&serverPort, "server-port", binutils.LocalNetworkGRPCServerPort, "server port to use")
cmd.Flags().StringVar(&gatewayPort, "gateway-port", binutils.LocalNetworkGRPCGatewayPort, "gateway port to use")
cmd.Flags().StringVar(&snapshotsDir, "snapshots-dir", "", "snapshots dir to use")
return cmd
}

func startBackend(_ *cobra.Command, _ []string) error {
s, err := binutils.NewGRPCServer(app.GetSnapshotsDir())
if snapshotsDir == "" {
snapshotsDir = app.GetSnapshotsDir()
}
s, err := binutils.NewGRPCServer(serverPort, gatewayPort, snapshotsDir)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/blockchaincmd/add_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
func CallAddValidator(
deployer *subnet.PublicDeployer,
network models.Network,
kc *keychain.Keychain,

Check warning on line 148 in cmd/blockchaincmd/add_validator.go

View workflow job for this annotation

GitHub Actions / Lint

unused-parameter: parameter 'kc' seems to be unused, consider removing or renaming it as _ (revive)
useLedgerSetting bool,
blockchainName string,
nodeIDStrFormat string,
Expand Down Expand Up @@ -192,7 +192,7 @@
}

// TODO: implement getting validator manager controller address
//kcKeys, err := kc.PChainFormattedStrAddresses()

Check failure on line 195 in cmd/blockchaincmd/add_validator.go

View workflow job for this annotation

GitHub Actions / Lint

commentFormatting: put a space between `//` and comment text (gocritic)
//if err != nil {
// return err
//}
Expand All @@ -218,7 +218,7 @@
}

if changeAddr == "" {
changeAddr, err = getKeyForChangeOwner("", network)
changeAddr, err = getKeyForChangeOwner(nodeIDStrFormat, "", network)
if err != nil {
return err
}
Expand Down Expand Up @@ -261,7 +261,7 @@
return nil
}

func generateWarpMessageAddValidator(subnetID ids.ID, nodeID ids.NodeID, weight uint64, blsPublicKey string, expiry uint64) (warpPlatformVM.Message, error) {

Check warning on line 264 in cmd/blockchaincmd/add_validator.go

View workflow job for this annotation

GitHub Actions / Lint

unused-parameter: parameter 'subnetID' seems to be unused, consider removing or renaming it as _ (revive)
return warpPlatformVM.Message{}, nil
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/blockchaincmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ configuration, pass the -f flag.`,
cmd.Flags().BoolVar(&createFlags.proofOfStake, "proof-of-stake", false, "(coming soon) use proof of stake for validator management")
cmd.Flags().StringVar(&createFlags.poaValidatorManagerOwner, "poa-manager-owner", "", "EVM address that controls Validator Manager Owner (for Proof of Authority only)")
cmd.Flags().BoolVar(&sovereign, "sovereign", true, "set to false if creating non-sovereign blockchain")
cmd.Flags().BoolVar(&createFlags.enableDebugging, "debug", false, "enable blockchain debugging")
cmd.Flags().BoolVar(&createFlags.enableDebugging, "debug", true, "enable blockchain debugging")
return cmd
}

Expand Down
191 changes: 167 additions & 24 deletions cmd/blockchaincmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
package blockchaincmd

import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"github.com/ava-labs/avalanchego/api/info"
"os"
"path/filepath"
"strings"
"time"

"github.com/ava-labs/avalanche-cli/pkg/node"
"github.com/ava-labs/avalanche-cli/pkg/evm"

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

Expand Down Expand Up @@ -49,6 +52,7 @@
var deploySupportedNetworkOptions = []networkoptions.NetworkOption{
networkoptions.Local,
networkoptions.Devnet,
networkoptions.EtnaDevnet,
networkoptions.Fuji,
networkoptions.Mainnet,
}
Expand All @@ -62,6 +66,8 @@
userProvidedAvagoVersion string
outputTxPath string
useLedger bool
useLocalMachine bool
localMachineCluster string
useEwoq bool
ledgerAddresses []string
sovereign bool
Expand All @@ -74,6 +80,7 @@
generateNodeID bool
bootstrapValidatorsJSONFilePath string
privateKeyFlags contract.PrivateKeyFlags
bootstrapEndpoints []string

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 @@ -128,6 +135,9 @@
cmd.Flags().StringVar(&icmSpec.RegistryBydecodePath, "teleporter-registry-bytecode-path", "", "path to an interchain messenger registry bytecode file")
cmd.Flags().StringVar(&bootstrapValidatorsJSONFilePath, "bootstrap-filepath", "", "JSON file path that provides details about bootstrap validators, leave Node-ID and BLS values empty if using --generate-node-id=true")
cmd.Flags().BoolVar(&generateNodeID, "generate-node-id", false, "whether to create new node id for bootstrap validators (Node-ID and BLS values in bootstrap JSON file will be overridden if --bootstrap-filepath flag is used)")
cmd.Flags().StringSliceVar(&bootstrapEndpoints, "bootstrap-enu dpoints", nil, "take validator node info from the given endpoints")
cmd.Flags().BoolVar(&useLocalMachine, "use-local-machine", false, "use local machine as a blockchain validator")
cmd.Flags().StringVar(&localMachineCluster, "local-machine-cluster", "", "existing local machine to be used as a blockchain validator")
return cmd
}

Expand Down Expand Up @@ -394,13 +404,6 @@
}
}

if sidecar.Sovereign && bootstrapValidatorsJSONFilePath == "" {
bootstrapValidators, err = promptBootstrapValidators(network)
if err != nil {
return err
}
}

ux.Logger.PrintToUser("Deploying %s to %s", chains, network.Name())

if network.Kind == models.Local {
Expand Down Expand Up @@ -433,10 +436,20 @@
}

deployer := subnet.NewLocalDeployer(app, userProvidedAvagoVersion, avagoBinaryPath, vmBin)
deployInfo, err := deployer.DeployToLocalNetwork(chain, genesisPath, icmSpec, subnetIDStr)
deployInfo, err := deployer.DeployToLocalNetwork(
chain,
genesisPath,
icmSpec,
subnetIDStr,
constants.ServerRunFileLocalNetworkPrefix,
)
if err != nil {
if deployer.BackendStartedHere() {
if innerErr := binutils.KillgRPCServerProcess(app); innerErr != nil {
if innerErr := binutils.KillgRPCServerProcess(
app,
binutils.LocalNetworkGRPCServerEndpoint,
constants.ServerRunFileLocalNetworkPrefix,
); innerErr != nil {
app.Log.Warn("tried to kill the gRPC server process but it failed", zap.Error(innerErr))
}
}
Expand All @@ -452,13 +465,95 @@
deployInfo.BlockchainID,
deployInfo.ICMMessengerAddress,
deployInfo.ICMRegistryAddress,
bootstrapValidators,
nil,
); err != nil {
return err
}
return PrintSubnetInfo(blockchainName, true)
}

if sidecar.Sovereign {
if !useLocalMachine {
ux.Logger.PrintToUser("You can use your local machine as a bootstrap validator on the blockchain")
ux.Logger.PrintToUser("This means that you don't have to to set up a remote server on a cloud service (e.g. AWS / GCP) to be a validator on the blockchain.")

useLocalMachine, err = app.Prompt.CaptureYesNo("Do you want to use your local machine as a bootstrap validator?")
if err != nil {
return err
}
}
if useLocalMachine {
// stop any local avalanche go process running before we start local node
_ = node.StopLocalNode(app)
clusterName := fmt.Sprintf("%s-local-node", blockchainName)
if localMachineCluster != "" {
// don't destroy cluster if local cluster name is provided
clusterName = localMachineCluster
} else {

Check failure on line 492 in cmd/blockchaincmd/deploy.go

View workflow job for this annotation

GitHub Actions / Lint

elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic)
// destroy any cluster with same name before we start local node
// we don't want to reuse snapshots from previous sessions
if utils.DirectoryExists(app.GetLocalDir(clusterName)) {
_ = node.DestroyLocalNode(app, clusterName)
}
}
// TODO: replace bootstrapEndpoints with dynamic port number
bootstrapEndpoints = []string{"http://127.0.0.1:9650"}
anrSettings := node.ANRSettings{}
avagoVersionSettings := node.AvalancheGoVersionSettings{}
useEtnaDevnet := false
if network.Kind == models.EtnaDevnet {
useEtnaDevnet = true
}
if avagoBinaryPath == "" {
ux.Logger.PrintToUser("Local build of Avalanche Go is required to create an Avalanche node using local machine")
ux.Logger.PrintToUser("Please download Avalanche Go repo at https://github.com/ava-labs/avalanchego and build from source through ./scripts/build.sh")
ux.Logger.PrintToUser("Please provide the full path to Avalanche Go binary in the build directory (e.g, xxx/build/avalanchego)")
avagoBinaryPath, err = app.Prompt.CaptureString("Path to Avalanche Go build")
if err != nil {
return err
}
}
network = models.NewNetworkFromCluster(network, clusterName)
// anrSettings, avagoVersionSettings, globalNetworkFlags are empty
if err = node.StartLocalNode(app, clusterName, useEtnaDevnet, avagoBinaryPath, anrSettings, avagoVersionSettings, globalNetworkFlags, nil); err != nil {
return err
}
}

if len(bootstrapEndpoints) > 0 {
var changeAddr string
for _, endpoint := range bootstrapEndpoints {
infoClient := info.NewClient(endpoint)
ctx, cancel := utils.GetAPILargeContext()
defer cancel()
nodeID, proofOfPossession, err := infoClient.GetNodeID(ctx)
if err != nil {
return err
}
publicKey = "0x" + hex.EncodeToString(proofOfPossession.PublicKey[:])
pop = "0x" + hex.EncodeToString(proofOfPossession.ProofOfPossession[:])
changeAddr, err = getKeyForChangeOwner(nodeID.String(), changeAddr, network)
if err != nil {
return err
}
bootstrapValidators = append(bootstrapValidators, models.SubnetValidator{
NodeID: nodeID.String(),
Weight: constants.BootstrapValidatorWeight,
Balance: constants.BootstrapValidatorBalance,
BLSPublicKey: publicKey,
BLSProofOfPossession: pop,
ChangeOwnerAddr: changeAddr,
})
}
}
if len(bootstrapValidators) == 0 {
bootstrapValidators, err = promptBootstrapValidators(network)
if err != nil {
return err
}
}
}

// from here on we are assuming a public deploy
if subnetOnly && subnetIDStr != "" {
return errMutuallyExlusiveSubnetFlags
Expand Down Expand Up @@ -687,19 +782,27 @@
}

if !generateNodeID {
clusterName, err := node.GetClusterNameFromList(app)
if err != nil {
return err
clusterName := network.ClusterName
if clusterName == "" {
clusterName, err = node.GetClusterNameFromList(app)
if err != nil {
return err
}
}

if err = node.SyncSubnet(app, clusterName, blockchainName, true, nil); err != nil {
return err
}
if !useLocalMachine {
if err = node.SyncSubnet(app, clusterName, blockchainName, true, nil); err != nil {
return err
}

if err := node.WaitForHealthyCluster(app, clusterName, node.HealthCheckTimeout, node.HealthCheckPoolTime); err != nil {
return err
if err := node.WaitForHealthyCluster(app, clusterName, node.HealthCheckTimeout, node.HealthCheckPoolTime); err != nil {
return err
}
} else {
if err := node.TrackSubnetWithLocalMachine(app, clusterName, blockchainName); err != nil {
return err
}
}

chainSpec := contract.ChainSpec{
BlockchainName: blockchainName,
}
Expand All @@ -721,20 +824,29 @@
if err != nil {
return err
}
client, err := evm.GetClient(rpcURL)
if err != nil {
return err
}
evm.WaitForChainID(client)
privateAggregatorEndpoints, err := GetAggregatorExtraPeerEndpoints(network)
if err != nil {
return err
}
ux.Logger.PrintToUser("Initializing Proof of Authority Validator Manager contract on blockchain %s ...", blockchainName)
if err := validatormanager.SetupPoA(
app,
network,
rpcURL,
contract.ChainSpec{
BlockchainName: blockchainName,
},
chainSpec,
genesisPrivateKey,
common.HexToAddress(sidecar.PoAValidatorManagerOwner),
avaGoBootstrapValidators,
privateAggregatorEndpoints,
); err != nil {
return err
}
ux.Logger.GreenCheckmarkToUser("L1 is successfully converted to sovereign blockchain")
ux.Logger.GreenCheckmarkToUser("Proof of Authority Validator Manager contract successfully initialized on blockchain %s", blockchainName)
} else {
ux.Logger.GreenCheckmarkToUser("Generated Node ID and BLS info for bootstrap validator(s)")
ux.Logger.PrintToUser("To convert L1 to sovereign blockchain, create the corresponding Avalanche node(s) with the provided Node ID and BLS Info")
Expand Down Expand Up @@ -1003,3 +1115,34 @@
}
return subnetValidators, nil
}

func GetAggregatorExtraPeerEndpoints(network models.Network) ([]string, error) {
aggregatorExtraPeerEndpoints := []string{}
if network.ClusterName != "" {
clustersConfig, err := app.LoadClustersConfig()
if err != nil {
return nil, err
}
clusterConfig := clustersConfig.Clusters[network.ClusterName]
if clusterConfig.Local {
cli, err := binutils.NewGRPCClientWithEndpoint(
binutils.LocalClusterGRPCServerEndpoint,
binutils.WithAvoidRPCVersionCheck(true),
binutils.WithDialTimeout(constants.FastGRPCDialTimeout),
)
if err != nil {
return nil, err
}
ctx, cancel := utils.GetANRContext()
defer cancel()
status, err := cli.Status(ctx)
if err != nil {
return nil, err
}
for _, nodeInfo := range status.ClusterInfo.NodeInfos {
aggregatorExtraPeerEndpoints = append(aggregatorExtraPeerEndpoints, nodeInfo.Uri)
}
}
}
return aggregatorExtraPeerEndpoints, nil
}
6 changes: 4 additions & 2 deletions cmd/blockchaincmd/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ func PrintSubnetInfo(blockchainName string, onlyLocalnetInfo bool) error {
for net, data := range sc.Networks {
network, err := networkoptions.GetNetworkFromSidecarNetworkName(app, net)
if err != nil {
return err
ux.Logger.RedXToUser("%s is supposed to be deployed to network %s: %s ", blockchainName, network.Name(), err)
ux.Logger.PrintToUser("")
continue
}
if network.Kind == models.Local && !locallyDeployed {
continue
Expand Down Expand Up @@ -191,7 +193,7 @@ func PrintSubnetInfo(blockchainName string, onlyLocalnetInfo bool) error {
for net, data := range sc.Networks {
network, err := networkoptions.GetNetworkFromSidecarNetworkName(app, net)
if err != nil {
return err
continue
}
if network.Kind == models.Local && !locallyDeployed {
continue
Expand Down
2 changes: 1 addition & 1 deletion cmd/blockchaincmd/prompt_genesis_input.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func promptBootstrapValidators(network models.Network) ([]models.SubnetValidator
return nil, err
}
}
changeAddr, err := getKeyForChangeOwner(previousAddr, network)
changeAddr, err := getKeyForChangeOwner(nodeIDStr, previousAddr, network)
if err != nil {
return nil, err
}
Expand Down
7 changes: 5 additions & 2 deletions cmd/blockchaincmd/prompt_owners.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,11 @@ func getThreshold(maxLen int) (uint32, error) {
return uint32(intTh), err
}

func getKeyForChangeOwner(previouslyUsedAddr string, network models.Network) (string, error) {
changeAddrPrompt := "Which key would you like to set as change owner for leftover AVAX if the node is removed from validator set?"
func getKeyForChangeOwner(nodeID string, previouslyUsedAddr string, network models.Network) (string, error) {
changeAddrPrompt := fmt.Sprintf(
"Which key would you like to set as change owner for leftover AVAX if the node %s is removed from validator set?",
nodeID,
)

const (
getFromStored = "Get address from an existing stored key (created from avalanche key create or avalanche key import)"
Expand Down
Loading
Loading