diff options
Diffstat (limited to 'cmd')
37 files changed, 800 insertions, 659 deletions
diff --git a/cmd/bootnode/main.go b/cmd/bootnode/main.go new file mode 100644 index 000000000..dda9f34d4 --- /dev/null +++ b/cmd/bootnode/main.go @@ -0,0 +1,93 @@ +/* + This file is part of go-ethereum + + go-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + go-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. +*/ + +// Command bootnode runs a bootstrap node for the Discovery Protocol. +package main + +import ( + "crypto/ecdsa" + "encoding/hex" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/nat" +) + +func main() { + var ( + listenAddr = flag.String("addr", ":30301", "listen address") + genKey = flag.String("genkey", "", "generate a node key and quit") + nodeKeyFile = flag.String("nodekey", "", "private key filename") + nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") + natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)") + + nodeKey *ecdsa.PrivateKey + err error + ) + flag.Parse() + logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.DebugLevel)) + + if *genKey != "" { + writeKey(*genKey) + os.Exit(0) + } + + natm, err := nat.Parse(*natdesc) + if err != nil { + log.Fatalf("-nat: %v", err) + } + switch { + case *nodeKeyFile == "" && *nodeKeyHex == "": + log.Fatal("Use -nodekey or -nodekeyhex to specify a private key") + case *nodeKeyFile != "" && *nodeKeyHex != "": + log.Fatal("Options -nodekey and -nodekeyhex are mutually exclusive") + case *nodeKeyFile != "": + if nodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil { + log.Fatalf("-nodekey: %v", err) + } + case *nodeKeyHex != "": + if nodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil { + log.Fatalf("-nodekeyhex: %v", err) + } + } + + if _, err := discover.ListenUDP(nodeKey, *listenAddr, natm); err != nil { + log.Fatal(err) + } + select {} +} + +func writeKey(target string) { + key, err := crypto.GenerateKey() + if err != nil { + log.Fatal("could not generate key: %v", err) + } + b := crypto.FromECDSA(key) + if target == "-" { + fmt.Println(hex.EncodeToString(b)) + } else { + if err := ioutil.WriteFile(target, b, 0600); err != nil { + log.Fatal("write error: ", err) + } + } +} diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go index af57c6a67..577bee442 100644 --- a/cmd/ethereum/flags.go +++ b/cmd/ethereum/flags.go @@ -21,6 +21,7 @@ package main import ( + "crypto/ecdsa" "flag" "fmt" "log" @@ -28,7 +29,9 @@ import ( "os/user" "path" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/vm" ) @@ -42,14 +45,14 @@ var ( StartWebSockets bool RpcPort int WsPort int - NatType string - PMPGateway string OutboundPort string ShowGenesis bool AddPeer string MaxPeer int GenAddr bool - SeedNode string + BootNodes string + NodeKey *ecdsa.PrivateKey + NAT nat.Interface SecretFile string ExportDir string NonInteractive bool @@ -58,6 +61,7 @@ var ( ConfigFile string DebugFile string LogLevel int + LogFormat string Dump bool DumpHash string DumpNumber int @@ -83,6 +87,7 @@ func defaultDataDir() string { var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini") func Init() { + // TODO: move common flag processing to cmd/util flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line\n", os.Args[0]) flag.PrintDefaults() @@ -92,18 +97,12 @@ func Init() { flag.StringVar(&Identifier, "id", "", "Custom client identifier") flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use") flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") - flag.StringVar(&OutboundPort, "port", "30303", "listening port") - flag.StringVar(&NatType, "nat", "", "NAT support (UPNP|PMP) (none)") - flag.StringVar(&PMPGateway, "pmp", "", "Gateway IP for PMP") - flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers") + 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.BoolVar(&StartRpc, "rpc", false, "start rpc server") flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server") flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)") - flag.StringVar(&SeedNode, "seednode", "poc-8.ethdev.com:30303", "ip:port of seed node to connect to. Set to blank for skip") - flag.BoolVar(&SHH, "shh", true, "whisper protocol (on)") - flag.BoolVar(&Dial, "dial", true, "dial out connections (on)") flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") 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") @@ -112,6 +111,7 @@ func Init() { 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(&LogFormat, "logformat", "std", "logformat: std,raw)") flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0") flag.StringVar(&DiffType, "diff", "all", "sets the level of diff output [vm, all]. Has no effect if difftool=false") flag.BoolVar(&ShowGenesis, "genesis", false, "Dump the genesis block") @@ -125,8 +125,38 @@ func Init() { flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console") flag.BoolVar(&PrintVersion, "version", false, "prints version number") + // Network stuff + var ( + nodeKeyFile = flag.String("nodekey", "", "network private key file") + nodeKeyHex = flag.String("nodekeyhex", "", "network private key (for testing)") + natstr = flag.String("nat", "any", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)") + ) + flag.BoolVar(&Dial, "dial", true, "dial out connections (default on)") + //flag.BoolVar(&SHH, "shh", true, "run whisper protocol (default on)") + flag.StringVar(&OutboundPort, "port", "30303", "listening port") + + flag.StringVar(&BootNodes, "bootnodes", "", "space-separated node URLs for discovery bootstrap") + flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers") + flag.Parse() + var err error + if NAT, err = nat.Parse(*natstr); err != nil { + log.Fatalf("-nat: %v", err) + } + switch { + case *nodeKeyFile != "" && *nodeKeyHex != "": + log.Fatal("Options -nodekey and -nodekeyhex are mutually exclusive") + case *nodeKeyFile != "": + if NodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil { + log.Fatalf("-nodekey: %v", err) + } + case *nodeKeyHex != "": + if NodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil { + log.Fatalf("-nodekeyhex: %v", err) + } + } + if VmType >= int(vm.MaxVmTy) { log.Fatal("Invalid VM type ", VmType) } diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 4b16fb79f..9c840de58 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -31,12 +31,13 @@ import ( "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/state" ) const ( ClientIdentifier = "Ethereum(G)" - Version = "0.8.2" + Version = "0.8.5" ) var clilogger = logger.NewLogger("CLI") @@ -61,20 +62,20 @@ func main() { utils.InitConfig(VmType, ConfigFile, Datadir, "ETH") ethereum, err := eth.New(ð.Config{ - Name: ClientIdentifier, - Version: Version, - KeyStore: KeyStore, - DataDir: Datadir, - LogFile: LogFile, - LogLevel: LogLevel, - Identifier: Identifier, - MaxPeers: MaxPeer, - Port: OutboundPort, - NATType: PMPGateway, - PMPGateway: PMPGateway, - KeyRing: KeyRing, - Shh: SHH, - Dial: Dial, + Name: p2p.MakeName(ClientIdentifier, Version), + KeyStore: KeyStore, + DataDir: Datadir, + LogFile: LogFile, + LogLevel: LogLevel, + LogFormat: LogFormat, + MaxPeers: MaxPeer, + Port: OutboundPort, + NAT: NAT, + KeyRing: KeyRing, + Shh: true, + Dial: Dial, + BootNodes: BootNodes, + NodeKey: NodeKey, }) if err != nil { @@ -134,7 +135,7 @@ func main() { utils.StartWebSockets(ethereum, WsPort) } - utils.StartEthereum(ethereum, SeedNode) + utils.StartEthereum(ethereum) if StartJsConsole { InitJsConsole(ethereum) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index e1c4806ad..40874616c 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -51,8 +51,8 @@ func StateObjectFromAccount(db ethutil.Database, addr string, account Account) * if ethutil.IsHex(account.Code) { account.Code = account.Code[2:] } - obj.Code = ethutil.Hex2Bytes(account.Code) - obj.Nonce = ethutil.Big(account.Nonce).Uint64() + obj.SetCode(ethutil.Hex2Bytes(account.Code)) + obj.SetNonce(ethutil.Big(account.Nonce).Uint64()) return obj } diff --git a/cmd/mist/assets/backButtonDisabled.png b/cmd/mist/assets/backButtonDisabled.png Binary files differnew file mode 100644 index 000000000..428747870 --- /dev/null +++ b/cmd/mist/assets/backButtonDisabled.png diff --git a/cmd/mist/assets/backButtonDisabled@2x.png b/cmd/mist/assets/backButtonDisabled@2x.png Binary files differnew file mode 100644 index 000000000..0eaa6daa5 --- /dev/null +++ b/cmd/mist/assets/backButtonDisabled@2x.png diff --git a/cmd/mist/assets/backButtonHover.png b/cmd/mist/assets/backButtonHover.png Binary files differnew file mode 100644 index 000000000..8c5226f5a --- /dev/null +++ b/cmd/mist/assets/backButtonHover.png diff --git a/cmd/mist/assets/backButtonHover@2x.png b/cmd/mist/assets/backButtonHover@2x.png Binary files differnew file mode 100644 index 000000000..406601ebc --- /dev/null +++ b/cmd/mist/assets/backButtonHover@2x.png diff --git a/cmd/mist/assets/browser.png b/cmd/mist/assets/browser.png Binary files differindex 7b3b0870c..074c9ae3c 100644 --- a/cmd/mist/assets/browser.png +++ b/cmd/mist/assets/browser.png diff --git a/cmd/mist/assets/browser@2x.png b/cmd/mist/assets/browser@2x.png Binary files differnew file mode 100644 index 000000000..8ca417608 --- /dev/null +++ b/cmd/mist/assets/browser@2x.png diff --git a/cmd/mist/assets/examples/bomb.html b/cmd/mist/assets/examples/bomb.html new file mode 100644 index 000000000..62540f9bb --- /dev/null +++ b/cmd/mist/assets/examples/bomb.html @@ -0,0 +1,22 @@ +<html> +<head> +<script src="../ext/bignumber.min.js"></script> +<script src="../ext/ethereum.js/dist/ethereum.js"></script> + +<script> +var web3 = require('web3'); +web3.setProvider(new web3.providers.HttpSyncProvider('http://localhost:8545')); +var eth = web3.eth; + +function bomb() { + for (var i = 0; i < 200; i++) { + eth.transact({}) + } +} +</script> +</head> + +<body> +<button onclick="bomb();">BOOM!</button> +</body> +</html> diff --git a/cmd/mist/assets/examples/coin.html b/cmd/mist/assets/examples/coin.html index 71b359834..18a6811d7 100644 --- a/cmd/mist/assets/examples/coin.html +++ b/cmd/mist/assets/examples/coin.html @@ -7,15 +7,16 @@ </head> <body> -<h1>JevCoin <code id="address"></code></h1> +<h1>JevCoin <code id="contract_addr"></code></h1> <div> <strong>Balance</strong> <span id="balance"></strong> </div> <div> - <span class="amount">Amount:</span> + <span>Address:</span> <input type="text" id="address" style="width:200px"> + <span>Amount:</span> <input type="text" id="amount" style="width:200px"> <button onclick="transact()">Send</button> </div> @@ -58,32 +59,25 @@ }], "outputs": [] }, { - "name":"changed", + "name":"Changed", "type":"event", "inputs": [ - {"name":"to","type":"address","indexed":true}, {"name":"from","type":"address","indexed":true}, + {"name":"amount","type":"uint256","indexed":true}, ], }]; var address = localStorage.getItem("address"); // deploy if not exist if (address == null) { - var code = "0x60056013565b610132806100356000396000f35b620f4240600033600160a060020a0316600052602052604060002081905550560060e060020a6000350480637bb98a681461002b578063d0679d3414610039578063e3d670d71461004d57005b61003361012d565b60006000f35b610047600435602435610062565b60006000f35b61005860043561010b565b8060005260206000f35b80600033600160a060020a0316600052602052604060002054106100855761008a565b610107565b80600033600160a060020a0316600052602052604060002090815403908190555080600083600160a060020a0316600052602052604060002090815401908190555081600160a060020a031633600160a060020a03167f1863989b4bb7c5c3941722099764574df7a459f9f9c6b6cdca35ddc9731792b860006000a35b5050565b6000600082600160a060020a03166000526020526040600020549050919050565b5b60008156"; - address = web3.eth.transact({ - data: code, - gasPrice: "1000000000000000", - gas: "10000", - }); + var code = "0x60056013565b61014f8061003a6000396000f35b620f42406000600033600160a060020a0316815260200190815260200160002081905550560060e060020a600035048063d0679d3414610020578063e3d670d71461003457005b61002e600435602435610049565b60006000f35b61003f600435610129565b8060005260206000f35b806000600033600160a060020a03168152602001908152602001600020541061007157610076565b610125565b806000600033600160a060020a03168152602001908152602001600020908154039081905550806000600084600160a060020a031681526020019081526020016000209081540190819055508033600160a060020a03167fb52dda022b6c1a1f40905a85f257f689aa5d69d850e49cf939d688fbe5af594660006000a38082600160a060020a03167fb52dda022b6c1a1f40905a85f257f689aa5d69d850e49cf939d688fbe5af594660006000a35b5050565b60006000600083600160a060020a0316815260200190815260200160002054905091905056"; + address = web3.eth.transact({data: code}); localStorage.setItem("address", address); } - document.querySelector("#address").innerHTML = address.toUpperCase(); + document.querySelector("#contract_addr").innerHTML = address; var contract = web3.eth.contract(address, desc); - contract.changed({from: eth.accounts[0]}).changed(function() { - refresh(); - }); - eth.watch('chain').changed(function() { + contract.Changed({from: eth.coinbase}).changed(function() { refresh(); }); @@ -96,13 +90,12 @@ var storage = eth.storageAt(address); table.innerHTML = ""; for( var item in storage ) { - table.innerHTML += "<tr><td>"+item.toUpperCase()+"</td><td>"+web3.toDecimal(storage[item])+"</td></tr>"; + table.innerHTML += "<tr><td>"+item+"</td><td>"+web3.toDecimal(storage[item])+"</td></tr>"; } } function transact() { var to = document.querySelector("#address").value; - if( to.length == 0 ) { to = "0x4205b06c2cfa0e30359edcab94543266cb6fa1d3"; } else { @@ -110,13 +103,13 @@ } var value = parseInt( document.querySelector("#amount").value ); + console.log("transact: ", to, " => ", value) contract.send( to, value ); } refresh(); </script> - </html> <!-- @@ -126,7 +119,7 @@ contract JevCoin { balances[msg.sender] = 1000000; } - event changed(address indexed from, address indexed to); + event Changed(address indexed from, uint indexed amount); function send(address to, uint value) { if( balances[msg.sender] < value ) return; @@ -134,7 +127,8 @@ contract JevCoin { balances[msg.sender] -= value; balances[to] += value; - changed(msg.sender, to); + Changed(msg.sender, value); + Changed(to, value); } function balance(address who) constant returns(uint t) diff --git a/cmd/mist/assets/examples/coin.js b/cmd/mist/assets/examples/coin.js new file mode 100644 index 000000000..77daac846 --- /dev/null +++ b/cmd/mist/assets/examples/coin.js @@ -0,0 +1,65 @@ +var walletABI = [ + { + "name":"confirm", + "type":"function", + "constant":false, + "inputs":[ + {"name":"_h","type":"hash256"} + ], + "outputs":[] + },{ + "name":"execute", + "constant":false, + "type":"function", + "inputs":[ + {"name":"_to","type":"address"}, + {"name":"_value","type":"uint256"}, + {"name":"_data","type":"bytes"} + ], + "outputs":[ + {"name":"_r","type":"hash256"} + ] + },{ + "name":"kill", + "type":"function", + "constant":false, + "inputs":[ + {"name":"_to","type":"address"} + ], + "outputs":[] + },{ + "name":"changeOwner", + "type":"function", + "constant":false, + "inputs":[ + {"name":"_from","type":"address"}, + {"name":"_to","type":"address"} + ], + "outputs":[] + },{ + "name":"CashIn", + "type":"event", + "inputs":[ + {"indexed":false,"name":"value","type":"uint256"} + ] + },{ + "name":"SingleTransact", + "type":"event", + "inputs":[ + {"indexed":true,"name":"out","type":"string32"}, + {"indexed":false,"name":"owner","type":"address"}, + {"indexed":false,"name":"value","type":"uint256"}, + {"indexed":false,"name":"to","type":"address"} + ] + },{ + "name":"MultiTransact", + "type":"event", + "inputs":[ + {"indexed":true,"name":"out","type":"string32"}, + {"indexed":false,"name":"owner","type":"address"}, + {"indexed":false,"name":"operation","type":"hash256"}, + {"indexed":false,"name":"value","type":"uint256"}, + {"indexed":false,"name":"to","type":"address"} + ] + } +]; diff --git a/cmd/mist/assets/examples/info.html b/cmd/mist/assets/examples/info.html index daad8c706..2a405c280 100644 --- a/cmd/mist/assets/examples/info.html +++ b/cmd/mist/assets/examples/info.html @@ -1,8 +1,8 @@ <!doctype> <html> - <head> +<meta name="badge" content="10"> <script type="text/javascript" src="../ext/bignumber.min.js"></script> <script type="text/javascript" src="../ext/ethereum.js/dist/ethereum.js"></script> </head> @@ -60,7 +60,7 @@ var web3 = require('web3'); var eth = web3.eth; - web3.setProvider(new web3.providers.HttpSyncProvider('http://localhost:8080')); + web3.setProvider(new web3.providers.HttpSyncProvider('http://localhost:8545')); document.querySelector("#number").innerHTML = eth.number; document.querySelector("#coinbase").innerHTML = eth.coinbase @@ -71,6 +71,10 @@ document.querySelector("#gas_price").innerHTML = eth.gasPrice; document.querySelector("#mining").innerHTML = eth.mining; document.querySelector("#listening").innerHTML = eth.listening; + eth.watch('chain').changed(function() { + document.querySelector("#number").innerHTML = eth.number; + }); + </script> </html> diff --git a/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js b/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js index d0e9d3cb7..83b598b3f 100644 --- a/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js +++ b/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js @@ -1417,6 +1417,8 @@ var ethMethods = function () { var methods = [ { name: 'balanceAt', call: 'eth_balanceAt' }, + { name: 'register', call: 'eth_register' }, + { name: 'unregister', call: 'eth_unregister' }, { name: 'stateAt', call: 'eth_stateAt' }, { name: 'storageAt', call: 'eth_storageAt' }, { name: 'countAt', call: 'eth_countAt'}, diff --git a/cmd/mist/assets/ext/mist.js b/cmd/mist/assets/ext/mist.js new file mode 100644 index 000000000..2fc38cdfa --- /dev/null +++ b/cmd/mist/assets/ext/mist.js @@ -0,0 +1,37 @@ +// Copyright (c) 2015, ETHDEV. All rights reserved. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +// MA 02110-1301 USA + +// this function is included locally, but you can also include separately via a header definition + +console.log("loaded?"); + +document.onkeydown = function(evt) { + // This functions keeps track of keyboard inputs in order to allow copy, paste and other features + + evt = evt || window.event; + if (evt.ctrlKey && evt.keyCode == 67) { + window.document.execCommand("copy"); + } else if (evt.ctrlKey && evt.keyCode == 88) { + window.document.execCommand("cut"); + } else if (evt.ctrlKey && evt.keyCode == 86) { + window.document.execCommand("paste"); + } else if (evt.ctrlKey && evt.keyCode == 90) { + window.document.execCommand("undo"); + } else if (evt.ctrlKey && evt.shiftKey && evt.keyCode == 90) { + window.document.execCommand("redo"); + } +};
\ No newline at end of file diff --git a/cmd/mist/assets/miner.png b/cmd/mist/assets/miner.png Binary files differdeleted file mode 100644 index 58e3f4dfe..000000000 --- a/cmd/mist/assets/miner.png +++ /dev/null diff --git a/cmd/mist/assets/mining-icon.png b/cmd/mist/assets/mining-icon.png Binary files differnew file mode 100644 index 000000000..db611e5c0 --- /dev/null +++ b/cmd/mist/assets/mining-icon.png diff --git a/cmd/mist/assets/mining-icon@2x.png b/cmd/mist/assets/mining-icon@2x.png Binary files differnew file mode 100644 index 000000000..16466d338 --- /dev/null +++ b/cmd/mist/assets/mining-icon@2x.png diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index e169f54ec..e80bd87e0 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -17,6 +17,7 @@ ApplicationWindow { // Use this to make the window frameless. But then you'll need to do move and resize by hand property var ethx : Eth.ethx + property var catalog; width: 1200 height: 820 @@ -39,19 +40,22 @@ ApplicationWindow { // Takes care of loading all default plugins Component.onCompleted: { - addPlugin("./views/catalog.qml", {noAdd: true, close: false, section: "begin"}); - var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true}); + catalog = addPlugin("./views/catalog.qml", {noAdd: true, close: false, section: "begin", active: true}); - addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true}); + var walletWeb = addPlugin("./views/browser.qml", {noAdd: true, close: false, section: "ethereum", active: false}); + walletWeb.view.url = "http://ethereum-dapp-wallet.meteor.com/"; + walletWeb.menuItem.title = "Wallet"; + + addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: false}); addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/whisper.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"}); - mainSplit.setView(wallet.view, wallet.menuItem); + mainSplit.setView(catalog.view, catalog.menuItem); - newBrowserTab("http://ethereum-dapp-whisper-client.meteor.com/chat/amsteam"); + //newBrowserTab("http://ethereum-dapp-catalog.meteor.com"); // Command setup gui.sendCommand(0) @@ -59,13 +63,14 @@ ApplicationWindow { function activeView(view, menuItem) { mainSplit.setView(view, menuItem) - if (view.hideUrl) { + /*if (view.hideUrl) { urlPane.visible = false; mainView.anchors.top = rootView.top } else { urlPane.visible = true; mainView.anchors.top = divider.bottom - } + }*/ + } function addViews(view, path, options) { @@ -114,10 +119,34 @@ ApplicationWindow { } function newBrowserTab(url) { - var window = addPlugin("./views/browser.qml", {noAdd: true, close: true, section: "apps", active: true}); - window.view.url = url; - window.menuItem.title = "Mist"; - activeView(window.view, window.menuItem); + + var urlMatches = url.toString().match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); + var requestedDomain = urlMatches && urlMatches[1]; + + var domainAlreadyOpen = false; + + for(var i = 0; i < mainSplit.views.length; i++) { + if (mainSplit.views[i].view.url) { + var matches = mainSplit.views[i].view.url.toString().match(/^[a-z]*\:\/\/(?:www\.)?([^\/?#]+)(?:[\/?#]|$)/i); + var existingDomain = matches && matches[1]; + if (requestedDomain == existingDomain) { + domainAlreadyOpen = true; + + if (mainSplit.views[i].view.url != url){ + mainSplit.views[i].view.url = url; + } + + activeView(mainSplit.views[i].view, mainSplit.views[i].menuItem); + } + } + } + + if (!domainAlreadyOpen) { + var window = addPlugin("./views/browser.qml", {noAdd: true, close: true, section: "apps", active: true}); + window.view.url = url; + window.menuItem.title = "Mist"; + activeView(window.view, window.menuItem); + } } @@ -126,27 +155,10 @@ ApplicationWindow { Menu { title: "File" MenuItem { - text: "Import App" - shortcut: "Ctrl+o" - onTriggered: { - generalFileDialog.show(true, importApp) - } - } - - MenuItem { - text: "Add plugin" - onTriggered: { - generalFileDialog.show(true, function(path) { - addPlugin(path, {close: true, section: "apps"}) - }) - } - } - - MenuItem { text: "New tab" shortcut: "Ctrl+t" onTriggered: { - newBrowserTab("http://etherian.io"); + activeView(catalog.view, catalog.menuItem); } } @@ -239,90 +251,8 @@ ApplicationWindow { } } - Menu { - title: "GLOBAL SHORTCUTS" - visible: false - MenuItem { - visible: false - shortcut: "Ctrl+l" - onTriggered: { - url.focus = true - } - } - } - } - - statusBar: StatusBar { - //height: 32 - visible: false - - id: statusBar - Label { - //y: 6 - id: walletValueLabel - - font.pixelSize: 10 - styleColor: "#797979" - } - - Label { - //y: 6 - objectName: "miningLabel" - visible: true - font.pixelSize: 10 - anchors.right: lastBlockLabel.left - anchors.rightMargin: 5 - } - - Label { - id: lastBlockLabel - objectName: "lastBlockLabel" - visible: true - text: "---" - font.pixelSize: 10 - anchors.right: peerGroup.left - anchors.rightMargin: 5 - } - - ProgressBar { - visible: false - id: downloadIndicator - value: 0 - objectName: "downloadIndicator" - y: -4 - x: statusBar.width / 2 - this.width / 2 - width: 160 - } - - Label { - visible: false - objectName: "downloadLabel" - //y: 7 - anchors.left: downloadIndicator.right - anchors.leftMargin: 5 - font.pixelSize: 10 - text: "0 / 0" - } - - - RowLayout { - id: peerGroup - //y: 7 - anchors.right: parent.right - MouseArea { - onDoubleClicked: peerWindow.visible = true - anchors.fill: parent - } - - Label { - id: peerLabel - font.pixelSize: 10 - text: "0 / 0" - } - } } - property var blockModel: ListModel { id: blockModel } @@ -332,8 +262,9 @@ ApplicationWindow { id: mainSplit anchors.fill: parent - resizing: false + //resizing: false // this is NOT where we remove that damning resizing handle.. handleDelegate: Item { + //This handle is a way to remove the line between the split views Rectangle { anchors.fill: parent } @@ -447,10 +378,14 @@ ApplicationWindow { property var view; property var path; property var closable; + property var badgeContent; property alias title: label.text property alias icon: icon.source property alias secondaryTitle: secondary.text + property alias badgeNumber: badgeNumberLabel.text + property alias badgeIcon: badgeIconLabel.text + function setSelection(on) { sel.visible = on @@ -464,7 +399,7 @@ ApplicationWindow { label.visible = !on buttonLabel.visible = on } - + width: 192 height: 55 color: "#00000000" @@ -497,7 +432,7 @@ ApplicationWindow { anchors.fill: parent border.width: 0 radius: 5 - color: "#FFFFFFFF" + color: "#FAFAFA" } Rectangle { anchors { @@ -506,7 +441,7 @@ ApplicationWindow { right: r.right } width: 10 - color: "#FFFFFFFF" + color: "#FAFAFA" border.width:0 Rectangle { @@ -517,7 +452,7 @@ ApplicationWindow { top: parent.top } height: 1 - color: "#FFFFFF" + color: "#FAFAFA" } Rectangle { @@ -528,7 +463,7 @@ ApplicationWindow { bottom: parent.bottom } height: 1 - color: "#FFFFFF" + color: "#FAFAFA" } } } @@ -543,7 +478,6 @@ ApplicationWindow { if (parent.closable == true) { closeIcon.visible = sel.visible } - } onExited: { closeIcon.visible = false @@ -552,8 +486,8 @@ ApplicationWindow { Image { id: icon - height: 24 - width: 24 + height: 28 + width: 28 anchors { left: parent.left verticalCenter: parent.verticalCenter @@ -576,18 +510,24 @@ ApplicationWindow { id: label font.family: sourceSansPro.name font.weight: Font.DemiBold + elide: Text.ElideRight + x:250 + color: "#665F5F" + font.pixelSize: 14 anchors { left: icon.right + right: parent.right verticalCenter: parent.verticalCenter leftMargin: 6 - // verticalCenterOffset: -10 + rightMargin: 8 + verticalCenterOffset: (secondaryTitle == "") ? 0 : -10; } - x:250 - color: "#665F5F" - font.pixelSize: 14 - } + + + } + Text { id: secondary font.family: sourceSansPro.name @@ -606,7 +546,7 @@ ApplicationWindow { visible: false width: 10 height: 10 - color: "#FFFFFF" + color: "#FAFAFA" anchors { fill: icon } @@ -625,9 +565,49 @@ ApplicationWindow { centerIn: parent } color: "#665F5F" - font.pixelSize: 18 + font.pixelSize: 20 text: "\ue082" } + } + + Rectangle { + id: badge + visible: (badgeContent == "icon" || badgeContent == "number" )? true : false + width: 32 + color: "#05000000" + anchors { + right: parent.right; + top: parent.top; + bottom: parent.bottom; + rightMargin: 4; + } + + Text { + id: badgeIconLabel + visible: (badgeContent == "icon") ? true : false; + font.family: simpleLineIcons.name + anchors { + centerIn: parent + } + horizontalAlignment: Text.AlignCenter + color: "#AAA0A0" + font.pixelSize: 20 + text: badgeIcon + } + + Text { + id: badgeNumberLabel + visible: (badgeContent == "number") ? true : false; + anchors { + centerIn: parent + } + horizontalAlignment: Text.AlignCenter + font.family: sourceSansPro.name + font.weight: Font.Light + color: "#AAA0A0" + font.pixelSize: 18 + text: badgeNumber + } } @@ -800,7 +780,7 @@ ApplicationWindow { anchors.top: parent.top color: "#00000000" - Rectangle { + /*Rectangle { id: urlPane height: 40 color: "#00000000" @@ -847,7 +827,7 @@ ApplicationWindow { z: -1 height: 1 color: "#CCCCCC" - } + }*/ Rectangle { id: mainView @@ -855,7 +835,7 @@ ApplicationWindow { anchors.right: parent.right anchors.left: parent.left anchors.bottom: parent.bottom - anchors.top: divider.bottom + anchors.top: parent.top function createView(component) { var view = component.createObject(mainView) @@ -899,9 +879,8 @@ ApplicationWindow { } } - function setWalletValue(value) { - walletValueLabel.text = value + //walletValueLabel.text = value } function loadPlugin(name) { @@ -909,17 +888,11 @@ ApplicationWindow { var view = mainView.addPlugin(name) } - function setPeers(text) { - peerLabel.text = text - } - - function addPeer(peer) { - // We could just append the whole peer object but it cries if you try to alter them - peerModel.append({ip: peer.ip, port: peer.port, lastResponse:timeAgo(peer.lastSend), latency: peer.latency, version: peer.version, caps: peer.caps}) - } + function clearPeers() { peerModel.clear() } + function addPeer(peer) { peerModel.append(peer) } - function resetPeers(){ - peerModel.clear() + function setPeerCounters(text) { + //peerCounterLabel.text = text } function timeAgo(unixTs){ @@ -957,9 +930,10 @@ ApplicationWindow { anchors.fill: parent id: peerTable model: peerModel - TableViewColumn{width: 200; role: "ip" ; title: "IP" } - TableViewColumn{width: 260; role: "version" ; title: "Version" } - TableViewColumn{width: 180; role: "caps" ; title: "Capabilities" } + TableViewColumn{width: 180; role: "addr" ; title: "Remote Address" } + TableViewColumn{width: 280; role: "nodeID" ; title: "Node ID" } + TableViewColumn{width: 100; role: "name" ; title: "Name" } + TableViewColumn{width: 40; role: "caps" ; title: "Capabilities" } } } } @@ -990,7 +964,7 @@ ApplicationWindow { anchors.top: parent.top anchors.topMargin: 30 font.pointSize: 12 - text: "<h2>Mist (0.7.10)</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor Trón<br>Felix Lange<br>Taylor Gerring<br>Daniel Nagy<br><h3>UX</h3>Alex van de Sande<br>" + text: "<h2>Mist (0.8.5)</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor Trón<br>Felix Lange<br>Taylor Gerring<br>Daniel Nagy<br>Gustav Simonsson<br><h3>UX/UI</h3>Alex van de Sande<br>Fabian Vogelsteller" } } @@ -1027,37 +1001,25 @@ ApplicationWindow { Window { id: addPeerWin visible: false - minimumWidth: 300 - maximumWidth: 300 + minimumWidth: 400 + maximumWidth: 400 maximumHeight: 50 minimumHeight: 50 title: "Connect to peer" - ComboBox { + TextField { id: addrField anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.right: addPeerButton.left anchors.leftMargin: 10 anchors.rightMargin: 10 + placeholderText: "enode://<hex node id>:<IP address>:<port>" onAccepted: { - eth.connectToPeer(addrField.currentText) - addPeerWin.visible = false - } - - editable: true - model: ListModel { id: pastPeers } - - Component.onCompleted: { - pastPeers.insert(0, {text: "poc-8.ethdev.com:30303"}) - /* - var ips = eth.pastPeers() - for(var i = 0; i < ips.length; i++) { - pastPeers.append({text: ips.get(i)}) - } - - pastPeers.insert(0, {text: "poc-7.ethdev.com:30303"}) - */ + if(addrField.text.length != 0) { + eth.connectToPeer(addrField.text) + addPeerWin.visible = false + } } } @@ -1066,14 +1028,16 @@ ApplicationWindow { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter anchors.rightMargin: 10 - text: "Add" + text: "Connect" onClicked: { - eth.connectToPeer(addrField.currentText) - addPeerWin.visible = false + if(addrField.text.length != 0) { + eth.connectToPeer(addrField.text) + addPeerWin.visible = false + } } } Component.onCompleted: { addrField.focus = true } } - }
\ No newline at end of file + } diff --git a/cmd/mist/assets/qml/views/browser.qml b/cmd/mist/assets/qml/views/browser.qml index db89c6837..edecc8696 100644 --- a/cmd/mist/assets/qml/views/browser.qml +++ b/cmd/mist/assets/qml/views/browser.qml @@ -3,7 +3,7 @@ import QtQuick.Controls 1.0; import QtQuick.Controls.Styles 1.0 import QtQuick.Layouts 1.0; import QtWebEngine 1.0 -//import QtWebEngine.experimental 1.0 +import QtWebEngine.experimental 1.0 import QtQuick.Window 2.0; Rectangle { @@ -64,23 +64,15 @@ Rectangle { } function showFullUrlBar(on){ - if (on) { - //appTitle.visible = false - //appDomain.visible = false - - //uriNav.visible = true - clickAnywhereOnApp.visible = true - - navBar.state = "fullUrlVisible" - } else { - //appTitle.visible = true - //appDomain.visible = true - //uriNav.visible = false - clickAnywhereOnApp.visible = false - - navBar.state = "titleVisible" - - } + if (uriNav.focus == false ) { + if (on == false) { + clickAnywhereOnApp.visible = false + navBar.state = "titleVisible" + } else { + clickAnywhereOnApp.visible = true + navBar.state = "fullUrlVisible" + } + } } @@ -90,24 +82,40 @@ Rectangle { Item { objectName: "root" id: root - anchors.fill: parent + anchors { + fill: parent + } + state: "inspectorShown" MouseArea { id: clickAnywhereOnApp z:15 - //hoverEnabled: true - anchors.fill: parent - /*hoverEnabled: true*/ + // Using a secondary screen to catch on mouse exits for the area, because + // there are many hover actions conflicting + + anchors { + top: parent.top + topMargin: 50 + right: parent.right + bottom: parent.bottom + left: parent.left + } + hoverEnabled: true - onClicked: { + onEntered: { showFullUrlBar(false); } - /*Rectangle { - anchors.fill: parent - color: "#88888888" - }*/ + onClicked: { + uriNav.focus = false + showFullUrlBar(false); + } + + // Rectangle { + // anchors.fill: parent + // color: "#88888888" + // } } RowLayout { @@ -121,40 +129,44 @@ Rectangle { Button { id: back - - onClicked: { - webview.goBack() + z: 30 + onClicked: { + webview.goBack() } - anchors{ + anchors { left: parent.left leftMargin: 6 } style: ButtonStyle { - background: Image { - source: "../../backButton.png" - width: 20 - height: 30 - } + background: Image { + source: (webview.canGoBack) ? + (control.hovered ? "../../backButtonHover.png" : "../../backButton.png") : + "../../backButtonDisabled.png" + width: 20 + height: 30 + } } } Rectangle { - id: appInfoPane - height: 28 - color: "#FFFFFF" - radius: 6 - - - MouseArea { + id: appInfoPane + height: 28 + color: "#FFFFFF" + radius: 6 + z:2 + MouseArea { anchors.fill: parent z: 10 hoverEnabled: true onEntered: { - showFullUrlBar(true); - } + showFullUrlBar(true); + } + /*onExited: { + showFullUrlBar(false); + }*/ } @@ -171,14 +183,15 @@ Rectangle { font.bold: true font.capitalization: Font.AllUppercase horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + anchors { left: parent.left right: parent.horizontalCenter top: parent.top bottom: parent.bottom - rightMargin: 10 + leftMargin: 32 } color: "#928484" } @@ -189,13 +202,15 @@ Rectangle { font.bold: false horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter + elide: Text.ElideLeft anchors { left: parent.horizontalCenter right: parent.right top: parent.top bottom: parent.bottom - leftMargin: 10 + leftMargin: 32 + } color: "#C0AFAF" } @@ -212,7 +227,7 @@ Rectangle { } horizontalAlignment: Text.AlignHCenter - + style: TextFieldStyle { textColor: "#928484" background: Rectangle { @@ -225,16 +240,16 @@ Rectangle { z: 20 activeFocusOnPress: true Keys.onReturnPressed: { - webview.url = this.text; + // if there's no http, add it. + var url = this.text, + matches = url.match(/^([a-z]*\:\/\/)?([^\/.]+)(:?\/)(.*|$)/i), + requestedProtocol = (matches && matches[1] != "undefined")? "" : "http://"; + + webview.url = requestedProtocol + url; } - /* onFocusedChanged: { - if (focused) { - //uriNav.selectAll(); - } - }*/ } - z:2 + } Rectangle { @@ -243,6 +258,7 @@ Rectangle { height: 30 color: "#BDB6B6" radius: 6 + z:1 anchors { left: back.right @@ -251,19 +267,17 @@ Rectangle { rightMargin:10 top: parent.top topMargin: 23 - } - - z:1 + } } Rectangle { id: navBarBackground anchors.fill: parent + z:-1 gradient: Gradient { GradientStop { position: 0.0; color: "#F6F1F2" } GradientStop { position: 1.0; color: "#DED5D5" } } - z:-1 } states: [ @@ -326,6 +340,8 @@ Rectangle { WebEngineView { objectName: "webView" id: webview + experimental.settings.javascriptCanAccessClipboard: true + //experimental.settings.localContentCanAccessRemoteUrls: true anchors { left: parent.left right: parent.right @@ -333,17 +349,79 @@ Rectangle { top: navBar.bottom } z: 10 + + Timer { + interval: 2000; running: true; repeat: true + onTriggered: { + webview.runJavaScript("try{document.querySelector('meta[name=ethereum-dapp-info]').getAttribute('content')}catch(e){}", function(extraInfo) { + if (extraInfo) { + menuItem.secondaryTitle = extraInfo; + } + }); + webview.runJavaScript("try{document.querySelector('meta[name=ethereum-dapp-badge]').getAttribute('content')}catch(e){}", function(badge) { + if (badge) { + if (Number(badge)>0 && Number(badge)<999) { + menuItem.badgeNumber = Number(badge); + menuItem.badgeContent = "number" + } else if (badge == "warning") { + menuItem.badgeIcon = "\ue00e" + menuItem.badgeContent = "icon" + + } else if (badge == "ghost") { + menuItem.badgeIcon = "\ue01a" + menuItem.badgeContent = "icon" + + } else if (badge == "question") { + menuItem.badgeIcon = "\ue05d" + menuItem.badgeContent = "icon" + + } else if (badge == "info") { + menuItem.badgeIcon = "\ue08b" + menuItem.badgeContent = "icon" + + } else if (badge == "check") { + menuItem.badgeIcon = "\ue080" + menuItem.badgeContent = "icon" + + } else if (badge == "gear") { + menuItem.badgeIcon = "\ue09a" + menuItem.badgeContent = "icon" + + } else { + menuItem.badgeContent = "" + } + } else { + menuItem.badgeContent = "" + } + }); + } + } onLoadingChanged: { if (loadRequest.status == WebEngineView.LoadSucceededStatus) { - webview.runJavaScript("document.title", function(pageTitle) { + + webview.runJavaScript("document.title", function(pageTitle) { menuItem.title = pageTitle; }); - //var topBarStyle - webView.runJavaScript("document.querySelector(\"meta[name='ethereum-dapp-url-bar-style']\").getAttribute(\"content\")", function(topBarStyle){ - if (topBarStyle=="transparent") { + webView.runJavaScript("try{document.querySelector(\"link[rel='icon']\").getAttribute(\"href\")}catch(e){}", function(sideIcon){ + if(sideIcon){ + menuItem.icon = webview.url + sideIcon; + }; + }); + + webView.runJavaScript("try{document.querySelector(\"meta[name='ethereum-dapp-url-bar-style']\").getAttribute(\"content\")}catch(e){}", function(topBarStyle){ + if (!topBarStyle) { + showFullUrlBar(true); + navBarBackground.visible = true; + back.visible = true; + appInfoPane.anchors.leftMargin = 0; + appInfoPaneShadow.anchors.leftMargin = 0; + webview.anchors.topMargin = 0; + return; + } + if (topBarStyle=="transparent") { // Adjust for a transparent sidebar Dapp navBarBackground.visible = false; back.visible = false; @@ -352,22 +430,31 @@ Rectangle { webview.anchors.topMargin = -74; webview.runJavaScript("document.querySelector('body').classList.add('ethereum-dapp-url-bar-style-transparent')") + } else { + navBarBackground.visible = true; + back.visible = true; + appInfoPane.anchors.leftMargin = 0; + appInfoPaneShadow.anchors.leftMargin = 0; + webview.anchors.topMargin = 0; }; }); - webview.runJavaScript(eth.readFile("bignumber.min.js")); - webview.runJavaScript(eth.readFile("ethereum.js/dist/ethereum.js")); - + webview.runJavaScript(eth.readFile("ethereum.js/dist/ethereum.js")); + webview.runJavaScript(eth.readFile("mist.js")); + var cleanTitle = webview.url.toString() var matches = cleanTitle.match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); var domain = matches && matches[1]; - appDomain.text = domain //webview.url.replace("a", "z") - appTitle.text = webview.title - showFullUrlBar(false); + if (domain) + appDomain.text = domain //webview.url.replace("a", "z") + if (webview.title) + appTitle.text = webview.title + + showFullUrlBar(false); } } onJavaScriptConsoleMessage: { diff --git a/cmd/mist/assets/qml/views/catalog.qml b/cmd/mist/assets/qml/views/catalog.qml index 7f42c25dc..29e133074 100644 --- a/cmd/mist/assets/qml/views/catalog.qml +++ b/cmd/mist/assets/qml/views/catalog.qml @@ -3,7 +3,7 @@ import QtQuick.Controls 1.0; import QtQuick.Controls.Styles 1.0 import QtQuick.Layouts 1.0; import QtWebEngine 1.0 -//import QtWebEngine.experimental 1.0 +import QtWebEngine.experimental 1.0 import QtQuick.Window 2.0; @@ -12,7 +12,7 @@ Rectangle { anchors.fill: parent color: "#00000000" - property var title: "" + property var title: "Catalog" property var iconSource: "" property var menuItem property var hideUrl: true @@ -21,8 +21,6 @@ Rectangle { property alias windowTitle: webview.title property alias webView: webview - - property var cleanPath: false property var open: function(url) { if(!window.cleanPath) { @@ -66,124 +64,61 @@ Rectangle { } } - Component.onCompleted: { - } - Item { objectName: "root" id: root anchors.fill: parent state: "inspectorShown" - RowLayout { - id: navBar - height: 184 - z: 20 + WebEngineView { + objectName: "webView" + id: webview + anchors.fill: parent - anchors { - left: parent.left - right: parent.right - } + property var protocol: "http://" + //property var domain: "localhost:3000" + property var domain: "ethereum-dapp-catalog.meteor.com" + url: protocol + domain - Rectangle { - id: appInfoPane - height: 28 - color: "#efefef" - radius: 6 - z:25 - - MouseArea { - anchors.fill: parent - z: 10 - hoverEnabled: true - onEntered: { - uriNav.visible = true - appTitle.visible = false - appDomain.visible = false - } - } - - anchors { - left: parent.left - right: parent.right - leftMargin: 10 - rightMargin: 10 - top: parent.verticalCenter - topMargin: 23 - } + experimental.settings.javascriptCanAccessClipboard: true - TextField { - id: uriNav - anchors { - left: parent.left - right: parent.right - leftMargin: 16 - top: parent.verticalCenter - topMargin: -10 - } - - horizontalAlignment: Text.AlignHCenter - - style: TextFieldStyle { - textColor: "#928484" - background: Rectangle { - border.width: 0 - color: "transparent" - } - } - text: "Type the address of a new Dapp"; - y: parent.height / 2 - this.height / 2 - z: 30 - activeFocusOnPress: true - Keys.onReturnPressed: { - newBrowserTab(this.text); - this.text = "Type the address of a new Dapp"; - } - - } - } - - Rectangle { - id: appInfoPaneShadow - width: 10 - height: 30 - color: "#BDB6B6" - radius: 6 - z: 15 - - anchors { - left: parent.left - right: parent.right - leftMargin:10 - rightMargin:10 - top: parent.verticalCenter - topMargin: 23 - } - + onJavaScriptConsoleMessage: { + console.log(sourceID + ":" + lineNumber + ":" + JSON.stringify(message)); } - } - - - WebEngineView { - objectName: "webView" - id: webview - anchors.fill: parent - + onNavigationRequested: { + // this checks if the domain of the requested link is the same as the catalog's + // If it is, it opens on the same window, if it's not it opens a new tab + + var cleanTitle = request.url.toString() + var matches = cleanTitle.match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); + var requestedDomain = matches && matches[1]; + + + if(request.navigationType==0){ + + if (requestedDomain === this.domain){ + request.action = WebEngineView.AcceptRequest; + } else { + request.action = WebEngineView.IgnoreRequest; + newBrowserTab(request.url); + } + + } + } onLoadingChanged: { if (loadRequest.status == WebEngineView.LoadSucceededStatus) { - webview.runJavaScript(eth.readFile("bignumber.min.js")); - webview.runJavaScript(eth.readFile("ethereum.js/dist/ethereum.js")); + webview.runJavaScript(eth.readFile("mist.js")); } } - onJavaScriptConsoleMessage: { - console.log(sourceID + ":" + lineNumber + ":" + JSON.stringify(message)); - } } + + + WebEngineView { id: inspector visible: false @@ -191,7 +126,7 @@ Rectangle { anchors { left: root.left right: root.right - top: sizeGrip.bottom + top: root.top bottom: root.bottom } diff --git a/cmd/mist/assets/qml/views/info.qml b/cmd/mist/assets/qml/views/info.qml index 14ee0bce1..b2d2f521c 100644 --- a/cmd/mist/assets/qml/views/info.qml +++ b/cmd/mist/assets/qml/views/info.qml @@ -32,18 +32,6 @@ Rectangle { width: 500 } - Label { - text: "Client ID" - } - TextField { - text: gui.getCustomIdentifier() - width: 500 - placeholderText: "Anonymous" - onTextChanged: { - gui.setCustomIdentifier(text) - } - } - TextArea { objectName: "statsPane" width: parent.width diff --git a/cmd/mist/assets/qml/views/miner.qml b/cmd/mist/assets/qml/views/miner.qml index 193ce37be..e239c7d7b 100644 --- a/cmd/mist/assets/qml/views/miner.qml +++ b/cmd/mist/assets/qml/views/miner.qml @@ -9,11 +9,32 @@ import Ethereum 1.0 Rectangle { id: root property var title: "Miner" - property var iconSource: "../miner.png" + property var iconSource: "../mining-icon.png" property var menuItem color: "#00000000" + Label { + visible: false + id: lastBlockLabel + objectName: "lastBlockLabel" + text: "---" + onTextChanged: { + //menuItem.secondaryTitle = text + } + } + + Label { + objectName: "miningLabel" + visible: false + font.pixelSize: 10 + anchors.right: lastBlockLabel.left + anchors.rightMargin: 5 + onTextChanged: { + menuItem.secondaryTitle = text + } + } + ColumnLayout { spacing: 10 anchors.fill: parent diff --git a/cmd/mist/assets/qml/views/pending_tx.qml b/cmd/mist/assets/qml/views/pending_tx.qml index 4442a69db..3dcedeff2 100644 --- a/cmd/mist/assets/qml/views/pending_tx.qml +++ b/cmd/mist/assets/qml/views/pending_tx.qml @@ -41,4 +41,13 @@ Rectangle { pendingTxModel.insert(0, {hash: tx.hash, to: tx.address, from: tx.sender, value: tx.value, contract: isContract}) } + + function removeTx(tx) { + for (var i = 0; i < pendingTxModel.count; i++) { + if (tx.hash === pendingTxModel.get(i).hash) { + pendingTxModel.remove(i); + break; + } + } + } } diff --git a/cmd/mist/assets/qml/views/transaction.qml b/cmd/mist/assets/qml/views/transaction.qml index 62c762956..df798a9c0 100644 --- a/cmd/mist/assets/qml/views/transaction.qml +++ b/cmd/mist/assets/qml/views/transaction.qml @@ -103,7 +103,7 @@ Rectangle { ComboBox { id: valueDenom - currentIndex: 6 + currentIndex: 5 model: denomModel } } @@ -177,7 +177,7 @@ Rectangle { mainContractColumn.state = "ERROR" } else { txResult.text = "Your transaction has been submitted:\n" - txOutput.text = res[0].address + txOutput.text = res.toString() mainContractColumn.state = "DONE" console.log(res) diff --git a/cmd/mist/assets/qml/views/wallet.qml b/cmd/mist/assets/qml/views/wallet.qml index 545098284..2369390c3 100644 --- a/cmd/mist/assets/qml/views/wallet.qml +++ b/cmd/mist/assets/qml/views/wallet.qml @@ -9,12 +9,20 @@ import Ethereum 1.0 Rectangle { id: root property var title: "Wallet" - property var iconSource: "../facet.png" property var menuItem objectName: "walletView" anchors.fill: parent + Label { + objectName: "balanceLabel" + visible: false + onTextChanged: { + balance.text = text + menuItem.secondaryTitle = text + } + } + function onReady() { setBalance() } @@ -95,7 +103,7 @@ Rectangle { ComboBox { id: valueDenom - currentIndex: 6 + currentIndex: 5 model: denomModel } diff --git a/cmd/mist/bindings.go b/cmd/mist/bindings.go index 706c789b1..9623538a3 100644 --- a/cmd/mist/bindings.go +++ b/cmd/mist/bindings.go @@ -64,15 +64,6 @@ func (gui *Gui) Transact(recipient, value, gas, gasPrice, d string) (string, err return gui.xeth.Transact(recipient, value, gas, gasPrice, data) } -func (gui *Gui) SetCustomIdentifier(customIdentifier string) { - gui.clientIdentity.SetCustomIdentifier(customIdentifier) - gui.config.Save("id", customIdentifier) -} - -func (gui *Gui) GetCustomIdentifier() string { - return gui.clientIdentity.GetCustomIdentifier() -} - // functions that allow Gui to implement interface guilogger.LogSystem func (gui *Gui) SetLogLevel(level logger.LogLevel) { gui.logLevel = level diff --git a/cmd/mist/ext_app.go b/cmd/mist/ext_app.go index 20ec52e60..7ac51db0b 100644 --- a/cmd/mist/ext_app.go +++ b/cmd/mist/ext_app.go @@ -24,7 +24,6 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/ui/qt" "github.com/ethereum/go-ethereum/xeth" "github.com/obscuren/qml" @@ -39,13 +38,12 @@ type AppContainer interface { NewBlock(*types.Block) NewWatcher(chan bool) - Messages(state.Messages, string) Post(string, int) } type ExtApplication struct { *xeth.XEth - eth core.EthManager + eth core.Backend events event.Subscription watcherQuitChan chan bool @@ -79,10 +77,6 @@ func (app *ExtApplication) run() { return } - // Subscribe to events - mux := app.lib.eth.EventMux() - app.events = mux.Subscribe(core.NewBlockEvent{}, state.Messages(nil)) - // Call the main loop go app.mainLoop() @@ -126,23 +120,3 @@ func (app *ExtApplication) mainLoop() { func (self *ExtApplication) Watch(filterOptions map[string]interface{}, identifier string) { self.filters[identifier] = qt.NewFilterFromMap(filterOptions, self.eth) } - -func (self *ExtApplication) GetMessages(object map[string]interface{}) string { - /* TODO remove me - filter := qt.NewFilterFromMap(object, self.eth) - - messages := filter.Find() - var msgs []javascript.JSMessage - for _, m := range messages { - msgs = append(msgs, javascript.NewJSMessage(m)) - } - - b, err := json.Marshal(msgs) - if err != nil { - return "{\"error\":" + err.Error() + "}" - } - - return string(b) - */ - return "" -} diff --git a/cmd/mist/flags.go b/cmd/mist/flags.go index f042b39b0..d9487de9e 100644 --- a/cmd/mist/flags.go +++ b/cmd/mist/flags.go @@ -21,6 +21,7 @@ package main import ( + "crypto/ecdsa" "flag" "fmt" "log" @@ -31,7 +32,9 @@ import ( "runtime" "bitbucket.org/kardianos/osext" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/vm" ) @@ -39,19 +42,18 @@ var ( Identifier string KeyRing string KeyStore string - PMPGateway string StartRpc bool StartWebSockets bool RpcPort int WsPort int - UseUPnP bool - NatType string OutboundPort string ShowGenesis bool AddPeer string MaxPeer int GenAddr bool - SeedNode string + BootNodes string + NodeKey *ecdsa.PrivateKey + NAT nat.Interface SecretFile string ExportDir string NonInteractive bool @@ -61,6 +63,7 @@ var ( DebugFile string LogLevel int VmType int + MinerThreads int ) // flags specific to gui client @@ -99,6 +102,7 @@ func defaultDataDir() string { var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini") func Init() { + // TODO: move common flag processing to cmd/utils flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line\n", os.Args[0]) flag.PrintDefaults() @@ -108,30 +112,53 @@ func Init() { flag.StringVar(&Identifier, "id", "", "Custom client identifier") flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use") flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") - flag.StringVar(&OutboundPort, "port", "30303", "listening port") - flag.BoolVar(&UseUPnP, "upnp", true, "enable UPnP support") - flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers") 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.BoolVar(&StartRpc, "rpc", true, "start rpc server") flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server") flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)") - flag.StringVar(&SeedNode, "seednode", "poc-8.ethdev.com:30303", "ip:port of seed node to connect to. Set to blank for skip") flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") - flag.StringVar(&NatType, "nat", "", "NAT support (UPNP|PMP) (none)") 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(&PMPGateway, "pmp", "", "Gateway IP for PMP") 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") + // Network stuff + var ( + nodeKeyFile = flag.String("nodekey", "", "network private key file") + nodeKeyHex = flag.String("nodekeyhex", "", "network private key (for testing)") + natstr = flag.String("nat", "any", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)") + ) + flag.StringVar(&OutboundPort, "port", "30303", "listening port") + flag.StringVar(&BootNodes, "bootnodes", "", "space-separated node URLs for discovery bootstrap") + flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers") + + flag.IntVar(&MinerThreads, "minerthreads", runtime.NumCPU(), "number of miner threads") + flag.Parse() + var err error + if NAT, err = nat.Parse(*natstr); err != nil { + log.Fatalf("-nat: %v", err) + } + switch { + case *nodeKeyFile != "" && *nodeKeyHex != "": + log.Fatal("Options -nodekey and -nodekeyhex are mutually exclusive") + case *nodeKeyFile != "": + if NodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil { + log.Fatalf("-nodekey: %v", err) + } + case *nodeKeyHex != "": + if NodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil { + log.Fatalf("-nodekeyhex: %v", err) + } + } + if VmType >= int(vm.MaxVmTy) { log.Fatal("Invalid VM type ", VmType) } diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index edc799abc..4af0cff43 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -31,6 +31,7 @@ import ( "os" "path" "runtime" + "sort" "strconv" "time" @@ -40,8 +41,6 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/miner" - "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/ui/qt/qwhisper" "github.com/ethereum/go-ethereum/xeth" "github.com/obscuren/qml" @@ -77,17 +76,14 @@ type Gui struct { xeth *xeth.XEth - Session string - clientIdentity *p2p.SimpleClientIdentity - config *ethutil.ConfigManager + Session string + config *ethutil.ConfigManager plugins map[string]plugin - - miner *miner.Miner } // Create GUI, but doesn't start it -func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIdentity *p2p.SimpleClientIdentity, session string, logLevel int) *Gui { +func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, session string, logLevel int) *Gui { db, err := ethdb.NewLDBDatabase("tx_database") if err != nil { panic(err) @@ -95,15 +91,14 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIden xeth := xeth.New(ethereum) gui := &Gui{eth: ethereum, - txDb: db, - xeth: xeth, - logLevel: logger.LogLevel(logLevel), - Session: session, - open: false, - clientIdentity: clientIdentity, - config: config, - plugins: make(map[string]plugin), - serviceEvents: make(chan ServEv, 1), + txDb: db, + xeth: xeth, + logLevel: logger.LogLevel(logLevel), + Session: session, + open: false, + config: config, + plugins: make(map[string]plugin), + serviceEvents: make(chan ServEv, 1), } data, _ := ethutil.ReadAllFile(path.Join(ethutil.Config.ExecPath, "plugins.json")) json.Unmarshal([]byte(data), &gui.plugins) @@ -136,6 +131,7 @@ func (gui *Gui) Start(assetPath string) { context.SetVar("gui", gui) context.SetVar("eth", gui.uiLib) context.SetVar("shh", gui.whisper) + //clipboard.SetQMLClipboard(context) win, err := gui.showWallet(context) if err != nil { @@ -391,16 +387,11 @@ func (gui *Gui) update() { generalUpdateTicker := time.NewTicker(500 * time.Millisecond) statsUpdateTicker := time.NewTicker(5 * time.Second) - state := gui.eth.ChainManager().TransState() - - gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Balance()))) - lastBlockLabel := gui.getObjectByName("lastBlockLabel") miningLabel := gui.getObjectByName("miningLabel") events := gui.eth.EventMux().Subscribe( - //eth.PeerListEvent{}, - core.NewBlockEvent{}, + core.ChainEvent{}, core.TxPreEvent{}, core.TxPostEvent{}, ) @@ -413,62 +404,22 @@ func (gui *Gui) update() { return } switch ev := ev.(type) { - case core.NewBlockEvent: + case core.ChainEvent: gui.processBlock(ev.Block, false) - if bytes.Compare(ev.Block.Coinbase(), gui.address()) == 0 { - gui.setWalletValue(gui.eth.ChainManager().State().GetBalance(gui.address()), nil) - } - case core.TxPreEvent: - tx := ev.Tx - - tstate := gui.eth.ChainManager().TransState() - cstate := gui.eth.ChainManager().State() - - taccount := tstate.GetAccount(gui.address()) - caccount := cstate.GetAccount(gui.address()) - unconfirmedFunds := new(big.Int).Sub(taccount.Balance(), caccount.Balance()) - - gui.setWalletValue(taccount.Balance(), unconfirmedFunds) - gui.insertTransaction("pre", tx) + gui.insertTransaction("pre", ev.Tx) case core.TxPostEvent: - tx := ev.Tx - object := state.GetAccount(gui.address()) - - if bytes.Compare(tx.From(), gui.address()) == 0 { - object.SubAmount(tx.Value()) - - gui.txDb.Put(tx.Hash(), tx.RlpEncode()) - } else if bytes.Compare(tx.To(), gui.address()) == 0 { - object.AddAmount(tx.Value()) - - gui.txDb.Put(tx.Hash(), tx.RlpEncode()) - } - - gui.setWalletValue(object.Balance(), nil) - state.UpdateStateObject(object) + gui.getObjectByName("pendingTxView").Call("removeTx", xeth.NewTx(ev.Tx)) } case <-peerUpdateTicker.C: gui.setPeerInfo() + case <-generalUpdateTicker.C: statusText := "#" + gui.eth.ChainManager().CurrentBlock().Number().String() lastBlockLabel.Set("text", statusText) - miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.GetPow().GetHashrate(), 10)+"Khash") - - /* - blockLength := gui.eth.BlockPool().BlocksProcessed - chainLength := gui.eth.BlockPool().ChainLength - - var ( - pct float64 = 1.0 / float64(chainLength) * float64(blockLength) - dlWidget = gui.win.Root().ObjectByName("downloadIndicator") - dlLabel = gui.win.Root().ObjectByName("downloadLabel") - ) - dlWidget.Set("value", pct) - dlLabel.Set("text", fmt.Sprintf("%d / %d", blockLength, chainLength)) - */ + miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.Miner().HashRate(), 10)+"/Khash") case <-statsUpdateTicker.C: gui.setStatsPane() @@ -502,12 +453,35 @@ NumGC: %d )) } +type qmlpeer struct{ Addr, NodeID, Name, Caps string } + +type peersByID []*qmlpeer + +func (s peersByID) Len() int { return len(s) } +func (s peersByID) Less(i, j int) bool { return s[i].NodeID < s[j].NodeID } +func (s peersByID) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + func (gui *Gui) setPeerInfo() { - gui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", gui.eth.PeerCount(), gui.eth.MaxPeers)) - gui.win.Root().Call("resetPeers") - //for _, peer := range gui.xeth.Peers() { - //gui.win.Root().Call("addPeer", peer) - //} + peers := gui.eth.Peers() + qpeers := make(peersByID, len(peers)) + for i, p := range peers { + qpeers[i] = &qmlpeer{ + NodeID: p.ID().String(), + Addr: p.RemoteAddr().String(), + Name: p.Name(), + Caps: fmt.Sprint(p.Caps()), + } + } + // we need to sort the peers because they jump around randomly + // otherwise. order returned by eth.Peers is random because they + // are taken from a map. + sort.Sort(qpeers) + + gui.win.Root().Call("setPeerCounters", fmt.Sprintf("%d / %d", len(peers), gui.eth.MaxPeers())) + gui.win.Root().Call("clearPeers") + for _, p := range qpeers { + gui.win.Root().Call("addPeer", p) + } } func (gui *Gui) privateKey() string { diff --git a/cmd/mist/html_container.go b/cmd/mist/html_container.go index 0909a6abd..e4ea57b9b 100644 --- a/cmd/mist/html_container.go +++ b/cmd/mist/html_container.go @@ -31,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/xeth" "github.com/howeyc/fsnotify" "github.com/obscuren/qml" @@ -144,19 +143,6 @@ func (app *HtmlApplication) NewBlock(block *types.Block) { app.webView.Call("onNewBlockCb", b) } -func (self *HtmlApplication) Messages(messages state.Messages, id string) { - /* TODO remove me - var msgs []javascript.JSMessage - for _, m := range messages { - msgs = append(msgs, javascript.NewJSMessage(m)) - } - - b, _ := json.Marshal(msgs) - - self.webView.Call("onWatchedCb", string(b), id) - */ -} - func (app *HtmlApplication) Destroy() { app.engine.Destroy() } diff --git a/cmd/mist/main.go b/cmd/mist/main.go index 66872a241..ad6eb5bec 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -36,7 +36,7 @@ import ( const ( ClientIdentifier = "Mist" - Version = "0.8.2" + Version = "0.8.5" ) var ethereum *eth.Ethereum @@ -52,19 +52,20 @@ func run() error { config := utils.InitConfig(VmType, ConfigFile, Datadir, "ETH") ethereum, err := eth.New(ð.Config{ - Name: ClientIdentifier, - Version: Version, - KeyStore: KeyStore, - DataDir: Datadir, - LogFile: LogFile, - LogLevel: LogLevel, - Identifier: Identifier, - MaxPeers: MaxPeer, - Port: OutboundPort, - NATType: PMPGateway, - PMPGateway: PMPGateway, - KeyRing: KeyRing, - Dial: true, + Name: p2p.MakeName(ClientIdentifier, Version), + KeyStore: KeyStore, + DataDir: Datadir, + LogFile: LogFile, + LogLevel: LogLevel, + MaxPeers: MaxPeer, + Port: OutboundPort, + NAT: NAT, + Shh: true, + BootNodes: BootNodes, + NodeKey: NodeKey, + KeyRing: KeyRing, + Dial: true, + MinerThreads: MinerThreads, }) if err != nil { mainlogger.Fatalln(err) @@ -79,12 +80,12 @@ func run() error { utils.StartWebSockets(ethereum, WsPort) } - gui := NewWindow(ethereum, config, ethereum.ClientIdentity().(*p2p.SimpleClientIdentity), KeyRing, LogLevel) + gui := NewWindow(ethereum, config, KeyRing, LogLevel) utils.RegisterInterrupt(func(os.Signal) { gui.Stop() }) - go utils.StartEthereum(ethereum, SeedNode) + go utils.StartEthereum(ethereum) fmt.Println("ETH stack took", time.Since(tstart)) diff --git a/cmd/mist/qml_container.go b/cmd/mist/qml_container.go index 9d76d8fe4..16a055bc0 100644 --- a/cmd/mist/qml_container.go +++ b/cmd/mist/qml_container.go @@ -22,12 +22,10 @@ package main import ( - "fmt" "runtime" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/xeth" "github.com/obscuren/qml" ) @@ -74,10 +72,6 @@ func (app *QmlApplication) NewBlock(block *types.Block) { app.win.Call("onNewBlockCb", pblock) } -func (self *QmlApplication) Messages(msgs state.Messages, id string) { - fmt.Println("IMPLEMENT QML APPLICATION MESSAGES METHOD") -} - // Getters func (app *QmlApplication) Engine() *qml.Engine { return app.engine diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index 7c5802076..4fa6e8e55 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -30,7 +30,6 @@ import ( "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/event/filter" "github.com/ethereum/go-ethereum/javascript" - "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/xeth" "github.com/obscuren/qml" ) @@ -56,13 +55,10 @@ type UiLib struct { filterCallbacks map[int][]int filterManager *filter.FilterManager - - miner *miner.Miner } func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib { lib := &UiLib{XEth: xeth.New(eth), engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(eth), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*xeth.JSFilter)} - lib.miner = miner.New(eth.KeyManager().Address(), eth) lib.filterManager = filter.NewFilterManager(eth.EventMux()) go lib.filterManager.Start() @@ -73,11 +69,6 @@ func (self *UiLib) Notef(args []interface{}) { guilogger.Infoln(args...) } -func (self *UiLib) PastPeers() *ethutil.List { - return ethutil.NewList([]string{}) - //return ethutil.NewList(eth.PastPeers()) -} - func (self *UiLib) ImportTx(rlpTx string) { tx := types.NewTransactionFromBytes(ethutil.Hex2Bytes(rlpTx)) err := self.eth.TxPool().Add(tx) @@ -136,15 +127,15 @@ func (ui *UiLib) Muted(content string) { func (ui *UiLib) Connect(button qml.Object) { if !ui.connected { - ui.eth.Start(SeedNode) + ui.eth.Start() ui.connected = true button.Set("enabled", false) } } -func (ui *UiLib) ConnectToPeer(addr string) { - if err := ui.eth.SuggestPeer(addr); err != nil { - guilogger.Infoln(err) +func (ui *UiLib) ConnectToPeer(nodeURL string) { + if err := ui.eth.SuggestPeer(nodeURL); err != nil { + guilogger.Infoln("SuggestPeer error: " + err.Error()) } } @@ -155,8 +146,8 @@ func (ui *UiLib) AssetPath(p string) string { func (self *UiLib) StartDbWithContractAndData(contractHash, data string) { dbWindow := NewDebuggerWindow(self) object := self.eth.ChainManager().State().GetStateObject(ethutil.Hex2Bytes(contractHash)) - if len(object.Code) > 0 { - dbWindow.SetCode(ethutil.Bytes2Hex(object.Code)) + if len(object.Code()) > 0 { + dbWindow.SetCode(ethutil.Bytes2Hex(object.Code())) } dbWindow.SetData(data) @@ -209,34 +200,37 @@ func (self *UiLib) Call(params map[string]interface{}) (string, error) { } func (self *UiLib) AddLocalTransaction(to, data, gas, gasPrice, value string) int { - return self.miner.AddLocalTx(&miner.LocalTx{ - To: ethutil.Hex2Bytes(to), - Data: ethutil.Hex2Bytes(data), - Gas: gas, - GasPrice: gasPrice, - Value: value, - }) - 1 + return 0 + /* + return self.miner.AddLocalTx(&miner.LocalTx{ + To: ethutil.Hex2Bytes(to), + Data: ethutil.Hex2Bytes(data), + Gas: gas, + GasPrice: gasPrice, + Value: value, + }) - 1 + */ } func (self *UiLib) RemoveLocalTransaction(id int) { - self.miner.RemoveLocalTx(id) + //self.miner.RemoveLocalTx(id) } func (self *UiLib) SetGasPrice(price string) { - self.miner.MinAcceptedGasPrice = ethutil.Big(price) + self.Miner().MinAcceptedGasPrice = ethutil.Big(price) } func (self *UiLib) SetExtra(extra string) { - self.miner.Extra = extra + self.Miner().Extra = extra } func (self *UiLib) ToggleMining() bool { - if !self.miner.Mining() { - self.miner.Start() + if !self.Miner().Mining() { + self.Miner().Start() return true } else { - self.miner.Stop() + self.Miner().Stop() return false } diff --git a/cmd/peerserver/main.go b/cmd/peerserver/main.go deleted file mode 100644 index 341c4dbb9..000000000 --- a/cmd/peerserver/main.go +++ /dev/null @@ -1,58 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. -*/ -package main - -import ( - "crypto/elliptic" - "flag" - "log" - "os" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/p2p" -) - -var ( - natType = flag.String("nat", "", "NAT traversal implementation") - pmpGateway = flag.String("gateway", "", "gateway address for NAT-PMP") - listenAddr = flag.String("addr", ":30301", "listen address") -) - -func main() { - flag.Parse() - nat, err := p2p.ParseNAT(*natType, *pmpGateway) - if err != nil { - log.Fatal("invalid nat:", err) - } - - logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.InfoLevel)) - key, _ := crypto.GenerateKey() - marshaled := elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y) - - srv := p2p.Server{ - MaxPeers: 100, - Identity: p2p.NewSimpleClientIdentity("Ethereum(G)", "0.1", "Peer Server Two", marshaled), - ListenAddr: *listenAddr, - NAT: nat, - NoDial: true, - } - if err := srv.Start(); err != nil { - log.Fatal("could not start server:", err) - } - select {} -} diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 70df289c3..bc8fafafb 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -121,13 +121,11 @@ func exit(err error) { os.Exit(status) } -func StartEthereum(ethereum *eth.Ethereum, SeedNode string) { - clilogger.Infof("Starting %s", ethereum.ClientIdentity()) - err := ethereum.Start(SeedNode) - if err != nil { +func StartEthereum(ethereum *eth.Ethereum) { + clilogger.Infoln("Starting ", ethereum.Name()) + if err := ethereum.Start(); err != nil { exit(err) } - RegisterInterrupt(func(sig os.Signal) { ethereum.Stop() logger.Flush() @@ -227,7 +225,7 @@ func StartMining(ethereum *eth.Ethereum) bool { go func() { clilogger.Infoln("Start mining") if gminer == nil { - gminer = miner.New(addr, ethereum) + gminer = miner.New(addr, ethereum, 4) } gminer.Start() }() @@ -274,7 +272,7 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error { parent := ethereum.ChainManager().GetBlock(block.ParentHash()) statedb := state.New(parent.Root(), ethereum.Db()) - _, err := ethereum.BlockProcessor().TransitionState(statedb, parent, block) + _, err := ethereum.BlockProcessor().TransitionState(statedb, parent, block, true) if err != nil { return err } |