diff options
author | Felix Lange <fjl@users.noreply.github.com> | 2017-02-27 05:21:51 +0800 |
---|---|---|
committer | Jeffrey Wilcke <jeffrey@ethereum.org> | 2017-02-27 05:21:51 +0800 |
commit | 5c8fe28b725bd9b128edceae3215132ea741641b (patch) | |
tree | 4bcbfeb1a21536edbba06d1715752999faa7f085 /cmd | |
parent | 50ee279f2585e9e2eee30f0e1d4a3bf5f781bd72 (diff) | |
download | go-tangerine-5c8fe28b725bd9b128edceae3215132ea741641b.tar go-tangerine-5c8fe28b725bd9b128edceae3215132ea741641b.tar.gz go-tangerine-5c8fe28b725bd9b128edceae3215132ea741641b.tar.bz2 go-tangerine-5c8fe28b725bd9b128edceae3215132ea741641b.tar.lz go-tangerine-5c8fe28b725bd9b128edceae3215132ea741641b.tar.xz go-tangerine-5c8fe28b725bd9b128edceae3215132ea741641b.tar.zst go-tangerine-5c8fe28b725bd9b128edceae3215132ea741641b.zip |
common: move big integer math to common/math (#3699)
* common: remove CurrencyToString
Move denomination values to params instead.
* common: delete dead code
* common: move big integer operations to common/math
This commit consolidates all big integer operations into common/math and
adds tests and documentation.
There should be no change in semantics for BigPow, BigMin, BigMax, S256,
U256, Exp and their behaviour is now locked in by tests.
The BigD, BytesToBig and Bytes2Big functions don't provide additional
value, all uses are replaced by new(big.Int).SetBytes().
BigToBytes is now called PaddedBigBytes, its minimum output size
parameter is now specified as the number of bytes instead of bits. The
single use of this function is in the EVM's MSTORE instruction.
Big and String2Big are replaced by ParseBig, which is slightly stricter.
It previously accepted leading zeros for hexadecimal inputs but treated
decimal inputs as octal if a leading zero digit was present.
ParseUint64 is used in places where String2Big was used to decode a
uint64.
The new functions MustParseBig and MustParseUint64 are now used in many
places where parsing errors were previously ignored.
* common: delete unused big integer variables
* accounts/abi: replace uses of BytesToBig with use of encoding/binary
* common: remove BytesToBig
* common: remove Bytes2Big
* common: remove BigTrue
* cmd/utils: add BigFlag and use it for error-checked integer flags
While here, remove environment variable processing for DirectoryFlag
because we don't use it.
* core: add missing error checks in genesis block parser
* common: remove String2Big
* cmd/evm: use utils.BigFlag
* common/math: check for 256 bit overflow in ParseBig
This is supposed to prevent silent overflow/truncation of values in the
genesis block JSON. Without this check, a genesis block that set a
balance larger than 256 bits would lead to weird behaviour in the VM.
* cmd/utils: fixup import
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/evm/main.go | 25 | ||||
-rw-r--r-- | cmd/utils/cmd.go | 15 | ||||
-rw-r--r-- | cmd/utils/customflags.go | 86 | ||||
-rw-r--r-- | cmd/utils/flags.go | 24 |
4 files changed, 88 insertions, 62 deletions
diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 86e2493ca..a489efbfc 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -20,6 +20,7 @@ package main import ( "fmt" "io/ioutil" + "math/big" "os" goruntime "runtime" "time" @@ -51,20 +52,20 @@ var ( Name: "codefile", Usage: "file containing EVM code", } - GasFlag = cli.StringFlag{ + GasFlag = cli.Uint64Flag{ Name: "gas", Usage: "gas limit for the evm", - Value: "10000000000", + Value: 10000000000, } - PriceFlag = cli.StringFlag{ + PriceFlag = utils.BigFlag{ Name: "price", Usage: "price set for the evm", - Value: "0", + Value: new(big.Int), } - ValueFlag = cli.StringFlag{ + ValueFlag = utils.BigFlag{ Name: "value", Usage: "value set for the evm", - Value: "0", + Value: new(big.Int), } DumpFlag = cli.BoolFlag{ Name: "dump", @@ -160,9 +161,9 @@ func run(ctx *cli.Context) error { ret, _, err = runtime.Create(input, &runtime.Config{ Origin: sender.Address(), State: statedb, - GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)).Uint64(), - GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)), - Value: common.Big(ctx.GlobalString(ValueFlag.Name)), + GasLimit: ctx.GlobalUint64(GasFlag.Name), + GasPrice: utils.GlobalBig(ctx, PriceFlag.Name), + Value: utils.GlobalBig(ctx, ValueFlag.Name), EVMConfig: vm.Config{ Tracer: logger, Debug: ctx.GlobalBool(DebugFlag.Name), @@ -177,9 +178,9 @@ func run(ctx *cli.Context) error { ret, err = runtime.Call(receiverAddress, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtime.Config{ Origin: sender.Address(), State: statedb, - GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)).Uint64(), - GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)), - Value: common.Big(ctx.GlobalString(ValueFlag.Name)), + GasLimit: ctx.GlobalUint64(GasFlag.Name), + GasPrice: utils.GlobalBig(ctx, PriceFlag.Name), + Value: utils.GlobalBig(ctx, ValueFlag.Name), EVMConfig: vm.Config{ Tracer: logger, Debug: ctx.GlobalBool(DebugFlag.Name), diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 062b9c50d..843cb5b4e 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -23,11 +23,9 @@ import ( "io" "os" "os/signal" - "regexp" "runtime" "strings" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/internal/debug" @@ -82,19 +80,6 @@ func StartNode(stack *node.Node) { }() } -func FormatTransactionData(data string) []byte { - d := common.StringToByteFunc(data, func(s string) (ret []byte) { - slice := regexp.MustCompile(`\n|\s`).Split(s, 1000000000) - for _, dataItem := range slice { - d := common.FormatData(dataItem) - ret = append(ret, d...) - } - return - }) - - return d -} - func ImportChain(chain *core.BlockChain, fn string) error { // Watch for Ctrl-C while the import is running. // If a signal is received, the import will stop at the next batch. diff --git a/cmd/utils/customflags.go b/cmd/utils/customflags.go index 52cd7b8c7..00f28f2ec 100644 --- a/cmd/utils/customflags.go +++ b/cmd/utils/customflags.go @@ -17,12 +17,17 @@ package utils import ( + "errors" "flag" "fmt" + "math/big" "os" "os/user" "path" "strings" + + "github.com/ethereum/go-ethereum/common/math" + "gopkg.in/urfave/cli.v1" ) // Custom type which is registered in the flags library which cli uses for @@ -44,10 +49,9 @@ func (self *DirectoryString) Set(value string) error { // Custom cli.Flag type which expand the received string to an absolute path. // e.g. ~/.ethereum -> /home/username/.ethereum type DirectoryFlag struct { - Name string - Value DirectoryString - Usage string - EnvVar string + Name string + Value DirectoryString + Usage string } func (self DirectoryFlag) String() string { @@ -55,7 +59,7 @@ func (self DirectoryFlag) String() string { if len(self.Value.Value) > 0 { fmtString = "%s \"%v\"\t%v" } - return withEnvHint(self.EnvVar, fmt.Sprintf(fmtString, prefixedNames(self.Name), self.Value.Value, self.Usage)) + return fmt.Sprintf(fmtString, prefixedNames(self.Name), self.Value.Value, self.Usage) } func eachName(longName string, fn func(string)) { @@ -69,21 +73,65 @@ func eachName(longName string, fn func(string)) { // called by cli library, grabs variable from environment (if in env) // and adds variable to flag set for parsing. func (self DirectoryFlag) Apply(set *flag.FlagSet) { - if self.EnvVar != "" { - for _, envVar := range strings.Split(self.EnvVar, ",") { - envVar = strings.TrimSpace(envVar) - if envVal := os.Getenv(envVar); envVal != "" { - self.Value.Value = envVal - break - } - } - } - eachName(self.Name, func(name string) { set.Var(&self.Value, self.Name, self.Usage) }) } +// BigFlag is a command line flag that accepts 256 bit big integers in decimal or +// hexadecimal syntax. +type BigFlag struct { + Name string + Value *big.Int + Usage string +} + +// bigValue turns *big.Int into a flag.Value +type bigValue big.Int + +func (b *bigValue) String() string { + if b == nil { + return "" + } + return (*big.Int)(b).String() +} + +func (b *bigValue) Set(s string) error { + int, ok := math.ParseBig256(s) + if !ok { + return errors.New("invalid integer syntax") + } + *b = (bigValue)(*int) + return nil +} + +func (f BigFlag) GetName() string { + return f.Name +} + +func (f BigFlag) String() string { + fmtString := "%s %v\t%v" + if f.Value != nil { + fmtString = "%s \"%v\"\t%v" + } + return fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage) +} + +func (f BigFlag) Apply(set *flag.FlagSet) { + eachName(f.Name, func(name string) { + set.Var((*bigValue)(f.Value), f.Name, f.Usage) + }) +} + +// GlobalBig returns the value of a BigFlag from the global flag set. +func GlobalBig(ctx *cli.Context, name string) *big.Int { + val := ctx.GlobalGeneric(name) + if val == nil { + return nil + } + return (*big.Int)(val.(*bigValue)) +} + func prefixFor(name string) (prefix string) { if len(name) == 1 { prefix = "-" @@ -106,14 +154,6 @@ func prefixedNames(fullName string) (prefixed string) { return } -func withEnvHint(envVar, str string) string { - envText := "" - if envVar != "" { - envText = fmt.Sprintf(" [$%s]", strings.Join(strings.Split(envVar, ","), ", $")) - } - return str + envText -} - func (self DirectoryFlag) GetName() string { return self.Name } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index a2e4ac814..25c3a1ada 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -179,10 +179,10 @@ var ( Usage: "Number of CPU threads to use for mining", Value: runtime.NumCPU(), } - TargetGasLimitFlag = cli.StringFlag{ + TargetGasLimitFlag = cli.Uint64Flag{ Name: "targetgaslimit", Usage: "Target gas limit sets the artificial target gas floor for the blocks to mine", - Value: params.GenesisGasLimit.String(), + Value: params.GenesisGasLimit.Uint64(), } AutoDAGFlag = cli.BoolFlag{ Name: "autodag", @@ -193,10 +193,10 @@ var ( Usage: "Public address for block mining rewards (default = first account created)", Value: "0", } - GasPriceFlag = cli.StringFlag{ + GasPriceFlag = BigFlag{ Name: "gasprice", Usage: "Minimal gas price to accept for mining a transactions", - Value: new(big.Int).Mul(big.NewInt(20), common.Shannon).String(), + Value: big.NewInt(20 * params.Shannon), } ExtraDataFlag = cli.StringFlag{ Name: "extradata", @@ -382,15 +382,15 @@ var ( } // Gas price oracle settings - GpoMinGasPriceFlag = cli.StringFlag{ + GpoMinGasPriceFlag = BigFlag{ Name: "gpomin", Usage: "Minimum suggested gas price", - Value: new(big.Int).Mul(big.NewInt(20), common.Shannon).String(), + Value: big.NewInt(20 * params.Shannon), } - GpoMaxGasPriceFlag = cli.StringFlag{ + GpoMaxGasPriceFlag = BigFlag{ Name: "gpomax", Usage: "Maximum suggested gas price", - Value: new(big.Int).Mul(big.NewInt(500), common.Shannon).String(), + Value: big.NewInt(500 * params.Shannon), } GpoFullBlockRatioFlag = cli.IntFlag{ Name: "gpofull", @@ -741,9 +741,9 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) { MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name), ExtraData: MakeMinerExtra(extra, ctx), DocRoot: ctx.GlobalString(DocRootFlag.Name), - GasPrice: common.String2Big(ctx.GlobalString(GasPriceFlag.Name)), - GpoMinGasPrice: common.String2Big(ctx.GlobalString(GpoMinGasPriceFlag.Name)), - GpoMaxGasPrice: common.String2Big(ctx.GlobalString(GpoMaxGasPriceFlag.Name)), + GasPrice: GlobalBig(ctx, GasPriceFlag.Name), + GpoMinGasPrice: GlobalBig(ctx, GpoMinGasPriceFlag.Name), + GpoMaxGasPrice: GlobalBig(ctx, GpoMaxGasPriceFlag.Name), GpoFullBlockRatio: ctx.GlobalInt(GpoFullBlockRatioFlag.Name), GpobaseStepDown: ctx.GlobalInt(GpobaseStepDownFlag.Name), GpobaseStepUp: ctx.GlobalInt(GpobaseStepUpFlag.Name), @@ -819,7 +819,7 @@ func RegisterEthStatsService(stack *node.Node, url string) { // SetupNetwork configures the system for either the main net or some test network. func SetupNetwork(ctx *cli.Context) { - params.TargetGasLimit = common.String2Big(ctx.GlobalString(TargetGasLimitFlag.Name)) + params.TargetGasLimit = new(big.Int).SetUint64(ctx.GlobalUint64(TargetGasLimitFlag.Name)) } // MakeChainConfig reads the chain configuration from the database in ctx.Datadir. |