diff --git a/common/big.go b/common/big.go index 8fe9d8bef5..e8057acf6b 100644 --- a/common/big.go +++ b/common/big.go @@ -2,6 +2,19 @@ package common import "math/big" +// Common big integers often used +var ( + Big1 = big.NewInt(1) + Big2 = big.NewInt(2) + Big3 = big.NewInt(3) + Big0 = big.NewInt(0) + BigTrue = Big1 + BigFalse = Big0 + Big32 = big.NewInt(32) + Big256 = big.NewInt(0xff) + Big257 = big.NewInt(257) +) + // Big pow // // Returns the power of two big integers diff --git a/common/bytes.go b/common/bytes.go index 5e553d23cf..2d885ac746 100644 --- a/common/bytes.go +++ b/common/bytes.go @@ -9,6 +9,28 @@ import ( "strings" ) +func ToHex(b []byte) string { + hex := Bytes2Hex(b) + // Prefer output of "0x0" instead of "0x" + if len(hex) == 0 { + hex = "0" + } + return "0x" + hex +} + +func FromHex(s string) []byte { + if len(s) > 1 { + if s[0:2] == "0x" { + s = s[2:] + } + if len(s)%2 == 1 { + s = "0" + s + } + return Hex2Bytes(s) + } + return nil +} + type Bytes []byte func (self Bytes) String() string { diff --git a/common/bytes_test.go b/common/bytes_test.go index ec106bf4bd..4b00aa49b5 100644 --- a/common/bytes_test.go +++ b/common/bytes_test.go @@ -1,6 +1,9 @@ package common import ( + "bytes" + "testing" + checker "gopkg.in/check.v1" ) @@ -191,3 +194,21 @@ func (s *BytesSuite) TestRightPadString(c *checker.C) { c.Assert(resstd, checker.Equals, exp) c.Assert(resshrt, checker.Equals, val) } + +func TestFromHex(t *testing.T) { + input := "0x01" + expected := []byte{1} + result := FromHex(input) + if bytes.Compare(expected, result) != 0 { + t.Errorf("Expected % x got % x", expected, result) + } +} + +func TestFromHexOddLength(t *testing.T) { + input := "0x1" + expected := []byte{1} + result := FromHex(input) + if bytes.Compare(expected, result) != 0 { + t.Errorf("Expected % x got % x", expected, result) + } +} diff --git a/common/common.go b/common/common.go deleted file mode 100644 index 155bb5c2a7..0000000000 --- a/common/common.go +++ /dev/null @@ -1,174 +0,0 @@ -package common - -import ( - "fmt" - "math/big" - "os" - "os/user" - "path" - "path/filepath" - "runtime" - "time" - - "github.com/kardianos/osext" -) - -// MakeName creates a node name that follows the ethereum convention -// for such names. It adds the operation system name and Go runtime version -// the name. -func MakeName(name, version string) string { - return fmt.Sprintf("%s/v%s/%s/%s", name, version, runtime.GOOS, runtime.Version()) -} - -func DefaultAssetPath() string { - var assetPath string - pwd, _ := os.Getwd() - srcdir := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist") - - // If the current working directory is the go-ethereum dir - // assume a debug build and use the source directory as - // asset directory. - if pwd == srcdir { - assetPath = path.Join(pwd, "assets") - } else { - switch runtime.GOOS { - case "darwin": - // Get Binary Directory - exedir, _ := osext.ExecutableFolder() - assetPath = filepath.Join(exedir, "../Resources") - case "linux": - assetPath = "/usr/share/mist" - case "windows": - assetPath = "./assets" - default: - assetPath = "." - } - } - - // Check if the assetPath exists. If not, try the source directory - // This happens when binary is run from outside cmd/mist directory - if _, err := os.Stat(assetPath); os.IsNotExist(err) { - assetPath = path.Join(srcdir, "assets") - } - - return assetPath -} - -func DefaultDataDir() string { - usr, _ := user.Current() - if runtime.GOOS == "darwin" { - return path.Join(usr.HomeDir, "Library/Ethereum") - } else if runtime.GOOS == "windows" { - return path.Join(usr.HomeDir, "AppData/Roaming/Ethereum") - } else { - return path.Join(usr.HomeDir, ".ethereum") - } -} - -func ToHex(b []byte) string { - hex := Bytes2Hex(b) - // Prefer output of "0x0" instead of "0x" - if len(hex) == 0 { - hex = "0" - } - return "0x" + hex -} - -func FromHex(s string) []byte { - if len(s) > 1 { - if s[0:2] == "0x" { - s = s[2:] - } - if len(s)%2 == 1 { - s = "0" + s - } - return Hex2Bytes(s) - } - return nil -} -func IsWindows() bool { - return runtime.GOOS == "windows" -} - -func WindonizePath(path string) string { - if string(path[0]) == "/" && IsWindows() { - path = path[1:] - } - return path -} - -// The different number of units -var ( - Douglas = BigPow(10, 42) - Einstein = BigPow(10, 21) - Ether = BigPow(10, 18) - Finney = BigPow(10, 15) - Szabo = BigPow(10, 12) - Shannon = BigPow(10, 9) - Babbage = BigPow(10, 6) - Ada = BigPow(10, 3) - Wei = big.NewInt(1) -) - -// -// Currency to string -// Returns a string representing a human readable format -func CurrencyToString(num *big.Int) string { - var ( - fin *big.Int = num - denom string = "Wei" - ) - - switch { - case num.Cmp(Douglas) >= 0: - fin = new(big.Int).Div(num, Douglas) - denom = "Douglas" - case num.Cmp(Einstein) >= 0: - fin = new(big.Int).Div(num, Einstein) - denom = "Einstein" - case num.Cmp(Ether) >= 0: - fin = new(big.Int).Div(num, Ether) - denom = "Ether" - case num.Cmp(Finney) >= 0: - fin = new(big.Int).Div(num, Finney) - denom = "Finney" - case num.Cmp(Szabo) >= 0: - fin = new(big.Int).Div(num, Szabo) - denom = "Szabo" - case num.Cmp(Shannon) >= 0: - fin = new(big.Int).Div(num, Shannon) - denom = "Shannon" - case num.Cmp(Babbage) >= 0: - fin = new(big.Int).Div(num, Babbage) - denom = "Babbage" - case num.Cmp(Ada) >= 0: - fin = new(big.Int).Div(num, Ada) - denom = "Ada" - } - - // TODO add comment clarifying expected behavior - if len(fin.String()) > 5 { - return fmt.Sprintf("%sE%d %s", fin.String()[0:5], len(fin.String())-5, denom) - } - - return fmt.Sprintf("%v %s", fin, denom) -} - -// Common big integers often used -var ( - Big1 = big.NewInt(1) - Big2 = big.NewInt(2) - Big3 = big.NewInt(3) - Big0 = big.NewInt(0) - BigTrue = Big1 - BigFalse = Big0 - Big32 = big.NewInt(32) - Big256 = big.NewInt(0xff) - Big257 = big.NewInt(257) -) - -func Bench(pre string, cb func()) { - start := time.Now() - cb() - fmt.Println(pre, ": took:", time.Since(start)) -} diff --git a/common/common_test.go b/common/common_test.go deleted file mode 100644 index c7ba87f906..0000000000 --- a/common/common_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package common - -import ( - "bytes" - "math/big" - "os" - "testing" - - checker "gopkg.in/check.v1" -) - -type CommonSuite struct{} - -var _ = checker.Suite(&CommonSuite{}) - -func (s *CommonSuite) TestOS(c *checker.C) { - expwin := (os.PathSeparator == '\\' && os.PathListSeparator == ';') - res := IsWindows() - - if !expwin { - c.Assert(res, checker.Equals, expwin, checker.Commentf("IsWindows is", res, "but path is", os.PathSeparator)) - } else { - c.Assert(res, checker.Not(checker.Equals), expwin, checker.Commentf("IsWindows is", res, "but path is", os.PathSeparator)) - } -} - -func (s *CommonSuite) TestWindonziePath(c *checker.C) { - iswindowspath := os.PathSeparator == '\\' - path := "/opt/eth/test/file.ext" - res := WindonizePath(path) - ressep := string(res[0]) - - if !iswindowspath { - c.Assert(ressep, checker.Equals, "/") - } else { - c.Assert(ressep, checker.Not(checker.Equals), "/") - } -} - -func (s *CommonSuite) TestCommon(c *checker.C) { - douglas := CurrencyToString(BigPow(10, 43)) - einstein := CurrencyToString(BigPow(10, 22)) - ether := CurrencyToString(BigPow(10, 19)) - finney := CurrencyToString(BigPow(10, 16)) - szabo := CurrencyToString(BigPow(10, 13)) - shannon := CurrencyToString(BigPow(10, 10)) - babbage := CurrencyToString(BigPow(10, 7)) - ada := CurrencyToString(BigPow(10, 4)) - wei := CurrencyToString(big.NewInt(10)) - - c.Assert(douglas, checker.Equals, "10 Douglas") - c.Assert(einstein, checker.Equals, "10 Einstein") - c.Assert(ether, checker.Equals, "10 Ether") - c.Assert(finney, checker.Equals, "10 Finney") - c.Assert(szabo, checker.Equals, "10 Szabo") - c.Assert(shannon, checker.Equals, "10 Shannon") - c.Assert(babbage, checker.Equals, "10 Babbage") - c.Assert(ada, checker.Equals, "10 Ada") - c.Assert(wei, checker.Equals, "10 Wei") -} - -func (s *CommonSuite) TestLarge(c *checker.C) { - douglaslarge := CurrencyToString(BigPow(100000000, 43)) - adalarge := CurrencyToString(BigPow(100000000, 4)) - weilarge := CurrencyToString(big.NewInt(100000000)) - - c.Assert(douglaslarge, checker.Equals, "10000E298 Douglas") - c.Assert(adalarge, checker.Equals, "10000E7 Einstein") - c.Assert(weilarge, checker.Equals, "100 Babbage") -} - -//fromHex -func TestFromHex(t *testing.T) { - input := "0x01" - expected := []byte{1} - result := FromHex(input) - if bytes.Compare(expected, result) != 0 { - t.Errorf("Expected % x got % x", expected, result) - } -} - -func TestFromHexOddLength(t *testing.T) { - input := "0x1" - expected := []byte{1} - result := FromHex(input) - if bytes.Compare(expected, result) != 0 { - t.Errorf("Expected % x got % x", expected, result) - } -} diff --git a/common/path.go b/common/path.go index 680c8366c2..d38b1fd5b3 100644 --- a/common/path.go +++ b/common/path.go @@ -1,13 +1,25 @@ package common import ( + "fmt" "io/ioutil" "os" "os/user" "path" + "path/filepath" + "runtime" "strings" + + "github.com/kardianos/osext" ) +// MakeName creates a node name that follows the ethereum convention +// for such names. It adds the operation system name and Go runtime version +// the name. +func MakeName(name, version string) string { + return fmt.Sprintf("%s/v%s/%s/%s", name, version, runtime.GOOS, runtime.Version()) +} + func ExpandHomePath(p string) (path string) { path = p @@ -66,3 +78,59 @@ func AbsolutePath(Datadir string, filename string) string { } return path.Join(Datadir, filename) } + +func DefaultAssetPath() string { + var assetPath string + pwd, _ := os.Getwd() + srcdir := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist") + + // If the current working directory is the go-ethereum dir + // assume a debug build and use the source directory as + // asset directory. + if pwd == srcdir { + assetPath = path.Join(pwd, "assets") + } else { + switch runtime.GOOS { + case "darwin": + // Get Binary Directory + exedir, _ := osext.ExecutableFolder() + assetPath = filepath.Join(exedir, "../Resources") + case "linux": + assetPath = "/usr/share/mist" + case "windows": + assetPath = "./assets" + default: + assetPath = "." + } + } + + // Check if the assetPath exists. If not, try the source directory + // This happens when binary is run from outside cmd/mist directory + if _, err := os.Stat(assetPath); os.IsNotExist(err) { + assetPath = path.Join(srcdir, "assets") + } + + return assetPath +} + +func DefaultDataDir() string { + usr, _ := user.Current() + if runtime.GOOS == "darwin" { + return path.Join(usr.HomeDir, "Library/Ethereum") + } else if runtime.GOOS == "windows" { + return path.Join(usr.HomeDir, "AppData/Roaming/Ethereum") + } else { + return path.Join(usr.HomeDir, ".ethereum") + } +} + +func IsWindows() bool { + return runtime.GOOS == "windows" +} + +func WindonizePath(path string) string { + if string(path[0]) == "/" && IsWindows() { + path = path[1:] + } + return path +} diff --git a/common/path_test.go b/common/path_test.go index 4af1bd7af7..c831d1a57d 100644 --- a/common/path_test.go +++ b/common/path_test.go @@ -1,8 +1,10 @@ package common import ( - // "os" + "os" "testing" + + checker "gopkg.in/check.v1" ) func TestGoodFile(t *testing.T) { @@ -49,3 +51,31 @@ func TestBadFile(t *testing.T) { } } + +type CommonSuite struct{} + +var _ = checker.Suite(&CommonSuite{}) + +func (s *CommonSuite) TestOS(c *checker.C) { + expwin := (os.PathSeparator == '\\' && os.PathListSeparator == ';') + res := IsWindows() + + if !expwin { + c.Assert(res, checker.Equals, expwin, checker.Commentf("IsWindows is", res, "but path is", os.PathSeparator)) + } else { + c.Assert(res, checker.Not(checker.Equals), expwin, checker.Commentf("IsWindows is", res, "but path is", os.PathSeparator)) + } +} + +func (s *CommonSuite) TestWindonziePath(c *checker.C) { + iswindowspath := os.PathSeparator == '\\' + path := "/opt/eth/test/file.ext" + res := WindonizePath(path) + ressep := string(res[0]) + + if !iswindowspath { + c.Assert(ressep, checker.Equals, "/") + } else { + c.Assert(ressep, checker.Not(checker.Equals), "/") + } +} diff --git a/common/size.go b/common/size.go index 80a17279bd..b5c0b0b3f6 100644 --- a/common/size.go +++ b/common/size.go @@ -1,6 +1,9 @@ package common -import "fmt" +import ( + "fmt" + "math/big" +) type StorageSize float64 @@ -13,3 +16,60 @@ func (self StorageSize) String() string { return fmt.Sprintf("%.2f B", self) } } + +// The different number of units +var ( + Douglas = BigPow(10, 42) + Einstein = BigPow(10, 21) + Ether = BigPow(10, 18) + Finney = BigPow(10, 15) + Szabo = BigPow(10, 12) + Shannon = BigPow(10, 9) + Babbage = BigPow(10, 6) + Ada = BigPow(10, 3) + Wei = big.NewInt(1) +) + +// +// Currency to string +// Returns a string representing a human readable format +func CurrencyToString(num *big.Int) string { + var ( + fin *big.Int = num + denom string = "Wei" + ) + + switch { + case num.Cmp(Douglas) >= 0: + fin = new(big.Int).Div(num, Douglas) + denom = "Douglas" + case num.Cmp(Einstein) >= 0: + fin = new(big.Int).Div(num, Einstein) + denom = "Einstein" + case num.Cmp(Ether) >= 0: + fin = new(big.Int).Div(num, Ether) + denom = "Ether" + case num.Cmp(Finney) >= 0: + fin = new(big.Int).Div(num, Finney) + denom = "Finney" + case num.Cmp(Szabo) >= 0: + fin = new(big.Int).Div(num, Szabo) + denom = "Szabo" + case num.Cmp(Shannon) >= 0: + fin = new(big.Int).Div(num, Shannon) + denom = "Shannon" + case num.Cmp(Babbage) >= 0: + fin = new(big.Int).Div(num, Babbage) + denom = "Babbage" + case num.Cmp(Ada) >= 0: + fin = new(big.Int).Div(num, Ada) + denom = "Ada" + } + + // TODO add comment clarifying expected behavior + if len(fin.String()) > 5 { + return fmt.Sprintf("%sE%d %s", fin.String()[0:5], len(fin.String())-5, denom) + } + + return fmt.Sprintf("%v %s", fin, denom) +} diff --git a/common/size_test.go b/common/size_test.go index c90eabc261..1cbeff0a8c 100644 --- a/common/size_test.go +++ b/common/size_test.go @@ -1,6 +1,8 @@ package common import ( + "math/big" + checker "gopkg.in/check.v1" ) @@ -21,3 +23,35 @@ func (s *SizeSuite) TestStorageSizeString(c *checker.C) { c.Assert(StorageSize(data2).String(), checker.Equals, exp2) c.Assert(StorageSize(data3).String(), checker.Equals, exp3) } + +func (s *CommonSuite) TestCommon(c *checker.C) { + douglas := CurrencyToString(BigPow(10, 43)) + einstein := CurrencyToString(BigPow(10, 22)) + ether := CurrencyToString(BigPow(10, 19)) + finney := CurrencyToString(BigPow(10, 16)) + szabo := CurrencyToString(BigPow(10, 13)) + shannon := CurrencyToString(BigPow(10, 10)) + babbage := CurrencyToString(BigPow(10, 7)) + ada := CurrencyToString(BigPow(10, 4)) + wei := CurrencyToString(big.NewInt(10)) + + c.Assert(douglas, checker.Equals, "10 Douglas") + c.Assert(einstein, checker.Equals, "10 Einstein") + c.Assert(ether, checker.Equals, "10 Ether") + c.Assert(finney, checker.Equals, "10 Finney") + c.Assert(szabo, checker.Equals, "10 Szabo") + c.Assert(shannon, checker.Equals, "10 Shannon") + c.Assert(babbage, checker.Equals, "10 Babbage") + c.Assert(ada, checker.Equals, "10 Ada") + c.Assert(wei, checker.Equals, "10 Wei") +} + +func (s *CommonSuite) TestLarge(c *checker.C) { + douglaslarge := CurrencyToString(BigPow(100000000, 43)) + adalarge := CurrencyToString(BigPow(100000000, 4)) + weilarge := CurrencyToString(big.NewInt(100000000)) + + c.Assert(douglaslarge, checker.Equals, "10000E298 Douglas") + c.Assert(adalarge, checker.Equals, "10000E7 Einstein") + c.Assert(weilarge, checker.Equals, "100 Babbage") +}