Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
2 changes: 1 addition & 1 deletion cmd/blockchaincmd/add_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func addValidator(cmd *cobra.Command, args []string) error {
}

if len(args) == 0 {
sc, _, err = importBlockchain(network, addValidatorFlags.RPC, ids.Empty, ux.Logger.PrintToUser)
sc, _, err = importBlockchain(network, addValidatorFlags.RPC, true, ids.Empty, ux.Logger.PrintToUser)
if err != nil {
return err
}
Expand Down
43 changes: 28 additions & 15 deletions cmd/blockchaincmd/import_public.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var (
useSubnetEvm bool
useCustomVM bool
rpcURL string
noRPCAvailable bool
)

// avalanche blockchain import public
Expand Down Expand Up @@ -70,6 +71,7 @@ plag.`,
"the blockchain ID",
)
cmd.Flags().StringVar(&rpcURL, "rpc", "", "rpc endpoint for the blockchain")
cmd.Flags().BoolVar(&noRPCAvailable, "no-rpc-available", false, "use this when an RPC if offline and can't be accesed")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems that noRPCAvailable flag needs to be set to true so that importBlockchain can:

if rpcIsAvailable {
			sc.ValidatorManagement, err = validatorManagerSDK.GetValidatorManagerType(rpcURL, common.HexToAddress(validatorManagerAddress))
			if err != nil {
				return models.Sidecar{}, nil, fmt.Errorf("could not obtain validator manager type: %w", err)
			}
			printFunc("  Validation Kind: %s", sc.ValidatorManagement)
			if sc.ValidatorManagement == validatormanagertypes.ProofOfAuthority {
				owner, err := contract.GetContractOwner(rpcURL, common.HexToAddress(validatorManagerAddress))
				if err != nil {
					return models.Sidecar{}, nil, err
				}
				sc.ValidatorManagerOwner = owner.String()
				printFunc("  Validator Manager Owner: %s", sc.ValidatorManagerOwner)
			}
		}

and

if rpcIsAvailable {
			blockchainID, _ = precompiles.WarpPrecompileGetBlockchainID(rpcURL)
		}
		if blockchainID == ids.Empty {
			blockchainID, err = app.Prompt.CaptureID("What is the Blockchain ID?")
			if err != nil {
				return models.Sidecar{}, nil, err
			}
		}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why don't we just remove this flag and:
return error if rpc is unavailable when:

sc.ValidatorManagement, err = validatorManagerSDK.GetValidatorManagerType(rpcURL, common.HexToAddress(validatorManagerAddress)

since we need to know if poa/ pos anyways

and if

blockchainID, _ = precompiles.WarpPrecompileGetBlockchainID(rpcURL)
		}

returns error due to url being unavailable we can just prompt for the blockchainID

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TLDR: I think we should remove this flag

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are cases where a rpc in unavailable because all rpc nodes are down but you anyway want to be
able to partially import the L1, most notably to increase validator balances, or to try out some local tests, or for any
misc debugging reason like be able to easily have access to certain L1 info.
I indeed used this functionality twice in the past month

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eg if all your validator drawn the balance, you need to use increase balance, and a reasonable flow would be to
call first import on the rpc, and then increase the balances

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of using flag why not we just make a call to this RPC, and if this RPC is not returning any response then we know that it is not available (don't return the error) and respond accordingly as if we have the flag set as true

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can be the case that there is a temporal network failure and the import from a failed rpc will be assumed to be successful, being not the case, also, the idea of this flag is to even avoid asking for the url instead of requiring the user to provide
a fake url.
not opposing to this but the flag, being kind of a bit more ugly, seems a better option to me.
as you wish

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or we can just accept any URL string at prompt, and tell the user which to use for empty rpc, eg just enter

return cmd
}

Expand All @@ -95,7 +97,7 @@ func importPublic(*cobra.Command, []string) error {
}
}

sc, genBytes, err := importBlockchain(network, rpcURL, blockchainID, ux.Logger.PrintToUser)
sc, genBytes, err := importBlockchain(network, rpcURL, !noRPCAvailable, blockchainID, ux.Logger.PrintToUser)
if err != nil {
return err
}
Expand Down Expand Up @@ -181,21 +183,25 @@ func importPublic(*cobra.Command, []string) error {
func importBlockchain(
network models.Network,
rpcURL string,
rpcIsAvailable bool,
blockchainID ids.ID,
printFunc func(msg string, args ...interface{}),
) (models.Sidecar, []byte, error) {
var err error

if rpcURL == "" {
if rpcIsAvailable && rpcURL == "" {
rpcURL, err = app.Prompt.CaptureURL("What is the RPC endpoint?", false)
if err != nil {
return models.Sidecar{}, nil, err
}
}

if blockchainID == ids.Empty {
blockchainID, err = precompiles.WarpPrecompileGetBlockchainID(rpcURL)
if err != nil {
var err error
if rpcIsAvailable {
blockchainID, _ = precompiles.WarpPrecompileGetBlockchainID(rpcURL)
}
if blockchainID == ids.Empty {
blockchainID, err = app.Prompt.CaptureID("What is the Blockchain ID?")
if err != nil {
return models.Sidecar{}, nil, err
Expand Down Expand Up @@ -230,7 +236,6 @@ func importBlockchain(
network.Name(): {
SubnetID: subnetID,
BlockchainID: blockchainID,
RPCEndpoints: []string{rpcURL},
},
},
Subnet: blockchainName,
Expand All @@ -239,25 +244,33 @@ func importBlockchain(
ImportedFromAPM: true,
}

if rpcIsAvailable {
e := sc.Networks[network.Name()]
e.RPCEndpoints = []string{rpcURL}
sc.Networks[network.Name()] = e
}

if !subnetInfo.IsPermissioned {
sc.Sovereign = true
validatorManagerAddress = "0x" + hex.EncodeToString(subnetInfo.ManagerAddress)
e := sc.Networks[network.Name()]
e.ValidatorManagerAddress = validatorManagerAddress
sc.Networks[network.Name()] = e
sc.ValidatorManagement, err = validatorManagerSDK.GetValidatorManagerType(rpcURL, common.HexToAddress(validatorManagerAddress))
if err != nil {
return models.Sidecar{}, nil, fmt.Errorf("could not obtain validator manager type: %w", err)
}
printFunc(" Validator Manager Address: %s", validatorManagerAddress)
printFunc(" Validation Kind: %s", sc.ValidatorManagement)
if sc.ValidatorManagement == validatormanagertypes.ProofOfAuthority {
owner, err := contract.GetContractOwner(rpcURL, common.HexToAddress(validatorManagerAddress))
if rpcIsAvailable {
sc.ValidatorManagement, err = validatorManagerSDK.GetValidatorManagerType(rpcURL, common.HexToAddress(validatorManagerAddress))
if err != nil {
return models.Sidecar{}, nil, err
return models.Sidecar{}, nil, fmt.Errorf("could not obtain validator manager type: %w", err)
}
printFunc(" Validation Kind: %s", sc.ValidatorManagement)
if sc.ValidatorManagement == validatormanagertypes.ProofOfAuthority {
owner, err := contract.GetContractOwner(rpcURL, common.HexToAddress(validatorManagerAddress))
if err != nil {
return models.Sidecar{}, nil, err
}
sc.ValidatorManagerOwner = owner.String()
printFunc(" Validator Manager Owner: %s", sc.ValidatorManagerOwner)
}
sc.ValidatorManagerOwner = owner.String()
printFunc(" Validator Manager Owner: %s", sc.ValidatorManagerOwner)
}
}

Expand Down
Loading