From 05c353eca0c4e01457412dd643529200816ab159 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 21 Feb 2014 12:37:40 +0100 Subject: Added a basic UI --- ui/gui.go | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 ui/gui.go (limited to 'ui') diff --git a/ui/gui.go b/ui/gui.go new file mode 100644 index 000000000..b2a8dad73 --- /dev/null +++ b/ui/gui.go @@ -0,0 +1,83 @@ +package ethui + +import ( + "bufio" + "encoding/hex" + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "github.com/niemeyer/qml" + "strings" +) + +type Gui struct { + win *qml.Window + engine *qml.Engine + component *qml.Common + eth *eth.Ethereum +} + +func New(ethereum *eth.Ethereum) *Gui { + return &Gui{eth: ethereum} +} + +type Block struct { + Number int + Hash string +} + +func NewBlockFromBlock(block *ethchain.Block) *Block { + info := block.BlockInfo() + hash := hex.EncodeToString(block.Hash()) + + return &Block{Number: int(info.Number), Hash: hash} +} + +func (ui *Gui) Start() { + qml.RegisterTypes("GoExtensions", 1, 0, []qml.TypeSpec{{ + Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, + }}) + + ethutil.Config.Log.Infoln("[GUI] Starting GUI") + ui.engine = qml.NewEngine() + component, err := ui.engine.LoadFile("wallet.qml") + if err != nil { + panic(err) + } + + ui.win = component.CreateWindow(nil) + root := ui.win.Root() + + context := ui.engine.Context() + context.SetVar("tester", &Tester{root: root}) + + ui.eth.BlockManager.SecondaryBlockProcessor = ui + ui.eth.Start() + + ui.win.Show() + ui.win.Wait() +} + +func (ui *Gui) ProcessBlock(block *ethchain.Block) { + ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) +} + +type Tester struct { + root qml.Object +} + +func (t *Tester) Compile(area qml.Object) { + fmt.Println(area) + ethutil.Config.Log.Infoln("[TESTER] Compiling") + + code := area.String("text") + + scanner := bufio.NewScanner(strings.NewReader(code)) + scanner.Split(bufio.ScanLines) + + var lines []string + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } +} -- cgit v1.2.3 From aaac0c9998ee78d796c1dbab118f721f886ce426 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 21 Feb 2014 13:06:17 +0100 Subject: Initial block chain fetching of existing blocks --- ui/gui.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/gui.go b/ui/gui.go index b2a8dad73..aae1320fc 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -53,12 +53,22 @@ func (ui *Gui) Start() { context.SetVar("tester", &Tester{root: root}) ui.eth.BlockManager.SecondaryBlockProcessor = ui - ui.eth.Start() + + go ui.setInitialBlockChain() ui.win.Show() ui.win.Wait() } +func (ui *Gui) setInitialBlockChain() { + chain := ui.eth.BlockManager.BlockChain().GetChain(ui.eth.BlockManager.BlockChain().CurrentBlock.Hash(), 10) + for _, block := range chain { + ui.ProcessBlock(block) + } + + ui.eth.Start() +} + func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } -- cgit v1.2.3 From 95a48cea18eccd4ea2cb298027dbd01bd21f43e8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 21 Feb 2014 13:23:35 +0100 Subject: Peer amount update --- ui/gui.go | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'ui') diff --git a/ui/gui.go b/ui/gui.go index aae1320fc..e223fe262 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" "strings" + "time" ) type Gui struct { @@ -55,6 +56,7 @@ func (ui *Gui) Start() { ui.eth.BlockManager.SecondaryBlockProcessor = ui go ui.setInitialBlockChain() + go ui.updatePeers() ui.win.Show() ui.win.Wait() @@ -73,6 +75,13 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } +func (ui *Gui) updatePeers() { + for { + ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) + time.Sleep(1 * time.Second) + } +} + type Tester struct { root qml.Object } -- cgit v1.2.3 From 3e8b27c9dc78ffeeefae987e67730fae17707df4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 21 Feb 2014 17:29:59 +0100 Subject: WIP library, sample app --- ui/gui.go | 28 +++++++++++++++++++++++++--- ui/library.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 ui/library.go (limited to 'ui') diff --git a/ui/gui.go b/ui/gui.go index e223fe262..8f063843c 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -17,10 +17,15 @@ type Gui struct { engine *qml.Engine component *qml.Common eth *eth.Ethereum + + // The Ethereum library + lib *EthLib } func New(ethereum *eth.Ethereum) *Gui { - return &Gui{eth: ethereum} + lib := &EthLib{blockManager: ethereum.BlockManager, blockChain: ethereum.BlockManager.BlockChain(), txPool: ethereum.TxPool} + + return &Gui{eth: ethereum, lib: lib} } type Block struct { @@ -48,10 +53,10 @@ func (ui *Gui) Start() { } ui.win = component.CreateWindow(nil) - root := ui.win.Root() context := ui.engine.Context() - context.SetVar("tester", &Tester{root: root}) + context.SetVar("eth", ui.lib) + context.SetVar("ui", &UiLib{engine: ui.engine}) ui.eth.BlockManager.SecondaryBlockProcessor = ui @@ -82,6 +87,23 @@ func (ui *Gui) updatePeers() { } } +type UiLib struct { + engine *qml.Engine +} + +func (ui *UiLib) Open(path string) { + component, err := ui.engine.LoadFile(path[7:]) + if err != nil { + ethutil.Config.Log.Debugln(err) + } + win := component.CreateWindow(nil) + + go func() { + win.Show() + win.Wait() + }() +} + type Tester struct { root qml.Object } diff --git a/ui/library.go b/ui/library.go new file mode 100644 index 000000000..36952e198 --- /dev/null +++ b/ui/library.go @@ -0,0 +1,42 @@ +package ethui + +import ( + "encoding/hex" + "fmt" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "math/big" +) + +type EthLib struct { + blockManager *ethchain.BlockManager + blockChain *ethchain.BlockChain + txPool *ethchain.TxPool +} + +func (lib *EthLib) CreateTx(receiver string, amount uint64) string { + hash, err := hex.DecodeString(receiver) + if err != nil { + return err.Error() + } + + tx := ethchain.NewTransaction(hash, big.NewInt(int64(amount)), []string{""}) + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + tx.Sign(keyRing.Get(0).Bytes()) + + lib.txPool.QueueTransaction(tx) + + return ethutil.Hex(tx.Hash()) +} + +func (lib *EthLib) GetBlock(hexHash string) *Block { + hash, err := hex.DecodeString(hexHash) + if err != nil { + return nil + } + + block := lib.blockChain.GetBlock(hash) + fmt.Println(block) + return &Block{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())} +} -- cgit v1.2.3 From 2b967558cebcef9d3ef9719cbb28a5e596982a5d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 22 Feb 2014 01:52:47 +0100 Subject: Working out UI --- ui/gui.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'ui') diff --git a/ui/gui.go b/ui/gui.go index 8f063843c..fad7e9591 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -56,10 +56,12 @@ func (ui *Gui) Start() { context := ui.engine.Context() context.SetVar("eth", ui.lib) - context.SetVar("ui", &UiLib{engine: ui.engine}) + context.SetVar("ui", &UiLib{engine: ui.engine, eth: ui.eth}) ui.eth.BlockManager.SecondaryBlockProcessor = ui + ethutil.Config.Log.AddLogSystem(ui) + go ui.setInitialBlockChain() go ui.updatePeers() @@ -73,13 +75,23 @@ func (ui *Gui) setInitialBlockChain() { ui.ProcessBlock(block) } - ui.eth.Start() } func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } +func (ui *Gui) Println(v ...interface{}) { + str := fmt.Sprintln(v...) + // remove last \n + ui.win.Root().Call("addLog", str[:len(str)-1]) +} + +func (ui *Gui) Printf(format string, v ...interface{}) { + str := strings.TrimRight(fmt.Sprintf(format, v...), "\n") + ui.win.Root().Call("addLog", str) +} + func (ui *Gui) updatePeers() { for { ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) @@ -89,6 +101,7 @@ func (ui *Gui) updatePeers() { type UiLib struct { engine *qml.Engine + eth *eth.Ethereum } func (ui *UiLib) Open(path string) { @@ -104,6 +117,10 @@ func (ui *UiLib) Open(path string) { }() } +func (ui *UiLib) Connect() { + ui.eth.Start() +} + type Tester struct { root qml.Object } -- cgit v1.2.3 From aa33a4b2fb9dc07468498decceb6fdb56d38f54d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 22 Feb 2014 23:19:38 +0100 Subject: Added some ui elements to make it easier to connect to nodes --- ui/gui.go | 81 +++++++++++++++++++++++++++++++++++++++++++---------------- ui/library.go | 10 +++++--- 2 files changed, 65 insertions(+), 26 deletions(-) (limited to 'ui') diff --git a/ui/gui.go b/ui/gui.go index fad7e9591..51fd6d9a8 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -12,41 +12,56 @@ import ( "time" ) +// Block interface exposed to QML +type Block struct { + Number int + Hash string +} + +// Creates a new QML Block from a chain block +func NewBlockFromBlock(block *ethchain.Block) *Block { + info := block.BlockInfo() + hash := hex.EncodeToString(block.Hash()) + + return &Block{Number: int(info.Number), Hash: hash} +} + type Gui struct { - win *qml.Window + // The main application window + win *qml.Window + // QML Engine engine *qml.Engine component *qml.Common - eth *eth.Ethereum + // The ethereum interface + eth *eth.Ethereum - // The Ethereum library + // The public Ethereum library lib *EthLib } +// Create GUI, but doesn't start it func New(ethereum *eth.Ethereum) *Gui { lib := &EthLib{blockManager: ethereum.BlockManager, blockChain: ethereum.BlockManager.BlockChain(), txPool: ethereum.TxPool} - return &Gui{eth: ethereum, lib: lib} -} + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + addr := keyRing.Get(1).Bytes() -type Block struct { - Number int - Hash string -} - -func NewBlockFromBlock(block *ethchain.Block) *Block { - info := block.BlockInfo() - hash := hex.EncodeToString(block.Hash()) + ethereum.BlockManager.WatchAddr(addr) - return &Block{Number: int(info.Number), Hash: hash} + return &Gui{eth: ethereum, lib: lib} } func (ui *Gui) Start() { - qml.RegisterTypes("GoExtensions", 1, 0, []qml.TypeSpec{{ + // Register ethereum functions + qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, }}) ethutil.Config.Log.Infoln("[GUI] Starting GUI") + // Create a new QML engine ui.engine = qml.NewEngine() + // Load the main QML interface component, err := ui.engine.LoadFile("wallet.qml") if err != nil { panic(err) @@ -55,13 +70,18 @@ func (ui *Gui) Start() { ui.win = component.CreateWindow(nil) context := ui.engine.Context() + + // Expose the eth library and the ui library to QML context.SetVar("eth", ui.lib) context.SetVar("ui", &UiLib{engine: ui.engine, eth: ui.eth}) + // Register the ui as a block processor ui.eth.BlockManager.SecondaryBlockProcessor = ui + // Add the ui as a log system so we can log directly to the UGI ethutil.Config.Log.AddLogSystem(ui) + // Loads previous blocks go ui.setInitialBlockChain() go ui.updatePeers() @@ -70,6 +90,7 @@ func (ui *Gui) Start() { } func (ui *Gui) setInitialBlockChain() { + // Load previous 10 blocks chain := ui.eth.BlockManager.BlockChain().GetChain(ui.eth.BlockManager.BlockChain().CurrentBlock.Hash(), 10) for _, block := range chain { ui.ProcessBlock(block) @@ -81,17 +102,24 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } +// Logging functions that log directly to the GUI interface func (ui *Gui) Println(v ...interface{}) { - str := fmt.Sprintln(v...) - // remove last \n - ui.win.Root().Call("addLog", str[:len(str)-1]) + str := strings.TrimRight(fmt.Sprintln(v...), "\n") + lines := strings.Split(str, "\n") + for _, line := range lines { + ui.win.Root().Call("addLog", line) + } } func (ui *Gui) Printf(format string, v ...interface{}) { str := strings.TrimRight(fmt.Sprintf(format, v...), "\n") - ui.win.Root().Call("addLog", str) + lines := strings.Split(str, "\n") + for _, line := range lines { + ui.win.Root().Call("addLog", line) + } } +// Simple go routine function that updates the list of peers in the GUI func (ui *Gui) updatePeers() { for { ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) @@ -99,11 +127,14 @@ func (ui *Gui) updatePeers() { } } +// UI Library that has some basic functionality exposed type UiLib struct { - engine *qml.Engine - eth *eth.Ethereum + engine *qml.Engine + eth *eth.Ethereum + connected bool } +// Opens a QML file (external application) func (ui *UiLib) Open(path string) { component, err := ui.engine.LoadFile(path[7:]) if err != nil { @@ -118,7 +149,13 @@ func (ui *UiLib) Open(path string) { } func (ui *UiLib) Connect() { - ui.eth.Start() + if !ui.connected { + ui.eth.Start() + } +} + +func (ui *UiLib) ConnectToPeer(addr string) { + ui.eth.ConnectToPeer(addr) } type Tester struct { diff --git a/ui/library.go b/ui/library.go index 36952e198..0dfb10ac7 100644 --- a/ui/library.go +++ b/ui/library.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" - "math/big" ) type EthLib struct { @@ -14,15 +13,18 @@ type EthLib struct { txPool *ethchain.TxPool } -func (lib *EthLib) CreateTx(receiver string, amount uint64) string { +func (lib *EthLib) CreateTx(receiver, a string) string { hash, err := hex.DecodeString(receiver) if err != nil { return err.Error() } - - tx := ethchain.NewTransaction(hash, big.NewInt(int64(amount)), []string{""}) data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) keyRing := ethutil.NewValueFromBytes(data) + + amount := ethutil.Big(a) + tx := ethchain.NewTransaction(hash, amount, []string{""}) + tx.Nonce = lib.blockManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce + tx.Sign(keyRing.Get(0).Bytes()) lib.txPool.QueueTransaction(tx) -- cgit v1.2.3 From 0656f465b0c0690f237e42ac1e8f306dcda6c40b Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 23 Feb 2014 01:56:04 +0100 Subject: Added transactions window --- ui/gui.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'ui') diff --git a/ui/gui.go b/ui/gui.go index 51fd6d9a8..f0e281de1 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -18,6 +18,17 @@ type Block struct { Hash string } +type Tx struct { + Value, Hash, Address string +} + +func NewTxFromTransaction(tx *ethchain.Transaction) *Tx { + hash := hex.EncodeToString(tx.Hash()) + sender := hex.EncodeToString(tx.Recipient) + + return &Tx{Hash: hash[:4], Value: tx.Value.String(), Address: sender} +} + // Creates a new QML Block from a chain block func NewBlockFromBlock(block *ethchain.Block) *Block { info := block.BlockInfo() @@ -56,6 +67,8 @@ func (ui *Gui) Start() { // Register ethereum functions qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, + }, { + Init: func(p *Tx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" }, }}) ethutil.Config.Log.Infoln("[GUI] Starting GUI") @@ -66,6 +79,7 @@ func (ui *Gui) Start() { if err != nil { panic(err) } + ui.engine.LoadFile("transactions.qml") ui.win = component.CreateWindow(nil) @@ -77,6 +91,7 @@ func (ui *Gui) Start() { // Register the ui as a block processor ui.eth.BlockManager.SecondaryBlockProcessor = ui + ui.eth.TxPool.SecondaryProcessor = ui // Add the ui as a log system so we can log directly to the UGI ethutil.Config.Log.AddLogSystem(ui) @@ -102,6 +117,10 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } +func (ui *Gui) ProcessTransaction(tx *ethchain.Transaction) { + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) +} + // Logging functions that log directly to the GUI interface func (ui *Gui) Println(v ...interface{}) { str := strings.TrimRight(fmt.Sprintln(v...), "\n") -- cgit v1.2.3 From fe9eb472887baec464cc50657affd85b13bcbeba Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 24 Feb 2014 13:51:16 +0100 Subject: Minor fixes that to reflect changes in library --- ui/library.go | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'ui') diff --git a/ui/library.go b/ui/library.go index 0dfb10ac7..c9273e8c5 100644 --- a/ui/library.go +++ b/ui/library.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" + "strings" ) type EthLib struct { @@ -13,22 +14,34 @@ type EthLib struct { txPool *ethchain.TxPool } -func (lib *EthLib) CreateTx(receiver, a string) string { - hash, err := hex.DecodeString(receiver) - if err != nil { - return err.Error() +func (lib *EthLib) CreateTx(receiver, a, data string) string { + var hash []byte + if len(receiver) == 0 { + hash = ethchain.ContractAddr + } else { + var err error + hash, err = hex.DecodeString(receiver) + if err != nil { + return err.Error() + } } - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) + + k, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(k) amount := ethutil.Big(a) - tx := ethchain.NewTransaction(hash, amount, []string{""}) + code := ethchain.Compile(strings.Split(data, "\n")) + tx := ethchain.NewTransaction(hash, amount, code) tx.Nonce = lib.blockManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce tx.Sign(keyRing.Get(0).Bytes()) lib.txPool.QueueTransaction(tx) + if len(receiver) == 0 { + ethutil.Config.Log.Infof("Contract addr %x", tx.Hash()[12:]) + } + return ethutil.Hex(tx.Hash()) } @@ -40,5 +53,6 @@ func (lib *EthLib) GetBlock(hexHash string) *Block { block := lib.blockChain.GetBlock(hash) fmt.Println(block) + return &Block{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())} } -- cgit v1.2.3 From e60ff6ca41832c8124acfab6b8408516d60ac140 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 25 Feb 2014 10:54:15 +0100 Subject: Moved ui lib --- ui/ui_lib.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 ui/ui_lib.go (limited to 'ui') diff --git a/ui/ui_lib.go b/ui/ui_lib.go new file mode 100644 index 000000000..93712eba2 --- /dev/null +++ b/ui/ui_lib.go @@ -0,0 +1,38 @@ +package ethui + +import ( + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethutil" + "github.com/niemeyer/qml" +) + +// UI Library that has some basic functionality exposed +type UiLib struct { + engine *qml.Engine + eth *eth.Ethereum + connected bool +} + +// Opens a QML file (external application) +func (ui *UiLib) Open(path string) { + component, err := ui.engine.LoadFile(path[7:]) + if err != nil { + ethutil.Config.Log.Debugln(err) + } + win := component.CreateWindow(nil) + + go func() { + win.Show() + win.Wait() + }() +} + +func (ui *UiLib) Connect() { + if !ui.connected { + ui.eth.Start() + } +} + +func (ui *UiLib) ConnectToPeer(addr string) { + ui.eth.ConnectToPeer(addr) +} -- cgit v1.2.3 From 78b6e7ad9531461f389c5de3cef10fc665607050 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 25 Feb 2014 10:54:37 +0100 Subject: Proper Nonce --- ui/gui.go | 143 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 79 insertions(+), 64 deletions(-) (limited to 'ui') diff --git a/ui/gui.go b/ui/gui.go index f0e281de1..72e5b976a 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -1,15 +1,15 @@ package ethui import ( - "bufio" + "bytes" "encoding/hex" "fmt" "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" "strings" - "time" ) // Block interface exposed to QML @@ -26,7 +26,7 @@ func NewTxFromTransaction(tx *ethchain.Transaction) *Tx { hash := hex.EncodeToString(tx.Hash()) sender := hex.EncodeToString(tx.Recipient) - return &Tx{Hash: hash[:4], Value: tx.Value.String(), Address: sender} + return &Tx{Hash: hash, Value: tx.Value.String(), Address: sender} } // Creates a new QML Block from a chain block @@ -48,11 +48,19 @@ type Gui struct { // The public Ethereum library lib *EthLib + + txDb *ethdb.LDBDatabase + + addr []byte } // Create GUI, but doesn't start it func New(ethereum *eth.Ethereum) *Gui { lib := &EthLib{blockManager: ethereum.BlockManager, blockChain: ethereum.BlockManager.BlockChain(), txPool: ethereum.TxPool} + db, err := ethdb.NewLDBDatabase("tx_database") + if err != nil { + panic(err) + } data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) keyRing := ethutil.NewValueFromBytes(data) @@ -60,10 +68,12 @@ func New(ethereum *eth.Ethereum) *Gui { ethereum.BlockManager.WatchAddr(addr) - return &Gui{eth: ethereum, lib: lib} + return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr} } func (ui *Gui) Start() { + defer ui.txDb.Close() + // Register ethereum functions qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, @@ -91,17 +101,20 @@ func (ui *Gui) Start() { // Register the ui as a block processor ui.eth.BlockManager.SecondaryBlockProcessor = ui - ui.eth.TxPool.SecondaryProcessor = ui + //ui.eth.TxPool.SecondaryProcessor = ui // Add the ui as a log system so we can log directly to the UGI ethutil.Config.Log.AddLogSystem(ui) // Loads previous blocks go ui.setInitialBlockChain() - go ui.updatePeers() + go ui.readPreviousTransactions() + go ui.update() ui.win.Show() ui.win.Wait() + + ui.eth.Stop() } func (ui *Gui) setInitialBlockChain() { @@ -113,12 +126,72 @@ func (ui *Gui) setInitialBlockChain() { } +func (ui *Gui) readPreviousTransactions() { + it := ui.txDb.Db().NewIterator(nil) + for it.Next() { + tx := ethchain.NewTransactionFromBytes(it.Value()) + + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + } + it.Release() +} + func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } func (ui *Gui) ProcessTransaction(tx *ethchain.Transaction) { + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + + // TODO replace with general subscribe model +} + +// Simple go routine function that updates the list of peers in the GUI +func (ui *Gui) update() { + txChan := make(chan ethchain.TxMsg) + ui.eth.TxPool.Subscribe(txChan) + + account := ui.eth.BlockManager.GetAddrState(ui.addr).Account + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", account.Amount)) + for { + select { + case txMsg := <-txChan: + tx := txMsg.Tx + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + // Yeah, yeah, stupid code. Refactor next week + if txMsg.Type == ethchain.TxPre { + if bytes.Compare(tx.Sender(), ui.addr) == 0 { + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (- %v)", account.Amount, tx.Value)) + ui.eth.BlockManager.GetAddrState(ui.addr).Nonce += 1 + fmt.Println("Nonce", ui.eth.BlockManager.GetAddrState(ui.addr).Nonce) + } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (+ %v)", account.Amount, tx.Value)) + } + } else { + if bytes.Compare(tx.Sender(), ui.addr) == 0 { + amount := account.Amount.Sub(account.Amount, tx.Value) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", amount)) + } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { + amount := account.Amount.Sub(account.Amount, tx.Value) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", 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) + */ + + } } // Logging functions that log directly to the GUI interface @@ -137,61 +210,3 @@ func (ui *Gui) Printf(format string, v ...interface{}) { ui.win.Root().Call("addLog", line) } } - -// Simple go routine function that updates the list of peers in the GUI -func (ui *Gui) updatePeers() { - for { - ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) - time.Sleep(1 * time.Second) - } -} - -// UI Library that has some basic functionality exposed -type UiLib struct { - engine *qml.Engine - eth *eth.Ethereum - connected bool -} - -// Opens a QML file (external application) -func (ui *UiLib) Open(path string) { - component, err := ui.engine.LoadFile(path[7:]) - if err != nil { - ethutil.Config.Log.Debugln(err) - } - win := component.CreateWindow(nil) - - go func() { - win.Show() - win.Wait() - }() -} - -func (ui *UiLib) Connect() { - if !ui.connected { - ui.eth.Start() - } -} - -func (ui *UiLib) ConnectToPeer(addr string) { - ui.eth.ConnectToPeer(addr) -} - -type Tester struct { - root qml.Object -} - -func (t *Tester) Compile(area qml.Object) { - fmt.Println(area) - ethutil.Config.Log.Infoln("[TESTER] Compiling") - - code := area.String("text") - - scanner := bufio.NewScanner(strings.NewReader(code)) - scanner.Split(bufio.ScanLines) - - var lines []string - for scanner.Scan() { - lines = append(lines, scanner.Text()) - } -} -- cgit v1.2.3 From 6451a7187a5eeff6ac819ded11b6e7f0a5aa1b1b Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 25 Feb 2014 10:55:44 +0100 Subject: Minor UI change --- ui/library.go | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ui') diff --git a/ui/library.go b/ui/library.go index c9273e8c5..3bbb01314 100644 --- a/ui/library.go +++ b/ui/library.go @@ -40,6 +40,8 @@ func (lib *EthLib) CreateTx(receiver, a, data string) string { if len(receiver) == 0 { ethutil.Config.Log.Infof("Contract addr %x", tx.Hash()[12:]) + } else { + ethutil.Config.Log.Infof("Tx hash %x", tx.Hash()) } return ethutil.Hex(tx.Hash()) -- cgit v1.2.3 From dba1ba38220c92f96aaeeb2d4cc99c1991220dc4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 25 Feb 2014 11:24:04 +0100 Subject: Currency to string --- ui/gui.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'ui') diff --git a/ui/gui.go b/ui/gui.go index 72e5b976a..6e30b5891 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -26,7 +26,7 @@ func NewTxFromTransaction(tx *ethchain.Transaction) *Tx { hash := hex.EncodeToString(tx.Hash()) sender := hex.EncodeToString(tx.Recipient) - return &Tx{Hash: hash, Value: tx.Value.String(), Address: sender} + return &Tx{Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender} } // Creates a new QML Block from a chain block @@ -154,7 +154,7 @@ func (ui *Gui) update() { ui.eth.TxPool.Subscribe(txChan) account := ui.eth.BlockManager.GetAddrState(ui.addr).Account - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", account.Amount)) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(account.Amount))) for { select { case txMsg := <-txChan: @@ -162,22 +162,22 @@ func (ui *Gui) update() { ui.txDb.Put(tx.Hash(), tx.RlpEncode()) ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) - // Yeah, yeah, stupid code. Refactor next week + // TODO FOR THE LOVE OF EVERYTHING GOOD IN THIS WORLD REFACTOR ME if txMsg.Type == ethchain.TxPre { if bytes.Compare(tx.Sender(), ui.addr) == 0 { - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (- %v)", account.Amount, tx.Value)) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (- %v)", ethutil.CurrencyToString(account.Amount), ethutil.CurrencyToString(tx.Value))) ui.eth.BlockManager.GetAddrState(ui.addr).Nonce += 1 fmt.Println("Nonce", ui.eth.BlockManager.GetAddrState(ui.addr).Nonce) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (+ %v)", account.Amount, tx.Value)) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (+ %v)", ethutil.CurrencyToString(account.Amount), ethutil.CurrencyToString(tx.Value))) } } else { if bytes.Compare(tx.Sender(), ui.addr) == 0 { amount := account.Amount.Sub(account.Amount, tx.Value) - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", amount)) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { amount := account.Amount.Sub(account.Amount, tx.Value) - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", amount)) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) } } } -- cgit v1.2.3 From 8d1d72abeeee68ddcdffe02a28587a9bec1647e9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 28 Feb 2014 12:16:46 +0100 Subject: Improved overall UI design and added a bunch of icons --- ui/gui.go | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'ui') diff --git a/ui/gui.go b/ui/gui.go index 6e30b5891..556e682a9 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" + "math/big" "strings" ) @@ -62,9 +63,8 @@ func New(ethereum *eth.Ethereum) *Gui { panic(err) } - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - addr := keyRing.Get(1).Bytes() + key := ethutil.Config.Db.GetKeys()[0] + addr := key.Address() ethereum.BlockManager.WatchAddr(addr) @@ -127,7 +127,7 @@ func (ui *Gui) setInitialBlockChain() { } func (ui *Gui) readPreviousTransactions() { - it := ui.txDb.Db().NewIterator(nil) + it := ui.txDb.Db().NewIterator(nil, nil) for it.Next() { tx := ethchain.NewTransactionFromBytes(it.Value()) @@ -140,45 +140,50 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } -func (ui *Gui) ProcessTransaction(tx *ethchain.Transaction) { - ui.txDb.Put(tx.Hash(), tx.RlpEncode()) - - ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) - - // TODO replace with general subscribe model -} - // Simple go routine function that updates the list of peers in the GUI func (ui *Gui) update() { - txChan := make(chan ethchain.TxMsg) + txChan := make(chan ethchain.TxMsg, 1) ui.eth.TxPool.Subscribe(txChan) account := ui.eth.BlockManager.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 - ui.txDb.Put(tx.Hash(), tx.RlpEncode()) - ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) - // TODO FOR THE LOVE OF EVERYTHING GOOD IN THIS WORLD REFACTOR ME if txMsg.Type == ethchain.TxPre { if bytes.Compare(tx.Sender(), ui.addr) == 0 { - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (- %v)", ethutil.CurrencyToString(account.Amount), ethutil.CurrencyToString(tx.Value))) + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + ui.eth.BlockManager.GetAddrState(ui.addr).Nonce += 1 - fmt.Println("Nonce", ui.eth.BlockManager.GetAddrState(ui.addr).Nonce) + unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (+ %v)", ethutil.CurrencyToString(account.Amount), ethutil.CurrencyToString(tx.Value))) + 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 := account.Amount.Sub(account.Amount, tx.Value) - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) + amount.Sub(account.Amount, tx.Value) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { - amount := account.Amount.Sub(account.Amount, tx.Value) - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) + amount.Add(account.Amount, tx.Value) } + + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) } } -- cgit v1.2.3 From 560a7073f457a32c9d053f1a4b20f76d949f519d Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 28 Feb 2014 12:18:19 +0100 Subject: Fixed connection button spamming --- ui/ui_lib.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ui') diff --git a/ui/ui_lib.go b/ui/ui_lib.go index 93712eba2..c956fd032 100644 --- a/ui/ui_lib.go +++ b/ui/ui_lib.go @@ -27,9 +27,11 @@ func (ui *UiLib) Open(path string) { }() } -func (ui *UiLib) Connect() { +func (ui *UiLib) Connect(button qml.Object) { if !ui.connected { ui.eth.Start() + ui.connected = true + button.Set("enabled", false) } } -- cgit v1.2.3