aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/geth/js.go9
-rw-r--r--core/state/statedb.go3
-rw-r--r--eth/handler.go12
-rw-r--r--rpc/jeth.go75
4 files changed, 92 insertions, 7 deletions
diff --git a/cmd/geth/js.go b/cmd/geth/js.go
index 9329eaa0e..cdafab7fa 100644
--- a/cmd/geth/js.go
+++ b/cmd/geth/js.go
@@ -348,6 +348,15 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
persObj.Set("newAccount", jeth.NewAccount)
}
+ // The admin.sleep and admin.sleepBlocks are offered by the console and not by the RPC layer.
+ // Bind these if the admin module is available.
+ if a, err := js.re.Get("admin"); err == nil {
+ if adminObj := a.Object(); adminObj != nil {
+ adminObj.Set("sleepBlocks", jeth.SleepBlocks)
+ adminObj.Set("sleep", jeth.Sleep)
+ }
+ }
+
return nil
}
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 413321057..8093472b5 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -353,7 +353,8 @@ func (s *StateDB) IntermediateRoot() common.Hash {
// Commit commits all state changes to the database.
func (s *StateDB) Commit() (root common.Hash, err error) {
- return s.commit(s.db)
+ root, batch := s.CommitBatch()
+ return root, batch.Write()
}
// CommitBatch commits all state changes to a write batch but does not
diff --git a/eth/handler.go b/eth/handler.go
index 108a6679c..e8bac23c3 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -750,10 +750,10 @@ func (self *ProtocolManager) txBroadcastLoop() {
// EthNodeInfo represents a short summary of the Ethereum sub-protocol metadata known
// about the host peer.
type EthNodeInfo struct {
- Network int `json:"network"` // Ethereum network ID (0=Olympic, 1=Frontier, 2=Morden)
- Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain
- Genesis string `json:"genesis"` // SHA3 hash of the host's genesis block
- Head string `json:"head"` // SHA3 hash of the host's best owned block
+ Network int `json:"network"` // Ethereum network ID (0=Olympic, 1=Frontier, 2=Morden)
+ Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain
+ Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block
+ Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block
}
// NodeInfo retrieves some protocol metadata about the running host node.
@@ -761,7 +761,7 @@ func (self *ProtocolManager) NodeInfo() *EthNodeInfo {
return &EthNodeInfo{
Network: self.networkId,
Difficulty: self.blockchain.GetTd(self.blockchain.CurrentBlock().Hash()),
- Genesis: fmt.Sprintf("%x", self.blockchain.Genesis().Hash()),
- Head: fmt.Sprintf("%x", self.blockchain.CurrentBlock().Hash()),
+ Genesis: self.blockchain.Genesis().Hash(),
+ Head: self.blockchain.CurrentBlock().Hash(),
}
}
diff --git a/rpc/jeth.go b/rpc/jeth.go
index de7dd1e76..b195a4965 100644
--- a/rpc/jeth.go
+++ b/rpc/jeth.go
@@ -19,6 +19,7 @@ package rpc
import (
"encoding/json"
"fmt"
+ "time"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/jsre"
@@ -247,3 +248,77 @@ func (self *Jeth) confirmTransaction(id interface{}, jsonrpc string, args []inte
// Accept all tx which are send from this console
return self.client.Send(shared.NewRpcResponse(id, jsonrpc, true, nil)) == nil
}
+
+// throwJSExeception panics on an otto value, the Otto VM will then throw msg as a javascript error.
+func throwJSExeception(msg interface{}) otto.Value {
+ p, _ := otto.ToValue(msg)
+ panic(p)
+ return p
+}
+
+// Sleep will halt the console for arg[0] seconds.
+func (self *Jeth) Sleep(call otto.FunctionCall) (response otto.Value) {
+ if len(call.ArgumentList) >= 1 {
+ if call.Argument(0).IsNumber() {
+ sleep, _ := call.Argument(0).ToInteger()
+ time.Sleep(time.Duration(sleep) * time.Second)
+ return otto.TrueValue()
+ }
+ }
+ return throwJSExeception("usage: sleep(<sleep in seconds>)")
+}
+
+// SleepBlocks will wait for a specified number of new blocks or max for a
+// given of seconds. sleepBlocks(nBlocks[, maxSleep]).
+func (self *Jeth) SleepBlocks(call otto.FunctionCall) (response otto.Value) {
+ nBlocks := int64(0)
+ maxSleep := int64(9999999999999999) // indefinitely
+
+ nArgs := len(call.ArgumentList)
+
+ if nArgs == 0 {
+ throwJSExeception("usage: sleepBlocks(<n blocks>[, max sleep in seconds])")
+ }
+
+ if nArgs >= 1 {
+ if call.Argument(0).IsNumber() {
+ nBlocks, _ = call.Argument(0).ToInteger()
+ } else {
+ throwJSExeception("expected number as first argument")
+ }
+ }
+
+ if nArgs >= 2 {
+ if call.Argument(1).IsNumber() {
+ maxSleep, _ = call.Argument(1).ToInteger()
+ } else {
+ throwJSExeception("expected number as second argument")
+ }
+ }
+
+ // go through the console, this will allow web3 to call the appropriate
+ // callbacks if a delayed response or notification is received.
+ currentBlockNr := func() int64 {
+ result, err := call.Otto.Run("eth.blockNumber")
+ if err != nil {
+ throwJSExeception(err.Error())
+ }
+ blockNr, err := result.ToInteger()
+ if err != nil {
+ throwJSExeception(err.Error())
+ }
+ return blockNr
+ }
+
+ targetBlockNr := currentBlockNr() + nBlocks
+ deadline := time.Now().Add(time.Duration(maxSleep) * time.Second)
+
+ for time.Now().Before(deadline) {
+ if currentBlockNr() >= targetBlockNr {
+ return otto.TrueValue()
+ }
+ time.Sleep(time.Second)
+ }
+
+ return otto.FalseValue()
+}