node/cmd/guardiand: governance template improvements
The template commands now support generating full governance messages with all required fields. Outputs to stdout instead of a file. Change-Id: I3837107c3075363a54d31f9dfb4d6dc07c79daa5
This commit is contained in:
parent
964566c559
commit
d5f6540656
|
@ -1,10 +1,17 @@
|
|||
package guardiand
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/btcsuite/btcutil/bech32"
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/tendermint/tendermint/libs/rand"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -16,14 +23,31 @@ import (
|
|||
|
||||
var setUpdateNumGuardians *int
|
||||
var templateGuardianIndex *int
|
||||
var chainID *string
|
||||
var address *string
|
||||
var module *string
|
||||
|
||||
func init() {
|
||||
governanceFlagSet := pflag.NewFlagSet("governance", pflag.ExitOnError)
|
||||
chainID = governanceFlagSet.String("chain-id", "", "Chain ID")
|
||||
address = governanceFlagSet.String("new-address", "", "New address (hex, base58 or bech32)")
|
||||
|
||||
moduleFlagSet := pflag.NewFlagSet("module", pflag.ExitOnError)
|
||||
module = moduleFlagSet.String("module", "", "Module name")
|
||||
|
||||
templateGuardianIndex = TemplateCmd.PersistentFlags().Int("idx", 0, "Default current guardian set index")
|
||||
|
||||
setUpdateNumGuardians = AdminClientGuardianSetTemplateCmd.Flags().Int("num", 1, "Number of devnet guardians in example file")
|
||||
|
||||
TemplateCmd.AddCommand(AdminClientGuardianSetTemplateCmd)
|
||||
AdminClientContractUpgradeTemplateCmd.Flags().AddFlagSet(governanceFlagSet)
|
||||
TemplateCmd.AddCommand(AdminClientContractUpgradeTemplateCmd)
|
||||
|
||||
AdminClientTokenBridgeRegisterChainCmd.Flags().AddFlagSet(governanceFlagSet)
|
||||
AdminClientTokenBridgeRegisterChainCmd.Flags().AddFlagSet(moduleFlagSet)
|
||||
TemplateCmd.AddCommand(AdminClientTokenBridgeRegisterChainCmd)
|
||||
|
||||
AdminClientTokenBridgeUpgradeContractCmd.Flags().AddFlagSet(governanceFlagSet)
|
||||
AdminClientTokenBridgeUpgradeContractCmd.Flags().AddFlagSet(moduleFlagSet)
|
||||
TemplateCmd.AddCommand(AdminClientTokenBridgeUpgradeContractCmd)
|
||||
}
|
||||
|
||||
|
@ -33,36 +57,30 @@ var TemplateCmd = &cobra.Command{
|
|||
}
|
||||
|
||||
var AdminClientGuardianSetTemplateCmd = &cobra.Command{
|
||||
Use: "guardian-set-update [FILENAME]",
|
||||
Short: "Generate an empty guardian set template at specified path (offline)",
|
||||
Use: "guardian-set-update",
|
||||
Short: "Generate an empty guardian set template",
|
||||
Run: runGuardianSetTemplate,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
|
||||
var AdminClientContractUpgradeTemplateCmd = &cobra.Command{
|
||||
Use: "contract-upgrade [FILENAME]",
|
||||
Short: "Generate an empty contract upgrade template at specified path (offline)",
|
||||
Use: "contract-upgrade",
|
||||
Short: "Generate an empty contract upgrade template",
|
||||
Run: runContractUpgradeTemplate,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
|
||||
var AdminClientTokenBridgeRegisterChainCmd = &cobra.Command{
|
||||
Use: "token-bridge-register-chain [FILENAME]",
|
||||
Short: "Generate an empty token bridge chain registration template at specified path (offline)",
|
||||
Use: "token-bridge-register-chain",
|
||||
Short: "Generate an empty token bridge chain registration template at specified path",
|
||||
Run: runTokenBridgeRegisterChainTemplate,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
|
||||
var AdminClientTokenBridgeUpgradeContractCmd = &cobra.Command{
|
||||
Use: "token-bridge-upgrade-contract [FILENAME]",
|
||||
Short: "Generate an empty token bridge contract upgrade template at specified path (offline)",
|
||||
Use: "token-bridge-upgrade-contract",
|
||||
Short: "Generate an empty token bridge contract upgrade template at specified path",
|
||||
Run: runTokenBridgeUpgradeContractTemplate,
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
|
||||
func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
|
||||
path := args[0]
|
||||
|
||||
// Use deterministic devnet addresses as examples in the template, such that this doubles as a test fixture.
|
||||
guardians := make([]*nodev1.GuardianSetUpdate_Guardian, *setUpdateNumGuardians)
|
||||
for i := 0; i < *setUpdateNumGuardians; i++ {
|
||||
|
@ -75,7 +93,7 @@ func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
|
|||
|
||||
m := &nodev1.InjectGovernanceVAARequest{
|
||||
CurrentSetIndex: uint32(*templateGuardianIndex),
|
||||
Sequence: 1234,
|
||||
Sequence: rand.Uint64(),
|
||||
Nonce: rand.Uint32(),
|
||||
Payload: &nodev1.InjectGovernanceVAARequest_GuardianSet{
|
||||
GuardianSet: &nodev1.GuardianSetUpdate{Guardians: guardians},
|
||||
|
@ -86,15 +104,18 @@ func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(path, b, 0640)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Print(string(b))
|
||||
}
|
||||
|
||||
func runContractUpgradeTemplate(cmd *cobra.Command, args []string) {
|
||||
path := args[0]
|
||||
address, err := parseAddress(*address)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
chainID, err := parseChainID(*chainID)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
m := &nodev1.InjectGovernanceVAARequest{
|
||||
CurrentSetIndex: uint32(*templateGuardianIndex),
|
||||
|
@ -102,8 +123,8 @@ func runContractUpgradeTemplate(cmd *cobra.Command, args []string) {
|
|||
Nonce: rand.Uint32(),
|
||||
Payload: &nodev1.InjectGovernanceVAARequest_ContractUpgrade{
|
||||
ContractUpgrade: &nodev1.ContractUpgrade{
|
||||
ChainId: 1,
|
||||
NewContract: "0000000000000000000000000290FB167208Af455bB137780163b7B7a9a10C16",
|
||||
ChainId: uint32(chainID),
|
||||
NewContract: address,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -112,14 +133,17 @@ func runContractUpgradeTemplate(cmd *cobra.Command, args []string) {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(path, b, 0640)
|
||||
fmt.Print(string(b))
|
||||
}
|
||||
func runTokenBridgeRegisterChainTemplate(cmd *cobra.Command, args []string) {
|
||||
address, err := parseAddress(*address)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
chainID, err := parseChainID(*chainID)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
func runTokenBridgeRegisterChainTemplate(cmd *cobra.Command, args []string) {
|
||||
path := args[0]
|
||||
|
||||
m := &nodev1.InjectGovernanceVAARequest{
|
||||
CurrentSetIndex: uint32(*templateGuardianIndex),
|
||||
|
@ -127,9 +151,9 @@ func runTokenBridgeRegisterChainTemplate(cmd *cobra.Command, args []string) {
|
|||
Nonce: rand.Uint32(),
|
||||
Payload: &nodev1.InjectGovernanceVAARequest_BridgeRegisterChain{
|
||||
BridgeRegisterChain: &nodev1.BridgeRegisterChain{
|
||||
Module: "TokenBridge",
|
||||
ChainId: 5,
|
||||
EmitterAddress: "0000000000000000000000000290FB167208Af455bB137780163b7B7a9a10C16",
|
||||
Module: *module,
|
||||
ChainId: uint32(chainID),
|
||||
EmitterAddress: address,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -138,15 +162,18 @@ func runTokenBridgeRegisterChainTemplate(cmd *cobra.Command, args []string) {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(path, b, 0640)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Print(string(b))
|
||||
}
|
||||
|
||||
func runTokenBridgeUpgradeContractTemplate(cmd *cobra.Command, args []string) {
|
||||
path := args[0]
|
||||
address, err := parseAddress(*address)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
chainID, err := parseChainID(*chainID)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
m := &nodev1.InjectGovernanceVAARequest{
|
||||
CurrentSetIndex: uint32(*templateGuardianIndex),
|
||||
|
@ -154,9 +181,9 @@ func runTokenBridgeUpgradeContractTemplate(cmd *cobra.Command, args []string) {
|
|||
Nonce: rand.Uint32(),
|
||||
Payload: &nodev1.InjectGovernanceVAARequest_BridgeContractUpgrade{
|
||||
BridgeContractUpgrade: &nodev1.BridgeUpgradeContract{
|
||||
Module: "TokenBridge",
|
||||
TargetChainId: 5,
|
||||
NewContract: "0000000000000000000000000290FB167208Af455bB137780163b7B7a9a10C16",
|
||||
Module: *module,
|
||||
TargetChainId: uint32(chainID),
|
||||
NewContract: address,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -165,9 +192,55 @@ func runTokenBridgeUpgradeContractTemplate(cmd *cobra.Command, args []string) {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Print(string(b))
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(path, b, 0640)
|
||||
// parseAddress parses either a hex-encoded address and returns
|
||||
// a left-padded 32 byte hex string.
|
||||
func parseAddress(s string) (string, error) {
|
||||
// try base58
|
||||
b, err := base58.Decode(s)
|
||||
if err == nil {
|
||||
return leftPadAddress(b)
|
||||
}
|
||||
|
||||
// try bech32
|
||||
_, b, err = bech32.Decode(s)
|
||||
if err == nil {
|
||||
return leftPadAddress(b)
|
||||
}
|
||||
|
||||
// try hex
|
||||
if len(s) > 2 && strings.ToLower(s[:2]) == "0x" {
|
||||
s = s[2:]
|
||||
}
|
||||
|
||||
a, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return "", fmt.Errorf("invalid hex address: %v", err)
|
||||
}
|
||||
return leftPadAddress(a)
|
||||
}
|
||||
|
||||
func leftPadAddress(a []byte) (string, error) {
|
||||
if len(a) > 32 {
|
||||
return "", fmt.Errorf("address longer than 32 bytes")
|
||||
}
|
||||
return hex.EncodeToString(common.LeftPadBytes(a, 32)), nil
|
||||
}
|
||||
|
||||
// parseChainID parses a human-readable chain name or a chain ID.
|
||||
func parseChainID(name string) (vaa.ChainID, error) {
|
||||
s, err := vaa.ChainIDFromString(name)
|
||||
if err == nil {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// parse as uint32
|
||||
i, err := strconv.ParseUint(name, 10, 32)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to parse as name or uint32: %v", err)
|
||||
}
|
||||
|
||||
return vaa.ChainID(i), nil
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
@ -98,6 +99,25 @@ func (c ChainID) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
func ChainIDFromString(s string) (ChainID, error) {
|
||||
s = strings.ToLower(s)
|
||||
|
||||
switch s {
|
||||
case "solana":
|
||||
return ChainIDSolana, nil
|
||||
case "ethereum":
|
||||
return ChainIDEthereum, nil
|
||||
case "terra":
|
||||
return ChainIDTerra, nil
|
||||
case "bsc":
|
||||
return ChainIDBSC, nil
|
||||
case "polygon":
|
||||
return ChainIDPolygon, nil
|
||||
default:
|
||||
return ChainIDUnset, fmt.Errorf("unknown chain ID: %s", s)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
ChainIDUnset ChainID = 0
|
||||
// ChainIDSolana is the ChainID of Solana
|
||||
|
|
Loading…
Reference in New Issue