Skip to content

Commit

Permalink
Fixed bad handling of core symbol
Browse files Browse the repository at this point in the history
The core symbol is now retrieved on-demand when a command requires it. The
current retrieval way is to query the `rammarket` table which should have
a row only when `eosio:init` has been called with the core symbol set.

This row has a quote balance asset value that is always equalt to the
core symbol. This is where we get it.

In the eventuality that it's not possible to retrieve, the user can still
override the default 4,EOS by passing `--core-symbol` to the `eosc` CLI.
This will use this core symbol only when impossible to infer it.

Also added logging facilities to help debugging certain part of the `eosc`
CLI.

Fixes #136
  • Loading branch information
Matthieu Vachon committed Jun 14, 2019
1 parent 786f76a commit 1a909be
Show file tree
Hide file tree
Showing 21 changed files with 125 additions and 60 deletions.
93 changes: 74 additions & 19 deletions eosc/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ import (
"strings"
"time"

"go.uber.org/zap"

yaml2json "github.com/bronze1man/go-yaml2json"
"github.com/eoscanada/eos-go"
"github.com/eoscanada/eos-go/ecc"
"github.com/eoscanada/eos-go/sudo"
"github.com/eoscanada/eosc/cli"
eosvault "github.com/eoscanada/eosc/vault"
"github.com/spf13/viper"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)

Expand Down Expand Up @@ -85,6 +88,58 @@ func getAPI() *eos.API {
return api
}

var coreSymbolIsCached bool
var coreSymbol eos.Symbol

func getCoreSymbol() eos.Symbol {
if coreSymbolIsCached {
return coreSymbol
}

// In the event of a failure, we do not want to re-perform an API call,
// so let's record the fact that getCoreSymbol is cached right here.
// The init core symbol will take care of setting an approriate core
// symbol from global flag and reporting the error.
coreSymbolIsCached = true
if err := initCoreSymbol(); err != nil {
coreSymbol = eos.EOSSymbol
zlog.Debug(
"unable to retrieve core symbol from API, falling back to default",
zap.Error(err),
zap.Stringer("default", coreSymbol),
)
}

return coreSymbol
}

func initCoreSymbol() error {
resp, err := getAPI().GetTableRows(eos.GetTableRowsRequest{
Code: "eosio",
Scope: "eosio",
Table: "rammarket",
JSON: true,
})

if err != nil {
return fmt.Errorf("unable to fetch table: %s", err)
}

result := gjson.GetBytes(resp.Rows, "0.quote.balance")
if !result.Exists() {
return errors.New("table has not expected format")
}

asset, err := eos.NewAsset(result.String())
if !result.Exists() {
return fmt.Errorf("quote balance asset %q is not valid: %s", result.String(), err)
}

zlog.Debug("Retrieved core symbol from API, using it as default core symbol", zap.Stringer("symbol", asset.Symbol))
coreSymbol = asset.Symbol
return nil
}

func sanitizeAPIURL(input string) string {
return strings.TrimRight(input, "/")
}
Expand Down Expand Up @@ -312,32 +367,39 @@ func loadYAMLOrJSONFile(filename string, v interface{}) error {

func toAccount(in, field string) eos.AccountName {
acct, err := cli.ToAccountName(in)
if err != nil {
errorCheck(fmt.Sprintf("invalid account format for %q", field), err)
}
errorCheck(fmt.Sprintf("invalid account format for %q", field), err)

return acct
}

func toAsset(symbol eos.Symbol, in, field string) eos.Asset {
asset, err := eos.NewAssetFromString(symbol, in)
errorCheck(fmt.Sprintf("invalid %s asset for %q", symbol.String(), field), err)
asset, err := eos.NewFixedSymbolAssetFromString(symbol, in)
errorCheck(fmt.Sprintf("invalid %q value %q", field, in), err)

return asset
}

func toEOSAsset(in, field string) eos.Asset {
asset, err := eos.NewEOSAssetFromString(in)
errorCheck(fmt.Sprintf("invalid %s asset for %q", eos.EOSSymbol, field), err)
func toAssetWithDefaultCoreSymbol(in, field string) eos.Asset {
if len(strings.Split(in, " ")) == 1 {
return toCoreAsset(in, field)
}

asset, err := eos.NewAssetFromString(in)
errorCheck(fmt.Sprintf("invalid asset value %q for %q", in, field), err)

return asset
}

func toREXAsset(in, field string) eos.Asset {
asset, err := eos.NewREXAssetFromString(in)
errorCheck(fmt.Sprintf("invalid %s asset for %q", eos.REXSymbol, field), err)
func toCoreAsset(in, field string) eos.Asset {
return toAsset(getCoreSymbol(), in, field)
}

return asset
func toEOSAsset(in, field string) eos.Asset {
return toAsset(eos.EOSSymbol, in, field)
}

func toREXAsset(in, field string) eos.Asset {
return toAsset(eos.REXSymbol, in, field)
}

func toName(in, field string) eos.Name {
Expand Down Expand Up @@ -395,10 +457,3 @@ func isStubABI(abi eos.ABI) bool {
abi.Structs == nil && abi.Tables == nil &&
abi.Types == nil
}

func NewAssetDefaultEOS(input string) (eos.Asset, error) {
if len(strings.Split(input, " ")) == 1 {
return eos.NewEOSAssetFromString(input)
}
return eos.NewAsset(input)
}
11 changes: 11 additions & 0 deletions eosc/cmd/logging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package cmd

import (
"go.uber.org/zap"
)

var zlog = zap.NewNop()

func SetLogger(l *zap.Logger) {
zlog = l
}
2 changes: 1 addition & 1 deletion eosc/cmd/rexBuy.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var rexBuy = &cobra.Command{
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
account := toAccount(args[0], "account")
quantity := toEOSAsset(args[1], "quantity")
quantity := toCoreAsset(args[1], "quantity")

pushEOSCActions(getAPI(), rex.NewBuyREX(
account,
Expand Down
2 changes: 1 addition & 1 deletion eosc/cmd/rexDefundCPU.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var rexDefundCPU = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
account := toAccount(args[0], "account")
loanNumber := toUint64(args[1], "loan number")
quantity := toEOSAsset(args[2], "quantity")
quantity := toCoreAsset(args[2], "quantity")

pushEOSCActions(getAPI(), rex.NewDefundCPULoan(
account,
Expand Down
2 changes: 1 addition & 1 deletion eosc/cmd/rexDefundNET.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var rexDefundNet = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
account := toAccount(args[0], "account")
loanNumber := toUint64(args[1], "loan number")
quantity := toEOSAsset(args[2], "quantity")
quantity := toCoreAsset(args[2], "quantity")

pushEOSCActions(getAPI(), rex.NewDefundNetLoan(
account,
Expand Down
2 changes: 1 addition & 1 deletion eosc/cmd/rexDeposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var rexDeposit = &cobra.Command{
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
account := toAccount(args[0], "account")
quantity := toEOSAsset(args[1], "quantity")
quantity := toCoreAsset(args[1], "quantity")

pushEOSCActions(getAPI(), rex.NewDeposit(
account,
Expand Down
2 changes: 1 addition & 1 deletion eosc/cmd/rexFundCPU.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var rexFundCPU = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
account := toAccount(args[0], "account")
loanNumber := toUint64(args[1], "loan number")
quantity := toEOSAsset(args[2], "quantity")
quantity := toCoreAsset(args[2], "quantity")

pushEOSCActions(getAPI(), rex.NewFundCPULoan(
account,
Expand Down
2 changes: 1 addition & 1 deletion eosc/cmd/rexFundNet.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var rexFundNet = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
account := toAccount(args[0], "account")
loanNumber := toUint64(args[1], "loan number")
quantity := toEOSAsset(args[2], "quantity")
quantity := toCoreAsset(args[2], "quantity")

pushEOSCActions(getAPI(), rex.NewFundNetLoan(
account,
Expand Down
4 changes: 2 additions & 2 deletions eosc/cmd/rexRentCPU.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ var rexRentCPU = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
payer := toAccount(args[0], "payer")
receiver := toAccount(args[1], "receiver")
quantity := toEOSAsset(args[2], "quantity")
loanFund := toEOSAsset(args[3], "loan fund")
quantity := toCoreAsset(args[2], "quantity")
loanFund := toCoreAsset(args[3], "loan fund")

pushEOSCActions(getAPI(), rex.NewRentCPU(
payer,
Expand Down
4 changes: 2 additions & 2 deletions eosc/cmd/rexRentNet.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ var rexRentNet = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
payer := toAccount(args[0], "payer")
receiver := toAccount(args[1], "receiver")
quantity := toEOSAsset(args[2], "quantity")
loanFund := toEOSAsset(args[3], "loan fund")
quantity := toCoreAsset(args[2], "quantity")
loanFund := toCoreAsset(args[3], "loan fund")

pushEOSCActions(getAPI(), rex.NewRentNet(
payer,
Expand Down
4 changes: 2 additions & 2 deletions eosc/cmd/rexUnstakeTo.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ var rexUnstakeTo = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
staker := toAccount(args[0], "staker")
stakedTo := toAccount(args[1], "staked to")
net := toEOSAsset(args[2], "net")
cpu := toEOSAsset(args[3], "cpu")
net := toCoreAsset(args[2], "net")
cpu := toCoreAsset(args[3], "cpu")

pushEOSCActions(getAPI(), rex.NewUnstakeToREX(
staker,
Expand Down
2 changes: 1 addition & 1 deletion eosc/cmd/rexWithdraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var rexWithdraw = &cobra.Command{
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
account := toAccount(args[0], "account")
quantity := toEOSAsset(args[1], "quantity")
quantity := toCoreAsset(args[1], "quantity")

pushEOSCActions(getAPI(), rex.NewWithdraw(
account,
Expand Down
10 changes: 10 additions & 0 deletions eosc/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"os"
"strings"

"go.uber.org/zap"

"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
Expand Down Expand Up @@ -41,6 +43,7 @@ func Execute() {
func init() {
cobra.OnInitialize(initConfig)

RootCmd.PersistentFlags().StringP("core-symbol", "c", "", "Core symbol to use for all commands (default inferred from API if possible, 4,EOS otherwise)")
RootCmd.PersistentFlags().BoolP("debug", "", false, "Enables verbose API debug messages")
RootCmd.PersistentFlags().StringP("vault-file", "", "./eosc-vault.json", "Wallet file that contains encrypted key material")
RootCmd.PersistentFlags().StringSliceP("wallet-url", "", []string{}, "Base URL to wallet endpoint. You can pass this multiple times to use the multi-signer (will use each wallet to sign multi-sig transactions).")
Expand All @@ -65,6 +68,13 @@ func initConfig() {
viper.SetEnvKeyReplacer(replacer)

recurseViperCommands(RootCmd, nil)

if viper.GetBool("global-debug") {
zlog, err := zap.NewDevelopment()
if err == nil {
SetLogger(zlog)
}
}
}

func recurseViperCommands(root *cobra.Command, segments []string) {
Expand Down
3 changes: 1 addition & 2 deletions eosc/cmd/systemBidname.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ Read https://steemit.com/eos/@eos-canada/everything-you-need-to-know-about-names

bidder := toAccount(args[0], "bidder_account_name")
newname := toAccount(args[1], "premium_account_name")
bidAsset, err := NewAssetDefaultEOS(args[2])
errorCheck("bid amount invalid", err)
bidAsset := toCoreAsset(args[2], "bid quantity")

fmt.Printf("[%s] bidding for: %s , amount=%d precision=%d symbol=%s\n", bidder, newname, bidAsset.Amount, bidAsset.Symbol.Precision, bidAsset.Symbol.Symbol)

Expand Down
6 changes: 2 additions & 4 deletions eosc/cmd/systemDelegateBW.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,8 @@ Alternatively, you can use the simplified:
Run: func(cmd *cobra.Command, args []string) {
from := toAccount(args[0], "from")
receiver := toAccount(args[1], "receiver")
netStake, err := NewAssetDefaultEOS(args[2])
errorCheck(`"network bw stake qty" invalid`, err)
cpuStake, err := NewAssetDefaultEOS(args[3])
errorCheck(`"cpu bw stake qty" invalid`, err)
netStake := toCoreAsset(args[2], "network bw stake qty")
cpuStake := toCoreAsset(args[3], "cpu bw stake qty")
transfer := viper.GetBool("system-delegatebw-cmd-transfer")

api := getAPI()
Expand Down
9 changes: 3 additions & 6 deletions eosc/cmd/systemNewaccount.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,8 @@ active:
errorCheck("missing argument", fmt.Errorf("--stake-net missing"))
}

cpuStake, err := NewAssetDefaultEOS(cpuStakeStr)
errorCheck("--stake-cpu invalid", err)
netStake, err := NewAssetDefaultEOS(netStakeStr)
errorCheck("--stake-net invalid", err)
cpuStake := toCoreAsset(cpuStakeStr, "--stake-cpu")
netStake := toCoreAsset(netStakeStr, "--stake-net")

doTransfer := viper.GetBool("system-newaccount-cmd-transfer")
if cpuStake.Amount != 0 || netStake.Amount != 0 {
Expand All @@ -118,8 +116,7 @@ active:

buyRAM := viper.GetString("system-newaccount-cmd-buy-ram")
if buyRAM != "" {
buyRAMAmount, err := NewAssetDefaultEOS(buyRAM)
errorCheck("--buy-ram invalid", err)
buyRAMAmount := toCoreAsset(buyRAM, "--buy-ram")

actions = append(actions, system.NewBuyRAM(creator, newAccount, uint64(buyRAMAmount.Amount)))
} else {
Expand Down
10 changes: 3 additions & 7 deletions eosc/cmd/systemUndelegateBW.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,10 @@ See also: the "system delegatebw" command.
Run: func(cmd *cobra.Command, args []string) {
from := toAccount(args[0], "from")
receiver := toAccount(args[1], "receiver")
netStake, err := NewAssetDefaultEOS(args[2])
errorCheck(`"network bw unstake qty" invalid`, err)
cpuStake, err := NewAssetDefaultEOS(args[3])
errorCheck(`"cpu bw unstake qty" invalid`, err)
netStake := toCoreAsset(args[2], "network bw unstake qty")
cpuStake := toCoreAsset(args[3], "cpu bw unstake qty")

api := getAPI()

pushEOSCActions(api, system.NewUndelegateBW(from, receiver, cpuStake, netStake))
pushEOSCActions(getAPI(), system.NewUndelegateBW(from, receiver, cpuStake, netStake))
},
}

Expand Down
3 changes: 1 addition & 2 deletions eosc/cmd/toolsSellAccount.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ MAKE SURE TO INSPECT THE GENERATED MULTISIG TRANSACTION BEFORE APPROVING IT.
soldAccount := toAccount(args[0], "sold account")
buyerAccount := toAccount(args[1], "buyer account")
beneficiaryAccount := toAccount(args[2], "beneficiary account")
saleAmount, err := NewAssetDefaultEOS(args[3])
errorCheck(`sale "amount" invalid`, err)
saleAmount := toCoreAsset(args[3], "amount")
proposalName := viper.GetString("tools-sell-account-cmd-proposal-name")
memo := viper.GetString("tools-sell-account-cmd-memo")

Expand Down
8 changes: 3 additions & 5 deletions eosc/cmd/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@ var transferCmd = &cobra.Command{

from := toAccount(args[0], "from")
to := toAccount(args[1], "to")
quantity, err := NewAssetDefaultEOS(args[2])
errorCheck("invalid amount", err)
quantity := toAssetWithDefaultCoreSymbol(args[2], "quantity")
memo := viper.GetString("transfer-cmd-memo")

api := getAPI()

action := token.NewTransfer(from, to, quantity, memo)
action.Account = contract
pushEOSCActions(api, action)

pushEOSCActions(getAPI(), action)
},
}

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/abourget/llerrgroup v0.0.0-20161118145731-75f536392d17
github.com/bronze1man/go-yaml2json v0.0.0-20150129175009-f6f64b738964
github.com/davecgh/go-spew v1.1.1
github.com/eoscanada/eos-go v0.8.13
github.com/eoscanada/eos-go v0.8.14-0.20190614154328-0014a42badb5
github.com/golang/protobuf v1.3.1 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983 // indirect
Expand All @@ -25,7 +25,7 @@ require (
github.com/tidwall/sjson v1.0.0
go.uber.org/atomic v1.3.2 // indirect
go.uber.org/multierr v1.1.0 // indirect
go.uber.org/zap v1.9.1 // indirect
go.uber.org/zap v1.9.1
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e // indirect
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ github.com/eoscanada/eos-bios v1.2.0 h1:h2PC3rbOCvPVkq6+RapwUGKn0wZ41ScJmHHTwdDK
github.com/eoscanada/eos-bios v1.2.0/go.mod h1:64+2vEnagr6kY1QgIexkeOXPEXn4yeLDiluCzQ2B9dY=
github.com/eoscanada/eos-go v0.8.13 h1:2U6a+cj+VygmcrKP8Y2op1qukynXUTfhyhKrysjPmsY=
github.com/eoscanada/eos-go v0.8.13/go.mod h1:RKrm2XzZEZWxSMTRqH5QOyJ1fb/qKEjs2ix1aQl0sk4=
github.com/eoscanada/eos-go v0.8.14-0.20190614154328-0014a42badb5 h1:6Y6xlTLOaY7Uzb/aarC4hpqkztamhpyX8ELGXFRre00=
github.com/eoscanada/eos-go v0.8.14-0.20190614154328-0014a42badb5/go.mod h1:RKrm2XzZEZWxSMTRqH5QOyJ1fb/qKEjs2ix1aQl0sk4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
Expand Down

0 comments on commit 1a909be

Please sign in to comment.