lotus/chain/types/fil.go
Andrew Jackson (Ajax) fd7f1a95e2
feat: curio: web based config edit (#11822)
* cfg edit 1

* jsonschema deps

* feat: lp mig - first few steps

* lp mig: default tasks

* code comments

* docs

* lp-mig-progress

* shared

* comments and todos

* fix: curio: rename lotus-provider to curio (#11645)

* rename provider to curio

* install gotext

* fix lint errors, mod tidy

* fix typo

* fix API_INFO and add gotext to circleCI

* add back gotext

* add gotext after remerge

* lp: channels doc

* finish easy-migration TODOs

* out generate

* merging and more renames

* avoid make-all

* minor doc stuff

* cu: make gen

* make gen fix

* make gen

* tryfix

* go mod tidy

* minor ez migration fixes

* ez setup - ui cleanups

* better error message

* guided setup colors

* better path to saveconfigtolayer

* loadconfigwithupgrades fix

* readMiner oops

* guided - homedir

* err if miner is running

* prompt error should exit

* process already running, miner_id sectors in migration

* dont prompt for language a second time

* check miner stopped

* unlock repo

* render and sql oops

* curio easyMig - some fixes

* easyMigration runs successfully

* lint

* part 2 of last

* message

* merge addtl

* fixing guided setup for myself

* warn-on-no-post

* EditorLoads

* cleanups and styles

* create info

* fix tests

* make gen

* change layout, add help button

* Duration custom json

* mjs naming

---------

Co-authored-by: LexLuthr <88259624+LexLuthr@users.noreply.github.com>
Co-authored-by: LexLuthr <lexluthr@protocol.ai>
Co-authored-by: LexLuthr <lexluthr@curiostorage.org>
2024-04-16 09:30:27 -05:00

152 lines
2.9 KiB
Go

package types
import (
"encoding"
"fmt"
"math/big"
"strings"
"github.com/invopop/jsonschema"
"github.com/filecoin-project/lotus/build"
)
type FIL BigInt
func (f FIL) String() string {
if f.Int == nil {
return "0 FIL"
}
return f.Unitless() + " FIL"
}
func (f FIL) Unitless() string {
r := new(big.Rat).SetFrac(f.Int, big.NewInt(int64(build.FilecoinPrecision)))
if r.Sign() == 0 {
return "0"
}
return strings.TrimRight(strings.TrimRight(r.FloatString(18), "0"), ".")
}
var AttoFil = NewInt(1)
var FemtoFil = BigMul(AttoFil, NewInt(1000))
var PicoFil = BigMul(FemtoFil, NewInt(1000))
var NanoFil = BigMul(PicoFil, NewInt(1000))
var unitPrefixes = []string{"a", "f", "p", "n", "μ", "m"}
func (f FIL) Short() string {
n := BigInt(f).Abs()
dn := uint64(1)
var prefix string
for _, p := range unitPrefixes {
if n.LessThan(NewInt(dn * 1000)) {
prefix = p
break
}
dn *= 1000
}
r := new(big.Rat).SetFrac(f.Int, big.NewInt(int64(dn)))
if r.Sign() == 0 {
return "0"
}
return strings.TrimRight(strings.TrimRight(r.FloatString(3), "0"), ".") + " " + prefix + "FIL"
}
func (f FIL) Nano() string {
r := new(big.Rat).SetFrac(f.Int, big.NewInt(int64(1e9)))
if r.Sign() == 0 {
return "0"
}
return strings.TrimRight(strings.TrimRight(r.FloatString(9), "0"), ".") + " nFIL"
}
func (f FIL) Format(s fmt.State, ch rune) {
switch ch {
case 's', 'v':
fmt.Fprint(s, f.String())
default:
f.Int.Format(s, ch)
}
}
func (f FIL) MarshalText() (text []byte, err error) {
return []byte(f.String()), nil
}
func (f FIL) UnmarshalText(text []byte) error {
if f.Int == nil {
return fmt.Errorf("cannot unmarshal into nil BigInt (text:%s)", string(text))
}
p, err := ParseFIL(string(text))
if err != nil {
return err
}
f.Int.Set(p.Int)
return nil
}
func ParseFIL(s string) (FIL, error) {
suffix := strings.TrimLeft(s, "-.1234567890")
s = s[:len(s)-len(suffix)]
var attofil bool
if suffix != "" {
norm := strings.ToLower(strings.TrimSpace(suffix))
switch norm {
case "", "fil":
case "attofil", "afil":
attofil = true
default:
return FIL{}, fmt.Errorf("unrecognized suffix: %q", suffix)
}
}
if len(s) > 50 {
return FIL{}, fmt.Errorf("string length too large: %d", len(s))
}
r, ok := new(big.Rat).SetString(s) //nolint:gosec
if !ok {
return FIL{}, fmt.Errorf("failed to parse %q as a decimal number", s)
}
if !attofil {
r = r.Mul(r, big.NewRat(int64(build.FilecoinPrecision), 1))
}
if !r.IsInt() {
var pref string
if attofil {
pref = "atto"
}
return FIL{}, fmt.Errorf("invalid %sFIL value: %q", pref, s)
}
return FIL{r.Num()}, nil
}
func MustParseFIL(s string) FIL {
n, err := ParseFIL(s)
if err != nil {
panic(err)
}
return n
}
func (f FIL) JSONSchema() *jsonschema.Schema {
return &jsonschema.Schema{
Type: "string",
Pattern: `^((\d+(\.\d+)?|0x[0-9a-fA-F]+))( ([aA]([tT][tT][oO])?)?[fF][iI][lL])?$`,
}
}
var _ encoding.TextMarshaler = (*FIL)(nil)
var _ encoding.TextUnmarshaler = (*FIL)(nil)