aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-02-26 18:16:01 +0800
committerobscuren <geffobscura@gmail.com>2015-02-26 19:06:01 +0800
commit49ded3aa7752148ebfbacd4e6ff5f46dc9376f89 (patch)
treeebde269fc7a836b67eb8d7a2a95a90297d8c2435
parent5ab0eaa06d2f5879b9b22778988410bd0c73dcc0 (diff)
parent9884eed0cf7c95074fd5b3d5f0f592a423810a8a (diff)
downloadgo-tangerine-49ded3aa7752148ebfbacd4e6ff5f46dc9376f89.tar
go-tangerine-49ded3aa7752148ebfbacd4e6ff5f46dc9376f89.tar.gz
go-tangerine-49ded3aa7752148ebfbacd4e6ff5f46dc9376f89.tar.bz2
go-tangerine-49ded3aa7752148ebfbacd4e6ff5f46dc9376f89.tar.lz
go-tangerine-49ded3aa7752148ebfbacd4e6ff5f46dc9376f89.tar.xz
go-tangerine-49ded3aa7752148ebfbacd4e6ff5f46dc9376f89.tar.zst
go-tangerine-49ded3aa7752148ebfbacd4e6ff5f46dc9376f89.zip
Merge branch 'develop' of github.com-obscure:ethereum/go-ethereum into develop
Conflicts: accounts/account_manager.go
-rw-r--r--.travis.yml4
-rw-r--r--Godeps/Godeps.json11
-rw-r--r--Godeps/_workspace/src/bitbucket.org/kardianos/osext/LICENSE20
-rw-r--r--Godeps/_workspace/src/github.com/kardianos/osext/LICENSE27
-rw-r--r--Godeps/_workspace/src/github.com/kardianos/osext/README.md14
-rw-r--r--Godeps/_workspace/src/github.com/kardianos/osext/osext.go (renamed from Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext.go)5
-rw-r--r--Godeps/_workspace/src/github.com/kardianos/osext/osext_plan9.go (renamed from Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_plan9.go)18
-rw-r--r--Godeps/_workspace/src/github.com/kardianos/osext/osext_procfs.go (renamed from Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_procfs.go)7
-rw-r--r--Godeps/_workspace/src/github.com/kardianos/osext/osext_sysctl.go (renamed from Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_sysctl.go)0
-rw-r--r--Godeps/_workspace/src/github.com/kardianos/osext/osext_test.go (renamed from Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_test.go)0
-rw-r--r--Godeps/_workspace/src/github.com/kardianos/osext/osext_windows.go (renamed from Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_windows.go)0
-rw-r--r--accounts/account_manager.go50
-rw-r--r--accounts/accounts_test.go53
-rw-r--r--cmd/mist/flags.go31
-rw-r--r--cmd/utils/cmd.go29
-rw-r--r--core/block_processor.go7
-rw-r--r--ethutil/common.go29
-rw-r--r--rpc/api.go27
-rw-r--r--rpc/messages.go13
-rw-r--r--ui/frontend.go18
-rw-r--r--xeth/state.go33
21 files changed, 277 insertions, 119 deletions
diff --git a/.travis.yml b/.travis.yml
index 5499cf257..c4e39b05e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -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:
diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index 9b7306530..b66ea932f 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -1,16 +1,11 @@
{
"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",
"Rev": "7dda39b2e7d5e265014674c5af696ba4186679e9"
@@ -38,6 +33,10 @@
"Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1"
},
{
+ "ImportPath": "github.com/kardianos/osext",
+ "Rev": "ccfcd0245381f0c94c68f50626665eed3c6b726a"
+ },
+ {
"ImportPath": "github.com/obscuren/otto",
"Rev": "cf13cc4228c5e5ce0fe27a7aea90bc10091c4f19"
},
diff --git a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/LICENSE b/Godeps/_workspace/src/bitbucket.org/kardianos/osext/LICENSE
deleted file mode 100644
index 18527a28f..000000000
--- a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/LICENSE
+++ /dev/null
@@ -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.
diff --git a/Godeps/_workspace/src/github.com/kardianos/osext/LICENSE b/Godeps/_workspace/src/github.com/kardianos/osext/LICENSE
new file mode 100644
index 000000000..744875676
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/kardianos/osext/LICENSE
@@ -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.
diff --git a/Godeps/_workspace/src/github.com/kardianos/osext/README.md b/Godeps/_workspace/src/github.com/kardianos/osext/README.md
new file mode 100644
index 000000000..820e1ecb5
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/kardianos/osext/README.md
@@ -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.
diff --git a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext.go b/Godeps/_workspace/src/github.com/kardianos/osext/osext.go
index 37efbb221..4ed4b9aa3 100644
--- a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext.go
+++ b/Godeps/_workspace/src/github.com/kardianos/osext/osext.go
@@ -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()
-}
diff --git a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_plan9.go b/Godeps/_workspace/src/github.com/kardianos/osext/osext_plan9.go
index 4468a73a7..655750c54 100644
--- a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_plan9.go
+++ b/Godeps/_workspace/src/github.com/kardianos/osext/osext_plan9.go
@@ -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()))
}
diff --git a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_procfs.go b/Godeps/_workspace/src/github.com/kardianos/osext/osext_procfs.go
index 546fec915..a50021ad5 100644
--- a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_procfs.go
+++ b/Godeps/_workspace/src/github.com/kardianos/osext/osext_procfs.go
@@ -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)
}
diff --git a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_sysctl.go b/Godeps/_workspace/src/github.com/kardianos/osext/osext_sysctl.go
index b66cac878..b66cac878 100644
--- a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_sysctl.go
+++ b/Godeps/_workspace/src/github.com/kardianos/osext/osext_sysctl.go
diff --git a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_test.go b/Godeps/_workspace/src/github.com/kardianos/osext/osext_test.go
index dc661dbc2..dc661dbc2 100644
--- a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_test.go
+++ b/Godeps/_workspace/src/github.com/kardianos/osext/osext_test.go
diff --git a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_windows.go b/Godeps/_workspace/src/github.com/kardianos/osext/osext_windows.go
index 72d282cf8..72d282cf8 100644
--- a/Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_windows.go
+++ b/Godeps/_workspace/src/github.com/kardianos/osext/osext_windows.go
diff --git a/accounts/account_manager.go b/accounts/account_manager.go
index f1ad450e6..3e9fa7799 100644
--- a/accounts/account_manager.go
+++ b/accounts/account_manager.go
@@ -35,24 +35,33 @@ 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
}
@@ -61,11 +70,26 @@ func (am AccountManager) DeleteAccount(address []byte, auth string) error {
return am.keyStore.DeleteKey(address, auth)
}
-func (am *AccountManager) Sign(fromAccount *Account, keyAuth string, toSign []byte) (signature []byte, err error) {
+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
}
@@ -81,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 {
@@ -98,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()
+}
diff --git a/accounts/accounts_test.go b/accounts/accounts_test.go
index 4e97de545..44d1d72f1 100644
--- a/accounts/accounts_test.go
+++ b/accounts/accounts_test.go
@@ -6,20 +6,69 @@ 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(ethutil.DefaultDataDir() + "/testaccounts")
- am := NewAccountManager(ks)
+ 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)
diff --git a/cmd/mist/flags.go b/cmd/mist/flags.go
index d5ed60a21..0010df826 100644
--- a/cmd/mist/flags.go
+++ b/cmd/mist/flags.go
@@ -27,10 +27,8 @@ import (
"log"
"os"
"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"
@@ -68,33 +66,6 @@ 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
-}
-
var defaultConfigFile = path.Join(ethutil.DefaultDataDir(), "conf.ini")
func Init() {
@@ -122,7 +93,7 @@ func Init() {
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 (
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index bc8fafafb..a36c10e3b 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -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
diff --git a/core/block_processor.go b/core/block_processor.go
index fd591a29d..f66d158b2 100644
--- a/core/block_processor.go
+++ b/core/block_processor.go
@@ -62,7 +62,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)
@@ -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)
}
diff --git a/ethutil/common.go b/ethutil/common.go
index efc519732..c4e7415dc 100644
--- a/ethutil/common.go
+++ b/ethutil/common.go
@@ -3,12 +3,41 @@ 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" {
diff --git a/rpc/api.go b/rpc/api.go
index f337324d0..3b4a914ef 100644
--- a/rpc/api.go
+++ b/rpc/api.go
@@ -51,6 +51,8 @@ type EthereumApi struct {
register map[string][]*NewTxArgs
db ethutil.Database
+
+ defaultBlockAge int
}
func NewEthereumApi(eth *xeth.XEth) *EthereumApi {
@@ -80,11 +82,9 @@ done:
case ev := <-events.Chan():
switch ev.(type) {
case core.ChainEvent:
- // fixme
- const something = 1337
- if something < 0 {
+ if self.defaultBlockAge < 0 {
chain := self.xeth().Backend().ChainManager()
- block := chain.GetBlockByNumber(chain.CurrentBlock().Number().Uint64() - something)
+ block := chain.GetBlockByNumber(chain.CurrentBlock().Number().Uint64() - uint64(self.defaultBlockAge))
if block != nil {
statedb := state.New(block.Root(), self.db)
self.useState(statedb)
@@ -373,6 +373,17 @@ func (p *EthereumApi) SetMining(shouldmine bool, reply *interface{}) error {
return nil
}
+func (p *EthereumApi) GetDefaultBlockAge(reply *interface{}) error {
+ *reply = p.defaultBlockAge
+ return nil
+}
+
+func (p *EthereumApi) SetDefaultBlockAge(defaultBlockAge int, reply *interface{}) error {
+ p.defaultBlockAge = defaultBlockAge
+ *reply = true
+ return nil
+}
+
func (p *EthereumApi) BlockNumber(reply *interface{}) error {
*reply = p.xeth().Backend().ChainManager().CurrentBlock().Number()
return nil
@@ -513,6 +524,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(args, reply)
case "eth_peerCount":
return p.GetPeerCount(reply)
case "eth_number":
diff --git a/rpc/messages.go b/rpc/messages.go
index 044f07545..b37d8229d 100644
--- a/rpc/messages.go
+++ b/rpc/messages.go
@@ -210,6 +210,19 @@ func (req *RpcRequest) ToBoolArgs() (bool, error) {
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
+ }
+
+ return args, nil
+}
+
func (req *RpcRequest) ToCompileArgs() (string, error) {
if len(req.Params) < 1 {
return "", errArguments
diff --git a/ui/frontend.go b/ui/frontend.go
new file mode 100644
index 000000000..22dc64fdf
--- /dev/null
+++ b/ui/frontend.go
@@ -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)
+}
diff --git a/xeth/state.go b/xeth/state.go
new file mode 100644
index 000000000..e2562613c
--- /dev/null
+++ b/xeth/state.go
@@ -0,0 +1,33 @@
+package xeth
+
+import "github.com/ethereum/go-ethereum/state"
+
+type State struct {
+ xeth *XEth
+ state *state.StateDB
+}
+
+func NewState(xeth *XEth, statedb *state.StateDB) *State {
+ return &State{xeth, statedb}
+}
+
+func (self *State) State() *state.StateDB {
+ return self.state
+}
+
+func (self *State) Get(addr string) *Object {
+ return &Object{self.state.GetStateObject(fromHex(addr))}
+}
+
+func (self *State) SafeGet(addr string) *Object {
+ return &Object{self.safeGet(addr)}
+}
+
+func (self *State) safeGet(addr string) *state.StateObject {
+ object := self.state.GetStateObject(fromHex(addr))
+ if object == nil {
+ object = state.NewStateObject(fromHex(addr), self.xeth.eth.Db())
+ }
+
+ return object
+}