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
|
package guardiand
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"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"
|
"github.com/tendermint/tendermint/libs/rand"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -16,14 +23,31 @@ import (
|
||||||
|
|
||||||
var setUpdateNumGuardians *int
|
var setUpdateNumGuardians *int
|
||||||
var templateGuardianIndex *int
|
var templateGuardianIndex *int
|
||||||
|
var chainID *string
|
||||||
|
var address *string
|
||||||
|
var module *string
|
||||||
|
|
||||||
func init() {
|
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")
|
templateGuardianIndex = TemplateCmd.PersistentFlags().Int("idx", 0, "Default current guardian set index")
|
||||||
|
|
||||||
setUpdateNumGuardians = AdminClientGuardianSetTemplateCmd.Flags().Int("num", 1, "Number of devnet guardians in example file")
|
setUpdateNumGuardians = AdminClientGuardianSetTemplateCmd.Flags().Int("num", 1, "Number of devnet guardians in example file")
|
||||||
|
|
||||||
TemplateCmd.AddCommand(AdminClientGuardianSetTemplateCmd)
|
AdminClientContractUpgradeTemplateCmd.Flags().AddFlagSet(governanceFlagSet)
|
||||||
TemplateCmd.AddCommand(AdminClientContractUpgradeTemplateCmd)
|
TemplateCmd.AddCommand(AdminClientContractUpgradeTemplateCmd)
|
||||||
|
|
||||||
|
AdminClientTokenBridgeRegisterChainCmd.Flags().AddFlagSet(governanceFlagSet)
|
||||||
|
AdminClientTokenBridgeRegisterChainCmd.Flags().AddFlagSet(moduleFlagSet)
|
||||||
TemplateCmd.AddCommand(AdminClientTokenBridgeRegisterChainCmd)
|
TemplateCmd.AddCommand(AdminClientTokenBridgeRegisterChainCmd)
|
||||||
|
|
||||||
|
AdminClientTokenBridgeUpgradeContractCmd.Flags().AddFlagSet(governanceFlagSet)
|
||||||
|
AdminClientTokenBridgeUpgradeContractCmd.Flags().AddFlagSet(moduleFlagSet)
|
||||||
TemplateCmd.AddCommand(AdminClientTokenBridgeUpgradeContractCmd)
|
TemplateCmd.AddCommand(AdminClientTokenBridgeUpgradeContractCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,36 +57,30 @@ var TemplateCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
var AdminClientGuardianSetTemplateCmd = &cobra.Command{
|
var AdminClientGuardianSetTemplateCmd = &cobra.Command{
|
||||||
Use: "guardian-set-update [FILENAME]",
|
Use: "guardian-set-update",
|
||||||
Short: "Generate an empty guardian set template at specified path (offline)",
|
Short: "Generate an empty guardian set template",
|
||||||
Run: runGuardianSetTemplate,
|
Run: runGuardianSetTemplate,
|
||||||
Args: cobra.ExactArgs(1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var AdminClientContractUpgradeTemplateCmd = &cobra.Command{
|
var AdminClientContractUpgradeTemplateCmd = &cobra.Command{
|
||||||
Use: "contract-upgrade [FILENAME]",
|
Use: "contract-upgrade",
|
||||||
Short: "Generate an empty contract upgrade template at specified path (offline)",
|
Short: "Generate an empty contract upgrade template",
|
||||||
Run: runContractUpgradeTemplate,
|
Run: runContractUpgradeTemplate,
|
||||||
Args: cobra.ExactArgs(1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var AdminClientTokenBridgeRegisterChainCmd = &cobra.Command{
|
var AdminClientTokenBridgeRegisterChainCmd = &cobra.Command{
|
||||||
Use: "token-bridge-register-chain [FILENAME]",
|
Use: "token-bridge-register-chain",
|
||||||
Short: "Generate an empty token bridge chain registration template at specified path (offline)",
|
Short: "Generate an empty token bridge chain registration template at specified path",
|
||||||
Run: runTokenBridgeRegisterChainTemplate,
|
Run: runTokenBridgeRegisterChainTemplate,
|
||||||
Args: cobra.ExactArgs(1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var AdminClientTokenBridgeUpgradeContractCmd = &cobra.Command{
|
var AdminClientTokenBridgeUpgradeContractCmd = &cobra.Command{
|
||||||
Use: "token-bridge-upgrade-contract [FILENAME]",
|
Use: "token-bridge-upgrade-contract",
|
||||||
Short: "Generate an empty token bridge contract upgrade template at specified path (offline)",
|
Short: "Generate an empty token bridge contract upgrade template at specified path",
|
||||||
Run: runTokenBridgeUpgradeContractTemplate,
|
Run: runTokenBridgeUpgradeContractTemplate,
|
||||||
Args: cobra.ExactArgs(1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
|
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.
|
// Use deterministic devnet addresses as examples in the template, such that this doubles as a test fixture.
|
||||||
guardians := make([]*nodev1.GuardianSetUpdate_Guardian, *setUpdateNumGuardians)
|
guardians := make([]*nodev1.GuardianSetUpdate_Guardian, *setUpdateNumGuardians)
|
||||||
for i := 0; i < *setUpdateNumGuardians; i++ {
|
for i := 0; i < *setUpdateNumGuardians; i++ {
|
||||||
|
@ -75,7 +93,7 @@ func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
m := &nodev1.InjectGovernanceVAARequest{
|
m := &nodev1.InjectGovernanceVAARequest{
|
||||||
CurrentSetIndex: uint32(*templateGuardianIndex),
|
CurrentSetIndex: uint32(*templateGuardianIndex),
|
||||||
Sequence: 1234,
|
Sequence: rand.Uint64(),
|
||||||
Nonce: rand.Uint32(),
|
Nonce: rand.Uint32(),
|
||||||
Payload: &nodev1.InjectGovernanceVAARequest_GuardianSet{
|
Payload: &nodev1.InjectGovernanceVAARequest_GuardianSet{
|
||||||
GuardianSet: &nodev1.GuardianSetUpdate{Guardians: guardians},
|
GuardianSet: &nodev1.GuardianSetUpdate{Guardians: guardians},
|
||||||
|
@ -86,15 +104,18 @@ func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
fmt.Print(string(b))
|
||||||
err = ioutil.WriteFile(path, b, 0640)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runContractUpgradeTemplate(cmd *cobra.Command, args []string) {
|
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{
|
m := &nodev1.InjectGovernanceVAARequest{
|
||||||
CurrentSetIndex: uint32(*templateGuardianIndex),
|
CurrentSetIndex: uint32(*templateGuardianIndex),
|
||||||
|
@ -102,8 +123,8 @@ func runContractUpgradeTemplate(cmd *cobra.Command, args []string) {
|
||||||
Nonce: rand.Uint32(),
|
Nonce: rand.Uint32(),
|
||||||
Payload: &nodev1.InjectGovernanceVAARequest_ContractUpgrade{
|
Payload: &nodev1.InjectGovernanceVAARequest_ContractUpgrade{
|
||||||
ContractUpgrade: &nodev1.ContractUpgrade{
|
ContractUpgrade: &nodev1.ContractUpgrade{
|
||||||
ChainId: 1,
|
ChainId: uint32(chainID),
|
||||||
NewContract: "0000000000000000000000000290FB167208Af455bB137780163b7B7a9a10C16",
|
NewContract: address,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -112,14 +133,17 @@ func runContractUpgradeTemplate(cmd *cobra.Command, args []string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
fmt.Print(string(b))
|
||||||
err = ioutil.WriteFile(path, b, 0640)
|
}
|
||||||
|
func runTokenBridgeRegisterChainTemplate(cmd *cobra.Command, args []string) {
|
||||||
|
address, err := parseAddress(*address)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
chainID, err := parseChainID(*chainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
func runTokenBridgeRegisterChainTemplate(cmd *cobra.Command, args []string) {
|
|
||||||
path := args[0]
|
|
||||||
|
|
||||||
m := &nodev1.InjectGovernanceVAARequest{
|
m := &nodev1.InjectGovernanceVAARequest{
|
||||||
CurrentSetIndex: uint32(*templateGuardianIndex),
|
CurrentSetIndex: uint32(*templateGuardianIndex),
|
||||||
|
@ -127,9 +151,9 @@ func runTokenBridgeRegisterChainTemplate(cmd *cobra.Command, args []string) {
|
||||||
Nonce: rand.Uint32(),
|
Nonce: rand.Uint32(),
|
||||||
Payload: &nodev1.InjectGovernanceVAARequest_BridgeRegisterChain{
|
Payload: &nodev1.InjectGovernanceVAARequest_BridgeRegisterChain{
|
||||||
BridgeRegisterChain: &nodev1.BridgeRegisterChain{
|
BridgeRegisterChain: &nodev1.BridgeRegisterChain{
|
||||||
Module: "TokenBridge",
|
Module: *module,
|
||||||
ChainId: 5,
|
ChainId: uint32(chainID),
|
||||||
EmitterAddress: "0000000000000000000000000290FB167208Af455bB137780163b7B7a9a10C16",
|
EmitterAddress: address,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -138,15 +162,18 @@ func runTokenBridgeRegisterChainTemplate(cmd *cobra.Command, args []string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
fmt.Print(string(b))
|
||||||
err = ioutil.WriteFile(path, b, 0640)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTokenBridgeUpgradeContractTemplate(cmd *cobra.Command, args []string) {
|
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{
|
m := &nodev1.InjectGovernanceVAARequest{
|
||||||
CurrentSetIndex: uint32(*templateGuardianIndex),
|
CurrentSetIndex: uint32(*templateGuardianIndex),
|
||||||
|
@ -154,9 +181,9 @@ func runTokenBridgeUpgradeContractTemplate(cmd *cobra.Command, args []string) {
|
||||||
Nonce: rand.Uint32(),
|
Nonce: rand.Uint32(),
|
||||||
Payload: &nodev1.InjectGovernanceVAARequest_BridgeContractUpgrade{
|
Payload: &nodev1.InjectGovernanceVAARequest_BridgeContractUpgrade{
|
||||||
BridgeContractUpgrade: &nodev1.BridgeUpgradeContract{
|
BridgeContractUpgrade: &nodev1.BridgeUpgradeContract{
|
||||||
Module: "TokenBridge",
|
Module: *module,
|
||||||
TargetChainId: 5,
|
TargetChainId: uint32(chainID),
|
||||||
NewContract: "0000000000000000000000000290FB167208Af455bB137780163b7B7a9a10C16",
|
NewContract: address,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -165,9 +192,55 @@ func runTokenBridgeUpgradeContractTemplate(cmd *cobra.Command, args []string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
fmt.Print(string(b))
|
||||||
err = ioutil.WriteFile(path, b, 0640)
|
}
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
// 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 {
|
||||||
|
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"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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 (
|
const (
|
||||||
ChainIDUnset ChainID = 0
|
ChainIDUnset ChainID = 0
|
||||||
// ChainIDSolana is the ChainID of Solana
|
// ChainIDSolana is the ChainID of Solana
|
||||||
|
|
Loading…
Reference in New Issue