// Simple go routine function that updates the list of peers in the GUI func (ui *Gui) update() { txChan := make(chan ethchain.TxMsg, 1) ui.eth.TxPool().Subscribe(txChan) account := ui.eth.StateManager().GetAddrState(ui.addr).Account unconfirmedFunds := new(big.Int) ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(account.Amount))) for { select { case txMsg := <-txChan: tx := txMsg.Tx if txMsg.Type == ethchain.TxPre { if bytes.Compare(tx.Sender(), ui.addr) == 0 { ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) ui.txDb.Put(tx.Hash(), tx.RlpEncode()) ui.eth.StateManager().GetAddrState(ui.addr).Nonce += 1 unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) ui.txDb.Put(tx.Hash(), tx.RlpEncode()) unconfirmedFunds.Add(unconfirmedFunds, tx.Value) } pos := "+" if unconfirmedFunds.Cmp(big.NewInt(0)) >= 0 { pos = "-" } val := ethutil.CurrencyToString(new(big.Int).Abs(ethutil.BigCopy(unconfirmedFunds))) str := fmt.Sprintf("%v (%s %v)", ethutil.CurrencyToString(account.Amount), pos, val) ui.win.Root().Call("setWalletValue", str) } else { amount := account.Amount if bytes.Compare(tx.Sender(), ui.addr) == 0 { amount.Sub(account.Amount, tx.Value) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { amount.Add(account.Amount, tx.Value) } ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) } } /* accountAmount := ui.eth.BlockManager.GetAddrState(ui.addr).Account.Amount ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", accountAmount)) ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) time.Sleep(1 * time.Second) */ } }
func (gui *Gui) setWalletValue(amount, unconfirmedFunds *big.Int) { var str string if unconfirmedFunds != nil { pos := "+" if unconfirmedFunds.Cmp(big.NewInt(0)) < 0 { pos = "-" } val := ethutil.CurrencyToString(new(big.Int).Abs(ethutil.BigCopy(unconfirmedFunds))) str = fmt.Sprintf("%v (%s %v)", ethutil.CurrencyToString(amount), pos, val) } else { str = fmt.Sprintf("%v", ethutil.CurrencyToString(amount)) } gui.win.Root().Call("setWalletValue", str) }
func NewJSTx(tx *ethchain.Transaction) *JSTransaction { hash := ethutil.Bytes2Hex(tx.Hash()) receiver := ethutil.Bytes2Hex(tx.Recipient) if receiver == "0000000000000000000000000000000000000000" { receiver = ethutil.Bytes2Hex(tx.CreationAddress()) } sender := ethutil.Bytes2Hex(tx.Sender()) createsContract := tx.CreatesContract() var data string if tx.CreatesContract() { data = strings.Join(ethchain.Disassemble(tx.Data), "\n") } else { data = ethutil.Bytes2Hex(tx.Data) } return &JSTransaction{ref: tx, Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: receiver, Contract: tx.CreatesContract(), Gas: tx.Gas.String(), GasPrice: tx.GasPrice.String(), Data: data, Sender: sender, CreatesContract: createsContract, RawData: ethutil.Bytes2Hex(tx.Data)} }
func (self *JSPipe) NumberToHuman(balance string) string { b := ethutil.Big(balance) return ethutil.CurrencyToString(b) }
func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, dataStr string) { if !self.Db.done { self.Db.Q <- true } defer func() { if r := recover(); r != nil { self.Logf("compile FAULT: %v", r) } }() data := ethutil.StringToByteFunc(dataStr, func(s string) (ret []byte) { slice := strings.Split(dataStr, "\n") for _, dataItem := range slice { d := ethutil.FormatData(dataItem) ret = append(ret, d...) } return }) var err error script := ethutil.StringToByteFunc(scriptStr, func(s string) (ret []byte) { ret, err = ethutil.Compile(s, false) return }) if err != nil { self.Logln(err) return } var ( gas = ethutil.Big(gasStr) gasPrice = ethutil.Big(gasPriceStr) value = ethutil.Big(valueStr) // Contract addr as test address keyPair = self.lib.eth.KeyManager().KeyPair() ) state := self.lib.eth.StateManager().TransState() account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address()) contract := ethchain.NewStateObject([]byte{0}) contract.Amount = value callerClosure := ethchain.NewClosure(account, contract, script, state, gas, gasPrice) block := self.lib.eth.BlockChain().CurrentBlock vm := ethchain.NewVm(state, self.lib.eth.StateManager(), ethchain.RuntimeVars{ Block: block, Origin: account.Address(), BlockNumber: block.Number, PrevHash: block.PrevHash, Coinbase: block.Coinbase, Time: block.Time, Diff: block.Difficulty, Value: ethutil.Big(valueStr), }) vm.Verbose = true vm.Dbg = self.Db self.vm = vm self.Db.done = false self.Logf("callsize %d", len(script)) go func() { ret, g, err := callerClosure.Call(vm, data) tot := new(big.Int).Mul(g, gasPrice) self.Logf("gas usage %v total price = %v (%v)", g, tot, ethutil.CurrencyToString(tot)) if err != nil { self.Logln("exited with errors:", err) } else { if len(ret) > 0 { self.Logf("exited: % x", ret) } else { self.Logf("exited: nil") } } state.Reset() if !self.Db.interrupt { self.Db.done = true } else { self.Db.interrupt = false } }() }
// Simple go routine function that updates the list of peers in the GUI func (gui *Gui) update() { reactor := gui.eth.Reactor() var ( blockChan = make(chan ethutil.React, 1) txChan = make(chan ethutil.React, 1) objectChan = make(chan ethutil.React, 1) peerChan = make(chan ethutil.React, 1) chainSyncChan = make(chan ethutil.React, 1) miningChan = make(chan ethutil.React, 1) ) reactor.Subscribe("newBlock", blockChan) reactor.Subscribe("newTx:pre", txChan) reactor.Subscribe("newTx:post", txChan) reactor.Subscribe("chainSync", chainSyncChan) reactor.Subscribe("miner:start", miningChan) reactor.Subscribe("miner:stop", miningChan) nameReg := ethpub.EthereumConfig(gui.eth.StateManager()).NameReg() if nameReg != nil { reactor.Subscribe("object:"+string(nameReg.Address()), objectChan) } reactor.Subscribe("peerList", peerChan) peerUpdateTicker := time.NewTicker(5 * time.Second) generalUpdateTicker := time.NewTicker(1 * time.Second) state := gui.eth.StateManager().TransState() unconfirmedFunds := new(big.Int) gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Amount))) gui.getObjectByName("syncProgressIndicator").Set("visible", !gui.eth.IsUpToDate()) lastBlockLabel := gui.getObjectByName("lastBlockLabel") for { select { case b := <-blockChan: block := b.Resource.(*ethchain.Block) gui.processBlock(block, false) if bytes.Compare(block.Coinbase, gui.address()) == 0 { gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Amount, nil) } case txMsg := <-txChan: tx := txMsg.Resource.(*ethchain.Transaction) if txMsg.Event == "newTx:pre" { object := state.GetAccount(gui.address()) if bytes.Compare(tx.Sender(), gui.address()) == 0 { gui.win.Root().Call("addTx", ethpub.NewPTx(tx), "send") gui.txDb.Put(tx.Hash(), tx.RlpEncode()) unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { gui.win.Root().Call("addTx", ethpub.NewPTx(tx), "recv") gui.txDb.Put(tx.Hash(), tx.RlpEncode()) unconfirmedFunds.Add(unconfirmedFunds, tx.Value) } gui.setWalletValue(object.Amount, unconfirmedFunds) } else { object := state.GetAccount(gui.address()) if bytes.Compare(tx.Sender(), gui.address()) == 0 { object.SubAmount(tx.Value) } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { object.AddAmount(tx.Value) } gui.setWalletValue(object.Amount, nil) state.UpdateStateObject(object) } case msg := <-chainSyncChan: sync := msg.Resource.(bool) gui.win.Root().ObjectByName("syncProgressIndicator").Set("visible", sync) case <-objectChan: gui.loadAddressBook() case <-peerChan: gui.setPeerInfo() case <-peerUpdateTicker.C: gui.setPeerInfo() case msg := <-miningChan: if msg.Event == "miner:start" { gui.miner = msg.Resource.(*ethminer.Miner) } else { gui.miner = nil } case <-generalUpdateTicker.C: statusText := "#" + gui.eth.BlockChain().CurrentBlock.Number.String() if gui.miner != nil { pow := gui.miner.GetPow() if pow.GetHashrate() != 0 { statusText = "Mining @ " + strconv.FormatInt(pow.GetHashrate(), 10) + "Khash - " + statusText } } lastBlockLabel.Set("text", statusText) } } }
func NewTxFromTransaction(tx *ethchain.Transaction) *Tx { hash := hex.EncodeToString(tx.Hash()) sender := hex.EncodeToString(tx.Recipient) return &Tx{Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender} }
func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, dataStr string) { if !self.Db.done { self.Db.Q <- true } defer func() { if r := recover(); r != nil { self.Logf("compile FAULT: %v", r) } }() data := utils.FormatTransactionData(dataStr) var err error script := ethutil.StringToByteFunc(scriptStr, func(s string) (ret []byte) { ret, err = ethutil.Compile(s, false) return }) if err != nil { self.Logln(err) return } var ( gas = ethutil.Big(gasStr) gasPrice = ethutil.Big(gasPriceStr) value = ethutil.Big(valueStr) // Contract addr as test address keyPair = self.lib.eth.KeyManager().KeyPair() ) state := self.lib.eth.StateManager().TransState() account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address()) contract := ethstate.NewStateObject([]byte{0}) contract.Balance = value self.SetAsm(script) block := self.lib.eth.BlockChain().CurrentBlock callerClosure := ethvm.NewClosure(ðstate.Message{}, account, contract, script, gas, gasPrice) env := utils.NewEnv(state, block, account.Address(), value) vm := ethvm.New(env) vm.Verbose = true vm.Dbg = self.Db self.vm = vm self.Db.done = false self.Logf("callsize %d", len(script)) go func() { ret, g, err := callerClosure.Call(vm, data) tot := new(big.Int).Mul(g, gasPrice) self.Logf("gas usage %v total price = %v (%v)", g, tot, ethutil.CurrencyToString(tot)) if err != nil { self.Logln("exited with errors:", err) } else { if len(ret) > 0 { self.Logf("exited: % x", ret) } else { self.Logf("exited: nil") } } state.Reset() if !self.Db.interrupt { self.Db.done = true } else { self.Db.interrupt = false } }() }
// Simple go routine function that updates the list of peers in the GUI func (gui *Gui) update() { // We have to wait for qml to be done loading all the windows. for !gui.qmlDone { time.Sleep(500 * time.Millisecond) } go func() { go gui.setInitialBlockChain() gui.loadAddressBook() gui.setPeerInfo() gui.readPreviousTransactions() }() for _, plugin := range gui.plugins { gui.win.Root().Call("addPlugin", plugin.Path, "") } var ( blockChan = make(chan ethreact.Event, 100) txChan = make(chan ethreact.Event, 100) objectChan = make(chan ethreact.Event, 100) peerChan = make(chan ethreact.Event, 100) chainSyncChan = make(chan ethreact.Event, 100) miningChan = make(chan ethreact.Event, 100) ) peerUpdateTicker := time.NewTicker(5 * time.Second) generalUpdateTicker := time.NewTicker(1 * time.Second) state := gui.eth.StateManager().TransState() unconfirmedFunds := new(big.Int) gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Balance))) gui.getObjectByName("syncProgressIndicator").Set("visible", !gui.eth.IsUpToDate()) lastBlockLabel := gui.getObjectByName("lastBlockLabel") miningLabel := gui.getObjectByName("miningLabel") go func() { for { select { case b := <-blockChan: block := b.Resource.(*ethchain.Block) gui.processBlock(block, false) if bytes.Compare(block.Coinbase, gui.address()) == 0 { gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Balance, nil) } case txMsg := <-txChan: tx := txMsg.Resource.(*ethchain.Transaction) if txMsg.Name == "newTx:pre" { object := state.GetAccount(gui.address()) if bytes.Compare(tx.Sender(), gui.address()) == 0 { unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { unconfirmedFunds.Add(unconfirmedFunds, tx.Value) } gui.setWalletValue(object.Balance, unconfirmedFunds) gui.insertTransaction("pre", tx) } else { object := state.GetAccount(gui.address()) if bytes.Compare(tx.Sender(), gui.address()) == 0 { object.SubAmount(tx.Value) gui.getObjectByName("transactionView").Call("addTx", ethpipe.NewJSTx(tx), "send") gui.txDb.Put(tx.Hash(), tx.RlpEncode()) } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { object.AddAmount(tx.Value) gui.getObjectByName("transactionView").Call("addTx", ethpipe.NewJSTx(tx), "recv") gui.txDb.Put(tx.Hash(), tx.RlpEncode()) } gui.setWalletValue(object.Balance, nil) state.UpdateStateObject(object) } case msg := <-chainSyncChan: sync := msg.Resource.(bool) gui.win.Root().ObjectByName("syncProgressIndicator").Set("visible", sync) case <-objectChan: gui.loadAddressBook() case <-peerChan: gui.setPeerInfo() case <-peerUpdateTicker.C: gui.setPeerInfo() case msg := <-miningChan: if msg.Name == "miner:start" { gui.miner = msg.Resource.(*ethminer.Miner) } else { gui.miner = nil } case <-generalUpdateTicker.C: statusText := "#" + gui.eth.BlockChain().CurrentBlock.Number.String() lastBlockLabel.Set("text", statusText) if gui.miner != nil { pow := gui.miner.GetPow() miningLabel.Set("text", "Mining @ "+strconv.FormatInt(pow.GetHashrate(), 10)+"Khash") } } } }() reactor := gui.eth.Reactor() reactor.Subscribe("newBlock", blockChan) reactor.Subscribe("newTx:pre", txChan) reactor.Subscribe("newTx:post", txChan) reactor.Subscribe("chainSync", chainSyncChan) reactor.Subscribe("miner:start", miningChan) reactor.Subscribe("miner:stop", miningChan) nameReg := gui.pipe.World().Config().Get("NameReg") reactor.Subscribe("object:"+string(nameReg.Address()), objectChan) reactor.Subscribe("peerList", peerChan) }