diff --git a/internal/cli/commands.go b/internal/cli/commands.go index 2a040cb..2f9384a 100644 --- a/internal/cli/commands.go +++ b/internal/cli/commands.go @@ -956,59 +956,85 @@ func (c *RcLimitCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) // If no limit given, display current if c.limit == nil { if ee.rcLimit.absolute { - result.AddMessage(fmt.Sprintf("Current rc limit: %f", ee.rcLimit.value)) + decAmount, err := util.SatoshiToDecimal(ee.rcLimit.value, cliutil.KoinPrecision) + if err != nil { + return nil, err + } + result.AddMessage(fmt.Sprintf("Current rc limit: %v", decAmount)) return result, nil } // Otherwise its relative if !ee.IsOnline() || !ee.IsWalletOpen() { - result.AddMessage(fmt.Sprintf("Current rc limit: %f%%", ee.rcLimit.value*100)) + decAmount, err := util.SatoshiToDecimal(ee.rcLimit.value, cliutil.KoinPrecision) + resultVal := decimal.NewFromFloat(100).Mul(*decAmount) + if err != nil { + return nil, err + } + result.AddMessage(fmt.Sprintf("Current rc limit: %v%%", resultVal)) return result, nil } - limit, err := ee.RPCClient.GetAccountRc(ctx, ee.Key.AddressBytes()) + amount, err := ee.GetRcLimit(ctx) + if err != nil { + return nil, err + } + + decAmount, err := util.SatoshiToDecimal(amount, cliutil.KoinPrecision) if err != nil { return nil, err } - dAmount, err := util.SatoshiToDecimal(limit, cliutil.KoinPrecision) + decLimit, err := util.SatoshiToDecimal(ee.rcLimit.value, cliutil.KoinPrecision) if err != nil { return nil, err } - f, _ := dAmount.Mul(decimal.NewFromFloat(ee.rcLimit.value)).Float64() - result.AddMessage(fmt.Sprintf("Current rc limit: %f%% (%f)", ee.rcLimit.value*100, f)) + result.AddMessage(fmt.Sprintf("Current rc limit: %v%% (%v)", decLimit.Mul(decimal.NewFromInt(100)), decAmount)) return result, nil } // Otherwise we are setting the limit s := *c.limit if s[len(s)-1] == '%' { - res, err := strconv.ParseFloat(s[:len(s)-1], 64) + res, err := decimal.NewFromString(s[:len(s)-1]) if err != nil { return nil, err } // Check bounds - if res < 0 || res > 100 { + if res.LessThan(decimal.NewFromInt(0)) || res.GreaterThan(decimal.NewFromInt(100)) { return nil, fmt.Errorf("%w: percentage rc limit must be between 0%% and 100%%", cliutil.ErrInvalidParam) } - ee.rcLimit.value = res / 100.0 + // Convert to decimal + resFrac := res.Div(decimal.NewFromInt(100)) + val, err := util.DecimalToSatoshi(&resFrac, cliutil.KoinPrecision) + if err != nil { + return nil, err + } + + ee.rcLimit.value = val ee.rcLimit.absolute = false - result.AddMessage(fmt.Sprintf("Set rc limit to %f%%", res)) + result.AddMessage(fmt.Sprintf("Set rc limit to %v%%", res)) return result, nil } // Otherwise we are setting the absolute limit - res, err := strconv.ParseFloat(s, 64) + res, err := decimal.NewFromString(s) + if err != nil { + return nil, err + } + + // Convert to satoshi + val, err := util.DecimalToSatoshi(&res, cliutil.KoinPrecision) if err != nil { return nil, err } - ee.rcLimit.value = res + ee.rcLimit.value = val ee.rcLimit.absolute = true - result.AddMessage(fmt.Sprintf("Set rc limit to %f", res)) + result.AddMessage(fmt.Sprintf("Set rc limit to %v", res)) return result, nil } diff --git a/internal/cli/interpreter.go b/internal/cli/interpreter.go index 2e18699..992b932 100644 --- a/internal/cli/interpreter.go +++ b/internal/cli/interpreter.go @@ -12,7 +12,6 @@ import ( "github.com/koinos/koinos-cli/internal/cliutil" "github.com/koinos/koinos-proto-golang/koinos/protocol" util "github.com/koinos/koinos-util-golang" - "github.com/shopspring/decimal" ) // Command execution code @@ -55,7 +54,7 @@ func (er *ExecutionResult) Print() { } type rcInfo struct { - value float64 + value uint64 absolute bool } @@ -86,7 +85,7 @@ func NewExecutionEnvironment(rpcClient *cliutil.KoinosRPCClient, parser *Command Contracts: make(map[string]*ContractInfo), Session: &TransactionSession{}, nonceMap: make(map[string]*nonceInfo), - rcLimit: rcInfo{value: 1.0, absolute: false}, + rcLimit: rcInfo{value: 100000000, absolute: false}, payer: SelfPayer, chainID: AutoChainID, nonceMode: AutoNonce, @@ -184,14 +183,7 @@ func (ee *ExecutionEnvironment) GetChainID(ctx context.Context) ([]byte, error) // GetRcLimit returns the current RC limit func (ee *ExecutionEnvironment) GetRcLimit(ctx context.Context) (uint64, error) { if ee.rcLimit.absolute { - dAmount := decimal.NewFromFloat(ee.rcLimit.value) - - val, err := util.DecimalToSatoshi(&dAmount, cliutil.KoinPrecision) - if err != nil { - return 0, fmt.Errorf("%w: %s", cliutil.ErrInvalidAmount, err.Error()) - } - - return val, nil + return ee.rcLimit.value, nil } // else it's relative @@ -200,8 +192,23 @@ func (ee *ExecutionEnvironment) GetRcLimit(ctx context.Context) (uint64, error) return 0, err } - val := uint64(float64(limit) * ee.rcLimit.value) - return val, nil + decLimit, err := util.SatoshiToDecimal(limit, 8) + if err != nil { + return 0, err + } + + decVal, err := util.SatoshiToDecimal(ee.rcLimit.value, 8) + if err != nil { + return 0, err + } + + decResult := decLimit.Mul(*decVal) + res, err := util.DecimalToSatoshi(&decResult, 8) + if err != nil { + return 0, err + } + + return res, nil } // SubmitTransaction is a utility function to submit a transaction from a command