Skip to content

Commit

Permalink
Problem: base denomination can't be parsed with decimal point (fixes #16
Browse files Browse the repository at this point in the history
)

Solution:
- decimal point is something for the future: cosmos/cosmos-sdk#7113
- for the moment -- configured "human" denomination ("cro") + base ("basecro" / "carson") -- configs/tx use "basecro"
- custom commands that use "human" denomination and convert it to the base
- custom init that changes bond_denom + gov minimum deposit to use the base denomination
  • Loading branch information
tomtau committed Sep 8, 2020
1 parent 6091800 commit 26cdffe
Show file tree
Hide file tree
Showing 23 changed files with 579 additions and 38 deletions.
6 changes: 3 additions & 3 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ import (
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/params"
paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/supply"
"github.com/crypto-com/chain-main/x/chainmain"
chainmainkeeper "github.com/crypto-com/chain-main/x/chainmain/keeper"
chainmaintypes "github.com/crypto-com/chain-main/x/chainmain/types"
// this line is used by starport scaffolding
distr "github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/gov"
paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
)

const appName = "Crypto.com Chain"
Expand Down
2 changes: 1 addition & 1 deletion app/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (app *NewApp) ExportAppStateAndValidators(
func (app *NewApp) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string) {
applyWhiteList := false

//Check if there is a whitelist
// Check if there is a whitelist
if len(jailWhiteList) > 0 {
applyWhiteList = true
}
Expand Down
18 changes: 18 additions & 0 deletions app/prefix.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package app

import (
"log"

sdk "github.com/cosmos/cosmos-sdk/types"
)

Expand All @@ -11,12 +13,28 @@ var (
ValidatorPubKeyPrefix = "crocnclpub"
ConsNodeAddressPrefix = "crocnclcons"
ConsNodePubKeyPrefix = "crocnclconspub"
HumanCoinUnit = "cro"
BaseCoinUnit = "basecro" // 10^-8 AKA "carson"
)

func SetConfig() {
config := sdk.GetConfig()
config.SetBech32PrefixForAccount(AccountAddressPrefix, AccountPubKeyPrefix)
config.SetBech32PrefixForValidator(ValidatorAddressPrefix, ValidatorPubKeyPrefix)
config.SetBech32PrefixForConsensusNode(ConsNodeAddressPrefix, ConsNodePubKeyPrefix)

croUnit := sdk.OneDec()
err := sdk.RegisterDenom(HumanCoinUnit, croUnit)
if err != nil {
log.Fatal(err)
}

carsonUnit := sdk.NewDecWithPrec(1, 8) // 10^-8 (carson)
err = sdk.RegisterDenom(BaseCoinUnit, carsonUnit)

if err != nil {
log.Fatal(err)
}

config.Seal()
}
44 changes: 44 additions & 0 deletions app/prefix_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package app_test

import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/crypto-com/chain-main/app"
"github.com/stretchr/testify/require"
)

func TestConversion(t *testing.T) {
app.SetConfig()

testCases := []struct {
input sdk.Coin
denom string
result sdk.Coin
expErr bool
}{
{sdk.NewCoin("foo", sdk.ZeroInt()), app.HumanCoinUnit, sdk.Coin{}, true},
{sdk.NewCoin(app.HumanCoinUnit, sdk.ZeroInt()), "foo", sdk.Coin{}, true},
{sdk.NewCoin(app.HumanCoinUnit, sdk.ZeroInt()), "FOO", sdk.Coin{}, true},

{sdk.NewCoin(app.HumanCoinUnit, sdk.NewInt(5)),
app.BaseCoinUnit, sdk.NewCoin(app.BaseCoinUnit, sdk.NewInt(500000000)), false}, // cro => carson

{sdk.NewCoin(app.BaseCoinUnit, sdk.NewInt(500000000)),
app.HumanCoinUnit, sdk.NewCoin(app.HumanCoinUnit, sdk.NewInt(5)), false}, // carson => cro

}

for i, tc := range testCases {
res, err := sdk.ConvertCoin(tc.input, tc.denom)
require.Equal(
t, tc.expErr, err != nil,
"unexpected error; tc: #%d, input: %s, denom: %s", i+1, tc.input, tc.denom,
)
require.Equal(
t, tc.result, res,
"invalid result; tc: #%d, input: %s, denom: %s", i+1, tc.input, tc.denom,
)
}

}
54 changes: 49 additions & 5 deletions cmd/chain-maincli/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"bufio"
"fmt"
"os"
"path"
Expand All @@ -10,21 +11,23 @@ import (
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/client/lcd"
"github.com/cosmos/cosmos-sdk/client/rpc"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
"github.com/cosmos/cosmos-sdk/x/bank"
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/tendermint/go-amino"
amino "github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/libs/cli"

"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
"github.com/crypto-com/chain-main/app"
// this line is used by starport scaffolding
// this line is used by starport scaffolding
)

func main() {
Expand Down Expand Up @@ -99,14 +102,55 @@ func queryCmd(cdc *amino.Codec) *cobra.Command {
return queryCmd
}

// SendTxCmd will create a send tx and sign it with the given key.
// and convert CRO to carson
func CustomSendTxCmd(cdc *amino.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "send [from_key_or_address] [to_address] [amount]",
Short: "Create and sign a send tx",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
inBuf := bufio.NewReader(cmd.InOrStdin())
txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContextWithInputAndFrom(inBuf, args[0]).WithCodec(cdc)

to, err := sdk.AccAddressFromBech32(args[1])
if err != nil {
return err
}

// parse coins trying to be sent
coins, err := sdk.ParseCoins(args[2])
if err != nil {
return err
}
for i := 0; i < len(coins); i++ {
coin, err := sdk.ConvertCoin(coins[i], app.BaseCoinUnit)
if err != nil {
return err
}
coins[i] = coin
}

// build and sign the transaction, then broadcast to Tendermint
msg := bank.NewMsgSend(cliCtx.GetFromAddress(), to, coins)
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
},
}

cmd = flags.PostCommands(cmd)[0]

return cmd
}

func txCmd(cdc *amino.Codec) *cobra.Command {
txCmd := &cobra.Command{
Use: "tx",
Short: "Transactions subcommands",
}

txCmd.AddCommand(
bankcmd.SendTxCmd(cdc),
CustomSendTxCmd(cdc),
flags.LineBreak,
authcmd.GetSignCommand(cdc),
authcmd.GetMultiSignCommand(cdc),
Expand Down Expand Up @@ -141,7 +185,7 @@ func registerRoutes(rs *lcd.RestServer) {
client.RegisterRoutes(rs.CliCtx, rs.Mux)
authrest.RegisterTxRoutes(rs.CliCtx, rs.Mux)
app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux)
// this line is used by starport scaffolding # 2
// this line is used by starport scaffolding # 2
}

func initConfig(cmd *cobra.Command) error {
Expand Down
23 changes: 22 additions & 1 deletion cmd/chain-maind/genaccounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import (
"errors"
"fmt"

"github.com/crypto-com/chain-main/app"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/tendermint/tendermint/libs/cli"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
Expand Down Expand Up @@ -50,6 +51,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
inBuf := bufio.NewReader(cmd.InOrStdin())
if err != nil {
// attempt to lookup address from Keybase if no address was provided
// nolint: govet
kb, err := keys.NewKeyring(
sdk.KeyringServiceName(),
viper.GetString(flags.FlagKeyringBackend),
Expand All @@ -72,6 +74,14 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
if err != nil {
return fmt.Errorf("failed to parse coins: %w", err)
}
for i := 0; i < len(coins); i++ {
// nolint: govet
coin, err := sdk.ConvertCoin(coins[i], app.BaseCoinUnit)
if err != nil {
return fmt.Errorf("failed to convert coins: %w", err)
}
coins[i] = coin
}

vestingStart := viper.GetInt64(flagVestingStart)
vestingEnd := viper.GetInt64(flagVestingEnd)
Expand All @@ -80,11 +90,21 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
return fmt.Errorf("failed to parse vesting amount: %w", err)
}

for i := 0; i < len(vestingAmt); i++ {
// nolint: govet
coin, err := sdk.ConvertCoin(vestingAmt[i], app.BaseCoinUnit)
if err != nil {
return fmt.Errorf("failed to convert coins: %w", err)
}
vestingAmt[i] = coin
}

// create concrete account type based on input parameters
var genAccount authexported.GenesisAccount

baseAccount := auth.NewBaseAccount(addr, coins.Sort(), nil, 0, 0)
if !vestingAmt.IsZero() {
// nolint: govet
baseVestingAccount, err := authvesting.NewBaseVestingAccount(baseAccount, vestingAmt.Sort(), vestingEnd)
if err != nil {
return fmt.Errorf("failed to create base vesting account: %w", err)
Expand All @@ -104,6 +124,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa
genAccount = baseAccount
}

// nolint: govet
if err := genAccount.Validate(); err != nil {
return fmt.Errorf("failed to validate new genesis account: %w", err)
}
Expand Down
Loading

0 comments on commit 26cdffe

Please sign in to comment.