Merge branch 'master' into hotfix/0.8.5-2
This commit is contained in:
		| @@ -1,8 +1,8 @@ | |||||||
| language: go | language: go | ||||||
| go: | go: | ||||||
|   - 1.4.1 |   - 1.4.2 | ||||||
| before_install: | 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 update -qq | ||||||
|   - sudo apt-get install -yqq libgmp3-dev libreadline6-dev qt54quickcontrols qt54webengine |   - sudo apt-get install -yqq libgmp3-dev libreadline6-dev qt54quickcontrols qt54webengine | ||||||
| install: | install: | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							| @@ -1,15 +1,10 @@ | |||||||
| { | { | ||||||
| 	"ImportPath": "github.com/ethereum/go-ethereum", | 	"ImportPath": "github.com/ethereum/go-ethereum", | ||||||
| 	"GoVersion": "go1.4.1", | 	"GoVersion": "go1.4.2", | ||||||
| 	"Packages": [ | 	"Packages": [ | ||||||
| 		"./..." | 		"./..." | ||||||
| 	], | 	], | ||||||
| 	"Deps": [ | 	"Deps": [ | ||||||
| 		{ |  | ||||||
| 			"ImportPath": "bitbucket.org/kardianos/osext", |  | ||||||
| 			"Comment": "null-13", |  | ||||||
| 			"Rev": "5d3ddcf53a508cc2f7404eaebf546ef2cb5cdb6e" |  | ||||||
| 		}, |  | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "code.google.com/p/go-uuid/uuid", | 			"ImportPath": "code.google.com/p/go-uuid/uuid", | ||||||
| 			"Comment": "null-12", | 			"Comment": "null-12", | ||||||
| @@ -37,6 +32,10 @@ | |||||||
| 			"ImportPath": "github.com/jackpal/go-nat-pmp", | 			"ImportPath": "github.com/jackpal/go-nat-pmp", | ||||||
| 			"Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1" | 			"Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1" | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"ImportPath": "github.com/kardianos/osext", | ||||||
|  | 			"Rev": "ccfcd0245381f0c94c68f50626665eed3c6b726a" | ||||||
|  | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "github.com/obscuren/otto", | 			"ImportPath": "github.com/obscuren/otto", | ||||||
| 			"Rev": "cf13cc4228c5e5ce0fe27a7aea90bc10091c4f19" | 			"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) | 	folder, _ := filepath.Split(p) | ||||||
| 	return folder, nil | 	return folder, nil | ||||||
| } | } | ||||||
| 
 |  | ||||||
| // Depricated. Same as Executable(). |  | ||||||
| func GetExePath() (exePath string, err error) { |  | ||||||
| 	return Executable() |  | ||||||
| } |  | ||||||
| @@ -5,16 +5,16 @@ | |||||||
| package osext | package osext | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|     "syscall" | 	"os" | ||||||
|     "os" | 	"strconv" | ||||||
|     "strconv" | 	"syscall" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func executable() (string, error) { | func executable() (string, error) { | ||||||
|     f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text") | 	f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text") | ||||||
|     if err != nil { | 	if err != nil { | ||||||
|         return "", err | 		return "", err | ||||||
|     } | 	} | ||||||
|     defer f.Close() | 	defer f.Close() | ||||||
|     return syscall.Fd2path(int(f.Fd())) | 	return syscall.Fd2path(int(f.Fd())) | ||||||
| } | } | ||||||
| @@ -2,12 +2,13 @@ | |||||||
| // Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| // +build linux netbsd openbsd | // +build linux netbsd openbsd solaris dragonfly | ||||||
| 
 | 
 | ||||||
| package osext | package osext | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
|  | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| 	"runtime" | 	"runtime" | ||||||
| ) | ) | ||||||
| @@ -18,8 +19,10 @@ func executable() (string, error) { | |||||||
| 		return os.Readlink("/proc/self/exe") | 		return os.Readlink("/proc/self/exe") | ||||||
| 	case "netbsd": | 	case "netbsd": | ||||||
| 		return os.Readlink("/proc/curproc/exe") | 		return os.Readlink("/proc/curproc/exe") | ||||||
| 	case "openbsd": | 	case "openbsd", "dragonfly": | ||||||
| 		return os.Readlink("/proc/curproc/file") | 		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) | 	return "", errors.New("ExecPath not implemented for " + runtime.GOOS) | ||||||
| } | } | ||||||
| @@ -34,33 +34,62 @@ package accounts | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	crand "crypto/rand" | 	crand "crypto/rand" | ||||||
|  |  | ||||||
|  | 	"errors" | ||||||
|  | 	"sync" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/ethereum/go-ethereum/crypto" | 	"github.com/ethereum/go-ethereum/crypto" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | var ErrLocked = errors.New("account is locked; please request passphrase") | ||||||
|  |  | ||||||
| // TODO: better name for this struct? | // TODO: better name for this struct? | ||||||
| type Account struct { | type Account struct { | ||||||
| 	Address []byte | 	Address []byte | ||||||
| } | } | ||||||
|  |  | ||||||
| type AccountManager struct { | 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 | func NewAccountManager(keyStore crypto.KeyStore2, unlockMilliseconds time.Duration) AccountManager { | ||||||
|  | 	keysMap := make(map[string]crypto.Key) | ||||||
| // TODO: pass through passphrase for APIs which require access to private key? |  | ||||||
| func NewAccountManager(keyStore crypto.KeyStore2) AccountManager { |  | ||||||
| 	am := &AccountManager{ | 	am := &AccountManager{ | ||||||
| 		keyStore: keyStore, | 		keyStore:           keyStore, | ||||||
|  | 		unlockedKeys:       keysMap, | ||||||
|  | 		unlockMilliseconds: unlockMilliseconds, | ||||||
| 	} | 	} | ||||||
| 	return *am | 	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) | 	key, err := am.keyStore.GetKey(fromAccount.Address, keyAuth) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		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) | 	signature, err = crypto.Sign(toSign, key.PrivateKey) | ||||||
| 	return signature, err | 	return signature, err | ||||||
| } | } | ||||||
| @@ -76,8 +105,6 @@ func (am AccountManager) NewAccount(auth string) (*Account, error) { | |||||||
| 	return ua, err | 	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) { | func (am *AccountManager) Accounts() ([]Account, error) { | ||||||
| 	addresses, err := am.keyStore.GetKeyAddresses() | 	addresses, err := am.keyStore.GetKeyAddresses() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -93,3 +120,13 @@ func (am *AccountManager) Accounts() ([]Account, error) { | |||||||
| 	} | 	} | ||||||
| 	return accounts, err | 	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" | ||||||
| 	"github.com/ethereum/go-ethereum/crypto/randentropy" | 	"github.com/ethereum/go-ethereum/crypto/randentropy" | ||||||
|  | 	"github.com/ethereum/go-ethereum/ethutil" | ||||||
|  | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestAccountManager(t *testing.T) { | func TestAccountManager(t *testing.T) { | ||||||
| 	ks := crypto.NewKeyStorePlain(crypto.DefaultDataDir()) | 	ks := crypto.NewKeyStorePlain(ethutil.DefaultDataDir() + "/testaccounts") | ||||||
| 	am := NewAccountManager(ks) | 	am := NewAccountManager(ks, 100) | ||||||
| 	pass := "" // not used but required by API | 	pass := "" // not used but required by API | ||||||
| 	a1, err := am.NewAccount(pass) | 	a1, err := am.NewAccount(pass) | ||||||
| 	toSign := randentropy.GetEntropyCSPRNG(32) | 	toSign := randentropy.GetEntropyCSPRNG(32) | ||||||
| 	_, err = am.Sign(a1, pass, toSign) | 	_, err = am.SignLocked(a1, pass, toSign) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		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,10 +26,10 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"log" | 	"log" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/user" |  | ||||||
| 	"path" | 	"path" | ||||||
|  |  | ||||||
| 	"github.com/ethereum/go-ethereum/crypto" | 	"github.com/ethereum/go-ethereum/crypto" | ||||||
|  | 	"github.com/ethereum/go-ethereum/ethutil" | ||||||
| 	"github.com/ethereum/go-ethereum/logger" | 	"github.com/ethereum/go-ethereum/logger" | ||||||
| 	"github.com/ethereum/go-ethereum/p2p/nat" | 	"github.com/ethereum/go-ethereum/p2p/nat" | ||||||
| 	"github.com/ethereum/go-ethereum/vm" | 	"github.com/ethereum/go-ethereum/vm" | ||||||
| @@ -79,12 +79,7 @@ var ( | |||||||
| 	InputFile      string | 	InputFile      string | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func defaultDataDir() string { | var defaultConfigFile = path.Join(ethutil.DefaultDataDir(), "conf.ini") | ||||||
| 	usr, _ := user.Current() |  | ||||||
| 	return path.Join(usr.HomeDir, ".ethereum") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini") |  | ||||||
|  |  | ||||||
| func Init() { | func Init() { | ||||||
| 	// TODO: move common flag processing to cmd/util | 	// TODO: move common flag processing to cmd/util | ||||||
| @@ -107,7 +102,7 @@ func Init() { | |||||||
| 	flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)") | 	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(&ExportDir, "export", "", "exports the session keyring to files in the directory given") | ||||||
| 	flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)") | 	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(&ConfigFile, "conf", defaultConfigFile, "config file") | ||||||
| 	flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)") | 	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)") | ||||||
|   | |||||||
| @@ -62,6 +62,8 @@ | |||||||
|  |  | ||||||
|     web3.setProvider(new web3.providers.HttpSyncProvider('http://localhost:8545')); |     web3.setProvider(new web3.providers.HttpSyncProvider('http://localhost:8545')); | ||||||
|  |  | ||||||
|  |     eth.defaultBlock = -2 | ||||||
|  |  | ||||||
|     document.querySelector("#number").innerHTML = eth.number; |     document.querySelector("#number").innerHTML = eth.number; | ||||||
|     document.querySelector("#coinbase").innerHTML = eth.coinbase |     document.querySelector("#coinbase").innerHTML = eth.coinbase | ||||||
|     document.querySelector("#peer_count").innerHTML = eth.peerCount; |     document.querySelector("#peer_count").innerHTML = eth.peerCount; | ||||||
| @@ -72,8 +74,9 @@ | |||||||
|     document.querySelector("#mining").innerHTML = eth.mining; |     document.querySelector("#mining").innerHTML = eth.mining; | ||||||
|     document.querySelector("#listening").innerHTML = eth.listening; |     document.querySelector("#listening").innerHTML = eth.listening; | ||||||
|     eth.watch('chain').changed(function() { |     eth.watch('chain').changed(function() { | ||||||
| 		    document.querySelector("#number").innerHTML = eth.number; |         document.querySelector("#number").innerHTML = eth.number; | ||||||
| 		     }); |     }); | ||||||
|  |  | ||||||
|  |  | ||||||
| </script> | </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
											
										
									
								
							| @@ -26,13 +26,11 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"log" | 	"log" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/user" |  | ||||||
| 	"path" | 	"path" | ||||||
| 	"path/filepath" |  | ||||||
| 	"runtime" | 	"runtime" | ||||||
|  |  | ||||||
| 	"bitbucket.org/kardianos/osext" |  | ||||||
| 	"github.com/ethereum/go-ethereum/crypto" | 	"github.com/ethereum/go-ethereum/crypto" | ||||||
|  | 	"github.com/ethereum/go-ethereum/ethutil" | ||||||
| 	"github.com/ethereum/go-ethereum/logger" | 	"github.com/ethereum/go-ethereum/logger" | ||||||
| 	"github.com/ethereum/go-ethereum/p2p/nat" | 	"github.com/ethereum/go-ethereum/p2p/nat" | ||||||
| 	"github.com/ethereum/go-ethereum/vm" | 	"github.com/ethereum/go-ethereum/vm" | ||||||
| @@ -68,38 +66,7 @@ var ( | |||||||
|  |  | ||||||
| // flags specific to gui client | // flags specific to gui client | ||||||
| var AssetPath string | var AssetPath string | ||||||
|  | var defaultConfigFile = path.Join(ethutil.DefaultDataDir(), "conf.ini") | ||||||
| //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") |  | ||||||
|  |  | ||||||
| func Init() { | func Init() { | ||||||
| 	// TODO: move common flag processing to cmd/utils | 	// TODO: move common flag processing to cmd/utils | ||||||
| @@ -121,12 +88,12 @@ func Init() { | |||||||
| 	flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)") | 	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(&ExportDir, "export", "", "exports the session keyring to files in the directory given") | ||||||
| 	flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)") | 	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(&ConfigFile, "conf", defaultConfigFile, "config file") | ||||||
| 	flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)") | 	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 | 	// Network stuff | ||||||
| 	var ( | 	var ( | ||||||
|   | |||||||
| @@ -25,12 +25,8 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/signal" | 	"os/signal" | ||||||
| 	"path" |  | ||||||
| 	"path/filepath" |  | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"runtime" |  | ||||||
|  |  | ||||||
| 	"bitbucket.org/kardianos/osext" |  | ||||||
| 	"github.com/ethereum/go-ethereum/core/types" | 	"github.com/ethereum/go-ethereum/core/types" | ||||||
| 	"github.com/ethereum/go-ethereum/crypto" | 	"github.com/ethereum/go-ethereum/crypto" | ||||||
| 	"github.com/ethereum/go-ethereum/eth" | 	"github.com/ethereum/go-ethereum/eth" | ||||||
| @@ -132,31 +128,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) { | func KeyTasks(keyManager *crypto.KeyManager, KeyRing string, GenAddr bool, SecretFile string, ExportDir string, NonInteractive bool) { | ||||||
|  |  | ||||||
| 	var err error | 	var err error | ||||||
|   | |||||||
| @@ -48,9 +48,8 @@ type BlockProcessor struct { | |||||||
|  |  | ||||||
| func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor { | func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor { | ||||||
| 	sm := &BlockProcessor{ | 	sm := &BlockProcessor{ | ||||||
| 		db:  db, | 		db:       db, | ||||||
| 		mem: make(map[string]*big.Int), | 		mem:      make(map[string]*big.Int), | ||||||
| 		//Pow:      ðash.Ethash{}, |  | ||||||
| 		Pow:      ezp.New(), | 		Pow:      ezp.New(), | ||||||
| 		bc:       chainManager, | 		bc:       chainManager, | ||||||
| 		eventMux: eventMux, | 		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) { | 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 := statedb.GetOrNewStateObject(block.Header().Coinbase) | ||||||
| 	coinbase.SetGasPool(CalcGasLimit(parent, block)) | 	coinbase.SetGasPool(block.Header().GasLimit) | ||||||
|  |  | ||||||
| 	// Process the transactions on to parent state | 	// Process the transactions on to parent state | ||||||
| 	receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), transientProcess) | 	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 | 	// Notify all subscribers | ||||||
| 	if !transientProcess { | 	if !transientProcess { | ||||||
| 		go self.eventMux.Post(TxPostEvent{tx}) | 		go self.eventMux.Post(TxPostEvent{tx}) | ||||||
| 		go self.eventMux.Post(statedb.Logs()) | 		logs := statedb.Logs() | ||||||
|  | 		go self.eventMux.Post(logs) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return receipt, txGas, err | 	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) | 		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() { | 	if block.Time() < parent.Time() { | ||||||
| 		return ValidationError("Block timestamp not after prev block (%v - %v)", block.Header().Time, parent.Header().Time) | 		return ValidationError("Block timestamp not after prev block (%v - %v)", block.Header().Time, parent.Header().Time) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -283,7 +283,6 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain | |||||||
| 			break | 			break | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	fmt.Printf("get hash %x (%d)\n", hash, len(chain)) |  | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|   | |||||||
| @@ -126,7 +126,7 @@ func (self *StateTransition) BuyGas() error { | |||||||
|  |  | ||||||
| 	self.AddGas(self.msg.Gas()) | 	self.AddGas(self.msg.Gas()) | ||||||
| 	self.initialGas.Set(self.msg.Gas()) | 	self.initialGas.Set(self.msg.Gas()) | ||||||
| 	sender.SubAmount(MessageGasValue(self.msg)) | 	sender.SubBalance(MessageGasValue(self.msg)) | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -251,13 +251,16 @@ func (self *StateTransition) RefundGas() { | |||||||
| 	coinbase, sender := self.Coinbase(), self.From() | 	coinbase, sender := self.Coinbase(), self.From() | ||||||
| 	// Return remaining gas | 	// Return remaining gas | ||||||
| 	remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice()) | 	remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice()) | ||||||
| 	sender.AddAmount(remaining) | 	fmt.Println("REFUND:", remaining) | ||||||
|  | 	sender.AddBalance(remaining) | ||||||
|  |  | ||||||
| 	uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2) | 	uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2) | ||||||
| 	for addr, ref := range self.state.Refunds() { | 	for addr, ref := range self.state.Refunds() { | ||||||
| 		refund := ethutil.BigMin(uhalf, ref) | 		refund := ethutil.BigMin(uhalf, ref) | ||||||
| 		self.gas.Add(self.gas, refund) | 		self.gas.Add(self.gas, refund) | ||||||
| 		self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice())) | 		addToIt := refund.Mul(refund, self.msg.GasPrice()) | ||||||
|  | 		fmt.Println("ADD TO IT", addToIt) | ||||||
|  | 		self.state.AddBalance([]byte(addr), addToIt) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	coinbase.RefundGas(self.gas, self.msg.GasPrice()) | 	coinbase.RefundGas(self.gas, self.msg.GasPrice()) | ||||||
|   | |||||||
| @@ -30,7 +30,6 @@ import ( | |||||||
| 	"io" | 	"io" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/user" |  | ||||||
| 	"path" | 	"path" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -48,12 +47,6 @@ type keyStorePlain struct { | |||||||
| 	keysDirPath string | 	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 { | func NewKeyStorePlain(path string) KeyStore2 { | ||||||
| 	return &keyStorePlain{path} | 	return &keyStorePlain{path} | ||||||
| } | } | ||||||
| @@ -126,8 +119,11 @@ func GetKeyAddresses(keysDirPath string) (addresses [][]byte, err error) { | |||||||
| 	} | 	} | ||||||
| 	addresses = make([][]byte, len(fileInfos)) | 	addresses = make([][]byte, len(fileInfos)) | ||||||
| 	for i, fileInfo := range fileInfos { | 	for i, fileInfo := range fileInfos { | ||||||
| 		addresses[i] = make([]byte, 40) | 		address, err := hex.DecodeString(fileInfo.Name()) | ||||||
| 		addresses[i] = []byte(fileInfo.Name()) | 		if err != nil { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		addresses[i] = address | ||||||
| 	} | 	} | ||||||
| 	return addresses, err | 	return addresses, err | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,12 +2,13 @@ package crypto | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"github.com/ethereum/go-ethereum/crypto/randentropy" | 	"github.com/ethereum/go-ethereum/crypto/randentropy" | ||||||
|  | 	"github.com/ethereum/go-ethereum/ethutil" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestKeyStorePlain(t *testing.T) { | func TestKeyStorePlain(t *testing.T) { | ||||||
| 	ks := NewKeyStorePlain(DefaultDataDir()) | 	ks := NewKeyStorePlain(ethutil.DefaultDataDir()) | ||||||
| 	pass := "" // not used but required by API | 	pass := "" // not used but required by API | ||||||
| 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -35,7 +36,7 @@ func TestKeyStorePlain(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestKeyStorePassphrase(t *testing.T) { | func TestKeyStorePassphrase(t *testing.T) { | ||||||
| 	ks := NewKeyStorePassphrase(DefaultDataDir()) | 	ks := NewKeyStorePassphrase(ethutil.DefaultDataDir()) | ||||||
| 	pass := "foo" | 	pass := "foo" | ||||||
| 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -61,7 +62,7 @@ func TestKeyStorePassphrase(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestKeyStorePassphraseDecryptionFail(t *testing.T) { | func TestKeyStorePassphraseDecryptionFail(t *testing.T) { | ||||||
| 	ks := NewKeyStorePassphrase(DefaultDataDir()) | 	ks := NewKeyStorePassphrase(ethutil.DefaultDataDir()) | ||||||
| 	pass := "foo" | 	pass := "foo" | ||||||
| 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -89,7 +90,7 @@ func TestImportPreSaleKey(t *testing.T) { | |||||||
| 	// python pyethsaletool.py genwallet | 	// python pyethsaletool.py genwallet | ||||||
| 	// with password "foo" | 	// with password "foo" | ||||||
| 	fileContent := "{\"encseed\": \"26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba\", \"ethaddr\": \"d4584b5f6229b7be90727b0fc8c6b91bb427821f\", \"email\": \"gustav.simonsson@gmail.com\", \"btcaddr\": \"1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx\"}" | 	fileContent := "{\"encseed\": \"26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba\", \"ethaddr\": \"d4584b5f6229b7be90727b0fc8c6b91bb427821f\", \"email\": \"gustav.simonsson@gmail.com\", \"btcaddr\": \"1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx\"}" | ||||||
| 	ks := NewKeyStorePassphrase(DefaultDataDir()) | 	ks := NewKeyStorePassphrase(ethutil.DefaultDataDir()) | ||||||
| 	pass := "foo" | 	pass := "foo" | ||||||
| 	_, err := ImportPreSaleKey(ks, []byte(fileContent), pass) | 	_, err := ImportPreSaleKey(ks, []byte(fileContent), pass) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -3,10 +3,51 @@ package ethutil | |||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math/big" | 	"math/big" | ||||||
|  | 	"os" | ||||||
|  | 	"os/user" | ||||||
|  | 	"path" | ||||||
|  | 	"path/filepath" | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/kardianos/osext" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | 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() | ||||||
|  | 	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 { | func IsWindows() bool { | ||||||
| 	return runtime.GOOS == "windows" | 	return runtime.GOOS == "windows" | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ package filter | |||||||
| // TODO make use of the generic filtering system | // TODO make use of the generic filtering system | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" |  | ||||||
| 	"sync" | 	"sync" | ||||||
|  |  | ||||||
| 	"github.com/ethereum/go-ethereum/core" | 	"github.com/ethereum/go-ethereum/core" | ||||||
| @@ -75,7 +74,6 @@ out: | |||||||
| 		case event := <-events.Chan(): | 		case event := <-events.Chan(): | ||||||
| 			switch event := event.(type) { | 			switch event := event.(type) { | ||||||
| 			case core.ChainEvent: | 			case core.ChainEvent: | ||||||
| 				fmt.Println("filter start") |  | ||||||
| 				self.filterMu.RLock() | 				self.filterMu.RLock() | ||||||
| 				for _, filter := range self.filters { | 				for _, filter := range self.filters { | ||||||
| 					if filter.BlockCallback != nil { | 					if filter.BlockCallback != nil { | ||||||
| @@ -83,7 +81,6 @@ out: | |||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				self.filterMu.RUnlock() | 				self.filterMu.RUnlock() | ||||||
| 				fmt.Println("filter stop") |  | ||||||
|  |  | ||||||
| 			case core.PendingBlockEvent: | 			case core.PendingBlockEvent: | ||||||
| 				self.filterMu.RLock() | 				self.filterMu.RLock() | ||||||
|   | |||||||
| @@ -197,7 +197,7 @@ gasLimit: | |||||||
| 	} | 	} | ||||||
| 	self.eth.TxPool().RemoveSet(remove) | 	self.eth.TxPool().RemoveSet(remove) | ||||||
|  |  | ||||||
| 	self.current.coinbase.AddAmount(core.BlockReward) | 	self.current.coinbase.AddBalance(core.BlockReward) | ||||||
|  |  | ||||||
| 	self.current.state.Update(ethutil.Big0) | 	self.current.state.Update(ethutil.Big0) | ||||||
| 	self.push() | 	self.push() | ||||||
| @@ -225,7 +225,7 @@ func (self *worker) commitUncle(uncle *types.Header) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	uncleAccount := self.current.state.GetAccount(uncle.Coinbase) | 	uncleAccount := self.current.state.GetAccount(uncle.Coinbase) | ||||||
| 	uncleAccount.AddAmount(uncleReward) | 	uncleAccount.AddBalance(uncleReward) | ||||||
|  |  | ||||||
| 	self.current.coinbase.AddBalance(uncleReward) | 	self.current.coinbase.AddBalance(uncleReward) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,18 +20,24 @@ import ( | |||||||
| 	"github.com/ethereum/go-ethereum/crypto" | 	"github.com/ethereum/go-ethereum/crypto" | ||||||
| 	"github.com/ethereum/go-ethereum/ethdb" | 	"github.com/ethereum/go-ethereum/ethdb" | ||||||
| 	"github.com/ethereum/go-ethereum/ethutil" | 	"github.com/ethereum/go-ethereum/ethutil" | ||||||
|  | 	"github.com/ethereum/go-ethereum/event" | ||||||
| 	"github.com/ethereum/go-ethereum/event/filter" | 	"github.com/ethereum/go-ethereum/event/filter" | ||||||
| 	"github.com/ethereum/go-ethereum/state" | 	"github.com/ethereum/go-ethereum/state" | ||||||
|  | 	"github.com/ethereum/go-ethereum/ui" | ||||||
| 	"github.com/ethereum/go-ethereum/xeth" | 	"github.com/ethereum/go-ethereum/xeth" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | var ( | ||||||
| 	defaultGasPrice = "10000000000000" | 	defaultGasPrice  = big.NewInt(10000000000000) | ||||||
| 	defaultGas      = "10000" | 	defaultGas       = big.NewInt(10000) | ||||||
|  | 	filterTickerTime = 15 * time.Second | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type EthereumApi struct { | type EthereumApi struct { | ||||||
| 	xeth          *xeth.XEth | 	eth    *xeth.XEth | ||||||
|  | 	xethMu sync.RWMutex | ||||||
|  | 	mux    *event.TypeMux | ||||||
|  | 
 | ||||||
| 	quit          chan struct{} | 	quit          chan struct{} | ||||||
| 	filterManager *filter.FilterManager | 	filterManager *filter.FilterManager | ||||||
| 
 | 
 | ||||||
| @@ -45,17 +51,21 @@ type EthereumApi struct { | |||||||
| 	register map[string][]*NewTxArgs | 	register map[string][]*NewTxArgs | ||||||
| 
 | 
 | ||||||
| 	db ethutil.Database | 	db ethutil.Database | ||||||
|  | 
 | ||||||
|  | 	defaultBlockAge int64 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewEthereumApi(eth *xeth.XEth) *EthereumApi { | func NewEthereumApi(eth *xeth.XEth) *EthereumApi { | ||||||
| 	db, _ := ethdb.NewLDBDatabase("dapps") | 	db, _ := ethdb.NewLDBDatabase("dapps") | ||||||
| 	api := &EthereumApi{ | 	api := &EthereumApi{ | ||||||
| 		xeth:          eth, | 		eth:             eth, | ||||||
| 		quit:          make(chan struct{}), | 		mux:             eth.Backend().EventMux(), | ||||||
| 		filterManager: filter.NewFilterManager(eth.Backend().EventMux()), | 		quit:            make(chan struct{}), | ||||||
| 		logs:          make(map[int]*logFilter), | 		filterManager:   filter.NewFilterManager(eth.Backend().EventMux()), | ||||||
| 		messages:      make(map[int]*whisperFilter), | 		logs:            make(map[int]*logFilter), | ||||||
| 		db:            db, | 		messages:        make(map[int]*whisperFilter), | ||||||
|  | 		db:              db, | ||||||
|  | 		defaultBlockAge: -1, | ||||||
| 	} | 	} | ||||||
| 	go api.filterManager.Start() | 	go api.filterManager.Start() | ||||||
| 	go api.start() | 	go api.start() | ||||||
| @@ -63,6 +73,64 @@ func NewEthereumApi(eth *xeth.XEth) *EthereumApi { | |||||||
| 	return api | 	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 { | func (self *EthereumApi) Register(args string, reply *interface{}) error { | ||||||
| 	self.regmut.Lock() | 	self.regmut.Lock() | ||||||
| 	defer self.regmut.Unlock() | 	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 { | func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error { | ||||||
| 	var id int | 	var id int | ||||||
| 	filter := core.NewFilter(self.xeth.Backend()) | 	filter := core.NewFilter(self.xeth().Backend()) | ||||||
| 	filter.SetOptions(toFilterOptions(args)) | 	filter.SetOptions(toFilterOptions(args)) | ||||||
| 	filter.LogsCallback = func(logs state.Logs) { | 	filter.LogsCallback = func(logs state.Logs) { | ||||||
| 		self.logMut.Lock() | 		self.logMut.Lock() | ||||||
| @@ -120,7 +188,7 @@ func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error { | |||||||
| 
 | 
 | ||||||
| func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error { | func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error { | ||||||
| 	var id int | 	var id int | ||||||
| 	filter := core.NewFilter(self.xeth.Backend()) | 	filter := core.NewFilter(self.xeth().Backend()) | ||||||
| 
 | 
 | ||||||
| 	callback := func(block *types.Block) { | 	callback := func(block *types.Block) { | ||||||
| 		self.logMut.Lock() | 		self.logMut.Lock() | ||||||
| @@ -165,7 +233,7 @@ func (self *EthereumApi) Logs(id int, reply *interface{}) error { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (self *EthereumApi) AllLogs(args *FilterOptions, 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)) | 	filter.SetOptions(toFilterOptions(args)) | ||||||
| 
 | 
 | ||||||
| 	*reply = toLogs(filter.Find()) | 	*reply = toLogs(filter.Find()) | ||||||
| @@ -174,41 +242,54 @@ func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error { | func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error { | ||||||
| 	err := args.requirements() | 	// This seems a bit precarious Maybe worth splitting to discrete functions | ||||||
| 	if err != nil { | 	if len(args.Hash) > 0 { | ||||||
| 		return err | 		*reply = p.xeth().BlockByHash(args.Hash) | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if args.BlockNumber > 0 { |  | ||||||
| 		*reply = p.xeth.BlockByNumber(args.BlockNumber) |  | ||||||
| 	} else { | 	} else { | ||||||
| 		*reply = p.xeth.BlockByHash(args.Hash) | 		*reply = p.xeth().BlockByNumber(args.BlockNumber) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error { | func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error { | ||||||
| 	if len(args.Gas) == 0 { | 	if len(args.Gas) == 0 { | ||||||
| 		args.Gas = defaultGas | 		args.Gas = defaultGas.String() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if len(args.GasPrice) == 0 { | 	if len(args.GasPrice) == 0 { | ||||||
| 		args.GasPrice = defaultGasPrice | 		args.GasPrice = defaultGasPrice.String() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// TODO if no_private_key then | 	// TODO if no_private_key then | ||||||
| 	if _, exists := p.register[args.From]; exists { | 	//if _, exists := p.register[args.From]; exists { | ||||||
| 		p.register[args.From] = append(p.register[args.From], args) | 	//	p.register[args.From] = append(p.register[args.From], args) | ||||||
| 	} else { | 	//} else { | ||||||
| 		result, _ := p.xeth.Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) | 	/* | ||||||
| 		*reply = result | 		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 | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error { | 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 { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -222,7 +303,7 @@ func (p *EthereumApi) PushTx(args *PushTxArgs, reply *interface{}) error { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	result, _ := p.xeth.PushTx(args.Tx) | 	result, _ := p.xeth().PushTx(args.Tx) | ||||||
| 	*reply = result | 	*reply = result | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -233,7 +314,7 @@ func (p *EthereumApi) GetStateAt(args *GetStateArgs, reply *interface{}) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	state := p.xeth.State().SafeGet(args.Address) | 	state := p.xeth().State().SafeGet(args.Address) | ||||||
| 
 | 
 | ||||||
| 	value := state.StorageString(args.Key) | 	value := state.StorageString(args.Key) | ||||||
| 	var hx string | 	var hx string | ||||||
| @@ -255,42 +336,55 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageArgs, reply *interface{}) err | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	*reply = p.xeth.State().SafeGet(args.Address).Storage() | 	*reply = p.xeth().State().SafeGet(args.Address).Storage() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) GetPeerCount(reply *interface{}) error { | func (p *EthereumApi) GetPeerCount(reply *interface{}) error { | ||||||
| 	*reply = p.xeth.PeerCount() | 	*reply = p.xeth().PeerCount() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) GetIsListening(reply *interface{}) error { | func (p *EthereumApi) GetIsListening(reply *interface{}) error { | ||||||
| 	*reply = p.xeth.IsListening() | 	*reply = p.xeth().IsListening() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) GetCoinbase(reply *interface{}) error { | func (p *EthereumApi) GetCoinbase(reply *interface{}) error { | ||||||
| 	*reply = p.xeth.Coinbase() | 	*reply = p.xeth().Coinbase() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) Accounts(reply *interface{}) error { | func (p *EthereumApi) Accounts(reply *interface{}) error { | ||||||
| 	*reply = p.xeth.Accounts() | 	*reply = p.xeth().Accounts() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) GetIsMining(reply *interface{}) error { | func (p *EthereumApi) GetIsMining(reply *interface{}) error { | ||||||
| 	*reply = p.xeth.IsMining() | 	*reply = p.xeth().IsMining() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) SetMining(shouldmine bool, reply *interface{}) error { | 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 | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) BlockNumber(reply *interface{}) error { | func (p *EthereumApi) BlockNumber(reply *interface{}) error { | ||||||
| 	*reply = p.xeth.Backend().ChainManager().CurrentBlock().Number() | 	*reply = p.xeth().Backend().ChainManager().CurrentBlock().Number() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -299,7 +393,7 @@ func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) err | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	*reply = p.xeth.TxCountAt(args.Address) | 	*reply = p.xeth().TxCountAt(args.Address) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -308,7 +402,7 @@ func (p *EthereumApi) GetBalanceAt(args *GetBalanceArgs, reply *interface{}) err | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	state := p.xeth.State().SafeGet(args.Address) | 	state := p.xeth().State().SafeGet(args.Address) | ||||||
| 	*reply = toHex(state.Balance().Bytes()) | 	*reply = toHex(state.Balance().Bytes()) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -318,7 +412,7 @@ func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	*reply = p.xeth.CodeAt(args.Address) | 	*reply = p.xeth().CodeAt(args.Address) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -365,7 +459,7 @@ func (p *EthereumApi) DbGet(args *DbArgs, reply *interface{}) error { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error { | func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error { | ||||||
| 	*reply = p.xeth.Whisper().NewIdentity() | 	*reply = p.xeth().Whisper().NewIdentity() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -376,7 +470,7 @@ func (p *EthereumApi) NewWhisperFilter(args *xeth.Options, reply *interface{}) e | |||||||
| 		defer p.messagesMut.Unlock() | 		defer p.messagesMut.Unlock() | ||||||
| 		p.messages[id].add(msg) // = append(p.messages[id], msg) | 		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()} | 	p.messages[id] = &whisperFilter{timeout: time.Now()} | ||||||
| 	*reply = id | 	*reply = id | ||||||
| 	return nil | 	return nil | ||||||
| @@ -394,7 +488,7 @@ func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, 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 { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -404,17 +498,17 @@ func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) HasWhisperIdentity(args string, reply *interface{}) error { | func (p *EthereumApi) HasWhisperIdentity(args string, reply *interface{}) error { | ||||||
| 	*reply = p.xeth.Whisper().HasIdentity(args) | 	*reply = p.xeth().Whisper().HasIdentity(args) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error { | func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error { | ||||||
| 	*reply = p.xeth.Whisper().Messages(id) | 	*reply = p.xeth().Whisper().Messages(id) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { | 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) | 	rpclogger.DebugDetailf("%T %s", req.Params, req.Params) | ||||||
| 	switch req.Method { | 	switch req.Method { | ||||||
| 	case "eth_coinbase": | 	case "eth_coinbase": | ||||||
| @@ -429,6 +523,14 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error | |||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		return p.SetMining(args, reply) | 		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": | 	case "eth_peerCount": | ||||||
| 		return p.GetPeerCount(reply) | 		return p.GetPeerCount(reply) | ||||||
| 	case "eth_number": | 	case "eth_number": | ||||||
| @@ -520,7 +622,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error | |||||||
| 		} | 		} | ||||||
| 		return p.AllLogs(args, reply) | 		return p.AllLogs(args, reply) | ||||||
| 	case "eth_gasPrice": | 	case "eth_gasPrice": | ||||||
| 		*reply = defaultGasPrice | 		*reply = toHex(defaultGasPrice.Bytes()) | ||||||
| 		return nil | 		return nil | ||||||
| 	case "eth_register": | 	case "eth_register": | ||||||
| 		args, err := req.ToRegisterArgs() | 		args, err := req.ToRegisterArgs() | ||||||
| @@ -599,44 +701,34 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error | |||||||
| 		} | 		} | ||||||
| 		return p.WhisperMessages(args, reply) | 		return p.WhisperMessages(args, reply) | ||||||
| 	default: | 	default: | ||||||
| 		return NewErrorResponse(fmt.Sprintf("%v %s", ErrorNotImplemented, req.Method)) | 		return NewErrorWithMessage(errNotImplemented, req.Method) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	rpclogger.DebugDetailf("Reply: %T %s", reply, reply) | 	rpclogger.DebugDetailf("Reply: %T %s", reply, reply) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var filterTickerTime = 15 * time.Second | func (self *EthereumApi) xeth() *xeth.XEth { | ||||||
|  | 	self.xethMu.RLock() | ||||||
|  | 	defer self.xethMu.RUnlock() | ||||||
| 
 | 
 | ||||||
| func (self *EthereumApi) start() { | 	return self.eth | ||||||
| 	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 { |  | ||||||
| 					self.filterManager.UninstallFilter(id) |  | ||||||
| 					delete(self.logs, id) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 
 | 
 | ||||||
| 			for id, filter := range self.messages { | func (self *EthereumApi) useState(statedb *state.StateDB) { | ||||||
| 				if time.Since(filter.timeout) > 20*time.Second { | 	self.xethMu.Lock() | ||||||
| 					self.xeth.Whisper().Unwatch(id) | 	defer self.xethMu.Unlock() | ||||||
| 					delete(self.messages, id) | 
 | ||||||
| 				} | 	self.eth = self.eth.UseState(statedb) | ||||||
| 			} | } | ||||||
| 			self.logMut.Unlock() | 
 | ||||||
| 			self.messagesMut.Unlock() | func t(f ui.Frontend) { | ||||||
| 		case <-self.quit: | 	// Call the password dialog | ||||||
| 			break done | 	ret, err := f.Call("PasswordDialog") | ||||||
| 		} | 	if err != nil { | ||||||
|  | 		fmt.Println(err) | ||||||
| 	} | 	} | ||||||
| } | 	// Get the first argument | ||||||
| 
 | 	t, _ := ret.Get(0) | ||||||
| func (self *EthereumApi) stop() { | 	fmt.Println("return:", t) | ||||||
| 	close(self.quit) |  | ||||||
| } | } | ||||||
| @@ -7,6 +7,7 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestFilterClose(t *testing.T) { | func TestFilterClose(t *testing.T) { | ||||||
|  | 	t.Skip() | ||||||
| 	api := &EthereumApi{ | 	api := &EthereumApi{ | ||||||
| 		logs:     make(map[int]*logFilter), | 		logs:     make(map[int]*logFilter), | ||||||
| 		messages: make(map[int]*whisperFilter), | 		messages: make(map[int]*whisperFilter), | ||||||
							
								
								
									
										73
									
								
								rpc/args.go
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								rpc/args.go
									
									
									
									
									
								
							| @@ -19,14 +19,7 @@ func (obj *GetBlockArgs) UnmarshalJSON(b []byte) (err error) { | |||||||
| 		obj.Hash = argstr | 		obj.Hash = argstr | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	return NewErrorResponse(ErrorDecodeArgs) | 	return errDecodeArgs | ||||||
| } |  | ||||||
|  |  | ||||||
| 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 |  | ||||||
| } | } | ||||||
|  |  | ||||||
| type NewTxArgs struct { | type NewTxArgs struct { | ||||||
| @@ -64,7 +57,7 @@ func (obj *NewTxArgs) UnmarshalJSON(b []byte) (err error) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return NewErrorResponse(ErrorDecodeArgs) | 	return errDecodeArgs | ||||||
| } | } | ||||||
|  |  | ||||||
| type PushTxArgs struct { | type PushTxArgs struct { | ||||||
| @@ -77,12 +70,12 @@ func (obj *PushTxArgs) UnmarshalJSON(b []byte) (err error) { | |||||||
| 		obj.Tx = arg0 | 		obj.Tx = arg0 | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	return NewErrorResponse(ErrorDecodeArgs) | 	return errDecodeArgs | ||||||
| } | } | ||||||
|  |  | ||||||
| func (a *PushTxArgs) requirementsPushTx() error { | func (a *PushTxArgs) requirementsPushTx() error { | ||||||
| 	if a.Tx == "" { | 	if a.Tx == "" { | ||||||
| 		return NewErrorResponse("PushTx requires a 'tx' as argument") | 		return NewErrorWithMessage(errArguments, "PushTx requires a 'tx' as argument") | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -93,14 +86,14 @@ type GetStorageArgs struct { | |||||||
|  |  | ||||||
| func (obj *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { | func (obj *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { | ||||||
| 	if err = json.Unmarshal(b, &obj.Address); err != nil { | 	if err = json.Unmarshal(b, &obj.Address); err != nil { | ||||||
| 		return NewErrorResponse(ErrorDecodeArgs) | 		return errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
| func (a *GetStorageArgs) requirements() error { | func (a *GetStorageArgs) requirements() error { | ||||||
| 	if len(a.Address) == 0 { | 	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 | 	return nil | ||||||
| } | } | ||||||
| @@ -116,64 +109,39 @@ func (obj *GetStateArgs) UnmarshalJSON(b []byte) (err error) { | |||||||
| 		obj.Address = arg0 | 		obj.Address = arg0 | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	return NewErrorResponse(ErrorDecodeArgs) | 	return errDecodeArgs | ||||||
| } | } | ||||||
|  |  | ||||||
| func (a *GetStateArgs) requirements() error { | func (a *GetStateArgs) requirements() error { | ||||||
| 	if a.Address == "" { | 	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 == "" { | 	if a.Key == "" { | ||||||
| 		return NewErrorResponse("GetStorageAt requires an 'key' value as argument") | 		return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'key' value as argument") | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| type GetStorageAtRes struct { |  | ||||||
| 	Key   string `json:"key"` |  | ||||||
| 	Value string `json:"value"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type GetTxCountArgs struct { | type GetTxCountArgs struct { | ||||||
| 	Address string `json:"address"` | 	Address string `json:"address"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // type GetTxCountRes struct { |  | ||||||
| //  Nonce int `json:"nonce"` |  | ||||||
| // } |  | ||||||
|  |  | ||||||
| func (obj *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { | func (obj *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { | ||||||
| 	arg0 := "" | 	arg0 := "" | ||||||
| 	if err = json.Unmarshal(b, &arg0); err == nil { | 	if err = json.Unmarshal(b, &arg0); err == nil { | ||||||
| 		obj.Address = arg0 | 		obj.Address = arg0 | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	return NewErrorResponse("Could not determine JSON parameters") | 	return errDecodeArgs | ||||||
| } | } | ||||||
|  |  | ||||||
| func (a *GetTxCountArgs) requirements() error { | func (a *GetTxCountArgs) requirements() error { | ||||||
| 	if a.Address == "" { | 	if a.Address == "" { | ||||||
| 		return NewErrorResponse("GetTxCountAt requires an 'address' value as argument") | 		return NewErrorWithMessage(errArguments, "GetTxCountAt requires an 'address' value as argument") | ||||||
| 	} | 	} | ||||||
| 	return nil | 	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 { | type GetBalanceArgs struct { | ||||||
| 	Address string | 	Address string | ||||||
| } | } | ||||||
| @@ -184,21 +152,16 @@ func (obj *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { | |||||||
| 		obj.Address = arg0 | 		obj.Address = arg0 | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	return NewErrorResponse("Could not determine JSON parameters") | 	return errDecodeArgs | ||||||
| } | } | ||||||
|  |  | ||||||
| func (a *GetBalanceArgs) requirements() error { | func (a *GetBalanceArgs) requirements() error { | ||||||
| 	if a.Address == "" { | 	if a.Address == "" { | ||||||
| 		return NewErrorResponse("GetBalanceAt requires an 'address' value as argument") | 		return NewErrorWithMessage(errArguments, "GetBalanceAt requires an 'address' value as argument") | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| type BalanceRes struct { |  | ||||||
| 	Balance string `json:"balance"` |  | ||||||
| 	Address string `json:"address"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type GetCodeAtArgs struct { | type GetCodeAtArgs struct { | ||||||
| 	Address string | 	Address string | ||||||
| } | } | ||||||
| @@ -209,12 +172,12 @@ func (obj *GetCodeAtArgs) UnmarshalJSON(b []byte) (err error) { | |||||||
| 		obj.Address = arg0 | 		obj.Address = arg0 | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	return NewErrorResponse(ErrorDecodeArgs) | 	return errDecodeArgs | ||||||
| } | } | ||||||
|  |  | ||||||
| func (a *GetCodeAtArgs) requirements() error { | func (a *GetCodeAtArgs) requirements() error { | ||||||
| 	if a.Address == "" { | 	if a.Address == "" { | ||||||
| 		return NewErrorResponse("GetCodeAt requires an 'address' value as argument") | 		return NewErrorWithMessage(errArguments, "GetCodeAt requires an 'address' value as argument") | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -225,7 +188,7 @@ type Sha3Args struct { | |||||||
|  |  | ||||||
| func (obj *Sha3Args) UnmarshalJSON(b []byte) (err error) { | func (obj *Sha3Args) UnmarshalJSON(b []byte) (err error) { | ||||||
| 	if err = json.Unmarshal(b, &obj.Data); err != nil { | 	if err = json.Unmarshal(b, &obj.Data); err != nil { | ||||||
| 		return NewErrorResponse(ErrorDecodeArgs) | 		return errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| @@ -277,10 +240,10 @@ type DbArgs struct { | |||||||
|  |  | ||||||
| func (a *DbArgs) requirements() error { | func (a *DbArgs) requirements() error { | ||||||
| 	if len(a.Database) == 0 { | 	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 { | 	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 | 	return nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -92,7 +92,7 @@ func (s *RpcHttpServer) apiHandler(api *rpc.EthereumApi) http.Handler { | |||||||
|  |  | ||||||
| 		reqParsed, reqerr := JSON.ParseRequestBody(req) | 		reqParsed, reqerr := JSON.ParseRequestBody(req) | ||||||
| 		if reqerr != nil { | 		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}) | 			JSON.Send(w, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -25,12 +25,11 @@ import ( | |||||||
| 	"github.com/ethereum/go-ethereum/xeth" | 	"github.com/ethereum/go-ethereum/xeth" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | var ( | ||||||
| 	ErrorArguments      = "Error: Insufficient arguments" | 	errArguments      = errors.New("Error: Insufficient arguments") | ||||||
| 	ErrorNotImplemented = "Error: Method not implemented" | 	errNotImplemented = errors.New("Error: Method not implemented") | ||||||
| 	ErrorUnknown        = "Error: Unknown error" | 	errUnknown        = errors.New("Error: Unknown error") | ||||||
| 	ErrorParseRequest   = "Error: Could not parse request" | 	errDecodeArgs     = errors.New("Error: Could not decode arguments") | ||||||
| 	ErrorDecodeArgs     = "Error: Could not decode arguments" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type RpcRequest struct { | type RpcRequest struct { | ||||||
| @@ -58,76 +57,72 @@ type RpcErrorObject struct { | |||||||
| 	// Data    interface{} `json:"data"` | 	// Data    interface{} `json:"data"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewErrorResponse(msg string) error { | func NewErrorWithMessage(err error, msg string) error { | ||||||
| 	return errors.New(msg) | 	return fmt.Errorf("%s: %s", err.Error(), msg) | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewErrorResponseWithError(msg string, err error) error { |  | ||||||
| 	return fmt.Errorf("%s: %v", msg, err) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToSha3Args() (*Sha3Args, error) { | func (req *RpcRequest) ToSha3Args() (*Sha3Args, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	args := new(Sha3Args) | 	args := new(Sha3Args) | ||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	if err := json.NewDecoder(r).Decode(args); err != nil { | 	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 | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToGetBlockArgs() (*GetBlockArgs, error) { | func (req *RpcRequest) ToGetBlockArgs() (*GetBlockArgs, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	args := new(GetBlockArgs) | 	args := new(GetBlockArgs) | ||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	err := json.NewDecoder(r).Decode(args) | 	err := json.NewDecoder(r).Decode(args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | 		return nil, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToNewTxArgs() (*NewTxArgs, error) { | func (req *RpcRequest) ToNewTxArgs() (*NewTxArgs, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	args := new(NewTxArgs) | 	args := new(NewTxArgs) | ||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	err := json.NewDecoder(r).Decode(args) | 	err := json.NewDecoder(r).Decode(args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToPushTxArgs() (*PushTxArgs, error) { | func (req *RpcRequest) ToPushTxArgs() (*PushTxArgs, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	args := new(PushTxArgs) | 	args := new(PushTxArgs) | ||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	err := json.NewDecoder(r).Decode(args) | 	err := json.NewDecoder(r).Decode(args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | 		return nil, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToGetStateArgs() (*GetStateArgs, error) { | func (req *RpcRequest) ToGetStateArgs() (*GetStateArgs, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	args := new(GetStateArgs) | 	args := new(GetStateArgs) | ||||||
| @@ -135,234 +130,241 @@ func (req *RpcRequest) ToGetStateArgs() (*GetStateArgs, error) { | |||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	err := json.NewDecoder(r).Decode(args) | 	err := json.NewDecoder(r).Decode(args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | 		return nil, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToStorageAtArgs() (*GetStorageArgs, error) { | func (req *RpcRequest) ToStorageAtArgs() (*GetStorageArgs, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	args := new(GetStorageArgs) | 	args := new(GetStorageArgs) | ||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	err := json.NewDecoder(r).Decode(args) | 	err := json.NewDecoder(r).Decode(args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | 		return nil, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToGetTxCountArgs() (*GetTxCountArgs, error) { | func (req *RpcRequest) ToGetTxCountArgs() (*GetTxCountArgs, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	args := new(GetTxCountArgs) | 	args := new(GetTxCountArgs) | ||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	err := json.NewDecoder(r).Decode(args) | 	err := json.NewDecoder(r).Decode(args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | 		return nil, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToGetBalanceArgs() (*GetBalanceArgs, error) { | func (req *RpcRequest) ToGetBalanceArgs() (*GetBalanceArgs, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	args := new(GetBalanceArgs) | 	args := new(GetBalanceArgs) | ||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	err := json.NewDecoder(r).Decode(args) | 	err := json.NewDecoder(r).Decode(args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | 		return nil, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToGetCodeAtArgs() (*GetCodeAtArgs, error) { | func (req *RpcRequest) ToGetCodeAtArgs() (*GetCodeAtArgs, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	args := new(GetCodeAtArgs) | 	args := new(GetCodeAtArgs) | ||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	err := json.NewDecoder(r).Decode(args) | 	err := json.NewDecoder(r).Decode(args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | 		return nil, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToBoolArgs() (bool, error) { | func (req *RpcRequest) ToBoolArgs() (bool, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return false, NewErrorResponse(ErrorArguments) | 		return false, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args bool | 	var args bool | ||||||
| 	err := json.Unmarshal(req.Params[0], &args) | 	err := json.Unmarshal(req.Params[0], &args) | ||||||
| 	if err != nil { | 	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 | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToCompileArgs() (string, error) { | func (req *RpcRequest) ToCompileArgs() (string, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return "", NewErrorResponse(ErrorArguments) | 		return "", errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args string | 	var args string | ||||||
| 	err := json.Unmarshal(req.Params[0], &args) | 	err := json.Unmarshal(req.Params[0], &args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", NewErrorResponse(ErrorDecodeArgs) | 		return "", errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) |  | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToFilterArgs() (*FilterOptions, error) { | func (req *RpcRequest) ToFilterArgs() (*FilterOptions, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	args := new(FilterOptions) | 	args := new(FilterOptions) | ||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	err := json.NewDecoder(r).Decode(args) | 	err := json.NewDecoder(r).Decode(args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | 		return nil, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) |  | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToFilterStringArgs() (string, error) { | func (req *RpcRequest) ToFilterStringArgs() (string, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return "", NewErrorResponse(ErrorArguments) | 		return "", errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args string | 	var args string | ||||||
| 	err := json.Unmarshal(req.Params[0], &args) | 	err := json.Unmarshal(req.Params[0], &args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", NewErrorResponse(ErrorDecodeArgs) | 		return "", errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) |  | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToUninstallFilterArgs() (int, error) { | func (req *RpcRequest) ToUninstallFilterArgs() (int, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return 0, NewErrorResponse(ErrorArguments) | 		return 0, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args int | 	var args int | ||||||
| 	err := json.Unmarshal(req.Params[0], &args) | 	err := json.Unmarshal(req.Params[0], &args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return 0, NewErrorResponse(ErrorDecodeArgs) | 		return 0, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) |  | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToFilterChangedArgs() (int, error) { | func (req *RpcRequest) ToFilterChangedArgs() (int, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return 0, NewErrorResponse(ErrorArguments) | 		return 0, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var id int | 	var id int | ||||||
| 	r := bytes.NewReader(req.Params[0]) | 	r := bytes.NewReader(req.Params[0]) | ||||||
| 	err := json.NewDecoder(r).Decode(&id) | 	err := json.NewDecoder(r).Decode(&id) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return 0, NewErrorResponse(ErrorDecodeArgs) | 		return 0, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", id, id) |  | ||||||
| 	return id, nil | 	return id, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToDbPutArgs() (*DbArgs, error) { | func (req *RpcRequest) ToDbPutArgs() (*DbArgs, error) { | ||||||
| 	if len(req.Params) < 3 { | 	if len(req.Params) < 3 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args DbArgs | 	var args DbArgs | ||||||
| 	err := json.Unmarshal(req.Params[0], &args.Database) | 	err := json.Unmarshal(req.Params[0], &args.Database) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||||
| 	} | 	} | ||||||
| 	err = json.Unmarshal(req.Params[1], &args.Key) | 	err = json.Unmarshal(req.Params[1], &args.Key) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||||
| 	} | 	} | ||||||
| 	err = json.Unmarshal(req.Params[2], &args.Value) | 	err = json.Unmarshal(req.Params[2], &args.Value) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return &args, nil | 	return &args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToDbGetArgs() (*DbArgs, error) { | func (req *RpcRequest) ToDbGetArgs() (*DbArgs, error) { | ||||||
| 	if len(req.Params) < 2 { | 	if len(req.Params) < 2 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args DbArgs | 	var args DbArgs | ||||||
| 	err := json.Unmarshal(req.Params[0], &args.Database) | 	err := json.Unmarshal(req.Params[0], &args.Database) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = json.Unmarshal(req.Params[1], &args.Key) | 	err = json.Unmarshal(req.Params[1], &args.Key) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return &args, nil | 	return &args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToWhisperFilterArgs() (*xeth.Options, error) { | func (req *RpcRequest) ToWhisperFilterArgs() (*xeth.Options, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args xeth.Options | 	var args xeth.Options | ||||||
| 	err := json.Unmarshal(req.Params[0], &args) | 	err := json.Unmarshal(req.Params[0], &args) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return &args, nil | 	return &args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToIdArgs() (int, error) { | func (req *RpcRequest) ToIdArgs() (int, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return 0, NewErrorResponse(ErrorArguments) | 		return 0, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var id int | 	var id int | ||||||
| 	err := json.Unmarshal(req.Params[0], &id) | 	err := json.Unmarshal(req.Params[0], &id) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return 0, NewErrorResponse(ErrorDecodeArgs) | 		return 0, errDecodeArgs | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", id, id) | 
 | ||||||
| 	return id, nil | 	return id, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToWhisperPostArgs() (*WhisperMessageArgs, error) { | func (req *RpcRequest) ToWhisperPostArgs() (*WhisperMessageArgs, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return nil, NewErrorResponse(ErrorArguments) | 		return nil, errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args WhisperMessageArgs | 	var args WhisperMessageArgs | ||||||
| @@ -370,13 +372,13 @@ func (req *RpcRequest) ToWhisperPostArgs() (*WhisperMessageArgs, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return &args, nil | 	return &args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) { | func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return "", NewErrorResponse(ErrorArguments) | 		return "", errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args string | 	var args string | ||||||
| @@ -384,13 +386,13 @@ func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToRegisterArgs() (string, error) { | func (req *RpcRequest) ToRegisterArgs() (string, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return "", NewErrorResponse(ErrorArguments) | 		return "", errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args string | 	var args string | ||||||
| @@ -398,13 +400,13 @@ func (req *RpcRequest) ToRegisterArgs() (string, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (req *RpcRequest) ToWatchTxArgs() (string, error) { | func (req *RpcRequest) ToWatchTxArgs() (string, error) { | ||||||
| 	if len(req.Params) < 1 { | 	if len(req.Params) < 1 { | ||||||
| 		return "", NewErrorResponse(ErrorArguments) | 		return "", errArguments | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var args string | 	var args string | ||||||
| @@ -412,6 +414,6 @@ func (req *RpcRequest) ToWatchTxArgs() (string, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | 
 | ||||||
| 	return args, nil | 	return args, nil | ||||||
| } | } | ||||||
| @@ -82,7 +82,7 @@ type RpcServer interface { | |||||||
|  |  | ||||||
| type Log struct { | type Log struct { | ||||||
| 	Address string   `json:"address"` | 	Address string   `json:"address"` | ||||||
| 	Topic   []string `json:"topics"` | 	Topic   []string `json:"topic"` | ||||||
| 	Data    string   `json:"data"` | 	Data    string   `json:"data"` | ||||||
| 	Number  uint64   `json:"number"` | 	Number  uint64   `json:"number"` | ||||||
| } | } | ||||||
|   | |||||||
| @@ -99,7 +99,7 @@ func sockHandler(api *rpc.EthereumApi) websocket.Handler { | |||||||
|  |  | ||||||
| 			// reqParsed, reqerr := JSON.ParseRequestBody(conn.Request()) | 			// reqParsed, reqerr := JSON.ParseRequestBody(conn.Request()) | ||||||
| 			if err := websocket.JSON.Receive(conn, &reqParsed); err != nil { | 			if err := websocket.JSON.Receive(conn, &reqParsed); err != nil { | ||||||
| 				jsonerr := &rpc.RpcErrorObject{-32700, rpc.ErrorParseRequest} | 				jsonerr := &rpc.RpcErrorObject{-32700, "Error: Could not parse request"} | ||||||
| 				JSON.Send(conn, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) | 				JSON.Send(conn, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ func (self *StateDB) Dump() []byte { | |||||||
|  |  | ||||||
| 		storageIt := stateObject.State.trie.Iterator() | 		storageIt := stateObject.State.trie.Iterator() | ||||||
| 		for storageIt.Next() { | 		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 | 		world.Accounts[ethutil.Bytes2Hex(it.Key)] = account | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -19,6 +19,14 @@ func (self Code) String() string { | |||||||
|  |  | ||||||
| type Storage map[string]*ethutil.Value | 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 { | func (self Storage) Copy() Storage { | ||||||
| 	cpy := make(Storage) | 	cpy := make(Storage) | ||||||
| 	for key, value := range self { | 	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) { | func (self *StateObject) SetStorage(key *big.Int, value *ethutil.Value) { | ||||||
| 	self.SetState(key.Bytes(), 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 | 	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) | 	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) { | func (c *StateObject) SubBalance(amount *big.Int) { | ||||||
| 	c.SetBalance(new(big.Int).Sub(c.balance, amount)) | 	c.SetBalance(new(big.Int).Sub(c.balance, amount)) | ||||||
|  |  | ||||||
| 	statelogger.Debugf("%x: #%d %v (- %v)\n", c.Address(), c.nonce, 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) { | func (c *StateObject) SetBalance(amount *big.Int) { | ||||||
| 	c.balance = amount | 	c.balance = amount | ||||||
| 	c.dirty = true | 	c.dirty = true | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (c *StateObject) St() Storage { | ||||||
|  | 	return c.storage | ||||||
|  | } | ||||||
|  |  | ||||||
| // | // | ||||||
| // Gas setters and getters | // 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) | 		return fmt.Errorf("insufficient amount: %v, %v", c.balance, total) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	c.SubAmount(total) | 	c.SubBalance(total) | ||||||
|  |  | ||||||
| 	c.dirty = true | 	c.dirty = true | ||||||
|  |  | ||||||
| @@ -221,7 +230,7 @@ func (self *StateObject) BuyGas(gas, price *big.Int) error { | |||||||
| 	rGas := new(big.Int).Set(gas) | 	rGas := new(big.Int).Set(gas) | ||||||
| 	rGas.Mul(rGas, price) | 	rGas.Mul(rGas, price) | ||||||
|  |  | ||||||
| 	self.AddAmount(rGas) | 	self.AddBalance(rGas) | ||||||
|  |  | ||||||
| 	self.dirty = true | 	self.dirty = true | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										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) | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								vm/vm.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								vm/vm.go
									
									
									
									
									
								
							| @@ -664,6 +664,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I | |||||||
| 				} | 				} | ||||||
| 				addr = ref.Address() | 				addr = ref.Address() | ||||||
|  |  | ||||||
|  | 				fmt.Printf("CREATE %X\n", addr) | ||||||
| 				stack.Push(ethutil.BigD(addr)) | 				stack.Push(ethutil.BigD(addr)) | ||||||
|  |  | ||||||
| 			} | 			} | ||||||
| @@ -727,7 +728,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I | |||||||
|  |  | ||||||
| 			self.Printf(" => (%x) %v", receiver.Address()[:4], balance) | 			self.Printf(" => (%x) %v", receiver.Address()[:4], balance) | ||||||
|  |  | ||||||
| 			receiver.AddAmount(balance) | 			receiver.AddBalance(balance) | ||||||
| 			statedb.Delete(context.Address()) | 			statedb.Delete(context.Address()) | ||||||
|  |  | ||||||
| 			fallthrough | 			fallthrough | ||||||
| @@ -779,9 +780,9 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo | |||||||
| 	// Stack Check, memory resize & gas phase | 	// Stack Check, memory resize & gas phase | ||||||
| 	switch op { | 	switch op { | ||||||
| 	// Stack checks only | 	// Stack checks only | ||||||
| 	case ISZERO, CALLDATALOAD, POP, JUMP, NOT: // 1 | 	case ISZERO, CALLDATALOAD, POP, JUMP, NOT, EXTCODESIZE, BLOCKHASH: // 1 | ||||||
| 		stack.require(1) | 		stack.require(1) | ||||||
| 	case JUMPI, ADD, SUB, DIV, SDIV, MOD, SMOD, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE, SIGNEXTEND: // 2 | 	case JUMPI, ADD, SUB, DIV, MUL, SDIV, MOD, SMOD, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE, SIGNEXTEND: // 2 | ||||||
| 		stack.require(2) | 		stack.require(2) | ||||||
| 	case ADDMOD, MULMOD: // 3 | 	case ADDMOD, MULMOD: // 3 | ||||||
| 		stack.require(3) | 		stack.require(3) | ||||||
| @@ -828,7 +829,7 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo | |||||||
| 			// 0 => non 0 | 			// 0 => non 0 | ||||||
| 			mult = ethutil.Big3 | 			mult = ethutil.Big3 | ||||||
| 		} else if len(val) > 0 && len(y.Bytes()) == 0 { | 		} else if len(val) > 0 && len(y.Bytes()) == 0 { | ||||||
| 			statedb.Refund(caller.Address(), GasSStoreRefund) | 			statedb.Refund(self.env.Origin(), GasSStoreRefund) | ||||||
|  |  | ||||||
| 			mult = ethutil.Big0 | 			mult = ethutil.Big0 | ||||||
| 		} else { | 		} else { | ||||||
| @@ -859,7 +860,7 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo | |||||||
| 		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2]) | 		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2]) | ||||||
| 		additionalGas.Set(stack.data[stack.Len()-2]) | 		additionalGas.Set(stack.data[stack.Len()-2]) | ||||||
| 	case CALLDATACOPY: | 	case CALLDATACOPY: | ||||||
| 		stack.require(2) | 		stack.require(3) | ||||||
|  |  | ||||||
| 		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3]) | 		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3]) | ||||||
| 		additionalGas.Set(stack.data[stack.Len()-3]) | 		additionalGas.Set(stack.data[stack.Len()-3]) | ||||||
|   | |||||||
| @@ -3,19 +3,20 @@ package xeth | |||||||
| import "github.com/ethereum/go-ethereum/state" | import "github.com/ethereum/go-ethereum/state" | ||||||
| 
 | 
 | ||||||
| type State struct { | type State struct { | ||||||
| 	xeth *XEth | 	xeth  *XEth | ||||||
|  | 	state *state.StateDB | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewState(xeth *XEth) *State { | func NewState(xeth *XEth, statedb *state.StateDB) *State { | ||||||
| 	return &State{xeth} | 	return &State{xeth, statedb} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (self *State) State() *state.StateDB { | func (self *State) State() *state.StateDB { | ||||||
| 	return self.xeth.chainManager.TransState() | 	return self.state | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (self *State) Get(addr string) *Object { | 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 { | 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 { | func (self *State) safeGet(addr string) *state.StateObject { | ||||||
| 	object := self.State().GetStateObject(fromHex(addr)) | 	object := self.state.GetStateObject(fromHex(addr)) | ||||||
| 	if object == nil { | 	if object == nil { | ||||||
| 		object = state.NewStateObject(fromHex(addr), self.xeth.eth.Db()) | 		object = state.NewStateObject(fromHex(addr), self.xeth.eth.Db()) | ||||||
| 	} | 	} | ||||||
							
								
								
									
										22
									
								
								xeth/xeth.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								xeth/xeth.go
									
									
									
									
									
								
							| @@ -17,6 +17,7 @@ import ( | |||||||
| 	"github.com/ethereum/go-ethereum/logger" | 	"github.com/ethereum/go-ethereum/logger" | ||||||
| 	"github.com/ethereum/go-ethereum/miner" | 	"github.com/ethereum/go-ethereum/miner" | ||||||
| 	"github.com/ethereum/go-ethereum/p2p" | 	"github.com/ethereum/go-ethereum/p2p" | ||||||
|  | 	"github.com/ethereum/go-ethereum/state" | ||||||
| 	"github.com/ethereum/go-ethereum/whisper" | 	"github.com/ethereum/go-ethereum/whisper" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -54,13 +55,26 @@ func New(eth Backend) *XEth { | |||||||
| 		whisper:        NewWhisper(eth.Whisper()), | 		whisper:        NewWhisper(eth.Whisper()), | ||||||
| 		miner:          eth.Miner(), | 		miner:          eth.Miner(), | ||||||
| 	} | 	} | ||||||
| 	xeth.state = NewState(xeth) | 	xeth.state = NewState(xeth, xeth.chainManager.TransState()) | ||||||
|  |  | ||||||
| 	return xeth | 	return xeth | ||||||
| } | } | ||||||
|  |  | ||||||
| func (self *XEth) Backend() Backend    { return self.eth } | func (self *XEth) Backend() Backend { return self.eth } | ||||||
| func (self *XEth) State() *State       { return self.state } | 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) Whisper() *Whisper   { return self.whisper } | ||||||
| func (self *XEth) Miner() *miner.Miner { return self.miner } | 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 ( | 	var ( | ||||||
| 		statedb = self.chainManager.TransState() | 		statedb = self.State().State() //self.chainManager.TransState() | ||||||
| 		key     = self.eth.KeyManager().KeyPair() | 		key     = self.eth.KeyManager().KeyPair() | ||||||
| 		from    = statedb.GetOrNewStateObject(key.Address()) | 		from    = statedb.GetOrNewStateObject(key.Address()) | ||||||
| 		block   = self.chainManager.CurrentBlock() | 		block   = self.chainManager.CurrentBlock() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user