mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 22:26:42 +00:00
Merge branch 'develop' of github.com:ethereum/go-ethereum into limits-changes
This commit is contained in:
commit
eeac2e7a15
92 changed files with 3305 additions and 3460 deletions
|
|
@ -5,7 +5,7 @@ install:
|
||||||
# - go get code.google.com/p/go.tools/cmd/goimports
|
# - go get code.google.com/p/go.tools/cmd/goimports
|
||||||
# - go get github.com/golang/lint/golint
|
# - go get github.com/golang/lint/golint
|
||||||
# - go get golang.org/x/tools/cmd/vet
|
# - go get golang.org/x/tools/cmd/vet
|
||||||
- go get golang.org/x/tools/cmd/cover github.com/mattn/goveralls
|
- go get golang.org/x/tools/cmd/cover
|
||||||
before_script:
|
before_script:
|
||||||
# - gofmt -l -w .
|
# - gofmt -l -w .
|
||||||
# - goimports -l -w .
|
# - goimports -l -w .
|
||||||
|
|
@ -15,7 +15,7 @@ before_script:
|
||||||
script:
|
script:
|
||||||
- make travis-test-with-coverage
|
- make travis-test-with-coverage
|
||||||
after_success:
|
after_success:
|
||||||
- if [ "$COVERALLS_TOKEN" ]; then goveralls -coverprofile=profile.cov -service=travis-ci -repotoken $COVERALLS_TOKEN; fi
|
- bash <(curl -s https://codecov.io/bash)
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- secure: "U2U1AmkU4NJBgKR/uUAebQY87cNL0+1JHjnLOmmXwxYYyj5ralWb1aSuSH3qSXiT93qLBmtaUkuv9fberHVqrbAeVlztVdUsKAq7JMQH+M99iFkC9UiRMqHmtjWJ0ok4COD1sRYixxi21wb/JrMe3M1iL4QJVS61iltjHhVdM64="
|
- secure: "U2U1AmkU4NJBgKR/uUAebQY87cNL0+1JHjnLOmmXwxYYyj5ralWb1aSuSH3qSXiT93qLBmtaUkuv9fberHVqrbAeVlztVdUsKAq7JMQH+M99iFkC9UiRMqHmtjWJ0ok4COD1sRYixxi21wb/JrMe3M1iL4QJVS61iltjHhVdM64="
|
||||||
|
|
|
||||||
9
CONTRIBUTING.md
Normal file
9
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
If you'd like to contribute to go-ethereum please fork, fix, commit and
|
||||||
|
send a pull request. Commits who do not comply with the coding standards
|
||||||
|
are ignored (use gofmt!). If you send pull requests make absolute sure that you
|
||||||
|
commit on the `develop` branch and that you do not merge to master.
|
||||||
|
Commits that are directly based on master are simply ignored.
|
||||||
|
|
||||||
|
See [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide)
|
||||||
|
for more details on configuring your environment, testing, and
|
||||||
|
dependency management.
|
||||||
18
Godeps/Godeps.json
generated
18
Godeps/Godeps.json
generated
|
|
@ -24,14 +24,18 @@
|
||||||
"Comment": "v23.1-227-g8f6ccaa",
|
"Comment": "v23.1-227-g8f6ccaa",
|
||||||
"Rev": "8f6ccaaef9b418553807a73a95cb5f49cd3ea39f"
|
"Rev": "8f6ccaaef9b418553807a73a95cb5f49cd3ea39f"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/fatih/color",
|
||||||
|
"Comment": "v0.1-5-gf773d4c",
|
||||||
|
"Rev": "f773d4c806cc8e4a5749d6a35e2a4bbcd71443d6"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gizak/termui",
|
"ImportPath": "github.com/gizak/termui",
|
||||||
"Rev": "bab8dce01c193d82bc04888a0a9a7814d505f532"
|
"Rev": "bab8dce01c193d82bc04888a0a9a7814d505f532"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/howeyc/fsnotify",
|
"ImportPath": "github.com/hashicorp/golang-lru",
|
||||||
"Comment": "v0.9.0-11-g6b1ef89",
|
"Rev": "7f9ef20a0256f494e24126014135cf893ab71e9e"
|
||||||
"Rev": "6b1ef893dc11e0447abda6da20a5203481878dda"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/huin/goupnp",
|
"ImportPath": "github.com/huin/goupnp",
|
||||||
|
|
@ -45,10 +49,6 @@
|
||||||
"ImportPath": "github.com/kardianos/osext",
|
"ImportPath": "github.com/kardianos/osext",
|
||||||
"Rev": "ccfcd0245381f0c94c68f50626665eed3c6b726a"
|
"Rev": "ccfcd0245381f0c94c68f50626665eed3c6b726a"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/mattn/go-colorable",
|
|
||||||
"Rev": "043ae16291351db8465272edf465c9f388161627"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mattn/go-isatty",
|
"ImportPath": "github.com/mattn/go-isatty",
|
||||||
"Rev": "fdbe02a1b44e75977b2690062b83cf507d70c013"
|
"Rev": "fdbe02a1b44e75977b2690062b83cf507d70c013"
|
||||||
|
|
@ -78,6 +78,10 @@
|
||||||
"ImportPath": "github.com/rs/cors",
|
"ImportPath": "github.com/rs/cors",
|
||||||
"Rev": "6e0c3cb65fc0fdb064c743d176a620e3ca446dfb"
|
"Rev": "6e0c3cb65fc0fdb064c743d176a620e3ca446dfb"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/shiena/ansicolor",
|
||||||
|
"Rev": "a5e2b567a4dd6cc74545b8a4f27c9d63b9e7735b"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
||||||
"Rev": "4875955338b0a434238a31165cb87255ab6e9e4a"
|
"Rev": "4875955338b0a434238a31165cb87255ab6e9e4a"
|
||||||
|
|
|
||||||
3
Godeps/_workspace/src/github.com/fatih/color/.travis.yml
generated
vendored
Normal file
3
Godeps/_workspace/src/github.com/fatih/color/.travis.yml
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
language: go
|
||||||
|
go: 1.3
|
||||||
|
|
||||||
20
Godeps/_workspace/src/github.com/fatih/color/LICENSE.md
generated
vendored
Normal file
20
Godeps/_workspace/src/github.com/fatih/color/LICENSE.md
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 Fatih Arslan
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
151
Godeps/_workspace/src/github.com/fatih/color/README.md
generated
vendored
Normal file
151
Godeps/_workspace/src/github.com/fatih/color/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
# Color [](http://godoc.org/github.com/fatih/color) [](https://travis-ci.org/fatih/color)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Color lets you use colorized outputs in terms of [ANSI Escape Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It has support for Windows too! The API can be used in several ways, pick one that suits you.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get github.com/fatih/color
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Standard colors
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Print with default helper functions
|
||||||
|
color.Cyan("Prints text in cyan.")
|
||||||
|
|
||||||
|
// A newline will be appended automatically
|
||||||
|
color.Blue("Prints %s in blue.", "text")
|
||||||
|
|
||||||
|
// These are using the default foreground colors
|
||||||
|
color.Red("We have red")
|
||||||
|
color.Magenta("And many others ..")
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mix and reuse colors
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Create a new color object
|
||||||
|
c := color.New(color.FgCyan).Add(color.Underline)
|
||||||
|
c.Println("Prints cyan text with an underline.")
|
||||||
|
|
||||||
|
// Or just add them to New()
|
||||||
|
d := color.New(color.FgCyan, color.Bold)
|
||||||
|
d.Printf("This prints bold cyan %s\n", "too!.")
|
||||||
|
|
||||||
|
// Mix up foreground and background colors, create new mixes!
|
||||||
|
red := color.New(color.FgRed)
|
||||||
|
|
||||||
|
boldRed := red.Add(color.Bold)
|
||||||
|
boldRed.Println("This will print text in bold red.")
|
||||||
|
|
||||||
|
whiteBackground := red.Add(color.BgWhite)
|
||||||
|
whiteBackground.Println("Red text with white background.")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom print functions (PrintFunc)
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Create a custom print function for convenience
|
||||||
|
red := color.New(color.FgRed).PrintfFunc()
|
||||||
|
red("Warning")
|
||||||
|
red("Error: %s", err)
|
||||||
|
|
||||||
|
// Mix up multiple attributes
|
||||||
|
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
|
||||||
|
notice("Don't forget this...")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Insert into noncolor strings (SprintFunc)
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Create SprintXxx functions to mix strings with other non-colorized strings:
|
||||||
|
yellow := color.New(color.FgYellow).SprintFunc()
|
||||||
|
red := color.New(color.FgRed).SprintFunc()
|
||||||
|
fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error"))
|
||||||
|
|
||||||
|
info := color.New(color.FgWhite, color.BgGreen).SprintFunc()
|
||||||
|
fmt.Printf("This %s rocks!\n", info("package"))
|
||||||
|
|
||||||
|
// Use helper functions
|
||||||
|
fmt.Printf("This", color.RedString("warning"), "should be not neglected.")
|
||||||
|
fmt.Printf(color.GreenString("Info:"), "an important message." )
|
||||||
|
|
||||||
|
// Windows supported too! Just don't forget to change the output to color.Output
|
||||||
|
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Plug into existing code
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Use handy standard colors
|
||||||
|
color.Set(color.FgYellow)
|
||||||
|
|
||||||
|
fmt.Println("Existing text will now be in yellow")
|
||||||
|
fmt.Printf("This one %s\n", "too")
|
||||||
|
|
||||||
|
color.Unset() // Don't forget to unset
|
||||||
|
|
||||||
|
// You can mix up parameters
|
||||||
|
color.Set(color.FgMagenta, color.Bold)
|
||||||
|
defer color.Unset() // Use it in your function
|
||||||
|
|
||||||
|
fmt.Println("All text will now be bold magenta.")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disable color
|
||||||
|
|
||||||
|
There might be a case where you want to disable color output (for example to
|
||||||
|
pipe the standard output of your app to somewhere else). `Color` has support to
|
||||||
|
disable colors both globally and for single color definition. For example
|
||||||
|
suppose you have a CLI app and a `--no-color` bool flag. You can easily disable
|
||||||
|
the color output with:
|
||||||
|
|
||||||
|
```go
|
||||||
|
|
||||||
|
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
|
||||||
|
|
||||||
|
if *flagNoColor {
|
||||||
|
color.NoColor = true // disables colorized output
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It also has support for single color definitions (local). You can
|
||||||
|
disable/enable color output on the fly:
|
||||||
|
|
||||||
|
```go
|
||||||
|
c := color.New(color.FgCyan)
|
||||||
|
c.Println("Prints cyan text")
|
||||||
|
|
||||||
|
c.DisableColor()
|
||||||
|
c.Println("This is printed without any color")
|
||||||
|
|
||||||
|
c.EnableColor()
|
||||||
|
c.Println("This prints again cyan...")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Todo
|
||||||
|
|
||||||
|
* Save/Return previous values
|
||||||
|
* Evaluate fmt.Formatter interface
|
||||||
|
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
* [Fatih Arslan](https://github.com/fatih)
|
||||||
|
* Windows support via @shiena: [ansicolor](https://github.com/shiena/ansicolor)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details
|
||||||
|
|
||||||
353
Godeps/_workspace/src/github.com/fatih/color/color.go
generated
vendored
Normal file
353
Godeps/_workspace/src/github.com/fatih/color/color.go
generated
vendored
Normal file
|
|
@ -0,0 +1,353 @@
|
||||||
|
package color
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mattn/go-isatty"
|
||||||
|
"github.com/shiena/ansicolor"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NoColor defines if the output is colorized or not. It's dynamically set to
|
||||||
|
// false or true based on the stdout's file descriptor referring to a terminal
|
||||||
|
// or not. This is a global option and affects all colors. For more control
|
||||||
|
// over each color block use the methods DisableColor() individually.
|
||||||
|
var NoColor = !isatty.IsTerminal(os.Stdout.Fd())
|
||||||
|
|
||||||
|
// Color defines a custom color object which is defined by SGR parameters.
|
||||||
|
type Color struct {
|
||||||
|
params []Attribute
|
||||||
|
noColor *bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attribute defines a single SGR Code
|
||||||
|
type Attribute int
|
||||||
|
|
||||||
|
const escape = "\x1b"
|
||||||
|
|
||||||
|
// Base attributes
|
||||||
|
const (
|
||||||
|
Reset Attribute = iota
|
||||||
|
Bold
|
||||||
|
Faint
|
||||||
|
Italic
|
||||||
|
Underline
|
||||||
|
BlinkSlow
|
||||||
|
BlinkRapid
|
||||||
|
ReverseVideo
|
||||||
|
Concealed
|
||||||
|
CrossedOut
|
||||||
|
)
|
||||||
|
|
||||||
|
// Foreground text colors
|
||||||
|
const (
|
||||||
|
FgBlack Attribute = iota + 30
|
||||||
|
FgRed
|
||||||
|
FgGreen
|
||||||
|
FgYellow
|
||||||
|
FgBlue
|
||||||
|
FgMagenta
|
||||||
|
FgCyan
|
||||||
|
FgWhite
|
||||||
|
)
|
||||||
|
|
||||||
|
// Background text colors
|
||||||
|
const (
|
||||||
|
BgBlack Attribute = iota + 40
|
||||||
|
BgRed
|
||||||
|
BgGreen
|
||||||
|
BgYellow
|
||||||
|
BgBlue
|
||||||
|
BgMagenta
|
||||||
|
BgCyan
|
||||||
|
BgWhite
|
||||||
|
)
|
||||||
|
|
||||||
|
// New returns a newly created color object.
|
||||||
|
func New(value ...Attribute) *Color {
|
||||||
|
c := &Color{params: make([]Attribute, 0)}
|
||||||
|
c.Add(value...)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the given parameters immediately. It will change the color of
|
||||||
|
// output with the given SGR parameters until color.Unset() is called.
|
||||||
|
func Set(p ...Attribute) *Color {
|
||||||
|
c := New(p...)
|
||||||
|
c.Set()
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unset resets all escape attributes and clears the output. Usually should
|
||||||
|
// be called after Set().
|
||||||
|
func Unset() {
|
||||||
|
if NoColor {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(Output, "%s[%dm", escape, Reset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the SGR sequence.
|
||||||
|
func (c *Color) Set() *Color {
|
||||||
|
if c.isNoColorSet() {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(Output, c.format())
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) unset() {
|
||||||
|
if c.isNoColorSet() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add is used to chain SGR parameters. Use as many as parameters to combine
|
||||||
|
// and create custom color objects. Example: Add(color.FgRed, color.Underline).
|
||||||
|
func (c *Color) Add(value ...Attribute) *Color {
|
||||||
|
c.params = append(c.params, value...)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) prepend(value Attribute) {
|
||||||
|
c.params = append(c.params, 0)
|
||||||
|
copy(c.params[1:], c.params[0:])
|
||||||
|
c.params[0] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output defines the standard output of the print functions. By default
|
||||||
|
// os.Stdout is used.
|
||||||
|
var Output = ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||||
|
|
||||||
|
// Print formats using the default formats for its operands and writes to
|
||||||
|
// standard output. Spaces are added between operands when neither is a
|
||||||
|
// string. It returns the number of bytes written and any write error
|
||||||
|
// encountered. This is the standard fmt.Print() method wrapped with the given
|
||||||
|
// color.
|
||||||
|
func (c *Color) Print(a ...interface{}) (n int, err error) {
|
||||||
|
c.Set()
|
||||||
|
defer c.unset()
|
||||||
|
|
||||||
|
return fmt.Fprint(Output, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printf formats according to a format specifier and writes to standard output.
|
||||||
|
// It returns the number of bytes written and any write error encountered.
|
||||||
|
// This is the standard fmt.Printf() method wrapped with the given color.
|
||||||
|
func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
|
||||||
|
c.Set()
|
||||||
|
defer c.unset()
|
||||||
|
|
||||||
|
return fmt.Fprintf(Output, format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Println formats using the default formats for its operands and writes to
|
||||||
|
// standard output. Spaces are always added between operands and a newline is
|
||||||
|
// appended. It returns the number of bytes written and any write error
|
||||||
|
// encountered. This is the standard fmt.Print() method wrapped with the given
|
||||||
|
// color.
|
||||||
|
func (c *Color) Println(a ...interface{}) (n int, err error) {
|
||||||
|
c.Set()
|
||||||
|
defer c.unset()
|
||||||
|
|
||||||
|
return fmt.Fprintln(Output, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintFunc returns a new function that prints the passed arguments as
|
||||||
|
// colorized with color.Print().
|
||||||
|
func (c *Color) PrintFunc() func(a ...interface{}) {
|
||||||
|
return func(a ...interface{}) { c.Print(a...) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintfFunc returns a new function that prints the passed arguments as
|
||||||
|
// colorized with color.Printf().
|
||||||
|
func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
|
||||||
|
return func(format string, a ...interface{}) { c.Printf(format, a...) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintlnFunc returns a new function that prints the passed arguments as
|
||||||
|
// colorized with color.Println().
|
||||||
|
func (c *Color) PrintlnFunc() func(a ...interface{}) {
|
||||||
|
return func(a ...interface{}) { c.Println(a...) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// SprintFunc returns a new function that returns colorized strings for the
|
||||||
|
// given arguments with fmt.Sprint(). Useful to put into or mix into other
|
||||||
|
// string. Windows users should use this in conjuction with color.Output, example:
|
||||||
|
//
|
||||||
|
// put := New(FgYellow).SprintFunc()
|
||||||
|
// fmt.Fprintf(color.Output, "This is a %s", put("warning"))
|
||||||
|
func (c *Color) SprintFunc() func(a ...interface{}) string {
|
||||||
|
return func(a ...interface{}) string {
|
||||||
|
return c.wrap(fmt.Sprint(a...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SprintfFunc returns a new function that returns colorized strings for the
|
||||||
|
// given arguments with fmt.Sprintf(). Useful to put into or mix into other
|
||||||
|
// string. Windows users should use this in conjuction with color.Output.
|
||||||
|
func (c *Color) SprintfFunc() func(format string, a ...interface{}) string {
|
||||||
|
return func(format string, a ...interface{}) string {
|
||||||
|
return c.wrap(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SprintlnFunc returns a new function that returns colorized strings for the
|
||||||
|
// given arguments with fmt.Sprintln(). Useful to put into or mix into other
|
||||||
|
// string. Windows users should use this in conjuction with color.Output.
|
||||||
|
func (c *Color) SprintlnFunc() func(a ...interface{}) string {
|
||||||
|
return func(a ...interface{}) string {
|
||||||
|
return c.wrap(fmt.Sprintln(a...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m"
|
||||||
|
// an example output might be: "1;36" -> bold cyan
|
||||||
|
func (c *Color) sequence() string {
|
||||||
|
format := make([]string, len(c.params))
|
||||||
|
for i, v := range c.params {
|
||||||
|
format[i] = strconv.Itoa(int(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(format, ";")
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrap wraps the s string with the colors attributes. The string is ready to
|
||||||
|
// be printed.
|
||||||
|
func (c *Color) wrap(s string) string {
|
||||||
|
if c.isNoColorSet() {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.format() + s + c.unformat()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) format() string {
|
||||||
|
return fmt.Sprintf("%s[%sm", escape, c.sequence())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) unformat() string {
|
||||||
|
return fmt.Sprintf("%s[%dm", escape, Reset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableColor disables the color output. Useful to not change any existing
|
||||||
|
// code and still being able to output. Can be used for flags like
|
||||||
|
// "--no-color". To enable back use EnableColor() method.
|
||||||
|
func (c *Color) DisableColor() {
|
||||||
|
c.noColor = boolPtr(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableColor enables the color output. Use it in conjuction with
|
||||||
|
// DisableColor(). Otherwise this method has no side effects.
|
||||||
|
func (c *Color) EnableColor() {
|
||||||
|
c.noColor = boolPtr(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) isNoColorSet() bool {
|
||||||
|
// check first if we have user setted action
|
||||||
|
if c.noColor != nil {
|
||||||
|
return *c.noColor
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not return the global option, which is disabled by default
|
||||||
|
return NoColor
|
||||||
|
}
|
||||||
|
|
||||||
|
func boolPtr(v bool) *bool {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Black is an convenient helper function to print with black foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func Black(format string, a ...interface{}) { printColor(format, FgBlack, a...) }
|
||||||
|
|
||||||
|
// Red is an convenient helper function to print with red foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func Red(format string, a ...interface{}) { printColor(format, FgRed, a...) }
|
||||||
|
|
||||||
|
// Green is an convenient helper function to print with green foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func Green(format string, a ...interface{}) { printColor(format, FgGreen, a...) }
|
||||||
|
|
||||||
|
// Yellow is an convenient helper function to print with yellow foreground.
|
||||||
|
// A newline is appended to format by default.
|
||||||
|
func Yellow(format string, a ...interface{}) { printColor(format, FgYellow, a...) }
|
||||||
|
|
||||||
|
// Blue is an convenient helper function to print with blue foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func Blue(format string, a ...interface{}) { printColor(format, FgBlue, a...) }
|
||||||
|
|
||||||
|
// Magenta is an convenient helper function to print with magenta foreground.
|
||||||
|
// A newline is appended to format by default.
|
||||||
|
func Magenta(format string, a ...interface{}) { printColor(format, FgMagenta, a...) }
|
||||||
|
|
||||||
|
// Cyan is an convenient helper function to print with cyan foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func Cyan(format string, a ...interface{}) { printColor(format, FgCyan, a...) }
|
||||||
|
|
||||||
|
// White is an convenient helper function to print with white foreground. A
|
||||||
|
// newline is appended to format by default.
|
||||||
|
func White(format string, a ...interface{}) { printColor(format, FgWhite, a...) }
|
||||||
|
|
||||||
|
func printColor(format string, p Attribute, a ...interface{}) {
|
||||||
|
if !strings.HasSuffix(format, "\n") {
|
||||||
|
format += "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &Color{params: []Attribute{p}}
|
||||||
|
c.Printf(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlackString is an convenient helper function to return a string with black
|
||||||
|
// foreground.
|
||||||
|
func BlackString(format string, a ...interface{}) string {
|
||||||
|
return New(FgBlack).SprintfFunc()(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RedString is an convenient helper function to return a string with red
|
||||||
|
// foreground.
|
||||||
|
func RedString(format string, a ...interface{}) string {
|
||||||
|
return New(FgRed).SprintfFunc()(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GreenString is an convenient helper function to return a string with green
|
||||||
|
// foreground.
|
||||||
|
func GreenString(format string, a ...interface{}) string {
|
||||||
|
return New(FgGreen).SprintfFunc()(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// YellowString is an convenient helper function to return a string with yellow
|
||||||
|
// foreground.
|
||||||
|
func YellowString(format string, a ...interface{}) string {
|
||||||
|
return New(FgYellow).SprintfFunc()(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlueString is an convenient helper function to return a string with blue
|
||||||
|
// foreground.
|
||||||
|
func BlueString(format string, a ...interface{}) string {
|
||||||
|
return New(FgBlue).SprintfFunc()(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MagentaString is an convenient helper function to return a string with magenta
|
||||||
|
// foreground.
|
||||||
|
func MagentaString(format string, a ...interface{}) string {
|
||||||
|
return New(FgMagenta).SprintfFunc()(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CyanString is an convenient helper function to return a string with cyan
|
||||||
|
// foreground.
|
||||||
|
func CyanString(format string, a ...interface{}) string {
|
||||||
|
return New(FgCyan).SprintfFunc()(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WhiteString is an convenient helper function to return a string with white
|
||||||
|
// foreground.
|
||||||
|
func WhiteString(format string, a ...interface{}) string {
|
||||||
|
return New(FgWhite).SprintfFunc()(format, a...)
|
||||||
|
}
|
||||||
176
Godeps/_workspace/src/github.com/fatih/color/color_test.go
generated
vendored
Normal file
176
Godeps/_workspace/src/github.com/fatih/color/color_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
package color
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/shiena/ansicolor"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Testing colors is kinda different. First we test for given colors and their
|
||||||
|
// escaped formatted results. Next we create some visual tests to be tested.
|
||||||
|
// Each visual test includes the color name to be compared.
|
||||||
|
func TestColor(t *testing.T) {
|
||||||
|
rb := new(bytes.Buffer)
|
||||||
|
Output = rb
|
||||||
|
|
||||||
|
testColors := []struct {
|
||||||
|
text string
|
||||||
|
code Attribute
|
||||||
|
}{
|
||||||
|
{text: "black", code: FgBlack},
|
||||||
|
{text: "red", code: FgRed},
|
||||||
|
{text: "green", code: FgGreen},
|
||||||
|
{text: "yellow", code: FgYellow},
|
||||||
|
{text: "blue", code: FgBlue},
|
||||||
|
{text: "magent", code: FgMagenta},
|
||||||
|
{text: "cyan", code: FgCyan},
|
||||||
|
{text: "white", code: FgWhite},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range testColors {
|
||||||
|
New(c.code).Print(c.text)
|
||||||
|
|
||||||
|
line, _ := rb.ReadString('\n')
|
||||||
|
scannedLine := fmt.Sprintf("%q", line)
|
||||||
|
colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text)
|
||||||
|
escapedForm := fmt.Sprintf("%q", colored)
|
||||||
|
|
||||||
|
fmt.Printf("%s\t: %s\n", c.text, line)
|
||||||
|
|
||||||
|
if scannedLine != escapedForm {
|
||||||
|
t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoColor(t *testing.T) {
|
||||||
|
rb := new(bytes.Buffer)
|
||||||
|
Output = rb
|
||||||
|
|
||||||
|
testColors := []struct {
|
||||||
|
text string
|
||||||
|
code Attribute
|
||||||
|
}{
|
||||||
|
{text: "black", code: FgBlack},
|
||||||
|
{text: "red", code: FgRed},
|
||||||
|
{text: "green", code: FgGreen},
|
||||||
|
{text: "yellow", code: FgYellow},
|
||||||
|
{text: "blue", code: FgBlue},
|
||||||
|
{text: "magent", code: FgMagenta},
|
||||||
|
{text: "cyan", code: FgCyan},
|
||||||
|
{text: "white", code: FgWhite},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range testColors {
|
||||||
|
p := New(c.code)
|
||||||
|
p.DisableColor()
|
||||||
|
p.Print(c.text)
|
||||||
|
|
||||||
|
line, _ := rb.ReadString('\n')
|
||||||
|
if line != c.text {
|
||||||
|
t.Errorf("Expecting %s, got '%s'\n", c.text, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// global check
|
||||||
|
NoColor = true
|
||||||
|
defer func() {
|
||||||
|
NoColor = false
|
||||||
|
}()
|
||||||
|
for _, c := range testColors {
|
||||||
|
p := New(c.code)
|
||||||
|
p.Print(c.text)
|
||||||
|
|
||||||
|
line, _ := rb.ReadString('\n')
|
||||||
|
if line != c.text {
|
||||||
|
t.Errorf("Expecting %s, got '%s'\n", c.text, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestColorVisual(t *testing.T) {
|
||||||
|
// First Visual Test
|
||||||
|
fmt.Println("")
|
||||||
|
Output = ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||||
|
|
||||||
|
New(FgRed).Printf("red\t")
|
||||||
|
New(BgRed).Print(" ")
|
||||||
|
New(FgRed, Bold).Println(" red")
|
||||||
|
|
||||||
|
New(FgGreen).Printf("green\t")
|
||||||
|
New(BgGreen).Print(" ")
|
||||||
|
New(FgGreen, Bold).Println(" green")
|
||||||
|
|
||||||
|
New(FgYellow).Printf("yellow\t")
|
||||||
|
New(BgYellow).Print(" ")
|
||||||
|
New(FgYellow, Bold).Println(" yellow")
|
||||||
|
|
||||||
|
New(FgBlue).Printf("blue\t")
|
||||||
|
New(BgBlue).Print(" ")
|
||||||
|
New(FgBlue, Bold).Println(" blue")
|
||||||
|
|
||||||
|
New(FgMagenta).Printf("magenta\t")
|
||||||
|
New(BgMagenta).Print(" ")
|
||||||
|
New(FgMagenta, Bold).Println(" magenta")
|
||||||
|
|
||||||
|
New(FgCyan).Printf("cyan\t")
|
||||||
|
New(BgCyan).Print(" ")
|
||||||
|
New(FgCyan, Bold).Println(" cyan")
|
||||||
|
|
||||||
|
New(FgWhite).Printf("white\t")
|
||||||
|
New(BgWhite).Print(" ")
|
||||||
|
New(FgWhite, Bold).Println(" white")
|
||||||
|
fmt.Println("")
|
||||||
|
|
||||||
|
// Second Visual test
|
||||||
|
Black("black")
|
||||||
|
Red("red")
|
||||||
|
Green("green")
|
||||||
|
Yellow("yellow")
|
||||||
|
Blue("blue")
|
||||||
|
Magenta("magenta")
|
||||||
|
Cyan("cyan")
|
||||||
|
White("white")
|
||||||
|
|
||||||
|
// Third visual test
|
||||||
|
fmt.Println()
|
||||||
|
Set(FgBlue)
|
||||||
|
fmt.Println("is this blue?")
|
||||||
|
Unset()
|
||||||
|
|
||||||
|
Set(FgMagenta)
|
||||||
|
fmt.Println("and this magenta?")
|
||||||
|
Unset()
|
||||||
|
|
||||||
|
// Fourth Visual test
|
||||||
|
fmt.Println()
|
||||||
|
blue := New(FgBlue).PrintlnFunc()
|
||||||
|
blue("blue text with custom print func")
|
||||||
|
|
||||||
|
red := New(FgRed).PrintfFunc()
|
||||||
|
red("red text with a printf func: %d\n", 123)
|
||||||
|
|
||||||
|
put := New(FgYellow).SprintFunc()
|
||||||
|
warn := New(FgRed).SprintFunc()
|
||||||
|
|
||||||
|
fmt.Fprintf(Output, "this is a %s and this is %s.\n", put("warning"), warn("error"))
|
||||||
|
|
||||||
|
info := New(FgWhite, BgGreen).SprintFunc()
|
||||||
|
fmt.Fprintf(Output, "this %s rocks!\n", info("package"))
|
||||||
|
|
||||||
|
// Fifth Visual Test
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Fprintln(Output, BlackString("black"))
|
||||||
|
fmt.Fprintln(Output, RedString("red"))
|
||||||
|
fmt.Fprintln(Output, GreenString("green"))
|
||||||
|
fmt.Fprintln(Output, YellowString("yellow"))
|
||||||
|
fmt.Fprintln(Output, BlueString("blue"))
|
||||||
|
fmt.Fprintln(Output, MagentaString("magenta"))
|
||||||
|
fmt.Fprintln(Output, CyanString("cyan"))
|
||||||
|
fmt.Fprintln(Output, WhiteString("white"))
|
||||||
|
}
|
||||||
114
Godeps/_workspace/src/github.com/fatih/color/doc.go
generated
vendored
Normal file
114
Godeps/_workspace/src/github.com/fatih/color/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
Package color is an ANSI color package to output colorized or SGR defined
|
||||||
|
output to the standard output. The API can be used in several way, pick one
|
||||||
|
that suits you.
|
||||||
|
|
||||||
|
Use simple and default helper functions with predefined foreground colors:
|
||||||
|
|
||||||
|
color.Cyan("Prints text in cyan.")
|
||||||
|
|
||||||
|
// a newline will be appended automatically
|
||||||
|
color.Blue("Prints %s in blue.", "text")
|
||||||
|
|
||||||
|
// More default foreground colors..
|
||||||
|
color.Red("We have red")
|
||||||
|
color.Yellow("Yellow color too!")
|
||||||
|
color.Magenta("And many others ..")
|
||||||
|
|
||||||
|
However there are times where custom color mixes are required. Below are some
|
||||||
|
examples to create custom color objects and use the print functions of each
|
||||||
|
separate color object.
|
||||||
|
|
||||||
|
// Create a new color object
|
||||||
|
c := color.New(color.FgCyan).Add(color.Underline)
|
||||||
|
c.Println("Prints cyan text with an underline.")
|
||||||
|
|
||||||
|
// Or just add them to New()
|
||||||
|
d := color.New(color.FgCyan, color.Bold)
|
||||||
|
d.Printf("This prints bold cyan %s\n", "too!.")
|
||||||
|
|
||||||
|
|
||||||
|
// Mix up foreground and background colors, create new mixes!
|
||||||
|
red := color.New(color.FgRed)
|
||||||
|
|
||||||
|
boldRed := red.Add(color.Bold)
|
||||||
|
boldRed.Println("This will print text in bold red.")
|
||||||
|
|
||||||
|
whiteBackground := red.Add(color.BgWhite)
|
||||||
|
whiteBackground.Println("Red text with White background.")
|
||||||
|
|
||||||
|
|
||||||
|
You can create PrintXxx functions to simplify even more:
|
||||||
|
|
||||||
|
// Create a custom print function for convenient
|
||||||
|
red := color.New(color.FgRed).PrintfFunc()
|
||||||
|
red("warning")
|
||||||
|
red("error: %s", err)
|
||||||
|
|
||||||
|
// Mix up multiple attributes
|
||||||
|
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
|
||||||
|
notice("don't forget this...")
|
||||||
|
|
||||||
|
|
||||||
|
Or create SprintXxx functions to mix strings with other non-colorized strings:
|
||||||
|
|
||||||
|
yellow := New(FgYellow).SprintFunc()
|
||||||
|
red := New(FgRed).SprintFunc()
|
||||||
|
|
||||||
|
fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error"))
|
||||||
|
|
||||||
|
info := New(FgWhite, BgGreen).SprintFunc()
|
||||||
|
fmt.Printf("this %s rocks!\n", info("package"))
|
||||||
|
|
||||||
|
Windows support is enabled by default. All Print functions works as intended.
|
||||||
|
However only for color.SprintXXX functions, user should use fmt.FprintXXX and
|
||||||
|
set the output to color.Output:
|
||||||
|
|
||||||
|
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
|
||||||
|
|
||||||
|
info := New(FgWhite, BgGreen).SprintFunc()
|
||||||
|
fmt.Fprintf(color.Output, "this %s rocks!\n", info("package"))
|
||||||
|
|
||||||
|
Using with existing code is possible. Just use the Set() method to set the
|
||||||
|
standard output to the given parameters. That way a rewrite of an existing
|
||||||
|
code is not required.
|
||||||
|
|
||||||
|
// Use handy standard colors.
|
||||||
|
color.Set(color.FgYellow)
|
||||||
|
|
||||||
|
fmt.Println("Existing text will be now in Yellow")
|
||||||
|
fmt.Printf("This one %s\n", "too")
|
||||||
|
|
||||||
|
color.Unset() // don't forget to unset
|
||||||
|
|
||||||
|
// You can mix up parameters
|
||||||
|
color.Set(color.FgMagenta, color.Bold)
|
||||||
|
defer color.Unset() // use it in your function
|
||||||
|
|
||||||
|
fmt.Println("All text will be now bold magenta.")
|
||||||
|
|
||||||
|
There might be a case where you want to disable color output (for example to
|
||||||
|
pipe the standard output of your app to somewhere else). `Color` has support to
|
||||||
|
disable colors both globally and for single color definition. For example
|
||||||
|
suppose you have a CLI app and a `--no-color` bool flag. You can easily disable
|
||||||
|
the color output with:
|
||||||
|
|
||||||
|
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
|
||||||
|
|
||||||
|
if *flagNoColor {
|
||||||
|
color.NoColor = true // disables colorized output
|
||||||
|
}
|
||||||
|
|
||||||
|
It also has support for single color definitions (local). You can
|
||||||
|
disable/enable color output on the fly:
|
||||||
|
|
||||||
|
c := color.New(color.FgCyan)
|
||||||
|
c.Println("Prints cyan text")
|
||||||
|
|
||||||
|
c.DisableColor()
|
||||||
|
c.Println("This is printed without any color")
|
||||||
|
|
||||||
|
c.EnableColor()
|
||||||
|
c.Println("This prints again cyan...")
|
||||||
|
*/
|
||||||
|
package color
|
||||||
4
Godeps/_workspace/src/github.com/huin/goupnp/httpu/httpu.go
generated
vendored
4
Godeps/_workspace/src/github.com/huin/goupnp/httpu/httpu.go
generated
vendored
|
|
@ -9,8 +9,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/fdtrack"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTPUClient is a client for dealing with HTTPU (HTTP over UDP). Its typical
|
// HTTPUClient is a client for dealing with HTTPU (HTTP over UDP). Its typical
|
||||||
|
|
@ -27,7 +25,6 @@ func NewHTTPUClient() (*HTTPUClient, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fdtrack.Open("upnp")
|
|
||||||
return &HTTPUClient{conn: conn}, nil
|
return &HTTPUClient{conn: conn}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,7 +33,6 @@ func NewHTTPUClient() (*HTTPUClient, error) {
|
||||||
func (httpu *HTTPUClient) Close() error {
|
func (httpu *HTTPUClient) Close() error {
|
||||||
httpu.connLock.Lock()
|
httpu.connLock.Lock()
|
||||||
defer httpu.connLock.Unlock()
|
defer httpu.connLock.Unlock()
|
||||||
fdtrack.Close("upnp")
|
|
||||||
return httpu.conn.Close()
|
return httpu.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
14
Godeps/_workspace/src/github.com/huin/goupnp/soap/soap.go
generated
vendored
14
Godeps/_workspace/src/github.com/huin/goupnp/soap/soap.go
generated
vendored
|
|
@ -7,12 +7,9 @@ import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/fdtrack"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -29,17 +26,6 @@ type SOAPClient struct {
|
||||||
func NewSOAPClient(endpointURL url.URL) *SOAPClient {
|
func NewSOAPClient(endpointURL url.URL) *SOAPClient {
|
||||||
return &SOAPClient{
|
return &SOAPClient{
|
||||||
EndpointURL: endpointURL,
|
EndpointURL: endpointURL,
|
||||||
HTTPClient: http.Client{
|
|
||||||
Transport: &http.Transport{
|
|
||||||
Dial: func(network, addr string) (net.Conn, error) {
|
|
||||||
c, err := net.Dial(network, addr)
|
|
||||||
if c != nil {
|
|
||||||
c = fdtrack.WrapConn("upnp", c)
|
|
||||||
}
|
|
||||||
return c, err
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
Godeps/_workspace/src/github.com/jackpal/go-nat-pmp/natpmp.go
generated
vendored
4
Godeps/_workspace/src/github.com/jackpal/go-nat-pmp/natpmp.go
generated
vendored
|
|
@ -5,8 +5,6 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/fdtrack"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Implement the NAT-PMP protocol, typically supported by Apple routers and open source
|
// Implement the NAT-PMP protocol, typically supported by Apple routers and open source
|
||||||
|
|
@ -104,8 +102,6 @@ func (n *Client) rpc(msg []byte, resultSize int) (result []byte, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fdtrack.Open("natpmp")
|
|
||||||
defer fdtrack.Close("natpmp")
|
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
result = make([]byte, resultSize)
|
result = make([]byte, resultSize)
|
||||||
|
|
|
||||||
42
Godeps/_workspace/src/github.com/mattn/go-colorable/README.md
generated
vendored
42
Godeps/_workspace/src/github.com/mattn/go-colorable/README.md
generated
vendored
|
|
@ -1,42 +0,0 @@
|
||||||
# go-colorable
|
|
||||||
|
|
||||||
Colorable writer for windows.
|
|
||||||
|
|
||||||
For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)
|
|
||||||
This package is possible to handle escape sequence for ansi color on windows.
|
|
||||||
|
|
||||||
## Too Bad!
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
## So Good!
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```go
|
|
||||||
logrus.SetOutput(colorable.NewColorableStdout())
|
|
||||||
|
|
||||||
logrus.Info("succeeded")
|
|
||||||
logrus.Warn("not correct")
|
|
||||||
logrus.Error("something error")
|
|
||||||
logrus.Fatal("panic")
|
|
||||||
```
|
|
||||||
|
|
||||||
You can compile above code on non-windows OSs.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```
|
|
||||||
$ go get github.com/mattn/go-colorable
|
|
||||||
```
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
MIT
|
|
||||||
|
|
||||||
# Author
|
|
||||||
|
|
||||||
Yasuhiro Matsumoto (a.k.a mattn)
|
|
||||||
16
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
16
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
|
|
@ -1,16 +0,0 @@
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package colorable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewColorableStdout() io.Writer {
|
|
||||||
return os.Stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewColorableStderr() io.Writer {
|
|
||||||
return os.Stderr
|
|
||||||
}
|
|
||||||
594
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
594
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_windows.go
generated
vendored
|
|
@ -1,594 +0,0 @@
|
||||||
package colorable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/mattn/go-isatty"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
foregroundBlue = 0x1
|
|
||||||
foregroundGreen = 0x2
|
|
||||||
foregroundRed = 0x4
|
|
||||||
foregroundIntensity = 0x8
|
|
||||||
foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)
|
|
||||||
backgroundBlue = 0x10
|
|
||||||
backgroundGreen = 0x20
|
|
||||||
backgroundRed = 0x40
|
|
||||||
backgroundIntensity = 0x80
|
|
||||||
backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)
|
|
||||||
)
|
|
||||||
|
|
||||||
type wchar uint16
|
|
||||||
type short int16
|
|
||||||
type dword uint32
|
|
||||||
type word uint16
|
|
||||||
|
|
||||||
type coord struct {
|
|
||||||
x short
|
|
||||||
y short
|
|
||||||
}
|
|
||||||
|
|
||||||
type smallRect struct {
|
|
||||||
left short
|
|
||||||
top short
|
|
||||||
right short
|
|
||||||
bottom short
|
|
||||||
}
|
|
||||||
|
|
||||||
type consoleScreenBufferInfo struct {
|
|
||||||
size coord
|
|
||||||
cursorPosition coord
|
|
||||||
attributes word
|
|
||||||
window smallRect
|
|
||||||
maximumWindowSize coord
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
|
||||||
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Writer struct {
|
|
||||||
out io.Writer
|
|
||||||
handle syscall.Handle
|
|
||||||
lastbuf bytes.Buffer
|
|
||||||
oldattr word
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewColorableStdout() io.Writer {
|
|
||||||
var csbi consoleScreenBufferInfo
|
|
||||||
out := os.Stdout
|
|
||||||
if !isatty.IsTerminal(out.Fd()) {
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
handle := syscall.Handle(out.Fd())
|
|
||||||
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
|
||||||
return &Writer{out: out, handle: handle, oldattr: csbi.attributes}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewColorableStderr() io.Writer {
|
|
||||||
var csbi consoleScreenBufferInfo
|
|
||||||
out := os.Stderr
|
|
||||||
if !isatty.IsTerminal(out.Fd()) {
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
handle := syscall.Handle(out.Fd())
|
|
||||||
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
|
|
||||||
return &Writer{out: out, handle: handle, oldattr: csbi.attributes}
|
|
||||||
}
|
|
||||||
|
|
||||||
var color256 = map[int]int{
|
|
||||||
0: 0x000000,
|
|
||||||
1: 0x800000,
|
|
||||||
2: 0x008000,
|
|
||||||
3: 0x808000,
|
|
||||||
4: 0x000080,
|
|
||||||
5: 0x800080,
|
|
||||||
6: 0x008080,
|
|
||||||
7: 0xc0c0c0,
|
|
||||||
8: 0x808080,
|
|
||||||
9: 0xff0000,
|
|
||||||
10: 0x00ff00,
|
|
||||||
11: 0xffff00,
|
|
||||||
12: 0x0000ff,
|
|
||||||
13: 0xff00ff,
|
|
||||||
14: 0x00ffff,
|
|
||||||
15: 0xffffff,
|
|
||||||
16: 0x000000,
|
|
||||||
17: 0x00005f,
|
|
||||||
18: 0x000087,
|
|
||||||
19: 0x0000af,
|
|
||||||
20: 0x0000d7,
|
|
||||||
21: 0x0000ff,
|
|
||||||
22: 0x005f00,
|
|
||||||
23: 0x005f5f,
|
|
||||||
24: 0x005f87,
|
|
||||||
25: 0x005faf,
|
|
||||||
26: 0x005fd7,
|
|
||||||
27: 0x005fff,
|
|
||||||
28: 0x008700,
|
|
||||||
29: 0x00875f,
|
|
||||||
30: 0x008787,
|
|
||||||
31: 0x0087af,
|
|
||||||
32: 0x0087d7,
|
|
||||||
33: 0x0087ff,
|
|
||||||
34: 0x00af00,
|
|
||||||
35: 0x00af5f,
|
|
||||||
36: 0x00af87,
|
|
||||||
37: 0x00afaf,
|
|
||||||
38: 0x00afd7,
|
|
||||||
39: 0x00afff,
|
|
||||||
40: 0x00d700,
|
|
||||||
41: 0x00d75f,
|
|
||||||
42: 0x00d787,
|
|
||||||
43: 0x00d7af,
|
|
||||||
44: 0x00d7d7,
|
|
||||||
45: 0x00d7ff,
|
|
||||||
46: 0x00ff00,
|
|
||||||
47: 0x00ff5f,
|
|
||||||
48: 0x00ff87,
|
|
||||||
49: 0x00ffaf,
|
|
||||||
50: 0x00ffd7,
|
|
||||||
51: 0x00ffff,
|
|
||||||
52: 0x5f0000,
|
|
||||||
53: 0x5f005f,
|
|
||||||
54: 0x5f0087,
|
|
||||||
55: 0x5f00af,
|
|
||||||
56: 0x5f00d7,
|
|
||||||
57: 0x5f00ff,
|
|
||||||
58: 0x5f5f00,
|
|
||||||
59: 0x5f5f5f,
|
|
||||||
60: 0x5f5f87,
|
|
||||||
61: 0x5f5faf,
|
|
||||||
62: 0x5f5fd7,
|
|
||||||
63: 0x5f5fff,
|
|
||||||
64: 0x5f8700,
|
|
||||||
65: 0x5f875f,
|
|
||||||
66: 0x5f8787,
|
|
||||||
67: 0x5f87af,
|
|
||||||
68: 0x5f87d7,
|
|
||||||
69: 0x5f87ff,
|
|
||||||
70: 0x5faf00,
|
|
||||||
71: 0x5faf5f,
|
|
||||||
72: 0x5faf87,
|
|
||||||
73: 0x5fafaf,
|
|
||||||
74: 0x5fafd7,
|
|
||||||
75: 0x5fafff,
|
|
||||||
76: 0x5fd700,
|
|
||||||
77: 0x5fd75f,
|
|
||||||
78: 0x5fd787,
|
|
||||||
79: 0x5fd7af,
|
|
||||||
80: 0x5fd7d7,
|
|
||||||
81: 0x5fd7ff,
|
|
||||||
82: 0x5fff00,
|
|
||||||
83: 0x5fff5f,
|
|
||||||
84: 0x5fff87,
|
|
||||||
85: 0x5fffaf,
|
|
||||||
86: 0x5fffd7,
|
|
||||||
87: 0x5fffff,
|
|
||||||
88: 0x870000,
|
|
||||||
89: 0x87005f,
|
|
||||||
90: 0x870087,
|
|
||||||
91: 0x8700af,
|
|
||||||
92: 0x8700d7,
|
|
||||||
93: 0x8700ff,
|
|
||||||
94: 0x875f00,
|
|
||||||
95: 0x875f5f,
|
|
||||||
96: 0x875f87,
|
|
||||||
97: 0x875faf,
|
|
||||||
98: 0x875fd7,
|
|
||||||
99: 0x875fff,
|
|
||||||
100: 0x878700,
|
|
||||||
101: 0x87875f,
|
|
||||||
102: 0x878787,
|
|
||||||
103: 0x8787af,
|
|
||||||
104: 0x8787d7,
|
|
||||||
105: 0x8787ff,
|
|
||||||
106: 0x87af00,
|
|
||||||
107: 0x87af5f,
|
|
||||||
108: 0x87af87,
|
|
||||||
109: 0x87afaf,
|
|
||||||
110: 0x87afd7,
|
|
||||||
111: 0x87afff,
|
|
||||||
112: 0x87d700,
|
|
||||||
113: 0x87d75f,
|
|
||||||
114: 0x87d787,
|
|
||||||
115: 0x87d7af,
|
|
||||||
116: 0x87d7d7,
|
|
||||||
117: 0x87d7ff,
|
|
||||||
118: 0x87ff00,
|
|
||||||
119: 0x87ff5f,
|
|
||||||
120: 0x87ff87,
|
|
||||||
121: 0x87ffaf,
|
|
||||||
122: 0x87ffd7,
|
|
||||||
123: 0x87ffff,
|
|
||||||
124: 0xaf0000,
|
|
||||||
125: 0xaf005f,
|
|
||||||
126: 0xaf0087,
|
|
||||||
127: 0xaf00af,
|
|
||||||
128: 0xaf00d7,
|
|
||||||
129: 0xaf00ff,
|
|
||||||
130: 0xaf5f00,
|
|
||||||
131: 0xaf5f5f,
|
|
||||||
132: 0xaf5f87,
|
|
||||||
133: 0xaf5faf,
|
|
||||||
134: 0xaf5fd7,
|
|
||||||
135: 0xaf5fff,
|
|
||||||
136: 0xaf8700,
|
|
||||||
137: 0xaf875f,
|
|
||||||
138: 0xaf8787,
|
|
||||||
139: 0xaf87af,
|
|
||||||
140: 0xaf87d7,
|
|
||||||
141: 0xaf87ff,
|
|
||||||
142: 0xafaf00,
|
|
||||||
143: 0xafaf5f,
|
|
||||||
144: 0xafaf87,
|
|
||||||
145: 0xafafaf,
|
|
||||||
146: 0xafafd7,
|
|
||||||
147: 0xafafff,
|
|
||||||
148: 0xafd700,
|
|
||||||
149: 0xafd75f,
|
|
||||||
150: 0xafd787,
|
|
||||||
151: 0xafd7af,
|
|
||||||
152: 0xafd7d7,
|
|
||||||
153: 0xafd7ff,
|
|
||||||
154: 0xafff00,
|
|
||||||
155: 0xafff5f,
|
|
||||||
156: 0xafff87,
|
|
||||||
157: 0xafffaf,
|
|
||||||
158: 0xafffd7,
|
|
||||||
159: 0xafffff,
|
|
||||||
160: 0xd70000,
|
|
||||||
161: 0xd7005f,
|
|
||||||
162: 0xd70087,
|
|
||||||
163: 0xd700af,
|
|
||||||
164: 0xd700d7,
|
|
||||||
165: 0xd700ff,
|
|
||||||
166: 0xd75f00,
|
|
||||||
167: 0xd75f5f,
|
|
||||||
168: 0xd75f87,
|
|
||||||
169: 0xd75faf,
|
|
||||||
170: 0xd75fd7,
|
|
||||||
171: 0xd75fff,
|
|
||||||
172: 0xd78700,
|
|
||||||
173: 0xd7875f,
|
|
||||||
174: 0xd78787,
|
|
||||||
175: 0xd787af,
|
|
||||||
176: 0xd787d7,
|
|
||||||
177: 0xd787ff,
|
|
||||||
178: 0xd7af00,
|
|
||||||
179: 0xd7af5f,
|
|
||||||
180: 0xd7af87,
|
|
||||||
181: 0xd7afaf,
|
|
||||||
182: 0xd7afd7,
|
|
||||||
183: 0xd7afff,
|
|
||||||
184: 0xd7d700,
|
|
||||||
185: 0xd7d75f,
|
|
||||||
186: 0xd7d787,
|
|
||||||
187: 0xd7d7af,
|
|
||||||
188: 0xd7d7d7,
|
|
||||||
189: 0xd7d7ff,
|
|
||||||
190: 0xd7ff00,
|
|
||||||
191: 0xd7ff5f,
|
|
||||||
192: 0xd7ff87,
|
|
||||||
193: 0xd7ffaf,
|
|
||||||
194: 0xd7ffd7,
|
|
||||||
195: 0xd7ffff,
|
|
||||||
196: 0xff0000,
|
|
||||||
197: 0xff005f,
|
|
||||||
198: 0xff0087,
|
|
||||||
199: 0xff00af,
|
|
||||||
200: 0xff00d7,
|
|
||||||
201: 0xff00ff,
|
|
||||||
202: 0xff5f00,
|
|
||||||
203: 0xff5f5f,
|
|
||||||
204: 0xff5f87,
|
|
||||||
205: 0xff5faf,
|
|
||||||
206: 0xff5fd7,
|
|
||||||
207: 0xff5fff,
|
|
||||||
208: 0xff8700,
|
|
||||||
209: 0xff875f,
|
|
||||||
210: 0xff8787,
|
|
||||||
211: 0xff87af,
|
|
||||||
212: 0xff87d7,
|
|
||||||
213: 0xff87ff,
|
|
||||||
214: 0xffaf00,
|
|
||||||
215: 0xffaf5f,
|
|
||||||
216: 0xffaf87,
|
|
||||||
217: 0xffafaf,
|
|
||||||
218: 0xffafd7,
|
|
||||||
219: 0xffafff,
|
|
||||||
220: 0xffd700,
|
|
||||||
221: 0xffd75f,
|
|
||||||
222: 0xffd787,
|
|
||||||
223: 0xffd7af,
|
|
||||||
224: 0xffd7d7,
|
|
||||||
225: 0xffd7ff,
|
|
||||||
226: 0xffff00,
|
|
||||||
227: 0xffff5f,
|
|
||||||
228: 0xffff87,
|
|
||||||
229: 0xffffaf,
|
|
||||||
230: 0xffffd7,
|
|
||||||
231: 0xffffff,
|
|
||||||
232: 0x080808,
|
|
||||||
233: 0x121212,
|
|
||||||
234: 0x1c1c1c,
|
|
||||||
235: 0x262626,
|
|
||||||
236: 0x303030,
|
|
||||||
237: 0x3a3a3a,
|
|
||||||
238: 0x444444,
|
|
||||||
239: 0x4e4e4e,
|
|
||||||
240: 0x585858,
|
|
||||||
241: 0x626262,
|
|
||||||
242: 0x6c6c6c,
|
|
||||||
243: 0x767676,
|
|
||||||
244: 0x808080,
|
|
||||||
245: 0x8a8a8a,
|
|
||||||
246: 0x949494,
|
|
||||||
247: 0x9e9e9e,
|
|
||||||
248: 0xa8a8a8,
|
|
||||||
249: 0xb2b2b2,
|
|
||||||
250: 0xbcbcbc,
|
|
||||||
251: 0xc6c6c6,
|
|
||||||
252: 0xd0d0d0,
|
|
||||||
253: 0xdadada,
|
|
||||||
254: 0xe4e4e4,
|
|
||||||
255: 0xeeeeee,
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Writer) Write(data []byte) (n int, err error) {
|
|
||||||
var csbi consoleScreenBufferInfo
|
|
||||||
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
|
||||||
|
|
||||||
er := bytes.NewBuffer(data)
|
|
||||||
loop:
|
|
||||||
for {
|
|
||||||
r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
|
|
||||||
if r1 == 0 {
|
|
||||||
break loop
|
|
||||||
}
|
|
||||||
|
|
||||||
c1, _, err := er.ReadRune()
|
|
||||||
if err != nil {
|
|
||||||
break loop
|
|
||||||
}
|
|
||||||
if c1 != 0x1b {
|
|
||||||
fmt.Fprint(w.out, string(c1))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c2, _, err := er.ReadRune()
|
|
||||||
if err != nil {
|
|
||||||
w.lastbuf.WriteRune(c1)
|
|
||||||
break loop
|
|
||||||
}
|
|
||||||
if c2 != 0x5b {
|
|
||||||
w.lastbuf.WriteRune(c1)
|
|
||||||
w.lastbuf.WriteRune(c2)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
var m rune
|
|
||||||
for {
|
|
||||||
c, _, err := er.ReadRune()
|
|
||||||
if err != nil {
|
|
||||||
w.lastbuf.WriteRune(c1)
|
|
||||||
w.lastbuf.WriteRune(c2)
|
|
||||||
w.lastbuf.Write(buf.Bytes())
|
|
||||||
break loop
|
|
||||||
}
|
|
||||||
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
|
|
||||||
m = c
|
|
||||||
break
|
|
||||||
}
|
|
||||||
buf.Write([]byte(string(c)))
|
|
||||||
}
|
|
||||||
|
|
||||||
switch m {
|
|
||||||
case 'm':
|
|
||||||
attr := csbi.attributes
|
|
||||||
cs := buf.String()
|
|
||||||
if cs == "" {
|
|
||||||
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
token := strings.Split(cs, ";")
|
|
||||||
for i, ns := range token {
|
|
||||||
if n, err = strconv.Atoi(ns); err == nil {
|
|
||||||
switch {
|
|
||||||
case n == 0 || n == 100:
|
|
||||||
attr = w.oldattr
|
|
||||||
case 1 <= n && n <= 5:
|
|
||||||
attr |= foregroundIntensity
|
|
||||||
case n == 7:
|
|
||||||
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
|
|
||||||
case 22 == n || n == 25 || n == 25:
|
|
||||||
attr |= foregroundIntensity
|
|
||||||
case n == 27:
|
|
||||||
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
|
|
||||||
case 30 <= n && n <= 37:
|
|
||||||
attr = (attr & backgroundMask)
|
|
||||||
if (n-30)&1 != 0 {
|
|
||||||
attr |= foregroundRed
|
|
||||||
}
|
|
||||||
if (n-30)&2 != 0 {
|
|
||||||
attr |= foregroundGreen
|
|
||||||
}
|
|
||||||
if (n-30)&4 != 0 {
|
|
||||||
attr |= foregroundBlue
|
|
||||||
}
|
|
||||||
case n == 38: // set foreground color.
|
|
||||||
if i < len(token)-2 && token[i+1] == "5" {
|
|
||||||
if n256, err := strconv.Atoi(token[i+2]); err == nil {
|
|
||||||
if n256foreAttr == nil {
|
|
||||||
n256setup()
|
|
||||||
}
|
|
||||||
attr &= backgroundMask
|
|
||||||
attr |= n256foreAttr[n256]
|
|
||||||
i += 2
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
attr = attr & (w.oldattr & backgroundMask)
|
|
||||||
}
|
|
||||||
case n == 39: // reset foreground color.
|
|
||||||
attr &= backgroundMask
|
|
||||||
attr |= w.oldattr & foregroundMask
|
|
||||||
case 40 <= n && n <= 47:
|
|
||||||
attr = (attr & foregroundMask)
|
|
||||||
if (n-40)&1 != 0 {
|
|
||||||
attr |= backgroundRed
|
|
||||||
}
|
|
||||||
if (n-40)&2 != 0 {
|
|
||||||
attr |= backgroundGreen
|
|
||||||
}
|
|
||||||
if (n-40)&4 != 0 {
|
|
||||||
attr |= backgroundBlue
|
|
||||||
}
|
|
||||||
case n == 48: // set background color.
|
|
||||||
if i < len(token)-2 && token[i+1] == "5" {
|
|
||||||
if n256, err := strconv.Atoi(token[i+2]); err == nil {
|
|
||||||
if n256backAttr == nil {
|
|
||||||
n256setup()
|
|
||||||
}
|
|
||||||
attr &= foregroundMask
|
|
||||||
attr |= n256backAttr[n256]
|
|
||||||
i += 2
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
attr = attr & (w.oldattr & foregroundMask)
|
|
||||||
}
|
|
||||||
case n == 49: // reset foreground color.
|
|
||||||
attr &= foregroundMask
|
|
||||||
attr |= w.oldattr & backgroundMask
|
|
||||||
}
|
|
||||||
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return len(data) - w.lastbuf.Len(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type consoleColor struct {
|
|
||||||
red bool
|
|
||||||
green bool
|
|
||||||
blue bool
|
|
||||||
intensity bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func minmax3(a, b, c int) (min, max int) {
|
|
||||||
if a < b {
|
|
||||||
if b < c {
|
|
||||||
return a, c
|
|
||||||
} else if a < c {
|
|
||||||
return a, b
|
|
||||||
} else {
|
|
||||||
return c, b
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if a < c {
|
|
||||||
return b, c
|
|
||||||
} else if b < c {
|
|
||||||
return b, a
|
|
||||||
} else {
|
|
||||||
return c, a
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toConsoleColor(rgb int) (c consoleColor) {
|
|
||||||
r, g, b := (rgb&0xFF0000)>>16, (rgb&0x00FF00)>>8, rgb&0x0000FF
|
|
||||||
min, max := minmax3(r, g, b)
|
|
||||||
a := (min + max) / 2
|
|
||||||
if r < 128 && g < 128 && b < 128 {
|
|
||||||
if r >= a {
|
|
||||||
c.red = true
|
|
||||||
}
|
|
||||||
if g >= a {
|
|
||||||
c.green = true
|
|
||||||
}
|
|
||||||
if b >= a {
|
|
||||||
c.blue = true
|
|
||||||
}
|
|
||||||
// non-intensed white is lighter than intensed black, so swap those.
|
|
||||||
if c.red && c.green && c.blue {
|
|
||||||
c.red, c.green, c.blue = false, false, false
|
|
||||||
c.intensity = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if min < 128 {
|
|
||||||
min = 128
|
|
||||||
a = (min + max) / 2
|
|
||||||
}
|
|
||||||
if r >= a {
|
|
||||||
c.red = true
|
|
||||||
}
|
|
||||||
if g >= a {
|
|
||||||
c.green = true
|
|
||||||
}
|
|
||||||
if b >= a {
|
|
||||||
c.blue = true
|
|
||||||
}
|
|
||||||
c.intensity = true
|
|
||||||
// intensed black is darker than non-intensed white, so swap those.
|
|
||||||
if !c.red && !c.green && !c.blue {
|
|
||||||
c.red, c.green, c.blue = true, true, true
|
|
||||||
c.intensity = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c consoleColor) foregroundAttr() (attr word) {
|
|
||||||
if c.red {
|
|
||||||
attr |= foregroundRed
|
|
||||||
}
|
|
||||||
if c.green {
|
|
||||||
attr |= foregroundGreen
|
|
||||||
}
|
|
||||||
if c.blue {
|
|
||||||
attr |= foregroundBlue
|
|
||||||
}
|
|
||||||
if c.intensity {
|
|
||||||
attr |= foregroundIntensity
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c consoleColor) backgroundAttr() (attr word) {
|
|
||||||
if c.red {
|
|
||||||
attr |= backgroundRed
|
|
||||||
}
|
|
||||||
if c.green {
|
|
||||||
attr |= backgroundGreen
|
|
||||||
}
|
|
||||||
if c.blue {
|
|
||||||
attr |= backgroundBlue
|
|
||||||
}
|
|
||||||
if c.intensity {
|
|
||||||
attr |= backgroundIntensity
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var n256foreAttr []word
|
|
||||||
var n256backAttr []word
|
|
||||||
|
|
||||||
func n256setup() {
|
|
||||||
n256foreAttr = make([]word, 256)
|
|
||||||
n256backAttr = make([]word, 256)
|
|
||||||
for i, rgb := range color256 {
|
|
||||||
c := toConsoleColor(rgb)
|
|
||||||
n256foreAttr[i] = c.foregroundAttr()
|
|
||||||
n256backAttr[i] = c.backgroundAttr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
27
Godeps/_workspace/src/github.com/shiena/ansicolor/.gitignore
generated
vendored
Normal file
27
Godeps/_workspace/src/github.com/shiena/ansicolor/.gitignore
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Created by http://www.gitignore.io
|
||||||
|
|
||||||
|
### Go ###
|
||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
|
||||||
21
Godeps/_workspace/src/github.com/shiena/ansicolor/LICENSE
generated
vendored
Normal file
21
Godeps/_workspace/src/github.com/shiena/ansicolor/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) [2014] [shiena]
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
100
Godeps/_workspace/src/github.com/shiena/ansicolor/README.md
generated
vendored
Normal file
100
Godeps/_workspace/src/github.com/shiena/ansicolor/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
[](https://godoc.org/github.com/shiena/ansicolor)
|
||||||
|
|
||||||
|
# ansicolor
|
||||||
|
|
||||||
|
Ansicolor library provides color console in Windows as ANSICON for Golang.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
|Escape sequence|Text attributes|
|
||||||
|
|---------------|----|
|
||||||
|
|\x1b[0m|All attributes off(color at startup)|
|
||||||
|
|\x1b[1m|Bold on(enable foreground intensity)|
|
||||||
|
|\x1b[4m|Underline on|
|
||||||
|
|\x1b[5m|Blink on(enable background intensity)|
|
||||||
|
|\x1b[21m|Bold off(disable foreground intensity)|
|
||||||
|
|\x1b[24m|Underline off|
|
||||||
|
|\x1b[25m|Blink off(disable background intensity)|
|
||||||
|
|
||||||
|
|Escape sequence|Foreground colors|
|
||||||
|
|---------------|----|
|
||||||
|
|\x1b[30m|Black|
|
||||||
|
|\x1b[31m|Red|
|
||||||
|
|\x1b[32m|Green|
|
||||||
|
|\x1b[33m|Yellow|
|
||||||
|
|\x1b[34m|Blue|
|
||||||
|
|\x1b[35m|Magenta|
|
||||||
|
|\x1b[36m|Cyan|
|
||||||
|
|\x1b[37m|White|
|
||||||
|
|\x1b[39m|Default(foreground color at startup)|
|
||||||
|
|\x1b[90m|Light Gray|
|
||||||
|
|\x1b[91m|Light Red|
|
||||||
|
|\x1b[92m|Light Green|
|
||||||
|
|\x1b[93m|Light Yellow|
|
||||||
|
|\x1b[94m|Light Blue|
|
||||||
|
|\x1b[95m|Light Magenta|
|
||||||
|
|\x1b[96m|Light Cyan|
|
||||||
|
|\x1b[97m|Light White|
|
||||||
|
|
||||||
|
|Escape sequence|Background colors|
|
||||||
|
|---------------|----|
|
||||||
|
|\x1b[40m|Black|
|
||||||
|
|\x1b[41m|Red|
|
||||||
|
|\x1b[42m|Green|
|
||||||
|
|\x1b[43m|Yellow|
|
||||||
|
|\x1b[44m|Blue|
|
||||||
|
|\x1b[45m|Magenta|
|
||||||
|
|\x1b[46m|Cyan|
|
||||||
|
|\x1b[47m|White|
|
||||||
|
|\x1b[49m|Default(background color at startup)|
|
||||||
|
|\x1b[100m|Light Gray|
|
||||||
|
|\x1b[101m|Light Red|
|
||||||
|
|\x1b[102m|Light Green|
|
||||||
|
|\x1b[103m|Light Yellow|
|
||||||
|
|\x1b[104m|Light Blue|
|
||||||
|
|\x1b[105m|Light Magenta|
|
||||||
|
|\x1b[106m|Light Cyan|
|
||||||
|
|\x1b[107m|Light White|
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/shiena/ansicolor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
w := ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||||
|
text := "%sforeground %sbold%s %sbackground%s\n"
|
||||||
|
fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## See also:
|
||||||
|
|
||||||
|
- https://github.com/daviddengcn/go-colortext
|
||||||
|
- https://github.com/adoxa/ansicon
|
||||||
|
- https://github.com/aslakhellesoy/wac
|
||||||
|
- https://github.com/wsxiaoys/terminal
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
1. Fork it
|
||||||
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||||
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||||
|
4. Push to the branch (`git push origin my-new-feature`)
|
||||||
|
5. Create new Pull Request
|
||||||
|
|
||||||
20
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor.go
generated
vendored
Normal file
20
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor.go
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2014 shiena Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package ansicolor provides color console in Windows as ANSICON.
|
||||||
|
package ansicolor
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
// NewAnsiColorWriter creates and initializes a new ansiColorWriter
|
||||||
|
// using io.Writer w as its initial contents.
|
||||||
|
// In the console of Windows, which change the foreground and background
|
||||||
|
// colors of the text by the escape sequence.
|
||||||
|
// In the console of other systems, which writes to w all text.
|
||||||
|
func NewAnsiColorWriter(w io.Writer) io.Writer {
|
||||||
|
if _, ok := w.(*ansiColorWriter); !ok {
|
||||||
|
return &ansiColorWriter{w: w}
|
||||||
|
}
|
||||||
|
return w
|
||||||
|
}
|
||||||
27
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor/main.go
generated
vendored
Normal file
27
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor/main.go
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2014 shiena Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
The ansicolor command colors a console text by ANSI escape sequence like wac.
|
||||||
|
|
||||||
|
$ go get github.com/shiena/ansicolor/ansicolor
|
||||||
|
|
||||||
|
See also:
|
||||||
|
https://github.com/aslakhellesoy/wac
|
||||||
|
|
||||||
|
*/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/shiena/ansicolor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
w := ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||||
|
io.Copy(w, os.Stdin)
|
||||||
|
}
|
||||||
17
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_ansi.go
generated
vendored
Normal file
17
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_ansi.go
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2014 shiena Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package ansicolor
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
type ansiColorWriter struct {
|
||||||
|
w io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cw *ansiColorWriter) Write(p []byte) (int, error) {
|
||||||
|
return cw.w.Write(p)
|
||||||
|
}
|
||||||
25
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_test.go
generated
vendored
Normal file
25
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
package ansicolor_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/shiena/ansicolor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewAnsiColor1(t *testing.T) {
|
||||||
|
inner := bytes.NewBufferString("")
|
||||||
|
w := ansicolor.NewAnsiColorWriter(inner)
|
||||||
|
if w == inner {
|
||||||
|
t.Errorf("Get %#v, want %#v", w, inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewAnsiColor2(t *testing.T) {
|
||||||
|
inner := bytes.NewBufferString("")
|
||||||
|
w1 := ansicolor.NewAnsiColorWriter(inner)
|
||||||
|
w2 := ansicolor.NewAnsiColorWriter(w1)
|
||||||
|
if w1 != w2 {
|
||||||
|
t.Errorf("Get %#v, want %#v", w1, w2)
|
||||||
|
}
|
||||||
|
}
|
||||||
351
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_windows.go
generated
vendored
Normal file
351
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_windows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,351 @@
|
||||||
|
// Copyright 2014 shiena Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package ansicolor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type csiState int
|
||||||
|
|
||||||
|
const (
|
||||||
|
outsideCsiCode csiState = iota
|
||||||
|
firstCsiCode
|
||||||
|
secondCsiCode
|
||||||
|
)
|
||||||
|
|
||||||
|
type ansiColorWriter struct {
|
||||||
|
w io.Writer
|
||||||
|
state csiState
|
||||||
|
paramBuf bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
firstCsiChar byte = '\x1b'
|
||||||
|
secondeCsiChar byte = '['
|
||||||
|
separatorChar byte = ';'
|
||||||
|
sgrCode byte = 'm'
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
foregroundBlue = uint16(0x0001)
|
||||||
|
foregroundGreen = uint16(0x0002)
|
||||||
|
foregroundRed = uint16(0x0004)
|
||||||
|
foregroundIntensity = uint16(0x0008)
|
||||||
|
backgroundBlue = uint16(0x0010)
|
||||||
|
backgroundGreen = uint16(0x0020)
|
||||||
|
backgroundRed = uint16(0x0040)
|
||||||
|
backgroundIntensity = uint16(0x0080)
|
||||||
|
underscore = uint16(0x8000)
|
||||||
|
|
||||||
|
foregroundMask = foregroundBlue | foregroundGreen | foregroundRed | foregroundIntensity
|
||||||
|
backgroundMask = backgroundBlue | backgroundGreen | backgroundRed | backgroundIntensity
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ansiReset = "0"
|
||||||
|
ansiIntensityOn = "1"
|
||||||
|
ansiIntensityOff = "21"
|
||||||
|
ansiUnderlineOn = "4"
|
||||||
|
ansiUnderlineOff = "24"
|
||||||
|
ansiBlinkOn = "5"
|
||||||
|
ansiBlinkOff = "25"
|
||||||
|
|
||||||
|
ansiForegroundBlack = "30"
|
||||||
|
ansiForegroundRed = "31"
|
||||||
|
ansiForegroundGreen = "32"
|
||||||
|
ansiForegroundYellow = "33"
|
||||||
|
ansiForegroundBlue = "34"
|
||||||
|
ansiForegroundMagenta = "35"
|
||||||
|
ansiForegroundCyan = "36"
|
||||||
|
ansiForegroundWhite = "37"
|
||||||
|
ansiForegroundDefault = "39"
|
||||||
|
|
||||||
|
ansiBackgroundBlack = "40"
|
||||||
|
ansiBackgroundRed = "41"
|
||||||
|
ansiBackgroundGreen = "42"
|
||||||
|
ansiBackgroundYellow = "43"
|
||||||
|
ansiBackgroundBlue = "44"
|
||||||
|
ansiBackgroundMagenta = "45"
|
||||||
|
ansiBackgroundCyan = "46"
|
||||||
|
ansiBackgroundWhite = "47"
|
||||||
|
ansiBackgroundDefault = "49"
|
||||||
|
|
||||||
|
ansiLightForegroundGray = "90"
|
||||||
|
ansiLightForegroundRed = "91"
|
||||||
|
ansiLightForegroundGreen = "92"
|
||||||
|
ansiLightForegroundYellow = "93"
|
||||||
|
ansiLightForegroundBlue = "94"
|
||||||
|
ansiLightForegroundMagenta = "95"
|
||||||
|
ansiLightForegroundCyan = "96"
|
||||||
|
ansiLightForegroundWhite = "97"
|
||||||
|
|
||||||
|
ansiLightBackgroundGray = "100"
|
||||||
|
ansiLightBackgroundRed = "101"
|
||||||
|
ansiLightBackgroundGreen = "102"
|
||||||
|
ansiLightBackgroundYellow = "103"
|
||||||
|
ansiLightBackgroundBlue = "104"
|
||||||
|
ansiLightBackgroundMagenta = "105"
|
||||||
|
ansiLightBackgroundCyan = "106"
|
||||||
|
ansiLightBackgroundWhite = "107"
|
||||||
|
)
|
||||||
|
|
||||||
|
type drawType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
foreground drawType = iota
|
||||||
|
background
|
||||||
|
)
|
||||||
|
|
||||||
|
type winColor struct {
|
||||||
|
code uint16
|
||||||
|
drawType drawType
|
||||||
|
}
|
||||||
|
|
||||||
|
var colorMap = map[string]winColor{
|
||||||
|
ansiForegroundBlack: {0, foreground},
|
||||||
|
ansiForegroundRed: {foregroundRed, foreground},
|
||||||
|
ansiForegroundGreen: {foregroundGreen, foreground},
|
||||||
|
ansiForegroundYellow: {foregroundRed | foregroundGreen, foreground},
|
||||||
|
ansiForegroundBlue: {foregroundBlue, foreground},
|
||||||
|
ansiForegroundMagenta: {foregroundRed | foregroundBlue, foreground},
|
||||||
|
ansiForegroundCyan: {foregroundGreen | foregroundBlue, foreground},
|
||||||
|
ansiForegroundWhite: {foregroundRed | foregroundGreen | foregroundBlue, foreground},
|
||||||
|
ansiForegroundDefault: {foregroundRed | foregroundGreen | foregroundBlue, foreground},
|
||||||
|
|
||||||
|
ansiBackgroundBlack: {0, background},
|
||||||
|
ansiBackgroundRed: {backgroundRed, background},
|
||||||
|
ansiBackgroundGreen: {backgroundGreen, background},
|
||||||
|
ansiBackgroundYellow: {backgroundRed | backgroundGreen, background},
|
||||||
|
ansiBackgroundBlue: {backgroundBlue, background},
|
||||||
|
ansiBackgroundMagenta: {backgroundRed | backgroundBlue, background},
|
||||||
|
ansiBackgroundCyan: {backgroundGreen | backgroundBlue, background},
|
||||||
|
ansiBackgroundWhite: {backgroundRed | backgroundGreen | backgroundBlue, background},
|
||||||
|
ansiBackgroundDefault: {0, background},
|
||||||
|
|
||||||
|
ansiLightForegroundGray: {foregroundIntensity, foreground},
|
||||||
|
ansiLightForegroundRed: {foregroundIntensity | foregroundRed, foreground},
|
||||||
|
ansiLightForegroundGreen: {foregroundIntensity | foregroundGreen, foreground},
|
||||||
|
ansiLightForegroundYellow: {foregroundIntensity | foregroundRed | foregroundGreen, foreground},
|
||||||
|
ansiLightForegroundBlue: {foregroundIntensity | foregroundBlue, foreground},
|
||||||
|
ansiLightForegroundMagenta: {foregroundIntensity | foregroundRed | foregroundBlue, foreground},
|
||||||
|
ansiLightForegroundCyan: {foregroundIntensity | foregroundGreen | foregroundBlue, foreground},
|
||||||
|
ansiLightForegroundWhite: {foregroundIntensity | foregroundRed | foregroundGreen | foregroundBlue, foreground},
|
||||||
|
|
||||||
|
ansiLightBackgroundGray: {backgroundIntensity, background},
|
||||||
|
ansiLightBackgroundRed: {backgroundIntensity | backgroundRed, background},
|
||||||
|
ansiLightBackgroundGreen: {backgroundIntensity | backgroundGreen, background},
|
||||||
|
ansiLightBackgroundYellow: {backgroundIntensity | backgroundRed | backgroundGreen, background},
|
||||||
|
ansiLightBackgroundBlue: {backgroundIntensity | backgroundBlue, background},
|
||||||
|
ansiLightBackgroundMagenta: {backgroundIntensity | backgroundRed | backgroundBlue, background},
|
||||||
|
ansiLightBackgroundCyan: {backgroundIntensity | backgroundGreen | backgroundBlue, background},
|
||||||
|
ansiLightBackgroundWhite: {backgroundIntensity | backgroundRed | backgroundGreen | backgroundBlue, background},
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
|
||||||
|
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||||
|
defaultAttr *textAttributes
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||||
|
if screenInfo != nil {
|
||||||
|
colorMap[ansiForegroundDefault] = winColor{
|
||||||
|
screenInfo.WAttributes & (foregroundRed | foregroundGreen | foregroundBlue),
|
||||||
|
foreground,
|
||||||
|
}
|
||||||
|
colorMap[ansiBackgroundDefault] = winColor{
|
||||||
|
screenInfo.WAttributes & (backgroundRed | backgroundGreen | backgroundBlue),
|
||||||
|
background,
|
||||||
|
}
|
||||||
|
defaultAttr = convertTextAttr(screenInfo.WAttributes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type coord struct {
|
||||||
|
X, Y int16
|
||||||
|
}
|
||||||
|
|
||||||
|
type smallRect struct {
|
||||||
|
Left, Top, Right, Bottom int16
|
||||||
|
}
|
||||||
|
|
||||||
|
type consoleScreenBufferInfo struct {
|
||||||
|
DwSize coord
|
||||||
|
DwCursorPosition coord
|
||||||
|
WAttributes uint16
|
||||||
|
SrWindow smallRect
|
||||||
|
DwMaximumWindowSize coord
|
||||||
|
}
|
||||||
|
|
||||||
|
func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *consoleScreenBufferInfo {
|
||||||
|
var csbi consoleScreenBufferInfo
|
||||||
|
ret, _, _ := procGetConsoleScreenBufferInfo.Call(
|
||||||
|
hConsoleOutput,
|
||||||
|
uintptr(unsafe.Pointer(&csbi)))
|
||||||
|
if ret == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &csbi
|
||||||
|
}
|
||||||
|
|
||||||
|
func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool {
|
||||||
|
ret, _, _ := procSetConsoleTextAttribute.Call(
|
||||||
|
hConsoleOutput,
|
||||||
|
uintptr(wAttributes))
|
||||||
|
return ret != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type textAttributes struct {
|
||||||
|
foregroundColor uint16
|
||||||
|
backgroundColor uint16
|
||||||
|
foregroundIntensity uint16
|
||||||
|
backgroundIntensity uint16
|
||||||
|
underscore uint16
|
||||||
|
otherAttributes uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertTextAttr(winAttr uint16) *textAttributes {
|
||||||
|
fgColor := winAttr & (foregroundRed | foregroundGreen | foregroundBlue)
|
||||||
|
bgColor := winAttr & (backgroundRed | backgroundGreen | backgroundBlue)
|
||||||
|
fgIntensity := winAttr & foregroundIntensity
|
||||||
|
bgIntensity := winAttr & backgroundIntensity
|
||||||
|
underline := winAttr & underscore
|
||||||
|
otherAttributes := winAttr &^ (foregroundMask | backgroundMask | underscore)
|
||||||
|
return &textAttributes{fgColor, bgColor, fgIntensity, bgIntensity, underline, otherAttributes}
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertWinAttr(textAttr *textAttributes) uint16 {
|
||||||
|
var winAttr uint16 = 0
|
||||||
|
winAttr |= textAttr.foregroundColor
|
||||||
|
winAttr |= textAttr.backgroundColor
|
||||||
|
winAttr |= textAttr.foregroundIntensity
|
||||||
|
winAttr |= textAttr.backgroundIntensity
|
||||||
|
winAttr |= textAttr.underscore
|
||||||
|
winAttr |= textAttr.otherAttributes
|
||||||
|
return winAttr
|
||||||
|
}
|
||||||
|
|
||||||
|
func changeColor(param []byte) {
|
||||||
|
if defaultAttr == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||||
|
if screenInfo == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
winAttr := convertTextAttr(screenInfo.WAttributes)
|
||||||
|
strParam := string(param)
|
||||||
|
if len(strParam) <= 0 {
|
||||||
|
strParam = "0"
|
||||||
|
}
|
||||||
|
csiParam := strings.Split(strParam, string(separatorChar))
|
||||||
|
for _, p := range csiParam {
|
||||||
|
c, ok := colorMap[p]
|
||||||
|
switch {
|
||||||
|
case !ok:
|
||||||
|
switch p {
|
||||||
|
case ansiReset:
|
||||||
|
winAttr.foregroundColor = defaultAttr.foregroundColor
|
||||||
|
winAttr.backgroundColor = defaultAttr.backgroundColor
|
||||||
|
winAttr.foregroundIntensity = defaultAttr.foregroundIntensity
|
||||||
|
winAttr.backgroundIntensity = defaultAttr.backgroundIntensity
|
||||||
|
winAttr.underscore = 0
|
||||||
|
winAttr.otherAttributes = 0
|
||||||
|
case ansiIntensityOn:
|
||||||
|
winAttr.foregroundIntensity = foregroundIntensity
|
||||||
|
case ansiIntensityOff:
|
||||||
|
winAttr.foregroundIntensity = 0
|
||||||
|
case ansiUnderlineOn:
|
||||||
|
winAttr.underscore = underscore
|
||||||
|
case ansiUnderlineOff:
|
||||||
|
winAttr.underscore = 0
|
||||||
|
case ansiBlinkOn:
|
||||||
|
winAttr.backgroundIntensity = backgroundIntensity
|
||||||
|
case ansiBlinkOff:
|
||||||
|
winAttr.backgroundIntensity = 0
|
||||||
|
default:
|
||||||
|
// unknown code
|
||||||
|
}
|
||||||
|
case c.drawType == foreground:
|
||||||
|
winAttr.foregroundColor = c.code
|
||||||
|
case c.drawType == background:
|
||||||
|
winAttr.backgroundColor = c.code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
winTextAttribute := convertWinAttr(winAttr)
|
||||||
|
setConsoleTextAttribute(uintptr(syscall.Stdout), winTextAttribute)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseEscapeSequence(command byte, param []byte) {
|
||||||
|
switch command {
|
||||||
|
case sgrCode:
|
||||||
|
changeColor(param)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isParameterChar(b byte) bool {
|
||||||
|
return ('0' <= b && b <= '9') || b == separatorChar
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cw *ansiColorWriter) Write(p []byte) (int, error) {
|
||||||
|
r, nw, nc, first, last := 0, 0, 0, 0, 0
|
||||||
|
var err error
|
||||||
|
for i, ch := range p {
|
||||||
|
switch cw.state {
|
||||||
|
case outsideCsiCode:
|
||||||
|
if ch == firstCsiChar {
|
||||||
|
nc++
|
||||||
|
cw.state = firstCsiCode
|
||||||
|
}
|
||||||
|
case firstCsiCode:
|
||||||
|
switch ch {
|
||||||
|
case firstCsiChar:
|
||||||
|
nc++
|
||||||
|
break
|
||||||
|
case secondeCsiChar:
|
||||||
|
nc++
|
||||||
|
cw.state = secondCsiCode
|
||||||
|
last = i - 1
|
||||||
|
default:
|
||||||
|
cw.state = outsideCsiCode
|
||||||
|
}
|
||||||
|
case secondCsiCode:
|
||||||
|
nc++
|
||||||
|
if isParameterChar(ch) {
|
||||||
|
cw.paramBuf.WriteByte(ch)
|
||||||
|
} else {
|
||||||
|
nw, err = cw.w.Write(p[first:last])
|
||||||
|
r += nw
|
||||||
|
if err != nil {
|
||||||
|
return r, err
|
||||||
|
}
|
||||||
|
first = i + 1
|
||||||
|
param := cw.paramBuf.Bytes()
|
||||||
|
cw.paramBuf.Reset()
|
||||||
|
parseEscapeSequence(ch, param)
|
||||||
|
cw.state = outsideCsiCode
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
cw.state = outsideCsiCode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cw.state == outsideCsiCode {
|
||||||
|
nw, err = cw.w.Write(p[first:len(p)])
|
||||||
|
}
|
||||||
|
|
||||||
|
return r + nw + nc, err
|
||||||
|
}
|
||||||
236
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_windows_test.go
generated
vendored
Normal file
236
Godeps/_workspace/src/github.com/shiena/ansicolor/ansicolor_windows_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,236 @@
|
||||||
|
// Copyright 2014 shiena Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package ansicolor_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/shiena/ansicolor"
|
||||||
|
. "github.com/shiena/ansicolor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWritePlanText(t *testing.T) {
|
||||||
|
inner := bytes.NewBufferString("")
|
||||||
|
w := ansicolor.NewAnsiColorWriter(inner)
|
||||||
|
expected := "plain text"
|
||||||
|
fmt.Fprintf(w, expected)
|
||||||
|
actual := inner.String()
|
||||||
|
if actual != expected {
|
||||||
|
t.Errorf("Get %s, want %s", actual, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteParseText(t *testing.T) {
|
||||||
|
inner := bytes.NewBufferString("")
|
||||||
|
w := ansicolor.NewAnsiColorWriter(inner)
|
||||||
|
|
||||||
|
inputTail := "\x1b[0mtail text"
|
||||||
|
expectedTail := "tail text"
|
||||||
|
fmt.Fprintf(w, inputTail)
|
||||||
|
actualTail := inner.String()
|
||||||
|
inner.Reset()
|
||||||
|
if actualTail != expectedTail {
|
||||||
|
t.Errorf("Get %s, want %s", actualTail, expectedTail)
|
||||||
|
}
|
||||||
|
|
||||||
|
inputHead := "head text\x1b[0m"
|
||||||
|
expectedHead := "head text"
|
||||||
|
fmt.Fprintf(w, inputHead)
|
||||||
|
actualHead := inner.String()
|
||||||
|
inner.Reset()
|
||||||
|
if actualHead != expectedHead {
|
||||||
|
t.Errorf("Get %s, want %s", actualHead, expectedHead)
|
||||||
|
}
|
||||||
|
|
||||||
|
inputBothEnds := "both ends \x1b[0m text"
|
||||||
|
expectedBothEnds := "both ends text"
|
||||||
|
fmt.Fprintf(w, inputBothEnds)
|
||||||
|
actualBothEnds := inner.String()
|
||||||
|
inner.Reset()
|
||||||
|
if actualBothEnds != expectedBothEnds {
|
||||||
|
t.Errorf("Get %s, want %s", actualBothEnds, expectedBothEnds)
|
||||||
|
}
|
||||||
|
|
||||||
|
inputManyEsc := "\x1b\x1b\x1b\x1b[0m many esc"
|
||||||
|
expectedManyEsc := "\x1b\x1b\x1b many esc"
|
||||||
|
fmt.Fprintf(w, inputManyEsc)
|
||||||
|
actualManyEsc := inner.String()
|
||||||
|
inner.Reset()
|
||||||
|
if actualManyEsc != expectedManyEsc {
|
||||||
|
t.Errorf("Get %s, want %s", actualManyEsc, expectedManyEsc)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedSplit := "split text"
|
||||||
|
for _, ch := range "split \x1b[0m text" {
|
||||||
|
fmt.Fprintf(w, string(ch))
|
||||||
|
}
|
||||||
|
actualSplit := inner.String()
|
||||||
|
inner.Reset()
|
||||||
|
if actualSplit != expectedSplit {
|
||||||
|
t.Errorf("Get %s, want %s", actualSplit, expectedSplit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type screenNotFoundError struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeAnsiColor(expectedText, colorCode string) (actualText string, actualAttributes uint16, err error) {
|
||||||
|
inner := bytes.NewBufferString("")
|
||||||
|
w := ansicolor.NewAnsiColorWriter(inner)
|
||||||
|
fmt.Fprintf(w, "\x1b[%sm%s", colorCode, expectedText)
|
||||||
|
|
||||||
|
actualText = inner.String()
|
||||||
|
screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||||
|
if screenInfo != nil {
|
||||||
|
actualAttributes = screenInfo.WAttributes
|
||||||
|
} else {
|
||||||
|
err = &screenNotFoundError{}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type testParam struct {
|
||||||
|
text string
|
||||||
|
attributes uint16
|
||||||
|
ansiColor string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteAnsiColorText(t *testing.T) {
|
||||||
|
screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout))
|
||||||
|
if screenInfo == nil {
|
||||||
|
t.Fatal("Could not get ConsoleScreenBufferInfo")
|
||||||
|
}
|
||||||
|
defer ChangeColor(screenInfo.WAttributes)
|
||||||
|
defaultFgColor := screenInfo.WAttributes & uint16(0x0007)
|
||||||
|
defaultBgColor := screenInfo.WAttributes & uint16(0x0070)
|
||||||
|
defaultFgIntensity := screenInfo.WAttributes & uint16(0x0008)
|
||||||
|
defaultBgIntensity := screenInfo.WAttributes & uint16(0x0080)
|
||||||
|
|
||||||
|
fgParam := []testParam{
|
||||||
|
{"foreground black ", uint16(0x0000 | 0x0000), "30"},
|
||||||
|
{"foreground red ", uint16(0x0004 | 0x0000), "31"},
|
||||||
|
{"foreground green ", uint16(0x0002 | 0x0000), "32"},
|
||||||
|
{"foreground yellow ", uint16(0x0006 | 0x0000), "33"},
|
||||||
|
{"foreground blue ", uint16(0x0001 | 0x0000), "34"},
|
||||||
|
{"foreground magenta", uint16(0x0005 | 0x0000), "35"},
|
||||||
|
{"foreground cyan ", uint16(0x0003 | 0x0000), "36"},
|
||||||
|
{"foreground white ", uint16(0x0007 | 0x0000), "37"},
|
||||||
|
{"foreground default", defaultFgColor | 0x0000, "39"},
|
||||||
|
{"foreground light gray ", uint16(0x0000 | 0x0008 | 0x0000), "90"},
|
||||||
|
{"foreground light red ", uint16(0x0004 | 0x0008 | 0x0000), "91"},
|
||||||
|
{"foreground light green ", uint16(0x0002 | 0x0008 | 0x0000), "92"},
|
||||||
|
{"foreground light yellow ", uint16(0x0006 | 0x0008 | 0x0000), "93"},
|
||||||
|
{"foreground light blue ", uint16(0x0001 | 0x0008 | 0x0000), "94"},
|
||||||
|
{"foreground light magenta", uint16(0x0005 | 0x0008 | 0x0000), "95"},
|
||||||
|
{"foreground light cyan ", uint16(0x0003 | 0x0008 | 0x0000), "96"},
|
||||||
|
{"foreground light white ", uint16(0x0007 | 0x0008 | 0x0000), "97"},
|
||||||
|
}
|
||||||
|
|
||||||
|
bgParam := []testParam{
|
||||||
|
{"background black ", uint16(0x0007 | 0x0000), "40"},
|
||||||
|
{"background red ", uint16(0x0007 | 0x0040), "41"},
|
||||||
|
{"background green ", uint16(0x0007 | 0x0020), "42"},
|
||||||
|
{"background yellow ", uint16(0x0007 | 0x0060), "43"},
|
||||||
|
{"background blue ", uint16(0x0007 | 0x0010), "44"},
|
||||||
|
{"background magenta", uint16(0x0007 | 0x0050), "45"},
|
||||||
|
{"background cyan ", uint16(0x0007 | 0x0030), "46"},
|
||||||
|
{"background white ", uint16(0x0007 | 0x0070), "47"},
|
||||||
|
{"background default", uint16(0x0007) | defaultBgColor, "49"},
|
||||||
|
{"background light gray ", uint16(0x0007 | 0x0000 | 0x0080), "100"},
|
||||||
|
{"background light red ", uint16(0x0007 | 0x0040 | 0x0080), "101"},
|
||||||
|
{"background light green ", uint16(0x0007 | 0x0020 | 0x0080), "102"},
|
||||||
|
{"background light yellow ", uint16(0x0007 | 0x0060 | 0x0080), "103"},
|
||||||
|
{"background light blue ", uint16(0x0007 | 0x0010 | 0x0080), "104"},
|
||||||
|
{"background light magenta", uint16(0x0007 | 0x0050 | 0x0080), "105"},
|
||||||
|
{"background light cyan ", uint16(0x0007 | 0x0030 | 0x0080), "106"},
|
||||||
|
{"background light white ", uint16(0x0007 | 0x0070 | 0x0080), "107"},
|
||||||
|
}
|
||||||
|
|
||||||
|
resetParam := []testParam{
|
||||||
|
{"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, "0"},
|
||||||
|
{"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, ""},
|
||||||
|
}
|
||||||
|
|
||||||
|
boldParam := []testParam{
|
||||||
|
{"bold on", uint16(0x0007 | 0x0008), "1"},
|
||||||
|
{"bold off", uint16(0x0007), "21"},
|
||||||
|
}
|
||||||
|
|
||||||
|
underscoreParam := []testParam{
|
||||||
|
{"underscore on", uint16(0x0007 | 0x8000), "4"},
|
||||||
|
{"underscore off", uint16(0x0007), "24"},
|
||||||
|
}
|
||||||
|
|
||||||
|
blinkParam := []testParam{
|
||||||
|
{"blink on", uint16(0x0007 | 0x0080), "5"},
|
||||||
|
{"blink off", uint16(0x0007), "25"},
|
||||||
|
}
|
||||||
|
|
||||||
|
mixedParam := []testParam{
|
||||||
|
{"both black, bold, underline, blink", uint16(0x0000 | 0x0000 | 0x0008 | 0x8000 | 0x0080), "30;40;1;4;5"},
|
||||||
|
{"both red, bold, underline, blink", uint16(0x0004 | 0x0040 | 0x0008 | 0x8000 | 0x0080), "31;41;1;4;5"},
|
||||||
|
{"both green, bold, underline, blink", uint16(0x0002 | 0x0020 | 0x0008 | 0x8000 | 0x0080), "32;42;1;4;5"},
|
||||||
|
{"both yellow, bold, underline, blink", uint16(0x0006 | 0x0060 | 0x0008 | 0x8000 | 0x0080), "33;43;1;4;5"},
|
||||||
|
{"both blue, bold, underline, blink", uint16(0x0001 | 0x0010 | 0x0008 | 0x8000 | 0x0080), "34;44;1;4;5"},
|
||||||
|
{"both magenta, bold, underline, blink", uint16(0x0005 | 0x0050 | 0x0008 | 0x8000 | 0x0080), "35;45;1;4;5"},
|
||||||
|
{"both cyan, bold, underline, blink", uint16(0x0003 | 0x0030 | 0x0008 | 0x8000 | 0x0080), "36;46;1;4;5"},
|
||||||
|
{"both white, bold, underline, blink", uint16(0x0007 | 0x0070 | 0x0008 | 0x8000 | 0x0080), "37;47;1;4;5"},
|
||||||
|
{"both default, bold, underline, blink", uint16(defaultFgColor | defaultBgColor | 0x0008 | 0x8000 | 0x0080), "39;49;1;4;5"},
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTextAttribute := func(expectedText string, expectedAttributes uint16, ansiColor string) {
|
||||||
|
actualText, actualAttributes, err := writeAnsiColor(expectedText, ansiColor)
|
||||||
|
if actualText != expectedText {
|
||||||
|
t.Errorf("Get %s, want %s", actualText, expectedText)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Could not get ConsoleScreenBufferInfo")
|
||||||
|
}
|
||||||
|
if actualAttributes != expectedAttributes {
|
||||||
|
t.Errorf("Text: %s, Get 0x%04x, want 0x%04x", expectedText, actualAttributes, expectedAttributes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range fgParam {
|
||||||
|
ResetColor()
|
||||||
|
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range bgParam {
|
||||||
|
ChangeColor(uint16(0x0070 | 0x0007))
|
||||||
|
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range resetParam {
|
||||||
|
ChangeColor(uint16(0x0000 | 0x0070 | 0x0008))
|
||||||
|
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetColor()
|
||||||
|
for _, v := range boldParam {
|
||||||
|
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetColor()
|
||||||
|
for _, v := range underscoreParam {
|
||||||
|
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetColor()
|
||||||
|
for _, v := range blinkParam {
|
||||||
|
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range mixedParam {
|
||||||
|
ResetColor()
|
||||||
|
assertTextAttribute(v.text, v.attributes, v.ansiColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Godeps/_workspace/src/github.com/shiena/ansicolor/example_test.go
generated
vendored
Normal file
24
Godeps/_workspace/src/github.com/shiena/ansicolor/example_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2014 shiena Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ansicolor_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/shiena/ansicolor"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleNewAnsiColorWriter() {
|
||||||
|
w := ansicolor.NewAnsiColorWriter(os.Stdout)
|
||||||
|
text := "%sforeground %sbold%s %sbackground%s\n"
|
||||||
|
fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m")
|
||||||
|
fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m")
|
||||||
|
}
|
||||||
19
Godeps/_workspace/src/github.com/shiena/ansicolor/export_test.go
generated
vendored
Normal file
19
Godeps/_workspace/src/github.com/shiena/ansicolor/export_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2014 shiena Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package ansicolor
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
var GetConsoleScreenBufferInfo = getConsoleScreenBufferInfo
|
||||||
|
|
||||||
|
func ChangeColor(color uint16) {
|
||||||
|
setConsoleTextAttribute(uintptr(syscall.Stdout), color)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResetColor() {
|
||||||
|
ChangeColor(uint16(0x0007))
|
||||||
|
}
|
||||||
5
Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go
generated
vendored
5
Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go
generated
vendored
|
|
@ -18,7 +18,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/fdtrack"
|
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
"github.com/syndtr/goleveldb/leveldb/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -370,8 +369,6 @@ func (fw fileWrap) Close() error {
|
||||||
err := fw.File.Close()
|
err := fw.File.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.fs.log(fmt.Sprintf("close %s.%d: %v", f.Type(), f.Num(), err))
|
f.fs.log(fmt.Sprintf("close %s.%d: %v", f.Type(), f.Num(), err))
|
||||||
} else {
|
|
||||||
fdtrack.Close("leveldb")
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -403,7 +400,6 @@ func (f *file) Open() (Reader, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ok:
|
ok:
|
||||||
fdtrack.Open("leveldb")
|
|
||||||
f.open = true
|
f.open = true
|
||||||
f.fs.open++
|
f.fs.open++
|
||||||
return fileWrap{of, f}, nil
|
return fileWrap{of, f}, nil
|
||||||
|
|
@ -422,7 +418,6 @@ func (f *file) Create() (Writer, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fdtrack.Open("leveldb")
|
|
||||||
f.open = true
|
f.open = true
|
||||||
f.fs.open++
|
f.fs.open++
|
||||||
return fileWrap{of, f}, nil
|
return fileWrap{of, f}, nil
|
||||||
|
|
|
||||||
45
README.md
45
README.md
|
|
@ -1,19 +1,18 @@
|
||||||
## Ethereum Go
|
## Ethereum Go
|
||||||
|
|
||||||
Ethereum Go Client, by Jeffrey Wilcke (and some other people).
|
Official golang implementation of the Ethereum protocol
|
||||||
|
|
||||||
| Linux | OSX | ARM | Windows | Tests
|
| Linux | OSX | ARM | Windows | Tests
|
||||||
----------|---------|-----|-----|---------|------
|
----------|---------|-----|-----|---------|------
|
||||||
develop | [](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/ARM%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/Windows%20Go%20develop%20branch/builds/-1) | [](https://travis-ci.org/ethereum/go-ethereum) [](https://coveralls.io/r/ethereum/go-ethereum?branch=develop)
|
develop | [](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/ARM%20Go%20develop%20branch/builds/-1) | [](https://build.ethdev.com/builders/Windows%20Go%20develop%20branch/builds/-1) | [](https://travis-ci.org/ethereum/go-ethereum) [](http://codecov.io/github/ethereum/go-ethereum?branch=develop)
|
||||||
master | [](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/ARM%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/Windows%20Go%20master%20branch/builds/-1) | [](https://travis-ci.org/ethereum/go-ethereum) [](https://coveralls.io/r/ethereum/go-ethereum?branch=master)
|
master | [](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/ARM%20Go%20master%20branch/builds/-1) | [](https://build.ethdev.com/builders/Windows%20Go%20master%20branch/builds/-1) | [](https://travis-ci.org/ethereum/go-ethereum) [](http://codecov.io/github/ethereum/go-ethereum?branch=master)
|
||||||
|
|
||||||
[](https://waffle.io/ethereum/go-ethereum)
|
[](https://waffle.io/ethereum/go-ethereum)
|
https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667
|
||||||
[](http://waffle.io/ethereum/go-ethereum)
|
)](https://godoc.org/github.com/ethereum/go-ethereum)
|
||||||
[](https://gitter.im/ethereum/go-ethereum?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
[](https://gitter.im/ethereum/go-ethereum?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||||
|
|
||||||
Automated development builds
|
## Automated development builds
|
||||||
======================
|
|
||||||
|
|
||||||
The following builds are build automatically by our build servers after each push to the [develop](https://github.com/ethereum/go-ethereum/tree/develop) branch.
|
The following builds are build automatically by our build servers after each push to the [develop](https://github.com/ethereum/go-ethereum/tree/develop) branch.
|
||||||
|
|
||||||
|
|
@ -25,8 +24,7 @@ The following builds are build automatically by our build servers after each pus
|
||||||
* [Windows 64-bit](https://build.ethdev.com/builds/Windows%20Go%20develop%20branch/Geth-Win64-latest.zip)
|
* [Windows 64-bit](https://build.ethdev.com/builds/Windows%20Go%20develop%20branch/Geth-Win64-latest.zip)
|
||||||
* [ARM](https://build.ethdev.com/builds/ARM%20Go%20develop%20branch/geth-ARM-latest.tar.bz2)
|
* [ARM](https://build.ethdev.com/builds/ARM%20Go%20develop%20branch/geth-ARM-latest.tar.bz2)
|
||||||
|
|
||||||
Building the source
|
## Building the source
|
||||||
===================
|
|
||||||
|
|
||||||
For prerequisites and detailed build instructions please read the
|
For prerequisites and detailed build instructions please read the
|
||||||
[Installation Instructions](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum)
|
[Installation Instructions](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum)
|
||||||
|
|
@ -38,34 +36,31 @@ Once the dependencies are installed, run
|
||||||
|
|
||||||
make geth
|
make geth
|
||||||
|
|
||||||
Executables
|
## Executables
|
||||||
===========
|
|
||||||
|
|
||||||
Go Ethereum comes with several wrappers/executables found in
|
Go Ethereum comes with several wrappers/executables found in
|
||||||
[the `cmd` directory](https://github.com/ethereum/go-ethereum/tree/develop/cmd):
|
[the `cmd` directory](https://github.com/ethereum/go-ethereum/tree/develop/cmd):
|
||||||
|
|
||||||
* `geth` Ethereum CLI (ethereum command line interface client)
|
Command | |
|
||||||
* `bootnode` runs a bootstrap node for the Discovery Protocol
|
----------|---------|
|
||||||
* `ethtest` test tool which runs with the [tests](https://github.com/ethereum/tests) suite:
|
`geth` | Ethereum CLI (ethereum command line interface client) |
|
||||||
`/path/to/test.json > ethtest --test BlockTests --stdin`.
|
`bootnode` | runs a bootstrap node for the Discovery Protocol |
|
||||||
* `evm` is a generic Ethereum Virtual Machine: `evm -code 60ff60ff -gas
|
`ethtest` | test tool which runs with the [tests](https://github.com/ethereum/tests) suite: `/path/to/test.json > ethtest --test BlockTests --stdin`.
|
||||||
10000 -price 0 -dump`. See `-h` for a detailed description.
|
`evm` | is a generic Ethereum Virtual Machine: `evm -code 60ff60ff -gas 10000 -price 0 -dump`. See `-h` for a detailed description. |
|
||||||
* `disasm` disassembles EVM code: `echo "6001" | disasm`
|
`disasm` | disassembles EVM code: `echo "6001" | disasm` |
|
||||||
* `rlpdump` prints RLP structures
|
`rlpdump` | prints RLP structures |
|
||||||
|
|
||||||
Command line options
|
## Command line options
|
||||||
====================
|
|
||||||
|
|
||||||
`geth` can be configured via command line options, environment variables and config files.
|
`geth` can be configured via command line options, environment variables and config files.
|
||||||
|
|
||||||
To get the options available:
|
To get the options available:
|
||||||
|
|
||||||
geth --help
|
geth help
|
||||||
|
|
||||||
For further details on options, see the [wiki](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)
|
For further details on options, see the [wiki](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)
|
||||||
|
|
||||||
Contribution
|
## Contribution
|
||||||
============
|
|
||||||
|
|
||||||
If you'd like to contribute to go-ethereum please fork, fix, commit and
|
If you'd like to contribute to go-ethereum please fork, fix, commit and
|
||||||
send a pull request. Commits who do not comply with the coding standards
|
send a pull request. Commits who do not comply with the coding standards
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,15 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# This script runs all package tests and merges the resulting coverage
|
|
||||||
# profiles. Coverage is accounted per package under test.
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
echo "" > coverage.txt
|
||||||
|
|
||||||
if [ ! -f "build/env.sh" ]; then
|
for d in $(find ./* -maxdepth 10 -type d -not -path "./build" -not -path "./Godeps/*" ); do
|
||||||
echo "$0 must be run from the root of the repository."
|
if ls $d/*.go &> /dev/null; then
|
||||||
exit 2
|
go test -coverprofile=profile.out -covermode=atomic $d
|
||||||
fi
|
if [ -f profile.out ]; then
|
||||||
|
cat profile.out >> coverage.txt
|
||||||
echo "mode: count" > profile.cov
|
echo '<<<<<< EOF' >> coverage.txt
|
||||||
|
rm profile.out
|
||||||
for pkg in $(go list ./...); do
|
fi
|
||||||
# drop the namespace prefix.
|
|
||||||
dir=${pkg##github.com/ethereum/go-ethereum/}
|
|
||||||
|
|
||||||
if [[ $dir != "tests" ]]; then
|
|
||||||
go test -covermode=count -coverprofile=$dir/profile.tmp $pkg
|
|
||||||
fi
|
|
||||||
if [[ -f $dir/profile.tmp ]]; then
|
|
||||||
tail -n +2 $dir/profile.tmp >> profile.cov
|
|
||||||
rm $dir/profile.tmp
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ func init() {
|
||||||
func run(ctx *cli.Context) {
|
func run(ctx *cli.Context) {
|
||||||
vm.Debug = ctx.GlobalBool(DebugFlag.Name)
|
vm.Debug = ctx.GlobalBool(DebugFlag.Name)
|
||||||
vm.ForceJit = ctx.GlobalBool(ForceJitFlag.Name)
|
vm.ForceJit = ctx.GlobalBool(ForceJitFlag.Name)
|
||||||
vm.DisableJit = ctx.GlobalBool(DisableJitFlag.Name)
|
vm.EnableJit = !ctx.GlobalBool(DisableJitFlag.Name)
|
||||||
|
|
||||||
glog.SetToStderr(true)
|
glog.SetToStderr(true)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,17 +115,16 @@ func exportChain(ctx *cli.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeDB(ctx *cli.Context) {
|
func removeDB(ctx *cli.Context) {
|
||||||
confirm, err := utils.PromptConfirm("Remove local databases?")
|
confirm, err := utils.PromptConfirm("Remove local database?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("%v", err)
|
utils.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if confirm {
|
if confirm {
|
||||||
fmt.Println("Removing chain and state databases...")
|
fmt.Println("Removing chaindata...")
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "blockchain"))
|
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "chaindata"))
|
||||||
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "state"))
|
|
||||||
|
|
||||||
fmt.Printf("Removed in %v\n", time.Since(start))
|
fmt.Printf("Removed in %v\n", time.Since(start))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -145,19 +145,15 @@ func apiWordCompleter(line string, pos int) (head string, completions []string,
|
||||||
return begin, completionWords, end
|
return begin, completionWords, end
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive bool, f xeth.Frontend) *jsre {
|
func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive bool) *jsre {
|
||||||
js := &jsre{ps1: "> "}
|
js := &jsre{ps1: "> "}
|
||||||
js.wait = make(chan *big.Int)
|
js.wait = make(chan *big.Int)
|
||||||
js.client = client
|
js.client = client
|
||||||
js.ds = docserver.New("/")
|
js.ds = docserver.New("/")
|
||||||
|
|
||||||
if f == nil {
|
|
||||||
f = js
|
|
||||||
}
|
|
||||||
|
|
||||||
// update state in separare forever blocks
|
// update state in separare forever blocks
|
||||||
js.re = re.New(libPath)
|
js.re = re.New(libPath)
|
||||||
if err := js.apiBindings(f); err != nil {
|
if err := js.apiBindings(js); err != nil {
|
||||||
utils.Fatalf("Unable to initialize console - %v", err)
|
utils.Fatalf("Unable to initialize console - %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,15 +228,10 @@ func (self *jsre) loadAutoCompletion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *jsre) batch(statement string) {
|
func (self *jsre) batch(statement string) {
|
||||||
val, err := self.re.Run(statement)
|
err := self.re.EvalAndPrettyPrint(statement)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("error: %v", err)
|
fmt.Printf("error: %v", err)
|
||||||
} else if val.IsDefined() && val.IsObject() {
|
|
||||||
obj, _ := self.re.Get("ret_result")
|
|
||||||
fmt.Printf("%v", obj)
|
|
||||||
} else if val.IsDefined() {
|
|
||||||
fmt.Printf("%v", val)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.atexit != nil {
|
if self.atexit != nil {
|
||||||
|
|
@ -252,22 +243,22 @@ func (self *jsre) batch(statement string) {
|
||||||
|
|
||||||
// show summary of current geth instance
|
// show summary of current geth instance
|
||||||
func (self *jsre) welcome() {
|
func (self *jsre) welcome() {
|
||||||
self.re.Eval(`console.log('instance: ' + web3.version.client);`)
|
self.re.Run(`
|
||||||
self.re.Eval(`console.log(' datadir: ' + admin.datadir);`)
|
(function () {
|
||||||
self.re.Eval(`console.log("coinbase: " + eth.coinbase);`)
|
console.log('instance: ' + web3.version.client);
|
||||||
self.re.Eval(`var lastBlockTimestamp = 1000 * eth.getBlock(eth.blockNumber).timestamp`)
|
console.log(' datadir: ' + admin.datadir);
|
||||||
self.re.Eval(`console.log("at block: " + eth.blockNumber + " (" + new Date(lastBlockTimestamp).toLocaleDateString()
|
console.log("coinbase: " + eth.coinbase);
|
||||||
+ " " + new Date(lastBlockTimestamp).toLocaleTimeString() + ")");`)
|
var ts = 1000 * eth.getBlock(eth.blockNumber).timestamp;
|
||||||
|
console.log("at block: " + eth.blockNumber + " (" + new Date(ts) + ")");
|
||||||
|
})();
|
||||||
|
`)
|
||||||
if modules, err := self.supportedApis(); err == nil {
|
if modules, err := self.supportedApis(); err == nil {
|
||||||
loadedModules := make([]string, 0)
|
loadedModules := make([]string, 0)
|
||||||
for api, version := range modules {
|
for api, version := range modules {
|
||||||
loadedModules = append(loadedModules, fmt.Sprintf("%s:%s", api, version))
|
loadedModules = append(loadedModules, fmt.Sprintf("%s:%s", api, version))
|
||||||
}
|
}
|
||||||
sort.Strings(loadedModules)
|
sort.Strings(loadedModules)
|
||||||
|
fmt.Println("modules:", strings.Join(loadedModules, " "))
|
||||||
self.re.Eval(fmt.Sprintf("var modules = '%s';", strings.Join(loadedModules, " ")))
|
|
||||||
self.re.Eval(`console.log(" modules: " + modules);`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -291,7 +282,7 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
|
||||||
utils.Fatalf("Unable to determine supported api's: %v", err)
|
utils.Fatalf("Unable to determine supported api's: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
jeth := rpc.NewJeth(api.Merge(apiImpl...), js.re, js.client)
|
jeth := rpc.NewJeth(api.Merge(apiImpl...), js.re, js.client, f)
|
||||||
js.re.Set("jeth", struct{}{})
|
js.re.Set("jeth", struct{}{})
|
||||||
t, _ := js.re.Get("jeth")
|
t, _ := js.re.Get("jeth")
|
||||||
jethObj := t.Object()
|
jethObj := t.Object()
|
||||||
|
|
@ -309,12 +300,12 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
|
||||||
utils.Fatalf("Error loading web3.js: %v", err)
|
utils.Fatalf("Error loading web3.js: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = js.re.Eval("var web3 = require('web3');")
|
_, err = js.re.Run("var web3 = require('web3');")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Error requiring web3: %v", err)
|
utils.Fatalf("Error requiring web3: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = js.re.Eval("web3.setProvider(jeth)")
|
_, err = js.re.Run("web3.setProvider(jeth)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Error setting web3 provider: %v", err)
|
utils.Fatalf("Error setting web3 provider: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -333,13 +324,13 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = js.re.Eval(shortcuts)
|
_, err = js.re.Run(shortcuts)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Error setting namespaces: %v", err)
|
utils.Fatalf("Error setting namespaces: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
js.re.Eval(`var GlobalRegistrar = eth.contract(` + registrar.GlobalRegistrarAbi + `); registrar = GlobalRegistrar.at("` + registrar.GlobalRegistrarAddr + `");`)
|
js.re.Run(`var GlobalRegistrar = eth.contract(` + registrar.GlobalRegistrarAbi + `); registrar = GlobalRegistrar.at("` + registrar.GlobalRegistrarAddr + `");`)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -387,6 +378,11 @@ func (self *jsre) interactive() {
|
||||||
for {
|
for {
|
||||||
line, err := self.Prompt(<-prompt)
|
line, err := self.Prompt(<-prompt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == liner.ErrPromptAborted { // ctrl-C
|
||||||
|
self.resetPrompt()
|
||||||
|
inputln <- ""
|
||||||
|
continue
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
inputln <- line
|
inputln <- line
|
||||||
|
|
@ -458,8 +454,7 @@ func (self *jsre) parseInput(code string) {
|
||||||
fmt.Println("[native] error", r)
|
fmt.Println("[native] error", r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
value, err := self.re.Run(code)
|
if err := self.re.EvalAndPrettyPrint(code); err != nil {
|
||||||
if err != nil {
|
|
||||||
if ottoErr, ok := err.(*otto.Error); ok {
|
if ottoErr, ok := err.(*otto.Error); ok {
|
||||||
fmt.Println(ottoErr.String())
|
fmt.Println(ottoErr.String())
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -467,12 +462,17 @@ func (self *jsre) parseInput(code string) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.printValue(value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var indentCount = 0
|
var indentCount = 0
|
||||||
var str = ""
|
var str = ""
|
||||||
|
|
||||||
|
func (self *jsre) resetPrompt() {
|
||||||
|
indentCount = 0
|
||||||
|
str = ""
|
||||||
|
self.ps1 = "> "
|
||||||
|
}
|
||||||
|
|
||||||
func (self *jsre) setIndent() {
|
func (self *jsre) setIndent() {
|
||||||
open := strings.Count(str, "{")
|
open := strings.Count(str, "{")
|
||||||
open += strings.Count(str, "(")
|
open += strings.Count(str, "(")
|
||||||
|
|
@ -486,10 +486,3 @@ func (self *jsre) setIndent() {
|
||||||
self.ps1 += " "
|
self.ps1 += " "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *jsre) printValue(v interface{}) {
|
|
||||||
val, err := self.re.PrettyPrint(v)
|
|
||||||
if err == nil {
|
|
||||||
fmt.Printf("%v", val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -38,7 +37,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/fdtrack"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
|
|
@ -46,16 +44,14 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
"github.com/ethereum/go-ethereum/rpc/comms"
|
"github.com/ethereum/go-ethereum/rpc/comms"
|
||||||
"github.com/mattn/go-colorable"
|
|
||||||
"github.com/mattn/go-isatty"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ClientIdentifier = "Geth"
|
ClientIdentifier = "Geth"
|
||||||
Version = "1.0.1"
|
Version = "1.0.3"
|
||||||
VersionMajor = 1
|
VersionMajor = 1
|
||||||
VersionMinor = 0
|
VersionMinor = 0
|
||||||
VersionPatch = 1
|
VersionPatch = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -398,14 +394,6 @@ func run(ctx *cli.Context) {
|
||||||
func attach(ctx *cli.Context) {
|
func attach(ctx *cli.Context) {
|
||||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||||
|
|
||||||
// Wrap the standard output with a colorified stream (windows)
|
|
||||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
|
||||||
if pr, pw, err := os.Pipe(); err == nil {
|
|
||||||
go io.Copy(colorable.NewColorableStdout(), pr)
|
|
||||||
os.Stdout = pw
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var client comms.EthereumClient
|
var client comms.EthereumClient
|
||||||
var err error
|
var err error
|
||||||
if ctx.Args().Present() {
|
if ctx.Args().Present() {
|
||||||
|
|
@ -425,7 +413,7 @@ func attach(ctx *cli.Context) {
|
||||||
ctx.GlobalString(utils.JSpathFlag.Name),
|
ctx.GlobalString(utils.JSpathFlag.Name),
|
||||||
client,
|
client,
|
||||||
true,
|
true,
|
||||||
nil)
|
)
|
||||||
|
|
||||||
if ctx.GlobalString(utils.ExecFlag.Name) != "" {
|
if ctx.GlobalString(utils.ExecFlag.Name) != "" {
|
||||||
repl.batch(ctx.GlobalString(utils.ExecFlag.Name))
|
repl.batch(ctx.GlobalString(utils.ExecFlag.Name))
|
||||||
|
|
@ -438,14 +426,6 @@ func attach(ctx *cli.Context) {
|
||||||
func console(ctx *cli.Context) {
|
func console(ctx *cli.Context) {
|
||||||
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
|
||||||
|
|
||||||
// Wrap the standard output with a colorified stream (windows)
|
|
||||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
|
||||||
if pr, pw, err := os.Pipe(); err == nil {
|
|
||||||
go io.Copy(colorable.NewColorableStdout(), pr)
|
|
||||||
os.Stdout = pw
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
|
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
|
||||||
ethereum, err := eth.New(cfg)
|
ethereum, err := eth.New(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -565,9 +545,6 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) {
|
||||||
// Start Ethereum itself
|
// Start Ethereum itself
|
||||||
utils.StartEthereum(eth)
|
utils.StartEthereum(eth)
|
||||||
|
|
||||||
// Start logging file descriptor stats.
|
|
||||||
fdtrack.Start()
|
|
||||||
|
|
||||||
am := eth.AccountManager()
|
am := eth.AccountManager()
|
||||||
account := ctx.GlobalString(utils.UnlockedAccountFlag.Name)
|
account := ctx.GlobalString(utils.UnlockedAccountFlag.Name)
|
||||||
accounts := strings.Split(account, " ")
|
accounts := strings.Split(account, " ")
|
||||||
|
|
|
||||||
|
|
@ -21,30 +21,32 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/ethereum/ethash"
|
"github.com/ethereum/ethash"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||||
"github.com/ethereum/go-ethereum/rpc/api"
|
"github.com/ethereum/go-ethereum/rpc/api"
|
||||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
"github.com/ethereum/go-ethereum/rpc/comms"
|
"github.com/ethereum/go-ethereum/rpc/comms"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/useragent"
|
||||||
"github.com/ethereum/go-ethereum/xeth"
|
"github.com/ethereum/go-ethereum/xeth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -452,7 +454,7 @@ func SetupLogger(ctx *cli.Context) {
|
||||||
|
|
||||||
// SetupVM configured the VM package's global settings
|
// SetupVM configured the VM package's global settings
|
||||||
func SetupVM(ctx *cli.Context) {
|
func SetupVM(ctx *cli.Context) {
|
||||||
vm.DisableJit = !ctx.GlobalBool(VMEnableJitFlag.Name)
|
vm.EnableJit = ctx.GlobalBool(VMEnableJitFlag.Name)
|
||||||
vm.ForceJit = ctx.GlobalBool(VMForceJitFlag.Name)
|
vm.ForceJit = ctx.GlobalBool(VMForceJitFlag.Name)
|
||||||
vm.SetJITCacheSize(ctx.GlobalInt(VMJitCacheFlag.Name))
|
vm.SetJITCacheSize(ctx.GlobalInt(VMJitCacheFlag.Name))
|
||||||
}
|
}
|
||||||
|
|
@ -518,15 +520,20 @@ func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error {
|
||||||
Endpoint: IpcSocketPath(ctx),
|
Endpoint: IpcSocketPath(ctx),
|
||||||
}
|
}
|
||||||
|
|
||||||
xeth := xeth.New(eth, nil)
|
initializer := func(conn net.Conn) (shared.EthereumApi, error) {
|
||||||
codec := codec.JSON
|
fe := useragent.NewRemoteFrontend(conn, eth.AccountManager())
|
||||||
|
xeth := xeth.New(eth, fe)
|
||||||
|
codec := codec.JSON
|
||||||
|
|
||||||
apis, err := api.ParseApiString(ctx.GlobalString(IPCApiFlag.Name), codec, xeth, eth)
|
apis, err := api.ParseApiString(ctx.GlobalString(IPCApiFlag.Name), codec, xeth, eth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.Merge(apis...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return comms.StartIpc(config, codec, api.Merge(apis...))
|
return comms.StartIpc(config, codec.JSON, initializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error {
|
func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error {
|
||||||
|
|
|
||||||
|
|
@ -349,23 +349,11 @@ func (sm *BlockProcessor) GetBlockReceipts(bhash common.Hash) types.Receipts {
|
||||||
// the depricated way by re-processing the block.
|
// the depricated way by re-processing the block.
|
||||||
func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) {
|
func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) {
|
||||||
receipts := GetBlockReceipts(sm.chainDb, block.Hash())
|
receipts := GetBlockReceipts(sm.chainDb, block.Hash())
|
||||||
if len(receipts) > 0 {
|
// coalesce logs
|
||||||
// coalesce logs
|
for _, receipt := range receipts {
|
||||||
for _, receipt := range receipts {
|
logs = append(logs, receipt.Logs()...)
|
||||||
logs = append(logs, receipt.Logs()...)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return logs, nil
|
||||||
// TODO: remove backward compatibility
|
|
||||||
var (
|
|
||||||
parent = sm.bc.GetBlock(block.ParentHash())
|
|
||||||
state = state.New(parent.Root(), sm.chainDb)
|
|
||||||
)
|
|
||||||
|
|
||||||
sm.TransitionState(state, parent, block, true)
|
|
||||||
|
|
||||||
return state.Logs(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// See YP section 4.3.4. "Block Header Validity"
|
// See YP section 4.3.4. "Block Header Validity"
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,5 @@ import "github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
// Set of manually tracked bad hashes (usually hard forks)
|
// Set of manually tracked bad hashes (usually hard forks)
|
||||||
var BadHashes = map[common.Hash]bool{
|
var BadHashes = map[common.Hash]bool{
|
||||||
common.HexToHash("f269c503aed286caaa0d114d6a5320e70abbc2febe37953207e76a2873f2ba79"): true,
|
common.HexToHash("0x05bef30ef572270f654746da22639a7a0c97dd97a7050b9e252391996aaeb689"): true,
|
||||||
common.HexToHash("38f5bbbffd74804820ffa4bab0cd540e9de229725afb98c1a7e57936f4a714bc"): true,
|
|
||||||
common.HexToHash("7064455b364775a16afbdecd75370e912c6e2879f202eda85b9beae547fff3ac"): true,
|
|
||||||
common.HexToHash("5b7c80070a6eff35f3eb3181edb023465c776d40af2885571e1bc4689f3a44d8"): true,
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -647,7 +647,9 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
|
||||||
queue[i] = ChainSplitEvent{block, logs}
|
queue[i] = ChainSplitEvent{block, logs}
|
||||||
queueEvent.splitCount++
|
queueEvent.splitCount++
|
||||||
}
|
}
|
||||||
PutBlockReceipts(self.chainDb, block, receipts)
|
if err := PutBlockReceipts(self.chainDb, block, receipts); err != nil {
|
||||||
|
glog.V(logger.Warn).Infoln("error writing block receipts:", err)
|
||||||
|
}
|
||||||
|
|
||||||
stats.processed++
|
stats.processed++
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AccountChange struct {
|
type AccountChange struct {
|
||||||
|
|
@ -111,7 +113,7 @@ done:
|
||||||
// Get the logs of the block
|
// Get the logs of the block
|
||||||
unfiltered, err := self.eth.BlockProcessor().GetLogs(block)
|
unfiltered, err := self.eth.BlockProcessor().GetLogs(block)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
chainlogger.Warnln("err: filter get logs ", err)
|
glog.V(logger.Warn).Infoln("err: filter get logs ", err)
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,8 +82,9 @@ type StateObject struct {
|
||||||
// Mark for deletion
|
// Mark for deletion
|
||||||
// When an object is marked for deletion it will be delete from the trie
|
// When an object is marked for deletion it will be delete from the trie
|
||||||
// during the "update" phase of the state transition
|
// during the "update" phase of the state transition
|
||||||
remove bool
|
remove bool
|
||||||
dirty bool
|
deleted bool
|
||||||
|
dirty bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateObject) Reset() {
|
func (self *StateObject) Reset() {
|
||||||
|
|
|
||||||
|
|
@ -203,18 +203,20 @@ func (self *StateDB) UpdateStateObject(stateObject *StateObject) {
|
||||||
|
|
||||||
// Delete the given state object and delete it from the state trie
|
// Delete the given state object and delete it from the state trie
|
||||||
func (self *StateDB) DeleteStateObject(stateObject *StateObject) {
|
func (self *StateDB) DeleteStateObject(stateObject *StateObject) {
|
||||||
|
stateObject.deleted = true
|
||||||
|
|
||||||
addr := stateObject.Address()
|
addr := stateObject.Address()
|
||||||
self.trie.Delete(addr[:])
|
self.trie.Delete(addr[:])
|
||||||
|
|
||||||
//delete(self.stateObjects, addr.Str())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve a state object given my the address. Nil if not found
|
// Retrieve a state object given my the address. Nil if not found
|
||||||
func (self *StateDB) GetStateObject(addr common.Address) *StateObject {
|
func (self *StateDB) GetStateObject(addr common.Address) (stateObject *StateObject) {
|
||||||
//addr = common.Address(addr)
|
stateObject = self.stateObjects[addr.Str()]
|
||||||
|
|
||||||
stateObject := self.stateObjects[addr.Str()]
|
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
|
if stateObject.deleted {
|
||||||
|
stateObject = nil
|
||||||
|
}
|
||||||
|
|
||||||
return stateObject
|
return stateObject
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,7 +238,7 @@ func (self *StateDB) SetStateObject(object *StateObject) {
|
||||||
// Retrieve a state object or create a new state object if nil
|
// Retrieve a state object or create a new state object if nil
|
||||||
func (self *StateDB) GetOrNewStateObject(addr common.Address) *StateObject {
|
func (self *StateDB) GetOrNewStateObject(addr common.Address) *StateObject {
|
||||||
stateObject := self.GetStateObject(addr)
|
stateObject := self.GetStateObject(addr)
|
||||||
if stateObject == nil {
|
if stateObject == nil || stateObject.deleted {
|
||||||
stateObject = self.CreateAccount(addr)
|
stateObject = self.CreateAccount(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -341,19 +341,19 @@ func opCoinbase(instr instruction, env Environment, context *Context, memory *Me
|
||||||
}
|
}
|
||||||
|
|
||||||
func opTimestamp(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
func opTimestamp(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
||||||
stack.push(new(big.Int).SetUint64(env.Time()))
|
stack.push(U256(new(big.Int).SetUint64(env.Time())))
|
||||||
}
|
}
|
||||||
|
|
||||||
func opNumber(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
func opNumber(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
||||||
stack.push(U256(env.BlockNumber()))
|
stack.push(U256(new(big.Int).Set(env.BlockNumber())))
|
||||||
}
|
}
|
||||||
|
|
||||||
func opDifficulty(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
func opDifficulty(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
||||||
stack.push(new(big.Int).Set(env.Difficulty()))
|
stack.push(U256(new(big.Int).Set(env.Difficulty())))
|
||||||
}
|
}
|
||||||
|
|
||||||
func opGasLimit(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
func opGasLimit(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
||||||
stack.push(new(big.Int).Set(env.GasLimit()))
|
stack.push(U256(new(big.Int).Set(env.GasLimit())))
|
||||||
}
|
}
|
||||||
|
|
||||||
func opPop(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
func opPop(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
||||||
|
|
@ -415,15 +415,12 @@ func opSstore(instr instruction, env Environment, context *Context, memory *Memo
|
||||||
env.State().SetState(context.Address(), loc, common.BigToHash(val))
|
env.State().SetState(context.Address(), loc, common.BigToHash(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
func opJump(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
func opJump(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {}
|
||||||
}
|
func opJumpi(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {}
|
||||||
func opJumpi(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
func opJumpdest(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {}
|
||||||
}
|
|
||||||
func opJumpdest(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func opPc(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
func opPc(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
||||||
stack.push(instr.data)
|
stack.push(new(big.Int).Set(instr.data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func opMsize(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
func opMsize(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) {
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ type Program struct {
|
||||||
code []byte
|
code []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewProgram returns a new JIT program
|
||||||
func NewProgram(code []byte) *Program {
|
func NewProgram(code []byte) *Program {
|
||||||
program := &Program{
|
program := &Program{
|
||||||
Id: crypto.Sha3Hash(code),
|
Id: crypto.Sha3Hash(code),
|
||||||
|
|
@ -113,6 +114,7 @@ func (p *Program) addInstr(op OpCode, pc uint64, fn instrFn, data *big.Int) {
|
||||||
p.mapping[pc] = len(p.instructions) - 1
|
p.mapping[pc] = len(p.instructions) - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompileProgram compiles the given program and return an error when it fails
|
||||||
func CompileProgram(program *Program) (err error) {
|
func CompileProgram(program *Program) (err error) {
|
||||||
if progStatus(atomic.LoadInt32(&program.status)) == progCompile {
|
if progStatus(atomic.LoadInt32(&program.status)) == progCompile {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -272,6 +274,8 @@ func CompileProgram(program *Program) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunProgram runs the program given the enviroment and context and returns an
|
||||||
|
// error if the execution failed (non-consensus)
|
||||||
func RunProgram(program *Program, env Environment, context *Context, input []byte) ([]byte, error) {
|
func RunProgram(program *Program, env Environment, context *Context, input []byte) ([]byte, error) {
|
||||||
return runProgram(program, 0, NewMemory(), newstack(), env, context, input)
|
return runProgram(program, 0, NewMemory(), newstack(), env, context, input)
|
||||||
}
|
}
|
||||||
|
|
@ -352,6 +356,8 @@ func runProgram(program *Program, pcstart uint64, mem *Memory, stack *stack, env
|
||||||
pc++
|
pc++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context.Input = nil
|
||||||
|
|
||||||
return context.Return(nil), nil
|
return context.Return(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ func runVmBench(test vmBench, b *testing.B) {
|
||||||
}
|
}
|
||||||
env := NewEnv()
|
env := NewEnv()
|
||||||
|
|
||||||
DisableJit = test.nojit
|
EnableJit = !test.nojit
|
||||||
ForceJit = test.forcejit
|
ForceJit = test.forcejit
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
var (
|
var (
|
||||||
DisableJit bool = true // Disable the JIT VM
|
EnableJit bool // Enables the JIT VM
|
||||||
ForceJit bool // Force the JIT, skip byte VM
|
ForceJit bool // Force the JIT, skip byte VM
|
||||||
MaxProgSize int // Max cache size for JIT Programs
|
MaxProgSize int // Max cache size for JIT Programs
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultJitMaxCache int = 64
|
const defaultJitMaxCache int = 64
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
|
||||||
codehash = crypto.Sha3Hash(context.Code) // codehash is used when doing jump dest caching
|
codehash = crypto.Sha3Hash(context.Code) // codehash is used when doing jump dest caching
|
||||||
program *Program
|
program *Program
|
||||||
)
|
)
|
||||||
if !DisableJit {
|
if EnableJit {
|
||||||
// Fetch program status.
|
// Fetch program status.
|
||||||
// * If ready run using JIT
|
// * If ready run using JIT
|
||||||
// * If unknown, compile in a seperate goroutine
|
// * If unknown, compile in a seperate goroutine
|
||||||
|
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
// Copyright 2014 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package crypto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
|
||||||
)
|
|
||||||
|
|
||||||
type KeyPair struct {
|
|
||||||
PrivateKey []byte
|
|
||||||
PublicKey []byte
|
|
||||||
address []byte
|
|
||||||
mnemonic string
|
|
||||||
// The associated account
|
|
||||||
// account *StateObject
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenerateNewKeyPair() *KeyPair {
|
|
||||||
_, prv := secp256k1.GenerateKeyPair()
|
|
||||||
keyPair, _ := NewKeyPairFromSec(prv) // swallow error, this one cannot err
|
|
||||||
return keyPair
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewKeyPairFromSec(seckey []byte) (*KeyPair, error) {
|
|
||||||
pubkey, err := secp256k1.GeneratePubKey(seckey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &KeyPair{PrivateKey: seckey, PublicKey: pubkey}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *KeyPair) Address() []byte {
|
|
||||||
if k.address == nil {
|
|
||||||
k.address = Sha3(k.PublicKey[1:])[12:]
|
|
||||||
}
|
|
||||||
return k.address
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *KeyPair) Mnemonic() string {
|
|
||||||
if k.mnemonic == "" {
|
|
||||||
k.mnemonic = strings.Join(MnemonicEncode(common.Bytes2Hex(k.PrivateKey)), " ")
|
|
||||||
}
|
|
||||||
return k.mnemonic
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *KeyPair) AsStrings() (string, string, string, string) {
|
|
||||||
return k.Mnemonic(), common.Bytes2Hex(k.Address()), common.Bytes2Hex(k.PrivateKey), common.Bytes2Hex(k.PublicKey)
|
|
||||||
}
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
// Copyright 2014 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package crypto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: See if we can refactor this into a shared util lib if we need it multiple times
|
|
||||||
func IndexOf(slice []string, value string) int64 {
|
|
||||||
for p, v := range slice {
|
|
||||||
if v == value {
|
|
||||||
return int64(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func MnemonicEncode(message string) []string {
|
|
||||||
var out []string
|
|
||||||
n := int64(len(MnemonicWords))
|
|
||||||
|
|
||||||
for i := 0; i < len(message); i += (len(message) / 8) {
|
|
||||||
x := message[i : i+8]
|
|
||||||
bit, _ := strconv.ParseInt(x, 16, 64)
|
|
||||||
w1 := (bit % n)
|
|
||||||
w2 := ((bit / n) + w1) % n
|
|
||||||
w3 := ((bit / n / n) + w2) % n
|
|
||||||
out = append(out, MnemonicWords[w1], MnemonicWords[w2], MnemonicWords[w3])
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func MnemonicDecode(wordsar []string) string {
|
|
||||||
var out string
|
|
||||||
n := int64(len(MnemonicWords))
|
|
||||||
|
|
||||||
for i := 0; i < len(wordsar); i += 3 {
|
|
||||||
word1 := wordsar[i]
|
|
||||||
word2 := wordsar[i+1]
|
|
||||||
word3 := wordsar[i+2]
|
|
||||||
w1 := IndexOf(MnemonicWords, word1)
|
|
||||||
w2 := IndexOf(MnemonicWords, word2)
|
|
||||||
w3 := IndexOf(MnemonicWords, word3)
|
|
||||||
|
|
||||||
y := (w2 - w1) % n
|
|
||||||
z := (w3 - w2) % n
|
|
||||||
|
|
||||||
// Golang handles modulo with negative numbers different then most languages
|
|
||||||
// The modulo can be negative, we don't want that.
|
|
||||||
if z < 0 {
|
|
||||||
z += n
|
|
||||||
}
|
|
||||||
if y < 0 {
|
|
||||||
y += n
|
|
||||||
}
|
|
||||||
x := w1 + n*(y) + n*n*(z)
|
|
||||||
out += fmt.Sprintf("%08x", x)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
// Copyright 2014 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package crypto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMnDecode(t *testing.T) {
|
|
||||||
words := []string{
|
|
||||||
"ink",
|
|
||||||
"balance",
|
|
||||||
"gain",
|
|
||||||
"fear",
|
|
||||||
"happen",
|
|
||||||
"melt",
|
|
||||||
"mom",
|
|
||||||
"surface",
|
|
||||||
"stir",
|
|
||||||
"bottle",
|
|
||||||
"unseen",
|
|
||||||
"expression",
|
|
||||||
"important",
|
|
||||||
"curl",
|
|
||||||
"grant",
|
|
||||||
"fairy",
|
|
||||||
"across",
|
|
||||||
"back",
|
|
||||||
"figure",
|
|
||||||
"breast",
|
|
||||||
"nobody",
|
|
||||||
"scratch",
|
|
||||||
"worry",
|
|
||||||
"yesterday",
|
|
||||||
}
|
|
||||||
encode := "c61d43dc5bb7a4e754d111dae8105b6f25356492df5e50ecb33b858d94f8c338"
|
|
||||||
result := MnemonicDecode(words)
|
|
||||||
if encode != result {
|
|
||||||
t.Error("We expected", encode, "got", result, "instead")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func TestMnEncode(t *testing.T) {
|
|
||||||
encode := "c61d43dc5bb7a4e754d111dae8105b6f25356492df5e50ecb33b858d94f8c338"
|
|
||||||
result := []string{
|
|
||||||
"ink",
|
|
||||||
"balance",
|
|
||||||
"gain",
|
|
||||||
"fear",
|
|
||||||
"happen",
|
|
||||||
"melt",
|
|
||||||
"mom",
|
|
||||||
"surface",
|
|
||||||
"stir",
|
|
||||||
"bottle",
|
|
||||||
"unseen",
|
|
||||||
"expression",
|
|
||||||
"important",
|
|
||||||
"curl",
|
|
||||||
"grant",
|
|
||||||
"fairy",
|
|
||||||
"across",
|
|
||||||
"back",
|
|
||||||
"figure",
|
|
||||||
"breast",
|
|
||||||
"nobody",
|
|
||||||
"scratch",
|
|
||||||
"worry",
|
|
||||||
"yesterday",
|
|
||||||
}
|
|
||||||
words := MnemonicEncode(encode)
|
|
||||||
for i, word := range words {
|
|
||||||
if word != result[i] {
|
|
||||||
t.Error("Mnenonic does not match:", words, result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -61,10 +61,11 @@ var (
|
||||||
|
|
||||||
defaultBootNodes = []*discover.Node{
|
defaultBootNodes = []*discover.Node{
|
||||||
// ETH/DEV Go Bootnodes
|
// ETH/DEV Go Bootnodes
|
||||||
discover.MustParseNode("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303"),
|
discover.MustParseNode("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303"), // IE
|
||||||
discover.MustParseNode("enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303"),
|
discover.MustParseNode("enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303"), // BR
|
||||||
|
discover.MustParseNode("enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303"), // SG
|
||||||
// ETH/DEV cpp-ethereum (poc-9.ethdev.com)
|
// ETH/DEV cpp-ethereum (poc-9.ethdev.com)
|
||||||
discover.MustParseNode("enode://487611428e6c99a11a9795a6abe7b529e81315ca6aad66e2a2fc76e3adf263faba0d35466c2f8f68d561dbefa8878d4df5f1f2ddb1fbeab7f42ffb8cd328bd4a@5.1.83.226:30303"),
|
discover.MustParseNode("enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303"),
|
||||||
}
|
}
|
||||||
|
|
||||||
staticNodes = "static-nodes.json" // Path within <datadir> to search for the static node list
|
staticNodes = "static-nodes.json" // Path within <datadir> to search for the static node list
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,11 @@ type blockPriceInfo struct {
|
||||||
type GasPriceOracle struct {
|
type GasPriceOracle struct {
|
||||||
eth *Ethereum
|
eth *Ethereum
|
||||||
chain *core.ChainManager
|
chain *core.ChainManager
|
||||||
pool *core.TxPool
|
|
||||||
events event.Subscription
|
events event.Subscription
|
||||||
blocks map[uint64]*blockPriceInfo
|
blocks map[uint64]*blockPriceInfo
|
||||||
firstProcessed, lastProcessed uint64
|
firstProcessed, lastProcessed uint64
|
||||||
lastBaseMutex sync.Mutex
|
lastBaseMutex sync.Mutex
|
||||||
lastBase *big.Int
|
lastBase, minBase *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGasPriceOracle(eth *Ethereum) (self *GasPriceOracle) {
|
func NewGasPriceOracle(eth *Ethereum) (self *GasPriceOracle) {
|
||||||
|
|
@ -50,13 +49,15 @@ func NewGasPriceOracle(eth *Ethereum) (self *GasPriceOracle) {
|
||||||
self.blocks = make(map[uint64]*blockPriceInfo)
|
self.blocks = make(map[uint64]*blockPriceInfo)
|
||||||
self.eth = eth
|
self.eth = eth
|
||||||
self.chain = eth.chainManager
|
self.chain = eth.chainManager
|
||||||
self.pool = eth.txPool
|
|
||||||
self.events = eth.EventMux().Subscribe(
|
self.events = eth.EventMux().Subscribe(
|
||||||
core.ChainEvent{},
|
core.ChainEvent{},
|
||||||
core.ChainSplitEvent{},
|
core.ChainSplitEvent{},
|
||||||
core.TxPreEvent{},
|
|
||||||
core.TxPostEvent{},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
minbase := new(big.Int).Mul(self.eth.GpoMinGasPrice, big.NewInt(100))
|
||||||
|
minbase = minbase.Div(minbase, big.NewInt(int64(self.eth.GpobaseCorrectionFactor)))
|
||||||
|
self.minBase = minbase
|
||||||
|
|
||||||
self.processPastBlocks()
|
self.processPastBlocks()
|
||||||
go self.listenLoop()
|
go self.listenLoop()
|
||||||
return
|
return
|
||||||
|
|
@ -93,8 +94,6 @@ func (self *GasPriceOracle) listenLoop() {
|
||||||
self.processBlock(ev.Block)
|
self.processBlock(ev.Block)
|
||||||
case core.ChainSplitEvent:
|
case core.ChainSplitEvent:
|
||||||
self.processBlock(ev.Block)
|
self.processBlock(ev.Block)
|
||||||
case core.TxPreEvent:
|
|
||||||
case core.TxPostEvent:
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.events.Unsubscribe()
|
self.events.Unsubscribe()
|
||||||
|
|
@ -131,6 +130,10 @@ func (self *GasPriceOracle) processBlock(block *types.Block) {
|
||||||
newBase := new(big.Int).Mul(lastBase, big.NewInt(1000000+crand))
|
newBase := new(big.Int).Mul(lastBase, big.NewInt(1000000+crand))
|
||||||
newBase.Div(newBase, big.NewInt(1000000))
|
newBase.Div(newBase, big.NewInt(1000000))
|
||||||
|
|
||||||
|
if newBase.Cmp(self.minBase) < 0 {
|
||||||
|
newBase = self.minBase
|
||||||
|
}
|
||||||
|
|
||||||
bpi := self.blocks[i]
|
bpi := self.blocks[i]
|
||||||
if bpi == nil {
|
if bpi == nil {
|
||||||
bpi = &blockPriceInfo{}
|
bpi = &blockPriceInfo{}
|
||||||
|
|
@ -146,7 +149,7 @@ func (self *GasPriceOracle) processBlock(block *types.Block) {
|
||||||
|
|
||||||
// returns the lowers possible price with which a tx was or could have been included
|
// returns the lowers possible price with which a tx was or could have been included
|
||||||
func (self *GasPriceOracle) lowestPrice(block *types.Block) *big.Int {
|
func (self *GasPriceOracle) lowestPrice(block *types.Block) *big.Int {
|
||||||
gasUsed := new(big.Int)
|
gasUsed := big.NewInt(0)
|
||||||
|
|
||||||
receipts := self.eth.BlockProcessor().GetBlockReceipts(block.Hash())
|
receipts := self.eth.BlockProcessor().GetBlockReceipts(block.Hash())
|
||||||
if len(receipts) > 0 {
|
if len(receipts) > 0 {
|
||||||
|
|
@ -158,12 +161,12 @@ func (self *GasPriceOracle) lowestPrice(block *types.Block) *big.Int {
|
||||||
if new(big.Int).Mul(gasUsed, big.NewInt(100)).Cmp(new(big.Int).Mul(block.GasLimit(),
|
if new(big.Int).Mul(gasUsed, big.NewInt(100)).Cmp(new(big.Int).Mul(block.GasLimit(),
|
||||||
big.NewInt(int64(self.eth.GpoFullBlockRatio)))) < 0 {
|
big.NewInt(int64(self.eth.GpoFullBlockRatio)))) < 0 {
|
||||||
// block is not full, could have posted a tx with MinGasPrice
|
// block is not full, could have posted a tx with MinGasPrice
|
||||||
return self.eth.GpoMinGasPrice
|
return big.NewInt(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
txs := block.Transactions()
|
txs := block.Transactions()
|
||||||
if len(txs) == 0 {
|
if len(txs) == 0 {
|
||||||
return self.eth.GpoMinGasPrice
|
return big.NewInt(0)
|
||||||
}
|
}
|
||||||
// block is full, find smallest gasPrice
|
// block is full, find smallest gasPrice
|
||||||
minPrice := txs[0].GasPrice()
|
minPrice := txs[0].GasPrice()
|
||||||
|
|
|
||||||
|
|
@ -413,10 +413,12 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
|
|
||||||
pm.fetcher.Enqueue(p.id, request.Block)
|
pm.fetcher.Enqueue(p.id, request.Block)
|
||||||
|
|
||||||
// TODO: Schedule a sync to cover potential gaps (this needs proto update)
|
// Update the peers total difficulty if needed, schedule a download if gapped
|
||||||
if request.TD.Cmp(p.Td()) > 0 {
|
if request.TD.Cmp(p.Td()) > 0 {
|
||||||
p.SetTd(request.TD)
|
p.SetTd(request.TD)
|
||||||
go pm.synchronise(p)
|
if request.TD.Cmp(new(big.Int).Add(pm.chainman.Td(), request.Block.Difficulty())) > 0 {
|
||||||
|
go pm.synchronise(p)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case TxMsg:
|
case TxMsg:
|
||||||
|
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
// Copyright 2015 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// Package fdtrack logs statistics about open file descriptors.
|
|
||||||
package fdtrack
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"sort"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
mutex sync.Mutex
|
|
||||||
all = make(map[string]int)
|
|
||||||
)
|
|
||||||
|
|
||||||
func Open(desc string) {
|
|
||||||
mutex.Lock()
|
|
||||||
all[desc] += 1
|
|
||||||
mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Close(desc string) {
|
|
||||||
mutex.Lock()
|
|
||||||
defer mutex.Unlock()
|
|
||||||
if c, ok := all[desc]; ok {
|
|
||||||
if c == 1 {
|
|
||||||
delete(all, desc)
|
|
||||||
} else {
|
|
||||||
all[desc]--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WrapListener(desc string, l net.Listener) net.Listener {
|
|
||||||
Open(desc)
|
|
||||||
return &wrappedListener{l, desc}
|
|
||||||
}
|
|
||||||
|
|
||||||
type wrappedListener struct {
|
|
||||||
net.Listener
|
|
||||||
desc string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *wrappedListener) Accept() (net.Conn, error) {
|
|
||||||
c, err := w.Listener.Accept()
|
|
||||||
if err == nil {
|
|
||||||
c = WrapConn(w.desc, c)
|
|
||||||
}
|
|
||||||
return c, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *wrappedListener) Close() error {
|
|
||||||
err := w.Listener.Close()
|
|
||||||
if err == nil {
|
|
||||||
Close(w.desc)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func WrapConn(desc string, conn net.Conn) net.Conn {
|
|
||||||
Open(desc)
|
|
||||||
return &wrappedConn{conn, desc}
|
|
||||||
}
|
|
||||||
|
|
||||||
type wrappedConn struct {
|
|
||||||
net.Conn
|
|
||||||
desc string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *wrappedConn) Close() error {
|
|
||||||
err := w.Conn.Close()
|
|
||||||
if err == nil {
|
|
||||||
Close(w.desc)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func Start() {
|
|
||||||
go func() {
|
|
||||||
for range time.Tick(15 * time.Second) {
|
|
||||||
mutex.Lock()
|
|
||||||
var sum, tracked = 0, []string{}
|
|
||||||
for what, n := range all {
|
|
||||||
sum += n
|
|
||||||
tracked = append(tracked, fmt.Sprintf("%s:%d", what, n))
|
|
||||||
}
|
|
||||||
mutex.Unlock()
|
|
||||||
used, _ := fdusage()
|
|
||||||
sort.Strings(tracked)
|
|
||||||
glog.Infof("fd usage %d/%d, tracked %d %v", used, fdlimit(), sum, tracked)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
// Copyright 2015 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// +build darwin
|
|
||||||
|
|
||||||
package fdtrack
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// #cgo CFLAGS: -lproc
|
|
||||||
// #include <libproc.h>
|
|
||||||
// #include <stdlib.h>
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
func fdlimit() int {
|
|
||||||
var nofile syscall.Rlimit
|
|
||||||
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &nofile); err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return int(nofile.Cur)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fdusage() (int, error) {
|
|
||||||
pid := C.int(os.Getpid())
|
|
||||||
// Query for a rough estimate on the amout of data that
|
|
||||||
// proc_pidinfo will return.
|
|
||||||
rlen, err := C.proc_pidinfo(pid, C.PROC_PIDLISTFDS, 0, nil, 0)
|
|
||||||
if rlen <= 0 {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
// Load the list of file descriptors. We don't actually care about
|
|
||||||
// the content, only about the size. Since the number of fds can
|
|
||||||
// change while we're reading them, the loop enlarges the buffer
|
|
||||||
// until proc_pidinfo says the result fitted.
|
|
||||||
var buf unsafe.Pointer
|
|
||||||
defer func() {
|
|
||||||
if buf != nil {
|
|
||||||
C.free(buf)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
for buflen := rlen; ; buflen *= 2 {
|
|
||||||
buf, err = C.reallocf(buf, C.size_t(buflen))
|
|
||||||
if buf == nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
rlen, err = C.proc_pidinfo(pid, C.PROC_PIDLISTFDS, 0, buf, buflen)
|
|
||||||
if rlen <= 0 {
|
|
||||||
return 0, err
|
|
||||||
} else if rlen == buflen {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return int(rlen / C.PROC_PIDLISTFD_SIZE), nil
|
|
||||||
}
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
// Copyright 2015 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package fdtrack
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func fdlimit() int {
|
|
||||||
var nofile syscall.Rlimit
|
|
||||||
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &nofile); err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return int(nofile.Cur)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fdusage() (int, error) {
|
|
||||||
f, err := os.Open("/proc/self/fd")
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
const batchSize = 100
|
|
||||||
n := 0
|
|
||||||
for {
|
|
||||||
list, err := f.Readdirnames(batchSize)
|
|
||||||
n += len(list)
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
} else if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
34
jsre/jsre.go
34
jsre/jsre.go
|
|
@ -65,8 +65,8 @@ func New(assetPath string) *JSRE {
|
||||||
}
|
}
|
||||||
re.loopWg.Add(1)
|
re.loopWg.Add(1)
|
||||||
go re.runEventLoop()
|
go re.runEventLoop()
|
||||||
re.Compile("pp.js", pp_js) // load prettyprint func definition
|
|
||||||
re.Set("loadScript", re.loadScript)
|
re.Set("loadScript", re.loadScript)
|
||||||
|
re.Set("inspect", prettyPrintJS)
|
||||||
return re
|
return re
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,35 +255,19 @@ func (self *JSRE) loadScript(call otto.FunctionCall) otto.Value {
|
||||||
return otto.TrueValue()
|
return otto.TrueValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrettyPrint writes v to standard output.
|
// EvalAndPrettyPrint evaluates code and pretty prints the result to
|
||||||
func (self *JSRE) PrettyPrint(v interface{}) (val otto.Value, err error) {
|
// standard output.
|
||||||
var method otto.Value
|
func (self *JSRE) EvalAndPrettyPrint(code string) (err error) {
|
||||||
self.do(func(vm *otto.Otto) {
|
self.do(func(vm *otto.Otto) {
|
||||||
val, err = vm.ToValue(v)
|
var val otto.Value
|
||||||
|
val, err = vm.Run(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
method, err = vm.Get("prettyPrint")
|
prettyPrint(vm, val)
|
||||||
if err != nil {
|
fmt.Println()
|
||||||
return
|
|
||||||
}
|
|
||||||
val, err = method.Call(method, val)
|
|
||||||
})
|
})
|
||||||
return val, err
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
// Eval evaluates JS function and returns result in a pretty printed string format.
|
|
||||||
func (self *JSRE) Eval(code string) (s string, err error) {
|
|
||||||
var val otto.Value
|
|
||||||
val, err = self.Run(code)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val, err = self.PrettyPrint(val)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%v", val), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile compiles and then runs a piece of JS code.
|
// Compile compiles and then runs a piece of JS code.
|
||||||
|
|
|
||||||
|
|
@ -103,19 +103,14 @@ func TestNatto(t *testing.T) {
|
||||||
|
|
||||||
func TestBind(t *testing.T) {
|
func TestBind(t *testing.T) {
|
||||||
jsre := New("")
|
jsre := New("")
|
||||||
|
defer jsre.Stop(false)
|
||||||
|
|
||||||
jsre.Bind("no", &testNativeObjectBinding{})
|
jsre.Bind("no", &testNativeObjectBinding{})
|
||||||
|
|
||||||
val, err := jsre.Run(`no.TestMethod("testMsg")`)
|
_, err := jsre.Run(`no.TestMethod("testMsg")`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("expected no error, got %v", err)
|
t.Errorf("expected no error, got %v", err)
|
||||||
}
|
}
|
||||||
pp, err := jsre.PrettyPrint(val)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("expected no error, got %v", err)
|
|
||||||
}
|
|
||||||
t.Logf("no: %v", pp)
|
|
||||||
jsre.Stop(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoadScript(t *testing.T) {
|
func TestLoadScript(t *testing.T) {
|
||||||
|
|
|
||||||
137
jsre/pp_js.go
137
jsre/pp_js.go
|
|
@ -1,137 +0,0 @@
|
||||||
// Copyright 2014 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package jsre
|
|
||||||
|
|
||||||
const pp_js = `
|
|
||||||
function pp(object, indent) {
|
|
||||||
try {
|
|
||||||
JSON.stringify(object)
|
|
||||||
} catch(e) {
|
|
||||||
return pp(e, indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
var str = "";
|
|
||||||
if(object instanceof Array) {
|
|
||||||
str += "[";
|
|
||||||
for(var i = 0, l = object.length; i < l; i++) {
|
|
||||||
str += pp(object[i], indent);
|
|
||||||
|
|
||||||
if(i < l-1) {
|
|
||||||
str += ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
str += " ]";
|
|
||||||
} else if (object instanceof Error) {
|
|
||||||
str += "\033[31m" + "Error:\033[0m " + object.message;
|
|
||||||
} else if (isBigNumber(object)) {
|
|
||||||
str += "\033[32m'" + object.toString(10) + "'";
|
|
||||||
} else if(typeof(object) === "object") {
|
|
||||||
str += "{\n";
|
|
||||||
indent += " ";
|
|
||||||
|
|
||||||
var fields = getFields(object);
|
|
||||||
var last = fields[fields.length - 1];
|
|
||||||
fields.forEach(function (key) {
|
|
||||||
str += indent + key + ": ";
|
|
||||||
try {
|
|
||||||
str += pp(object[key], indent);
|
|
||||||
} catch (e) {
|
|
||||||
str += pp(e, indent);
|
|
||||||
}
|
|
||||||
if(key !== last) {
|
|
||||||
str += ",";
|
|
||||||
}
|
|
||||||
str += "\n";
|
|
||||||
});
|
|
||||||
str += indent.substr(2, indent.length) + "}";
|
|
||||||
} else if(typeof(object) === "string") {
|
|
||||||
str += "\033[32m'" + object + "'";
|
|
||||||
} else if(typeof(object) === "undefined") {
|
|
||||||
str += "\033[1m\033[30m" + object;
|
|
||||||
} else if(typeof(object) === "number") {
|
|
||||||
str += "\033[31m" + object;
|
|
||||||
} else if(typeof(object) === "function") {
|
|
||||||
str += "\033[35m" + object.toString().split(" {")[0];
|
|
||||||
} else {
|
|
||||||
str += object;
|
|
||||||
}
|
|
||||||
|
|
||||||
str += "\033[0m";
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
var redundantFields = [
|
|
||||||
'valueOf',
|
|
||||||
'toString',
|
|
||||||
'toLocaleString',
|
|
||||||
'hasOwnProperty',
|
|
||||||
'isPrototypeOf',
|
|
||||||
'propertyIsEnumerable',
|
|
||||||
'constructor'
|
|
||||||
];
|
|
||||||
|
|
||||||
var getFields = function (object) {
|
|
||||||
var members = Object.getOwnPropertyNames(object);
|
|
||||||
if (object.constructor && object.constructor.prototype) {
|
|
||||||
members = members.concat(Object.getOwnPropertyNames(object.constructor.prototype));
|
|
||||||
}
|
|
||||||
|
|
||||||
var fields = members.filter(function (member) {
|
|
||||||
return !isMemberFunction(object, member)
|
|
||||||
}).sort()
|
|
||||||
var funcs = members.filter(function (member) {
|
|
||||||
return isMemberFunction(object, member)
|
|
||||||
}).sort()
|
|
||||||
|
|
||||||
var results = fields.concat(funcs);
|
|
||||||
return results.filter(function (field) {
|
|
||||||
return redundantFields.indexOf(field) === -1;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var isMemberFunction = function(object, member) {
|
|
||||||
try {
|
|
||||||
return typeof(object[member]) === "function";
|
|
||||||
} catch(e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var isBigNumber = function (object) {
|
|
||||||
var result = typeof BigNumber !== 'undefined' && object instanceof BigNumber;
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
if (typeof(object) === "object" && object.constructor != null) {
|
|
||||||
result = object.constructor.toString().indexOf("function BigNumber(") == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
};
|
|
||||||
|
|
||||||
function prettyPrint(/* */) {
|
|
||||||
var args = arguments;
|
|
||||||
var ret = "";
|
|
||||||
for(var i = 0, l = args.length; i < l; i++) {
|
|
||||||
ret += pp(args[i], "") + "\n";
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
var print = prettyPrint;
|
|
||||||
`
|
|
||||||
231
jsre/pretty.go
Normal file
231
jsre/pretty.go
Normal file
|
|
@ -0,0 +1,231 @@
|
||||||
|
// Copyright 2015 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package jsre
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
"github.com/robertkrimen/otto"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
maxPrettyPrintLevel = 3
|
||||||
|
indentString = " "
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
functionColor = color.New(color.FgMagenta)
|
||||||
|
specialColor = color.New(color.Bold)
|
||||||
|
numberColor = color.New(color.FgRed)
|
||||||
|
stringColor = color.New(color.FgGreen)
|
||||||
|
)
|
||||||
|
|
||||||
|
// these fields are hidden when printing objects.
|
||||||
|
var boringKeys = map[string]bool{
|
||||||
|
"valueOf": true,
|
||||||
|
"toString": true,
|
||||||
|
"toLocaleString": true,
|
||||||
|
"hasOwnProperty": true,
|
||||||
|
"isPrototypeOf": true,
|
||||||
|
"propertyIsEnumerable": true,
|
||||||
|
"constructor": true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// prettyPrint writes value to standard output.
|
||||||
|
func prettyPrint(vm *otto.Otto, value otto.Value) {
|
||||||
|
ppctx{vm}.printValue(value, 0, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func prettyPrintJS(call otto.FunctionCall) otto.Value {
|
||||||
|
for _, v := range call.ArgumentList {
|
||||||
|
prettyPrint(call.Otto, v)
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
return otto.UndefinedValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
type ppctx struct{ vm *otto.Otto }
|
||||||
|
|
||||||
|
func (ctx ppctx) indent(level int) string {
|
||||||
|
return strings.Repeat(indentString, level)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx ppctx) printValue(v otto.Value, level int, inArray bool) {
|
||||||
|
switch {
|
||||||
|
case v.IsObject():
|
||||||
|
ctx.printObject(v.Object(), level, inArray)
|
||||||
|
case v.IsNull():
|
||||||
|
specialColor.Print("null")
|
||||||
|
case v.IsUndefined():
|
||||||
|
specialColor.Print("undefined")
|
||||||
|
case v.IsString():
|
||||||
|
s, _ := v.ToString()
|
||||||
|
stringColor.Printf("%q", s)
|
||||||
|
case v.IsBoolean():
|
||||||
|
b, _ := v.ToBoolean()
|
||||||
|
specialColor.Printf("%t", b)
|
||||||
|
case v.IsNaN():
|
||||||
|
numberColor.Printf("NaN")
|
||||||
|
case v.IsNumber():
|
||||||
|
s, _ := v.ToString()
|
||||||
|
numberColor.Printf("%s", s)
|
||||||
|
default:
|
||||||
|
fmt.Printf("<unprintable>")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx ppctx) printObject(obj *otto.Object, level int, inArray bool) {
|
||||||
|
switch obj.Class() {
|
||||||
|
case "Array":
|
||||||
|
lv, _ := obj.Get("length")
|
||||||
|
len, _ := lv.ToInteger()
|
||||||
|
if len == 0 {
|
||||||
|
fmt.Printf("[]")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if level > maxPrettyPrintLevel {
|
||||||
|
fmt.Print("[...]")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Print("[")
|
||||||
|
for i := int64(0); i < len; i++ {
|
||||||
|
el, err := obj.Get(strconv.FormatInt(i, 10))
|
||||||
|
if err == nil {
|
||||||
|
ctx.printValue(el, level+1, true)
|
||||||
|
}
|
||||||
|
if i < len-1 {
|
||||||
|
fmt.Printf(", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Print("]")
|
||||||
|
|
||||||
|
case "Object":
|
||||||
|
// Print values from bignumber.js as regular numbers.
|
||||||
|
if ctx.isBigNumber(obj) {
|
||||||
|
numberColor.Print(toString(obj))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Otherwise, print all fields indented, but stop if we're too deep.
|
||||||
|
keys := ctx.fields(obj)
|
||||||
|
if len(keys) == 0 {
|
||||||
|
fmt.Print("{}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if level > maxPrettyPrintLevel {
|
||||||
|
fmt.Print("{...}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("{")
|
||||||
|
for i, k := range keys {
|
||||||
|
v, _ := obj.Get(k)
|
||||||
|
fmt.Printf("%s%s: ", ctx.indent(level+1), k)
|
||||||
|
ctx.printValue(v, level+1, false)
|
||||||
|
if i < len(keys)-1 {
|
||||||
|
fmt.Printf(",")
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
if inArray {
|
||||||
|
level--
|
||||||
|
}
|
||||||
|
fmt.Printf("%s}", ctx.indent(level))
|
||||||
|
|
||||||
|
case "Function":
|
||||||
|
// Use toString() to display the argument list if possible.
|
||||||
|
if robj, err := obj.Call("toString"); err != nil {
|
||||||
|
functionColor.Print("function()")
|
||||||
|
} else {
|
||||||
|
desc := strings.Trim(strings.Split(robj.String(), "{")[0], " \t\n")
|
||||||
|
desc = strings.Replace(desc, " (", "(", 1)
|
||||||
|
functionColor.Print(desc)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "RegExp":
|
||||||
|
stringColor.Print(toString(obj))
|
||||||
|
|
||||||
|
default:
|
||||||
|
if v, _ := obj.Get("toString"); v.IsFunction() && level <= maxPrettyPrintLevel {
|
||||||
|
s, _ := obj.Call("toString")
|
||||||
|
fmt.Printf("<%s %s>", obj.Class(), s.String())
|
||||||
|
} else {
|
||||||
|
fmt.Printf("<%s>", obj.Class())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx ppctx) fields(obj *otto.Object) []string {
|
||||||
|
var (
|
||||||
|
vals, methods []string
|
||||||
|
seen = make(map[string]bool)
|
||||||
|
)
|
||||||
|
add := func(k string) {
|
||||||
|
if seen[k] || boringKeys[k] {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
seen[k] = true
|
||||||
|
if v, _ := obj.Get(k); v.IsFunction() {
|
||||||
|
methods = append(methods, k)
|
||||||
|
} else {
|
||||||
|
vals = append(vals, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add own properties
|
||||||
|
ctx.doOwnProperties(obj.Value(), add)
|
||||||
|
// add properties of the constructor
|
||||||
|
if cp := constructorPrototype(obj); cp != nil {
|
||||||
|
ctx.doOwnProperties(cp.Value(), add)
|
||||||
|
}
|
||||||
|
sort.Strings(vals)
|
||||||
|
sort.Strings(methods)
|
||||||
|
return append(vals, methods...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx ppctx) doOwnProperties(v otto.Value, f func(string)) {
|
||||||
|
Object, _ := ctx.vm.Object("Object")
|
||||||
|
rv, _ := Object.Call("getOwnPropertyNames", v)
|
||||||
|
gv, _ := rv.Export()
|
||||||
|
for _, v := range gv.([]interface{}) {
|
||||||
|
f(v.(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx ppctx) isBigNumber(v *otto.Object) bool {
|
||||||
|
BigNumber, err := ctx.vm.Run("BigNumber.prototype")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
cp := constructorPrototype(v)
|
||||||
|
return cp != nil && cp.Value() == BigNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
func toString(obj *otto.Object) string {
|
||||||
|
s, _ := obj.Call("toString")
|
||||||
|
return s.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func constructorPrototype(obj *otto.Object) *otto.Object {
|
||||||
|
if v, _ := obj.Get("constructor"); v.Object() != nil {
|
||||||
|
if v, _ = v.Object().Get("prototype"); v.Object() != nil {
|
||||||
|
return v.Object()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -297,14 +297,17 @@ func (self *worker) wait() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// broadcast before waiting for validation
|
// broadcast before waiting for validation
|
||||||
go func(block *types.Block, logs state.Logs) {
|
go func(block *types.Block, logs state.Logs, receipts []*types.Receipt) {
|
||||||
self.mux.Post(core.NewMinedBlockEvent{block})
|
self.mux.Post(core.NewMinedBlockEvent{block})
|
||||||
self.mux.Post(core.ChainEvent{block, block.Hash(), logs})
|
self.mux.Post(core.ChainEvent{block, block.Hash(), logs})
|
||||||
if stat == core.CanonStatTy {
|
if stat == core.CanonStatTy {
|
||||||
self.mux.Post(core.ChainHeadEvent{block})
|
self.mux.Post(core.ChainHeadEvent{block})
|
||||||
self.mux.Post(logs)
|
self.mux.Post(logs)
|
||||||
}
|
}
|
||||||
}(block, work.state.Logs())
|
if err := core.PutBlockReceipts(self.chainDb, block, receipts); err != nil {
|
||||||
|
glog.V(logger.Warn).Infoln("error writing block receipts:", err)
|
||||||
|
}
|
||||||
|
}(block, work.state.Logs(), work.receipts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check staleness and display confirmation
|
// check staleness and display confirmation
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/fdtrack"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
|
@ -213,7 +212,6 @@ func (t *dialTask) Do(srv *Server) {
|
||||||
glog.V(logger.Detail).Infof("dial error: %v", err)
|
glog.V(logger.Detail).Infof("dial error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fd = fdtrack.WrapConn("p2p", fd)
|
|
||||||
mfd := newMeteredConn(fd, false)
|
mfd := newMeteredConn(fd, false)
|
||||||
|
|
||||||
srv.setupConn(mfd, t.flags, t.dest)
|
srv.setupConn(mfd, t.flags, t.dest)
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,10 @@ type Node struct {
|
||||||
// In those tests, the content of sha will not actually correspond
|
// In those tests, the content of sha will not actually correspond
|
||||||
// with ID.
|
// with ID.
|
||||||
sha common.Hash
|
sha common.Hash
|
||||||
|
|
||||||
|
// whether this node is currently being pinged in order to replace
|
||||||
|
// it in a bucket
|
||||||
|
contested bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNode(id NodeID, ip net.IP, udpPort, tcpPort uint16) *Node {
|
func newNode(id NodeID, ip net.IP, udpPort, tcpPort uint16) *Node {
|
||||||
|
|
|
||||||
|
|
@ -455,24 +455,31 @@ func (tab *Table) ping(id NodeID, addr *net.UDPAddr) error {
|
||||||
func (tab *Table) add(new *Node) {
|
func (tab *Table) add(new *Node) {
|
||||||
b := tab.buckets[logdist(tab.self.sha, new.sha)]
|
b := tab.buckets[logdist(tab.self.sha, new.sha)]
|
||||||
tab.mutex.Lock()
|
tab.mutex.Lock()
|
||||||
|
defer tab.mutex.Unlock()
|
||||||
if b.bump(new) {
|
if b.bump(new) {
|
||||||
tab.mutex.Unlock()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var oldest *Node
|
var oldest *Node
|
||||||
if len(b.entries) == bucketSize {
|
if len(b.entries) == bucketSize {
|
||||||
oldest = b.entries[bucketSize-1]
|
oldest = b.entries[bucketSize-1]
|
||||||
|
if oldest.contested {
|
||||||
|
// The node is already being replaced, don't attempt
|
||||||
|
// to replace it.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
oldest.contested = true
|
||||||
// Let go of the mutex so other goroutines can access
|
// Let go of the mutex so other goroutines can access
|
||||||
// the table while we ping the least recently active node.
|
// the table while we ping the least recently active node.
|
||||||
tab.mutex.Unlock()
|
tab.mutex.Unlock()
|
||||||
if err := tab.ping(oldest.ID, oldest.addr()); err == nil {
|
err := tab.ping(oldest.ID, oldest.addr())
|
||||||
|
tab.mutex.Lock()
|
||||||
|
oldest.contested = false
|
||||||
|
if err == nil {
|
||||||
// The node responded, don't replace it.
|
// The node responded, don't replace it.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tab.mutex.Lock()
|
|
||||||
}
|
}
|
||||||
added := b.replace(new, oldest)
|
added := b.replace(new, oldest)
|
||||||
tab.mutex.Unlock()
|
|
||||||
if added && tab.nodeAddedHook != nil {
|
if added && tab.nodeAddedHook != nil {
|
||||||
tab.nodeAddedHook(new)
|
tab.nodeAddedHook(new)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/fdtrack"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||||
|
|
@ -200,7 +199,6 @@ func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface, nodeDBP
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fdtrack.Open("p2p")
|
|
||||||
conn, err := net.ListenUDP("udp", addr)
|
conn, err := net.ListenUDP("udp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -238,7 +236,6 @@ func newUDP(priv *ecdsa.PrivateKey, c conn, natm nat.Interface, nodeDBPath strin
|
||||||
|
|
||||||
func (t *udp) close() {
|
func (t *udp) close() {
|
||||||
close(t.closing)
|
close(t.closing)
|
||||||
fdtrack.Close("p2p")
|
|
||||||
t.conn.Close()
|
t.conn.Close()
|
||||||
// TODO: wait for the loops to end.
|
// TODO: wait for the loops to end.
|
||||||
}
|
}
|
||||||
|
|
@ -458,6 +455,10 @@ func encodePacket(priv *ecdsa.PrivateKey, ptype byte, req interface{}) ([]byte,
|
||||||
return packet, nil
|
return packet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tempError interface {
|
||||||
|
Temporary() bool
|
||||||
|
}
|
||||||
|
|
||||||
// readLoop runs in its own goroutine. it handles incoming UDP packets.
|
// readLoop runs in its own goroutine. it handles incoming UDP packets.
|
||||||
func (t *udp) readLoop() {
|
func (t *udp) readLoop() {
|
||||||
defer t.conn.Close()
|
defer t.conn.Close()
|
||||||
|
|
@ -467,7 +468,13 @@ func (t *udp) readLoop() {
|
||||||
buf := make([]byte, 1280)
|
buf := make([]byte, 1280)
|
||||||
for {
|
for {
|
||||||
nbytes, from, err := t.conn.ReadFromUDP(buf)
|
nbytes, from, err := t.conn.ReadFromUDP(buf)
|
||||||
if err != nil {
|
if tempErr, ok := err.(tempError); ok && tempErr.Temporary() {
|
||||||
|
// Ignore temporary read errors.
|
||||||
|
glog.V(logger.Debug).Infof("Temporary read error: %v", err)
|
||||||
|
continue
|
||||||
|
} else if err != nil {
|
||||||
|
// Shut down the loop for permament errors.
|
||||||
|
glog.V(logger.Debug).Infof("Read error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.handlePacket(from, buf[:nbytes])
|
t.handlePacket(from, buf[:nbytes])
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ var (
|
||||||
// meteredConn is a wrapper around a network TCP connection that meters both the
|
// meteredConn is a wrapper around a network TCP connection that meters both the
|
||||||
// inbound and outbound network traffic.
|
// inbound and outbound network traffic.
|
||||||
type meteredConn struct {
|
type meteredConn struct {
|
||||||
net.Conn
|
*net.TCPConn // Network connection to wrap with metering
|
||||||
}
|
}
|
||||||
|
|
||||||
// newMeteredConn creates a new metered connection, also bumping the ingress or
|
// newMeteredConn creates a new metered connection, also bumping the ingress or
|
||||||
|
|
@ -45,13 +45,13 @@ func newMeteredConn(conn net.Conn, ingress bool) net.Conn {
|
||||||
} else {
|
} else {
|
||||||
egressConnectMeter.Mark(1)
|
egressConnectMeter.Mark(1)
|
||||||
}
|
}
|
||||||
return &meteredConn{conn}
|
return &meteredConn{conn.(*net.TCPConn)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read delegates a network read to the underlying connection, bumping the ingress
|
// Read delegates a network read to the underlying connection, bumping the ingress
|
||||||
// traffic meter along the way.
|
// traffic meter along the way.
|
||||||
func (c *meteredConn) Read(b []byte) (n int, err error) {
|
func (c *meteredConn) Read(b []byte) (n int, err error) {
|
||||||
n, err = c.Conn.Read(b)
|
n, err = c.TCPConn.Read(b)
|
||||||
ingressTrafficMeter.Mark(int64(n))
|
ingressTrafficMeter.Mark(int64(n))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +59,7 @@ func (c *meteredConn) Read(b []byte) (n int, err error) {
|
||||||
// Write delegates a network write to the underlying connection, bumping the
|
// Write delegates a network write to the underlying connection, bumping the
|
||||||
// egress traffic meter along the way.
|
// egress traffic meter along the way.
|
||||||
func (c *meteredConn) Write(b []byte) (n int, err error) {
|
func (c *meteredConn) Write(b []byte) (n int, err error) {
|
||||||
n, err = c.Conn.Write(b)
|
n, err = c.TCPConn.Write(b)
|
||||||
egressTrafficMeter.Mark(int64(n))
|
egressTrafficMeter.Mark(int64(n))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/fdtrack"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
|
@ -373,7 +372,7 @@ func (srv *Server) startListening() error {
|
||||||
}
|
}
|
||||||
laddr := listener.Addr().(*net.TCPAddr)
|
laddr := listener.Addr().(*net.TCPAddr)
|
||||||
srv.ListenAddr = laddr.String()
|
srv.ListenAddr = laddr.String()
|
||||||
srv.listener = fdtrack.WrapListener("p2p", listener)
|
srv.listener = listener
|
||||||
srv.loopWG.Add(1)
|
srv.loopWG.Add(1)
|
||||||
go srv.listenLoop()
|
go srv.listenLoop()
|
||||||
// Map the TCP listening port if NAT is configured.
|
// Map the TCP listening port if NAT is configured.
|
||||||
|
|
@ -542,6 +541,10 @@ func (srv *Server) encHandshakeChecks(peers map[discover.NodeID]*Peer, c *conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tempError interface {
|
||||||
|
Temporary() bool
|
||||||
|
}
|
||||||
|
|
||||||
// listenLoop runs in its own goroutine and accepts
|
// listenLoop runs in its own goroutine and accepts
|
||||||
// inbound connections.
|
// inbound connections.
|
||||||
func (srv *Server) listenLoop() {
|
func (srv *Server) listenLoop() {
|
||||||
|
|
@ -561,16 +564,31 @@ func (srv *Server) listenLoop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
// Wait for a handshake slot before accepting.
|
||||||
<-slots
|
<-slots
|
||||||
fd, err := srv.listener.Accept()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mfd := newMeteredConn(fd, true)
|
|
||||||
|
|
||||||
glog.V(logger.Debug).Infof("Accepted conn %v\n", mfd.RemoteAddr())
|
var (
|
||||||
|
fd net.Conn
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
for {
|
||||||
|
fd, err = srv.listener.Accept()
|
||||||
|
if tempErr, ok := err.(tempError); ok && tempErr.Temporary() {
|
||||||
|
glog.V(logger.Debug).Infof("Temporary read error: %v", err)
|
||||||
|
continue
|
||||||
|
} else if err != nil {
|
||||||
|
glog.V(logger.Debug).Infof("Read error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fd = newMeteredConn(fd, true)
|
||||||
|
glog.V(logger.Debug).Infof("Accepted conn %v\n", fd.RemoteAddr())
|
||||||
|
|
||||||
|
// Spawn the handler. It will give the slot back when the connection
|
||||||
|
// has been established.
|
||||||
go func() {
|
go func() {
|
||||||
srv.setupConn(mfd, inboundConn, nil)
|
srv.setupConn(fd, inboundConn, nil)
|
||||||
slots <- struct{}{}
|
slots <- struct{}{}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
"github.com/ethereum/go-ethereum/rpc/comms"
|
"github.com/ethereum/go-ethereum/rpc/comms"
|
||||||
"github.com/ethereum/go-ethereum/rpc/shared"
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/useragent"
|
||||||
"github.com/ethereum/go-ethereum/xeth"
|
"github.com/ethereum/go-ethereum/xeth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -71,6 +72,7 @@ var (
|
||||||
"admin_httpGet": (*adminApi).HttpGet,
|
"admin_httpGet": (*adminApi).HttpGet,
|
||||||
"admin_sleepBlocks": (*adminApi).SleepBlocks,
|
"admin_sleepBlocks": (*adminApi).SleepBlocks,
|
||||||
"admin_sleep": (*adminApi).Sleep,
|
"admin_sleep": (*adminApi).Sleep,
|
||||||
|
"admin_enableUserAgent": (*adminApi).EnableUserAgent,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -474,3 +476,10 @@ func (self *adminApi) HttpGet(req *shared.Request) (interface{}, error) {
|
||||||
|
|
||||||
return string(resp), nil
|
return string(resp), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *adminApi) EnableUserAgent(req *shared.Request) (interface{}, error) {
|
||||||
|
if fe, ok := self.xeth.Frontend().(*useragent.RemoteFrontend); ok {
|
||||||
|
fe.Enable()
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -577,10 +577,10 @@ func (self *ethApi) SubmitWork(req *shared.Request) (interface{}, error) {
|
||||||
func (self *ethApi) SubmitHashrate(req *shared.Request) (interface{}, error) {
|
func (self *ethApi) SubmitHashrate(req *shared.Request) (interface{}, error) {
|
||||||
args := new(SubmitHashRateArgs)
|
args := new(SubmitHashRateArgs)
|
||||||
if err := self.codec.Decode(req.Params, &args); err != nil {
|
if err := self.codec.Decode(req.Params, &args); err != nil {
|
||||||
return nil, shared.NewDecodeParamError(err.Error())
|
return false, shared.NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
self.xeth.RemoteMining().SubmitHashrate(common.HexToHash(args.Id), args.Rate)
|
self.xeth.RemoteMining().SubmitHashrate(common.HexToHash(args.Id), args.Rate)
|
||||||
return nil, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ethApi) Resend(req *shared.Request) (interface{}, error) {
|
func (self *ethApi) Resend(req *shared.Request) (interface{}, error) {
|
||||||
|
|
|
||||||
|
|
@ -908,14 +908,14 @@ func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
type tx struct {
|
type tx struct {
|
||||||
tx *types.Transaction
|
tx *types.Transaction
|
||||||
|
|
||||||
To string
|
To string `json:"to"`
|
||||||
From string
|
From string `json:"from"`
|
||||||
Nonce string
|
Nonce string `json:"nonce"`
|
||||||
Value string
|
Value string `json:"value"`
|
||||||
Data string
|
Data string `json:"data"`
|
||||||
GasLimit string
|
GasLimit string `json:"gas"`
|
||||||
GasPrice string
|
GasPrice string `json:"gasPrice"`
|
||||||
Hash string
|
Hash string `json:"hash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTx(t *types.Transaction) *tx {
|
func newTx(t *types.Transaction) *tx {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ var (
|
||||||
netMapping = map[string]nethandler{
|
netMapping = map[string]nethandler{
|
||||||
"net_peerCount": (*netApi).PeerCount,
|
"net_peerCount": (*netApi).PeerCount,
|
||||||
"net_listening": (*netApi).IsListening,
|
"net_listening": (*netApi).IsListening,
|
||||||
"net_version": (*netApi).Version,
|
"net_version": (*netApi).Version,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -97,4 +97,3 @@ func (self *netApi) IsListening(req *shared.Request) (interface{}, error) {
|
||||||
func (self *netApi) Version(req *shared.Request) (interface{}, error) {
|
func (self *netApi) Version(req *shared.Request) (interface{}, error) {
|
||||||
return self.xeth.NetworkVersion(), nil
|
return self.xeth.NetworkVersion(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -125,18 +126,17 @@ func (self *personalApi) UnlockAccount(req *shared.Request) (interface{}, error)
|
||||||
return nil, shared.NewDecodeParamError(err.Error())
|
return nil, shared.NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
if len(args.Passphrase) == 0 {
|
||||||
|
fe := self.xeth.Frontend()
|
||||||
|
if fe == nil {
|
||||||
|
return false, fmt.Errorf("No password provided")
|
||||||
|
}
|
||||||
|
return fe.UnlockAccount(common.HexToAddress(args.Address).Bytes()), nil
|
||||||
|
}
|
||||||
|
|
||||||
am := self.ethereum.AccountManager()
|
am := self.ethereum.AccountManager()
|
||||||
addr := common.HexToAddress(args.Address)
|
addr := common.HexToAddress(args.Address)
|
||||||
|
|
||||||
if args.Duration == -1 {
|
err := am.TimedUnlock(addr, args.Passphrase, time.Duration(args.Duration)*time.Second)
|
||||||
err = am.Unlock(addr, args.Passphrase)
|
return err == nil, err
|
||||||
} else {
|
|
||||||
err = am.TimedUnlock(addr, args.Passphrase, time.Duration(args.Duration)*time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return false, err
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,10 +86,10 @@ func (args *UnlockAccountArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return shared.NewDecodeParamError(err.Error())
|
return shared.NewDecodeParamError(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Duration = -1
|
args.Duration = 0
|
||||||
|
|
||||||
if len(obj) < 2 {
|
if len(obj) < 1 {
|
||||||
return shared.NewInsufficientParamsError(len(obj), 2)
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if addrstr, ok := obj[0].(string); ok {
|
if addrstr, ok := obj[0].(string); ok {
|
||||||
|
|
@ -98,10 +98,18 @@ func (args *UnlockAccountArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
return shared.NewInvalidTypeError("address", "not a string")
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
if passphrasestr, ok := obj[1].(string); ok {
|
if len(obj) >= 2 && obj[1] != nil {
|
||||||
args.Passphrase = passphrasestr
|
if passphrasestr, ok := obj[1].(string); ok {
|
||||||
} else {
|
args.Passphrase = passphrasestr
|
||||||
return shared.NewInvalidTypeError("passphrase", "not a string")
|
} else {
|
||||||
|
return shared.NewInvalidTypeError("passphrase", "not a string")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) >= 3 && obj[2] != nil {
|
||||||
|
if duration, ok := obj[2].(float64); ok {
|
||||||
|
args.Duration = int(duration)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ type ApiCoder interface {
|
||||||
ReadRequest() ([]*shared.Request, bool, error)
|
ReadRequest() ([]*shared.Request, bool, error)
|
||||||
// Parse response message from underlying stream
|
// Parse response message from underlying stream
|
||||||
ReadResponse() (interface{}, error)
|
ReadResponse() (interface{}, error)
|
||||||
|
// Read raw message from underlying stream
|
||||||
|
Recv() (interface{}, error)
|
||||||
// Encode response to encoded form in underlying stream
|
// Encode response to encoded form in underlying stream
|
||||||
WriteResponse(interface{}) error
|
WriteResponse(interface{}) error
|
||||||
// Decode single message from data
|
// Decode single message from data
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/rpc/shared"
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
)
|
)
|
||||||
|
|
@ -73,35 +74,41 @@ func (self *JsonCodec) ReadRequest() (requests []*shared.Request, isBatch bool,
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *JsonCodec) ReadResponse() (interface{}, error) {
|
func (self *JsonCodec) Recv() (interface{}, error) {
|
||||||
bytesInBuffer := 0
|
var msg json.RawMessage
|
||||||
buf := make([]byte, MAX_RESPONSE_SIZE)
|
err := self.d.Decode(&msg)
|
||||||
|
if err != nil {
|
||||||
deadline := time.Now().Add(READ_TIMEOUT * time.Second)
|
self.c.Close()
|
||||||
if err := self.c.SetDeadline(deadline); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
return msg, err
|
||||||
n, err := self.c.Read(buf[bytesInBuffer:])
|
}
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
bytesInBuffer += n
|
|
||||||
|
|
||||||
var failure shared.ErrorResponse
|
func (self *JsonCodec) ReadResponse() (interface{}, error) {
|
||||||
if err = json.Unmarshal(buf[:bytesInBuffer], &failure); err == nil && failure.Error != nil {
|
in, err := self.Recv()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if msg, ok := in.(json.RawMessage); ok {
|
||||||
|
var req *shared.Request
|
||||||
|
if err = json.Unmarshal(msg, &req); err == nil && strings.HasPrefix(req.Method, "agent_") {
|
||||||
|
return req, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var failure *shared.ErrorResponse
|
||||||
|
if err = json.Unmarshal(msg, &failure); err == nil && failure.Error != nil {
|
||||||
return failure, fmt.Errorf(failure.Error.Message)
|
return failure, fmt.Errorf(failure.Error.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
var success shared.SuccessResponse
|
var success *shared.SuccessResponse
|
||||||
if err = json.Unmarshal(buf[:bytesInBuffer], &success); err == nil {
|
if err = json.Unmarshal(msg, &success); err == nil {
|
||||||
return success, nil
|
return success, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.c.Close()
|
return in, err
|
||||||
return nil, fmt.Errorf("Unable to read response")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode data
|
// Decode data
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type EthereumClient interface {
|
type EthereumClient interface {
|
||||||
// Close underlaying connection
|
// Close underlying connection
|
||||||
Close()
|
Close()
|
||||||
// Send request
|
// Send request
|
||||||
Send(interface{}) error
|
Send(interface{}) error
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/fdtrack"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
|
|
@ -178,7 +177,6 @@ func listenHTTP(addr string, h http.Handler) (*stopServer, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
l = fdtrack.WrapListener("rpc", l)
|
|
||||||
s := &stopServer{l: l, idle: make(map[net.Conn]struct{})}
|
s := &stopServer{l: l, idle: make(map[net.Conn]struct{})}
|
||||||
s.Server = &http.Server{
|
s.Server = &http.Server{
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ func (self *InProcClient) Send(req interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *InProcClient) Recv() (interface{}, error) {
|
func (self *InProcClient) Recv() (interface{}, error) {
|
||||||
return self.lastRes, self.lastErr
|
return *shared.NewRpcResponse(self.lastId, self.lastJsonrpc, self.lastRes, self.lastErr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *InProcClient) SupportedModules() (map[string]string, error) {
|
func (self *InProcClient) SupportedModules() (map[string]string, error) {
|
||||||
|
|
|
||||||
|
|
@ -46,33 +46,18 @@ func (self *ipcClient) Send(req interface{}) error {
|
||||||
var err error
|
var err error
|
||||||
if r, ok := req.(*shared.Request); ok {
|
if r, ok := req.(*shared.Request); ok {
|
||||||
if err = self.coder.WriteResponse(r); err != nil {
|
if err = self.coder.WriteResponse(r); err != nil {
|
||||||
if _, ok := err.(*net.OpError); ok { // connection lost, retry once
|
if err = self.reconnect(); err == nil {
|
||||||
if err = self.reconnect(); err == nil {
|
err = self.coder.WriteResponse(r)
|
||||||
err = self.coder.WriteResponse(r)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
return fmt.Errorf("Invalid request (%T)", req)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ipcClient) Recv() (interface{}, error) {
|
func (self *ipcClient) Recv() (interface{}, error) {
|
||||||
res, err := self.coder.ReadResponse()
|
return self.coder.ReadResponse()
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if r, ok := res.(shared.SuccessResponse); ok {
|
|
||||||
return r.Result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if r, ok := res.(shared.ErrorResponse); ok {
|
|
||||||
return r.Error, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ipcClient) SupportedModules() (map[string]string, error) {
|
func (self *ipcClient) SupportedModules() (map[string]string, error) {
|
||||||
|
|
@ -91,7 +76,7 @@ func (self *ipcClient) SupportedModules() (map[string]string, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if sucRes, ok := res.(shared.SuccessResponse); ok {
|
if sucRes, ok := res.(*shared.SuccessResponse); ok {
|
||||||
data, _ := json.Marshal(sucRes.Result)
|
data, _ := json.Marshal(sucRes.Result)
|
||||||
modules := make(map[string]string)
|
modules := make(map[string]string)
|
||||||
err = json.Unmarshal(data, &modules)
|
err = json.Unmarshal(data, &modules)
|
||||||
|
|
@ -109,8 +94,8 @@ func NewIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start IPC server
|
// Start IPC server
|
||||||
func StartIpc(cfg IpcConfig, codec codec.Codec, offeredApi shared.EthereumApi) error {
|
func StartIpc(cfg IpcConfig, codec codec.Codec, initializer func(conn net.Conn) (shared.EthereumApi, error)) error {
|
||||||
return startIpc(cfg, codec, offeredApi)
|
return startIpc(cfg, codec, initializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newIpcConnId() int {
|
func newIpcConnId() int {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/fdtrack"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/rpc/codec"
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
|
|
@ -48,19 +47,18 @@ func (self *ipcClient) reconnect() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
|
func startIpc(cfg IpcConfig, codec codec.Codec, initializer func(conn net.Conn) (shared.EthereumApi, error)) error {
|
||||||
os.Remove(cfg.Endpoint) // in case it still exists from a previous run
|
os.Remove(cfg.Endpoint) // in case it still exists from a previous run
|
||||||
|
|
||||||
l, err := net.Listen("unix", cfg.Endpoint)
|
l, err := net.ListenUnix("unix", &net.UnixAddr{Name: cfg.Endpoint, Net: "unix"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l = fdtrack.WrapListener("ipc", l)
|
|
||||||
os.Chmod(cfg.Endpoint, 0600)
|
os.Chmod(cfg.Endpoint, 0600)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
conn, err := l.Accept()
|
conn, err := l.AcceptUnix()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(logger.Error).Infof("Error accepting ipc connection - %v\n", err)
|
glog.V(logger.Error).Infof("Error accepting ipc connection - %v\n", err)
|
||||||
continue
|
continue
|
||||||
|
|
@ -69,6 +67,13 @@ func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
|
||||||
id := newIpcConnId()
|
id := newIpcConnId()
|
||||||
glog.V(logger.Debug).Infof("New IPC connection with id %06d started\n", id)
|
glog.V(logger.Debug).Infof("New IPC connection with id %06d started\n", id)
|
||||||
|
|
||||||
|
api, err := initializer(conn)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Unable to initialize IPC connection - %v\n", err)
|
||||||
|
conn.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
go handle(id, conn, api, codec)
|
go handle(id, conn, api, codec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -667,7 +667,7 @@ func (self *ipcClient) reconnect() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
|
func startIpc(cfg IpcConfig, codec codec.Codec, initializer func(conn net.Conn) (shared.EthereumApi, error)) error {
|
||||||
os.Remove(cfg.Endpoint) // in case it still exists from a previous run
|
os.Remove(cfg.Endpoint) // in case it still exists from a previous run
|
||||||
|
|
||||||
l, err := Listen(cfg.Endpoint)
|
l, err := Listen(cfg.Endpoint)
|
||||||
|
|
@ -687,6 +687,13 @@ func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
|
||||||
id := newIpcConnId()
|
id := newIpcConnId()
|
||||||
glog.V(logger.Debug).Infof("New IPC connection with id %06d started\n", id)
|
glog.V(logger.Debug).Infof("New IPC connection with id %06d started\n", id)
|
||||||
|
|
||||||
|
api, err := initializer(conn)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Unable to initialize IPC connection - %v\n", err)
|
||||||
|
conn.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
go handle(id, conn, api, codec)
|
go handle(id, conn, api, codec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
89
rpc/jeth.go
89
rpc/jeth.go
|
|
@ -18,12 +18,17 @@ package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/jsre"
|
"github.com/ethereum/go-ethereum/jsre"
|
||||||
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/rpc/comms"
|
"github.com/ethereum/go-ethereum/rpc/comms"
|
||||||
"github.com/ethereum/go-ethereum/rpc/shared"
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/useragent"
|
||||||
|
"github.com/ethereum/go-ethereum/xeth"
|
||||||
|
|
||||||
"github.com/robertkrimen/otto"
|
"github.com/robertkrimen/otto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -31,10 +36,21 @@ type Jeth struct {
|
||||||
ethApi shared.EthereumApi
|
ethApi shared.EthereumApi
|
||||||
re *jsre.JSRE
|
re *jsre.JSRE
|
||||||
client comms.EthereumClient
|
client comms.EthereumClient
|
||||||
|
fe xeth.Frontend
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewJeth(ethApi shared.EthereumApi, re *jsre.JSRE, client comms.EthereumClient) *Jeth {
|
func NewJeth(ethApi shared.EthereumApi, re *jsre.JSRE, client comms.EthereumClient, fe xeth.Frontend) *Jeth {
|
||||||
return &Jeth{ethApi, re, client}
|
// enable the jeth as the user agent
|
||||||
|
req := shared.Request{
|
||||||
|
Id: 0,
|
||||||
|
Method: useragent.EnableUserAgentMethod,
|
||||||
|
Jsonrpc: shared.JsonRpcVersion,
|
||||||
|
Params: []byte("[]"),
|
||||||
|
}
|
||||||
|
client.Send(&req)
|
||||||
|
client.Recv()
|
||||||
|
|
||||||
|
return &Jeth{ethApi, re, client, fe}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Jeth) err(call otto.FunctionCall, code int, msg string, id interface{}) (response otto.Value) {
|
func (self *Jeth) err(call otto.FunctionCall, code int, msg string, id interface{}) (response otto.Value) {
|
||||||
|
|
@ -72,16 +88,34 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return self.err(call, -32603, err.Error(), req.Id)
|
return self.err(call, -32603, err.Error(), req.Id)
|
||||||
}
|
}
|
||||||
respif, err = self.client.Recv()
|
|
||||||
|
|
||||||
|
recv:
|
||||||
|
respif, err = self.client.Recv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return self.err(call, -32603, err.Error(), req.Id)
|
return self.err(call, -32603, err.Error(), req.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
agentreq, isRequest := respif.(*shared.Request)
|
||||||
|
if isRequest {
|
||||||
|
self.handleRequest(agentreq)
|
||||||
|
goto recv // receive response after agent interaction
|
||||||
|
}
|
||||||
|
|
||||||
|
sucres, isSuccessResponse := respif.(*shared.SuccessResponse)
|
||||||
|
errres, isErrorResponse := respif.(*shared.ErrorResponse)
|
||||||
|
if !isSuccessResponse && !isErrorResponse {
|
||||||
|
return self.err(call, -32603, fmt.Sprintf("Invalid response type (%T)", respif), req.Id)
|
||||||
|
}
|
||||||
|
|
||||||
call.Otto.Set("ret_jsonrpc", shared.JsonRpcVersion)
|
call.Otto.Set("ret_jsonrpc", shared.JsonRpcVersion)
|
||||||
call.Otto.Set("ret_id", req.Id)
|
call.Otto.Set("ret_id", req.Id)
|
||||||
|
|
||||||
res, _ := json.Marshal(respif)
|
var res []byte
|
||||||
|
if isSuccessResponse {
|
||||||
|
res, err = json.Marshal(sucres.Result)
|
||||||
|
} else if isErrorResponse {
|
||||||
|
res, err = json.Marshal(errres.Error)
|
||||||
|
}
|
||||||
|
|
||||||
call.Otto.Set("ret_result", string(res))
|
call.Otto.Set("ret_result", string(res))
|
||||||
call.Otto.Set("response_idx", i)
|
call.Otto.Set("response_idx", i)
|
||||||
|
|
@ -105,3 +139,48 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleRequest will handle user agent requests by interacting with the user and sending
|
||||||
|
// the user response back to the geth service
|
||||||
|
func (self *Jeth) handleRequest(req *shared.Request) bool {
|
||||||
|
var err error
|
||||||
|
var args []interface{}
|
||||||
|
if err = json.Unmarshal(req.Params, &args); err != nil {
|
||||||
|
glog.V(logger.Info).Infof("Unable to parse agent request - %v\n", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch req.Method {
|
||||||
|
case useragent.AskPasswordMethod:
|
||||||
|
return self.askPassword(req.Id, req.Jsonrpc, args)
|
||||||
|
case useragent.ConfirmTransactionMethod:
|
||||||
|
return self.confirmTransaction(req.Id, req.Jsonrpc, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// askPassword will ask the user to supply the password for a given account
|
||||||
|
func (self *Jeth) askPassword(id interface{}, jsonrpc string, args []interface{}) bool {
|
||||||
|
var err error
|
||||||
|
var passwd string
|
||||||
|
if len(args) >= 1 {
|
||||||
|
if account, ok := args[0].(string); ok {
|
||||||
|
fmt.Printf("Unlock account %s\n", account)
|
||||||
|
passwd, err = utils.PromptPassword("Passphrase: ", true)
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = self.client.Send(shared.NewRpcResponse(id, jsonrpc, passwd, err)); err != nil {
|
||||||
|
glog.V(logger.Info).Infof("Unable to send user agent ask password response - %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Jeth) confirmTransaction(id interface{}, jsonrpc string, args []interface{}) bool {
|
||||||
|
// Accept all tx which are send from this console
|
||||||
|
return self.client.Send(shared.NewRpcResponse(id, jsonrpc, true, nil)) == nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,11 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// +build !linux,!darwin
|
// package user agent provides frontends and agents which can interact with the user
|
||||||
|
package useragent
|
||||||
|
|
||||||
package fdtrack
|
var (
|
||||||
|
AskPasswordMethod = "agent_askPassword"
|
||||||
import "errors"
|
ConfirmTransactionMethod = "agent_confirmTransaction"
|
||||||
|
EnableUserAgentMethod = "admin_enableUserAgent"
|
||||||
func fdlimit() int {
|
)
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func fdusage() (int, error) {
|
|
||||||
return 0, errors.New("not implemented")
|
|
||||||
}
|
|
||||||
141
rpc/useragent/remote_frontend.go
Normal file
141
rpc/useragent/remote_frontend.go
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
// Copyright 2015 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package useragent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
|
)
|
||||||
|
|
||||||
|
// remoteFrontend implements xeth.Frontend and will communicate with an external
|
||||||
|
// user agent over a connection
|
||||||
|
type RemoteFrontend struct {
|
||||||
|
enabled bool
|
||||||
|
mgr *accounts.Manager
|
||||||
|
d *json.Decoder
|
||||||
|
e *json.Encoder
|
||||||
|
n int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRemoteFrontend creates a new frontend which will interact with an user agent
|
||||||
|
// over the given connection
|
||||||
|
func NewRemoteFrontend(conn net.Conn, mgr *accounts.Manager) *RemoteFrontend {
|
||||||
|
return &RemoteFrontend{false, mgr, json.NewDecoder(conn), json.NewEncoder(conn), 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable will enable user interaction
|
||||||
|
func (fe *RemoteFrontend) Enable() {
|
||||||
|
fe.enabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnlockAccount asks the user agent for the user password and tries to unlock the account.
|
||||||
|
// It will try 3 attempts before giving up.
|
||||||
|
func (fe *RemoteFrontend) UnlockAccount(address []byte) bool {
|
||||||
|
if !fe.enabled {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
err := fe.send(AskPasswordMethod, common.Bytes2Hex(address))
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Unable to send password request to agent - %v\n", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
passwdRes, err := fe.recv()
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Unable to recv password response from agent - %v\n", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if passwd, ok := passwdRes.Result.(string); ok {
|
||||||
|
err = fe.mgr.Unlock(common.BytesToAddress(address), passwd)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
glog.V(logger.Debug).Infoln("3 invalid account unlock attempts")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfirmTransaction asks the user for approval
|
||||||
|
func (fe *RemoteFrontend) ConfirmTransaction(tx string) bool {
|
||||||
|
if !fe.enabled {
|
||||||
|
return true // backwards compatibility
|
||||||
|
}
|
||||||
|
|
||||||
|
err := fe.send(ConfirmTransactionMethod, tx)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Unable to send tx confirmation request to agent - %v\n", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmResponse, err := fe.recv()
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Error).Infof("Unable to recv tx confirmation response from agent - %v\n", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if confirmed, ok := confirmResponse.Result.(bool); ok {
|
||||||
|
return confirmed
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// send request to the agent
|
||||||
|
func (fe *RemoteFrontend) send(method string, params ...interface{}) error {
|
||||||
|
fe.n += 1
|
||||||
|
|
||||||
|
p, err := json.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Info).Infof("Unable to send agent request %v\n", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req := shared.Request{
|
||||||
|
Method: method,
|
||||||
|
Jsonrpc: shared.JsonRpcVersion,
|
||||||
|
Id: fe.n,
|
||||||
|
Params: p,
|
||||||
|
}
|
||||||
|
|
||||||
|
return fe.e.Encode(&req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// recv user response from agent
|
||||||
|
func (fe *RemoteFrontend) recv() (*shared.SuccessResponse, error) {
|
||||||
|
var res json.RawMessage
|
||||||
|
if err := fe.d.Decode(&res); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var response shared.SuccessResponse
|
||||||
|
if err := json.Unmarshal(res, &response); err == nil {
|
||||||
|
return &response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("Invalid user agent response")
|
||||||
|
}
|
||||||
18
rpc/xeth.go
18
rpc/xeth.go
|
|
@ -53,7 +53,7 @@ func (self *Xeth) Call(method string, params []interface{}) (map[string]interfac
|
||||||
Method: method,
|
Method: method,
|
||||||
Params: data,
|
Params: data,
|
||||||
}
|
}
|
||||||
// Send the request over and process the response
|
// Send the request over and retrieve the response
|
||||||
if err := self.client.Send(req); err != nil {
|
if err := self.client.Send(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -61,9 +61,17 @@ func (self *Xeth) Call(method string, params []interface{}) (map[string]interfac
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
value, ok := res.(map[string]interface{})
|
// Ensure the response is valid, and extract the results
|
||||||
if !ok {
|
success, isSuccessResponse := res.(*shared.SuccessResponse)
|
||||||
return nil, fmt.Errorf("Invalid response type: have %v, want %v", reflect.TypeOf(res), reflect.TypeOf(make(map[string]interface{})))
|
failure, isFailureResponse := res.(*shared.ErrorResponse)
|
||||||
|
switch {
|
||||||
|
case isFailureResponse:
|
||||||
|
return nil, fmt.Errorf("Method invocation failed: %v", failure.Error)
|
||||||
|
|
||||||
|
case isSuccessResponse:
|
||||||
|
return success.Result.(map[string]interface{}), nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Invalid response type: %v", reflect.TypeOf(res))
|
||||||
}
|
}
|
||||||
return value, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ func runBlockTests(bt map[string]*BlockTest, skipTests []string) error {
|
||||||
|
|
||||||
// test the block
|
// test the block
|
||||||
if err := runBlockTest(test); err != nil {
|
if err := runBlockTest(test); err != nil {
|
||||||
return err
|
return fmt.Errorf("%s: %v", name, err)
|
||||||
}
|
}
|
||||||
glog.Infoln("Block test passed: ", name)
|
glog.Infoln("Block test passed: ", name)
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -27,14 +27,13 @@ import (
|
||||||
func init() {
|
func init() {
|
||||||
if os.Getenv("JITVM") == "true" {
|
if os.Getenv("JITVM") == "true" {
|
||||||
vm.ForceJit = true
|
vm.ForceJit = true
|
||||||
} else {
|
vm.EnableJit = true
|
||||||
vm.DisableJit = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkStateCall1024(b *testing.B) {
|
func BenchmarkStateCall1024(b *testing.B) {
|
||||||
fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json")
|
fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json")
|
||||||
if err := BenchVmTest(fn, bconf{"Call1024BalanceTooLow", true, false}, b); err != nil {
|
if err := BenchVmTest(fn, bconf{"Call1024BalanceTooLow", true, os.Getenv("JITVM") == "true"}, b); err != nil {
|
||||||
b.Error(err)
|
b.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,8 @@ func BenchStateTest(p string, conf bconf, b *testing.B) error {
|
||||||
return fmt.Errorf("test not found: %s", conf.name)
|
return fmt.Errorf("test not found: %s", conf.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pNoJit := vm.DisableJit
|
pJit := vm.EnableJit
|
||||||
vm.DisableJit = conf.nojit
|
vm.EnableJit = conf.jit
|
||||||
pForceJit := vm.ForceJit
|
pForceJit := vm.ForceJit
|
||||||
vm.ForceJit = conf.precomp
|
vm.ForceJit = conf.precomp
|
||||||
|
|
||||||
|
|
@ -94,7 +94,7 @@ func BenchStateTest(p string, conf bconf, b *testing.B) error {
|
||||||
benchStateTest(test, env, b)
|
benchStateTest(test, env, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
vm.DisableJit = pNoJit
|
vm.EnableJit = pJit
|
||||||
vm.ForceJit = pForceJit
|
vm.ForceJit = pForceJit
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -17,20 +17,21 @@
|
||||||
package tests
|
package tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkVmAckermann32Tests(b *testing.B) {
|
func BenchmarkVmAckermann32Tests(b *testing.B) {
|
||||||
fn := filepath.Join(vmTestDir, "vmPerformanceTest.json")
|
fn := filepath.Join(vmTestDir, "vmPerformanceTest.json")
|
||||||
if err := BenchVmTest(fn, bconf{"ackermann32", true, false}, b); err != nil {
|
if err := BenchVmTest(fn, bconf{"ackermann32", true, os.Getenv("JITVM") == "true"}, b); err != nil {
|
||||||
b.Error(err)
|
b.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkVmFibonacci16Tests(b *testing.B) {
|
func BenchmarkVmFibonacci16Tests(b *testing.B) {
|
||||||
fn := filepath.Join(vmTestDir, "vmPerformanceTest.json")
|
fn := filepath.Join(vmTestDir, "vmPerformanceTest.json")
|
||||||
if err := BenchVmTest(fn, bconf{"fibonacci16", true, false}, b); err != nil {
|
if err := BenchVmTest(fn, bconf{"fibonacci16", true, os.Getenv("JITVM") == "true"}, b); err != nil {
|
||||||
b.Error(err)
|
b.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func RunVmTestWithReader(r io.Reader, skipTests []string) error {
|
||||||
type bconf struct {
|
type bconf struct {
|
||||||
name string
|
name string
|
||||||
precomp bool
|
precomp bool
|
||||||
nojit bool
|
jit bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchVmTest(p string, conf bconf, b *testing.B) error {
|
func BenchVmTest(p string, conf bconf, b *testing.B) error {
|
||||||
|
|
@ -67,8 +67,8 @@ func BenchVmTest(p string, conf bconf, b *testing.B) error {
|
||||||
return fmt.Errorf("test not found: %s", conf.name)
|
return fmt.Errorf("test not found: %s", conf.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pNoJit := vm.DisableJit
|
pJit := vm.EnableJit
|
||||||
vm.DisableJit = conf.nojit
|
vm.EnableJit = conf.jit
|
||||||
pForceJit := vm.ForceJit
|
pForceJit := vm.ForceJit
|
||||||
vm.ForceJit = conf.precomp
|
vm.ForceJit = conf.precomp
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ func BenchVmTest(p string, conf bconf, b *testing.B) error {
|
||||||
benchVmTest(test, env, b)
|
benchVmTest(test, env, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
vm.DisableJit = pNoJit
|
vm.EnableJit = pJit
|
||||||
vm.ForceJit = pForceJit
|
vm.ForceJit = pForceJit
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
26
xeth/xeth.go
26
xeth/xeth.go
|
|
@ -89,8 +89,7 @@ type XEth struct {
|
||||||
messagesMu sync.RWMutex
|
messagesMu sync.RWMutex
|
||||||
messages map[int]*whisperFilter
|
messages map[int]*whisperFilter
|
||||||
|
|
||||||
// regmut sync.Mutex
|
transactMu sync.Mutex
|
||||||
// register map[string][]*interface{} // TODO improve return type
|
|
||||||
|
|
||||||
agent *miner.RemoteAgent
|
agent *miner.RemoteAgent
|
||||||
|
|
||||||
|
|
@ -823,18 +822,22 @@ func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr st
|
||||||
}
|
}
|
||||||
|
|
||||||
from.SetBalance(common.MaxBig)
|
from.SetBalance(common.MaxBig)
|
||||||
from.SetGasLimit(self.backend.ChainManager().GasLimit())
|
from.SetGasLimit(common.MaxBig)
|
||||||
|
|
||||||
msg := callmsg{
|
msg := callmsg{
|
||||||
from: from,
|
from: from,
|
||||||
to: common.HexToAddress(toStr),
|
|
||||||
gas: common.Big(gasStr),
|
gas: common.Big(gasStr),
|
||||||
gasPrice: common.Big(gasPriceStr),
|
gasPrice: common.Big(gasPriceStr),
|
||||||
value: common.Big(valueStr),
|
value: common.Big(valueStr),
|
||||||
data: common.FromHex(dataStr),
|
data: common.FromHex(dataStr),
|
||||||
}
|
}
|
||||||
|
if len(toStr) > 0 {
|
||||||
|
addr := common.HexToAddress(toStr)
|
||||||
|
msg.to = &addr
|
||||||
|
}
|
||||||
|
|
||||||
if msg.gas.Cmp(big.NewInt(0)) == 0 {
|
if msg.gas.Cmp(big.NewInt(0)) == 0 {
|
||||||
msg.gas = DefaultGas()
|
msg.gas = big.NewInt(50000000)
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.gasPrice.Cmp(big.NewInt(0)) == 0 {
|
if msg.gasPrice.Cmp(big.NewInt(0)) == 0 {
|
||||||
|
|
@ -885,6 +888,10 @@ func isAddress(addr string) bool {
|
||||||
return addrReg.MatchString(addr)
|
return addrReg.MatchString(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *XEth) Frontend() Frontend {
|
||||||
|
return self.frontend
|
||||||
|
}
|
||||||
|
|
||||||
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
|
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
|
||||||
|
|
||||||
// this minimalistic recoding is enough (works for natspec.js)
|
// this minimalistic recoding is enough (works for natspec.js)
|
||||||
|
|
@ -948,8 +955,9 @@ func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceS
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: align default values to have the same type, e.g. not depend on
|
self.transactMu.Lock()
|
||||||
// common.Value conversions later on
|
defer self.transactMu.Unlock()
|
||||||
|
|
||||||
var nonce uint64
|
var nonce uint64
|
||||||
if len(nonceStr) != 0 {
|
if len(nonceStr) != 0 {
|
||||||
nonce = common.Big(nonceStr).Uint64()
|
nonce = common.Big(nonceStr).Uint64()
|
||||||
|
|
@ -994,7 +1002,7 @@ func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock boo
|
||||||
// callmsg is the message type used for call transations.
|
// callmsg is the message type used for call transations.
|
||||||
type callmsg struct {
|
type callmsg struct {
|
||||||
from *state.StateObject
|
from *state.StateObject
|
||||||
to common.Address
|
to *common.Address
|
||||||
gas, gasPrice *big.Int
|
gas, gasPrice *big.Int
|
||||||
value *big.Int
|
value *big.Int
|
||||||
data []byte
|
data []byte
|
||||||
|
|
@ -1003,7 +1011,7 @@ type callmsg struct {
|
||||||
// accessor boilerplate to implement core.Message
|
// accessor boilerplate to implement core.Message
|
||||||
func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil }
|
func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil }
|
||||||
func (m callmsg) Nonce() uint64 { return m.from.Nonce() }
|
func (m callmsg) Nonce() uint64 { return m.from.Nonce() }
|
||||||
func (m callmsg) To() *common.Address { return &m.to }
|
func (m callmsg) To() *common.Address { return m.to }
|
||||||
func (m callmsg) GasPrice() *big.Int { return m.gasPrice }
|
func (m callmsg) GasPrice() *big.Int { return m.gasPrice }
|
||||||
func (m callmsg) Gas() *big.Int { return m.gas }
|
func (m callmsg) Gas() *big.Int { return m.gas }
|
||||||
func (m callmsg) Value() *big.Int { return m.value }
|
func (m callmsg) Value() *big.Int { return m.value }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue