Merge PR #2614: Configurable Bech32 prefix for SDK users
This commit is contained in:
parent
fcf5b7764b
commit
9cf53f25f7
|
@ -26,6 +26,7 @@ FEATURES
|
|||
* Gaia
|
||||
|
||||
* SDK
|
||||
* (#1336) Mechanism for SDK Users to configure their own Bech32 prefixes instead of using the default cosmos prefixes.
|
||||
|
||||
* Tendermint
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client/rpc"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
|
@ -47,6 +48,12 @@ func main() {
|
|||
cobra.EnableCommandSorting = false
|
||||
cdc := app.MakeCodec()
|
||||
|
||||
config := sdk.GetConfig()
|
||||
config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub)
|
||||
config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub)
|
||||
config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub)
|
||||
config.Seal()
|
||||
|
||||
// TODO: setup keybase, viper object, etc. to be passed into
|
||||
// the below functions and eliminate global vars, like we do
|
||||
// with the cdc
|
||||
|
|
|
@ -18,10 +18,18 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
gaiaInit "github.com/cosmos/cosmos-sdk/cmd/gaia/init"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cdc := app.MakeCodec()
|
||||
|
||||
config := sdk.GetConfig()
|
||||
config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub)
|
||||
config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub)
|
||||
config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub)
|
||||
config.Seal()
|
||||
|
||||
ctx := server.NewDefaultContext()
|
||||
cobra.EnableCommandSorting = false
|
||||
rootCmd := &cobra.Command{
|
||||
|
|
|
@ -19,6 +19,13 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
|
||||
config := sdk.GetConfig()
|
||||
config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub)
|
||||
config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub)
|
||||
config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub)
|
||||
config.Seal()
|
||||
|
||||
rootCmd.AddCommand(txCmd)
|
||||
rootCmd.AddCommand(pubkeyCmd)
|
||||
rootCmd.AddCommand(addrCmd)
|
||||
|
|
|
@ -21,6 +21,8 @@ import (
|
|||
coolcmd "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool/client/cli"
|
||||
powcmd "github.com/cosmos/cosmos-sdk/examples/democoin/x/pow/client/cli"
|
||||
simplestakingcmd "github.com/cosmos/cosmos-sdk/examples/democoin/x/simplestake/client/cli"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// rootCmd is the entry point for this binary
|
||||
|
@ -38,6 +40,13 @@ func main() {
|
|||
// get the codec
|
||||
cdc := app.MakeCodec()
|
||||
|
||||
// Setup certain SDK config
|
||||
config := sdk.GetConfig()
|
||||
config.SetBech32PrefixForAccount("demoacc", "demopub")
|
||||
config.SetBech32PrefixForValidator("demoval", "demovalpub")
|
||||
config.SetBech32PrefixForConsensusNode("democons", "democonspub")
|
||||
config.Seal()
|
||||
|
||||
// TODO: setup keybase, viper object, etc. to be passed into
|
||||
// the below functions and eliminate global vars, like we do
|
||||
// with the cdc
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/examples/democoin/app"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -135,6 +136,14 @@ func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB, _ io.Writer) (j
|
|||
|
||||
func main() {
|
||||
cdc := app.MakeCodec()
|
||||
|
||||
// Setup certain SDK config
|
||||
config := sdk.GetConfig()
|
||||
config.SetBech32PrefixForAccount("demoacc", "demopub")
|
||||
config.SetBech32PrefixForValidator("demoval", "demovalpub")
|
||||
config.SetBech32PrefixForConsensusNode("democons", "democonspub")
|
||||
config.Seal()
|
||||
|
||||
ctx := server.NewDefaultContext()
|
||||
|
||||
rootCmd := &cobra.Command{
|
||||
|
|
|
@ -55,7 +55,8 @@ func AccAddressFromHex(address string) (addr AccAddress, err error) {
|
|||
|
||||
// AccAddressFromBech32 creates an AccAddress from a Bech32 string.
|
||||
func AccAddressFromBech32(address string) (addr AccAddress, err error) {
|
||||
bz, err := GetFromBech32(address, Bech32PrefixAccAddr)
|
||||
bech32PrefixAccAddr := GetConfig().GetBech32AccountAddrPrefix()
|
||||
bz, err := GetFromBech32(address, bech32PrefixAccAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -124,7 +125,8 @@ func (aa AccAddress) Bytes() []byte {
|
|||
|
||||
// String implements the Stringer interface.
|
||||
func (aa AccAddress) String() string {
|
||||
bech32Addr, err := bech32.ConvertAndEncode(Bech32PrefixAccAddr, aa.Bytes())
|
||||
bech32PrefixAccAddr := GetConfig().GetBech32AccountAddrPrefix()
|
||||
bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixAccAddr, aa.Bytes())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -169,7 +171,8 @@ func ValAddressFromHex(address string) (addr ValAddress, err error) {
|
|||
|
||||
// ValAddressFromBech32 creates a ValAddress from a Bech32 string.
|
||||
func ValAddressFromBech32(address string) (addr ValAddress, err error) {
|
||||
bz, err := GetFromBech32(address, Bech32PrefixValAddr)
|
||||
bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix()
|
||||
bz, err := GetFromBech32(address, bech32PrefixValAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -239,7 +242,8 @@ func (va ValAddress) Bytes() []byte {
|
|||
|
||||
// String implements the Stringer interface.
|
||||
func (va ValAddress) String() string {
|
||||
bech32Addr, err := bech32.ConvertAndEncode(Bech32PrefixValAddr, va.Bytes())
|
||||
bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix()
|
||||
bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixValAddr, va.Bytes())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -284,7 +288,8 @@ func ConsAddressFromHex(address string) (addr ConsAddress, err error) {
|
|||
|
||||
// ConsAddressFromBech32 creates a ConsAddress from a Bech32 string.
|
||||
func ConsAddressFromBech32(address string) (addr ConsAddress, err error) {
|
||||
bz, err := GetFromBech32(address, Bech32PrefixConsAddr)
|
||||
bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix()
|
||||
bz, err := GetFromBech32(address, bech32PrefixConsAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -359,7 +364,8 @@ func (ca ConsAddress) Bytes() []byte {
|
|||
|
||||
// String implements the Stringer interface.
|
||||
func (ca ConsAddress) String() string {
|
||||
bech32Addr, err := bech32.ConvertAndEncode(Bech32PrefixConsAddr, ca.Bytes())
|
||||
bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix()
|
||||
bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixConsAddr, ca.Bytes())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -387,7 +393,8 @@ func (ca ConsAddress) Format(s fmt.State, verb rune) {
|
|||
// Bech32ifyAccPub returns a Bech32 encoded string containing the
|
||||
// Bech32PrefixAccPub prefix for a given account PubKey.
|
||||
func Bech32ifyAccPub(pub crypto.PubKey) (string, error) {
|
||||
return bech32.ConvertAndEncode(Bech32PrefixAccPub, pub.Bytes())
|
||||
bech32PrefixAccPub := GetConfig().GetBech32AccountPubPrefix()
|
||||
return bech32.ConvertAndEncode(bech32PrefixAccPub, pub.Bytes())
|
||||
}
|
||||
|
||||
// MustBech32ifyAccPub returns the result of Bech32ifyAccPub panicing on failure.
|
||||
|
@ -403,7 +410,8 @@ func MustBech32ifyAccPub(pub crypto.PubKey) string {
|
|||
// Bech32ifyValPub returns a Bech32 encoded string containing the
|
||||
// Bech32PrefixValPub prefix for a given validator operator's PubKey.
|
||||
func Bech32ifyValPub(pub crypto.PubKey) (string, error) {
|
||||
return bech32.ConvertAndEncode(Bech32PrefixValPub, pub.Bytes())
|
||||
bech32PrefixValPub := GetConfig().GetBech32ValidatorPubPrefix()
|
||||
return bech32.ConvertAndEncode(bech32PrefixValPub, pub.Bytes())
|
||||
}
|
||||
|
||||
// MustBech32ifyValPub returns the result of Bech32ifyValPub panicing on failure.
|
||||
|
@ -419,7 +427,8 @@ func MustBech32ifyValPub(pub crypto.PubKey) string {
|
|||
// Bech32ifyConsPub returns a Bech32 encoded string containing the
|
||||
// Bech32PrefixConsPub prefixfor a given consensus node's PubKey.
|
||||
func Bech32ifyConsPub(pub crypto.PubKey) (string, error) {
|
||||
return bech32.ConvertAndEncode(Bech32PrefixConsPub, pub.Bytes())
|
||||
bech32PrefixConsPub := GetConfig().GetBech32ConsensusPubPrefix()
|
||||
return bech32.ConvertAndEncode(bech32PrefixConsPub, pub.Bytes())
|
||||
}
|
||||
|
||||
// MustBech32ifyConsPub returns the result of Bech32ifyConsPub panicing on
|
||||
|
@ -436,7 +445,8 @@ func MustBech32ifyConsPub(pub crypto.PubKey) string {
|
|||
// GetAccPubKeyBech32 creates a PubKey for an account with a given public key
|
||||
// string using the Bech32 Bech32PrefixAccPub prefix.
|
||||
func GetAccPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) {
|
||||
bz, err := GetFromBech32(pubkey, Bech32PrefixAccPub)
|
||||
bech32PrefixAccPub := GetConfig().GetBech32AccountPubPrefix()
|
||||
bz, err := GetFromBech32(pubkey, bech32PrefixAccPub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -463,7 +473,8 @@ func MustGetAccPubKeyBech32(pubkey string) (pk crypto.PubKey) {
|
|||
// GetValPubKeyBech32 creates a PubKey for a validator's operator with a given
|
||||
// public key string using the Bech32 Bech32PrefixValPub prefix.
|
||||
func GetValPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) {
|
||||
bz, err := GetFromBech32(pubkey, Bech32PrefixValPub)
|
||||
bech32PrefixValPub := GetConfig().GetBech32ValidatorPubPrefix()
|
||||
bz, err := GetFromBech32(pubkey, bech32PrefixValPub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -490,7 +501,8 @@ func MustGetValPubKeyBech32(pubkey string) (pk crypto.PubKey) {
|
|||
// GetConsPubKeyBech32 creates a PubKey for a consensus node with a given public
|
||||
// key string using the Bech32 Bech32PrefixConsPub prefix.
|
||||
func GetConsPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) {
|
||||
bz, err := GetFromBech32(pubkey, Bech32PrefixConsPub)
|
||||
bech32PrefixConsPub := GetConfig().GetBech32ConsensusPubPrefix()
|
||||
bz, err := GetFromBech32(pubkey, bech32PrefixConsPub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import (
|
|||
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
|
@ -178,3 +180,44 @@ func TestConsAddress(t *testing.T) {
|
|||
require.NotNil(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
const letterBytes = "abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
func RandString(n int) string {
|
||||
b := make([]byte, n)
|
||||
for i := range b {
|
||||
b[i] = letterBytes[rand.Intn(len(letterBytes))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func TestConfiguredPrefix(t *testing.T) {
|
||||
var pub ed25519.PubKeyEd25519
|
||||
for length := 1; length < 10; length++ {
|
||||
for times := 1; times < 20; times++ {
|
||||
rand.Read(pub[:])
|
||||
// Test if randomly generated prefix of a given length works
|
||||
prefix := RandString(length)
|
||||
// Assuming that GetConfig is not sealed.
|
||||
config := types.GetConfig()
|
||||
config.SetBech32PrefixForAccount(prefix+"acc", prefix+"pub")
|
||||
acc := types.AccAddress(pub.Address())
|
||||
require.True(t, strings.HasPrefix(acc.String(), prefix+"acc"))
|
||||
bech32Pub := types.MustBech32ifyAccPub(pub)
|
||||
require.True(t, strings.HasPrefix(bech32Pub, prefix+"pub"))
|
||||
|
||||
config.SetBech32PrefixForValidator(prefix+"valaddr", prefix+"valpub")
|
||||
val := types.ValAddress(pub.Address())
|
||||
require.True(t, strings.HasPrefix(val.String(), prefix+"valaddr"))
|
||||
bech32ValPub := types.MustBech32ifyValPub(pub)
|
||||
require.True(t, strings.HasPrefix(bech32ValPub, prefix+"valpub"))
|
||||
|
||||
config.SetBech32PrefixForConsensusNode(prefix+"consaddr", prefix+"conspub")
|
||||
cons := types.ConsAddress(pub.Address())
|
||||
require.True(t, strings.HasPrefix(cons.String(), prefix+"consaddr"))
|
||||
bech32ConsPub := types.MustBech32ifyConsPub(pub)
|
||||
require.True(t, strings.HasPrefix(bech32ConsPub, prefix+"conspub"))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Config is the structure that holds the SDK configuration parameters.
|
||||
// This could be used to initialize certain configuration parameters for the SDK.
|
||||
type Config struct {
|
||||
mtx sync.RWMutex
|
||||
sealed bool
|
||||
bech32AddressPrefix map[string]string
|
||||
}
|
||||
|
||||
var (
|
||||
// Initializing an instance of Config
|
||||
sdkConfig = &Config{
|
||||
sealed: false,
|
||||
bech32AddressPrefix: map[string]string{
|
||||
"account_addr": Bech32PrefixAccAddr,
|
||||
"validator_addr": Bech32PrefixValAddr,
|
||||
"consensus_addr": Bech32PrefixConsAddr,
|
||||
"account_pub": Bech32PrefixAccPub,
|
||||
"validator_pub": Bech32PrefixValPub,
|
||||
"consensus_pub": Bech32PrefixConsPub,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// GetConfig returns the config instance for the SDK.
|
||||
func GetConfig() *Config {
|
||||
return sdkConfig
|
||||
}
|
||||
|
||||
func (config *Config) assertNotSealed() {
|
||||
config.mtx.Lock()
|
||||
defer config.mtx.Unlock()
|
||||
|
||||
if config.sealed {
|
||||
panic("Config is sealed")
|
||||
}
|
||||
}
|
||||
|
||||
// SetBech32PrefixForAccount builds the Config with Bech32 addressPrefix and publKeyPrefix for accounts
|
||||
// and returns the config instance
|
||||
func (config *Config) SetBech32PrefixForAccount(addressPrefix, pubKeyPrefix string) {
|
||||
config.assertNotSealed()
|
||||
config.bech32AddressPrefix["account_addr"] = addressPrefix
|
||||
config.bech32AddressPrefix["account_pub"] = pubKeyPrefix
|
||||
}
|
||||
|
||||
// SetBech32PrefixForValidator builds the Config with Bech32 addressPrefix and publKeyPrefix for validators
|
||||
// and returns the config instance
|
||||
func (config *Config) SetBech32PrefixForValidator(addressPrefix, pubKeyPrefix string) {
|
||||
config.assertNotSealed()
|
||||
config.bech32AddressPrefix["validator_addr"] = addressPrefix
|
||||
config.bech32AddressPrefix["validator_pub"] = pubKeyPrefix
|
||||
}
|
||||
|
||||
// SetBech32PrefixForConsensusNode builds the Config with Bech32 addressPrefix and publKeyPrefix for consensus nodes
|
||||
// and returns the config instance
|
||||
func (config *Config) SetBech32PrefixForConsensusNode(addressPrefix, pubKeyPrefix string) {
|
||||
config.assertNotSealed()
|
||||
config.bech32AddressPrefix["consensus_addr"] = addressPrefix
|
||||
config.bech32AddressPrefix["consensus_pub"] = pubKeyPrefix
|
||||
}
|
||||
|
||||
// Seal seals the config such that the config state could not be modified further
|
||||
func (config *Config) Seal() *Config {
|
||||
config.mtx.Lock()
|
||||
defer config.mtx.Unlock()
|
||||
|
||||
config.sealed = true
|
||||
return config
|
||||
}
|
||||
|
||||
// GetBech32AccountAddrPrefix returns the Bech32 prefix for account address
|
||||
func (config *Config) GetBech32AccountAddrPrefix() string {
|
||||
return config.bech32AddressPrefix["account_addr"]
|
||||
}
|
||||
|
||||
// GetBech32ValidatorAddrPrefix returns the Bech32 prefix for validator address
|
||||
func (config *Config) GetBech32ValidatorAddrPrefix() string {
|
||||
return config.bech32AddressPrefix["validator_addr"]
|
||||
}
|
||||
|
||||
// GetBech32ConsensusAddrPrefix returns the Bech32 prefix for consensus node address
|
||||
func (config *Config) GetBech32ConsensusAddrPrefix() string {
|
||||
return config.bech32AddressPrefix["consensus_addr"]
|
||||
}
|
||||
|
||||
// GetBech32AccountPubPrefix returns the Bech32 prefix for account public key
|
||||
func (config *Config) GetBech32AccountPubPrefix() string {
|
||||
return config.bech32AddressPrefix["account_pub"]
|
||||
}
|
||||
|
||||
// GetBech32ValidatorPubPrefix returns the Bech32 prefix for validator public key
|
||||
func (config *Config) GetBech32ValidatorPubPrefix() string {
|
||||
return config.bech32AddressPrefix["validator_pub"]
|
||||
}
|
||||
|
||||
// GetBech32ConsensusPubPrefix returns the Bech32 prefix for consensus node public key
|
||||
func (config *Config) GetBech32ConsensusPubPrefix() string {
|
||||
return config.bech32AddressPrefix["consensus_pub"]
|
||||
}
|
Loading…
Reference in New Issue