This commit is contained in:
obscuren 2015-03-03 17:56:36 +01:00
commit 40ff3cac39
15 changed files with 169 additions and 209 deletions

View File

@ -27,6 +27,7 @@ import (
"log" "log"
"os" "os"
"path" "path"
"runtime"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
@ -36,40 +37,42 @@ import (
) )
var ( var (
Identifier string Identifier string
KeyRing string KeyRing string
DiffTool bool DiffTool bool
DiffType string DiffType string
KeyStore string KeyStore string
StartRpc bool StartRpc bool
StartWebSockets bool StartWebSockets bool
RpcPort int RpcListenAddress string
WsPort int RpcPort int
OutboundPort string WsPort int
ShowGenesis bool OutboundPort string
AddPeer string ShowGenesis bool
MaxPeer int AddPeer string
GenAddr bool MaxPeer int
BootNodes string GenAddr bool
NodeKey *ecdsa.PrivateKey BootNodes string
NAT nat.Interface NodeKey *ecdsa.PrivateKey
SecretFile string NAT nat.Interface
ExportDir string SecretFile string
NonInteractive bool ExportDir string
Datadir string NonInteractive bool
LogFile string Datadir string
ConfigFile string LogFile string
DebugFile string ConfigFile string
LogLevel int DebugFile string
LogFormat string LogLevel int
Dump bool LogFormat string
DumpHash string Dump bool
DumpNumber int DumpHash string
VmType int DumpNumber int
ImportChain string VmType int
SHH bool ImportChain string
Dial bool SHH bool
PrintVersion bool Dial bool
PrintVersion bool
MinerThreads int
) )
// flags specific to cli client // flags specific to cli client
@ -93,6 +96,7 @@ func Init() {
flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use") flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use")
flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)")
flag.StringVar(&RpcListenAddress, "rpcaddr", "127.0.0.1", "address for json-rpc server to listen on")
flag.IntVar(&RpcPort, "rpcport", 8545, "port to start json-rpc server on") flag.IntVar(&RpcPort, "rpcport", 8545, "port to start json-rpc server on")
flag.IntVar(&WsPort, "wsport", 40404, "port to start websocket rpc server on") flag.IntVar(&WsPort, "wsport", 40404, "port to start websocket rpc server on")
flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
@ -119,6 +123,7 @@ func Init() {
flag.BoolVar(&StartMining, "mine", false, "start dagger mining") flag.BoolVar(&StartMining, "mine", false, "start dagger mining")
flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console") flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console")
flag.BoolVar(&PrintVersion, "version", false, "prints version number") flag.BoolVar(&PrintVersion, "version", false, "prints version number")
flag.IntVar(&MinerThreads, "minerthreads", runtime.NumCPU(), "number of miner threads")
// Network stuff // Network stuff
var ( var (

View File

@ -62,20 +62,21 @@ func main() {
utils.InitConfig(VmType, ConfigFile, Datadir, "ETH") utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
ethereum, err := eth.New(&eth.Config{ ethereum, err := eth.New(&eth.Config{
Name: p2p.MakeName(ClientIdentifier, Version), Name: p2p.MakeName(ClientIdentifier, Version),
KeyStore: KeyStore, KeyStore: KeyStore,
DataDir: Datadir, DataDir: Datadir,
LogFile: LogFile, LogFile: LogFile,
LogLevel: LogLevel, LogLevel: LogLevel,
LogFormat: LogFormat, LogFormat: LogFormat,
MaxPeers: MaxPeer, MaxPeers: MaxPeer,
Port: OutboundPort, Port: OutboundPort,
NAT: NAT, NAT: NAT,
KeyRing: KeyRing, KeyRing: KeyRing,
Shh: true, Shh: true,
Dial: Dial, Dial: Dial,
BootNodes: BootNodes, BootNodes: BootNodes,
NodeKey: NodeKey, NodeKey: NodeKey,
MinerThreads: MinerThreads,
}) })
if err != nil { if err != nil {
@ -128,7 +129,7 @@ func main() {
} }
if StartRpc { if StartRpc {
utils.StartRpc(ethereum, RpcPort) utils.StartRpc(ethereum, RpcListenAddress, RpcPort)
} }
if StartWebSockets { if StartWebSockets {
@ -139,6 +140,10 @@ func main() {
fmt.Printf("Welcome to the FRONTIER\n") fmt.Printf("Welcome to the FRONTIER\n")
if StartMining {
ethereum.Miner().Start()
}
if StartJsConsole { if StartJsConsole {
InitJsConsole(ethereum) InitJsConsole(ethereum)
} else if len(InputFile) > 0 { } else if len(InputFile) > 0 {

View File

@ -37,31 +37,32 @@ import (
) )
var ( var (
Identifier string Identifier string
KeyRing string KeyRing string
KeyStore string KeyStore string
StartRpc bool StartRpc bool
StartWebSockets bool StartWebSockets bool
RpcPort int RpcListenAddress string
WsPort int RpcPort int
OutboundPort string WsPort int
ShowGenesis bool OutboundPort string
AddPeer string ShowGenesis bool
MaxPeer int AddPeer string
GenAddr bool MaxPeer int
BootNodes string GenAddr bool
NodeKey *ecdsa.PrivateKey BootNodes string
NAT nat.Interface NodeKey *ecdsa.PrivateKey
SecretFile string NAT nat.Interface
ExportDir string SecretFile string
NonInteractive bool ExportDir string
Datadir string NonInteractive bool
LogFile string Datadir string
ConfigFile string LogFile string
DebugFile string ConfigFile string
LogLevel int DebugFile string
VmType int LogLevel int
MinerThreads int VmType int
MinerThreads int
) )
// flags specific to gui client // flags specific to gui client
@ -79,6 +80,7 @@ func Init() {
flag.StringVar(&Identifier, "id", "", "Custom client identifier") flag.StringVar(&Identifier, "id", "", "Custom client identifier")
flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use") flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use")
flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)")
flag.StringVar(&RpcListenAddress, "rpcaddr", "127.0.0.1", "address for json-rpc server to listen on")
flag.IntVar(&RpcPort, "rpcport", 8545, "port to start json-rpc server on") flag.IntVar(&RpcPort, "rpcport", 8545, "port to start json-rpc server on")
flag.IntVar(&WsPort, "wsport", 40404, "port to start websocket rpc server on") flag.IntVar(&WsPort, "wsport", 40404, "port to start websocket rpc server on")
flag.BoolVar(&StartRpc, "rpc", true, "start rpc server") flag.BoolVar(&StartRpc, "rpc", true, "start rpc server")

View File

@ -73,7 +73,7 @@ func run() error {
utils.KeyTasks(ethereum.KeyManager(), KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive) utils.KeyTasks(ethereum.KeyManager(), KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
if StartRpc { if StartRpc {
utils.StartRpc(ethereum, RpcPort) utils.StartRpc(ethereum, RpcListenAddress, RpcPort)
} }
if StartWebSockets { if StartWebSockets {

View File

@ -159,9 +159,9 @@ func KeyTasks(keyManager *crypto.KeyManager, KeyRing string, GenAddr bool, Secre
clilogger.Infof("Main address %x\n", keyManager.Address()) clilogger.Infof("Main address %x\n", keyManager.Address())
} }
func StartRpc(ethereum *eth.Ethereum, RpcPort int) { func StartRpc(ethereum *eth.Ethereum, RpcListenAddress string, RpcPort int) {
var err error var err error
ethereum.RpcServer, err = rpchttp.NewRpcHttpServer(xeth.New(ethereum), RpcPort) ethereum.RpcServer, err = rpchttp.NewRpcHttpServer(xeth.New(ethereum), RpcListenAddress, RpcPort)
if err != nil { if err != nil {
clilogger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err) clilogger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err)
} else { } else {

View File

@ -17,7 +17,7 @@ type FilterOptions struct {
Latest int64 Latest int64
Address [][]byte Address [][]byte
Topics [][]byte Topics [][][]byte
Skip int Skip int
Max int Max int
@ -31,7 +31,7 @@ type Filter struct {
skip int skip int
address [][]byte address [][]byte
max int max int
topics [][]byte topics [][][]byte
BlockCallback func(*types.Block) BlockCallback func(*types.Block)
PendingCallback func(*types.Block) PendingCallback func(*types.Block)
@ -44,6 +44,8 @@ func NewFilter(eth Backend) *Filter {
return &Filter{eth: eth} return &Filter{eth: eth}
} }
// SetOptions copies the filter options to the filter it self. The reason for this "silly" copy
// is simply because named arguments in this case is extremely nice and readable.
func (self *Filter) SetOptions(options FilterOptions) { func (self *Filter) SetOptions(options FilterOptions) {
self.earliest = options.Earliest self.earliest = options.Earliest
self.latest = options.Latest self.latest = options.Latest
@ -69,7 +71,7 @@ func (self *Filter) SetAddress(addr [][]byte) {
self.address = addr self.address = addr
} }
func (self *Filter) SetTopics(topics [][]byte) { func (self *Filter) SetTopics(topics [][][]byte) {
self.topics = topics self.topics = topics
} }
@ -149,10 +151,18 @@ Logs:
continue continue
} }
max := int(math.Min(float64(len(self.topics)), float64(len(log.Topics())))) logTopics := make([][]byte, len(self.topics))
for i := 0; i < max; i++ { copy(logTopics, log.Topics())
if !bytes.Equal(log.Topics()[i], self.topics[i]) {
continue Logs for i, topics := range self.topics {
for _, topic := range topics {
var match bool
if bytes.Equal(log.Topics()[i], topic) {
match = true
}
if !match {
continue Logs
}
} }
} }
@ -177,8 +187,15 @@ func (self *Filter) bloomFilter(block *types.Block) bool {
} }
} }
for _, topic := range self.topics { for _, sub := range self.topics {
if !types.BloomLookup(block.Bloom(), topic) { var included bool
for _, topic := range sub {
if types.BloomLookup(block.Bloom(), topic) {
included = true
break
}
}
if !included {
return false return false
} }
} }

View File

@ -15,11 +15,13 @@ import (
func DefaultAssetPath() string { func DefaultAssetPath() string {
var assetPath string var assetPath string
pwd, _ := os.Getwd()
srcdir := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist")
// If the current working directory is the go-ethereum dir // If the current working directory is the go-ethereum dir
// assume a debug build and use the source directory as // assume a debug build and use the source directory as
// asset directory. // asset directory.
pwd, _ := os.Getwd() if pwd == srcdir {
if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist") {
assetPath = path.Join(pwd, "assets") assetPath = path.Join(pwd, "assets")
} else { } else {
switch runtime.GOOS { switch runtime.GOOS {
@ -35,6 +37,13 @@ func DefaultAssetPath() string {
assetPath = "." assetPath = "."
} }
} }
// Check if the assetPath exists. If not, try the source directory
// This happens when binary is run from outside cmd/mist directory
if _, err := os.Stat(assetPath); os.IsNotExist(err) {
assetPath = path.Join(srcdir, "assets")
}
return assetPath return assetPath
} }

View File

@ -6,7 +6,6 @@ import (
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/ui"
"github.com/ethereum/go-ethereum/xeth" "github.com/ethereum/go-ethereum/xeth"
"github.com/obscuren/otto" "github.com/obscuren/otto"
) )
@ -96,17 +95,3 @@ func (self *JSEthereum) toVal(v interface{}) otto.Value {
return result return result
} }
func (self *JSEthereum) Messages(object map[string]interface{}) otto.Value {
filter := ui.NewFilterFromMap(object, self.ethereum)
logs := filter.Find()
var jslogs []JSLog
for _, m := range logs {
jslogs = append(jslogs, NewJSLog(m))
}
v, _ := self.vm.ToValue(jslogs)
return v
}

View File

@ -55,10 +55,5 @@ func (self *Miner) Stop() {
} }
func (self *Miner) HashRate() int64 { func (self *Miner) HashRate() int64 {
var tot int64 return self.worker.HashRate()
for _, agent := range self.worker.agents {
tot += agent.Pow().GetHashrate()
}
return tot
} }

View File

@ -5,6 +5,7 @@ import (
"math/big" "math/big"
"sort" "sort"
"sync" "sync"
"time"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
@ -113,6 +114,8 @@ func (self *worker) register(agent Agent) {
func (self *worker) update() { func (self *worker) update() {
events := self.mux.Subscribe(core.ChainEvent{}, core.NewMinedBlockEvent{}) events := self.mux.Subscribe(core.ChainEvent{}, core.NewMinedBlockEvent{})
timer := time.NewTicker(2 * time.Second)
out: out:
for { for {
select { select {
@ -131,6 +134,8 @@ out:
agent.Stop() agent.Stop()
} }
break out break out
case <-timer.C:
minerlogger.Debugln("Hash rate:", self.HashRate(), "Khash")
} }
} }
@ -250,3 +255,12 @@ func (self *worker) commitTransaction(tx *types.Transaction) error {
return nil return nil
} }
func (self *worker) HashRate() int64 {
var tot int64
for _, agent := range self.agents {
tot += agent.Pow().GetHashrate()
}
return tot
}

View File

@ -197,7 +197,7 @@ type FilterOptions struct {
Earliest int64 Earliest int64
Latest int64 Latest int64
Address interface{} Address interface{}
Topic []string Topic []interface{}
Skip int Skip int
Max int Max int
} }
@ -220,10 +220,20 @@ func toFilterOptions(options *FilterOptions) core.FilterOptions {
opts.Earliest = options.Earliest opts.Earliest = options.Earliest
opts.Latest = options.Latest opts.Latest = options.Latest
opts.Topics = make([][]byte, len(options.Topic))
for i, topic := range options.Topic { topics := make([][][]byte, len(options.Topic))
opts.Topics[i] = fromHex(topic) for i, topicDat := range options.Topic {
if slice, ok := topicDat.([]interface{}); ok {
topics[i] = make([][]byte, len(slice))
for j, topic := range slice {
topics[i][j] = fromHex(topic.(string))
}
} else if str, ok := topicDat.(string); ok {
topics[i] = make([][]byte, 1)
topics[i][0] = fromHex(str)
}
} }
opts.Topics = topics
return opts return opts
} }

View File

@ -29,8 +29,8 @@ import (
var rpchttplogger = logger.NewLogger("RPC-HTTP") var rpchttplogger = logger.NewLogger("RPC-HTTP")
var JSON rpc.JsonWrapper var JSON rpc.JsonWrapper
func NewRpcHttpServer(pipe *xeth.XEth, port int) (*RpcHttpServer, error) { func NewRpcHttpServer(pipe *xeth.XEth, address string, port int) (*RpcHttpServer, error) {
sport := fmt.Sprintf("127.0.0.1:%d", port) sport := fmt.Sprintf("%s:%d", address, port)
l, err := net.Listen("tcp", sport) l, err := net.Listen("tcp", sport)
if err != nil { if err != nil {
return nil, err return nil, err
@ -41,6 +41,7 @@ func NewRpcHttpServer(pipe *xeth.XEth, port int) (*RpcHttpServer, error) {
quit: make(chan bool), quit: make(chan bool),
pipe: pipe, pipe: pipe,
port: port, port: port,
addr: address,
}, nil }, nil
} }
@ -49,6 +50,7 @@ type RpcHttpServer struct {
listener net.Listener listener net.Listener
pipe *xeth.XEth pipe *xeth.XEth
port int port int
addr string
} }
func (s *RpcHttpServer) exitHandler() { func (s *RpcHttpServer) exitHandler() {
@ -69,7 +71,7 @@ func (s *RpcHttpServer) Stop() {
} }
func (s *RpcHttpServer) Start() { func (s *RpcHttpServer) Start() {
rpchttplogger.Infof("Starting RPC-HTTP server on port %d", s.port) rpchttplogger.Infof("Starting RPC-HTTP server on %s:%d", s.addr, s.port)
go s.exitHandler() go s.exitHandler()
api := rpc.NewEthereumApi(s.pipe) api := rpc.NewEthereumApi(s.pipe)

View File

@ -54,7 +54,7 @@ func (self *StateDB) Refund(addr []byte, gas *big.Int) {
// Retrieve the balance from the given address or 0 if object not found // Retrieve the balance from the given address or 0 if object not found
func (self *StateDB) GetBalance(addr []byte) *big.Int { func (self *StateDB) GetBalance(addr []byte) *big.Int {
stateObject := self.GetStateObject(addr) stateObject := self.GetOrNewStateObject(addr)
if stateObject != nil { if stateObject != nil {
return stateObject.balance return stateObject.balance
} }
@ -63,14 +63,14 @@ func (self *StateDB) GetBalance(addr []byte) *big.Int {
} }
func (self *StateDB) AddBalance(addr []byte, amount *big.Int) { func (self *StateDB) AddBalance(addr []byte, amount *big.Int) {
stateObject := self.GetStateObject(addr) stateObject := self.GetOrNewStateObject(addr)
if stateObject != nil { if stateObject != nil {
stateObject.AddBalance(amount) stateObject.AddBalance(amount)
} }
} }
func (self *StateDB) GetNonce(addr []byte) uint64 { func (self *StateDB) GetNonce(addr []byte) uint64 {
stateObject := self.GetStateObject(addr) stateObject := self.GetOrNewStateObject(addr)
if stateObject != nil { if stateObject != nil {
return stateObject.nonce return stateObject.nonce
} }
@ -79,7 +79,7 @@ func (self *StateDB) GetNonce(addr []byte) uint64 {
} }
func (self *StateDB) GetCode(addr []byte) []byte { func (self *StateDB) GetCode(addr []byte) []byte {
stateObject := self.GetStateObject(addr) stateObject := self.GetOrNewStateObject(addr)
if stateObject != nil { if stateObject != nil {
return stateObject.code return stateObject.code
} }
@ -88,7 +88,7 @@ func (self *StateDB) GetCode(addr []byte) []byte {
} }
func (self *StateDB) GetState(a, b []byte) []byte { func (self *StateDB) GetState(a, b []byte) []byte {
stateObject := self.GetStateObject(a) stateObject := self.GetOrNewStateObject(a)
if stateObject != nil { if stateObject != nil {
return stateObject.GetState(b).Bytes() return stateObject.GetState(b).Bytes()
} }
@ -97,28 +97,28 @@ func (self *StateDB) GetState(a, b []byte) []byte {
} }
func (self *StateDB) SetNonce(addr []byte, nonce uint64) { func (self *StateDB) SetNonce(addr []byte, nonce uint64) {
stateObject := self.GetStateObject(addr) stateObject := self.GetOrNewStateObject(addr)
if stateObject != nil { if stateObject != nil {
stateObject.SetNonce(nonce) stateObject.SetNonce(nonce)
} }
} }
func (self *StateDB) SetCode(addr, code []byte) { func (self *StateDB) SetCode(addr, code []byte) {
stateObject := self.GetStateObject(addr) stateObject := self.GetOrNewStateObject(addr)
if stateObject != nil { if stateObject != nil {
stateObject.SetCode(code) stateObject.SetCode(code)
} }
} }
func (self *StateDB) SetState(addr, key []byte, value interface{}) { func (self *StateDB) SetState(addr, key []byte, value interface{}) {
stateObject := self.GetStateObject(addr) stateObject := self.GetOrNewStateObject(addr)
if stateObject != nil { if stateObject != nil {
stateObject.SetState(key, ethutil.NewValue(value)) stateObject.SetState(key, ethutil.NewValue(value))
} }
} }
func (self *StateDB) Delete(addr []byte) bool { func (self *StateDB) Delete(addr []byte) bool {
stateObject := self.GetStateObject(addr) stateObject := self.GetOrNewStateObject(addr)
if stateObject != nil { if stateObject != nil {
stateObject.MarkForDeletion() stateObject.MarkForDeletion()

View File

@ -1,77 +1 @@
package ui package ui
import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/ethutil"
)
func fromHex(s string) []byte {
if len(s) > 1 {
if s[0:2] == "0x" {
s = s[2:]
}
return ethutil.Hex2Bytes(s)
}
return nil
}
func NewFilterFromMap(object map[string]interface{}, eth core.Backend) *core.Filter {
filter := core.NewFilter(eth)
if object["earliest"] != nil {
val := ethutil.NewValue(object["earliest"])
filter.SetEarliestBlock(val.Int())
}
if object["latest"] != nil {
val := ethutil.NewValue(object["latest"])
filter.SetLatestBlock(val.Int())
}
if object["address"] != nil {
//val := ethutil.NewValue(object["address"])
//filter.SetAddress(fromHex(val.Str()))
}
if object["max"] != nil {
val := ethutil.NewValue(object["max"])
filter.SetMax(int(val.Uint()))
}
if object["skip"] != nil {
val := ethutil.NewValue(object["skip"])
filter.SetSkip(int(val.Uint()))
}
if object["topics"] != nil {
filter.SetTopics(MakeTopics(object["topics"]))
}
return filter
}
// Conversion methodn
func mapToAccountChange(m map[string]interface{}) (d core.AccountChange) {
if str, ok := m["id"].(string); ok {
d.Address = fromHex(str)
}
if str, ok := m["at"].(string); ok {
d.StateAddress = fromHex(str)
}
return
}
// data can come in in the following formats:
// ["aabbccdd", {id: "ccddee", at: "11223344"}], "aabbcc", {id: "ccddee", at: "1122"}
func MakeTopics(v interface{}) (d [][]byte) {
if str, ok := v.(string); ok {
d = append(d, fromHex(str))
} else if slice, ok := v.([]string); ok {
for _, item := range slice {
d = append(d, fromHex(item))
}
}
return
}

View File

@ -300,14 +300,6 @@ func (self *XEth) Transact(toStr, valueStr, gasStr, gasPriceStr, codeStr string)
tx.SetNonce(nonce) tx.SetNonce(nonce)
tx.Sign(key.PrivateKey) tx.Sign(key.PrivateKey)
//fmt.Printf("create tx: %x %v\n", tx.Hash()[:4], tx.Nonce())
// Do some pre processing for our "pre" events and hooks
//block := self.chainManager.NewBlock(key.Address())
//coinbase := state.GetOrNewStateObject(key.Address())
//coinbase.SetGasPool(block.GasLimit())
//self.blockProcessor.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true)
err = self.eth.TxPool().Add(tx) err = self.eth.TxPool().Add(tx)
if err != nil { if err != nil {
return "", err return "", err