Merge branch 'master' into hotfix/0.8.5-2
This commit is contained in:
		| @@ -1,8 +1,8 @@ | ||||
| language: go | ||||
| go: | ||||
|   - 1.4.1 | ||||
|   - 1.4.2 | ||||
| before_install: | ||||
|   - sudo add-apt-repository ppa:beineri/opt-qt54 -y | ||||
|   - sudo add-apt-repository ppa:beineri/opt-qt541 -y | ||||
|   - sudo apt-get update -qq | ||||
|   - sudo apt-get install -yqq libgmp3-dev libreadline6-dev qt54quickcontrols qt54webengine | ||||
| install: | ||||
|   | ||||
							
								
								
									
										11
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							| @@ -1,15 +1,10 @@ | ||||
| { | ||||
| 	"ImportPath": "github.com/ethereum/go-ethereum", | ||||
| 	"GoVersion": "go1.4.1", | ||||
| 	"GoVersion": "go1.4.2", | ||||
| 	"Packages": [ | ||||
| 		"./..." | ||||
| 	], | ||||
| 	"Deps": [ | ||||
| 		{ | ||||
| 			"ImportPath": "bitbucket.org/kardianos/osext", | ||||
| 			"Comment": "null-13", | ||||
| 			"Rev": "5d3ddcf53a508cc2f7404eaebf546ef2cb5cdb6e" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "code.google.com/p/go-uuid/uuid", | ||||
| 			"Comment": "null-12", | ||||
| @@ -37,6 +32,10 @@ | ||||
| 			"ImportPath": "github.com/jackpal/go-nat-pmp", | ||||
| 			"Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "github.com/kardianos/osext", | ||||
| 			"Rev": "ccfcd0245381f0c94c68f50626665eed3c6b726a" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "github.com/obscuren/otto", | ||||
| 			"Rev": "cf13cc4228c5e5ce0fe27a7aea90bc10091c4f19" | ||||
|   | ||||
							
								
								
									
										20
									
								
								Godeps/_workspace/src/bitbucket.org/kardianos/osext/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								Godeps/_workspace/src/bitbucket.org/kardianos/osext/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,20 +0,0 @@ | ||||
| Copyright (c) 2012 Daniel Theophanes | ||||
|  | ||||
| This software is provided 'as-is', without any express or implied | ||||
| warranty. In no event will the authors be held liable for any damages | ||||
| arising from the use of this software. | ||||
|  | ||||
| Permission is granted to anyone to use this software for any purpose, | ||||
| including commercial applications, and to alter it and redistribute it | ||||
| freely, subject to the following restrictions: | ||||
|  | ||||
|    1. The origin of this software must not be misrepresented; you must not | ||||
|    claim that you wrote the original software. If you use this software | ||||
|    in a product, an acknowledgment in the product documentation would be | ||||
|    appreciated but is not required. | ||||
|  | ||||
|    2. Altered source versions must be plainly marked as such, and must not be | ||||
|    misrepresented as being the original software. | ||||
|  | ||||
|    3. This notice may not be removed or altered from any source | ||||
|    distribution. | ||||
							
								
								
									
										27
									
								
								Godeps/_workspace/src/github.com/kardianos/osext/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								Godeps/_workspace/src/github.com/kardianos/osext/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| Copyright (c) 2012 The Go Authors. All rights reserved. | ||||
|  | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
|  | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
|  | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										14
									
								
								Godeps/_workspace/src/github.com/kardianos/osext/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Godeps/_workspace/src/github.com/kardianos/osext/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| ### Extensions to the "os" package. | ||||
|  | ||||
| ## Find the current Executable and ExecutableFolder. | ||||
|  | ||||
| There is sometimes utility in finding the current executable file | ||||
| that is running. This can be used for upgrading the current executable | ||||
| or finding resources located relative to the executable file. | ||||
|  | ||||
| Multi-platform and supports: | ||||
|  * Linux | ||||
|  * OS X | ||||
|  * Windows | ||||
|  * Plan 9 | ||||
|  * BSDs. | ||||
| @@ -25,8 +25,3 @@ func ExecutableFolder() (string, error) { | ||||
| 	folder, _ := filepath.Split(p) | ||||
| 	return folder, nil | ||||
| } | ||||
| 
 | ||||
| // Depricated. Same as Executable(). | ||||
| func GetExePath() (exePath string, err error) { | ||||
| 	return Executable() | ||||
| } | ||||
| @@ -5,16 +5,16 @@ | ||||
| package osext | ||||
| 
 | ||||
| import ( | ||||
|     "syscall" | ||||
|     "os" | ||||
|     "strconv" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"syscall" | ||||
| ) | ||||
| 
 | ||||
| func executable() (string, error) { | ||||
|     f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text") | ||||
|     if err != nil { | ||||
|         return "", err | ||||
|     } | ||||
|     defer f.Close() | ||||
|     return syscall.Fd2path(int(f.Fd())) | ||||
| 	f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text") | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| 	return syscall.Fd2path(int(f.Fd())) | ||||
| } | ||||
| @@ -2,12 +2,13 @@ | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // +build linux netbsd openbsd | ||||
| // +build linux netbsd openbsd solaris dragonfly | ||||
| 
 | ||||
| package osext | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"runtime" | ||||
| ) | ||||
| @@ -18,8 +19,10 @@ func executable() (string, error) { | ||||
| 		return os.Readlink("/proc/self/exe") | ||||
| 	case "netbsd": | ||||
| 		return os.Readlink("/proc/curproc/exe") | ||||
| 	case "openbsd": | ||||
| 	case "openbsd", "dragonfly": | ||||
| 		return os.Readlink("/proc/curproc/file") | ||||
| 	case "solaris": | ||||
| 		return os.Readlink(fmt.Sprintf("/proc/%d/path/a.out", os.Getpid())) | ||||
| 	} | ||||
| 	return "", errors.New("ExecPath not implemented for " + runtime.GOOS) | ||||
| } | ||||
| @@ -34,33 +34,62 @@ package accounts | ||||
|  | ||||
| import ( | ||||
| 	crand "crypto/rand" | ||||
|  | ||||
| 	"errors" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| ) | ||||
|  | ||||
| var ErrLocked = errors.New("account is locked; please request passphrase") | ||||
|  | ||||
| // TODO: better name for this struct? | ||||
| type Account struct { | ||||
| 	Address []byte | ||||
| } | ||||
|  | ||||
| type AccountManager struct { | ||||
| 	keyStore crypto.KeyStore2 | ||||
| 	keyStore           crypto.KeyStore2 | ||||
| 	unlockedKeys       map[string]crypto.Key | ||||
| 	unlockMilliseconds time.Duration | ||||
| 	mutex              sync.RWMutex | ||||
| } | ||||
|  | ||||
| // TODO: get key by addr - modify KeyStore2 GetKey to work with addr | ||||
|  | ||||
| // TODO: pass through passphrase for APIs which require access to private key? | ||||
| func NewAccountManager(keyStore crypto.KeyStore2) AccountManager { | ||||
| func NewAccountManager(keyStore crypto.KeyStore2, unlockMilliseconds time.Duration) AccountManager { | ||||
| 	keysMap := make(map[string]crypto.Key) | ||||
| 	am := &AccountManager{ | ||||
| 		keyStore: keyStore, | ||||
| 		keyStore:           keyStore, | ||||
| 		unlockedKeys:       keysMap, | ||||
| 		unlockMilliseconds: unlockMilliseconds, | ||||
| 	} | ||||
| 	return *am | ||||
| } | ||||
|  | ||||
| func (am *AccountManager) Sign(fromAccount *Account, keyAuth string, toSign []byte) (signature []byte, err error) { | ||||
| func (am AccountManager) DeleteAccount(address []byte, auth string) error { | ||||
| 	return am.keyStore.DeleteKey(address, auth) | ||||
| } | ||||
|  | ||||
| func (am *AccountManager) Sign(fromAccount *Account, toSign []byte) (signature []byte, err error) { | ||||
| 	am.mutex.RLock() | ||||
| 	unlockedKey := am.unlockedKeys[string(fromAccount.Address)] | ||||
| 	am.mutex.RUnlock() | ||||
| 	if unlockedKey.Address == nil { | ||||
| 		return nil, ErrLocked | ||||
| 	} | ||||
| 	signature, err = crypto.Sign(toSign, unlockedKey.PrivateKey) | ||||
| 	return signature, err | ||||
| } | ||||
|  | ||||
| func (am *AccountManager) SignLocked(fromAccount *Account, keyAuth string, toSign []byte) (signature []byte, err error) { | ||||
| 	key, err := am.keyStore.GetKey(fromAccount.Address, keyAuth) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	am.mutex.RLock() | ||||
| 	am.unlockedKeys[string(fromAccount.Address)] = *key | ||||
| 	am.mutex.RUnlock() | ||||
| 	go unlockLater(am, fromAccount.Address) | ||||
| 	signature, err = crypto.Sign(toSign, key.PrivateKey) | ||||
| 	return signature, err | ||||
| } | ||||
| @@ -76,8 +105,6 @@ func (am AccountManager) NewAccount(auth string) (*Account, error) { | ||||
| 	return ua, err | ||||
| } | ||||
|  | ||||
| // set of accounts == set of keys in given key store | ||||
| // TODO: do we need persistence of accounts as well? | ||||
| func (am *AccountManager) Accounts() ([]Account, error) { | ||||
| 	addresses, err := am.keyStore.GetKeyAddresses() | ||||
| 	if err != nil { | ||||
| @@ -93,3 +120,13 @@ func (am *AccountManager) Accounts() ([]Account, error) { | ||||
| 	} | ||||
| 	return accounts, err | ||||
| } | ||||
|  | ||||
| func unlockLater(am *AccountManager, addr []byte) { | ||||
| 	select { | ||||
| 	case <-time.After(time.Millisecond * am.unlockMilliseconds): | ||||
| 	} | ||||
| 	am.mutex.RLock() | ||||
| 	// TODO: how do we know the key is actually gone from memory? | ||||
| 	delete(am.unlockedKeys, string(addr)) | ||||
| 	am.mutex.RUnlock() | ||||
| } | ||||
|   | ||||
| @@ -5,16 +5,78 @@ import ( | ||||
|  | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/crypto/randentropy" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| func TestAccountManager(t *testing.T) { | ||||
| 	ks := crypto.NewKeyStorePlain(crypto.DefaultDataDir()) | ||||
| 	am := NewAccountManager(ks) | ||||
| 	ks := crypto.NewKeyStorePlain(ethutil.DefaultDataDir() + "/testaccounts") | ||||
| 	am := NewAccountManager(ks, 100) | ||||
| 	pass := "" // not used but required by API | ||||
| 	a1, err := am.NewAccount(pass) | ||||
| 	toSign := randentropy.GetEntropyCSPRNG(32) | ||||
| 	_, err = am.Sign(a1, pass, toSign) | ||||
| 	_, err = am.SignLocked(a1, pass, toSign) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// Cleanup | ||||
| 	time.Sleep(time.Millisecond * 150) // wait for locking | ||||
|  | ||||
| 	accounts, err := am.Accounts() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	for _, account := range accounts { | ||||
| 		err := am.DeleteAccount(account.Address, pass) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestAccountManagerLocking(t *testing.T) { | ||||
| 	ks := crypto.NewKeyStorePassphrase(ethutil.DefaultDataDir() + "/testaccounts") | ||||
| 	am := NewAccountManager(ks, 200) | ||||
| 	pass := "foo" | ||||
| 	a1, err := am.NewAccount(pass) | ||||
| 	toSign := randentropy.GetEntropyCSPRNG(32) | ||||
|  | ||||
| 	// Signing without passphrase fails because account is locked | ||||
| 	_, err = am.Sign(a1, toSign) | ||||
| 	if err != ErrLocked { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// Signing with passphrase works | ||||
| 	_, err = am.SignLocked(a1, pass, toSign) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// Signing without passphrase works because account is temp unlocked | ||||
| 	_, err = am.Sign(a1, toSign) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// Signing without passphrase fails after automatic locking | ||||
| 	time.Sleep(time.Millisecond * time.Duration(250)) | ||||
|  | ||||
| 	_, err = am.Sign(a1, toSign) | ||||
| 	if err != ErrLocked { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	// Cleanup | ||||
| 	accounts, err := am.Accounts() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	for _, account := range accounts { | ||||
| 		err := am.DeleteAccount(account.Address, pass) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -26,10 +26,10 @@ import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path" | ||||
|  | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/p2p/nat" | ||||
| 	"github.com/ethereum/go-ethereum/vm" | ||||
| @@ -79,12 +79,7 @@ var ( | ||||
| 	InputFile      string | ||||
| ) | ||||
|  | ||||
| func defaultDataDir() string { | ||||
| 	usr, _ := user.Current() | ||||
| 	return path.Join(usr.HomeDir, ".ethereum") | ||||
| } | ||||
|  | ||||
| var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini") | ||||
| var defaultConfigFile = path.Join(ethutil.DefaultDataDir(), "conf.ini") | ||||
|  | ||||
| func Init() { | ||||
| 	// TODO: move common flag processing to cmd/util | ||||
| @@ -107,7 +102,7 @@ func Init() { | ||||
| 	flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)") | ||||
| 	flag.StringVar(&ExportDir, "export", "", "exports the session keyring to files in the directory given") | ||||
| 	flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)") | ||||
| 	flag.StringVar(&Datadir, "datadir", defaultDataDir(), "specifies the datadir to use") | ||||
| 	flag.StringVar(&Datadir, "datadir", ethutil.DefaultDataDir(), "specifies the datadir to use") | ||||
| 	flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file") | ||||
| 	flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)") | ||||
| 	flag.IntVar(&LogLevel, "loglevel", int(logger.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)") | ||||
|   | ||||
| @@ -62,6 +62,8 @@ | ||||
|  | ||||
|     web3.setProvider(new web3.providers.HttpSyncProvider('http://localhost:8545')); | ||||
|  | ||||
|     eth.defaultBlock = -2 | ||||
|  | ||||
|     document.querySelector("#number").innerHTML = eth.number; | ||||
|     document.querySelector("#coinbase").innerHTML = eth.coinbase | ||||
|     document.querySelector("#peer_count").innerHTML = eth.peerCount; | ||||
| @@ -72,8 +74,9 @@ | ||||
|     document.querySelector("#mining").innerHTML = eth.mining; | ||||
|     document.querySelector("#listening").innerHTML = eth.listening; | ||||
|     eth.watch('chain').changed(function() { | ||||
| 		    document.querySelector("#number").innerHTML = eth.number; | ||||
| 		     }); | ||||
|         document.querySelector("#number").innerHTML = eth.number; | ||||
|     }); | ||||
|  | ||||
|  | ||||
| </script> | ||||
|  | ||||
|   | ||||
							
								
								
									
										816
									
								
								cmd/mist/assets/ext/ethereum.js/dist/ethereum.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										816
									
								
								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" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
|  | ||||
| 	"bitbucket.org/kardianos/osext" | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/p2p/nat" | ||||
| 	"github.com/ethereum/go-ethereum/vm" | ||||
| @@ -68,38 +66,7 @@ var ( | ||||
|  | ||||
| // flags specific to gui client | ||||
| var AssetPath string | ||||
|  | ||||
| //TODO: If we re-use the one defined in cmd.go the binary osx image crashes. If somebody finds out why we can dry this up. | ||||
| func defaultAssetPath() string { | ||||
| 	var assetPath string | ||||
| 	// If the current working directory is the go-ethereum dir | ||||
| 	// assume a debug build and use the source directory as | ||||
| 	// asset directory. | ||||
| 	pwd, _ := os.Getwd() | ||||
| 	if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist") { | ||||
| 		assetPath = path.Join(pwd, "assets") | ||||
| 	} else { | ||||
| 		switch runtime.GOOS { | ||||
| 		case "darwin": | ||||
| 			// Get Binary Directory | ||||
| 			exedir, _ := osext.ExecutableFolder() | ||||
| 			assetPath = filepath.Join(exedir, "../Resources") | ||||
| 		case "linux": | ||||
| 			assetPath = "/usr/share/mist" | ||||
| 		case "windows": | ||||
| 			assetPath = "./assets" | ||||
| 		default: | ||||
| 			assetPath = "." | ||||
| 		} | ||||
| 	} | ||||
| 	return assetPath | ||||
| } | ||||
| func defaultDataDir() string { | ||||
| 	usr, _ := user.Current() | ||||
| 	return path.Join(usr.HomeDir, ".ethereum") | ||||
| } | ||||
|  | ||||
| var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini") | ||||
| var defaultConfigFile = path.Join(ethutil.DefaultDataDir(), "conf.ini") | ||||
|  | ||||
| func Init() { | ||||
| 	// TODO: move common flag processing to cmd/utils | ||||
| @@ -121,12 +88,12 @@ func Init() { | ||||
| 	flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)") | ||||
| 	flag.StringVar(&ExportDir, "export", "", "exports the session keyring to files in the directory given") | ||||
| 	flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)") | ||||
| 	flag.StringVar(&Datadir, "datadir", defaultDataDir(), "specifies the datadir to use") | ||||
| 	flag.StringVar(&Datadir, "datadir", ethutil.DefaultDataDir(), "specifies the datadir to use") | ||||
| 	flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file") | ||||
| 	flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)") | ||||
| 	flag.IntVar(&LogLevel, "loglevel", int(logger.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)") | ||||
|  | ||||
| 	flag.StringVar(&AssetPath, "asset_path", defaultAssetPath(), "absolute path to GUI assets directory") | ||||
| 	flag.StringVar(&AssetPath, "asset_path", ethutil.DefaultAssetPath(), "absolute path to GUI assets directory") | ||||
|  | ||||
| 	// Network stuff | ||||
| 	var ( | ||||
|   | ||||
| @@ -25,12 +25,8 @@ import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"os/signal" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"regexp" | ||||
| 	"runtime" | ||||
|  | ||||
| 	"bitbucket.org/kardianos/osext" | ||||
| 	"github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/eth" | ||||
| @@ -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) { | ||||
|  | ||||
| 	var err error | ||||
|   | ||||
| @@ -48,9 +48,8 @@ type BlockProcessor struct { | ||||
|  | ||||
| func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor { | ||||
| 	sm := &BlockProcessor{ | ||||
| 		db:  db, | ||||
| 		mem: make(map[string]*big.Int), | ||||
| 		//Pow:      ðash.Ethash{}, | ||||
| 		db:       db, | ||||
| 		mem:      make(map[string]*big.Int), | ||||
| 		Pow:      ezp.New(), | ||||
| 		bc:       chainManager, | ||||
| 		eventMux: eventMux, | ||||
| @@ -62,7 +61,7 @@ func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainM | ||||
|  | ||||
| func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block, transientProcess bool) (receipts types.Receipts, err error) { | ||||
| 	coinbase := statedb.GetOrNewStateObject(block.Header().Coinbase) | ||||
| 	coinbase.SetGasPool(CalcGasLimit(parent, block)) | ||||
| 	coinbase.SetGasPool(block.Header().GasLimit) | ||||
|  | ||||
| 	// Process the transactions on to parent state | ||||
| 	receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), transientProcess) | ||||
| @@ -100,7 +99,8 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated | ||||
| 	// Notify all subscribers | ||||
| 	if !transientProcess { | ||||
| 		go self.eventMux.Post(TxPostEvent{tx}) | ||||
| 		go self.eventMux.Post(statedb.Logs()) | ||||
| 		logs := statedb.Logs() | ||||
| 		go self.eventMux.Post(logs) | ||||
| 	} | ||||
|  | ||||
| 	return receipt, txGas, err | ||||
| @@ -247,6 +247,11 @@ func (sm *BlockProcessor) ValidateBlock(block, parent *types.Block) error { | ||||
| 		return fmt.Errorf("Difficulty check failed for block %v, %v", block.Header().Difficulty, expd) | ||||
| 	} | ||||
|  | ||||
| 	expl := CalcGasLimit(parent, block) | ||||
| 	if expl.Cmp(block.Header().GasLimit) != 0 { | ||||
| 		return fmt.Errorf("GasLimit check failed for block %v, %v", block.Header().GasLimit, expl) | ||||
| 	} | ||||
|  | ||||
| 	if block.Time() < parent.Time() { | ||||
| 		return ValidationError("Block timestamp not after prev block (%v - %v)", block.Header().Time, parent.Header().Time) | ||||
| 	} | ||||
|   | ||||
| @@ -283,7 +283,6 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	fmt.Printf("get hash %x (%d)\n", hash, len(chain)) | ||||
|  | ||||
| 	return | ||||
| } | ||||
|   | ||||
| @@ -126,7 +126,7 @@ func (self *StateTransition) BuyGas() error { | ||||
|  | ||||
| 	self.AddGas(self.msg.Gas()) | ||||
| 	self.initialGas.Set(self.msg.Gas()) | ||||
| 	sender.SubAmount(MessageGasValue(self.msg)) | ||||
| 	sender.SubBalance(MessageGasValue(self.msg)) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| @@ -251,13 +251,16 @@ func (self *StateTransition) RefundGas() { | ||||
| 	coinbase, sender := self.Coinbase(), self.From() | ||||
| 	// Return remaining gas | ||||
| 	remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice()) | ||||
| 	sender.AddAmount(remaining) | ||||
| 	fmt.Println("REFUND:", remaining) | ||||
| 	sender.AddBalance(remaining) | ||||
|  | ||||
| 	uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2) | ||||
| 	for addr, ref := range self.state.Refunds() { | ||||
| 		refund := ethutil.BigMin(uhalf, ref) | ||||
| 		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()) | ||||
|   | ||||
| @@ -30,7 +30,6 @@ import ( | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path" | ||||
| ) | ||||
|  | ||||
| @@ -48,12 +47,6 @@ type keyStorePlain struct { | ||||
| 	keysDirPath string | ||||
| } | ||||
|  | ||||
| // TODO: copied from cmd/ethereum/flags.go | ||||
| func DefaultDataDir() string { | ||||
| 	usr, _ := user.Current() | ||||
| 	return path.Join(usr.HomeDir, ".ethereum") | ||||
| } | ||||
|  | ||||
| func NewKeyStorePlain(path string) KeyStore2 { | ||||
| 	return &keyStorePlain{path} | ||||
| } | ||||
| @@ -126,8 +119,11 @@ func GetKeyAddresses(keysDirPath string) (addresses [][]byte, err error) { | ||||
| 	} | ||||
| 	addresses = make([][]byte, len(fileInfos)) | ||||
| 	for i, fileInfo := range fileInfos { | ||||
| 		addresses[i] = make([]byte, 40) | ||||
| 		addresses[i] = []byte(fileInfo.Name()) | ||||
| 		address, err := hex.DecodeString(fileInfo.Name()) | ||||
| 		if err != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		addresses[i] = address | ||||
| 	} | ||||
| 	return addresses, err | ||||
| } | ||||
|   | ||||
| @@ -2,12 +2,13 @@ package crypto | ||||
|  | ||||
| import ( | ||||
| 	"github.com/ethereum/go-ethereum/crypto/randentropy" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func TestKeyStorePlain(t *testing.T) { | ||||
| 	ks := NewKeyStorePlain(DefaultDataDir()) | ||||
| 	ks := NewKeyStorePlain(ethutil.DefaultDataDir()) | ||||
| 	pass := "" // not used but required by API | ||||
| 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | ||||
| 	if err != nil { | ||||
| @@ -35,7 +36,7 @@ func TestKeyStorePlain(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestKeyStorePassphrase(t *testing.T) { | ||||
| 	ks := NewKeyStorePassphrase(DefaultDataDir()) | ||||
| 	ks := NewKeyStorePassphrase(ethutil.DefaultDataDir()) | ||||
| 	pass := "foo" | ||||
| 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | ||||
| 	if err != nil { | ||||
| @@ -61,7 +62,7 @@ func TestKeyStorePassphrase(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestKeyStorePassphraseDecryptionFail(t *testing.T) { | ||||
| 	ks := NewKeyStorePassphrase(DefaultDataDir()) | ||||
| 	ks := NewKeyStorePassphrase(ethutil.DefaultDataDir()) | ||||
| 	pass := "foo" | ||||
| 	k1, err := ks.GenerateNewKey(randentropy.Reader, pass) | ||||
| 	if err != nil { | ||||
| @@ -89,7 +90,7 @@ func TestImportPreSaleKey(t *testing.T) { | ||||
| 	// python pyethsaletool.py genwallet | ||||
| 	// with password "foo" | ||||
| 	fileContent := "{\"encseed\": \"26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba\", \"ethaddr\": \"d4584b5f6229b7be90727b0fc8c6b91bb427821f\", \"email\": \"gustav.simonsson@gmail.com\", \"btcaddr\": \"1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx\"}" | ||||
| 	ks := NewKeyStorePassphrase(DefaultDataDir()) | ||||
| 	ks := NewKeyStorePassphrase(ethutil.DefaultDataDir()) | ||||
| 	pass := "foo" | ||||
| 	_, err := ImportPreSaleKey(ks, []byte(fileContent), pass) | ||||
| 	if err != nil { | ||||
|   | ||||
| @@ -3,10 +3,51 @@ package ethutil | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"math/big" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 	"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 { | ||||
| 	return runtime.GOOS == "windows" | ||||
| } | ||||
|   | ||||
| @@ -3,7 +3,6 @@ package filter | ||||
| // TODO make use of the generic filtering system | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"sync" | ||||
|  | ||||
| 	"github.com/ethereum/go-ethereum/core" | ||||
| @@ -75,7 +74,6 @@ out: | ||||
| 		case event := <-events.Chan(): | ||||
| 			switch event := event.(type) { | ||||
| 			case core.ChainEvent: | ||||
| 				fmt.Println("filter start") | ||||
| 				self.filterMu.RLock() | ||||
| 				for _, filter := range self.filters { | ||||
| 					if filter.BlockCallback != nil { | ||||
| @@ -83,7 +81,6 @@ out: | ||||
| 					} | ||||
| 				} | ||||
| 				self.filterMu.RUnlock() | ||||
| 				fmt.Println("filter stop") | ||||
|  | ||||
| 			case core.PendingBlockEvent: | ||||
| 				self.filterMu.RLock() | ||||
|   | ||||
| @@ -197,7 +197,7 @@ gasLimit: | ||||
| 	} | ||||
| 	self.eth.TxPool().RemoveSet(remove) | ||||
|  | ||||
| 	self.current.coinbase.AddAmount(core.BlockReward) | ||||
| 	self.current.coinbase.AddBalance(core.BlockReward) | ||||
|  | ||||
| 	self.current.state.Update(ethutil.Big0) | ||||
| 	self.push() | ||||
| @@ -225,7 +225,7 @@ func (self *worker) commitUncle(uncle *types.Header) error { | ||||
| 	} | ||||
|  | ||||
| 	uncleAccount := self.current.state.GetAccount(uncle.Coinbase) | ||||
| 	uncleAccount.AddAmount(uncleReward) | ||||
| 	uncleAccount.AddBalance(uncleReward) | ||||
|  | ||||
| 	self.current.coinbase.AddBalance(uncleReward) | ||||
|  | ||||
|   | ||||
| @@ -20,18 +20,24 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/ethereum/go-ethereum/ethdb" | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/event" | ||||
| 	"github.com/ethereum/go-ethereum/event/filter" | ||||
| 	"github.com/ethereum/go-ethereum/state" | ||||
| 	"github.com/ethereum/go-ethereum/ui" | ||||
| 	"github.com/ethereum/go-ethereum/xeth" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	defaultGasPrice = "10000000000000" | ||||
| 	defaultGas      = "10000" | ||||
| var ( | ||||
| 	defaultGasPrice  = big.NewInt(10000000000000) | ||||
| 	defaultGas       = big.NewInt(10000) | ||||
| 	filterTickerTime = 15 * time.Second | ||||
| ) | ||||
| 
 | ||||
| type EthereumApi struct { | ||||
| 	xeth          *xeth.XEth | ||||
| 	eth    *xeth.XEth | ||||
| 	xethMu sync.RWMutex | ||||
| 	mux    *event.TypeMux | ||||
| 
 | ||||
| 	quit          chan struct{} | ||||
| 	filterManager *filter.FilterManager | ||||
| 
 | ||||
| @@ -45,17 +51,21 @@ type EthereumApi struct { | ||||
| 	register map[string][]*NewTxArgs | ||||
| 
 | ||||
| 	db ethutil.Database | ||||
| 
 | ||||
| 	defaultBlockAge int64 | ||||
| } | ||||
| 
 | ||||
| func NewEthereumApi(eth *xeth.XEth) *EthereumApi { | ||||
| 	db, _ := ethdb.NewLDBDatabase("dapps") | ||||
| 	api := &EthereumApi{ | ||||
| 		xeth:          eth, | ||||
| 		quit:          make(chan struct{}), | ||||
| 		filterManager: filter.NewFilterManager(eth.Backend().EventMux()), | ||||
| 		logs:          make(map[int]*logFilter), | ||||
| 		messages:      make(map[int]*whisperFilter), | ||||
| 		db:            db, | ||||
| 		eth:             eth, | ||||
| 		mux:             eth.Backend().EventMux(), | ||||
| 		quit:            make(chan struct{}), | ||||
| 		filterManager:   filter.NewFilterManager(eth.Backend().EventMux()), | ||||
| 		logs:            make(map[int]*logFilter), | ||||
| 		messages:        make(map[int]*whisperFilter), | ||||
| 		db:              db, | ||||
| 		defaultBlockAge: -1, | ||||
| 	} | ||||
| 	go api.filterManager.Start() | ||||
| 	go api.start() | ||||
| @@ -63,6 +73,64 @@ func NewEthereumApi(eth *xeth.XEth) *EthereumApi { | ||||
| 	return api | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) setStateByBlockNumber(num int64) { | ||||
| 	chain := self.xeth().Backend().ChainManager() | ||||
| 	var block *types.Block | ||||
| 
 | ||||
| 	if self.defaultBlockAge < 0 { | ||||
| 		num = chain.CurrentBlock().Number().Int64() + num + 1 | ||||
| 	} | ||||
| 	block = chain.GetBlockByNumber(uint64(num)) | ||||
| 
 | ||||
| 	if block != nil { | ||||
| 		self.useState(state.New(block.Root(), self.xeth().Backend().Db())) | ||||
| 	} else { | ||||
| 		self.useState(chain.State()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) start() { | ||||
| 	timer := time.NewTicker(filterTickerTime) | ||||
| 	events := self.mux.Subscribe(core.ChainEvent{}) | ||||
| 
 | ||||
| done: | ||||
| 	for { | ||||
| 		select { | ||||
| 		case ev := <-events.Chan(): | ||||
| 			switch ev.(type) { | ||||
| 			case core.ChainEvent: | ||||
| 				if self.defaultBlockAge < 0 { | ||||
| 					self.setStateByBlockNumber(self.defaultBlockAge) | ||||
| 				} | ||||
| 			} | ||||
| 		case <-timer.C: | ||||
| 			self.logMut.Lock() | ||||
| 			self.messagesMut.Lock() | ||||
| 			for id, filter := range self.logs { | ||||
| 				if time.Since(filter.timeout) > 20*time.Second { | ||||
| 					self.filterManager.UninstallFilter(id) | ||||
| 					delete(self.logs, id) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			for id, filter := range self.messages { | ||||
| 				if time.Since(filter.timeout) > 20*time.Second { | ||||
| 					self.xeth().Whisper().Unwatch(id) | ||||
| 					delete(self.messages, id) | ||||
| 				} | ||||
| 			} | ||||
| 			self.logMut.Unlock() | ||||
| 			self.messagesMut.Unlock() | ||||
| 		case <-self.quit: | ||||
| 			break done | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) stop() { | ||||
| 	close(self.quit) | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) Register(args string, reply *interface{}) error { | ||||
| 	self.regmut.Lock() | ||||
| 	defer self.regmut.Unlock() | ||||
| @@ -95,7 +163,7 @@ func (self *EthereumApi) WatchTx(args string, reply *interface{}) error { | ||||
| 
 | ||||
| func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error { | ||||
| 	var id int | ||||
| 	filter := core.NewFilter(self.xeth.Backend()) | ||||
| 	filter := core.NewFilter(self.xeth().Backend()) | ||||
| 	filter.SetOptions(toFilterOptions(args)) | ||||
| 	filter.LogsCallback = func(logs state.Logs) { | ||||
| 		self.logMut.Lock() | ||||
| @@ -120,7 +188,7 @@ func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error { | ||||
| 
 | ||||
| func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error { | ||||
| 	var id int | ||||
| 	filter := core.NewFilter(self.xeth.Backend()) | ||||
| 	filter := core.NewFilter(self.xeth().Backend()) | ||||
| 
 | ||||
| 	callback := func(block *types.Block) { | ||||
| 		self.logMut.Lock() | ||||
| @@ -165,7 +233,7 @@ func (self *EthereumApi) Logs(id int, reply *interface{}) error { | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error { | ||||
| 	filter := core.NewFilter(self.xeth.Backend()) | ||||
| 	filter := core.NewFilter(self.xeth().Backend()) | ||||
| 	filter.SetOptions(toFilterOptions(args)) | ||||
| 
 | ||||
| 	*reply = toLogs(filter.Find()) | ||||
| @@ -174,41 +242,54 @@ func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error { | ||||
| 	err := args.requirements() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if args.BlockNumber > 0 { | ||||
| 		*reply = p.xeth.BlockByNumber(args.BlockNumber) | ||||
| 	// This seems a bit precarious Maybe worth splitting to discrete functions | ||||
| 	if len(args.Hash) > 0 { | ||||
| 		*reply = p.xeth().BlockByHash(args.Hash) | ||||
| 	} else { | ||||
| 		*reply = p.xeth.BlockByHash(args.Hash) | ||||
| 		*reply = p.xeth().BlockByNumber(args.BlockNumber) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error { | ||||
| 	if len(args.Gas) == 0 { | ||||
| 		args.Gas = defaultGas | ||||
| 		args.Gas = defaultGas.String() | ||||
| 	} | ||||
| 
 | ||||
| 	if len(args.GasPrice) == 0 { | ||||
| 		args.GasPrice = defaultGasPrice | ||||
| 		args.GasPrice = defaultGasPrice.String() | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO if no_private_key then | ||||
| 	if _, exists := p.register[args.From]; exists { | ||||
| 		p.register[args.From] = append(p.register[args.From], args) | ||||
| 	} else { | ||||
| 		result, _ := p.xeth.Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) | ||||
| 		*reply = result | ||||
| 	} | ||||
| 	//if _, exists := p.register[args.From]; exists { | ||||
| 	//	p.register[args.From] = append(p.register[args.From], args) | ||||
| 	//} else { | ||||
| 	/* | ||||
| 		account := accounts.Get(fromHex(args.From)) | ||||
| 		if account != nil { | ||||
| 			if account.Unlocked() { | ||||
| 				if !unlockAccount(account) { | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			result, _ := account.Transact(fromHex(args.To), fromHex(args.Value), fromHex(args.Gas), fromHex(args.GasPrice), fromHex(args.Data)) | ||||
| 			if len(result) > 0 { | ||||
| 				*reply = toHex(result) | ||||
| 			} | ||||
| 		} else if _, exists := p.register[args.From]; exists { | ||||
| 			p.register[ags.From] = append(p.register[args.From], args) | ||||
| 		} | ||||
| 	*/ | ||||
| 	result, _ := p.xeth().Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) | ||||
| 	*reply = result | ||||
| 	//} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error { | ||||
| 	result, err := p.xeth.Call( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) | ||||
| 	result, err := p.xeth().Call( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -222,7 +303,7 @@ func (p *EthereumApi) PushTx(args *PushTxArgs, reply *interface{}) error { | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	result, _ := p.xeth.PushTx(args.Tx) | ||||
| 	result, _ := p.xeth().PushTx(args.Tx) | ||||
| 	*reply = result | ||||
| 	return nil | ||||
| } | ||||
| @@ -233,7 +314,7 @@ func (p *EthereumApi) GetStateAt(args *GetStateArgs, reply *interface{}) error { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	state := p.xeth.State().SafeGet(args.Address) | ||||
| 	state := p.xeth().State().SafeGet(args.Address) | ||||
| 
 | ||||
| 	value := state.StorageString(args.Key) | ||||
| 	var hx string | ||||
| @@ -255,42 +336,55 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageArgs, reply *interface{}) err | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	*reply = p.xeth.State().SafeGet(args.Address).Storage() | ||||
| 	*reply = p.xeth().State().SafeGet(args.Address).Storage() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetPeerCount(reply *interface{}) error { | ||||
| 	*reply = p.xeth.PeerCount() | ||||
| 	*reply = p.xeth().PeerCount() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetIsListening(reply *interface{}) error { | ||||
| 	*reply = p.xeth.IsListening() | ||||
| 	*reply = p.xeth().IsListening() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetCoinbase(reply *interface{}) error { | ||||
| 	*reply = p.xeth.Coinbase() | ||||
| 	*reply = p.xeth().Coinbase() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) Accounts(reply *interface{}) error { | ||||
| 	*reply = p.xeth.Accounts() | ||||
| 	*reply = p.xeth().Accounts() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetIsMining(reply *interface{}) error { | ||||
| 	*reply = p.xeth.IsMining() | ||||
| 	*reply = p.xeth().IsMining() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) SetMining(shouldmine bool, reply *interface{}) error { | ||||
| 	*reply = p.xeth.SetMining(shouldmine) | ||||
| 	*reply = p.xeth().SetMining(shouldmine) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetDefaultBlockAge(reply *interface{}) error { | ||||
| 	*reply = p.defaultBlockAge | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) SetDefaultBlockAge(defaultBlockAge int64, reply *interface{}) error { | ||||
| 	p.defaultBlockAge = defaultBlockAge | ||||
| 	p.setStateByBlockNumber(p.defaultBlockAge) | ||||
| 
 | ||||
| 	*reply = true | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) BlockNumber(reply *interface{}) error { | ||||
| 	*reply = p.xeth.Backend().ChainManager().CurrentBlock().Number() | ||||
| 	*reply = p.xeth().Backend().ChainManager().CurrentBlock().Number() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @@ -299,7 +393,7 @@ func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) err | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	*reply = p.xeth.TxCountAt(args.Address) | ||||
| 	*reply = p.xeth().TxCountAt(args.Address) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @@ -308,7 +402,7 @@ func (p *EthereumApi) GetBalanceAt(args *GetBalanceArgs, reply *interface{}) err | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	state := p.xeth.State().SafeGet(args.Address) | ||||
| 	state := p.xeth().State().SafeGet(args.Address) | ||||
| 	*reply = toHex(state.Balance().Bytes()) | ||||
| 	return nil | ||||
| } | ||||
| @@ -318,7 +412,7 @@ func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error { | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	*reply = p.xeth.CodeAt(args.Address) | ||||
| 	*reply = p.xeth().CodeAt(args.Address) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @@ -365,7 +459,7 @@ func (p *EthereumApi) DbGet(args *DbArgs, reply *interface{}) error { | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error { | ||||
| 	*reply = p.xeth.Whisper().NewIdentity() | ||||
| 	*reply = p.xeth().Whisper().NewIdentity() | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @@ -376,7 +470,7 @@ func (p *EthereumApi) NewWhisperFilter(args *xeth.Options, reply *interface{}) e | ||||
| 		defer p.messagesMut.Unlock() | ||||
| 		p.messages[id].add(msg) // = append(p.messages[id], msg) | ||||
| 	} | ||||
| 	id = p.xeth.Whisper().Watch(args) | ||||
| 	id = p.xeth().Whisper().Watch(args) | ||||
| 	p.messages[id] = &whisperFilter{timeout: time.Now()} | ||||
| 	*reply = id | ||||
| 	return nil | ||||
| @@ -394,7 +488,7 @@ func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error { | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) error { | ||||
| 	err := p.xeth.Whisper().Post(args.Payload, args.To, args.From, args.Topic, args.Priority, args.Ttl) | ||||
| 	err := p.xeth().Whisper().Post(args.Payload, args.To, args.From, args.Topic, args.Priority, args.Ttl) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -404,17 +498,17 @@ func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) HasWhisperIdentity(args string, reply *interface{}) error { | ||||
| 	*reply = p.xeth.Whisper().HasIdentity(args) | ||||
| 	*reply = p.xeth().Whisper().HasIdentity(args) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) WhisperMessages(id int, reply *interface{}) error { | ||||
| 	*reply = p.xeth.Whisper().Messages(id) | ||||
| 	*reply = p.xeth().Whisper().Messages(id) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error { | ||||
| 	// Spec at https://github.com/ethereum/wiki/wiki/Generic-ON-RPC | ||||
| 	// Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC | ||||
| 	rpclogger.DebugDetailf("%T %s", req.Params, req.Params) | ||||
| 	switch req.Method { | ||||
| 	case "eth_coinbase": | ||||
| @@ -429,6 +523,14 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error | ||||
| 			return err | ||||
| 		} | ||||
| 		return p.SetMining(args, reply) | ||||
| 	case "eth_defaultBlock": | ||||
| 		return p.GetDefaultBlockAge(reply) | ||||
| 	case "eth_setDefaultBlock": | ||||
| 		args, err := req.ToIntArgs() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		return p.SetDefaultBlockAge(int64(args), reply) | ||||
| 	case "eth_peerCount": | ||||
| 		return p.GetPeerCount(reply) | ||||
| 	case "eth_number": | ||||
| @@ -520,7 +622,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error | ||||
| 		} | ||||
| 		return p.AllLogs(args, reply) | ||||
| 	case "eth_gasPrice": | ||||
| 		*reply = defaultGasPrice | ||||
| 		*reply = toHex(defaultGasPrice.Bytes()) | ||||
| 		return nil | ||||
| 	case "eth_register": | ||||
| 		args, err := req.ToRegisterArgs() | ||||
| @@ -599,44 +701,34 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error | ||||
| 		} | ||||
| 		return p.WhisperMessages(args, reply) | ||||
| 	default: | ||||
| 		return NewErrorResponse(fmt.Sprintf("%v %s", ErrorNotImplemented, req.Method)) | ||||
| 		return NewErrorWithMessage(errNotImplemented, req.Method) | ||||
| 	} | ||||
| 
 | ||||
| 	rpclogger.DebugDetailf("Reply: %T %s", reply, reply) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| var filterTickerTime = 15 * time.Second | ||||
| func (self *EthereumApi) xeth() *xeth.XEth { | ||||
| 	self.xethMu.RLock() | ||||
| 	defer self.xethMu.RUnlock() | ||||
| 
 | ||||
| func (self *EthereumApi) start() { | ||||
| 	timer := time.NewTicker(filterTickerTime) | ||||
| done: | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-timer.C: | ||||
| 			self.logMut.Lock() | ||||
| 			self.messagesMut.Lock() | ||||
| 			for id, filter := range self.logs { | ||||
| 				if time.Since(filter.timeout) > 20*time.Second { | ||||
| 					self.filterManager.UninstallFilter(id) | ||||
| 					delete(self.logs, id) | ||||
| 				} | ||||
| 			} | ||||
| 	return self.eth | ||||
| } | ||||
| 
 | ||||
| 			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) useState(statedb *state.StateDB) { | ||||
| 	self.xethMu.Lock() | ||||
| 	defer self.xethMu.Unlock() | ||||
| 
 | ||||
| 	self.eth = self.eth.UseState(statedb) | ||||
| } | ||||
| 
 | ||||
| func t(f ui.Frontend) { | ||||
| 	// Call the password dialog | ||||
| 	ret, err := f.Call("PasswordDialog") | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *EthereumApi) stop() { | ||||
| 	close(self.quit) | ||||
| 	// Get the first argument | ||||
| 	t, _ := ret.Get(0) | ||||
| 	fmt.Println("return:", t) | ||||
| } | ||||
| @@ -7,6 +7,7 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| func TestFilterClose(t *testing.T) { | ||||
| 	t.Skip() | ||||
| 	api := &EthereumApi{ | ||||
| 		logs:     make(map[int]*logFilter), | ||||
| 		messages: make(map[int]*whisperFilter), | ||||
							
								
								
									
										73
									
								
								rpc/args.go
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								rpc/args.go
									
									
									
									
									
								
							| @@ -19,14 +19,7 @@ func (obj *GetBlockArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		obj.Hash = argstr | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse(ErrorDecodeArgs) | ||||
| } | ||||
|  | ||||
| func (obj *GetBlockArgs) requirements() error { | ||||
| 	if obj.BlockNumber == 0 && obj.Hash == "" { | ||||
| 		return NewErrorResponse("GetBlock requires either a block 'number' or a block 'hash' as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| 	return errDecodeArgs | ||||
| } | ||||
|  | ||||
| type NewTxArgs struct { | ||||
| @@ -64,7 +57,7 @@ func (obj *NewTxArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	return NewErrorResponse(ErrorDecodeArgs) | ||||
| 	return errDecodeArgs | ||||
| } | ||||
|  | ||||
| type PushTxArgs struct { | ||||
| @@ -77,12 +70,12 @@ func (obj *PushTxArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		obj.Tx = arg0 | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse(ErrorDecodeArgs) | ||||
| 	return errDecodeArgs | ||||
| } | ||||
|  | ||||
| func (a *PushTxArgs) requirementsPushTx() error { | ||||
| 	if a.Tx == "" { | ||||
| 		return NewErrorResponse("PushTx requires a 'tx' as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "PushTx requires a 'tx' as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @@ -93,14 +86,14 @@ type GetStorageArgs struct { | ||||
|  | ||||
| func (obj *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 	if err = json.Unmarshal(b, &obj.Address); err != nil { | ||||
| 		return NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return errDecodeArgs | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (a *GetStorageArgs) requirements() error { | ||||
| 	if len(a.Address) == 0 { | ||||
| 		return NewErrorResponse("GetStorageAt requires an 'address' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'address' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @@ -116,64 +109,39 @@ func (obj *GetStateArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		obj.Address = arg0 | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse(ErrorDecodeArgs) | ||||
| 	return errDecodeArgs | ||||
| } | ||||
|  | ||||
| func (a *GetStateArgs) requirements() error { | ||||
| 	if a.Address == "" { | ||||
| 		return NewErrorResponse("GetStorageAt requires an 'address' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'address' value as argument") | ||||
| 	} | ||||
| 	if a.Key == "" { | ||||
| 		return NewErrorResponse("GetStorageAt requires an 'key' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetStorageAt requires an 'key' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type GetStorageAtRes struct { | ||||
| 	Key   string `json:"key"` | ||||
| 	Value string `json:"value"` | ||||
| } | ||||
|  | ||||
| type GetTxCountArgs struct { | ||||
| 	Address string `json:"address"` | ||||
| } | ||||
|  | ||||
| // type GetTxCountRes struct { | ||||
| //  Nonce int `json:"nonce"` | ||||
| // } | ||||
|  | ||||
| func (obj *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 	arg0 := "" | ||||
| 	if err = json.Unmarshal(b, &arg0); err == nil { | ||||
| 		obj.Address = arg0 | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse("Could not determine JSON parameters") | ||||
| 	return errDecodeArgs | ||||
| } | ||||
|  | ||||
| func (a *GetTxCountArgs) requirements() error { | ||||
| 	if a.Address == "" { | ||||
| 		return NewErrorResponse("GetTxCountAt requires an 'address' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetTxCountAt requires an 'address' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // type GetPeerCountRes struct { | ||||
| //  PeerCount int `json:"peerCount"` | ||||
| // } | ||||
|  | ||||
| // type GetListeningRes struct { | ||||
| //  IsListening bool `json:"isListening"` | ||||
| // } | ||||
|  | ||||
| // type GetCoinbaseRes struct { | ||||
| //  Coinbase string `json:"coinbase"` | ||||
| // } | ||||
|  | ||||
| // type GetMiningRes struct { | ||||
| //  IsMining bool `json:"isMining"` | ||||
| // } | ||||
|  | ||||
| type GetBalanceArgs struct { | ||||
| 	Address string | ||||
| } | ||||
| @@ -184,21 +152,16 @@ func (obj *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		obj.Address = arg0 | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse("Could not determine JSON parameters") | ||||
| 	return errDecodeArgs | ||||
| } | ||||
|  | ||||
| func (a *GetBalanceArgs) requirements() error { | ||||
| 	if a.Address == "" { | ||||
| 		return NewErrorResponse("GetBalanceAt requires an 'address' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetBalanceAt requires an 'address' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type BalanceRes struct { | ||||
| 	Balance string `json:"balance"` | ||||
| 	Address string `json:"address"` | ||||
| } | ||||
|  | ||||
| type GetCodeAtArgs struct { | ||||
| 	Address string | ||||
| } | ||||
| @@ -209,12 +172,12 @@ func (obj *GetCodeAtArgs) UnmarshalJSON(b []byte) (err error) { | ||||
| 		obj.Address = arg0 | ||||
| 		return | ||||
| 	} | ||||
| 	return NewErrorResponse(ErrorDecodeArgs) | ||||
| 	return errDecodeArgs | ||||
| } | ||||
|  | ||||
| func (a *GetCodeAtArgs) requirements() error { | ||||
| 	if a.Address == "" { | ||||
| 		return NewErrorResponse("GetCodeAt requires an 'address' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "GetCodeAt requires an 'address' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @@ -225,7 +188,7 @@ type Sha3Args struct { | ||||
|  | ||||
| func (obj *Sha3Args) UnmarshalJSON(b []byte) (err error) { | ||||
| 	if err = json.Unmarshal(b, &obj.Data); err != nil { | ||||
| 		return NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return errDecodeArgs | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| @@ -277,10 +240,10 @@ type DbArgs struct { | ||||
|  | ||||
| func (a *DbArgs) requirements() error { | ||||
| 	if len(a.Database) == 0 { | ||||
| 		return NewErrorResponse("DbPutArgs requires an 'Database' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "DbPutArgs requires an 'Database' value as argument") | ||||
| 	} | ||||
| 	if len(a.Key) == 0 { | ||||
| 		return NewErrorResponse("DbPutArgs requires an 'Key' value as argument") | ||||
| 		return NewErrorWithMessage(errArguments, "DbPutArgs requires an 'Key' value as argument") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -92,7 +92,7 @@ func (s *RpcHttpServer) apiHandler(api *rpc.EthereumApi) http.Handler { | ||||
|  | ||||
| 		reqParsed, reqerr := JSON.ParseRequestBody(req) | ||||
| 		if reqerr != nil { | ||||
| 			jsonerr := &rpc.RpcErrorObject{-32700, rpc.ErrorParseRequest} | ||||
| 			jsonerr := &rpc.RpcErrorObject{-32700, "Error: Could not parse request"} | ||||
| 			JSON.Send(w, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) | ||||
| 			return | ||||
| 		} | ||||
|   | ||||
| @@ -25,12 +25,11 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/xeth" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	ErrorArguments      = "Error: Insufficient arguments" | ||||
| 	ErrorNotImplemented = "Error: Method not implemented" | ||||
| 	ErrorUnknown        = "Error: Unknown error" | ||||
| 	ErrorParseRequest   = "Error: Could not parse request" | ||||
| 	ErrorDecodeArgs     = "Error: Could not decode arguments" | ||||
| var ( | ||||
| 	errArguments      = errors.New("Error: Insufficient arguments") | ||||
| 	errNotImplemented = errors.New("Error: Method not implemented") | ||||
| 	errUnknown        = errors.New("Error: Unknown error") | ||||
| 	errDecodeArgs     = errors.New("Error: Could not decode arguments") | ||||
| ) | ||||
| 
 | ||||
| type RpcRequest struct { | ||||
| @@ -58,76 +57,72 @@ type RpcErrorObject struct { | ||||
| 	// Data    interface{} `json:"data"` | ||||
| } | ||||
| 
 | ||||
| func NewErrorResponse(msg string) error { | ||||
| 	return errors.New(msg) | ||||
| } | ||||
| 
 | ||||
| func NewErrorResponseWithError(msg string, err error) error { | ||||
| 	return fmt.Errorf("%s: %v", msg, err) | ||||
| func NewErrorWithMessage(err error, msg string) error { | ||||
| 	return fmt.Errorf("%s: %s", err.Error(), msg) | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToSha3Args() (*Sha3Args, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(Sha3Args) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	if err := json.NewDecoder(r).Decode(args); err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToGetBlockArgs() (*GetBlockArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetBlockArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToNewTxArgs() (*NewTxArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(NewTxArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToPushTxArgs() (*PushTxArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(PushTxArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToGetStateArgs() (*GetStateArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetStateArgs) | ||||
| @@ -135,234 +130,241 @@ func (req *RpcRequest) ToGetStateArgs() (*GetStateArgs, error) { | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToStorageAtArgs() (*GetStorageArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetStorageArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToGetTxCountArgs() (*GetTxCountArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetTxCountArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToGetBalanceArgs() (*GetBalanceArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetBalanceArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToGetCodeAtArgs() (*GetCodeAtArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(GetCodeAtArgs) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToBoolArgs() (bool, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return false, NewErrorResponse(ErrorArguments) | ||||
| 		return false, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args bool | ||||
| 	err := json.Unmarshal(req.Params[0], &args) | ||||
| 	if err != nil { | ||||
| 		return false, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return false, errDecodeArgs | ||||
| 	} | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToIntArgs() (int, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return 0, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args int | ||||
| 	if err := json.Unmarshal(req.Params[0], &args); err != nil { | ||||
| 		return 0, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToCompileArgs() (string, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return "", NewErrorResponse(ErrorArguments) | ||||
| 		return "", errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args string | ||||
| 	err := json.Unmarshal(req.Params[0], &args) | ||||
| 	if err != nil { | ||||
| 		return "", NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return "", errDecodeArgs | ||||
| 	} | ||||
| 
 | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToFilterArgs() (*FilterOptions, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	args := new(FilterOptions) | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return nil, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToFilterStringArgs() (string, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return "", NewErrorResponse(ErrorArguments) | ||||
| 		return "", errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args string | ||||
| 	err := json.Unmarshal(req.Params[0], &args) | ||||
| 	if err != nil { | ||||
| 		return "", NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return "", errDecodeArgs | ||||
| 	} | ||||
| 
 | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToUninstallFilterArgs() (int, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return 0, NewErrorResponse(ErrorArguments) | ||||
| 		return 0, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args int | ||||
| 	err := json.Unmarshal(req.Params[0], &args) | ||||
| 	if err != nil { | ||||
| 		return 0, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return 0, errDecodeArgs | ||||
| 	} | ||||
| 
 | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToFilterChangedArgs() (int, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return 0, NewErrorResponse(ErrorArguments) | ||||
| 		return 0, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var id int | ||||
| 	r := bytes.NewReader(req.Params[0]) | ||||
| 	err := json.NewDecoder(r).Decode(&id) | ||||
| 	if err != nil { | ||||
| 		return 0, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return 0, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", id, id) | ||||
| 	return id, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToDbPutArgs() (*DbArgs, error) { | ||||
| 	if len(req.Params) < 3 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args DbArgs | ||||
| 	err := json.Unmarshal(req.Params[0], &args.Database) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	err = json.Unmarshal(req.Params[1], &args.Key) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	err = json.Unmarshal(req.Params[2], &args.Value) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return &args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToDbGetArgs() (*DbArgs, error) { | ||||
| 	if len(req.Params) < 2 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args DbArgs | ||||
| 	err := json.Unmarshal(req.Params[0], &args.Database) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	err = json.Unmarshal(req.Params[1], &args.Key) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return &args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToWhisperFilterArgs() (*xeth.Options, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args xeth.Options | ||||
| 	err := json.Unmarshal(req.Params[0], &args) | ||||
| 	if err != nil { | ||||
| 		return nil, NewErrorResponseWithError(ErrorDecodeArgs, err) | ||||
| 		return nil, NewErrorWithMessage(errDecodeArgs, err.Error()) | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return &args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToIdArgs() (int, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return 0, NewErrorResponse(ErrorArguments) | ||||
| 		return 0, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var id int | ||||
| 	err := json.Unmarshal(req.Params[0], &id) | ||||
| 	if err != nil { | ||||
| 		return 0, NewErrorResponse(ErrorDecodeArgs) | ||||
| 		return 0, errDecodeArgs | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", id, id) | ||||
| 
 | ||||
| 	return id, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToWhisperPostArgs() (*WhisperMessageArgs, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return nil, NewErrorResponse(ErrorArguments) | ||||
| 		return nil, errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args WhisperMessageArgs | ||||
| @@ -370,13 +372,13 @@ func (req *RpcRequest) ToWhisperPostArgs() (*WhisperMessageArgs, error) { | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return &args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return "", NewErrorResponse(ErrorArguments) | ||||
| 		return "", errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args string | ||||
| @@ -384,13 +386,13 @@ func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) { | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToRegisterArgs() (string, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return "", NewErrorResponse(ErrorArguments) | ||||
| 		return "", errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args string | ||||
| @@ -398,13 +400,13 @@ func (req *RpcRequest) ToRegisterArgs() (string, error) { | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| 
 | ||||
| func (req *RpcRequest) ToWatchTxArgs() (string, error) { | ||||
| 	if len(req.Params) < 1 { | ||||
| 		return "", NewErrorResponse(ErrorArguments) | ||||
| 		return "", errArguments | ||||
| 	} | ||||
| 
 | ||||
| 	var args string | ||||
| @@ -412,6 +414,6 @@ func (req *RpcRequest) ToWatchTxArgs() (string, error) { | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	rpclogger.DebugDetailf("%T %v", args, args) | ||||
| 
 | ||||
| 	return args, nil | ||||
| } | ||||
| @@ -82,7 +82,7 @@ type RpcServer interface { | ||||
|  | ||||
| type Log struct { | ||||
| 	Address string   `json:"address"` | ||||
| 	Topic   []string `json:"topics"` | ||||
| 	Topic   []string `json:"topic"` | ||||
| 	Data    string   `json:"data"` | ||||
| 	Number  uint64   `json:"number"` | ||||
| } | ||||
|   | ||||
| @@ -99,7 +99,7 @@ func sockHandler(api *rpc.EthereumApi) websocket.Handler { | ||||
|  | ||||
| 			// reqParsed, reqerr := JSON.ParseRequestBody(conn.Request()) | ||||
| 			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}) | ||||
| 				continue | ||||
| 			} | ||||
|   | ||||
| @@ -35,7 +35,7 @@ func (self *StateDB) Dump() []byte { | ||||
|  | ||||
| 		storageIt := stateObject.State.trie.Iterator() | ||||
| 		for storageIt.Next() { | ||||
| 			account.Storage[ethutil.Bytes2Hex(it.Key)] = ethutil.Bytes2Hex(it.Value) | ||||
| 			account.Storage[ethutil.Bytes2Hex(storageIt.Key)] = ethutil.Bytes2Hex(storageIt.Value) | ||||
| 		} | ||||
| 		world.Accounts[ethutil.Bytes2Hex(it.Key)] = account | ||||
| 	} | ||||
|   | ||||
| @@ -19,6 +19,14 @@ func (self Code) String() string { | ||||
|  | ||||
| type Storage map[string]*ethutil.Value | ||||
|  | ||||
| func (self Storage) String() (str string) { | ||||
| 	for key, value := range self { | ||||
| 		str += fmt.Sprintf("%X : %X\n", key, value.Bytes()) | ||||
| 	} | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (self Storage) Copy() Storage { | ||||
| 	cpy := make(Storage) | ||||
| 	for key, value := range self { | ||||
| @@ -119,10 +127,9 @@ func (self *StateObject) GetStorage(key *big.Int) *ethutil.Value { | ||||
| } | ||||
| func (self *StateObject) SetStorage(key *big.Int, value *ethutil.Value) { | ||||
| 	self.SetState(key.Bytes(), value) | ||||
| 	self.dirty = true | ||||
| } | ||||
|  | ||||
| func (self *StateObject) Storage() map[string]*ethutil.Value { | ||||
| func (self *StateObject) Storage() Storage { | ||||
| 	return self.storage | ||||
| } | ||||
|  | ||||
| @@ -172,20 +179,22 @@ func (c *StateObject) AddBalance(amount *big.Int) { | ||||
|  | ||||
| 	statelogger.Debugf("%x: #%d %v (+ %v)\n", c.Address(), c.nonce, c.balance, amount) | ||||
| } | ||||
| func (c *StateObject) AddAmount(amount *big.Int) { c.AddBalance(amount) } | ||||
|  | ||||
| func (c *StateObject) SubBalance(amount *big.Int) { | ||||
| 	c.SetBalance(new(big.Int).Sub(c.balance, amount)) | ||||
|  | ||||
| 	statelogger.Debugf("%x: #%d %v (- %v)\n", c.Address(), c.nonce, c.balance, amount) | ||||
| } | ||||
| func (c *StateObject) SubAmount(amount *big.Int) { c.SubBalance(amount) } | ||||
|  | ||||
| func (c *StateObject) SetBalance(amount *big.Int) { | ||||
| 	c.balance = amount | ||||
| 	c.dirty = true | ||||
| } | ||||
|  | ||||
| func (c *StateObject) St() Storage { | ||||
| 	return c.storage | ||||
| } | ||||
|  | ||||
| // | ||||
| // Gas setters and getters | ||||
| // | ||||
| @@ -198,7 +207,7 @@ func (c *StateObject) ConvertGas(gas, price *big.Int) error { | ||||
| 		return fmt.Errorf("insufficient amount: %v, %v", c.balance, total) | ||||
| 	} | ||||
|  | ||||
| 	c.SubAmount(total) | ||||
| 	c.SubBalance(total) | ||||
|  | ||||
| 	c.dirty = true | ||||
|  | ||||
| @@ -221,7 +230,7 @@ func (self *StateObject) BuyGas(gas, price *big.Int) error { | ||||
| 	rGas := new(big.Int).Set(gas) | ||||
| 	rGas.Mul(rGas, price) | ||||
|  | ||||
| 	self.AddAmount(rGas) | ||||
| 	self.AddBalance(rGas) | ||||
|  | ||||
| 	self.dirty = true | ||||
|  | ||||
|   | ||||
							
								
								
									
										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() | ||||
|  | ||||
| 				fmt.Printf("CREATE %X\n", 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) | ||||
|  | ||||
| 			receiver.AddAmount(balance) | ||||
| 			receiver.AddBalance(balance) | ||||
| 			statedb.Delete(context.Address()) | ||||
|  | ||||
| 			fallthrough | ||||
| @@ -779,9 +780,9 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo | ||||
| 	// Stack Check, memory resize & gas phase | ||||
| 	switch op { | ||||
| 	// Stack checks only | ||||
| 	case ISZERO, CALLDATALOAD, POP, JUMP, NOT: // 1 | ||||
| 	case ISZERO, CALLDATALOAD, POP, JUMP, NOT, EXTCODESIZE, BLOCKHASH: // 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) | ||||
| 	case ADDMOD, MULMOD: // 3 | ||||
| 		stack.require(3) | ||||
| @@ -828,7 +829,7 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo | ||||
| 			// 0 => non 0 | ||||
| 			mult = ethutil.Big3 | ||||
| 		} else if len(val) > 0 && len(y.Bytes()) == 0 { | ||||
| 			statedb.Refund(caller.Address(), GasSStoreRefund) | ||||
| 			statedb.Refund(self.env.Origin(), GasSStoreRefund) | ||||
|  | ||||
| 			mult = ethutil.Big0 | ||||
| 		} else { | ||||
| @@ -859,7 +860,7 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo | ||||
| 		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2]) | ||||
| 		additionalGas.Set(stack.data[stack.Len()-2]) | ||||
| 	case CALLDATACOPY: | ||||
| 		stack.require(2) | ||||
| 		stack.require(3) | ||||
|  | ||||
| 		newMemSize = calcMemSize(stack.Peek(), 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" | ||||
| 
 | ||||
| type State struct { | ||||
| 	xeth *XEth | ||||
| 	xeth  *XEth | ||||
| 	state *state.StateDB | ||||
| } | ||||
| 
 | ||||
| func NewState(xeth *XEth) *State { | ||||
| 	return &State{xeth} | ||||
| func NewState(xeth *XEth, statedb *state.StateDB) *State { | ||||
| 	return &State{xeth, statedb} | ||||
| } | ||||
| 
 | ||||
| func (self *State) State() *state.StateDB { | ||||
| 	return self.xeth.chainManager.TransState() | ||||
| 	return self.state | ||||
| } | ||||
| 
 | ||||
| func (self *State) Get(addr string) *Object { | ||||
| 	return &Object{self.State().GetStateObject(fromHex(addr))} | ||||
| 	return &Object{self.state.GetStateObject(fromHex(addr))} | ||||
| } | ||||
| 
 | ||||
| func (self *State) SafeGet(addr string) *Object { | ||||
| @@ -23,7 +24,7 @@ func (self *State) SafeGet(addr string) *Object { | ||||
| } | ||||
| 
 | ||||
| func (self *State) safeGet(addr string) *state.StateObject { | ||||
| 	object := self.State().GetStateObject(fromHex(addr)) | ||||
| 	object := self.state.GetStateObject(fromHex(addr)) | ||||
| 	if object == nil { | ||||
| 		object = state.NewStateObject(fromHex(addr), self.xeth.eth.Db()) | ||||
| 	} | ||||
							
								
								
									
										22
									
								
								xeth/xeth.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								xeth/xeth.go
									
									
									
									
									
								
							| @@ -17,6 +17,7 @@ import ( | ||||
| 	"github.com/ethereum/go-ethereum/logger" | ||||
| 	"github.com/ethereum/go-ethereum/miner" | ||||
| 	"github.com/ethereum/go-ethereum/p2p" | ||||
| 	"github.com/ethereum/go-ethereum/state" | ||||
| 	"github.com/ethereum/go-ethereum/whisper" | ||||
| ) | ||||
|  | ||||
| @@ -54,13 +55,26 @@ func New(eth Backend) *XEth { | ||||
| 		whisper:        NewWhisper(eth.Whisper()), | ||||
| 		miner:          eth.Miner(), | ||||
| 	} | ||||
| 	xeth.state = NewState(xeth) | ||||
| 	xeth.state = NewState(xeth, xeth.chainManager.TransState()) | ||||
|  | ||||
| 	return xeth | ||||
| } | ||||
|  | ||||
| func (self *XEth) Backend() Backend    { return self.eth } | ||||
| func (self *XEth) State() *State       { return self.state } | ||||
| func (self *XEth) Backend() Backend { return self.eth } | ||||
| func (self *XEth) UseState(statedb *state.StateDB) *XEth { | ||||
| 	xeth := &XEth{ | ||||
| 		eth:            self.eth, | ||||
| 		blockProcessor: self.blockProcessor, | ||||
| 		chainManager:   self.chainManager, | ||||
| 		whisper:        self.whisper, | ||||
| 		miner:          self.miner, | ||||
| 	} | ||||
|  | ||||
| 	xeth.state = NewState(xeth, statedb) | ||||
| 	return xeth | ||||
| } | ||||
| func (self *XEth) State() *State { return self.state } | ||||
|  | ||||
| func (self *XEth) Whisper() *Whisper   { return self.whisper } | ||||
| func (self *XEth) Miner() *miner.Miner { return self.miner } | ||||
|  | ||||
| @@ -229,7 +243,7 @@ func (self *XEth) Call(toStr, valueStr, gasStr, gasPriceStr, dataStr string) (st | ||||
| 	} | ||||
|  | ||||
| 	var ( | ||||
| 		statedb = self.chainManager.TransState() | ||||
| 		statedb = self.State().State() //self.chainManager.TransState() | ||||
| 		key     = self.eth.KeyManager().KeyPair() | ||||
| 		from    = statedb.GetOrNewStateObject(key.Address()) | ||||
| 		block   = self.chainManager.CurrentBlock() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user