Merge branch 'develop' into ui
This commit is contained in:
		
						commit
						5f25c117eb
					
				| @ -1,8 +1,8 @@ | ||||
| language: go | ||||
| go: | ||||
|   - 1.4.1 | ||||
|   - 1.4.2 | ||||
| before_install: | ||||
|   - sudo add-apt-repository ppa:beineri/opt-qt54 -y | ||||
|   - sudo add-apt-repository ppa:beineri/opt-qt541 -y | ||||
|   - sudo apt-get update -qq | ||||
|   - sudo apt-get install -yqq libgmp3-dev libreadline6-dev qt54quickcontrols qt54webengine | ||||
| install: | ||||
|  | ||||
							
								
								
									
										12
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								Dockerfile
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | ||||
| FROM ubuntu:14.04.1 | ||||
| FROM ubuntu:14.04.2 | ||||
| 
 | ||||
| ## Environment setup | ||||
| ENV HOME /root | ||||
| @ -12,22 +12,22 @@ ENV DEBIAN_FRONTEND noninteractive | ||||
| RUN apt-get update && apt-get upgrade -y | ||||
| RUN apt-get install -y git mercurial build-essential software-properties-common wget pkg-config libgmp3-dev libreadline6-dev libpcre3-dev libpcre++-dev | ||||
| 
 | ||||
| ## Install Qt5.4 (not required for CLI) | ||||
| # RUN add-apt-repository ppa:beineri/opt-qt54-trusty -y | ||||
| ## Install Qt5.4.1 (not required for CLI) | ||||
| # RUN add-apt-repository ppa:beineri/opt-qt541-trusty -y | ||||
| # RUN apt-get update -y | ||||
| # RUN apt-get install -y qt54quickcontrols qt54webengine mesa-common-dev libglu1-mesa-dev | ||||
| # ENV PKG_CONFIG_PATH /opt/qt54/lib/pkgconfig | ||||
| 
 | ||||
| # Install Golang | ||||
| RUN wget https://storage.googleapis.com/golang/go1.4.1.linux-amd64.tar.gz | ||||
| RUN wget https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz | ||||
| RUN tar -C /usr/local -xzf go*.tar.gz && go version | ||||
| 
 | ||||
| # this is a workaround, to make sure that docker's cache is invalidated whenever the git repo changes | ||||
| ADD https://api.github.com/repos/ethereum/go-ethereum/git/refs/heads/develop file_does_not_exist | ||||
| 
 | ||||
| ## Fetch and install go-ethereum | ||||
| RUN go get -v github.com/tools/godep | ||||
| RUN go get -v -d github.com/ethereum/go-ethereum/... | ||||
| RUN go get github.com/tools/godep | ||||
| RUN go get -d github.com/ethereum/go-ethereum/... | ||||
| WORKDIR $GOPATH/src/github.com/ethereum/go-ethereum | ||||
| RUN git checkout develop | ||||
| RUN godep restore | ||||
|  | ||||
							
								
								
									
										11
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							| @ -1,15 +1,10 @@ | ||||
| { | ||||
| 	"ImportPath": "github.com/ethereum/go-ethereum", | ||||
| 	"GoVersion": "go1.4.1", | ||||
| 	"GoVersion": "go1.4.2", | ||||
| 	"Packages": [ | ||||
| 		"./..." | ||||
| 	], | ||||
| 	"Deps": [ | ||||
| 		{ | ||||
| 			"ImportPath": "bitbucket.org/kardianos/osext", | ||||
| 			"Comment": "null-13", | ||||
| 			"Rev": "5d3ddcf53a508cc2f7404eaebf546ef2cb5cdb6e" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "code.google.com/p/go-uuid/uuid", | ||||
| 			"Comment": "null-12", | ||||
| @ -37,6 +32,10 @@ | ||||
| 			"ImportPath": "github.com/jackpal/go-nat-pmp", | ||||
| 			"Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "github.com/kardianos/osext", | ||||
| 			"Rev": "ccfcd0245381f0c94c68f50626665eed3c6b726a" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "github.com/obscuren/otto", | ||||
| 			"Rev": "cf13cc4228c5e5ce0fe27a7aea90bc10091c4f19" | ||||
|  | ||||
							
								
								
									
										20
									
								
								Godeps/_workspace/src/bitbucket.org/kardianos/osext/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								Godeps/_workspace/src/bitbucket.org/kardianos/osext/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,20 +0,0 @@ | ||||
| Copyright (c) 2012 Daniel Theophanes | ||||
| 
 | ||||
| This software is provided 'as-is', without any express or implied | ||||
| warranty. In no event will the authors be held liable for any damages | ||||
| arising from the use of this software. | ||||
| 
 | ||||
| Permission is granted to anyone to use this software for any purpose, | ||||
| including commercial applications, and to alter it and redistribute it | ||||
| freely, subject to the following restrictions: | ||||
| 
 | ||||
|    1. The origin of this software must not be misrepresented; you must not | ||||
|    claim that you wrote the original software. If you use this software | ||||
|    in a product, an acknowledgment in the product documentation would be | ||||
|    appreciated but is not required. | ||||
| 
 | ||||
|    2. Altered source versions must be plainly marked as such, and must not be | ||||
|    misrepresented as being the original software. | ||||
| 
 | ||||
|    3. This notice may not be removed or altered from any source | ||||
|    distribution. | ||||
							
								
								
									
										27
									
								
								Godeps/_workspace/src/github.com/kardianos/osext/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								Godeps/_workspace/src/github.com/kardianos/osext/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| Copyright (c) 2012 The Go Authors. All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
| 
 | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										14
									
								
								Godeps/_workspace/src/github.com/kardianos/osext/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Godeps/_workspace/src/github.com/kardianos/osext/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| ### Extensions to the "os" package. | ||||
| 
 | ||||
| ## Find the current Executable and ExecutableFolder. | ||||
| 
 | ||||
| There is sometimes utility in finding the current executable file | ||||
| that is running. This can be used for upgrading the current executable | ||||
| or finding resources located relative to the executable file. | ||||
| 
 | ||||
| Multi-platform and supports: | ||||
|  * Linux | ||||
|  * OS X | ||||
|  * Windows | ||||
|  * Plan 9 | ||||
|  * BSDs. | ||||
| @ -25,8 +25,3 @@ func ExecutableFolder() (string, error) { | ||||
| 	folder, _ := filepath.Split(p) | ||||
| 	return folder, nil | ||||
| } | ||||
| 
 | ||||
| // Depricated. Same as Executable().
 | ||||
| func GetExePath() (exePath string, err error) { | ||||
| 	return Executable() | ||||
| } | ||||
| @ -5,16 +5,16 @@ | ||||
| package osext | ||||
| 
 | ||||
| import ( | ||||
|     "syscall" | ||||
|     "os" | ||||
|     "strconv" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"syscall" | ||||
| ) | ||||
| 
 | ||||
| func executable() (string, error) { | ||||
|     f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text") | ||||
|     if err != nil { | ||||
|         return "", err | ||||
|     } | ||||
|     defer f.Close() | ||||
|     return syscall.Fd2path(int(f.Fd())) | ||||
| 	f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text") | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| 	return syscall.Fd2path(int(f.Fd())) | ||||
| } | ||||
| @ -2,12 +2,13 @@ | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| // +build linux netbsd openbsd
 | ||||
| // +build linux netbsd openbsd solaris dragonfly
 | ||||
| 
 | ||||
| package osext | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"runtime" | ||||
| ) | ||||
| @ -18,8 +19,10 @@ func executable() (string, error) { | ||||
| 		return os.Readlink("/proc/self/exe") | ||||
| 	case "netbsd": | ||||
| 		return os.Readlink("/proc/curproc/exe") | ||||
| 	case "openbsd": | ||||
| 	case "openbsd", "dragonfly": | ||||
| 		return os.Readlink("/proc/curproc/file") | ||||
| 	case "solaris": | ||||
| 		return os.Readlink(fmt.Sprintf("/proc/%d/path/a.out", os.Getpid())) | ||||
| 	} | ||||
| 	return "", errors.New("ExecPath not implemented for " + runtime.GOOS) | ||||
| } | ||||
							
								
								
									
										112
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								README.md
									
									
									
									
									
								
							| @ -24,7 +24,25 @@ Ethereum (CLI): | ||||
| 
 | ||||
| `go get github.com/ethereum/go-ethereum/cmd/ethereum` | ||||
| 
 | ||||
| For further, detailed, build instruction please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)) | ||||
| As of POC-8, go-ethereum uses [Godep](https://github.com/tools/godep) to manage dependencies. Assuming you have [your environment all set up](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)), switch to the go-ethereum repository root folder, and build/install the executable you need: | ||||
| 
 | ||||
| Mist (GUI): | ||||
| 
 | ||||
| ``` | ||||
| godep go build -v ./cmd/mist | ||||
| ``` | ||||
| 
 | ||||
| Ethereum (CLI): | ||||
| 
 | ||||
| ``` | ||||
| godep go build -v ./cmd/ethereum | ||||
| ``` | ||||
| 
 | ||||
| Instead of `build`, you can use `install` which will also install the resulting binary. | ||||
| 
 | ||||
| For prerequisites and detailed build instructions please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)) | ||||
| 
 | ||||
| If you intend to develop on go-ethereum, check the [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide) | ||||
| 
 | ||||
| Automated (dev) builds | ||||
| ====================== | ||||
| @ -34,97 +52,47 @@ Automated (dev) builds | ||||
| * [Windows] Coming soon™ | ||||
| * [Linux] Coming soon™ | ||||
| 
 | ||||
| Binaries | ||||
| ======== | ||||
| Executables | ||||
| =========== | ||||
| 
 | ||||
| Go Ethereum comes with several binaries found in | ||||
| [cmd](https://github.com/ethereum/go-ethereum/tree/master/cmd): | ||||
| Go Ethereum comes with several wrappers/executables found in  | ||||
| [the `cmd` directory](https://github.com/ethereum/go-ethereum/tree/develop/cmd): | ||||
| 
 | ||||
| * `mist` Official Ethereum Browser | ||||
| * `ethereum` Ethereum CLI | ||||
| * `ethtest` test tool which runs with the [tests](https://github.com/ethereum/testes) suit:  | ||||
| * `mist` Official Ethereum Browser (ethereum GUI client) | ||||
| * `ethereum` Ethereum CLI (ethereum command line interface client) | ||||
| * `bootnode` runs a bootstrap node for the Discovery Protocol | ||||
| * `ethtest` test tool which runs with the [tests](https://github.com/ethereum/testes) suite:  | ||||
|   `cat file | ethtest`. | ||||
| * `evm` is a generic Ethereum Virtual Machine: `evm -code 60ff60ff -gas | ||||
|   10000 -price 0 -dump`. See `-h` for a detailed description. | ||||
| * `rlpdump` converts a rlp stream to `interface{}`. | ||||
| * `peerserver` simple P2P (noi-ethereum) peer server. | ||||
| * `disasm` disassembles EVM code: `echo "6001" | disasm` | ||||
| * `rlpdump` converts a rlp stream to `interface{}`. | ||||
| 
 | ||||
| General command line options | ||||
| Command line options | ||||
| ============================ | ||||
| 
 | ||||
| Both `mist` and `ethereum` can be configured via command line options, environment variables and config files. | ||||
| 
 | ||||
| To get the options available: | ||||
| 
 | ||||
| ``` | ||||
| == Shared between ethereum and Mist == | ||||
| 
 | ||||
| = Settings | ||||
| -id      Set the custom identifier of the client (shows up on other clients) | ||||
| -port    Port on which the server will accept incomming connections | ||||
| -upnp    Enable UPnP | ||||
| -maxpeer Desired amount of peers | ||||
| -rpc     Start JSON RPC | ||||
| -dir     Data directory used to store configs and databases | ||||
| 
 | ||||
| = Utility  | ||||
| -h         This | ||||
| -import    Import a private key | ||||
| -genaddr   Generates a new address and private key (destructive action) | ||||
| -dump      Dump a specific state of a block to stdout given the -number or -hash | ||||
| -difftool  Supress all output and prints VM output to stdout | ||||
| -diff      vm=only vm output, all=all output including state storage | ||||
| 
 | ||||
| Ethereum only | ||||
| ethereum [options] [filename] | ||||
| -js        Start the JavaScript REPL | ||||
| filename   Load the given file and interpret as JavaScript | ||||
| -m       Start mining blocks | ||||
| 
 | ||||
| == Mist only == | ||||
| 
 | ||||
| -asset_path    absolute path to GUI assets directory | ||||
| ethereum -help | ||||
| ``` | ||||
| 
 | ||||
| For further details on options, see the [wiki](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) | ||||
| 
 | ||||
| Contribution | ||||
| ============ | ||||
| 
 | ||||
| If you'd like to contribute to 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 | ||||
| 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. | ||||
| 
 | ||||
| For dependency management, we use [godep](https://github.com/tools/godep). After installing with `go get github.com/tools/godep`, run `godep restore` to ensure that changes to other repositories do not break the build. To update a dependency version (for example, to include a new upstream fix), run `go get -u <foo/bar>` then `godep update <foo/...>`. To track a new dependency, add it to the project as normal than run `godep save ./...`. Changes to the Godeps folder should be manually verified then commited. | ||||
| For dependency management, we use [godep](https://github.com/tools/godep). After installing with `go get github.com/tools/godep`, run `godep restore` to ensure that changes to other repositories do not break the build. To update a dependency version (for example, to include a new upstream fix), run `go get -u <foo/bar>` then `godep update <foo/...>`. To track a new dependency, add it to the project as normal than run `godep save ./...`. Changes to the [Godeps folder](https://github.com/ethereum/go-ethereum/tree/develop/Godeps): should be manually verified then commited. | ||||
| 
 | ||||
| To make life easier try [git flow](http://nvie.com/posts/a-successful-git-branching-model/) it sets | ||||
| this all up and streamlines your work flow. | ||||
| 
 | ||||
| Coding standards | ||||
| ================ | ||||
| 
 | ||||
| Sources should be formatted according to the [Go Formatting | ||||
| Style](http://golang.org/doc/effective_go.html#formatting). | ||||
| 
 | ||||
| Unless structs fields are supposed to be directly accesible, provide | ||||
| Getters and hide the fields through Go's exporting facility. | ||||
| 
 | ||||
| When you comment put meaningful comments. Describe in detail what you | ||||
| want to achieve. | ||||
| 
 | ||||
| *wrong* | ||||
| 
 | ||||
| ```go | ||||
| // Check if the value at x is greater than y | ||||
| if x > y { | ||||
|     // It's greater! | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| Everyone reading the source probably know what you wanted to achieve | ||||
| with above code. Those are **not** meaningful comments. | ||||
| 
 | ||||
| While the project isn't 100% tested I want you to write tests non the | ||||
| less. I haven't got time to evaluate everyone's code in detail so I | ||||
| expect you to write tests for me so I don't have to test your code | ||||
| manually. (If you want to contribute by just writing tests that's fine | ||||
| too!) | ||||
| To make life easier try [git flow](http://nvie.com/posts/a-successful-git-branching-model/) it sets this all up and streamlines your work flow. | ||||
| 
 | ||||
| See [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide) | ||||
| 
 | ||||
|  | ||||
| @ -34,33 +34,62 @@ package accounts | ||||
| 
 | ||||
| import ( | ||||
| 	crand "crypto/rand" | ||||
| 
 | ||||
| 	"errors" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| ) | ||||
| 
 | ||||
| var ErrLocked = errors.New("account is locked; please request passphrase") | ||||
| 
 | ||||
| // TODO: better name for this struct?
 | ||||
| type Account struct { | ||||
| 	Address []byte | ||||
| } | ||||
| 
 | ||||
| type AccountManager struct { | ||||
| 	keyStore crypto.KeyStore2 | ||||
| 	keyStore           crypto.KeyStore2 | ||||
| 	unlockedKeys       map[string]crypto.Key | ||||
| 	unlockMilliseconds time.Duration | ||||
| 	mutex              sync.RWMutex | ||||
| } | ||||
| 
 | ||||
| // TODO: get key by addr - modify KeyStore2 GetKey to work with addr
 | ||||
| 
 | ||||
| // TODO: pass through passphrase for APIs which require access to private key?
 | ||||
| func NewAccountManager(keyStore crypto.KeyStore2) AccountManager { | ||||
| func NewAccountManager(keyStore crypto.KeyStore2, unlockMilliseconds time.Duration) AccountManager { | ||||
| 	keysMap := make(map[string]crypto.Key) | ||||
| 	am := &AccountManager{ | ||||
| 		keyStore: keyStore, | ||||
| 		keyStore:           keyStore, | ||||
| 		unlockedKeys:       keysMap, | ||||
| 		unlockMilliseconds: unlockMilliseconds, | ||||
| 	} | ||||
| 	return *am | ||||
| } | ||||
| 
 | ||||
| func (am *AccountManager) Sign(fromAccount *Account, keyAuth string, toSign []byte) (signature []byte, err error) { | ||||
| func (am AccountManager) DeleteAccount(address []byte, auth string) error { | ||||
| 	return am.keyStore.DeleteKey(address, auth) | ||||
| } | ||||
| 
 | ||||
| func (am *AccountManager) Sign(fromAccount *Account, toSign []byte) (signature []byte, err error) { | ||||
| 	am.mutex.RLock() | ||||
| 	unlockedKey := am.unlockedKeys[string(fromAccount.Address)] | ||||
| 	am.mutex.RUnlock() | ||||
| 	if unlockedKey.Address == nil { | ||||
| 		return nil, ErrLocked | ||||
| 	} | ||||
| 	signature, err = crypto.Sign(toSign, unlockedKey.PrivateKey) | ||||
| 	return signature, err | ||||
| } | ||||
| 
 | ||||
| func (am *AccountManager) SignLocked(fromAccount *Account, keyAuth string, toSign []byte) (signature []byte, err error) { | ||||
| 	key, err := am.keyStore.GetKey(fromAccount.Address, keyAuth) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	am.mutex.RLock() | ||||
| 	am.unlockedKeys[string(fromAccount.Address)] = *key | ||||
| 	am.mutex.RUnlock() | ||||
| 	go unlockLater(am, fromAccount.Address) | ||||
| 	signature, err = crypto.Sign(toSign, key.PrivateKey) | ||||
| 	return signature, err | ||||
| } | ||||
| @ -76,8 +105,6 @@ func (am AccountManager) NewAccount(auth string) (*Account, error) { | ||||
| 	return ua, err | ||||
| } | ||||
| 
 | ||||
| // set of accounts == set of keys in given key store
 | ||||
| // TODO: do we need persistence of accounts as well?
 | ||||
| func (am *AccountManager) Accounts() ([]Account, error) { | ||||
| 	addresses, err := am.keyStore.GetKeyAddresses() | ||||
| 	if err != nil { | ||||
| @ -93,3 +120,13 @@ func (am *AccountManager) Accounts() ([]Account, error) { | ||||
| 	} | ||||
| 	return accounts, err | ||||
| } | ||||
| 
 | ||||
| func unlockLater(am *AccountManager, addr []byte) { | ||||
| 	select { | ||||
| 	case <-time.After(time.Millisecond * am.unlockMilliseconds): | ||||
| 	} | ||||
| 	am.mutex.RLock() | ||||
| 	// TODO: how do we know the key is actually gone from memory?
 | ||||
| 	delete(am.unlockedKeys, string(addr)) | ||||
| 	am.mutex.RUnlock() | ||||
| } | ||||
|  | ||||
| @ -5,16 +5,78 @@ import ( | ||||
| 
 | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/crypto/randentropy" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| func TestAccountManager(t *testing.T) { | ||||
| 	ks := crypto.NewKeyStorePlain(crypto.DefaultDataDir()) | ||||
| 	am := NewAccountManager(ks) | ||||
| 	ks := crypto.NewKeyStorePlain(ethutil.DefaultDataDir() + "/testaccounts") | ||||
| 	am := NewAccountManager(ks, 100) | ||||
| 	pass := "" // not used but required by API
 | ||||
| 	a1, err := am.NewAccount(pass) | ||||
| 	toSign := randentropy.GetEntropyCSPRNG(32) | ||||
| 	_, err = am.Sign(a1, pass, toSign) | ||||
| 	_, err = am.SignLocked(a1, pass, toSign) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Cleanup
 | ||||
| 	time.Sleep(time.Millisecond * 150) // wait for locking
 | ||||
| 
 | ||||
| 	accounts, err := am.Accounts() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	for _, account := range accounts { | ||||
| 		err := am.DeleteAccount(account.Address, pass) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestAccountManagerLocking(t *testing.T) { | ||||
| 	ks := crypto.NewKeyStorePassphrase(ethutil.DefaultDataDir() + "/testaccounts") | ||||
| 	am := NewAccountManager(ks, 200) | ||||
| 	pass := "foo" | ||||
| 	a1, err := am.NewAccount(pass) | ||||
| 	toSign := randentropy.GetEntropyCSPRNG(32) | ||||
| 
 | ||||
| 	// Signing without passphrase fails because account is locked
 | ||||
| 	_, err = am.Sign(a1, toSign) | ||||
| 	if err != ErrLocked { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Signing with passphrase works
 | ||||
| 	_, err = am.SignLocked(a1, pass, toSign) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Signing without passphrase works because account is temp unlocked
 | ||||
| 	_, err = am.Sign(a1, toSign) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Signing without passphrase fails after automatic locking
 | ||||
| 	time.Sleep(time.Millisecond * time.Duration(250)) | ||||
| 
 | ||||
| 	_, err = am.Sign(a1, toSign) | ||||
| 	if err != ErrLocked { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Cleanup
 | ||||
| 	accounts, err := am.Accounts() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	for _, account := range accounts { | ||||
| 		err := am.DeleteAccount(account.Address, pass) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -26,50 +26,52 @@ import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path" | ||||
| 	"runtime" | ||||
| 
 | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/p2p/nat" | ||||
| 	"github.com/ethereum/go-ethereum/vm" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	Identifier      string | ||||
| 	KeyRing         string | ||||
| 	DiffTool        bool | ||||
| 	DiffType        string | ||||
| 	KeyStore        string | ||||
| 	StartRpc        bool | ||||
| 	StartWebSockets bool | ||||
| 	RpcPort         int | ||||
| 	WsPort          int | ||||
| 	OutboundPort    string | ||||
| 	ShowGenesis     bool | ||||
| 	AddPeer         string | ||||
| 	MaxPeer         int | ||||
| 	GenAddr         bool | ||||
| 	BootNodes       string | ||||
| 	NodeKey         *ecdsa.PrivateKey | ||||
| 	NAT             nat.Interface | ||||
| 	SecretFile      string | ||||
| 	ExportDir       string | ||||
| 	NonInteractive  bool | ||||
| 	Datadir         string | ||||
| 	LogFile         string | ||||
| 	ConfigFile      string | ||||
| 	DebugFile       string | ||||
| 	LogLevel        int | ||||
| 	LogFormat       string | ||||
| 	Dump            bool | ||||
| 	DumpHash        string | ||||
| 	DumpNumber      int | ||||
| 	VmType          int | ||||
| 	ImportChain     string | ||||
| 	SHH             bool | ||||
| 	Dial            bool | ||||
| 	PrintVersion    bool | ||||
| 	Identifier       string | ||||
| 	KeyRing          string | ||||
| 	DiffTool         bool | ||||
| 	DiffType         string | ||||
| 	KeyStore         string | ||||
| 	StartRpc         bool | ||||
| 	StartWebSockets  bool | ||||
| 	RpcListenAddress string | ||||
| 	RpcPort          int | ||||
| 	OutboundPort     string | ||||
| 	ShowGenesis      bool | ||||
| 	AddPeer          string | ||||
| 	MaxPeer          int | ||||
| 	GenAddr          bool | ||||
| 	BootNodes        string | ||||
| 	NodeKey          *ecdsa.PrivateKey | ||||
| 	NAT              nat.Interface | ||||
| 	SecretFile       string | ||||
| 	ExportDir        string | ||||
| 	NonInteractive   bool | ||||
| 	Datadir          string | ||||
| 	LogFile          string | ||||
| 	ConfigFile       string | ||||
| 	DebugFile        string | ||||
| 	LogLevel         int | ||||
| 	LogFormat        string | ||||
| 	Dump             bool | ||||
| 	DumpHash         string | ||||
| 	DumpNumber       int | ||||
| 	VmType           int | ||||
| 	ImportChain      string | ||||
| 	SHH              bool | ||||
| 	Dial             bool | ||||
| 	PrintVersion     bool | ||||
| 	MinerThreads     int | ||||
| ) | ||||
| 
 | ||||
| // flags specific to cli client
 | ||||
| @ -79,12 +81,7 @@ var ( | ||||
| 	InputFile      string | ||||
| ) | ||||
| 
 | ||||
| func defaultDataDir() string { | ||||
| 	usr, _ := user.Current() | ||||
| 	return path.Join(usr.HomeDir, ".ethereum") | ||||
| } | ||||
| 
 | ||||
| var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini") | ||||
| var defaultConfigFile = path.Join(ethutil.DefaultDataDir(), "conf.ini") | ||||
| 
 | ||||
| func Init() { | ||||
| 	// TODO: move common flag processing to cmd/util
 | ||||
| @ -96,22 +93,21 @@ func Init() { | ||||
| 	flag.IntVar(&VmType, "vm", 0, "Virtual Machine type: 0-1: standard, debug") | ||||
| 	flag.StringVar(&Identifier, "id", "", "Custom client identifier") | ||||
| 	flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use") | ||||
| 	flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") | ||||
| 	flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file") | ||||
| 
 | ||||
| 	flag.StringVar(&RpcListenAddress, "rpcaddr", "127.0.0.1", "address for json-rpc server to listen on") | ||||
| 	flag.IntVar(&RpcPort, "rpcport", 8545, "port to start json-rpc server on") | ||||
| 	flag.IntVar(&WsPort, "wsport", 40404, "port to start websocket rpc server on") | ||||
| 	flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") | ||||
| 	flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server") | ||||
| 	flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)") | ||||
| 	flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") | ||||
| 	flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)") | ||||
| 	flag.StringVar(&ExportDir, "export", "", "exports the session keyring to files in the directory given") | ||||
| 	flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)") | ||||
| 	flag.StringVar(&Datadir, "datadir", defaultDataDir(), "specifies the datadir to use") | ||||
| 	flag.StringVar(&Datadir, "datadir", ethutil.DefaultDataDir(), "specifies the datadir to use") | ||||
| 	flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file") | ||||
| 	flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)") | ||||
| 	flag.IntVar(&LogLevel, "loglevel", int(logger.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)") | ||||
| 	flag.StringVar(&LogFormat, "logformat", "std", "logformat: std,raw)") | ||||
| 	flag.IntVar(&LogLevel, "loglevel", int(logger.InfoLevel), "loglevel: 0-5 (= silent,error,warn,info,debug,debug detail)") | ||||
| 	flag.StringVar(&LogFormat, "logformat", "std", "logformat: std,raw") | ||||
| 	flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0") | ||||
| 	flag.StringVar(&DiffType, "diff", "all", "sets the level of diff output [vm, all]. Has no effect if difftool=false") | ||||
| 	flag.BoolVar(&ShowGenesis, "genesis", false, "Dump the genesis block") | ||||
| @ -121,9 +117,10 @@ func Init() { | ||||
| 	flag.StringVar(&DumpHash, "hash", "", "specify arg in hex") | ||||
| 	flag.IntVar(&DumpNumber, "number", -1, "specify arg in number") | ||||
| 
 | ||||
| 	flag.BoolVar(&StartMining, "mine", false, "start dagger mining") | ||||
| 	flag.BoolVar(&StartMining, "mine", false, "start mining") | ||||
| 	flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console") | ||||
| 	flag.BoolVar(&PrintVersion, "version", false, "prints version number") | ||||
| 	flag.IntVar(&MinerThreads, "minerthreads", runtime.NumCPU(), "number of miner threads") | ||||
| 
 | ||||
| 	// Network stuff
 | ||||
| 	var ( | ||||
| @ -140,6 +137,12 @@ func Init() { | ||||
| 
 | ||||
| 	flag.Parse() | ||||
| 
 | ||||
| 	// When the javascript console is started log to a file instead
 | ||||
| 	// of stdout
 | ||||
| 	if StartJsConsole { | ||||
| 		LogFile = path.Join(Datadir, "ethereum.log") | ||||
| 	} | ||||
| 
 | ||||
| 	var err error | ||||
| 	if NAT, err = nat.Parse(*natstr); err != nil { | ||||
| 		log.Fatalf("-nat: %v", err) | ||||
|  | ||||
| @ -37,7 +37,7 @@ import ( | ||||
| 
 | ||||
| const ( | ||||
| 	ClientIdentifier = "Ethereum(G)" | ||||
| 	Version          = "0.8.5" | ||||
| 	Version          = "0.8.6" | ||||
| ) | ||||
| 
 | ||||
| var clilogger = logger.NewLogger("CLI") | ||||
| @ -62,20 +62,21 @@ func main() { | ||||
| 	utils.InitConfig(VmType, ConfigFile, Datadir, "ETH") | ||||
| 
 | ||||
| 	ethereum, err := eth.New(ð.Config{ | ||||
| 		Name:      p2p.MakeName(ClientIdentifier, Version), | ||||
| 		KeyStore:  KeyStore, | ||||
| 		DataDir:   Datadir, | ||||
| 		LogFile:   LogFile, | ||||
| 		LogLevel:  LogLevel, | ||||
| 		LogFormat: LogFormat, | ||||
| 		MaxPeers:  MaxPeer, | ||||
| 		Port:      OutboundPort, | ||||
| 		NAT:       NAT, | ||||
| 		KeyRing:   KeyRing, | ||||
| 		Shh:       true, | ||||
| 		Dial:      Dial, | ||||
| 		BootNodes: BootNodes, | ||||
| 		NodeKey:   NodeKey, | ||||
| 		Name:         p2p.MakeName(ClientIdentifier, Version), | ||||
| 		KeyStore:     KeyStore, | ||||
| 		DataDir:      Datadir, | ||||
| 		LogFile:      LogFile, | ||||
| 		LogLevel:     LogLevel, | ||||
| 		LogFormat:    LogFormat, | ||||
| 		MaxPeers:     MaxPeer, | ||||
| 		Port:         OutboundPort, | ||||
| 		NAT:          NAT, | ||||
| 		KeyRing:      KeyRing, | ||||
| 		Shh:          true, | ||||
| 		Dial:         Dial, | ||||
| 		BootNodes:    BootNodes, | ||||
| 		NodeKey:      NodeKey, | ||||
| 		MinerThreads: MinerThreads, | ||||
| 	}) | ||||
| 
 | ||||
| 	if err != nil { | ||||
| @ -113,10 +114,6 @@ func main() { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if StartMining { | ||||
| 		utils.StartMining(ethereum) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(ImportChain) > 0 { | ||||
| 		start := time.Now() | ||||
| 		err := utils.ImportChain(ethereum, ImportChain) | ||||
| @ -128,15 +125,17 @@ func main() { | ||||
| 	} | ||||
| 
 | ||||
| 	if StartRpc { | ||||
| 		utils.StartRpc(ethereum, RpcPort) | ||||
| 	} | ||||
| 
 | ||||
| 	if StartWebSockets { | ||||
| 		utils.StartWebSockets(ethereum, WsPort) | ||||
| 		utils.StartRpc(ethereum, RpcListenAddress, RpcPort) | ||||
| 	} | ||||
| 
 | ||||
| 	utils.StartEthereum(ethereum) | ||||
| 
 | ||||
| 	fmt.Printf("Welcome to the FRONTIER\n") | ||||
| 
 | ||||
| 	if StartMining { | ||||
| 		ethereum.Miner().Start() | ||||
| 	} | ||||
| 
 | ||||
| 	if StartJsConsole { | ||||
| 		InitJsConsole(ethereum) | ||||
| 	} else if len(InputFile) > 0 { | ||||
|  | ||||
| @ -60,6 +60,7 @@ func (self *JSRepl) Start() { | ||||
| 	if !self.running { | ||||
| 		self.running = true | ||||
| 		repllogger.Infoln("init JS Console") | ||||
| 
 | ||||
| 		reader := bufio.NewReader(self.history) | ||||
| 		for { | ||||
| 			line, err := reader.ReadString('\n') | ||||
|  | ||||
| @ -19,6 +19,7 @@ | ||||
| 	<span>Amount:</span> | ||||
| 	<input type="text" id="amount" style="width:200px"> | ||||
| 	<button onclick="transact()">Send</button> | ||||
| 	<span id="message"></span> | ||||
| </div> | ||||
| 
 | ||||
| <hr> | ||||
| @ -95,17 +96,28 @@ | ||||
| 	} | ||||
| 
 | ||||
| 	function transact() { | ||||
| 		var to = document.querySelector("#address").value; | ||||
| 		if( to.length == 0 ) { | ||||
| 		var to = document.querySelector("#address"); | ||||
| 		if( to.value.length == 0 ) { | ||||
| 			to = "0x4205b06c2cfa0e30359edcab94543266cb6fa1d3"; | ||||
| 		} else { | ||||
| 			to = "0x"+to; | ||||
| 			if (to.value.substr(0,2) != "0x") | ||||
| 				to.value = "0x"+to.value; | ||||
| 		} | ||||
| 
 | ||||
| 		var value = parseInt( document.querySelector("#amount").value ); | ||||
| 		console.log("transact: ", to, " => ", value) | ||||
| 		var value = document.querySelector("#amount"); | ||||
| 		var amount = parseInt( value.value ); | ||||
| 		console.log("transact: ", to.value, " => ", amount) | ||||
| 
 | ||||
| 		contract.send( to, value ); | ||||
| 		contract.send( to.value, amount ); | ||||
| 
 | ||||
| 		to.value = ""; | ||||
| 		value.value = ""; | ||||
| 
 | ||||
| 		var message = document.querySelector("#message") | ||||
| 		message.innerHTML = "Submitted"; | ||||
| 		setTimeout(function() { | ||||
| 			message.innerHTML = ""; | ||||
| 		}, 1000); | ||||
| 	} | ||||
| 
 | ||||
| 	refresh(); | ||||
|  | ||||
| @ -62,6 +62,8 @@ | ||||
| 
 | ||||
|     web3.setProvider(new web3.providers.HttpSyncProvider('http://localhost:8545')); | ||||
| 
 | ||||
|     eth.defaultBlock = -2 | ||||
| 
 | ||||
|     document.querySelector("#number").innerHTML = eth.number; | ||||
|     document.querySelector("#coinbase").innerHTML = eth.coinbase | ||||
|     document.querySelector("#peer_count").innerHTML = eth.peerCount; | ||||
| @ -72,8 +74,9 @@ | ||||
|     document.querySelector("#mining").innerHTML = eth.mining; | ||||
|     document.querySelector("#listening").innerHTML = eth.listening; | ||||
|     eth.watch('chain').changed(function() { | ||||
| 		    document.querySelector("#number").innerHTML = eth.number; | ||||
| 		     }); | ||||
|         document.querySelector("#number").innerHTML = eth.number; | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
| </script> | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										812
									
								
								cmd/mist/assets/ext/ethereum.js/dist/ethereum.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										812
									
								
								cmd/mist/assets/ext/ethereum.js/dist/ethereum.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -981,7 +981,7 @@ ApplicationWindow { | ||||
|                  anchors.top: parent.top | ||||
|                  anchors.topMargin: 30 | ||||
|                  font.pointSize: 12 | ||||
|                  text: "<h2>Mist (0.8.5)</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor Trón<br>Felix Lange<br>Taylor Gerring<br>Daniel Nagy<br>Gustav Simonsson<br><h3>UX/UI</h3>Alex van de Sande<br>Fabian Vogelsteller" | ||||
|                  text: "<h2>Mist (0.8.6)</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor Trón<br>Felix Lange<br>Taylor Gerring<br>Daniel Nagy<br>Gustav Simonsson<br><h3>UX/UI</h3>Alex van de Sande<br>Fabian Vogelsteller" | ||||
|              } | ||||
|          } | ||||
| 
 | ||||
|  | ||||
| @ -24,7 +24,6 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/core" | ||||
| 	"github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/ethereum/go-ethereum/event" | ||||
| 	"github.com/ethereum/go-ethereum/ui/qt" | ||||
| 	"github.com/ethereum/go-ethereum/xeth" | ||||
| 	"github.com/obscuren/qml" | ||||
| ) | ||||
| @ -116,7 +115,3 @@ func (app *ExtApplication) mainLoop() { | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *ExtApplication) Watch(filterOptions map[string]interface{}, identifier string) { | ||||
| 	self.filters[identifier] = qt.NewFilterFromMap(filterOptions, self.eth) | ||||
| } | ||||
|  | ||||
| @ -26,80 +26,46 @@ import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 
 | ||||
| 	"bitbucket.org/kardianos/osext" | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/p2p/nat" | ||||
| 	"github.com/ethereum/go-ethereum/vm" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	Identifier      string | ||||
| 	KeyRing         string | ||||
| 	KeyStore        string | ||||
| 	StartRpc        bool | ||||
| 	StartWebSockets bool | ||||
| 	RpcPort         int | ||||
| 	WsPort          int | ||||
| 	OutboundPort    string | ||||
| 	ShowGenesis     bool | ||||
| 	AddPeer         string | ||||
| 	MaxPeer         int | ||||
| 	GenAddr         bool | ||||
| 	BootNodes       string | ||||
| 	NodeKey         *ecdsa.PrivateKey | ||||
| 	NAT             nat.Interface | ||||
| 	SecretFile      string | ||||
| 	ExportDir       string | ||||
| 	NonInteractive  bool | ||||
| 	Datadir         string | ||||
| 	LogFile         string | ||||
| 	ConfigFile      string | ||||
| 	DebugFile       string | ||||
| 	LogLevel        int | ||||
| 	VmType          int | ||||
| 	MinerThreads    int | ||||
| 	Identifier       string | ||||
| 	KeyRing          string | ||||
| 	KeyStore         string | ||||
| 	StartRpc         bool | ||||
| 	RpcListenAddress string | ||||
| 	RpcPort          int | ||||
| 	OutboundPort     string | ||||
| 	ShowGenesis      bool | ||||
| 	AddPeer          string | ||||
| 	MaxPeer          int | ||||
| 	GenAddr          bool | ||||
| 	BootNodes        string | ||||
| 	NodeKey          *ecdsa.PrivateKey | ||||
| 	NAT              nat.Interface | ||||
| 	SecretFile       string | ||||
| 	ExportDir        string | ||||
| 	NonInteractive   bool | ||||
| 	Datadir          string | ||||
| 	LogFile          string | ||||
| 	ConfigFile       string | ||||
| 	DebugFile        string | ||||
| 	LogLevel         int | ||||
| 	VmType           int | ||||
| 	MinerThreads     int | ||||
| ) | ||||
| 
 | ||||
| // flags specific to gui client
 | ||||
| var AssetPath string | ||||
| 
 | ||||
| //TODO: If we re-use the one defined in cmd.go the binary osx image crashes. If somebody finds out why we can dry this up.
 | ||||
| func defaultAssetPath() string { | ||||
| 	var assetPath string | ||||
| 	// If the current working directory is the go-ethereum dir
 | ||||
| 	// assume a debug build and use the source directory as
 | ||||
| 	// asset directory.
 | ||||
| 	pwd, _ := os.Getwd() | ||||
| 	if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist") { | ||||
| 		assetPath = path.Join(pwd, "assets") | ||||
| 	} else { | ||||
| 		switch runtime.GOOS { | ||||
| 		case "darwin": | ||||
| 			// Get Binary Directory
 | ||||
| 			exedir, _ := osext.ExecutableFolder() | ||||
| 			assetPath = filepath.Join(exedir, "../Resources") | ||||
| 		case "linux": | ||||
| 			assetPath = "/usr/share/mist" | ||||
| 		case "windows": | ||||
| 			assetPath = "./assets" | ||||
| 		default: | ||||
| 			assetPath = "." | ||||
| 		} | ||||
| 	} | ||||
| 	return assetPath | ||||
| } | ||||
| func defaultDataDir() string { | ||||
| 	usr, _ := user.Current() | ||||
| 	return path.Join(usr.HomeDir, ".ethereum") | ||||
| } | ||||
| 
 | ||||
| var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini") | ||||
| var defaultConfigFile = path.Join(ethutil.DefaultDataDir(), "conf.ini") | ||||
| 
 | ||||
| func Init() { | ||||
| 	// TODO: move common flag processing to cmd/utils
 | ||||
| @ -111,22 +77,21 @@ func Init() { | ||||
| 	flag.IntVar(&VmType, "vm", 0, "Virtual Machine type: 0-1: standard, debug") | ||||
| 	flag.StringVar(&Identifier, "id", "", "Custom client identifier") | ||||
| 	flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use") | ||||
| 	flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") | ||||
| 	flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file") | ||||
| 	flag.StringVar(&RpcListenAddress, "rpcaddr", "127.0.0.1", "address for json-rpc server to listen on") | ||||
| 	flag.IntVar(&RpcPort, "rpcport", 8545, "port to start json-rpc server on") | ||||
| 	flag.IntVar(&WsPort, "wsport", 40404, "port to start websocket rpc server on") | ||||
| 	flag.BoolVar(&StartRpc, "rpc", true, "start rpc server") | ||||
| 	flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server") | ||||
| 	flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)") | ||||
| 	flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") | ||||
| 	flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)") | ||||
| 	flag.StringVar(&ExportDir, "export", "", "exports the session keyring to files in the directory given") | ||||
| 	flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)") | ||||
| 	flag.StringVar(&Datadir, "datadir", defaultDataDir(), "specifies the datadir to use") | ||||
| 	flag.StringVar(&Datadir, "datadir", ethutil.DefaultDataDir(), "specifies the datadir to use") | ||||
| 	flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file") | ||||
| 	flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)") | ||||
| 	flag.IntVar(&LogLevel, "loglevel", int(logger.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)") | ||||
| 	flag.IntVar(&LogLevel, "loglevel", int(logger.InfoLevel), "loglevel: 0-5 (= silent,error,warn,info,debug,debug detail)") | ||||
| 
 | ||||
| 	flag.StringVar(&AssetPath, "asset_path", defaultAssetPath(), "absolute path to GUI assets directory") | ||||
| 	flag.StringVar(&AssetPath, "asset_path", ethutil.DefaultAssetPath(), "absolute path to GUI assets directory") | ||||
| 
 | ||||
| 	// Network stuff
 | ||||
| 	var ( | ||||
|  | ||||
| @ -36,7 +36,7 @@ import ( | ||||
| 
 | ||||
| const ( | ||||
| 	ClientIdentifier = "Mist" | ||||
| 	Version          = "0.8.5" | ||||
| 	Version          = "0.8.6" | ||||
| ) | ||||
| 
 | ||||
| var ethereum *eth.Ethereum | ||||
| @ -73,11 +73,7 @@ func run() error { | ||||
| 	utils.KeyTasks(ethereum.KeyManager(), KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive) | ||||
| 
 | ||||
| 	if StartRpc { | ||||
| 		utils.StartRpc(ethereum, RpcPort) | ||||
| 	} | ||||
| 
 | ||||
| 	if StartWebSockets { | ||||
| 		utils.StartWebSockets(ethereum, WsPort) | ||||
| 		utils.StartRpc(ethereum, RpcListenAddress, RpcPort) | ||||
| 	} | ||||
| 
 | ||||
| 	gui := NewWindow(ethereum, config, KeyRing, LogLevel) | ||||
|  | ||||
| @ -25,12 +25,8 @@ import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"os/signal" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"regexp" | ||||
| 	"runtime" | ||||
| 
 | ||||
| 	"bitbucket.org/kardianos/osext" | ||||
| 	"github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/eth" | ||||
| @ -39,7 +35,6 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/miner" | ||||
| 	"github.com/ethereum/go-ethereum/rlp" | ||||
| 	rpchttp "github.com/ethereum/go-ethereum/rpc/http" | ||||
| 	rpcws "github.com/ethereum/go-ethereum/rpc/ws" | ||||
| 	"github.com/ethereum/go-ethereum/state" | ||||
| 	"github.com/ethereum/go-ethereum/xeth" | ||||
| ) | ||||
| @ -132,31 +127,6 @@ func StartEthereum(ethereum *eth.Ethereum) { | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func DefaultAssetPath() string { | ||||
| 	var assetPath string | ||||
| 	// If the current working directory is the go-ethereum dir
 | ||||
| 	// assume a debug build and use the source directory as
 | ||||
| 	// asset directory.
 | ||||
| 	pwd, _ := os.Getwd() | ||||
| 	if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist") { | ||||
| 		assetPath = path.Join(pwd, "assets") | ||||
| 	} else { | ||||
| 		switch runtime.GOOS { | ||||
| 		case "darwin": | ||||
| 			// Get Binary Directory
 | ||||
| 			exedir, _ := osext.ExecutableFolder() | ||||
| 			assetPath = filepath.Join(exedir, "../Resources") | ||||
| 		case "linux": | ||||
| 			assetPath = "/usr/share/mist" | ||||
| 		case "windows": | ||||
| 			assetPath = "./assets" | ||||
| 		default: | ||||
| 			assetPath = "." | ||||
| 		} | ||||
| 	} | ||||
| 	return assetPath | ||||
| } | ||||
| 
 | ||||
| func KeyTasks(keyManager *crypto.KeyManager, KeyRing string, GenAddr bool, SecretFile string, ExportDir string, NonInteractive bool) { | ||||
| 
 | ||||
| 	var err error | ||||
| @ -189,9 +159,9 @@ func KeyTasks(keyManager *crypto.KeyManager, KeyRing string, GenAddr bool, Secre | ||||
| 	clilogger.Infof("Main address %x\n", keyManager.Address()) | ||||
| } | ||||
| 
 | ||||
| func StartRpc(ethereum *eth.Ethereum, RpcPort int) { | ||||
| func StartRpc(ethereum *eth.Ethereum, RpcListenAddress string, RpcPort int) { | ||||
| 	var err error | ||||
| 	ethereum.RpcServer, err = rpchttp.NewRpcHttpServer(xeth.New(ethereum), RpcPort) | ||||
| 	ethereum.RpcServer, err = rpchttp.NewRpcHttpServer(xeth.New(ethereum), RpcListenAddress, RpcPort) | ||||
| 	if err != nil { | ||||
| 		clilogger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err) | ||||
| 	} else { | ||||
| @ -199,18 +169,6 @@ func StartRpc(ethereum *eth.Ethereum, RpcPort int) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func StartWebSockets(eth *eth.Ethereum, wsPort int) { | ||||
| 	clilogger.Infoln("Starting WebSockets") | ||||
| 
 | ||||
| 	var err error | ||||
| 	eth.WsServer, err = rpcws.NewWebSocketServer(xeth.New(eth), wsPort) | ||||
| 	if err != nil { | ||||
| 		clilogger.Errorf("Could not start RPC interface (port %v): %v", wsPort, err) | ||||
| 	} else { | ||||
| 		go eth.WsServer.Start() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var gminer *miner.Miner | ||||
| 
 | ||||
| func GetMiner() *miner.Miner { | ||||
|  | ||||
| @ -48,9 +48,8 @@ type BlockProcessor struct { | ||||
| 
 | ||||
| func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor { | ||||
| 	sm := &BlockProcessor{ | ||||
| 		db:  db, | ||||
| 		mem: make(map[string]*big.Int), | ||||
| 		//Pow:      ðash.Ethash{},
 | ||||
| 		db:       db, | ||||
| 		mem:      make(map[string]*big.Int), | ||||
| 		Pow:      ezp.New(), | ||||
| 		bc:       chainManager, | ||||
| 		eventMux: eventMux, | ||||
| @ -62,7 +61,7 @@ func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainM | ||||
| 
 | ||||
| func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block, transientProcess bool) (receipts types.Receipts, err error) { | ||||
| 	coinbase := statedb.GetOrNewStateObject(block.Header().Coinbase) | ||||
| 	coinbase.SetGasPool(CalcGasLimit(parent, block)) | ||||
| 	coinbase.SetGasPool(block.Header().GasLimit) | ||||
| 
 | ||||
| 	// Process the transactions on to parent state
 | ||||
| 	receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), transientProcess) | ||||
| @ -100,7 +99,8 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated | ||||
| 	// Notify all subscribers
 | ||||
| 	if !transientProcess { | ||||
| 		go self.eventMux.Post(TxPostEvent{tx}) | ||||
| 		go self.eventMux.Post(statedb.Logs()) | ||||
| 		logs := statedb.Logs() | ||||
| 		go self.eventMux.Post(logs) | ||||
| 	} | ||||
| 
 | ||||
| 	return receipt, txGas, err | ||||
| @ -247,6 +247,11 @@ func (sm *BlockProcessor) ValidateBlock(block, parent *types.Block) error { | ||||
| 		return fmt.Errorf("Difficulty check failed for block %v, %v", block.Header().Difficulty, expd) | ||||
| 	} | ||||
| 
 | ||||
| 	expl := CalcGasLimit(parent, block) | ||||
| 	if expl.Cmp(block.Header().GasLimit) != 0 { | ||||
| 		return fmt.Errorf("GasLimit check failed for block %v, %v", block.Header().GasLimit, expl) | ||||
| 	} | ||||
| 
 | ||||
| 	if block.Time() < parent.Time() { | ||||
| 		return ValidationError("Block timestamp not after prev block (%v - %v)", block.Header().Time, parent.Header().Time) | ||||
| 	} | ||||
|  | ||||
| @ -85,12 +85,14 @@ type ChainManager struct { | ||||
| 	lastBlockHash []byte | ||||
| 
 | ||||
| 	transState *state.StateDB | ||||
| 	txState    *state.StateDB | ||||
| } | ||||
| 
 | ||||
| func NewChainManager(db ethutil.Database, mux *event.TypeMux) *ChainManager { | ||||
| 	bc := &ChainManager{db: db, genesisBlock: GenesisBlock(db), eventMux: mux} | ||||
| 	bc.setLastBlock() | ||||
| 	bc.transState = bc.State().Copy() | ||||
| 	bc.txState = bc.State().Copy() | ||||
| 
 | ||||
| 	return bc | ||||
| } | ||||
| @ -138,6 +140,19 @@ func (self *ChainManager) TransState() *state.StateDB { | ||||
| 	return self.transState | ||||
| } | ||||
| 
 | ||||
| func (self *ChainManager) TxState() *state.StateDB { | ||||
| 	self.tsmu.RLock() | ||||
| 	defer self.tsmu.RUnlock() | ||||
| 
 | ||||
| 	return self.txState | ||||
| } | ||||
| 
 | ||||
| func (self *ChainManager) setTxState(state *state.StateDB) { | ||||
| 	self.tsmu.Lock() | ||||
| 	defer self.tsmu.Unlock() | ||||
| 	self.txState = state | ||||
| } | ||||
| 
 | ||||
| func (self *ChainManager) setTransState(statedb *state.StateDB) { | ||||
| 	self.transState = statedb | ||||
| } | ||||
| @ -268,7 +283,6 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	fmt.Printf("get hash %x (%d)\n", hash, len(chain)) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| @ -363,6 +377,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { | ||||
| 	defer self.tsmu.Unlock() | ||||
| 
 | ||||
| 	for _, block := range chain { | ||||
| 		// Call in to the block processor and check for errors. It's likely that if one block fails
 | ||||
| 		// all others will fail too (unless a known block is returned).
 | ||||
| 		td, err := self.processor.Process(block) | ||||
| 		if err != nil { | ||||
| 			if IsKnownBlockErr(err) { | ||||
| @ -377,11 +393,15 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { | ||||
| 		} | ||||
| 		block.Td = td | ||||
| 
 | ||||
| 		var chain, split bool | ||||
| 		var canonical, split bool | ||||
| 		self.mu.Lock() | ||||
| 		{ | ||||
| 			// Write block to database. Eventually we'll have to improve on this and throw away blocks that are
 | ||||
| 			// not in the canonical chain.
 | ||||
| 			self.write(block) | ||||
| 			cblock := self.currentBlock | ||||
| 			// Compare the TD of the last known block in the canonical chain to make sure it's greater.
 | ||||
| 			// At this point it's possible that a different chain (fork) becomes the new canonical chain.
 | ||||
| 			if td.Cmp(self.td) > 0 { | ||||
| 				if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, ethutil.Big1)) < 0 { | ||||
| 					chainlogger.Infof("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n", block.Header().Number, block.Hash()[:4], td, cblock.Header().Number, cblock.Hash()[:4], self.td) | ||||
| @ -391,17 +411,18 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { | ||||
| 				self.setTotalDifficulty(td) | ||||
| 				self.insert(block) | ||||
| 
 | ||||
| 				chain = true | ||||
| 				canonical = true | ||||
| 			} | ||||
| 		} | ||||
| 		self.mu.Unlock() | ||||
| 
 | ||||
| 		if chain { | ||||
| 		if canonical { | ||||
| 			self.setTransState(state.New(block.Root(), self.db)) | ||||
| 			self.eventMux.Post(ChainEvent{block, td}) | ||||
| 		} | ||||
| 
 | ||||
| 		if split { | ||||
| 			self.setTransState(state.New(block.Root(), self.db)) | ||||
| 			self.setTxState(state.New(block.Root(), self.db)) | ||||
| 			self.eventMux.Post(ChainSplitEvent{block}) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -17,7 +17,7 @@ type FilterOptions struct { | ||||
| 	Latest   int64 | ||||
| 
 | ||||
| 	Address [][]byte | ||||
| 	Topics  [][]byte | ||||
| 	Topics  [][][]byte | ||||
| 
 | ||||
| 	Skip int | ||||
| 	Max  int | ||||
| @ -31,7 +31,7 @@ type Filter struct { | ||||
| 	skip     int | ||||
| 	address  [][]byte | ||||
| 	max      int | ||||
| 	topics   [][]byte | ||||
| 	topics   [][][]byte | ||||
| 
 | ||||
| 	BlockCallback   func(*types.Block) | ||||
| 	PendingCallback func(*types.Block) | ||||
| @ -44,6 +44,8 @@ func NewFilter(eth Backend) *Filter { | ||||
| 	return &Filter{eth: eth} | ||||
| } | ||||
| 
 | ||||
| // SetOptions copies the filter options to the filter it self. The reason for this "silly" copy
 | ||||
| // is simply because named arguments in this case is extremely nice and readable.
 | ||||
| func (self *Filter) SetOptions(options FilterOptions) { | ||||
| 	self.earliest = options.Earliest | ||||
| 	self.latest = options.Latest | ||||
| @ -69,7 +71,7 @@ func (self *Filter) SetAddress(addr [][]byte) { | ||||
| 	self.address = addr | ||||
| } | ||||
| 
 | ||||
| func (self *Filter) SetTopics(topics [][]byte) { | ||||
| func (self *Filter) SetTopics(topics [][][]byte) { | ||||
| 	self.topics = topics | ||||
| } | ||||
| 
 | ||||
| @ -149,10 +151,18 @@ Logs: | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		max := int(math.Min(float64(len(self.topics)), float64(len(log.Topics())))) | ||||
| 		for i := 0; i < max; i++ { | ||||
| 			if !bytes.Equal(log.Topics()[i], self.topics[i]) { | ||||
| 				continue Logs | ||||
| 		logTopics := make([][]byte, len(self.topics)) | ||||
| 		copy(logTopics, log.Topics()) | ||||
| 
 | ||||
| 		for i, topics := range self.topics { | ||||
| 			for _, topic := range topics { | ||||
| 				var match bool | ||||
| 				if bytes.Equal(log.Topics()[i], topic) { | ||||
| 					match = true | ||||
| 				} | ||||
| 				if !match { | ||||
| 					continue Logs | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| @ -177,8 +187,15 @@ func (self *Filter) bloomFilter(block *types.Block) bool { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for _, topic := range self.topics { | ||||
| 		if !types.BloomLookup(block.Bloom(), topic) { | ||||
| 	for _, sub := range self.topics { | ||||
| 		var included bool | ||||
| 		for _, topic := range sub { | ||||
| 			if types.BloomLookup(block.Bloom(), topic) { | ||||
| 				included = true | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		if !included { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -51,8 +51,6 @@ func GenesisBlock(db ethutil.Database) *types.Block { | ||||
| 	statedb.Sync() | ||||
| 	genesis.Header().Root = statedb.Root() | ||||
| 
 | ||||
| 	fmt.Printf("+++ genesis +++\nRoot: %x\nHash: %x\n", genesis.Header().Root, genesis.Hash()) | ||||
| 
 | ||||
| 	return genesis | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -126,7 +126,7 @@ func (self *StateTransition) BuyGas() error { | ||||
| 
 | ||||
| 	self.AddGas(self.msg.Gas()) | ||||
| 	self.initialGas.Set(self.msg.Gas()) | ||||
| 	sender.SubAmount(MessageGasValue(self.msg)) | ||||
| 	sender.SubBalance(MessageGasValue(self.msg)) | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| @ -251,7 +251,7 @@ func (self *StateTransition) RefundGas() { | ||||
| 	coinbase, sender := self.Coinbase(), self.From() | ||||
| 	// Return remaining gas
 | ||||
| 	remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice()) | ||||
| 	sender.AddAmount(remaining) | ||||
| 	sender.AddBalance(remaining) | ||||
| 
 | ||||
| 	uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2) | ||||
| 	for addr, ref := range self.state.Refunds() { | ||||
|  | ||||
| @ -30,7 +30,6 @@ import ( | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path" | ||||
| ) | ||||
| 
 | ||||
| @ -48,12 +47,6 @@ type keyStorePlain struct { | ||||
| 	keysDirPath string | ||||
| } | ||||
| 
 | ||||
| // TODO: copied from cmd/ethereum/flags.go
 | ||||
| func DefaultDataDir() string { | ||||
| 	usr, _ := user.Current() | ||||
| 	return path.Join(usr.HomeDir, ".ethereum") | ||||
| } | ||||
| 
 | ||||
| func NewKeyStorePlain(path string) KeyStore2 { | ||||
| 	return &keyStorePlain{path} | ||||
| } | ||||
| @ -126,8 +119,11 @@ func GetKeyAddresses(keysDirPath string) (addresses [][]byte, err error) { | ||||
| 	} | ||||
| 	addresses = make([][]byte, len(fileInfos)) | ||||
| 	for i, fileInfo := range fileInfos { | ||||
| 		addresses[i] = make([]byte, 40) | ||||
| 		addresses[i] = []byte(fileInfo.Name()) | ||||
| 		address, err := hex.DecodeString(fileInfo.Name()) | ||||
| 		if err != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		addresses[i] = address | ||||
| 	} | ||||
| 	return addresses, err | ||||
| } | ||||
|  | ||||
| @ -2,12 +2,13 @@ package crypto | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/ethereum/go-ethereum/crypto/randentropy" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| func TestKeyStorePlain(t *testing.T) { | ||||
| 	ks := NewKeyStorePlain(DefaultDataDir()) | ||||
| 	ks := NewKeyStorePlain(ethutil.DefaultDataDir()) | ||||
| 	pass := "" // not used but required by API
 | ||||
| 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | ||||
| 	if err != nil { | ||||
| @ -35,7 +36,7 @@ func TestKeyStorePlain(t *testing.T) { | ||||
| } | ||||
| 
 | ||||
| func TestKeyStorePassphrase(t *testing.T) { | ||||
| 	ks := NewKeyStorePassphrase(DefaultDataDir()) | ||||
| 	ks := NewKeyStorePassphrase(ethutil.DefaultDataDir()) | ||||
| 	pass := "foo" | ||||
| 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | ||||
| 	if err != nil { | ||||
| @ -61,7 +62,7 @@ func TestKeyStorePassphrase(t *testing.T) { | ||||
| } | ||||
| 
 | ||||
| func TestKeyStorePassphraseDecryptionFail(t *testing.T) { | ||||
| 	ks := NewKeyStorePassphrase(DefaultDataDir()) | ||||
| 	ks := NewKeyStorePassphrase(ethutil.DefaultDataDir()) | ||||
| 	pass := "foo" | ||||
| 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | ||||
| 	if err != nil { | ||||
| @ -89,7 +90,7 @@ func TestImportPreSaleKey(t *testing.T) { | ||||
| 	// python pyethsaletool.py genwallet
 | ||||
| 	// with password "foo"
 | ||||
| 	fileContent := "{\"encseed\": \"26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba\", \"ethaddr\": \"d4584b5f6229b7be90727b0fc8c6b91bb427821f\", \"email\": \"gustav.simonsson@gmail.com\", \"btcaddr\": \"1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx\"}" | ||||
| 	ks := NewKeyStorePassphrase(DefaultDataDir()) | ||||
| 	ks := NewKeyStorePassphrase(ethutil.DefaultDataDir()) | ||||
| 	pass := "foo" | ||||
| 	_, err := ImportPreSaleKey(ks, []byte(fileContent), pass) | ||||
| 	if err != nil { | ||||
|  | ||||
| @ -12,7 +12,7 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/ethdb" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/event" | ||||
| 	ethlogger "github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/miner" | ||||
| 	"github.com/ethereum/go-ethereum/p2p" | ||||
| 	"github.com/ethereum/go-ethereum/p2p/discover" | ||||
| @ -23,8 +23,8 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	logger     = ethlogger.NewLogger("SERV") | ||||
| 	jsonlogger = ethlogger.NewJsonLogger() | ||||
| 	ethlogger  = logger.NewLogger("SERV") | ||||
| 	jsonlogger = logger.NewJsonLogger() | ||||
| 
 | ||||
| 	defaultBootNodes = []*discover.Node{ | ||||
| 		// ETH/DEV cmd/bootnode
 | ||||
| @ -74,7 +74,7 @@ func (cfg *Config) parseBootNodes() []*discover.Node { | ||||
| 		} | ||||
| 		n, err := discover.ParseNode(url) | ||||
| 		if err != nil { | ||||
| 			logger.Errorf("Bootstrap URL %s: %v\n", url, err) | ||||
| 			ethlogger.Errorf("Bootstrap URL %s: %v\n", url, err) | ||||
| 			continue | ||||
| 		} | ||||
| 		ns = append(ns, n) | ||||
| @ -98,7 +98,7 @@ func (cfg *Config) nodeKey() (*ecdsa.PrivateKey, error) { | ||||
| 		return nil, fmt.Errorf("could not generate server key: %v", err) | ||||
| 	} | ||||
| 	if err := ioutil.WriteFile(keyfile, crypto.FromECDSA(key), 0600); err != nil { | ||||
| 		logger.Errorln("could not persist nodekey: ", err) | ||||
| 		ethlogger.Errorln("could not persist nodekey: ", err) | ||||
| 	} | ||||
| 	return key, nil | ||||
| } | ||||
| @ -127,17 +127,16 @@ type Ethereum struct { | ||||
| 	miner    *miner.Miner | ||||
| 
 | ||||
| 	RpcServer  rpc.RpcServer | ||||
| 	WsServer   rpc.RpcServer | ||||
| 	keyManager *crypto.KeyManager | ||||
| 
 | ||||
| 	logger ethlogger.LogSystem | ||||
| 	logger logger.LogSystem | ||||
| 
 | ||||
| 	Mining bool | ||||
| } | ||||
| 
 | ||||
| func New(config *Config) (*Ethereum, error) { | ||||
| 	// Boostrap database
 | ||||
| 	logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel, config.LogFormat) | ||||
| 	ethlogger := logger.New(config.DataDir, config.LogFile, config.LogLevel, config.LogFormat) | ||||
| 	db, err := ethdb.NewLDBDatabase("blockchain") | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| @ -147,7 +146,8 @@ func New(config *Config) (*Ethereum, error) { | ||||
| 	d, _ := db.Get([]byte("ProtocolVersion")) | ||||
| 	protov := ethutil.NewValue(d).Uint() | ||||
| 	if protov != ProtocolVersion && protov != 0 { | ||||
| 		return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, ethutil.Config.ExecPath+"/database") | ||||
| 		path := path.Join(config.DataDir, "blockchain") | ||||
| 		return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, path) | ||||
| 	} | ||||
| 
 | ||||
| 	// Create new keymanager
 | ||||
| @ -173,7 +173,7 @@ func New(config *Config) (*Ethereum, error) { | ||||
| 		keyManager:   keyManager, | ||||
| 		blacklist:    p2p.NewBlacklist(), | ||||
| 		eventMux:     &event.TypeMux{}, | ||||
| 		logger:       logger, | ||||
| 		logger:       ethlogger, | ||||
| 	} | ||||
| 
 | ||||
| 	eth.chainManager = core.NewChainManager(db, eth.EventMux()) | ||||
| @ -215,7 +215,7 @@ func New(config *Config) (*Ethereum, error) { | ||||
| } | ||||
| 
 | ||||
| func (s *Ethereum) KeyManager() *crypto.KeyManager       { return s.keyManager } | ||||
| func (s *Ethereum) Logger() ethlogger.LogSystem          { return s.logger } | ||||
| func (s *Ethereum) Logger() logger.LogSystem             { return s.logger } | ||||
| func (s *Ethereum) Name() string                         { return s.net.Name } | ||||
| func (s *Ethereum) ChainManager() *core.ChainManager     { return s.chainManager } | ||||
| func (s *Ethereum) BlockProcessor() *core.BlockProcessor { return s.blockProcessor } | ||||
| @ -233,7 +233,7 @@ func (s *Ethereum) Coinbase() []byte                     { return nil } // TODO | ||||
| 
 | ||||
| // Start the ethereum
 | ||||
| func (s *Ethereum) Start() error { | ||||
| 	jsonlogger.LogJson(ðlogger.LogStarting{ | ||||
| 	jsonlogger.LogJson(&logger.LogStarting{ | ||||
| 		ClientString:    s.net.Name, | ||||
| 		ProtocolVersion: ProtocolVersion, | ||||
| 	}) | ||||
| @ -259,7 +259,7 @@ func (s *Ethereum) Start() error { | ||||
| 	s.blockSub = s.eventMux.Subscribe(core.NewMinedBlockEvent{}) | ||||
| 	go s.blockBroadcastLoop() | ||||
| 
 | ||||
| 	logger.Infoln("Server started") | ||||
| 	ethlogger.Infoln("Server started") | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -284,9 +284,7 @@ func (s *Ethereum) Stop() { | ||||
| 	if s.RpcServer != nil { | ||||
| 		s.RpcServer.Stop() | ||||
| 	} | ||||
| 	if s.WsServer != nil { | ||||
| 		s.WsServer.Stop() | ||||
| 	} | ||||
| 
 | ||||
| 	s.txPool.Stop() | ||||
| 	s.eventMux.Stop() | ||||
| 	s.blockPool.Stop() | ||||
| @ -294,7 +292,7 @@ func (s *Ethereum) Stop() { | ||||
| 		s.whisper.Stop() | ||||
| 	} | ||||
| 
 | ||||
| 	logger.Infoln("Server stopped") | ||||
| 	ethlogger.Infoln("Server stopped") | ||||
| 	close(s.shutdownChan) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -12,11 +12,11 @@ import ( | ||||
| 
 | ||||
| 	"github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	ethlogger "github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/pow" | ||||
| ) | ||||
| 
 | ||||
| var poolLogger = ethlogger.NewLogger("Blockpool") | ||||
| var poolLogger = logger.NewLogger("Blockpool") | ||||
| 
 | ||||
| const ( | ||||
| 	blockHashesBatchSize       = 256 | ||||
|  | ||||
| @ -12,19 +12,19 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	ethlogger "github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/pow" | ||||
| ) | ||||
| 
 | ||||
| const waitTimeout = 60 // seconds
 | ||||
| 
 | ||||
| var logsys = ethlogger.NewStdLogSystem(os.Stdout, log.LstdFlags, ethlogger.LogLevel(ethlogger.DebugDetailLevel)) | ||||
| var logsys = logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.LogLevel(logger.DebugDetailLevel)) | ||||
| 
 | ||||
| var ini = false | ||||
| 
 | ||||
| func logInit() { | ||||
| 	if !ini { | ||||
| 		ethlogger.AddLogSystem(logsys) | ||||
| 		logger.AddLogSystem(logsys) | ||||
| 		ini = true | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -8,6 +8,7 @@ import ( | ||||
| 
 | ||||
| 	"github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/p2p" | ||||
| 	"github.com/ethereum/go-ethereum/rlp" | ||||
| ) | ||||
| @ -137,6 +138,12 @@ func (self *ethProtocol) handle() error { | ||||
| 		if err := msg.Decode(&txs); err != nil { | ||||
| 			return self.protoError(ErrDecode, "msg %v: %v", msg, err) | ||||
| 		} | ||||
| 		for _, tx := range txs { | ||||
| 			jsonlogger.LogJson(&logger.EthTxReceived{ | ||||
| 				TxHash:   ethutil.Bytes2Hex(tx.Hash()), | ||||
| 				RemoteId: self.peer.ID().String(), | ||||
| 			}) | ||||
| 		} | ||||
| 		self.txPool.AddTransactions(txs) | ||||
| 
 | ||||
| 	case GetBlockHashesMsg: | ||||
|  | ||||
| @ -12,12 +12,12 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	ethlogger "github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/p2p" | ||||
| 	"github.com/ethereum/go-ethereum/p2p/discover" | ||||
| ) | ||||
| 
 | ||||
| var sys = ethlogger.NewStdLogSystem(os.Stdout, log.LstdFlags, ethlogger.LogLevel(ethlogger.DebugDetailLevel)) | ||||
| var sys = logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.LogLevel(logger.DebugDetailLevel)) | ||||
| 
 | ||||
| type testMsgReadWriter struct { | ||||
| 	in  chan p2p.Msg | ||||
|  | ||||
| @ -3,10 +3,60 @@ package ethutil | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"math/big" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/kardianos/osext" | ||||
| ) | ||||
| 
 | ||||
| func DefaultAssetPath() string { | ||||
| 	var assetPath string | ||||
| 	pwd, _ := os.Getwd() | ||||
| 	srcdir := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist") | ||||
| 
 | ||||
| 	// If the current working directory is the go-ethereum dir
 | ||||
| 	// assume a debug build and use the source directory as
 | ||||
| 	// asset directory.
 | ||||
| 	if pwd == srcdir { | ||||
| 		assetPath = path.Join(pwd, "assets") | ||||
| 	} else { | ||||
| 		switch runtime.GOOS { | ||||
| 		case "darwin": | ||||
| 			// Get Binary Directory
 | ||||
| 			exedir, _ := osext.ExecutableFolder() | ||||
| 			assetPath = filepath.Join(exedir, "../Resources") | ||||
| 		case "linux": | ||||
| 			assetPath = "/usr/share/mist" | ||||
| 		case "windows": | ||||
| 			assetPath = "./assets" | ||||
| 		default: | ||||
| 			assetPath = "." | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Check if the assetPath exists. If not, try the source directory
 | ||||
| 	// This happens when binary is run from outside cmd/mist directory
 | ||||
| 	if _, err := os.Stat(assetPath); os.IsNotExist(err) { | ||||
| 		assetPath = path.Join(srcdir, "assets") | ||||
| 	} | ||||
| 
 | ||||
| 	return assetPath | ||||
| } | ||||
| 
 | ||||
| func DefaultDataDir() string { | ||||
| 	usr, _ := user.Current() | ||||
| 	if runtime.GOOS == "darwin" { | ||||
| 		return path.Join(usr.HomeDir, "Library/Ethereum") | ||||
| 	} else if runtime.GOOS == "windows" { | ||||
| 		return path.Join(usr.HomeDir, "AppData/Roaming/Ethereum") | ||||
| 	} else { | ||||
| 		return path.Join(usr.HomeDir, ".ethereum") | ||||
| 	} | ||||
| } | ||||
| func IsWindows() bool { | ||||
| 	return runtime.GOOS == "windows" | ||||
| } | ||||
|  | ||||
| @ -3,7 +3,6 @@ package filter | ||||
| // TODO make use of the generic filtering system
 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/ethereum/go-ethereum/core" | ||||
| @ -75,7 +74,6 @@ out: | ||||
| 		case event := <-events.Chan(): | ||||
| 			switch event := event.(type) { | ||||
| 			case core.ChainEvent: | ||||
| 				fmt.Println("filter start") | ||||
| 				self.filterMu.RLock() | ||||
| 				for _, filter := range self.filters { | ||||
| 					if filter.BlockCallback != nil { | ||||
| @ -83,7 +81,6 @@ out: | ||||
| 					} | ||||
| 				} | ||||
| 				self.filterMu.RUnlock() | ||||
| 				fmt.Println("filter stop") | ||||
| 
 | ||||
| 			case core.PendingBlockEvent: | ||||
| 				self.filterMu.RLock() | ||||
|  | ||||
							
								
								
									
										53
									
								
								install.sh
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								install.sh
									
									
									
									
									
								
							| @ -1,53 +0,0 @@ | ||||
| #!/bin/sh | ||||
| 
 | ||||
| if [ "$1" == "" ]; then | ||||
| 	echo "Usage $0 executable branch" | ||||
| 	echo "executable    ethereum | mist" | ||||
| 	echo "branch        develop | master" | ||||
| 	exit | ||||
| fi | ||||
| 
 | ||||
| exe=$1 | ||||
| path=$exe | ||||
| branch=$2 | ||||
| 
 | ||||
| if [ "$branch" == "develop" ]; then | ||||
| 	path="cmd/$exe" | ||||
| fi | ||||
| 
 | ||||
| # Test if go is installed | ||||
| command -v go >/dev/null 2>&1 || { echo >&2 "Unable to find 'go'. This script requires go."; exit 1; } | ||||
| 
 | ||||
| # Test if $GOPATH is set | ||||
| if [ "$GOPATH" == "" ]; then | ||||
| 	echo "\$GOPATH not set" | ||||
| 	exit | ||||
| fi | ||||
| 
 | ||||
| echo "changing branch to $branch" | ||||
| cd $GOPATH/src/github.com/ethereum/go-ethereum | ||||
| git checkout $branch | ||||
| 
 | ||||
| # installing package dependencies doesn't work for develop | ||||
| # branch as go get always pulls from master head | ||||
| # so build will continue to fail, but this installs locally | ||||
| # for people who git clone since go install will manage deps | ||||
| 
 | ||||
| #echo "go get -u -d github.com/ethereum/go-ethereum/$path" | ||||
| #go get -v -u -d github.com/ethereum/go-ethereum/$path | ||||
| #if [ $? != 0 ]; then | ||||
| #	echo "go get failed" | ||||
| #	exit | ||||
| #fi | ||||
| 
 | ||||
| cd $GOPATH/src/github.com/ethereum/go-ethereum/$path | ||||
| 
 | ||||
| if [ "$exe" == "mist" ]; then | ||||
| 	echo "Building Mist GUI. Assuming Qt is installed. If this step" | ||||
| 	echo "fails; please refer to: https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)" | ||||
| else | ||||
| 	echo "Building ethereum CLI." | ||||
| fi | ||||
| 
 | ||||
| go install | ||||
| echo "done. Please run $exe :-)" | ||||
| @ -24,7 +24,7 @@ var jsrelogger = logger.NewLogger("JSRE") | ||||
| type JSRE struct { | ||||
| 	ethereum *eth.Ethereum | ||||
| 	Vm       *otto.Otto | ||||
| 	pipe     *xeth.XEth | ||||
| 	xeth     *xeth.XEth | ||||
| 
 | ||||
| 	events event.Subscription | ||||
| 
 | ||||
| @ -67,7 +67,7 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE { | ||||
| 	// We have to make sure that, whoever calls this, calls "Stop"
 | ||||
| 	go re.mainLoop() | ||||
| 
 | ||||
| 	re.Bind("eth", &JSEthereum{re.pipe, re.Vm, ethereum}) | ||||
| 	re.Bind("eth", &JSEthereum{re.xeth, re.Vm, ethereum}) | ||||
| 
 | ||||
| 	re.initStdFuncs() | ||||
| 
 | ||||
| @ -113,12 +113,10 @@ func (self *JSRE) mainLoop() { | ||||
| func (self *JSRE) initStdFuncs() { | ||||
| 	t, _ := self.Vm.Get("eth") | ||||
| 	eth := t.Object() | ||||
| 	eth.Set("watch", self.watch) | ||||
| 	eth.Set("addPeer", self.addPeer) | ||||
| 	eth.Set("connect", self.connect) | ||||
| 	eth.Set("require", self.require) | ||||
| 	eth.Set("stopMining", self.stopMining) | ||||
| 	eth.Set("startMining", self.startMining) | ||||
| 	eth.Set("execBlock", self.execBlock) | ||||
| 	eth.Set("dump", self.dump) | ||||
| 	eth.Set("export", self.export) | ||||
| } | ||||
| @ -152,7 +150,8 @@ func (self *JSRE) dump(call otto.FunctionCall) otto.Value { | ||||
| 	} | ||||
| 
 | ||||
| 	statedb := state.New(block.Root(), self.ethereum.Db()) | ||||
| 	v, _ := self.Vm.ToValue(statedb.Dump()) | ||||
| 
 | ||||
| 	v, _ := self.Vm.ToValue(statedb.RawDump()) | ||||
| 
 | ||||
| 	return v | ||||
| } | ||||
| @ -167,36 +166,7 @@ func (self *JSRE) startMining(call otto.FunctionCall) otto.Value { | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| // eth.watch
 | ||||
| func (self *JSRE) watch(call otto.FunctionCall) otto.Value { | ||||
| 	addr, _ := call.Argument(0).ToString() | ||||
| 	var storageAddr string | ||||
| 	var cb otto.Value | ||||
| 	var storageCallback bool | ||||
| 	if len(call.ArgumentList) > 2 { | ||||
| 		storageCallback = true | ||||
| 		storageAddr, _ = call.Argument(1).ToString() | ||||
| 		cb = call.Argument(2) | ||||
| 	} else { | ||||
| 		cb = call.Argument(1) | ||||
| 	} | ||||
| 
 | ||||
| 	if storageCallback { | ||||
| 		self.objectCb[addr+storageAddr] = append(self.objectCb[addr+storageAddr], cb) | ||||
| 
 | ||||
| 		// event := "storage:" + string(ethutil.Hex2Bytes(addr)) + ":" + string(ethutil.Hex2Bytes(storageAddr))
 | ||||
| 		// self.ethereum.EventMux().Subscribe(event, self.changeChan)
 | ||||
| 	} else { | ||||
| 		self.objectCb[addr] = append(self.objectCb[addr], cb) | ||||
| 
 | ||||
| 		// event := "object:" + string(ethutil.Hex2Bytes(addr))
 | ||||
| 		// self.ethereum.EventMux().Subscribe(event, self.changeChan)
 | ||||
| 	} | ||||
| 
 | ||||
| 	return otto.UndefinedValue() | ||||
| } | ||||
| 
 | ||||
| func (self *JSRE) addPeer(call otto.FunctionCall) otto.Value { | ||||
| func (self *JSRE) connect(call otto.FunctionCall) otto.Value { | ||||
| 	nodeURL, err := call.Argument(0).ToString() | ||||
| 	if err != nil { | ||||
| 		return otto.FalseValue() | ||||
| @ -222,22 +192,12 @@ func (self *JSRE) require(call otto.FunctionCall) otto.Value { | ||||
| 	return t | ||||
| } | ||||
| 
 | ||||
| func (self *JSRE) execBlock(call otto.FunctionCall) otto.Value { | ||||
| 	hash, err := call.Argument(0).ToString() | ||||
| 	if err != nil { | ||||
| 		return otto.UndefinedValue() | ||||
| 	} | ||||
| 
 | ||||
| 	err = utils.BlockDo(self.ethereum, ethutil.Hex2Bytes(hash)) | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| func (self *JSRE) export(call otto.FunctionCall) otto.Value { | ||||
| 	if len(call.ArgumentList) == 0 { | ||||
| 		fmt.Println("err: require file name") | ||||
| 		return otto.FalseValue() | ||||
| 	} | ||||
| 
 | ||||
| 	return otto.TrueValue() | ||||
| } | ||||
| 
 | ||||
| func (self *JSRE) export(call otto.FunctionCall) otto.Value { | ||||
| 	fn, err := call.Argument(0).ToString() | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
|  | ||||
| @ -16,7 +16,7 @@ function pp(object) { | ||||
|         str += " ]"; | ||||
|     } else if(typeof(object) === "object") { | ||||
|         str += "{ "; | ||||
|         var last = Object.keys(object).sort().pop() | ||||
|         var last = Object.keys(object).pop() | ||||
|         for(var k in object) { | ||||
|             str += k + ": " + pp(object[k]); | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,6 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/eth" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/state" | ||||
| 	"github.com/ethereum/go-ethereum/ui" | ||||
| 	"github.com/ethereum/go-ethereum/xeth" | ||||
| 	"github.com/obscuren/otto" | ||||
| ) | ||||
| @ -96,17 +95,3 @@ func (self *JSEthereum) toVal(v interface{}) otto.Value { | ||||
| 
 | ||||
| 	return result | ||||
| } | ||||
| 
 | ||||
| func (self *JSEthereum) Messages(object map[string]interface{}) otto.Value { | ||||
| 	filter := ui.NewFilterFromMap(object, self.ethereum) | ||||
| 
 | ||||
| 	logs := filter.Find() | ||||
| 	var jslogs []JSLog | ||||
| 	for _, m := range logs { | ||||
| 		jslogs = append(jslogs, NewJSLog(m)) | ||||
| 	} | ||||
| 
 | ||||
| 	v, _ := self.vm.ToValue(jslogs) | ||||
| 
 | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package logger | ||||
| 
 | ||||
| import ( | ||||
| 	"math/big" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| @ -53,10 +54,10 @@ func (l *P2PDisconnected) EventName() string { | ||||
| } | ||||
| 
 | ||||
| type EthMinerNewBlock struct { | ||||
| 	BlockHash     string `json:"block_hash"` | ||||
| 	BlockNumber   int    `json:"block_number"` | ||||
| 	ChainHeadHash string `json:"chain_head_hash"` | ||||
| 	BlockPrevHash string `json:"block_prev_hash"` | ||||
| 	BlockHash     string   `json:"block_hash"` | ||||
| 	BlockNumber   *big.Int `json:"block_number"` | ||||
| 	ChainHeadHash string   `json:"chain_head_hash"` | ||||
| 	BlockPrevHash string   `json:"block_prev_hash"` | ||||
| 	LogEvent | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -52,10 +52,5 @@ func (self *Miner) Stop() { | ||||
| } | ||||
| 
 | ||||
| func (self *Miner) HashRate() int64 { | ||||
| 	var tot int64 | ||||
| 	for _, agent := range self.worker.agents { | ||||
| 		tot += agent.Pow().GetHashrate() | ||||
| 	} | ||||
| 
 | ||||
| 	return tot | ||||
| 	return self.worker.HashRate() | ||||
| } | ||||
|  | ||||
| @ -5,16 +5,20 @@ import ( | ||||
| 	"math/big" | ||||
| 	"sort" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/ethereum/go-ethereum/core" | ||||
| 	"github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/event" | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/pow" | ||||
| 	"github.com/ethereum/go-ethereum/state" | ||||
| 	"gopkg.in/fatih/set.v0" | ||||
| ) | ||||
| 
 | ||||
| var jsonlogger = logger.NewJsonLogger() | ||||
| 
 | ||||
| type environment struct { | ||||
| 	totalUsedGas *big.Int | ||||
| 	state        *state.StateDB | ||||
| @ -111,6 +115,8 @@ func (self *worker) register(agent Agent) { | ||||
| func (self *worker) update() { | ||||
| 	events := self.mux.Subscribe(core.ChainEvent{}, core.NewMinedBlockEvent{}) | ||||
| 
 | ||||
| 	timer := time.NewTicker(2 * time.Second) | ||||
| 
 | ||||
| out: | ||||
| 	for { | ||||
| 		select { | ||||
| @ -129,6 +135,8 @@ out: | ||||
| 				agent.Stop() | ||||
| 			} | ||||
| 			break out | ||||
| 		case <-timer.C: | ||||
| 			minerlogger.Debugln("Hash rate:", self.HashRate(), "Khash") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| @ -141,7 +149,12 @@ func (self *worker) wait() { | ||||
| 			block := self.current.block | ||||
| 			if block.Number().Uint64() == work.Number && block.Nonce() == nil { | ||||
| 				self.current.block.Header().Nonce = work.Nonce | ||||
| 
 | ||||
| 				jsonlogger.LogJson(&logger.EthMinerNewBlock{ | ||||
| 					BlockHash:     ethutil.Bytes2Hex(block.Hash()), | ||||
| 					BlockNumber:   block.Number(), | ||||
| 					ChainHeadHash: ethutil.Bytes2Hex(block.ParentHeaderHash), | ||||
| 					BlockPrevHash: ethutil.Bytes2Hex(block.ParentHeaderHash), | ||||
| 				}) | ||||
| 				if err := self.chain.InsertChain(types.Blocks{self.current.block}); err == nil { | ||||
| 					self.mux.Post(core.NewMinedBlockEvent{self.current.block}) | ||||
| 				} else { | ||||
| @ -197,7 +210,7 @@ gasLimit: | ||||
| 	} | ||||
| 	self.eth.TxPool().RemoveSet(remove) | ||||
| 
 | ||||
| 	self.current.coinbase.AddAmount(core.BlockReward) | ||||
| 	self.current.coinbase.AddBalance(core.BlockReward) | ||||
| 
 | ||||
| 	self.current.state.Update(ethutil.Big0) | ||||
| 	self.push() | ||||
| @ -225,7 +238,7 @@ func (self *worker) commitUncle(uncle *types.Header) error { | ||||
| 	} | ||||
| 
 | ||||
| 	uncleAccount := self.current.state.GetAccount(uncle.Coinbase) | ||||
| 	uncleAccount.AddAmount(uncleReward) | ||||
| 	uncleAccount.AddBalance(uncleReward) | ||||
| 
 | ||||
| 	self.current.coinbase.AddBalance(uncleReward) | ||||
| 
 | ||||
| @ -244,3 +257,12 @@ func (self *worker) commitTransaction(tx *types.Transaction) error { | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (self *worker) HashRate() int64 { | ||||
| 	var tot int64 | ||||
| 	for _, agent := range self.agents { | ||||
| 		tot += agent.Pow().GetHashrate() | ||||
| 	} | ||||
| 
 | ||||
| 	return tot | ||||
| } | ||||
|  | ||||
| @ -20,18 +20,24 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/ethdb" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/event" | ||||
| 	"github.com/ethereum/go-ethereum/event/filter" | ||||
| 	"github.com/ethereum/go-ethereum/state" | ||||
| 	"github.com/ethereum/go-ethereum/ui" | ||||
| 	"github.com/ethereum/go-ethereum/xeth" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	defaultGasPrice = "10000000000000" | ||||
| 	defaultGas      = "10000" | ||||
| var ( | ||||
| 	defaultGasPrice  = big.NewInt(10000000000000) | ||||
| 	defaultGas       = big.NewInt(10000) | ||||
| 	filterTickerTime = 15 * time.Second | ||||
| ) | ||||
| 
 | ||||
| type EthereumApi struct { | ||||
| 	xeth          *xeth.XEth | ||||
| 	eth    *xeth.XEth | ||||
| 	xethMu sync.RWMutex | ||||
| 	mux    *event.TypeMux | ||||
| 
 | ||||
| 	quit          chan struct{} | ||||
| 	filterManager *filter.FilterManager | ||||
| 
 | ||||
| @ -45,17 +51,21 @@ type EthereumApi struct { | ||||
| 	register map[string][]*NewTxArgs | ||||
| 
 | ||||
| 	db ethutil.Database | ||||
| 
 | ||||
| 	defaultBlockAge int64 | ||||
| } | ||||
| 
 | ||||
| func NewEthereumApi(eth *xeth.XEth) *EthereumApi { | ||||
| 	db, _ := ethdb.NewLDBDatabase("dapps") | ||||
| 	api := &EthereumApi{ | ||||
| 		xeth:          eth, | ||||
| 		quit:          make(chan struct{}), | ||||
| 		filterManager: filter.NewFilterManager(eth.Backend().EventMux()), | ||||
| 		logs:          make(map[int]*logFilter), | ||||
| 		messages:      make(map[int]*whisperFilter), | ||||
| 		db:            db, | ||||
| 		eth:             eth, | ||||
| 		mux:             eth.Backend().EventMux(), | ||||
| 		quit:            make(chan struct{}), | ||||
| 		filterManager:   filter.NewFilterManager(eth.Backend().EventMux()), | ||||
| 		logs:            make(map[int]*logFilter), | ||||
| 		messages:        make(map[int]*whisperFilter), | ||||
| 		db:              db, | ||||
| 		defaultBlockAge: -1, | ||||
| 	} | ||||
| 	go api.filterManager.Start() | ||||
| 	go api.start() | ||||
| @ -63,6 +73,64 @@ func NewEthereumApi(eth *xeth.XEth) *EthereumApi { | ||||
| 	return api | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) setStateByBlockNumber(num int64) { | ||||
| 	chain := self.xeth().Backend().ChainManager() | ||||
| 	var block *types.Block | ||||
| 
 | ||||
| 	if self.defaultBlockAge < 0 { | ||||
| 		num = chain.CurrentBlock().Number().Int64() + num + 1 | ||||
| 	} | ||||
| 	block = chain.GetBlockByNumber(uint64(num)) | ||||
| 
 | ||||
| 	if block != nil { | ||||
| 		self.useState(state.New(block.Root(), self.xeth().Backend().Db())) | ||||
| 	} else { | ||||
| 		self.useState(chain.State()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) start() { | ||||
| 	timer := time.NewTicker(filterTickerTime) | ||||
| 	events := self.mux.Subscribe(core.ChainEvent{}) | ||||
| 
 | ||||
| done: | ||||
| 	for { | ||||
| 		select { | ||||
| 		case ev := <-events.Chan(): | ||||
| 			switch ev.(type) { | ||||
| 			case core.ChainEvent: | ||||
| 				if self.defaultBlockAge < 0 { | ||||
| 					self.setStateByBlockNumber(self.defaultBlockAge) | ||||
| 				} | ||||
| 			} | ||||
| 		case <-timer.C: | ||||
| 			self.logMut.Lock() | ||||
| 			self.messagesMut.Lock() | ||||
| 			for id, filter := range self.logs { | ||||
| 				if time.Since(filter.timeout) > 20*time.Second { | ||||
| 					self.filterManager.UninstallFilter(id) | ||||
| 					delete(self.logs, id) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			for id, filter := range self.messages { | ||||
| 				if time.Since(filter.timeout) > 20*time.Second { | ||||
| 					self.xeth().Whisper().Unwatch(id) | ||||
| 					delete(self.messages, id) | ||||
| 				} | ||||
| 			} | ||||
| 			self.logMut.Unlock() | ||||
| 			self.messagesMut.Unlock() | ||||
| 		case <-self.quit: | ||||
| 			break done | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) stop() { | ||||
| 	close(self.quit) | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) Register(args string, reply *interface{}) error { | ||||
| 	self.regmut.Lock() | ||||
| 	defer self.regmut.Unlock() | ||||
| @ -95,7 +163,7 @@ func (self *EthereumApi) WatchTx(args string, reply *interface{}) error { | ||||
| 
 | ||||
| func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error { | ||||
| 	var id int | ||||
| 	filter := core.NewFilter(self.xeth.Backend()) | ||||
| 	filter := core.NewFilter(self.xeth().Backend()) | ||||
| 	filter.SetOptions(toFilterOptions(args)) | ||||
| 	filter.LogsCallback = func(logs state.Logs) { | ||||
| 		self.logMut.Lock() | ||||
| @ -120,16 +188,12 @@ func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error { | ||||
| 
 | ||||
| func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error { | ||||
| 	var id int | ||||
| 	filter := core.NewFilter(self.xeth.Backend()) | ||||
| 	filter := core.NewFilter(self.xeth().Backend()) | ||||
| 
 | ||||
| 	callback := func(block *types.Block) { | ||||
| 		self.logMut.Lock() | ||||
| 		defer self.logMut.Unlock() | ||||
| 
 | ||||
| 		if self.logs[id] == nil { | ||||
| 			self.logs[id] = &logFilter{timeout: time.Now()} | ||||
| 		} | ||||
| 
 | ||||
| 		self.logs[id].add(&state.StateLog{}) | ||||
| 	} | ||||
| 	if args == "pending" { | ||||
| @ -139,6 +203,7 @@ func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error | ||||
| 	} | ||||
| 
 | ||||
| 	id = self.filterManager.InstallFilter(filter) | ||||
| 	self.logs[id] = &logFilter{timeout: time.Now()} | ||||
| 	*reply = id | ||||
| 
 | ||||
| 	return nil | ||||
| @ -168,7 +233,7 @@ func (self *EthereumApi) Logs(id int, reply *interface{}) error { | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error { | ||||
| 	filter := core.NewFilter(self.xeth.Backend()) | ||||
| 	filter := core.NewFilter(self.xeth().Backend()) | ||||
| 	filter.SetOptions(toFilterOptions(args)) | ||||
| 
 | ||||
| 	*reply = toLogs(filter.Find()) | ||||
| @ -177,41 +242,54 @@ func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error { | ||||
| 	err := args.requirements() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if args.BlockNumber > 0 { | ||||
| 		*reply = p.xeth.BlockByNumber(args.BlockNumber) | ||||
| 	// This seems a bit precarious Maybe worth splitting to discrete functions
 | ||||
| 	if len(args.Hash) > 0 { | ||||
| 		*reply = p.xeth().BlockByHash(args.Hash) | ||||
| 	} else { | ||||
| 		*reply = p.xeth.BlockByHash(args.Hash) | ||||
| 		*reply = p.xeth().BlockByNumber(args.BlockNumber) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error { | ||||
| 	if len(args.Gas) == 0 { | ||||
| 		args.Gas = defaultGas | ||||
| 		args.Gas = defaultGas.String() | ||||
| 	} | ||||
| 
 | ||||
| 	if len(args.GasPrice) == 0 { | ||||
| 		args.GasPrice = defaultGasPrice | ||||
| 		args.GasPrice = defaultGasPrice.String() | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO if no_private_key then
 | ||||
| 	if _, exists := p.register[args.From]; exists { | ||||
| 		p.register[args.From] = append(p.register[args.From], args) | ||||
| 	} else { | ||||
| 		result, _ := p.xeth.Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) | ||||
| 		*reply = result | ||||
| 	} | ||||
| 	//if _, exists := p.register[args.From]; exists {
 | ||||
| 	//	p.register[args.From] = append(p.register[args.From], args)
 | ||||
| 	//} else {
 | ||||
| 	/* | ||||
| 		account := accounts.Get(fromHex(args.From)) | ||||
| 		if account != nil { | ||||
| 			if account.Unlocked() { | ||||
| 				if !unlockAccount(account) { | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			result, _ := account.Transact(fromHex(args.To), fromHex(args.Value), fromHex(args.Gas), fromHex(args.GasPrice), fromHex(args.Data)) | ||||
| 			if len(result) > 0 { | ||||
| 				*reply = toHex(result) | ||||
| 			} | ||||
| 		} else if _, exists := p.register[args.From]; exists { | ||||
| 			p.register[ags.From] = append(p.register[args.From], args) | ||||
| 		} | ||||
| 	*/ | ||||
| 	result, _ := p.xeth().Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) | ||||
| 	*reply = result | ||||
| 	//}
 | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error { | ||||
| 	result, err := p.xeth.Call( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) | ||||
| 	result, err := p.xeth().Call( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @ -225,7 +303,7 @@ func (p *EthereumApi) PushTx(args *PushTxArgs, reply *interface{}) error { | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	result, _ := p.xeth.PushTx(args.Tx) | ||||
| 	result, _ := p.xeth().PushTx(args.Tx) | ||||
| 	*reply = result | ||||
| 	return nil | ||||
| } | ||||
| @ -236,7 +314,7 @@ func (p *EthereumApi) GetStateAt(args *GetStateArgs, reply *interface{}) error { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	state := p.xeth.State().SafeGet(args.Address) | ||||
| 	state := p.xeth().State().SafeGet(args.Address) | ||||
| 
 | ||||
| 	value := state.StorageString(args.Key) | ||||
| 	var hx string | ||||
| @ -258,42 +336,55 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageArgs, reply *interface{}) err | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	*reply = p.xeth.State().SafeGet(args.Address).Storage() | ||||
| 	*reply = p.xeth().State().SafeGet(args.Address).Storage() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetPeerCount(reply *interface{}) error { | ||||
| 	*reply = p.xeth.PeerCount() | ||||
| 	*reply = p.xeth().PeerCount() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetIsListening(reply *interface{}) error { | ||||
| 	*reply = p.xeth.IsListening() | ||||
| 	*reply = p.xeth().IsListening() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetCoinbase(reply *interface{}) error { | ||||
| 	*reply = p.xeth.Coinbase() | ||||
| 	*reply = p.xeth().Coinbase() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) Accounts(reply *interface{}) error { | ||||
| 	*reply = p.xeth.Accounts() | ||||
| 	*reply = p.xeth().Accounts() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetIsMining(reply *interface{}) error { | ||||
| 	*reply = p.xeth.IsMining() | ||||
| 	*reply = p.xeth().IsMining() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) SetMining(shouldmine bool, reply *interface{}) error { | ||||
| 	*reply = p.xeth.SetMining(shouldmine) | ||||
| 	*reply = p.xeth().SetMining(shouldmine) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetDefaultBlockAge(reply *interface{}) error { | ||||
| 	*reply = p.defaultBlockAge | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) SetDefaultBlockAge(defaultBlockAge int64, reply *interface{}) error { | ||||
| 	p.defaultBlockAge = defaultBlockAge | ||||
| 	p.setStateByBlockNumber(p.defaultBlockAge) | ||||
| 
 | ||||
| 	*reply = true | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) BlockNumber(reply *interface{}) error { | ||||
| 	*reply = p.xeth.Backend().ChainManager().CurrentBlock().Number() | ||||
| 	*reply = p.xeth().Backend().ChainManager().CurrentBlock().Number() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -302,7 +393,7 @@ func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) err | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	*reply = p.xeth.TxCountAt(args.Address) | ||||
| 	*reply = p.xeth().TxCountAt(args.Address) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -311,7 +402,7 @@ func (p *EthereumApi) GetBalanceAt(args *GetBalanceArgs, reply *interface{}) err | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	state := p.xeth.State().SafeGet(args.Address) | ||||
| 	state := p.xeth().State().SafeGet(args.Address) | ||||
| 	*reply = toHex(state.Balance().Bytes()) | ||||
| 	return nil | ||||
| } | ||||
| @ -321,7 +412,7 @@ func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error { | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	*reply = p.xeth.CodeAt(args.Address) | ||||
| 	*reply = p.xeth().CodeAt(args.Address) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -368,7 +459,7 @@ func (p *EthereumApi) DbGet(args *DbArgs, reply *interface{}) error { | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error { | ||||
| 	*reply = p.xeth.Whisper().NewIdentity() | ||||
| 	*reply = p.xeth().Whisper().NewIdentity() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -377,12 +468,10 @@ func (p *EthereumApi) NewWhisperFilter(args *xeth.Options, reply *interface{}) e | ||||
| 	args.Fn = func(msg xeth.WhisperMessage) { | ||||
| 		p.messagesMut.Lock() | ||||
| 		defer p.messagesMut.Unlock() | ||||
| 		if p.messages[id] == nil { | ||||
| 			p.messages[id] = &whisperFilter{timeout: time.Now()} | ||||
| 		} | ||||
| 		p.messages[id].add(msg) // = append(p.messages[id], msg)
 | ||||
| 	} | ||||
| 	id = p.xeth.Whisper().Watch(args) | ||||
| 	id = p.xeth().Whisper().Watch(args) | ||||
| 	p.messages[id] = &whisperFilter{timeout: time.Now()} | ||||
| 	*reply = id | ||||
| 	return nil | ||||
| } | ||||
| @ -399,7 +488,7 @@ func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error { | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) error { | ||||
| 	err := p.xeth.Whisper().Post(args.Payload, args.To, args.From, args.Topic, args.Priority, args.Ttl) | ||||
| 	err := p.xeth().Whisper().Post(args.Payload, args.To, args.From, args.Topic, args.Priority, args.Ttl) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @ -409,17 +498,17 @@ func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) HasWhisperIdentity(args string, reply *interface{}) error { | ||||
| 	*reply = p.xeth.Whisper().HasIdentity(args) | ||||
| 	*reply = p.xeth().Whisper().HasIdentity(args) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error { | ||||
| 	*reply = p.xeth.Whisper().Messages(id) | ||||
| 	*reply = p.xeth().Whisper().Messages(id) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { | ||||
| 	// Spec at https://github.com/ethereum/wiki/wiki/Generic-ON-RPC
 | ||||
| 	// Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC
 | ||||
| 	rpclogger.DebugDetailf("%T %s", req.Params, req.Params) | ||||
| 	switch req.Method { | ||||
| 	case "eth_coinbase": | ||||
| @ -434,6 +523,14 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error | ||||
| 			return err | ||||
| 		} | ||||
| 		return p.SetMining(args, reply) | ||||
| 	case "eth_defaultBlock": | ||||
| 		return p.GetDefaultBlockAge(reply) | ||||
| 	case "eth_setDefaultBlock": | ||||
| 		args, err := req.ToIntArgs() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		return p.SetDefaultBlockAge(int64(args), reply) | ||||
| 	case "eth_peerCount": | ||||
| 		return p.GetPeerCount(reply) | ||||
| 	case "eth_number": | ||||
| @ -525,7 +622,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error | ||||
| 		} | ||||
| 		return p.AllLogs(args, reply) | ||||
| 	case "eth_gasPrice": | ||||
| 		*reply = defaultGasPrice | ||||
| 		*reply = toHex(defaultGasPrice.Bytes()) | ||||
| 		return nil | ||||
| 	case "eth_register": | ||||
| 		args, err := req.ToRegisterArgs() | ||||
| @ -604,42 +701,34 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error | ||||
| 		} | ||||
| 		return p.WhisperMessages(args, reply) | ||||
| 	default: | ||||
| 		return NewErrorResponse(fmt.Sprintf("%v %s", ErrorNotImplemented, req.Method)) | ||||
| 		return NewErrorWithMessage(errNotImplemented, req.Method) | ||||
| 	} | ||||
| 
 | ||||
| 	rpclogger.DebugDetailf("Reply: %T %s", reply, reply) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| var filterTickerTime = 15 * time.Second | ||||
| func (self *EthereumApi) xeth() *xeth.XEth { | ||||
| 	self.xethMu.RLock() | ||||
| 	defer self.xethMu.RUnlock() | ||||
| 
 | ||||
| func (self *EthereumApi) start() { | ||||
| 	timer := time.NewTicker(filterTickerTime) | ||||
| done: | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-timer.C: | ||||
| 			self.logMut.Lock() | ||||
| 			self.messagesMut.Lock() | ||||
| 			for id, filter := range self.logs { | ||||
| 				if time.Since(filter.timeout) > 20*time.Second { | ||||
| 					delete(self.logs, id) | ||||
| 				} | ||||
| 			} | ||||
| 	return self.eth | ||||
| } | ||||
| 
 | ||||
| 			for id, filter := range self.messages { | ||||
| 				if time.Since(filter.timeout) > 20*time.Second { | ||||
| 					delete(self.messages, id) | ||||
| 				} | ||||
| 			} | ||||
| 			self.logMut.Unlock() | ||||
| 			self.messagesMut.Unlock() | ||||
| 		case <-self.quit: | ||||
| 			break done | ||||
| 		} | ||||
| func (self *EthereumApi) useState(statedb *state.StateDB) { | ||||
| 	self.xethMu.Lock() | ||||
| 	defer self.xethMu.Unlock() | ||||
| 
 | ||||
| 	self.eth = self.eth.UseState(statedb) | ||||
| } | ||||
| 
 | ||||
| func t(f ui.Frontend) { | ||||
| 	// Call the password dialog
 | ||||
| 	ret, err := f.Call("PasswordDialog") | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) stop() { | ||||
| 	close(self.quit) | ||||
| 	// Get the first argument
 | ||||
| 	t, _ := ret.Get(0) | ||||
| 	fmt.Println("return:", t) | ||||
| } | ||||
| @ -7,6 +7,7 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| func TestFilterClose(t *testing.T) { | ||||
| 	t.Skip() | ||||
| 	api := &EthereumApi{ | ||||
| 		logs:     make(map[int]*logFilter), | ||||
| 		messages: make(map[int]*whisperFilter), | ||||
							
								
								
									
										91
									
								
								rpc/args.go
									
									
									
									
									
								
							
							
						
						
									
										91
									
								
								rpc/args.go
									
									
									
									
									
								
							| @ -19,14 +19,7 @@ func (obj *GetBlockArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		obj.Hash = argstr | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse(ErrorDecodeArgs) | ||||
| } | ||||
| 
 | ||||
| func (obj *GetBlockArgs) requirements() error { | ||||
| 	if obj.BlockNumber == 0 && obj.Hash == "" { | ||||
| 		return NewErrorResponse("GetBlock requires either a block 'number' or a block 'hash' as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| 	return errDecodeArgs | ||||
| } | ||||
| 
 | ||||
| type NewTxArgs struct { | ||||
| @ -64,7 +57,7 @@ func (obj *NewTxArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	return NewErrorResponse(ErrorDecodeArgs) | ||||
| 	return errDecodeArgs | ||||
| } | ||||
| 
 | ||||
| type PushTxArgs struct { | ||||
| @ -77,12 +70,12 @@ func (obj *PushTxArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		obj.Tx = arg0 | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse(ErrorDecodeArgs) | ||||
| 	return errDecodeArgs | ||||
| } | ||||
| 
 | ||||
| func (a *PushTxArgs) requirementsPushTx() error { | ||||
| 	if a.Tx == "" { | ||||
| 		return NewErrorResponse("PushTx requires a 'tx' as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "PushTx requires a 'tx' as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @ -93,14 +86,14 @@ type GetStorageArgs struct { | ||||
| 
 | ||||
| func (obj *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 	if err = json.Unmarshal(b, &obj.Address); err != nil { | ||||
| 		return NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return errDecodeArgs | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (a *GetStorageArgs) requirements() error { | ||||
| 	if len(a.Address) == 0 { | ||||
| 		return NewErrorResponse("GetStorageAt requires an 'address' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'address' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @ -116,64 +109,39 @@ func (obj *GetStateArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		obj.Address = arg0 | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse(ErrorDecodeArgs) | ||||
| 	return errDecodeArgs | ||||
| } | ||||
| 
 | ||||
| func (a *GetStateArgs) requirements() error { | ||||
| 	if a.Address == "" { | ||||
| 		return NewErrorResponse("GetStorageAt requires an 'address' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'address' value as argument") | ||||
| 	} | ||||
| 	if a.Key == "" { | ||||
| 		return NewErrorResponse("GetStorageAt requires an 'key' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'key' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| type GetStorageAtRes struct { | ||||
| 	Key   string `json:"key"` | ||||
| 	Value string `json:"value"` | ||||
| } | ||||
| 
 | ||||
| type GetTxCountArgs struct { | ||||
| 	Address string `json:"address"` | ||||
| } | ||||
| 
 | ||||
| // type GetTxCountRes struct {
 | ||||
| //  Nonce int `json:"nonce"`
 | ||||
| // }
 | ||||
| 
 | ||||
| func (obj *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 	arg0 := "" | ||||
| 	if err = json.Unmarshal(b, &arg0); err == nil { | ||||
| 		obj.Address = arg0 | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse("Could not determine JSON parameters") | ||||
| 	return errDecodeArgs | ||||
| } | ||||
| 
 | ||||
| func (a *GetTxCountArgs) requirements() error { | ||||
| 	if a.Address == "" { | ||||
| 		return NewErrorResponse("GetTxCountAt requires an 'address' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetTxCountAt requires an 'address' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // type GetPeerCountRes struct {
 | ||||
| //  PeerCount int `json:"peerCount"`
 | ||||
| // }
 | ||||
| 
 | ||||
| // type GetListeningRes struct {
 | ||||
| //  IsListening bool `json:"isListening"`
 | ||||
| // }
 | ||||
| 
 | ||||
| // type GetCoinbaseRes struct {
 | ||||
| //  Coinbase string `json:"coinbase"`
 | ||||
| // }
 | ||||
| 
 | ||||
| // type GetMiningRes struct {
 | ||||
| //  IsMining bool `json:"isMining"`
 | ||||
| // }
 | ||||
| 
 | ||||
| type GetBalanceArgs struct { | ||||
| 	Address string | ||||
| } | ||||
| @ -184,21 +152,16 @@ func (obj *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		obj.Address = arg0 | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse("Could not determine JSON parameters") | ||||
| 	return errDecodeArgs | ||||
| } | ||||
| 
 | ||||
| func (a *GetBalanceArgs) requirements() error { | ||||
| 	if a.Address == "" { | ||||
| 		return NewErrorResponse("GetBalanceAt requires an 'address' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetBalanceAt requires an 'address' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| type BalanceRes struct { | ||||
| 	Balance string `json:"balance"` | ||||
| 	Address string `json:"address"` | ||||
| } | ||||
| 
 | ||||
| type GetCodeAtArgs struct { | ||||
| 	Address string | ||||
| } | ||||
| @ -209,12 +172,12 @@ func (obj *GetCodeAtArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		obj.Address = arg0 | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse(ErrorDecodeArgs) | ||||
| 	return errDecodeArgs | ||||
| } | ||||
| 
 | ||||
| func (a *GetCodeAtArgs) requirements() error { | ||||
| 	if a.Address == "" { | ||||
| 		return NewErrorResponse("GetCodeAt requires an 'address' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetCodeAt requires an 'address' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @ -225,7 +188,7 @@ type Sha3Args struct { | ||||
| 
 | ||||
| func (obj *Sha3Args) UnmarshalJSON(b []byte) (err error) { | ||||
| 	if err = json.Unmarshal(b, &obj.Data); err != nil { | ||||
| 		return NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return errDecodeArgs | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| @ -234,7 +197,7 @@ type FilterOptions struct { | ||||
| 	Earliest int64 | ||||
| 	Latest   int64 | ||||
| 	Address  interface{} | ||||
| 	Topic    []string | ||||
| 	Topic    []interface{} | ||||
| 	Skip     int | ||||
| 	Max      int | ||||
| } | ||||
| @ -257,10 +220,20 @@ func toFilterOptions(options *FilterOptions) core.FilterOptions { | ||||
| 
 | ||||
| 	opts.Earliest = options.Earliest | ||||
| 	opts.Latest = options.Latest | ||||
| 	opts.Topics = make([][]byte, len(options.Topic)) | ||||
| 	for i, topic := range options.Topic { | ||||
| 		opts.Topics[i] = fromHex(topic) | ||||
| 
 | ||||
| 	topics := make([][][]byte, len(options.Topic)) | ||||
| 	for i, topicDat := range options.Topic { | ||||
| 		if slice, ok := topicDat.([]interface{}); ok { | ||||
| 			topics[i] = make([][]byte, len(slice)) | ||||
| 			for j, topic := range slice { | ||||
| 				topics[i][j] = fromHex(topic.(string)) | ||||
| 			} | ||||
| 		} else if str, ok := topicDat.(string); ok { | ||||
| 			topics[i] = make([][]byte, 1) | ||||
| 			topics[i][0] = fromHex(str) | ||||
| 		} | ||||
| 	} | ||||
| 	opts.Topics = topics | ||||
| 
 | ||||
| 	return opts | ||||
| } | ||||
| @ -277,10 +250,10 @@ type DbArgs struct { | ||||
| 
 | ||||
| func (a *DbArgs) requirements() error { | ||||
| 	if len(a.Database) == 0 { | ||||
| 		return NewErrorResponse("DbPutArgs requires an 'Database' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "DbPutArgs requires an 'Database' value as argument") | ||||
| 	} | ||||
| 	if len(a.Key) == 0 { | ||||
| 		return NewErrorResponse("DbPutArgs requires an 'Key' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "DbPutArgs requires an 'Key' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -29,8 +29,8 @@ import ( | ||||
| var rpchttplogger = logger.NewLogger("RPC-HTTP") | ||||
| var JSON rpc.JsonWrapper | ||||
| 
 | ||||
| func NewRpcHttpServer(pipe *xeth.XEth, port int) (*RpcHttpServer, error) { | ||||
| 	sport := fmt.Sprintf("127.0.0.1:%d", port) | ||||
| func NewRpcHttpServer(pipe *xeth.XEth, address string, port int) (*RpcHttpServer, error) { | ||||
| 	sport := fmt.Sprintf("%s:%d", address, port) | ||||
| 	l, err := net.Listen("tcp", sport) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| @ -41,6 +41,7 @@ func NewRpcHttpServer(pipe *xeth.XEth, port int) (*RpcHttpServer, error) { | ||||
| 		quit:     make(chan bool), | ||||
| 		pipe:     pipe, | ||||
| 		port:     port, | ||||
| 		addr:     address, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| @ -49,6 +50,7 @@ type RpcHttpServer struct { | ||||
| 	listener net.Listener | ||||
| 	pipe     *xeth.XEth | ||||
| 	port     int | ||||
| 	addr     string | ||||
| } | ||||
| 
 | ||||
| func (s *RpcHttpServer) exitHandler() { | ||||
| @ -69,7 +71,7 @@ func (s *RpcHttpServer) Stop() { | ||||
| } | ||||
| 
 | ||||
| func (s *RpcHttpServer) Start() { | ||||
| 	rpchttplogger.Infof("Starting RPC-HTTP server on port %d", s.port) | ||||
| 	rpchttplogger.Infof("Starting RPC-HTTP server on %s:%d", s.addr, s.port) | ||||
| 	go s.exitHandler() | ||||
| 
 | ||||
| 	api := rpc.NewEthereumApi(s.pipe) | ||||
| @ -92,7 +94,7 @@ func (s *RpcHttpServer) apiHandler(api *rpc.EthereumApi) http.Handler { | ||||
| 
 | ||||
| 		reqParsed, reqerr := JSON.ParseRequestBody(req) | ||||
| 		if reqerr != nil { | ||||
| 			jsonerr := &rpc.RpcErrorObject{-32700, rpc.ErrorParseRequest} | ||||
| 			jsonerr := &rpc.RpcErrorObject{-32700, "Error: Could not parse request"} | ||||
| 			JSON.Send(w, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| @ -25,12 +25,11 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/xeth" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	ErrorArguments      = "Error: Insufficient arguments" | ||||
| 	ErrorNotImplemented = "Error: Method not implemented" | ||||
| 	ErrorUnknown        = "Error: Unknown error" | ||||
| 	ErrorParseRequest   = "Error: Could not parse request" | ||||
| 	ErrorDecodeArgs     = "Error: Could not decode arguments" | ||||
| var ( | ||||
| 	errArguments      = errors.New("Error: Insufficient arguments") | ||||
| 	errNotImplemented = errors.New("Error: Method not implemented") | ||||
| 	errUnknown        = errors.New("Error: Unknown error") | ||||
| 	errDecodeArgs     = errors.New("Error: Could not decode arguments") | ||||
| ) | ||||
| 
 | ||||
| type RpcRequest struct { | ||||
| @ -58,76 +57,72 @@ type RpcErrorObject struct { | ||||
| 	// Data    interface{} `json:"data"`
 | ||||
| } | ||||
| 
 | ||||
| func NewErrorResponse(msg string) error { | ||||
| 	return errors.New(msg) | ||||
| } | ||||
| 
 | ||||
| func NewErrorResponseWithError(msg string, err error) error { | ||||
| 	return fmt.Errorf("%s: %v", msg, err) | ||||
| func NewErrorWithMessage(err error, msg string) error { | ||||
| 	return fmt.Errorf("%s: %s", err.Error(), msg) | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToSha3Args() (*Sha3Args, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(Sha3Args) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	if err := json.NewDecoder(r).Decode(args); err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToGetBlockArgs() (*GetBlockArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetBlockArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToNewTxArgs() (*NewTxArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(NewTxArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToPushTxArgs() (*PushTxArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(PushTxArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToGetStateArgs() (*GetStateArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetStateArgs) | ||||
| @ -135,234 +130,241 @@ func (req *RpcRequest) ToGetStateArgs() (*GetStateArgs, error) { | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToStorageAtArgs() (*GetStorageArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetStorageArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToGetTxCountArgs() (*GetTxCountArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetTxCountArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToGetBalanceArgs() (*GetBalanceArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetBalanceArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToGetCodeAtArgs() (*GetCodeAtArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetCodeAtArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToBoolArgs() (bool, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return false, NewErrorResponse(ErrorArguments) | ||||
| 		return false, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args bool | ||||
| 	err := json.Unmarshal(req.Params[0], &args) | ||||
| 	if err != nil { | ||||
| 		return false, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return false, errDecodeArgs | ||||
| 	} | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToIntArgs() (int, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return 0, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args int | ||||
| 	if err := json.Unmarshal(req.Params[0], &args); err != nil { | ||||
| 		return 0, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToCompileArgs() (string, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return "", NewErrorResponse(ErrorArguments) | ||||
| 		return "", errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args string | ||||
| 	err := json.Unmarshal(req.Params[0], &args) | ||||
| 	if err != nil { | ||||
| 		return "", NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return "", errDecodeArgs | ||||
| 	} | ||||
| 
 | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToFilterArgs() (*FilterOptions, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(FilterOptions) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToFilterStringArgs() (string, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return "", NewErrorResponse(ErrorArguments) | ||||
| 		return "", errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args string | ||||
| 	err := json.Unmarshal(req.Params[0], &args) | ||||
| 	if err != nil { | ||||
| 		return "", NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return "", errDecodeArgs | ||||
| 	} | ||||
| 
 | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToUninstallFilterArgs() (int, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return 0, NewErrorResponse(ErrorArguments) | ||||
| 		return 0, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args int | ||||
| 	err := json.Unmarshal(req.Params[0], &args) | ||||
| 	if err != nil { | ||||
| 		return 0, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return 0, errDecodeArgs | ||||
| 	} | ||||
| 
 | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToFilterChangedArgs() (int, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return 0, NewErrorResponse(ErrorArguments) | ||||
| 		return 0, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var id int | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(&id) | ||||
| 	if err != nil { | ||||
| 		return 0, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return 0, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", id, id) | ||||
| 	return id, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToDbPutArgs() (*DbArgs, error) { | ||||
| 	if len(req.Params) < 3 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args DbArgs | ||||
| 	err := json.Unmarshal(req.Params[0], &args.Database) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	err = json.Unmarshal(req.Params[1], &args.Key) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	err = json.Unmarshal(req.Params[2], &args.Value) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return &args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToDbGetArgs() (*DbArgs, error) { | ||||
| 	if len(req.Params) < 2 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args DbArgs | ||||
| 	err := json.Unmarshal(req.Params[0], &args.Database) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	err = json.Unmarshal(req.Params[1], &args.Key) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return &args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToWhisperFilterArgs() (*xeth.Options, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args xeth.Options | ||||
| 	err := json.Unmarshal(req.Params[0], &args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return &args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToIdArgs() (int, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return 0, NewErrorResponse(ErrorArguments) | ||||
| 		return 0, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var id int | ||||
| 	err := json.Unmarshal(req.Params[0], &id) | ||||
| 	if err != nil { | ||||
| 		return 0, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return 0, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", id, id) | ||||
| 
 | ||||
| 	return id, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToWhisperPostArgs() (*WhisperMessageArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args WhisperMessageArgs | ||||
| @ -370,13 +372,13 @@ func (req *RpcRequest) ToWhisperPostArgs() (*WhisperMessageArgs, error) { | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return &args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return "", NewErrorResponse(ErrorArguments) | ||||
| 		return "", errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args string | ||||
| @ -384,13 +386,13 @@ func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) { | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToRegisterArgs() (string, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return "", NewErrorResponse(ErrorArguments) | ||||
| 		return "", errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args string | ||||
| @ -398,13 +400,13 @@ func (req *RpcRequest) ToRegisterArgs() (string, error) { | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToWatchTxArgs() (string, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return "", NewErrorResponse(ErrorArguments) | ||||
| 		return "", errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args string | ||||
| @ -412,6 +414,6 @@ func (req *RpcRequest) ToWatchTxArgs() (string, error) { | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| @ -82,7 +82,7 @@ type RpcServer interface { | ||||
| 
 | ||||
| type Log struct { | ||||
| 	Address string   `json:"address"` | ||||
| 	Topic   []string `json:"topics"` | ||||
| 	Topic   []string `json:"topic"` | ||||
| 	Data    string   `json:"data"` | ||||
| 	Number  uint64   `json:"number"` | ||||
| } | ||||
| @ -108,6 +108,7 @@ func toLogs(logs state.Logs) (ls []Log) { | ||||
| type whisperFilter struct { | ||||
| 	messages []xeth.WhisperMessage | ||||
| 	timeout  time.Time | ||||
| 	id       int | ||||
| } | ||||
| 
 | ||||
| func (w *whisperFilter) add(msgs ...xeth.WhisperMessage) { | ||||
| @ -123,6 +124,7 @@ func (w *whisperFilter) get() []xeth.WhisperMessage { | ||||
| type logFilter struct { | ||||
| 	logs    state.Logs | ||||
| 	timeout time.Time | ||||
| 	id      int | ||||
| } | ||||
| 
 | ||||
| func (l *logFilter) add(logs ...state.Log) { | ||||
|  | ||||
							
								
								
									
										121
									
								
								rpc/ws/server.go
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								rpc/ws/server.go
									
									
									
									
									
								
							| @ -1,121 +0,0 @@ | ||||
| /* | ||||
|   This file is part of go-ethereum | ||||
| 
 | ||||
|   go-ethereum is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
| 
 | ||||
|   go-ethereum 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 General Public License for more details. | ||||
| 
 | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with go-ethereum.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| package rpcws | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 
 | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/rpc" | ||||
| 	"github.com/ethereum/go-ethereum/xeth" | ||||
| 	"golang.org/x/net/websocket" | ||||
| ) | ||||
| 
 | ||||
| var wslogger = logger.NewLogger("RPC-WS") | ||||
| var JSON rpc.JsonWrapper | ||||
| 
 | ||||
| type WebSocketServer struct { | ||||
| 	pipe     *xeth.XEth | ||||
| 	port     int | ||||
| 	doneCh   chan bool | ||||
| 	listener net.Listener | ||||
| } | ||||
| 
 | ||||
| func NewWebSocketServer(pipe *xeth.XEth, port int) (*WebSocketServer, error) { | ||||
| 	sport := fmt.Sprintf(":%d", port) | ||||
| 	l, err := net.Listen("tcp", sport) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return &WebSocketServer{ | ||||
| 		pipe, | ||||
| 		port, | ||||
| 		make(chan bool), | ||||
| 		l, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (self *WebSocketServer) handlerLoop() { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-self.doneCh: | ||||
| 			wslogger.Infoln("Shutdown RPC-WS server") | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *WebSocketServer) Stop() { | ||||
| 	close(self.doneCh) | ||||
| } | ||||
| 
 | ||||
| func (self *WebSocketServer) Start() { | ||||
| 	wslogger.Infof("Starting RPC-WS server on port %d", self.port) | ||||
| 	go self.handlerLoop() | ||||
| 
 | ||||
| 	api := rpc.NewEthereumApi(self.pipe) | ||||
| 	h := self.apiHandler(api) | ||||
| 	http.Handle("/ws", h) | ||||
| 
 | ||||
| 	err := http.Serve(self.listener, nil) | ||||
| 	if err != nil { | ||||
| 		wslogger.Errorln("Error on RPC-WS interface:", err) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (s *WebSocketServer) apiHandler(api *rpc.EthereumApi) http.Handler { | ||||
| 	fn := func(w http.ResponseWriter, req *http.Request) { | ||||
| 		h := sockHandler(api) | ||||
| 		s := websocket.Server{Handler: h} | ||||
| 		s.ServeHTTP(w, req) | ||||
| 	} | ||||
| 
 | ||||
| 	return http.HandlerFunc(fn) | ||||
| } | ||||
| 
 | ||||
| func sockHandler(api *rpc.EthereumApi) websocket.Handler { | ||||
| 	var jsonrpcver string = "2.0" | ||||
| 	fn := func(conn *websocket.Conn) { | ||||
| 		for { | ||||
| 			wslogger.Debugln("Handling connection") | ||||
| 			var reqParsed rpc.RpcRequest | ||||
| 
 | ||||
| 			// reqParsed, reqerr := JSON.ParseRequestBody(conn.Request())
 | ||||
| 			if err := websocket.JSON.Receive(conn, &reqParsed); err != nil { | ||||
| 				jsonerr := &rpc.RpcErrorObject{-32700, rpc.ErrorParseRequest} | ||||
| 				JSON.Send(conn, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			var response interface{} | ||||
| 			reserr := api.GetRequestReply(&reqParsed, &response) | ||||
| 			if reserr != nil { | ||||
| 				wslogger.Warnln(reserr) | ||||
| 				jsonerr := &rpc.RpcErrorObject{-32603, reserr.Error()} | ||||
| 				JSON.Send(conn, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Error: jsonerr}) | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			wslogger.Debugf("Generated response: %T %s", response, response) | ||||
| 			JSON.Send(conn, &rpc.RpcSuccessResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Result: response}) | ||||
| 		} | ||||
| 	} | ||||
| 	return websocket.Handler(fn) | ||||
| } | ||||
| @ -20,7 +20,7 @@ type World struct { | ||||
| 	Accounts map[string]Account `json:"accounts"` | ||||
| } | ||||
| 
 | ||||
| func (self *StateDB) Dump() []byte { | ||||
| func (self *StateDB) RawDump() World { | ||||
| 	world := World{ | ||||
| 		Root:     ethutil.Bytes2Hex(self.trie.Root()), | ||||
| 		Accounts: make(map[string]Account), | ||||
| @ -35,12 +35,15 @@ func (self *StateDB) Dump() []byte { | ||||
| 
 | ||||
| 		storageIt := stateObject.State.trie.Iterator() | ||||
| 		for storageIt.Next() { | ||||
| 			account.Storage[ethutil.Bytes2Hex(it.Key)] = ethutil.Bytes2Hex(it.Value) | ||||
| 			account.Storage[ethutil.Bytes2Hex(storageIt.Key)] = ethutil.Bytes2Hex(storageIt.Value) | ||||
| 		} | ||||
| 		world.Accounts[ethutil.Bytes2Hex(it.Key)] = account | ||||
| 	} | ||||
| 	return world | ||||
| } | ||||
| 
 | ||||
| 	json, err := json.MarshalIndent(world, "", "    ") | ||||
| func (self *StateDB) Dump() []byte { | ||||
| 	json, err := json.MarshalIndent(self.RawDump(), "", "    ") | ||||
| 	if err != nil { | ||||
| 		fmt.Println("dump err", err) | ||||
| 	} | ||||
|  | ||||
| @ -19,6 +19,14 @@ func (self Code) String() string { | ||||
| 
 | ||||
| type Storage map[string]*ethutil.Value | ||||
| 
 | ||||
| func (self Storage) String() (str string) { | ||||
| 	for key, value := range self { | ||||
| 		str += fmt.Sprintf("%X : %X\n", key, value.Bytes()) | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (self Storage) Copy() Storage { | ||||
| 	cpy := make(Storage) | ||||
| 	for key, value := range self { | ||||
| @ -119,10 +127,9 @@ func (self *StateObject) GetStorage(key *big.Int) *ethutil.Value { | ||||
| } | ||||
| func (self *StateObject) SetStorage(key *big.Int, value *ethutil.Value) { | ||||
| 	self.SetState(key.Bytes(), value) | ||||
| 	self.dirty = true | ||||
| } | ||||
| 
 | ||||
| func (self *StateObject) Storage() map[string]*ethutil.Value { | ||||
| func (self *StateObject) Storage() Storage { | ||||
| 	return self.storage | ||||
| } | ||||
| 
 | ||||
| @ -172,20 +179,22 @@ func (c *StateObject) AddBalance(amount *big.Int) { | ||||
| 
 | ||||
| 	statelogger.Debugf("%x: #%d %v (+ %v)\n", c.Address(), c.nonce, c.balance, amount) | ||||
| } | ||||
| func (c *StateObject) AddAmount(amount *big.Int) { c.AddBalance(amount) } | ||||
| 
 | ||||
| func (c *StateObject) SubBalance(amount *big.Int) { | ||||
| 	c.SetBalance(new(big.Int).Sub(c.balance, amount)) | ||||
| 
 | ||||
| 	statelogger.Debugf("%x: #%d %v (- %v)\n", c.Address(), c.nonce, c.balance, amount) | ||||
| } | ||||
| func (c *StateObject) SubAmount(amount *big.Int) { c.SubBalance(amount) } | ||||
| 
 | ||||
| func (c *StateObject) SetBalance(amount *big.Int) { | ||||
| 	c.balance = amount | ||||
| 	c.dirty = true | ||||
| } | ||||
| 
 | ||||
| func (c *StateObject) St() Storage { | ||||
| 	return c.storage | ||||
| } | ||||
| 
 | ||||
| //
 | ||||
| // Gas setters and getters
 | ||||
| //
 | ||||
| @ -198,7 +207,7 @@ func (c *StateObject) ConvertGas(gas, price *big.Int) error { | ||||
| 		return fmt.Errorf("insufficient amount: %v, %v", c.balance, total) | ||||
| 	} | ||||
| 
 | ||||
| 	c.SubAmount(total) | ||||
| 	c.SubBalance(total) | ||||
| 
 | ||||
| 	c.dirty = true | ||||
| 
 | ||||
| @ -221,7 +230,7 @@ func (self *StateObject) BuyGas(gas, price *big.Int) error { | ||||
| 	rGas := new(big.Int).Set(gas) | ||||
| 	rGas.Mul(rGas, price) | ||||
| 
 | ||||
| 	self.AddAmount(rGas) | ||||
| 	self.AddBalance(rGas) | ||||
| 
 | ||||
| 	self.dirty = true | ||||
| 
 | ||||
|  | ||||
| @ -54,7 +54,7 @@ func (self *StateDB) Refund(addr []byte, gas *big.Int) { | ||||
| 
 | ||||
| // Retrieve the balance from the given address or 0 if object not found
 | ||||
| func (self *StateDB) GetBalance(addr []byte) *big.Int { | ||||
| 	stateObject := self.GetStateObject(addr) | ||||
| 	stateObject := self.GetOrNewStateObject(addr) | ||||
| 	if stateObject != nil { | ||||
| 		return stateObject.balance | ||||
| 	} | ||||
| @ -63,14 +63,14 @@ func (self *StateDB) GetBalance(addr []byte) *big.Int { | ||||
| } | ||||
| 
 | ||||
| func (self *StateDB) AddBalance(addr []byte, amount *big.Int) { | ||||
| 	stateObject := self.GetStateObject(addr) | ||||
| 	stateObject := self.GetOrNewStateObject(addr) | ||||
| 	if stateObject != nil { | ||||
| 		stateObject.AddBalance(amount) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *StateDB) GetNonce(addr []byte) uint64 { | ||||
| 	stateObject := self.GetStateObject(addr) | ||||
| 	stateObject := self.GetOrNewStateObject(addr) | ||||
| 	if stateObject != nil { | ||||
| 		return stateObject.nonce | ||||
| 	} | ||||
| @ -79,7 +79,7 @@ func (self *StateDB) GetNonce(addr []byte) uint64 { | ||||
| } | ||||
| 
 | ||||
| func (self *StateDB) GetCode(addr []byte) []byte { | ||||
| 	stateObject := self.GetStateObject(addr) | ||||
| 	stateObject := self.GetOrNewStateObject(addr) | ||||
| 	if stateObject != nil { | ||||
| 		return stateObject.code | ||||
| 	} | ||||
| @ -88,7 +88,7 @@ func (self *StateDB) GetCode(addr []byte) []byte { | ||||
| } | ||||
| 
 | ||||
| func (self *StateDB) GetState(a, b []byte) []byte { | ||||
| 	stateObject := self.GetStateObject(a) | ||||
| 	stateObject := self.GetOrNewStateObject(a) | ||||
| 	if stateObject != nil { | ||||
| 		return stateObject.GetState(b).Bytes() | ||||
| 	} | ||||
| @ -97,28 +97,28 @@ func (self *StateDB) GetState(a, b []byte) []byte { | ||||
| } | ||||
| 
 | ||||
| func (self *StateDB) SetNonce(addr []byte, nonce uint64) { | ||||
| 	stateObject := self.GetStateObject(addr) | ||||
| 	stateObject := self.GetOrNewStateObject(addr) | ||||
| 	if stateObject != nil { | ||||
| 		stateObject.SetNonce(nonce) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *StateDB) SetCode(addr, code []byte) { | ||||
| 	stateObject := self.GetStateObject(addr) | ||||
| 	stateObject := self.GetOrNewStateObject(addr) | ||||
| 	if stateObject != nil { | ||||
| 		stateObject.SetCode(code) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *StateDB) SetState(addr, key []byte, value interface{}) { | ||||
| 	stateObject := self.GetStateObject(addr) | ||||
| 	stateObject := self.GetOrNewStateObject(addr) | ||||
| 	if stateObject != nil { | ||||
| 		stateObject.SetState(key, ethutil.NewValue(value)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *StateDB) Delete(addr []byte) bool { | ||||
| 	stateObject := self.GetStateObject(addr) | ||||
| 	stateObject := self.GetOrNewStateObject(addr) | ||||
| 	if stateObject != nil { | ||||
| 		stateObject.MarkForDeletion() | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										76
									
								
								ui/filter.go
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								ui/filter.go
									
									
									
									
									
								
							| @ -1,77 +1 @@ | ||||
| package ui | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/ethereum/go-ethereum/core" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| ) | ||||
| 
 | ||||
| func fromHex(s string) []byte { | ||||
| 	if len(s) > 1 { | ||||
| 		if s[0:2] == "0x" { | ||||
| 			s = s[2:] | ||||
| 		} | ||||
| 		return ethutil.Hex2Bytes(s) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func NewFilterFromMap(object map[string]interface{}, eth core.Backend) *core.Filter { | ||||
| 	filter := core.NewFilter(eth) | ||||
| 
 | ||||
| 	if object["earliest"] != nil { | ||||
| 		val := ethutil.NewValue(object["earliest"]) | ||||
| 		filter.SetEarliestBlock(val.Int()) | ||||
| 	} | ||||
| 
 | ||||
| 	if object["latest"] != nil { | ||||
| 		val := ethutil.NewValue(object["latest"]) | ||||
| 		filter.SetLatestBlock(val.Int()) | ||||
| 	} | ||||
| 
 | ||||
| 	if object["address"] != nil { | ||||
| 		//val := ethutil.NewValue(object["address"])
 | ||||
| 		//filter.SetAddress(fromHex(val.Str()))
 | ||||
| 	} | ||||
| 
 | ||||
| 	if object["max"] != nil { | ||||
| 		val := ethutil.NewValue(object["max"]) | ||||
| 		filter.SetMax(int(val.Uint())) | ||||
| 	} | ||||
| 
 | ||||
| 	if object["skip"] != nil { | ||||
| 		val := ethutil.NewValue(object["skip"]) | ||||
| 		filter.SetSkip(int(val.Uint())) | ||||
| 	} | ||||
| 
 | ||||
| 	if object["topics"] != nil { | ||||
| 		filter.SetTopics(MakeTopics(object["topics"])) | ||||
| 	} | ||||
| 
 | ||||
| 	return filter | ||||
| } | ||||
| 
 | ||||
| // Conversion methodn
 | ||||
| func mapToAccountChange(m map[string]interface{}) (d core.AccountChange) { | ||||
| 	if str, ok := m["id"].(string); ok { | ||||
| 		d.Address = fromHex(str) | ||||
| 	} | ||||
| 
 | ||||
| 	if str, ok := m["at"].(string); ok { | ||||
| 		d.StateAddress = fromHex(str) | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // data can come in in the following formats:
 | ||||
| // ["aabbccdd", {id: "ccddee", at: "11223344"}], "aabbcc", {id: "ccddee", at: "1122"}
 | ||||
| func MakeTopics(v interface{}) (d [][]byte) { | ||||
| 	if str, ok := v.(string); ok { | ||||
| 		d = append(d, fromHex(str)) | ||||
| 	} else if slice, ok := v.([]string); ok { | ||||
| 		for _, item := range slice { | ||||
| 			d = append(d, fromHex(item)) | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
							
								
								
									
										18
									
								
								ui/frontend.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								ui/frontend.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| package ui | ||||
| 
 | ||||
| // ReturnInterface is returned by the Intercom interface when a method is called
 | ||||
| type ReturnInterface interface { | ||||
| 	Get(i int) (interface{}, error) | ||||
| 	Size() int | ||||
| } | ||||
| 
 | ||||
| // Frontend is the basic interface for calling arbitrary methods on something that
 | ||||
| // implements a front end (GUI, CLI, etc)
 | ||||
| type Frontend interface { | ||||
| 	// Checks whether a specific method is implemented
 | ||||
| 	Supports(method string) bool | ||||
| 	// Call calls the given method on interface it implements. This will return
 | ||||
| 	// an error with errNotImplemented if the method hasn't been implemented
 | ||||
| 	// and will return a ReturnInterface if it does.
 | ||||
| 	Call(method string) (ReturnInterface, error) | ||||
| } | ||||
| @ -1,30 +1 @@ | ||||
| package qt | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/ethereum/go-ethereum/core" | ||||
| 	"github.com/ethereum/go-ethereum/ui" | ||||
| 	"github.com/obscuren/qml" | ||||
| ) | ||||
| 
 | ||||
| func NewFilterFromMap(object map[string]interface{}, eth core.Backend) *core.Filter { | ||||
| 	filter := ui.NewFilterFromMap(object, eth) | ||||
| 
 | ||||
| 	if object["topics"] != nil { | ||||
| 		filter.SetTopics(makeTopics(object["topics"])) | ||||
| 	} | ||||
| 
 | ||||
| 	return filter | ||||
| } | ||||
| 
 | ||||
| func makeTopics(v interface{}) (d [][]byte) { | ||||
| 	if qList, ok := v.(*qml.List); ok { | ||||
| 		var s []string | ||||
| 		qList.Convert(&s) | ||||
| 
 | ||||
| 		d = ui.MakeTopics(s) | ||||
| 	} else if str, ok := v.(string); ok { | ||||
| 		d = ui.MakeTopics(str) | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
|  | ||||
							
								
								
									
										23
									
								
								vm/vm.go
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								vm/vm.go
									
									
									
									
									
								
							| @ -16,6 +16,8 @@ type Vm struct { | ||||
| 	logStr string | ||||
| 
 | ||||
| 	err error | ||||
| 	// For logging
 | ||||
| 	debug bool | ||||
| 
 | ||||
| 	Dbg Debugger | ||||
| 
 | ||||
| @ -32,7 +34,7 @@ func New(env Environment) *Vm { | ||||
| 		lt = LogTyDiff | ||||
| 	} | ||||
| 
 | ||||
| 	return &Vm{env: env, logTy: lt, Recoverable: true} | ||||
| 	return &Vm{debug: false, env: env, logTy: lt, Recoverable: true} | ||||
| } | ||||
| 
 | ||||
| func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) { | ||||
| @ -664,6 +666,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I | ||||
| 				} | ||||
| 				addr = ref.Address() | ||||
| 
 | ||||
| 				fmt.Printf("CREATE %X\n", addr) | ||||
| 				stack.Push(ethutil.BigD(addr)) | ||||
| 
 | ||||
| 			} | ||||
| @ -727,7 +730,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I | ||||
| 
 | ||||
| 			self.Printf(" => (%x) %v", receiver.Address()[:4], balance) | ||||
| 
 | ||||
| 			receiver.AddAmount(balance) | ||||
| 			receiver.AddBalance(balance) | ||||
| 			statedb.Delete(context.Address()) | ||||
| 
 | ||||
| 			fallthrough | ||||
| @ -828,7 +831,7 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo | ||||
| 			// 0 => non 0
 | ||||
| 			mult = ethutil.Big3 | ||||
| 		} else if len(val) > 0 && len(y.Bytes()) == 0 { | ||||
| 			statedb.Refund(caller.Address(), GasSStoreRefund) | ||||
| 			statedb.Refund(self.env.Origin(), GasSStoreRefund) | ||||
| 
 | ||||
| 			mult = ethutil.Big0 | ||||
| 		} else { | ||||
| @ -937,17 +940,21 @@ func (self *Vm) RunPrecompiled(p *PrecompiledAccount, callData []byte, context * | ||||
| } | ||||
| 
 | ||||
| func (self *Vm) Printf(format string, v ...interface{}) VirtualMachine { | ||||
| 	if self.logTy == LogTyPretty { | ||||
| 		self.logStr += fmt.Sprintf(format, v...) | ||||
| 	if self.debug { | ||||
| 		if self.logTy == LogTyPretty { | ||||
| 			self.logStr += fmt.Sprintf(format, v...) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return self | ||||
| } | ||||
| 
 | ||||
| func (self *Vm) Endl() VirtualMachine { | ||||
| 	if self.logTy == LogTyPretty { | ||||
| 		vmlogger.Debugln(self.logStr) | ||||
| 		self.logStr = "" | ||||
| 	if self.debug { | ||||
| 		if self.logTy == LogTyPretty { | ||||
| 			vmlogger.Debugln(self.logStr) | ||||
| 			self.logStr = "" | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return self | ||||
|  | ||||
							
								
								
									
										23
									
								
								vm/vm_jit.go
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								vm/vm_jit.go
									
									
									
									
									
								
							| @ -50,6 +50,7 @@ type RuntimeData struct { | ||||
| 	timestamp    int64 | ||||
| 	code         *byte | ||||
| 	codeSize     uint64 | ||||
| 	codeHash     i256 | ||||
| } | ||||
| 
 | ||||
| func hash2llvm(h []byte) i256 { | ||||
| @ -180,6 +181,7 @@ func (self *JitVm) Run(me, caller ContextRef, code []byte, value, gas, price *bi | ||||
| 	self.data.timestamp = self.env.Time() | ||||
| 	self.data.code = getDataPtr(code) | ||||
| 	self.data.codeSize = uint64(len(code)) | ||||
| 	self.data.codeHash = hash2llvm(crypto.Sha3(code)) // TODO: Get already computed hash?
 | ||||
| 
 | ||||
| 	jit := C.evmjit_create() | ||||
| 	retCode := C.evmjit_run(jit, unsafe.Pointer(&self.data), unsafe.Pointer(self)) | ||||
| @ -197,12 +199,12 @@ func (self *JitVm) Run(me, caller ContextRef, code []byte, value, gas, price *bi | ||||
| 			receiverAddr := llvm2hashRef(bswap(&self.data.address)) | ||||
| 			receiver := state.GetOrNewStateObject(receiverAddr) | ||||
| 			balance := state.GetBalance(me.Address()) | ||||
| 			receiver.AddAmount(balance) | ||||
| 			receiver.AddBalance(balance) | ||||
| 			state.Delete(me.Address()) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	C.evmjit_destroy(jit); | ||||
| 	C.evmjit_destroy(jit) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| @ -278,7 +280,7 @@ func env_blockhash(_vm unsafe.Pointer, _number unsafe.Pointer, _result unsafe.Po | ||||
| } | ||||
| 
 | ||||
| //export env_call
 | ||||
| func env_call(_vm unsafe.Pointer, _gas unsafe.Pointer, _receiveAddr unsafe.Pointer, _value unsafe.Pointer, inDataPtr unsafe.Pointer, inDataLen uint64, outDataPtr *byte, outDataLen uint64, _codeAddr unsafe.Pointer) bool { | ||||
| func env_call(_vm unsafe.Pointer, _gas *int64, _receiveAddr unsafe.Pointer, _value unsafe.Pointer, inDataPtr unsafe.Pointer, inDataLen uint64, outDataPtr *byte, outDataLen uint64, _codeAddr unsafe.Pointer) bool { | ||||
| 	vm := (*JitVm)(_vm) | ||||
| 
 | ||||
| 	//fmt.Printf("env_call (depth %d)\n", vm.Env().Depth())
 | ||||
| @ -297,8 +299,7 @@ func env_call(_vm unsafe.Pointer, _gas unsafe.Pointer, _receiveAddr unsafe.Point | ||||
| 		inData := C.GoBytes(inDataPtr, C.int(inDataLen)) | ||||
| 		outData := llvm2bytesRef(outDataPtr, outDataLen) | ||||
| 		codeAddr := llvm2hash((*i256)(_codeAddr)) | ||||
| 		llvmGas := (*i256)(_gas) | ||||
| 		gas := llvm2big(llvmGas) | ||||
| 		gas := big.NewInt(*_gas) | ||||
| 		var out []byte | ||||
| 		var err error | ||||
| 		if bytes.Equal(codeAddr, receiveAddr) { | ||||
| @ -306,7 +307,7 @@ func env_call(_vm unsafe.Pointer, _gas unsafe.Pointer, _receiveAddr unsafe.Point | ||||
| 		} else { | ||||
| 			out, err = vm.env.CallCode(vm.me, codeAddr, inData, gas, vm.price, value) | ||||
| 		} | ||||
| 		*llvmGas = big2llvm(gas) | ||||
| 		*_gas = gas.Int64() | ||||
| 		if err == nil { | ||||
| 			copy(outData, out) | ||||
| 			return true | ||||
| @ -317,7 +318,7 @@ func env_call(_vm unsafe.Pointer, _gas unsafe.Pointer, _receiveAddr unsafe.Point | ||||
| } | ||||
| 
 | ||||
| //export env_create
 | ||||
| func env_create(_vm unsafe.Pointer, _gas unsafe.Pointer, _value unsafe.Pointer, initDataPtr unsafe.Pointer, initDataLen uint64, _result unsafe.Pointer) { | ||||
| func env_create(_vm unsafe.Pointer, _gas *int64, _value unsafe.Pointer, initDataPtr unsafe.Pointer, initDataLen uint64, _result unsafe.Pointer) { | ||||
| 	vm := (*JitVm)(_vm) | ||||
| 
 | ||||
| 	value := llvm2big((*i256)(_value)) | ||||
| @ -325,9 +326,7 @@ func env_create(_vm unsafe.Pointer, _gas unsafe.Pointer, _value unsafe.Pointer, | ||||
| 	result := (*i256)(_result) | ||||
| 	*result = i256{} | ||||
| 
 | ||||
| 	llvmGas := (*i256)(_gas) | ||||
| 	gas := llvm2big(llvmGas) | ||||
| 
 | ||||
| 	gas := big.NewInt(*_gas) | ||||
| 	ret, suberr, ref := vm.env.Create(vm.me, nil, initData, gas, vm.price, value) | ||||
| 	if suberr == nil { | ||||
| 		dataGas := big.NewInt(int64(len(ret))) // TODO: Nto the best design. env.Create can do it, it has the reference to gas counter
 | ||||
| @ -335,7 +334,7 @@ func env_create(_vm unsafe.Pointer, _gas unsafe.Pointer, _value unsafe.Pointer, | ||||
| 		gas.Sub(gas, dataGas) | ||||
| 		*result = hash2llvm(ref.Address()) | ||||
| 	} | ||||
| 	*llvmGas = big2llvm(gas) | ||||
| 	*_gas = gas.Int64() | ||||
| } | ||||
| 
 | ||||
| //export env_log
 | ||||
| @ -358,7 +357,7 @@ func env_log(_vm unsafe.Pointer, dataPtr unsafe.Pointer, dataLen uint64, _topic1 | ||||
| 		topics = append(topics, llvm2hash((*i256)(_topic4))) | ||||
| 	} | ||||
| 
 | ||||
| 	vm.Env().AddLog(state.NewLog(vm.me.Address(), topics, data)) | ||||
| 	vm.Env().AddLog(state.NewLog(vm.me.Address(), topics, data, vm.env.BlockNumber().Uint64())) | ||||
| } | ||||
| 
 | ||||
| //export env_extcode
 | ||||
|  | ||||
| @ -127,6 +127,10 @@ func (self *Whisper) Watch(opts Filter) int { | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (self *Whisper) Unwatch(id int) { | ||||
| 	self.filters.Uninstall(id) | ||||
| } | ||||
| 
 | ||||
| func (self *Whisper) Messages(id int) (messages []*Message) { | ||||
| 	filter := self.filters.Get(id) | ||||
| 	if filter != nil { | ||||
|  | ||||
| @ -3,19 +3,20 @@ package xeth | ||||
| import "github.com/ethereum/go-ethereum/state" | ||||
| 
 | ||||
| type State struct { | ||||
| 	xeth *XEth | ||||
| 	xeth  *XEth | ||||
| 	state *state.StateDB | ||||
| } | ||||
| 
 | ||||
| func NewState(xeth *XEth) *State { | ||||
| 	return &State{xeth} | ||||
| func NewState(xeth *XEth, statedb *state.StateDB) *State { | ||||
| 	return &State{xeth, statedb} | ||||
| } | ||||
| 
 | ||||
| func (self *State) State() *state.StateDB { | ||||
| 	return self.xeth.chainManager.TransState() | ||||
| 	return self.state | ||||
| } | ||||
| 
 | ||||
| func (self *State) Get(addr string) *Object { | ||||
| 	return &Object{self.State().GetStateObject(fromHex(addr))} | ||||
| 	return &Object{self.state.GetStateObject(fromHex(addr))} | ||||
| } | ||||
| 
 | ||||
| func (self *State) SafeGet(addr string) *Object { | ||||
| @ -23,7 +24,7 @@ func (self *State) SafeGet(addr string) *Object { | ||||
| } | ||||
| 
 | ||||
| func (self *State) safeGet(addr string) *state.StateObject { | ||||
| 	object := self.State().GetStateObject(fromHex(addr)) | ||||
| 	object := self.state.GetStateObject(fromHex(addr)) | ||||
| 	if object == nil { | ||||
| 		object = state.NewStateObject(fromHex(addr), self.xeth.eth.Db()) | ||||
| 	} | ||||
							
								
								
									
										32
									
								
								xeth/xeth.go
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								xeth/xeth.go
									
									
									
									
									
								
							| @ -17,6 +17,7 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/miner" | ||||
| 	"github.com/ethereum/go-ethereum/p2p" | ||||
| 	"github.com/ethereum/go-ethereum/state" | ||||
| 	"github.com/ethereum/go-ethereum/whisper" | ||||
| ) | ||||
| 
 | ||||
| @ -54,13 +55,26 @@ func New(eth Backend) *XEth { | ||||
| 		whisper:        NewWhisper(eth.Whisper()), | ||||
| 		miner:          eth.Miner(), | ||||
| 	} | ||||
| 	xeth.state = NewState(xeth) | ||||
| 	xeth.state = NewState(xeth, xeth.chainManager.TransState()) | ||||
| 
 | ||||
| 	return xeth | ||||
| } | ||||
| 
 | ||||
| func (self *XEth) Backend() Backend    { return self.eth } | ||||
| func (self *XEth) State() *State       { return self.state } | ||||
| func (self *XEth) Backend() Backend { return self.eth } | ||||
| func (self *XEth) UseState(statedb *state.StateDB) *XEth { | ||||
| 	xeth := &XEth{ | ||||
| 		eth:            self.eth, | ||||
| 		blockProcessor: self.blockProcessor, | ||||
| 		chainManager:   self.chainManager, | ||||
| 		whisper:        self.whisper, | ||||
| 		miner:          self.miner, | ||||
| 	} | ||||
| 
 | ||||
| 	xeth.state = NewState(xeth, statedb) | ||||
| 	return xeth | ||||
| } | ||||
| func (self *XEth) State() *State { return self.state } | ||||
| 
 | ||||
| func (self *XEth) Whisper() *Whisper   { return self.whisper } | ||||
| func (self *XEth) Miner() *miner.Miner { return self.miner } | ||||
| 
 | ||||
| @ -229,7 +243,7 @@ func (self *XEth) Call(toStr, valueStr, gasStr, gasPriceStr, dataStr string) (st | ||||
| 	} | ||||
| 
 | ||||
| 	var ( | ||||
| 		statedb = self.chainManager.TransState() | ||||
| 		statedb = self.State().State() //self.chainManager.TransState()
 | ||||
| 		key     = self.eth.KeyManager().KeyPair() | ||||
| 		from    = statedb.GetOrNewStateObject(key.Address()) | ||||
| 		block   = self.chainManager.CurrentBlock() | ||||
| @ -277,7 +291,7 @@ func (self *XEth) Transact(toStr, valueStr, gasStr, gasPriceStr, codeStr string) | ||||
| 	} | ||||
| 
 | ||||
| 	var err error | ||||
| 	state := self.eth.ChainManager().TransState() | ||||
| 	state := self.eth.ChainManager().TxState() | ||||
| 	if balance := state.GetBalance(key.Address()); balance.Cmp(tx.Value()) < 0 { | ||||
| 		return "", fmt.Errorf("insufficient balance. balance=%v tx=%v", balance, tx.Value()) | ||||
| 	} | ||||
| @ -286,14 +300,6 @@ func (self *XEth) Transact(toStr, valueStr, gasStr, gasPriceStr, codeStr string) | ||||
| 	tx.SetNonce(nonce) | ||||
| 	tx.Sign(key.PrivateKey) | ||||
| 
 | ||||
| 	//fmt.Printf("create tx: %x %v\n", tx.Hash()[:4], tx.Nonce())
 | ||||
| 
 | ||||
| 	// Do some pre processing for our "pre" events  and hooks
 | ||||
| 	block := self.chainManager.NewBlock(key.Address()) | ||||
| 	coinbase := state.GetOrNewStateObject(key.Address()) | ||||
| 	coinbase.SetGasPool(block.GasLimit()) | ||||
| 	self.blockProcessor.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true) | ||||
| 
 | ||||
| 	err = self.eth.TxPool().Add(tx) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user