From bd0abe2a8187c0ae948bba6a90cbaac07f479cc8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 00:39:16 +0100 Subject: [PATCH] Updated server and peers and mining processing --- dagger.go | 42 ++++++++++++------------------------------ ethereum.go | 31 ++++++++++++++++++++++++------- peer.go | 40 +++++++++++++++++++++++++++++++--------- server.go | 45 +++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 110 insertions(+), 48 deletions(-) diff --git a/dagger.go b/dagger.go index 9fef78a36..8509232a2 100644 --- a/dagger.go +++ b/dagger.go @@ -2,7 +2,6 @@ package main import ( "math/big" - "fmt" "math/rand" "time" "github.com/obscuren/sha3" @@ -26,8 +25,6 @@ func (dag *Dagger) Find(obj *big.Int, resChan chan int64) { resChan <- rnd // Notify other threads we've found a valid nonce Found = true - } else { - fmt.Printf(".") } // Break out if found @@ -37,17 +34,15 @@ func (dag *Dagger) Find(obj *big.Int, resChan chan int64) { resChan <- 0 } -func (dag *Dagger) Search(diff *big.Int) *big.Int { +func (dag *Dagger) Search(hash, diff *big.Int) *big.Int { // TODO fix multi threading. Somehow it results in the wrong nonce amountOfRoutines := 1 - dag.hash = big.NewInt(0) + dag.hash = hash obj := BigPow(2, 256) obj = obj.Div(obj, diff) - fmt.Println("diff", diff, "< objective", obj) - Found = false resChan := make(chan int64, 3) var res int64 @@ -64,8 +59,6 @@ func (dag *Dagger) Search(diff *big.Int) *big.Int { } } - fmt.Println("\n") - return big.NewInt(res) } @@ -128,32 +121,21 @@ func (dag *Dagger) Eval(N *big.Int) *big.Int { sha.Reset() ret := new(big.Int) - //doneChan := make(chan bool, 3) - for k := 0; k < 4; k++ { - //go func(_k int) { - _k := k - d := sha3.NewKeccak224() - b := new(big.Int) + d := sha3.NewKeccak224() + b := new(big.Int) - d.Reset() - d.Write(dag.hash.Bytes()) - d.Write(dag.xn.Bytes()) - d.Write(N.Bytes()) - d.Write(big.NewInt(int64(_k)).Bytes()) + d.Reset() + d.Write(dag.hash.Bytes()) + d.Write(dag.xn.Bytes()) + d.Write(N.Bytes()) + d.Write(big.NewInt(int64(k)).Bytes()) - b.SetBytes(Sum(d)) - pk := (b.Uint64() & 0x1ffffff) + b.SetBytes(Sum(d)) + pk := (b.Uint64() & 0x1ffffff) - sha.Write(dag.Node(9, pk).Bytes()) - //doneChan <- true - //}(k) + sha.Write(dag.Node(9, pk).Bytes()) } - //for k := 0; k < 4; k++ { - // <- doneChan - //} - - return ret.SetBytes(Sum(sha)) } diff --git a/ethereum.go b/ethereum.go index e3e5005eb..6ceb0249d 100644 --- a/ethereum.go +++ b/ethereum.go @@ -6,6 +6,7 @@ import ( "os/signal" "flag" "runtime" + "log" _"math/big" ) @@ -45,23 +46,39 @@ func main() { if StartConsole { console := NewConsole() console.Start() - } else if StartMining { - dagger := &Dagger{} - res := dagger.Search(BigPow(2, 36)) - fmt.Println("nonce =", res) - } else { - fmt.Println("[DBUG]: Starting Ethereum") + } else{ + log.Println("Starting Ethereum") server, err := NewServer() if err != nil { - fmt.Println("error NewServer:", err) + log.Println(err) return } RegisterInterupts(server) + if StartMining { + log.Println("Mining started") + dagger := &Dagger{} + + go func() { + for { + res := dagger.Search(Big("0"), BigPow(2, 36)) + server.Broadcast("foundblock", res.Bytes()) + } + }() + } + server.Start() + err = server.ConnectToPeer("localhost:12345") + if err != nil { + log.Println(err) + server.Stop() + return + } + + // Wait for shutdown server.WaitForShutdown() } diff --git a/peer.go b/peer.go index 0c8d38772..15e0fdcf1 100644 --- a/peer.go +++ b/peer.go @@ -11,6 +11,11 @@ type InMsg struct { data []byte // RLP encoded data } +type OutMsg struct { + msgType string + data []byte +} + func ReadMessage(conn net.Conn) (*InMsg, error) { buff := make([]byte, 4069) @@ -23,6 +28,7 @@ func ReadMessage(conn net.Conn) (*InMsg, error) { } // Read the header (MAX n) + // XXX The data specification is made up. This will change once more details have been released on the specification of the format decoder := NewRlpDecoder(buff[:n]) t := decoder.Get(0).AsString() if t == "" { @@ -32,10 +38,6 @@ func ReadMessage(conn net.Conn) (*InMsg, error) { return &InMsg{msgType: t, data: decoder.Get(1).AsBytes()}, nil } -type OutMsg struct { - data []byte -} - type Peer struct { server *Server conn net.Conn @@ -54,22 +56,34 @@ func NewPeer(conn net.Conn, server *Server) *Peer { } // Outputs any RLP encoded data to the peer -func (p *Peer) QueueMessage(data []byte) { - p.outputQueue <- OutMsg{data: data} +func (p *Peer) QueueMessage(msgType string, data []byte) { + p.outputQueue <- OutMsg{msgType: msgType, data: data} } func (p *Peer) HandleOutbound() { out: for { - switch { + select { + case msg := <-p.outputQueue: + p.WriteMessage(msg) + case <- p.quit: break out } } } +func (p *Peer) WriteMessage(msg OutMsg) { + encoded := Encode([]interface{}{ msg.msgType, msg.data }) + _, err := p.conn.Write(encoded) + if err != nil { + log.Println(err) + p.Stop() + } +} + func (p *Peer) HandleInbound() { - defer p.conn.Close() + defer p.Stop() out: for { @@ -80,7 +94,9 @@ out: break out } - log.Println(msg) + // TODO + data, _ := Decode(msg.data, 0) + log.Printf("%s, %s\n", msg.msgType, data) } // Notify the out handler we're quiting @@ -91,3 +107,9 @@ func (p *Peer) Start() { go p.HandleOutbound() go p.HandleInbound() } + +func (p *Peer) Stop() { + defer p.conn.Close() + + p.quit <- true +} diff --git a/server.go b/server.go index feaf61076..c2903cb59 100644 --- a/server.go +++ b/server.go @@ -4,6 +4,7 @@ import ( "container/list" "net" "log" + _"time" ) var Db *LDBDatabase @@ -38,7 +39,36 @@ func NewServer() (*Server, error) { } func (s *Server) AddPeer(conn net.Conn) { - s.peers.PushBack(NewPeer(conn, s)) + peer := NewPeer(conn, s) + s.peers.PushBack(peer) + peer.Start() + + log.Println("Peer connected ::", conn.RemoteAddr()) +} + +func (s *Server) ConnectToPeer(addr string) error { + conn, err := net.Dial("tcp", addr) + + if err != nil { + return err + } + + peer := NewPeer(conn, s) + s.peers.PushBack(peer) + peer.Start() + + + log.Println("Connected to peer ::", conn.RemoteAddr()) + + return nil +} + +func (s *Server) Broadcast(msgType string, data []byte) { + for e := s.peers.Front(); e != nil; e = e.Next() { + if peer, ok := e.Value.(*Peer); ok { + peer.QueueMessage(msgType, data) + } + } } // Start the server @@ -60,6 +90,15 @@ func (s *Server) Start() { go s.AddPeer(conn) } }() + + // TMP + //go func() { + // for { + // s.Broadcast("block", Encode("blockdata")) +// +// time.Sleep(100 * time.Millisecond) +// } +// }() } func (s *Server) Stop() { @@ -68,7 +107,9 @@ func (s *Server) Stop() { // Loop thru the peers and close them (if we had them) for e := s.peers.Front(); e != nil; e = e.Next() { - // peer close etc + if peer, ok := e.Value.(*Peer); ok { + peer.Stop() + } } s.shutdownChan <- true