From 2b32f47d2c17aaee655d56fd91c95798652b1116 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 23 Jan 2014 20:14:01 +0100 Subject: Initial commit bootstrapping package --- peer.go | 303 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 peer.go (limited to 'peer.go') diff --git a/peer.go b/peer.go new file mode 100644 index 000000000..ef9a05ed1 --- /dev/null +++ b/peer.go @@ -0,0 +1,303 @@ +package eth + +import ( + "github.com/ethereum/ethutil-go" + "github.com/ethereum/ethwire-go" + "log" + "net" + "strconv" + "sync/atomic" + "time" +) + +const ( + // The size of the output buffer for writing messages + outputBufferSize = 50 +) + +type Peer struct { + // Ethereum interface + ethereum *Ethereum + // Net connection + conn net.Conn + // Output queue which is used to communicate and handle messages + outputQueue chan *ethwire.Msg + // Quit channel + quit chan bool + // Determines whether it's an inbound or outbound peer + inbound bool + // Flag for checking the peer's connectivity state + connected int32 + disconnect int32 + // Last known message send + lastSend time.Time + // Indicated whether a verack has been send or not + // This flag is used by writeMessage to check if messages are allowed + // to be send or not. If no version is known all messages are ignored. + versionKnown bool + + // Last received pong message + lastPong int64 + // Indicates whether a MsgGetPeersTy was requested of the peer + // this to prevent receiving false peers. + requestedPeerList bool +} + +func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { + return &Peer{ + outputQueue: make(chan *ethwire.Msg, outputBufferSize), + quit: make(chan bool), + ethereum: ethereum, + conn: conn, + inbound: inbound, + disconnect: 0, + connected: 1, + } +} + +func NewOutboundPeer(addr string, ethereum *Ethereum) *Peer { + p := &Peer{ + outputQueue: make(chan *ethwire.Msg, outputBufferSize), + quit: make(chan bool), + ethereum: ethereum, + inbound: false, + connected: 0, + disconnect: 0, + } + + // Set up the connection in another goroutine so we don't block the main thread + go func() { + conn, err := net.Dial("tcp", addr) + if err != nil { + p.Stop() + } + p.conn = conn + + // Atomically set the connection state + atomic.StoreInt32(&p.connected, 1) + atomic.StoreInt32(&p.disconnect, 0) + + log.Println("Connected to peer ::", conn.RemoteAddr()) + + p.Start() + }() + + return p +} + +// Outputs any RLP encoded data to the peer +func (p *Peer) QueueMessage(msg *ethwire.Msg) { + p.outputQueue <- msg +} + +func (p *Peer) writeMessage(msg *ethwire.Msg) { + // Ignore the write if we're not connected + if atomic.LoadInt32(&p.connected) != 1 { + return + } + + if !p.versionKnown { + switch msg.Type { + case ethwire.MsgHandshakeTy: // Ok + default: // Anything but ack is allowed + return + } + } + + err := ethwire.WriteMessage(p.conn, msg) + if err != nil { + log.Println("Can't send message:", err) + // Stop the client if there was an error writing to it + p.Stop() + return + } +} + +// Outbound message handler. Outbound messages are handled here +func (p *Peer) HandleOutbound() { + // The ping timer. Makes sure that every 2 minutes a ping is send to the peer + tickleTimer := time.NewTicker(2 * time.Minute) +out: + for { + select { + // Main message queue. All outbound messages are processed through here + case msg := <-p.outputQueue: + p.writeMessage(msg) + + p.lastSend = time.Now() + + case <-tickleTimer.C: + p.writeMessage(ðwire.Msg{Type: ethwire.MsgPingTy}) + + // Break out of the for loop if a quit message is posted + case <-p.quit: + break out + } + } + +clean: + // This loop is for draining the output queue and anybody waiting for us + for { + select { + case <-p.outputQueue: + // TODO + default: + break clean + } + } +} + +// Inbound handler. Inbound messages are received here and passed to the appropriate methods +func (p *Peer) HandleInbound() { + +out: + for atomic.LoadInt32(&p.disconnect) == 0 { + // Wait for a message from the peer + msg, err := ethwire.ReadMessage(p.conn) + if err != nil { + log.Println(err) + + break out + } + + if ethutil.Config.Debug { + log.Printf("Received %s\n", msg.Type.String()) + } + + switch msg.Type { + case ethwire.MsgHandshakeTy: + // Version message + p.handleHandshake(msg) + case ethwire.MsgBlockTy: + err := p.ethereum.BlockManager.ProcessBlock(ethutil.NewBlock(msg.Data)) + if err != nil { + log.Println(err) + } + case ethwire.MsgTxTy: + p.ethereum.TxPool.QueueTransaction(ethutil.NewTransactionFromData(msg.Data)) + case ethwire.MsgInvTy: + case ethwire.MsgGetPeersTy: + p.requestedPeerList = true + // Peer asked for list of connected peers + p.pushPeers() + case ethwire.MsgPeersTy: + // Received a list of peers (probably because MsgGetPeersTy was send) + // Only act on message if we actually requested for a peers list + if p.requestedPeerList { + data := ethutil.Conv(msg.Data) + // Create new list of possible peers for the ethereum to process + peers := make([]string, data.Length()) + // Parse each possible peer + for i := 0; i < data.Length(); i++ { + peers[i] = data.Get(i).AsString() + strconv.Itoa(int(data.Get(i).AsUint())) + } + + // Connect to the list of peers + p.ethereum.ProcessPeerList(peers) + // Mark unrequested again + p.requestedPeerList = false + } + case ethwire.MsgPingTy: + // Respond back with pong + p.QueueMessage(ðwire.Msg{Type: ethwire.MsgPongTy}) + case ethwire.MsgPongTy: + p.lastPong = time.Now().Unix() + } + } + + p.Stop() +} + +func (p *Peer) Start() { + if !p.inbound { + err := p.pushHandshake() + if err != nil { + log.Printf("Peer can't send outbound version ack", err) + + p.Stop() + } + } + + // Run the outbound handler in a new goroutine + go p.HandleOutbound() + // Run the inbound handler in a new goroutine + go p.HandleInbound() +} + +func (p *Peer) Stop() { + if atomic.AddInt32(&p.disconnect, 1) != 1 { + return + } + + close(p.quit) + if atomic.LoadInt32(&p.connected) != 0 { + p.conn.Close() + } + + log.Println("Peer shutdown") +} + +func (p *Peer) pushHandshake() error { + msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, ethutil.Encode([]interface{}{ + 1, 0, p.ethereum.Nonce, + })) + + p.QueueMessage(msg) + + return nil +} + +// Pushes the list of outbound peers to the client when requested +func (p *Peer) pushPeers() { + outPeers := make([]interface{}, len(p.ethereum.OutboundPeers())) + // Serialise each peer + for i, peer := range p.ethereum.OutboundPeers() { + outPeers[i] = peer.RlpEncode() + } + + // Send message to the peer with the known list of connected clients + msg := ethwire.NewMessage(ethwire.MsgPeersTy, ethutil.Encode(outPeers)) + + p.QueueMessage(msg) +} + +func (p *Peer) handleHandshake(msg *ethwire.Msg) { + c := ethutil.Conv(msg.Data) + // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID] + if c.Get(2).AsUint() == p.ethereum.Nonce { + //if msg.Nonce == p.ethereum.Nonce { + log.Println("Peer connected to self, disconnecting") + + p.Stop() + + return + } + + p.versionKnown = true + + // If this is an inbound connection send an ack back + if p.inbound { + err := p.pushHandshake() + if err != nil { + log.Println("Peer can't send ack back") + + p.Stop() + } + } +} + +func (p *Peer) RlpEncode() []byte { + host, prt, err := net.SplitHostPort(p.conn.RemoteAddr().String()) + if err != nil { + return nil + } + + i, err := strconv.Atoi(prt) + if err != nil { + return nil + } + + port := ethutil.NumberToBytes(uint16(i), 16) + + return ethutil.Encode([]interface{}{host, port}) +} -- cgit v1.2.3 From 878e796c0adaa608a3e5feacf89a6766b347c9c8 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 23 Jan 2014 20:55:23 +0100 Subject: Updated packages --- peer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ef9a05ed1..d29481654 100644 --- a/peer.go +++ b/peer.go @@ -1,6 +1,7 @@ package eth import ( + "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" "github.com/ethereum/ethwire-go" "log" @@ -169,7 +170,7 @@ out: // Version message p.handleHandshake(msg) case ethwire.MsgBlockTy: - err := p.ethereum.BlockManager.ProcessBlock(ethutil.NewBlock(msg.Data)) + err := p.ethereum.BlockManager.ProcessBlock(ethchain.NewBlock(msg.Data)) if err != nil { log.Println(err) } -- cgit v1.2.3 From 233f5200ef77ee77b4d33b5ff277d0e524b1fb4d Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 23 Jan 2014 22:32:50 +0100 Subject: Data send over the wire shouldn't be RLPed more then once --- peer.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index d29481654..4f799e890 100644 --- a/peer.go +++ b/peer.go @@ -170,12 +170,15 @@ out: // Version message p.handleHandshake(msg) case ethwire.MsgBlockTy: - err := p.ethereum.BlockManager.ProcessBlock(ethchain.NewBlock(msg.Data)) - if err != nil { - log.Println(err) - } + /* + err := p.ethereum.BlockManager.ProcessBlock(ethchain.NewBlock(msg.Data)) + if err != nil { + log.Println(err) + } + */ case ethwire.MsgTxTy: - p.ethereum.TxPool.QueueTransaction(ethutil.NewTransactionFromData(msg.Data)) + //p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromData(msg.Data)) + p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromRlpValue(msg.Data.Get(0))) case ethwire.MsgInvTy: case ethwire.MsgGetPeersTy: p.requestedPeerList = true @@ -263,7 +266,7 @@ func (p *Peer) pushPeers() { } func (p *Peer) handleHandshake(msg *ethwire.Msg) { - c := ethutil.Conv(msg.Data) + c := msg.Data // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID] if c.Get(2).AsUint() == p.ethereum.Nonce { //if msg.Nonce == p.ethereum.Nonce { -- cgit v1.2.3 From 1b7cba18781ddd6ff262801057930367ea397c9e Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 24 Jan 2014 17:48:21 +0100 Subject: Updated peers --- peer.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4f799e890..afbe728fe 100644 --- a/peer.go +++ b/peer.go @@ -128,7 +128,7 @@ out: p.lastSend = time.Now() case <-tickleTimer.C: - p.writeMessage(ðwire.Msg{Type: ethwire.MsgPingTy}) + p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) // Break out of the for loop if a quit message is posted case <-p.quit: @@ -170,12 +170,12 @@ out: // Version message p.handleHandshake(msg) case ethwire.MsgBlockTy: - /* - err := p.ethereum.BlockManager.ProcessBlock(ethchain.NewBlock(msg.Data)) - if err != nil { - log.Println(err) - } - */ + block := ethchain.NewBlockFromRlpValue(msg.Data.Get(0)) + block.MakeContracts() + err := p.ethereum.BlockManager.ProcessBlock(block) + if err != nil { + log.Println(err) + } case ethwire.MsgTxTy: //p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromData(msg.Data)) p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromRlpValue(msg.Data.Get(0))) @@ -203,7 +203,7 @@ out: } case ethwire.MsgPingTy: // Respond back with pong - p.QueueMessage(ðwire.Msg{Type: ethwire.MsgPongTy}) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) case ethwire.MsgPongTy: p.lastPong = time.Now().Unix() } -- cgit v1.2.3 From 7931c6624cca041b373e97e17e43318633633250 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sat, 25 Jan 2014 17:13:33 +0100 Subject: Graceful shutdown of peers --- peer.go | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index afbe728fe..f370580cf 100644 --- a/peer.go +++ b/peer.go @@ -169,17 +169,26 @@ out: case ethwire.MsgHandshakeTy: // Version message p.handleHandshake(msg) + case ethwire.MsgDiscTy: + p.Stop() + case ethwire.MsgPingTy: + // Respond back with pong + p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) + case ethwire.MsgPongTy: + p.lastPong = time.Now().Unix() case ethwire.MsgBlockTy: - block := ethchain.NewBlockFromRlpValue(msg.Data.Get(0)) - block.MakeContracts() - err := p.ethereum.BlockManager.ProcessBlock(block) - if err != nil { - log.Println(err) + for i := 0; i < msg.Data.Length(); i++ { + block := ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) + err := p.ethereum.BlockManager.ProcessBlock(block) + + if err != nil { + log.Println(err) + } } case ethwire.MsgTxTy: - //p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromData(msg.Data)) - p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromRlpValue(msg.Data.Get(0))) - case ethwire.MsgInvTy: + for i := 0; i < msg.Data.Length(); i++ { + p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromRlpValue(msg.Data.Get(i))) + } case ethwire.MsgGetPeersTy: p.requestedPeerList = true // Peer asked for list of connected peers @@ -201,11 +210,8 @@ out: // Mark unrequested again p.requestedPeerList = false } - case ethwire.MsgPingTy: - // Respond back with pong - p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) - case ethwire.MsgPongTy: - p.lastPong = time.Now().Unix() + case ethwire.MsgGetChainTy: + } } @@ -235,6 +241,7 @@ func (p *Peer) Stop() { close(p.quit) if atomic.LoadInt32(&p.connected) != 0 { + p.writeMessage(ethwire.NewMessage(ethwire.MsgDiscTy, "")) p.conn.Close() } -- cgit v1.2.3 From 884f7928717394d631fbc8b721d8ee297f060e5b Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 27 Jan 2014 15:34:50 +0100 Subject: Removed default connection --- peer.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index f370580cf..d2328c393 100644 --- a/peer.go +++ b/peer.go @@ -68,9 +68,12 @@ func NewOutboundPeer(addr string, ethereum *Ethereum) *Peer { // Set up the connection in another goroutine so we don't block the main thread go func() { - conn, err := net.Dial("tcp", addr) + conn, err := net.DialTimeout("tcp", addr, 30*time.Second) + if err != nil { + log.Println("Connection to peer failed", err) p.Stop() + return } p.conn = conn @@ -211,7 +214,30 @@ out: p.requestedPeerList = false } case ethwire.MsgGetChainTy: + blocksFound := 0 + l := msg.Data.Length() + // Check each SHA block hash from the message and determine whether + // the SHA is in the database + for i := 0; i < l; i++ { + if p.ethereum.BlockManager.BlockChain().HasBlock(msg.Data.Get(i).AsString()) { + blocksFound++ + // TODO send reply + } + } + + // If no blocks are found we send back a reply with msg not in chain + // and the last hash from get chain + if blocksFound == 0 { + lastHash := msg.Data.Get(l - 1) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, lastHash)) + } + case ethwire.MsgNotInChainTy: + log.Println("Not in chain, not yet implemented") + // TODO + // Unofficial but fun nonetheless + case ethwire.MsgTalkTy: + log.Printf("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.Get(0).AsString()) } } -- cgit v1.2.3 From 3e400739a77c8d2555ea74ae1544b483b375a960 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 28 Jan 2014 15:35:44 +0100 Subject: Implemented get chain msg --- peer.go | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index d2328c393..ab16575e7 100644 --- a/peer.go +++ b/peer.go @@ -178,9 +178,14 @@ out: // Respond back with pong p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) case ethwire.MsgPongTy: + // If we received a pong back from a peer we set the + // last pong so the peer handler knows this peer is still + // active. p.lastPong = time.Now().Unix() case ethwire.MsgBlockTy: - for i := 0; i < msg.Data.Length(); i++ { + // Get all blocks and process them (TODO reverse order?) + msg.Data = msg.Data.Get(0) + for i := msg.Data.Length() - 1; i >= 0; i-- { block := ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) err := p.ethereum.BlockManager.ProcessBlock(block) @@ -189,10 +194,15 @@ out: } } case ethwire.MsgTxTy: + // If the message was a transaction queue the transaction + // in the TxPool where it will undergo validation and + // processing when a new block is found for i := 0; i < msg.Data.Length(); i++ { p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromRlpValue(msg.Data.Get(i))) } case ethwire.MsgGetPeersTy: + // Flag this peer as a 'requested of new peers' this to + // prevent malicious peers being forced. p.requestedPeerList = true // Peer asked for list of connected peers p.pushPeers() @@ -214,22 +224,31 @@ out: p.requestedPeerList = false } case ethwire.MsgGetChainTy: - blocksFound := 0 - l := msg.Data.Length() + var parent *ethchain.Block + // FIXME + msg.Data = msg.Data.Get(0) + // Length minus one since the very last element in the array is a count + l := msg.Data.Length() - 1 + // Amount of parents in the canonical chain + amountOfBlocks := msg.Data.Get(l).AsUint() // Check each SHA block hash from the message and determine whether // the SHA is in the database for i := 0; i < l; i++ { - if p.ethereum.BlockManager.BlockChain().HasBlock(msg.Data.Get(i).AsString()) { - blocksFound++ - // TODO send reply + if data := msg.Data.Get(i).AsBytes(); p.ethereum.BlockManager.BlockChain().HasBlock(data) { + parent = p.ethereum.BlockManager.BlockChain().GetBlock(data) + break } } - // If no blocks are found we send back a reply with msg not in chain - // and the last hash from get chain - if blocksFound == 0 { - lastHash := msg.Data.Get(l - 1) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, lastHash)) + // If a parent is found send back a reply + if parent != nil { + chain := p.ethereum.BlockManager.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) + } else { + // If no blocks are found we send back a reply with msg not in chain + // and the last hash from get chain + lastHash := msg.Data.Get(l) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, lastHash.AsRaw())) } case ethwire.MsgNotInChainTy: log.Println("Not in chain, not yet implemented") @@ -320,6 +339,9 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.Stop() } + } else { + msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)}) + p.QueueMessage(msg) } } -- cgit v1.2.3 From 7ccf51fd3035aaba8ed3eda0ca8e3b01edaaa2cf Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 30 Jan 2014 23:48:52 +0100 Subject: Updated seed peers --- peer.go | 243 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 129 insertions(+), 114 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ab16575e7..627e57b05 100644 --- a/peer.go +++ b/peer.go @@ -42,6 +42,9 @@ type Peer struct { // Indicates whether a MsgGetPeersTy was requested of the peer // this to prevent receiving false peers. requestedPeerList bool + + // Determines whether this is a seed peer + seed bool } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { @@ -81,9 +84,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum) *Peer { atomic.StoreInt32(&p.connected, 1) atomic.StoreInt32(&p.disconnect, 0) - log.Println("Connected to peer ::", conn.RemoteAddr()) - - p.Start() + p.Start(false) }() return p @@ -115,6 +116,14 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { p.Stop() return } + + // XXX TMP CODE FOR TESTNET + switch msg.Type { + case ethwire.MsgPeersTy: + if p.seed { + p.Stop() + } + } } // Outbound message handler. Outbound messages are handled here @@ -133,7 +142,7 @@ out: case <-tickleTimer.C: p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) - // Break out of the for loop if a quit message is posted + // Break out of the for loop if a quit message is posted case <-p.quit: break out } @@ -157,113 +166,118 @@ func (p *Peer) HandleInbound() { out: for atomic.LoadInt32(&p.disconnect) == 0 { // Wait for a message from the peer - msg, err := ethwire.ReadMessage(p.conn) - if err != nil { - log.Println(err) + msgs, err := ethwire.ReadMessages(p.conn) + for _, msg := range msgs { + if err != nil { + log.Println(err) - break out - } - - if ethutil.Config.Debug { - log.Printf("Received %s\n", msg.Type.String()) - } + break out + } - switch msg.Type { - case ethwire.MsgHandshakeTy: - // Version message - p.handleHandshake(msg) - case ethwire.MsgDiscTy: - p.Stop() - case ethwire.MsgPingTy: - // Respond back with pong - p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) - case ethwire.MsgPongTy: - // If we received a pong back from a peer we set the - // last pong so the peer handler knows this peer is still - // active. - p.lastPong = time.Now().Unix() - case ethwire.MsgBlockTy: - // Get all blocks and process them (TODO reverse order?) - msg.Data = msg.Data.Get(0) - for i := msg.Data.Length() - 1; i >= 0; i-- { - block := ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) - err := p.ethereum.BlockManager.ProcessBlock(block) - - if err != nil { - log.Println(err) + switch msg.Type { + case ethwire.MsgHandshakeTy: + // Version message + p.handleHandshake(msg) + case ethwire.MsgDiscTy: + p.Stop() + case ethwire.MsgPingTy: + // Respond back with pong + p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) + case ethwire.MsgPongTy: + // If we received a pong back from a peer we set the + // last pong so the peer handler knows this peer is still + // active. + p.lastPong = time.Now().Unix() + case ethwire.MsgBlockTy: + // Get all blocks and process them + msg.Data = msg.Data + for i := msg.Data.Length() - 1; i >= 0; i-- { + block := ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) + err := p.ethereum.BlockManager.ProcessBlock(block) + + if err != nil { + log.Println(err) + } } - } - case ethwire.MsgTxTy: - // If the message was a transaction queue the transaction - // in the TxPool where it will undergo validation and - // processing when a new block is found - for i := 0; i < msg.Data.Length(); i++ { - p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromRlpValue(msg.Data.Get(i))) - } - case ethwire.MsgGetPeersTy: - // Flag this peer as a 'requested of new peers' this to - // prevent malicious peers being forced. - p.requestedPeerList = true - // Peer asked for list of connected peers - p.pushPeers() - case ethwire.MsgPeersTy: - // Received a list of peers (probably because MsgGetPeersTy was send) - // Only act on message if we actually requested for a peers list - if p.requestedPeerList { - data := ethutil.Conv(msg.Data) - // Create new list of possible peers for the ethereum to process - peers := make([]string, data.Length()) - // Parse each possible peer - for i := 0; i < data.Length(); i++ { - peers[i] = data.Get(i).AsString() + strconv.Itoa(int(data.Get(i).AsUint())) + case ethwire.MsgTxTy: + // If the message was a transaction queue the transaction + // in the TxPool where it will undergo validation and + // processing when a new block is found + for i := 0; i < msg.Data.Length(); i++ { + p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromRlpValue(msg.Data.Get(i))) } + case ethwire.MsgGetPeersTy: + // Flag this peer as a 'requested of new peers' this to + // prevent malicious peers being forced. + p.requestedPeerList = true + // Peer asked for list of connected peers + p.pushPeers() + case ethwire.MsgPeersTy: + // Received a list of peers (probably because MsgGetPeersTy was send) + // Only act on message if we actually requested for a peers list + if p.requestedPeerList { + data := ethutil.Conv(msg.Data) + // Create new list of possible peers for the ethereum to process + peers := make([]string, data.Length()) + // Parse each possible peer + for i := 0; i < data.Length(); i++ { + peers[i] = data.Get(i).AsString() + strconv.Itoa(int(data.Get(i).AsUint())) + } + + // Connect to the list of peers + p.ethereum.ProcessPeerList(peers) + // Mark unrequested again + p.requestedPeerList = false - // Connect to the list of peers - p.ethereum.ProcessPeerList(peers) - // Mark unrequested again - p.requestedPeerList = false - } - case ethwire.MsgGetChainTy: - var parent *ethchain.Block - // FIXME - msg.Data = msg.Data.Get(0) - // Length minus one since the very last element in the array is a count - l := msg.Data.Length() - 1 - // Amount of parents in the canonical chain - amountOfBlocks := msg.Data.Get(l).AsUint() - // Check each SHA block hash from the message and determine whether - // the SHA is in the database - for i := 0; i < l; i++ { - if data := msg.Data.Get(i).AsBytes(); p.ethereum.BlockManager.BlockChain().HasBlock(data) { - parent = p.ethereum.BlockManager.BlockChain().GetBlock(data) + } + case ethwire.MsgGetChainTy: + var parent *ethchain.Block + // Length minus one since the very last element in the array is a count + l := msg.Data.Length() - 1 + // Ignore empty get chains + if l <= 1 { break } - } - // If a parent is found send back a reply - if parent != nil { - chain := p.ethereum.BlockManager.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) - } else { - // If no blocks are found we send back a reply with msg not in chain - // and the last hash from get chain - lastHash := msg.Data.Get(l) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, lastHash.AsRaw())) - } - case ethwire.MsgNotInChainTy: - log.Println("Not in chain, not yet implemented") - // TODO + // Amount of parents in the canonical chain + amountOfBlocks := msg.Data.Get(l).AsUint() + // Check each SHA block hash from the message and determine whether + // the SHA is in the database + for i := 0; i < l; i++ { + if data := msg.Data.Get(i).AsBytes(); p.ethereum.BlockManager.BlockChain().HasBlock(data) { + parent = p.ethereum.BlockManager.BlockChain().GetBlock(data) + break + } + } + + // If a parent is found send back a reply + if parent != nil { + chain := p.ethereum.BlockManager.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, append(chain, amountOfBlocks))) + } else { + // If no blocks are found we send back a reply with msg not in chain + // and the last hash from get chain + lastHash := msg.Data.Get(l - 1) + log.Printf("Sending not in chain with hash %x\n", lastHash.AsRaw()) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, []interface{}{lastHash.AsRaw()})) + } + case ethwire.MsgNotInChainTy: + log.Printf("Not in chain %x\n", msg.Data) + // TODO - // Unofficial but fun nonetheless - case ethwire.MsgTalkTy: - log.Printf("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.Get(0).AsString()) + // Unofficial but fun nonetheless + case ethwire.MsgTalkTy: + log.Printf("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.AsString()) + } } } p.Stop() } -func (p *Peer) Start() { +func (p *Peer) Start(seed bool) { + p.seed = seed + if !p.inbound { err := p.pushHandshake() if err != nil { @@ -277,6 +291,7 @@ func (p *Peer) Start() { go p.HandleOutbound() // Run the inbound handler in a new goroutine go p.HandleInbound() + } func (p *Peer) Stop() { @@ -294,9 +309,9 @@ func (p *Peer) Stop() { } func (p *Peer) pushHandshake() error { - msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, ethutil.Encode([]interface{}{ - 1, 0, p.ethereum.Nonce, - })) + msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ + uint32(0), uint32(0), "/Ethereum(G) v0.0.1/", + }) p.QueueMessage(msg) @@ -305,6 +320,7 @@ func (p *Peer) pushHandshake() error { // Pushes the list of outbound peers to the client when requested func (p *Peer) pushPeers() { + outPeers := make([]interface{}, len(p.ethereum.OutboundPeers())) // Serialise each peer for i, peer := range p.ethereum.OutboundPeers() { @@ -312,7 +328,7 @@ func (p *Peer) pushPeers() { } // Send message to the peer with the known list of connected clients - msg := ethwire.NewMessage(ethwire.MsgPeersTy, ethutil.Encode(outPeers)) + msg := ethwire.NewMessage(ethwire.MsgPeersTy, outPeers) p.QueueMessage(msg) } @@ -320,29 +336,28 @@ func (p *Peer) pushPeers() { func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID] - if c.Get(2).AsUint() == p.ethereum.Nonce { - //if msg.Nonce == p.ethereum.Nonce { - log.Println("Peer connected to self, disconnecting") - - p.Stop() - - return - } - p.versionKnown = true + var istr string // If this is an inbound connection send an ack back if p.inbound { - err := p.pushHandshake() - if err != nil { - log.Println("Peer can't send ack back") + /* + err := p.pushHandshake() + if err != nil { + log.Println("Peer can't send ack back") - p.Stop() - } + p.Stop() + } + */ + istr = "inbound" } else { msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)}) p.QueueMessage(msg) + + istr = "outbound" } + + log.Printf("peer connect (%s) %v %s\n", istr, p.conn.RemoteAddr(), c.Get(2).AsString()) } func (p *Peer) RlpEncode() []byte { -- cgit v1.2.3 From 7f100e96101a057cba7b2d5c58c12d2f7accf381 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 31 Jan 2014 00:56:32 +0100 Subject: Self connect detect --- peer.go | 54 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 627e57b05..bd75a0039 100644 --- a/peer.go +++ b/peer.go @@ -178,6 +178,8 @@ out: case ethwire.MsgHandshakeTy: // Version message p.handleHandshake(msg) + + p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) case ethwire.MsgDiscTy: p.Stop() case ethwire.MsgPingTy: @@ -216,12 +218,12 @@ out: // Received a list of peers (probably because MsgGetPeersTy was send) // Only act on message if we actually requested for a peers list if p.requestedPeerList { - data := ethutil.Conv(msg.Data) + data := msg.Data // Create new list of possible peers for the ethereum to process peers := make([]string, data.Length()) // Parse each possible peer for i := 0; i < data.Length(); i++ { - peers[i] = data.Get(i).AsString() + strconv.Itoa(int(data.Get(i).AsUint())) + peers[i] = data.Get(i).Get(0).AsString() + ":" + strconv.Itoa(int(data.Get(i).Get(1).AsUint())) } // Connect to the list of peers @@ -278,14 +280,27 @@ out: func (p *Peer) Start(seed bool) { p.seed = seed - if !p.inbound { - err := p.pushHandshake() - if err != nil { - log.Printf("Peer can't send outbound version ack", err) + peerHost, _, _ := net.SplitHostPort(p.conn.LocalAddr().String()) + servHost, _, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) + log.Println(peerHost, servHost) + if peerHost == servHost { + log.Println("Connected to self") - p.Stop() - } + p.Stop() + + return + } + + //if !p.inbound { + err := p.pushHandshake() + if err != nil { + log.Printf("Peer can't send outbound version ack", err) + + p.Stop() + + return } + //} // Run the outbound handler in a new goroutine go p.HandleOutbound() @@ -320,11 +335,10 @@ func (p *Peer) pushHandshake() error { // Pushes the list of outbound peers to the client when requested func (p *Peer) pushPeers() { - outPeers := make([]interface{}, len(p.ethereum.OutboundPeers())) // Serialise each peer for i, peer := range p.ethereum.OutboundPeers() { - outPeers[i] = peer.RlpEncode() + outPeers[i] = peer.RlpData() } // Send message to the peer with the known list of connected clients @@ -351,8 +365,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { */ istr = "inbound" } else { - msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)}) - p.QueueMessage(msg) + //msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)}) + //p.QueueMessage(msg) istr = "outbound" } @@ -360,6 +374,22 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { log.Printf("peer connect (%s) %v %s\n", istr, p.conn.RemoteAddr(), c.Get(2).AsString()) } +func (p *Peer) RlpData() []interface{} { + host, prt, err := net.SplitHostPort(p.conn.RemoteAddr().String()) + if err != nil { + return nil + } + + port, err := strconv.Atoi(prt) + if err != nil { + return nil + } + + //port := ethutil.NumberToBytes(uint16(i), 16) + + return []interface{}{host, port} +} + func (p *Peer) RlpEncode() []byte { host, prt, err := net.SplitHostPort(p.conn.RemoteAddr().String()) if err != nil { -- cgit v1.2.3 From da66eddfccf86eb5dc036e023ddc2e0278105706 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 31 Jan 2014 11:57:56 +0100 Subject: Get peers returns now both in and outbound peers --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index bd75a0039..410e310f5 100644 --- a/peer.go +++ b/peer.go @@ -335,9 +335,9 @@ func (p *Peer) pushHandshake() error { // Pushes the list of outbound peers to the client when requested func (p *Peer) pushPeers() { - outPeers := make([]interface{}, len(p.ethereum.OutboundPeers())) + outPeers := make([]interface{}, len(p.ethereum.InOutPeers())) // Serialise each peer - for i, peer := range p.ethereum.OutboundPeers() { + for i, peer := range p.ethereum.InOutPeers() { outPeers[i] = peer.RlpData() } -- cgit v1.2.3 From 8c09602a8b6dead7e03d0d4b9fe61cbd02d8a844 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 31 Jan 2014 13:03:13 +0100 Subject: Self connect --- peer.go | 1 - 1 file changed, 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 410e310f5..2c442dc82 100644 --- a/peer.go +++ b/peer.go @@ -282,7 +282,6 @@ func (p *Peer) Start(seed bool) { peerHost, _, _ := net.SplitHostPort(p.conn.LocalAddr().String()) servHost, _, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) - log.Println(peerHost, servHost) if peerHost == servHost { log.Println("Connected to self") -- cgit v1.2.3 From ce69334988bb42e5dd1e6cb6c81d8d311babcf04 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 31 Jan 2014 13:37:16 +0100 Subject: For the testnet always 30303 for now to make it easy --- peer.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 2c442dc82..c4499a67f 100644 --- a/peer.go +++ b/peer.go @@ -374,19 +374,21 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { } func (p *Peer) RlpData() []interface{} { - host, prt, err := net.SplitHostPort(p.conn.RemoteAddr().String()) + host, _, err := net.SplitHostPort(p.conn.RemoteAddr().String()) if err != nil { return nil } + /* FIXME port, err := strconv.Atoi(prt) if err != nil { return nil } + */ //port := ethutil.NumberToBytes(uint16(i), 16) - return []interface{}{host, port} + return []interface{}{host, uint16(30303) /*port*/} } func (p *Peer) RlpEncode() []byte { -- cgit v1.2.3 From 8c4746a3dfed68603612bb0d702fe1f3aca1e26f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 31 Jan 2014 20:01:28 +0100 Subject: (un)pack addr --- peer.go | 120 ++++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 33 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index c4499a67f..c91df79db 100644 --- a/peer.go +++ b/peer.go @@ -7,6 +7,7 @@ import ( "log" "net" "strconv" + "strings" "sync/atomic" "time" ) @@ -16,6 +17,36 @@ const ( outputBufferSize = 50 ) +// Peer capabillities +type Caps byte + +const ( + CapDiscoveryTy = 0x01 + CapTxTy = 0x02 + CapChainTy = 0x04 +) + +var capsToString = map[Caps]string{ + CapDiscoveryTy: "Peer discovery", + CapTxTy: "Transaction relaying", + CapChainTy: "Block chain relaying", +} + +func (c Caps) String() string { + var caps []string + if c&CapDiscoveryTy > 0 { + caps = append(caps, capsToString[CapDiscoveryTy]) + } + if c&CapChainTy > 0 { + caps = append(caps, capsToString[CapChainTy]) + } + if c&CapTxTy > 0 { + caps = append(caps, capsToString[CapTxTy]) + } + + return strings.Join(caps, " | ") +} + type Peer struct { // Ethereum interface ethereum *Ethereum @@ -45,6 +76,10 @@ type Peer struct { // Determines whether this is a seed peer seed bool + + host []byte + port uint16 + caps Caps } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { @@ -56,6 +91,7 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { inbound: inbound, disconnect: 0, connected: 1, + port: 30303, } } @@ -223,7 +259,8 @@ out: peers := make([]string, data.Length()) // Parse each possible peer for i := 0; i < data.Length(); i++ { - peers[i] = data.Get(i).Get(0).AsString() + ":" + strconv.Itoa(int(data.Get(i).Get(1).AsUint())) + peers[i] = unpackAddr(data.Get(i).Get(0).AsBytes(), data.Get(i).Get(1).AsUint()) + log.Println(peers[i]) } // Connect to the list of peers @@ -277,20 +314,52 @@ out: p.Stop() } +func packAddr(address, port string) ([]byte, uint16) { + addr := strings.Split(address, ".") + a, _ := strconv.Atoi(addr[0]) + b, _ := strconv.Atoi(addr[1]) + c, _ := strconv.Atoi(addr[2]) + d, _ := strconv.Atoi(addr[3]) + host := []byte{byte(a), byte(b), byte(c), byte(d)} + prt, _ := strconv.Atoi(port) + + return host, uint16(prt) +} + +func unpackAddr(h []byte, p uint64) string { + if len(h) != 4 { + return "" + } + + a := strconv.Itoa(int(h[0])) + b := strconv.Itoa(int(h[1])) + c := strconv.Itoa(int(h[2])) + d := strconv.Itoa(int(h[3])) + host := strings.Join([]string{a, b, c, d}, ".") + port := strconv.Itoa(int(p)) + + return net.JoinHostPort(host, port) +} + func (p *Peer) Start(seed bool) { p.seed = seed - peerHost, _, _ := net.SplitHostPort(p.conn.LocalAddr().String()) - servHost, _, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) + peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String()) + servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) if peerHost == servHost { log.Println("Connected to self") - p.Stop() + //p.Stop() - return + //return + } + + if p.inbound { + p.host, p.port = packAddr(peerHost, peerPort) + } else { + p.host, p.port = packAddr(servHost, servPort) } - //if !p.inbound { err := p.pushHandshake() if err != nil { log.Printf("Peer can't send outbound version ack", err) @@ -299,7 +368,6 @@ func (p *Peer) Start(seed bool) { return } - //} // Run the outbound handler in a new goroutine go p.HandleOutbound() @@ -324,7 +392,7 @@ func (p *Peer) Stop() { func (p *Peer) pushHandshake() error { msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(0), uint32(0), "/Ethereum(G) v0.0.1/", + uint32(0), uint32(0), "/Ethereum(G) v0.0.1/", CapChainTy | CapTxTy | CapDiscoveryTy, p.port, }) p.QueueMessage(msg) @@ -354,41 +422,27 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { var istr string // If this is an inbound connection send an ack back if p.inbound { - /* - err := p.pushHandshake() - if err != nil { - log.Println("Peer can't send ack back") + if port := c.Get(4).AsUint(); port != 0 { + p.port = uint16(port) + } - p.Stop() - } - */ istr = "inbound" } else { - //msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)}) - //p.QueueMessage(msg) + msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)}) + p.QueueMessage(msg) istr = "outbound" } - log.Printf("peer connect (%s) %v %s\n", istr, p.conn.RemoteAddr(), c.Get(2).AsString()) -} - -func (p *Peer) RlpData() []interface{} { - host, _, err := net.SplitHostPort(p.conn.RemoteAddr().String()) - if err != nil { - return nil - } - - /* FIXME - port, err := strconv.Atoi(prt) - if err != nil { - return nil + if caps := Caps(c.Get(3).AsByte()); caps != 0 { + p.caps = caps } - */ - //port := ethutil.NumberToBytes(uint16(i), 16) + log.Printf("peer connect (%s) %v %s [%s]\n", istr, p.conn.RemoteAddr(), c.Get(2).AsString(), p.caps) +} - return []interface{}{host, uint16(30303) /*port*/} +func (p *Peer) RlpData() []interface{} { + return []interface{}{p.host, p.port /*port*/} } func (p *Peer) RlpEncode() []byte { -- cgit v1.2.3 From dfa778fed684e97f868aab9b246646156a39e24a Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sat, 1 Feb 2014 21:30:54 +0100 Subject: UPNP wip --- peer.go | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index c91df79db..5d22b545c 100644 --- a/peer.go +++ b/peer.go @@ -253,22 +253,21 @@ out: case ethwire.MsgPeersTy: // Received a list of peers (probably because MsgGetPeersTy was send) // Only act on message if we actually requested for a peers list - if p.requestedPeerList { - data := msg.Data - // Create new list of possible peers for the ethereum to process - peers := make([]string, data.Length()) - // Parse each possible peer - for i := 0; i < data.Length(); i++ { - peers[i] = unpackAddr(data.Get(i).Get(0).AsBytes(), data.Get(i).Get(1).AsUint()) - log.Println(peers[i]) - } + //if p.requestedPeerList { + data := msg.Data + // Create new list of possible peers for the ethereum to process + peers := make([]string, data.Length()) + // Parse each possible peer + for i := 0; i < data.Length(); i++ { + peers[i] = unpackAddr(data.Get(i).Get(0), data.Get(i).Get(1).AsUint()) + } - // Connect to the list of peers - p.ethereum.ProcessPeerList(peers) - // Mark unrequested again - p.requestedPeerList = false + // Connect to the list of peers + p.ethereum.ProcessPeerList(peers) + // Mark unrequested again + p.requestedPeerList = false - } + //} case ethwire.MsgGetChainTy: var parent *ethchain.Block // Length minus one since the very last element in the array is a count @@ -326,15 +325,11 @@ func packAddr(address, port string) ([]byte, uint16) { return host, uint16(prt) } -func unpackAddr(h []byte, p uint64) string { - if len(h) != 4 { - return "" - } - - a := strconv.Itoa(int(h[0])) - b := strconv.Itoa(int(h[1])) - c := strconv.Itoa(int(h[2])) - d := strconv.Itoa(int(h[3])) +func unpackAddr(value *ethutil.RlpValue, p uint64) string { + a := strconv.Itoa(int(value.Get(0).AsUint())) + b := strconv.Itoa(int(value.Get(1).AsUint())) + c := strconv.Itoa(int(value.Get(2).AsUint())) + d := strconv.Itoa(int(value.Get(3).AsUint())) host := strings.Join([]string{a, b, c, d}, ".") port := strconv.Itoa(int(p)) @@ -349,9 +344,9 @@ func (p *Peer) Start(seed bool) { if peerHost == servHost { log.Println("Connected to self") - //p.Stop() + p.Stop() - //return + return } if p.inbound { -- cgit v1.2.3 From cb8a7d979d1a4b2a32317ee0a77815ec2ea38b9f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 2 Feb 2014 16:15:39 +0100 Subject: upnp test --- peer.go | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 5d22b545c..a715e205d 100644 --- a/peer.go +++ b/peer.go @@ -24,6 +24,8 @@ const ( CapDiscoveryTy = 0x01 CapTxTy = 0x02 CapChainTy = 0x04 + + CapDefault = CapChainTy | CapTxTy | CapDiscoveryTy ) var capsToString = map[Caps]string{ @@ -95,7 +97,7 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { } } -func NewOutboundPeer(addr string, ethereum *Ethereum) *Peer { +func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { p := &Peer{ outputQueue: make(chan *ethwire.Msg, outputBufferSize), quit: make(chan bool), @@ -103,6 +105,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum) *Peer { inbound: false, connected: 0, disconnect: 0, + caps: caps, } // Set up the connection in another goroutine so we don't block the main thread @@ -165,7 +168,8 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { // Outbound message handler. Outbound messages are handled here func (p *Peer) HandleOutbound() { // The ping timer. Makes sure that every 2 minutes a ping is send to the peer - tickleTimer := time.NewTicker(2 * time.Minute) + pingTimer := time.NewTicker(2 * time.Minute) + serviceTimer := time.NewTicker(5 * time.Second) out: for { select { @@ -175,11 +179,20 @@ out: p.lastSend = time.Now() - case <-tickleTimer.C: + // Ping timer sends a ping to the peer each 2 minutes + case <-pingTimer.C: p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) - // Break out of the for loop if a quit message is posted + // Service timer takes care of peer broadcasting, transaction + // posting or block posting + case <-serviceTimer.C: + if p.caps&CapDiscoveryTy > 0 { + msg := p.peersMessage() + p.ethereum.BroadcastMsg(msg) + } + case <-p.quit: + // Break out of the for loop if a quit message is posted break out } } @@ -387,7 +400,7 @@ func (p *Peer) Stop() { func (p *Peer) pushHandshake() error { msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(0), uint32(0), "/Ethereum(G) v0.0.1/", CapChainTy | CapTxTy | CapDiscoveryTy, p.port, + uint32(0), uint32(0), "/Ethereum(G) v0.0.1/", p.caps, p.port, }) p.QueueMessage(msg) @@ -395,18 +408,20 @@ func (p *Peer) pushHandshake() error { return nil } -// Pushes the list of outbound peers to the client when requested -func (p *Peer) pushPeers() { +func (p *Peer) peersMessage() *ethwire.Msg { outPeers := make([]interface{}, len(p.ethereum.InOutPeers())) // Serialise each peer for i, peer := range p.ethereum.InOutPeers() { outPeers[i] = peer.RlpData() } - // Send message to the peer with the known list of connected clients - msg := ethwire.NewMessage(ethwire.MsgPeersTy, outPeers) + // Return the message to the peer with the known list of connected clients + return ethwire.NewMessage(ethwire.MsgPeersTy, outPeers) +} - p.QueueMessage(msg) +// Pushes the list of outbound peers to the client when requested +func (p *Peer) pushPeers() { + p.QueueMessage(p.peersMessage()) } func (p *Peer) handleHandshake(msg *ethwire.Msg) { -- cgit v1.2.3 From f4a96ca588a4c7e1382e9c2265ca306a5b0d0adf Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 2 Feb 2014 19:46:37 +0100 Subject: Removed the seed peer option from start --- peer.go | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index a715e205d..e9a8f6c03 100644 --- a/peer.go +++ b/peer.go @@ -76,9 +76,6 @@ type Peer struct { // this to prevent receiving false peers. requestedPeerList bool - // Determines whether this is a seed peer - seed bool - host []byte port uint16 caps Caps @@ -123,7 +120,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { atomic.StoreInt32(&p.connected, 1) atomic.StoreInt32(&p.disconnect, 0) - p.Start(false) + p.Start() }() return p @@ -155,14 +152,6 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { p.Stop() return } - - // XXX TMP CODE FOR TESTNET - switch msg.Type { - case ethwire.MsgPeersTy: - if p.seed { - p.Stop() - } - } } // Outbound message handler. Outbound messages are handled here @@ -349,9 +338,7 @@ func unpackAddr(value *ethutil.RlpValue, p uint64) string { return net.JoinHostPort(host, port) } -func (p *Peer) Start(seed bool) { - p.seed = seed - +func (p *Peer) Start() { peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String()) servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) if peerHost == servHost { -- cgit v1.2.3 From aa9341570b8e63c907c0f9d917508610c7daa1ae Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 2 Feb 2014 20:00:09 +0100 Subject: Disconnection reasons --- peer.go | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index e9a8f6c03..0f6afebfe 100644 --- a/peer.go +++ b/peer.go @@ -17,27 +17,53 @@ const ( outputBufferSize = 50 ) -// Peer capabillities +type DiscReason byte + +const ( + DiscReRequested = 0x00 + DiscReTcpSysErr = 0x01 + DiscBadProto = 0x02 + DiscBadPeer = 0x03 + DiscTooManyPeers = 0x04 +) + +var discReasonToString = []string{ + "Disconnect requested", + "Disconnect TCP sys error", + "Disconnect Bad protocol", + "Disconnect Useless peer", + "Disconnect Too many peers", +} + +func (d DiscReason) String() string { + if len(discReasonToString) > int(d) { + return "Unknown" + } + + return discReasonToString[d] +} + +// Peer capabilities type Caps byte const ( - CapDiscoveryTy = 0x01 - CapTxTy = 0x02 - CapChainTy = 0x04 + CapPeerDiscTy = 0x01 + CapTxTy = 0x02 + CapChainTy = 0x04 - CapDefault = CapChainTy | CapTxTy | CapDiscoveryTy + CapDefault = CapChainTy | CapTxTy | CapPeerDiscTy ) var capsToString = map[Caps]string{ - CapDiscoveryTy: "Peer discovery", - CapTxTy: "Transaction relaying", - CapChainTy: "Block chain relaying", + CapPeerDiscTy: "Peer discovery", + CapTxTy: "Transaction relaying", + CapChainTy: "Block chain relaying", } func (c Caps) String() string { var caps []string - if c&CapDiscoveryTy > 0 { - caps = append(caps, capsToString[CapDiscoveryTy]) + if c&CapPeerDiscTy > 0 { + caps = append(caps, capsToString[CapPeerDiscTy]) } if c&CapChainTy > 0 { caps = append(caps, capsToString[CapChainTy]) @@ -175,7 +201,7 @@ out: // Service timer takes care of peer broadcasting, transaction // posting or block posting case <-serviceTimer.C: - if p.caps&CapDiscoveryTy > 0 { + if p.caps&CapPeerDiscTy > 0 { msg := p.peersMessage() p.ethereum.BroadcastMsg(msg) } @@ -220,6 +246,7 @@ out: p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) case ethwire.MsgDiscTy: p.Stop() + log.Println("Disconnect peer:", DiscReason(msg.Data.Get(0).AsUint())) case ethwire.MsgPingTy: // Respond back with pong p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) @@ -381,8 +408,6 @@ func (p *Peer) Stop() { p.writeMessage(ethwire.NewMessage(ethwire.MsgDiscTy, "")) p.conn.Close() } - - log.Println("Peer shutdown") } func (p *Peer) pushHandshake() error { -- cgit v1.2.3 From 04b6e413d99c9d8c2fa4c06fa3e7822700209bc6 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 2 Feb 2014 20:06:37 +0100 Subject: Encode caps as byte --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 0f6afebfe..80cca50c0 100644 --- a/peer.go +++ b/peer.go @@ -184,7 +184,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { func (p *Peer) HandleOutbound() { // The ping timer. Makes sure that every 2 minutes a ping is send to the peer pingTimer := time.NewTicker(2 * time.Minute) - serviceTimer := time.NewTicker(5 * time.Second) + serviceTimer := time.NewTicker(5 * time.Minute) out: for { select { @@ -412,7 +412,7 @@ func (p *Peer) Stop() { func (p *Peer) pushHandshake() error { msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(0), uint32(0), "/Ethereum(G) v0.0.1/", p.caps, p.port, + uint32(0), uint32(0), "/Ethereum(G) v0.0.1/", byte(p.caps), p.port, }) p.QueueMessage(msg) -- cgit v1.2.3 From a9a564c226bae04bc1939baf44884e7cd69ee924 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 2 Feb 2014 20:54:13 +0100 Subject: removed self connect log --- peer.go | 2 -- 1 file changed, 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 80cca50c0..c67e407d1 100644 --- a/peer.go +++ b/peer.go @@ -369,8 +369,6 @@ func (p *Peer) Start() { peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String()) servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) if peerHost == servHost { - log.Println("Connected to self") - p.Stop() return -- cgit v1.2.3 From 6292c5ad5a649c9c9c3dbe403c46fff960604f09 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 3 Feb 2014 01:10:10 +0100 Subject: Transaction processing --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index c67e407d1..b4225998e 100644 --- a/peer.go +++ b/peer.go @@ -271,7 +271,7 @@ out: // in the TxPool where it will undergo validation and // processing when a new block is found for i := 0; i < msg.Data.Length(); i++ { - p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromRlpValue(msg.Data.Get(i))) + p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromData(ethutil.Encode(msg.Data.Get(i).AsRaw()))) } case ethwire.MsgGetPeersTy: // Flag this peer as a 'requested of new peers' this to -- cgit v1.2.3 From f995f5763bf58bc2455058fe40bd15a6aa46a65f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 3 Feb 2014 01:12:44 +0100 Subject: Properly encode tx --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index b4225998e..dc2427b32 100644 --- a/peer.go +++ b/peer.go @@ -271,7 +271,7 @@ out: // in the TxPool where it will undergo validation and // processing when a new block is found for i := 0; i < msg.Data.Length(); i++ { - p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromData(ethutil.Encode(msg.Data.Get(i).AsRaw()))) + p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromData(msg.Data.Get(i).Encode())) } case ethwire.MsgGetPeersTy: // Flag this peer as a 'requested of new peers' this to -- cgit v1.2.3 From 04c00f40f0c31e2c927d3a67e3e115a5cb5b539d Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 6 Feb 2014 13:27:57 +0100 Subject: Fixed value --- peer.go | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index dc2427b32..940d0eefe 100644 --- a/peer.go +++ b/peer.go @@ -60,15 +60,19 @@ var capsToString = map[Caps]string{ CapChainTy: "Block chain relaying", } +func (c Caps) IsCap(cap Caps) bool { + return c&cap > 0 +} + func (c Caps) String() string { var caps []string - if c&CapPeerDiscTy > 0 { + if c.IsCap(CapPeerDiscTy) { caps = append(caps, capsToString[CapPeerDiscTy]) } - if c&CapChainTy > 0 { + if c.IsCap(CapChainTy) { caps = append(caps, capsToString[CapChainTy]) } - if c&CapTxTy > 0 { + if c.IsCap(CapTxTy) { caps = append(caps, capsToString[CapTxTy]) } @@ -243,7 +247,9 @@ out: // Version message p.handleHandshake(msg) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) + if p.caps.IsCap(CapPeerDiscTy) { + p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) + } case ethwire.MsgDiscTy: p.Stop() log.Println("Disconnect peer:", DiscReason(msg.Data.Get(0).AsUint())) @@ -259,7 +265,8 @@ out: // Get all blocks and process them msg.Data = msg.Data for i := msg.Data.Length() - 1; i >= 0; i-- { - block := ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) + // FIXME + block := ethchain.NewBlockFromRlpValue(ethutil.NewValue(msg.Data.Get(i).AsRaw())) err := p.ethereum.BlockManager.ProcessBlock(block) if err != nil { @@ -302,7 +309,7 @@ out: // Length minus one since the very last element in the array is a count l := msg.Data.Length() - 1 // Ignore empty get chains - if l <= 1 { + if l == 0 { break } @@ -369,9 +376,9 @@ func (p *Peer) Start() { peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String()) servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) if peerHost == servHost { - p.Stop() + //p.Stop() - return + //return } if p.inbound { @@ -462,21 +469,5 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { } func (p *Peer) RlpData() []interface{} { - return []interface{}{p.host, p.port /*port*/} -} - -func (p *Peer) RlpEncode() []byte { - host, prt, err := net.SplitHostPort(p.conn.RemoteAddr().String()) - if err != nil { - return nil - } - - i, err := strconv.Atoi(prt) - if err != nil { - return nil - } - - port := ethutil.NumberToBytes(uint16(i), 16) - - return ethutil.Encode([]interface{}{host, port}) + return []interface{}{p.host, p.port} } -- cgit v1.2.3 From 24349bc431d6ac69520b325650b1128c9125faf0 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sat, 8 Feb 2014 21:02:42 +0100 Subject: Changed peer format --- peer.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 940d0eefe..9b57e9bbb 100644 --- a/peer.go +++ b/peer.go @@ -106,7 +106,7 @@ type Peer struct { // this to prevent receiving false peers. requestedPeerList bool - host []byte + host []interface{} port uint16 caps Caps } @@ -314,7 +314,8 @@ out: } // Amount of parents in the canonical chain - amountOfBlocks := msg.Data.Get(l).AsUint() + //amountOfBlocks := msg.Data.Get(l).AsUint() + amountOfBlocks := uint64(100) // Check each SHA block hash from the message and determine whether // the SHA is in the database for i := 0; i < l; i++ { @@ -326,8 +327,10 @@ out: // If a parent is found send back a reply if parent != nil { + log.Printf("HASH %x (len %d) Amount = %d)\n", parent.Hash(), l, amountOfBlocks) chain := p.ethereum.BlockManager.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, append(chain, amountOfBlocks))) + //log.Printf("%q\n", chain) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) } else { // If no blocks are found we send back a reply with msg not in chain // and the last hash from get chain @@ -349,13 +352,13 @@ out: p.Stop() } -func packAddr(address, port string) ([]byte, uint16) { +func packAddr(address, port string) ([]interface{}, uint16) { addr := strings.Split(address, ".") a, _ := strconv.Atoi(addr[0]) b, _ := strconv.Atoi(addr[1]) c, _ := strconv.Atoi(addr[2]) d, _ := strconv.Atoi(addr[3]) - host := []byte{byte(a), byte(b), byte(c), byte(d)} + host := []interface{}{byte(a), byte(b), byte(c), byte(d)} prt, _ := strconv.Atoi(port) return host, uint16(prt) @@ -417,7 +420,7 @@ func (p *Peer) Stop() { func (p *Peer) pushHandshake() error { msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(0), uint32(0), "/Ethereum(G) v0.0.1/", byte(p.caps), p.port, + uint32(1), uint32(0), "/Ethereum(G) v0.0.1/", byte(p.caps), p.port, }) p.QueueMessage(msg) -- cgit v1.2.3 From 0de31a389803d05fb7eef776cbba922f019b6d9d Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 9 Feb 2014 23:34:33 +0100 Subject: Fixed self connect through public key discovery. Bumped protocol version number --- peer.go | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 9b57e9bbb..6257e32a4 100644 --- a/peer.go +++ b/peer.go @@ -1,6 +1,7 @@ package eth import ( + "bytes" "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" "github.com/ethereum/ethwire-go" @@ -109,6 +110,8 @@ type Peer struct { host []interface{} port uint16 caps Caps + + pubkey []byte } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { @@ -125,6 +128,8 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { } func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { + pubkey, _ := ethutil.Config.Db.Get([]byte("Pubkey")) + p := &Peer{ outputQueue: make(chan *ethwire.Msg, outputBufferSize), quit: make(chan bool), @@ -133,6 +138,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { connected: 0, disconnect: 0, caps: caps, + pubkey: pubkey, } // Set up the connection in another goroutine so we don't block the main thread @@ -235,13 +241,12 @@ out: for atomic.LoadInt32(&p.disconnect) == 0 { // Wait for a message from the peer msgs, err := ethwire.ReadMessages(p.conn) - for _, msg := range msgs { - if err != nil { - log.Println(err) - - break out - } + if err != nil { + log.Println(err) + break out + } + for _, msg := range msgs { switch msg.Type { case ethwire.MsgHandshakeTy: // Version message @@ -327,9 +332,7 @@ out: // If a parent is found send back a reply if parent != nil { - log.Printf("HASH %x (len %d) Amount = %d)\n", parent.Hash(), l, amountOfBlocks) chain := p.ethereum.BlockManager.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) - //log.Printf("%q\n", chain) p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) } else { // If no blocks are found we send back a reply with msg not in chain @@ -378,10 +381,13 @@ func unpackAddr(value *ethutil.RlpValue, p uint64) string { func (p *Peer) Start() { peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String()) servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) - if peerHost == servHost { - //p.Stop() - //return + pubkey, _ := ethutil.Config.Db.Get([]byte("Pubkey")) + if bytes.Compare(pubkey, p.pubkey) == 0 { + log.Println("self connect") + p.Stop() + + return } if p.inbound { @@ -420,7 +426,7 @@ func (p *Peer) Stop() { func (p *Peer) pushHandshake() error { msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(1), uint32(0), "/Ethereum(G) v0.0.1/", byte(p.caps), p.port, + uint32(2), uint32(0), "/Ethereum(G) v0.0.1/", p.pubkey, byte(p.caps), p.port, }) p.QueueMessage(msg) @@ -446,15 +452,21 @@ func (p *Peer) pushPeers() { func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data + + if c.Get(0).AsUint() != 2 { + log.Println("Invalid peer version. Require protocol v 2") + p.Stop() + return + } + // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID] p.versionKnown = true var istr string // If this is an inbound connection send an ack back if p.inbound { - if port := c.Get(4).AsUint(); port != 0 { - p.port = uint16(port) - } + p.pubkey = c.Get(3).AsBytes() + p.port = uint16(c.Get(5).AsUint()) istr = "inbound" } else { @@ -464,13 +476,11 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { istr = "outbound" } - if caps := Caps(c.Get(3).AsByte()); caps != 0 { - p.caps = caps - } + p.caps = Caps(c.Get(4).AsByte()) log.Printf("peer connect (%s) %v %s [%s]\n", istr, p.conn.RemoteAddr(), c.Get(2).AsString(), p.caps) } func (p *Peer) RlpData() []interface{} { - return []interface{}{p.host, p.port} + return []interface{}{p.host, p.port, p.pubkey} } -- cgit v1.2.3 From c00b1dd508bb6ddcc25a70d6a9a3d40df0867ccb Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 9 Feb 2014 23:58:59 +0100 Subject: Self connect on handshake --- peer.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 6257e32a4..c5e0f9ac9 100644 --- a/peer.go +++ b/peer.go @@ -128,7 +128,8 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { } func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { - pubkey, _ := ethutil.Config.Db.Get([]byte("Pubkey")) + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() p := &Peer{ outputQueue: make(chan *ethwire.Msg, outputBufferSize), @@ -382,14 +383,6 @@ func (p *Peer) Start() { peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String()) servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) - pubkey, _ := ethutil.Config.Db.Get([]byte("Pubkey")) - if bytes.Compare(pubkey, p.pubkey) == 0 { - log.Println("self connect") - p.Stop() - - return - } - if p.inbound { p.host, p.port = packAddr(peerHost, peerPort) } else { @@ -468,6 +461,14 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.pubkey = c.Get(3).AsBytes() p.port = uint16(c.Get(5).AsUint()) + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() + if bytes.Compare(pubkey, p.pubkey) == 0 { + p.Stop() + + return + } + istr = "inbound" } else { msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)}) -- cgit v1.2.3 From 3c4fb01da36b0b0c0557bdc0a2b185ab8dcbbb4f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 10 Feb 2014 01:09:12 +0100 Subject: Version 3 and added added catch up --- peer.go | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index c5e0f9ac9..8d5a96d25 100644 --- a/peer.go +++ b/peer.go @@ -112,6 +112,9 @@ type Peer struct { caps Caps pubkey []byte + + // Indicated whether the node is catching up or not + catchingUp bool } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { @@ -240,6 +243,9 @@ func (p *Peer) HandleInbound() { out: for atomic.LoadInt32(&p.disconnect) == 0 { + // HMM? + time.Sleep(500 * time.Millisecond) + // Wait for a message from the peer msgs, err := ethwire.ReadMessages(p.conn) if err != nil { @@ -277,6 +283,11 @@ out: if err != nil { log.Println(err) + } else { + if p.catchingUp && msg.Data.Length() > 1 { + p.catchingUp = false + p.CatchupWithPeer() + } } } case ethwire.MsgTxTy: @@ -419,7 +430,7 @@ func (p *Peer) Stop() { func (p *Peer) pushHandshake() error { msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(2), uint32(0), "/Ethereum(G) v0.0.1/", p.pubkey, byte(p.caps), p.port, + uint32(3), uint32(0), "/Ethereum(G) v0.0.1/", byte(p.caps), p.port, p.pubkey, }) p.QueueMessage(msg) @@ -452,15 +463,16 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { return } - // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID] + // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID, CAPS, PORT, PUBKEY] p.versionKnown = true var istr string // If this is an inbound connection send an ack back if p.inbound { - p.pubkey = c.Get(3).AsBytes() - p.port = uint16(c.Get(5).AsUint()) + p.pubkey = c.Get(5).AsBytes() + p.port = uint16(c.Get(4).AsUint()) + // Self connect detection data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() if bytes.Compare(pubkey, p.pubkey) == 0 { @@ -471,17 +483,26 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { istr = "inbound" } else { - msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(100)}) - p.QueueMessage(msg) + p.CatchupWithPeer() istr = "outbound" } - p.caps = Caps(c.Get(4).AsByte()) + p.caps = Caps(c.Get(3).AsByte()) log.Printf("peer connect (%s) %v %s [%s]\n", istr, p.conn.RemoteAddr(), c.Get(2).AsString(), p.caps) } +func (p *Peer) CatchupWithPeer() { + if !p.catchingUp { + p.catchingUp = true + msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(50)}) + p.QueueMessage(msg) + + log.Printf("Requesting blockchain up from %x\n", p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash()) + } +} + func (p *Peer) RlpData() []interface{} { return []interface{}{p.host, p.port, p.pubkey} } -- cgit v1.2.3 From a50b4f6b11d9299366a8026588cddae65fdbd085 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 10 Feb 2014 01:15:14 +0100 Subject: Forgot to bump the version --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 8d5a96d25..9848095ca 100644 --- a/peer.go +++ b/peer.go @@ -457,7 +457,7 @@ func (p *Peer) pushPeers() { func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data - if c.Get(0).AsUint() != 2 { + if c.Get(0).AsUint() != 3 { log.Println("Invalid peer version. Require protocol v 2") p.Stop() return -- cgit v1.2.3 From 8db7d791f0cee0fdcf574a9bcf34467dc00e313e Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 10 Feb 2014 11:20:42 +0100 Subject: Corrected version number in error log --- peer.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 9848095ca..6c2d6c8b5 100644 --- a/peer.go +++ b/peer.go @@ -283,13 +283,14 @@ out: if err != nil { log.Println(err) - } else { - if p.catchingUp && msg.Data.Length() > 1 { - p.catchingUp = false - p.CatchupWithPeer() - } } } + + // If we're catching up, try to catch up further. + if p.catchingUp && msg.Data.Length() > 1 { + p.catchingUp = false + p.CatchupWithPeer() + } case ethwire.MsgTxTy: // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and @@ -458,7 +459,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data if c.Get(0).AsUint() != 3 { - log.Println("Invalid peer version. Require protocol v 2") + log.Println("Invalid peer version. Require protocol v3") p.Stop() return } -- cgit v1.2.3 From d2edc2bbf4641f3ca2ccf33e9014892d342ad021 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 10 Feb 2014 11:36:49 +0100 Subject: Added some loggers --- peer.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 6c2d6c8b5..e7be3bcb0 100644 --- a/peer.go +++ b/peer.go @@ -26,14 +26,20 @@ const ( DiscBadProto = 0x02 DiscBadPeer = 0x03 DiscTooManyPeers = 0x04 + DiscConnDup = 0x05 + DiscGenesisErr = 0x06 + DiscProtoErr = 0x07 ) var discReasonToString = []string{ "Disconnect requested", "Disconnect TCP sys error", - "Disconnect Bad protocol", - "Disconnect Useless peer", - "Disconnect Too many peers", + "Disconnect bad protocol", + "Disconnect useless peer", + "Disconnect too many peers", + "Disconnect already connected", + "Disconnect wrong genesis block", + "Disconnect incompatible network", } func (d DiscReason) String() string { @@ -241,7 +247,6 @@ clean: // Inbound handler. Inbound messages are received here and passed to the appropriate methods func (p *Peer) HandleInbound() { -out: for atomic.LoadInt32(&p.disconnect) == 0 { // HMM? time.Sleep(500 * time.Millisecond) @@ -250,8 +255,6 @@ out: msgs, err := ethwire.ReadMessages(p.conn) if err != nil { log.Println(err) - - break out } for _, msg := range msgs { switch msg.Type { @@ -276,9 +279,10 @@ out: case ethwire.MsgBlockTy: // Get all blocks and process them msg.Data = msg.Data + var block *ethchain.Block for i := msg.Data.Length() - 1; i >= 0; i-- { // FIXME - block := ethchain.NewBlockFromRlpValue(ethutil.NewValue(msg.Data.Get(i).AsRaw())) + block = ethchain.NewBlockFromRlpValue(ethutil.NewValue(msg.Data.Get(i).AsRaw())) err := p.ethereum.BlockManager.ProcessBlock(block) if err != nil { @@ -288,6 +292,10 @@ out: // If we're catching up, try to catch up further. if p.catchingUp && msg.Data.Length() > 1 { + if ethutil.Config.Debug { + blockInfo := p.ethereum.BlockManager.BlockChain().BlockInfo(block) + log.Printf("Synced to block height #%d\n", blockInfo.Number) + } p.catchingUp = false p.CatchupWithPeer() } @@ -500,7 +508,7 @@ func (p *Peer) CatchupWithPeer() { msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(50)}) p.QueueMessage(msg) - log.Printf("Requesting blockchain up from %x\n", p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash()) + log.Printf("Requesting blockchain %x...\n", p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash()[:4]) } } -- cgit v1.2.3 From 1d26ae2deaeb9e8995e923018db432eb64b764c5 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 10 Feb 2014 11:45:08 +0100 Subject: Changed client id --- peer.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index e7be3bcb0..04dd24e93 100644 --- a/peer.go +++ b/peer.go @@ -2,11 +2,13 @@ package eth import ( "bytes" + "fmt" "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" "github.com/ethereum/ethwire-go" "log" "net" + "runtime" "strconv" "strings" "sync/atomic" @@ -438,8 +440,9 @@ func (p *Peer) Stop() { } func (p *Peer) pushHandshake() error { + clientId := fmt.Sprintf("/Ethereum(G) v%s/%s", ethutil.Config.Ver, runtime.GOOS) msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(3), uint32(0), "/Ethereum(G) v0.0.1/", byte(p.caps), p.port, p.pubkey, + uint32(3), uint32(0), clientId, byte(p.caps), p.port, p.pubkey, }) p.QueueMessage(msg) -- cgit v1.2.3 From 8ab6c53231deb92db1fe46bab263b1e2b12a8fb5 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 10 Feb 2014 13:59:05 +0100 Subject: Reversed back --- peer.go | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 04dd24e93..c592f275f 100644 --- a/peer.go +++ b/peer.go @@ -1,7 +1,7 @@ package eth import ( - "bytes" + _ "bytes" "fmt" "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" @@ -139,8 +139,6 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { } func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() p := &Peer{ outputQueue: make(chan *ethwire.Msg, outputBufferSize), @@ -150,7 +148,6 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { connected: 0, disconnect: 0, caps: caps, - pubkey: pubkey, } // Set up the connection in another goroutine so we don't block the main thread @@ -283,7 +280,6 @@ func (p *Peer) HandleInbound() { msg.Data = msg.Data var block *ethchain.Block for i := msg.Data.Length() - 1; i >= 0; i-- { - // FIXME block = ethchain.NewBlockFromRlpValue(ethutil.NewValue(msg.Data.Get(i).AsRaw())) err := p.ethereum.BlockManager.ProcessBlock(block) @@ -440,9 +436,12 @@ func (p *Peer) Stop() { } func (p *Peer) pushHandshake() error { + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() + clientId := fmt.Sprintf("/Ethereum(G) v%s/%s", ethutil.Config.Ver, runtime.GOOS) msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(3), uint32(0), clientId, byte(p.caps), p.port, p.pubkey, + uint32(3), uint32(0), clientId, byte(p.caps), p.port, pubkey, }) p.QueueMessage(msg) @@ -485,13 +484,15 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.port = uint16(c.Get(4).AsUint()) // Self connect detection - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() - if bytes.Compare(pubkey, p.pubkey) == 0 { - p.Stop() + /* + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() + if bytes.Compare(pubkey, p.pubkey) == 0 { + p.Stop() - return - } + return + } + */ istr = "inbound" } else { -- cgit v1.2.3 From 42123b439683725b71bbec8ee9ec7443a1af1214 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 10 Feb 2014 16:41:36 +0100 Subject: Fixed peer handling --- peer.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index c592f275f..6ec3c7ee7 100644 --- a/peer.go +++ b/peer.go @@ -319,7 +319,8 @@ func (p *Peer) HandleInbound() { peers := make([]string, data.Length()) // Parse each possible peer for i := 0; i < data.Length(); i++ { - peers[i] = unpackAddr(data.Get(i).Get(0), data.Get(i).Get(1).AsUint()) + value := ethutil.NewValue(data.Get(i).AsRaw()) + peers[i] = unpackAddr(value.Get(0), value.Get(1).Uint()) } // Connect to the list of peers @@ -380,17 +381,17 @@ func packAddr(address, port string) ([]interface{}, uint16) { b, _ := strconv.Atoi(addr[1]) c, _ := strconv.Atoi(addr[2]) d, _ := strconv.Atoi(addr[3]) - host := []interface{}{byte(a), byte(b), byte(c), byte(d)} + host := []interface{}{int32(a), int32(b), int32(c), int32(d)} prt, _ := strconv.Atoi(port) return host, uint16(prt) } -func unpackAddr(value *ethutil.RlpValue, p uint64) string { - a := strconv.Itoa(int(value.Get(0).AsUint())) - b := strconv.Itoa(int(value.Get(1).AsUint())) - c := strconv.Itoa(int(value.Get(2).AsUint())) - d := strconv.Itoa(int(value.Get(3).AsUint())) +func unpackAddr(value *ethutil.Value, p uint64) string { + a := strconv.Itoa(int(value.Get(0).Uint())) + b := strconv.Itoa(int(value.Get(1).Uint())) + c := strconv.Itoa(int(value.Get(2).Uint())) + d := strconv.Itoa(int(value.Get(3).Uint())) host := strings.Join([]string{a, b, c, d}, ".") port := strconv.Itoa(int(p)) -- cgit v1.2.3 From 02acef23d595dc2bc95295bab63658addf664aaf Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 11 Feb 2014 18:46:28 +0100 Subject: Interop! --- peer.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 6ec3c7ee7..5bfec1758 100644 --- a/peer.go +++ b/peer.go @@ -204,6 +204,7 @@ func (p *Peer) HandleOutbound() { // The ping timer. Makes sure that every 2 minutes a ping is send to the peer pingTimer := time.NewTicker(2 * time.Minute) serviceTimer := time.NewTicker(5 * time.Minute) + out: for { select { @@ -442,7 +443,7 @@ func (p *Peer) pushHandshake() error { clientId := fmt.Sprintf("/Ethereum(G) v%s/%s", ethutil.Config.Ver, runtime.GOOS) msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(3), uint32(0), clientId, byte(p.caps), p.port, pubkey, + uint32(4), uint32(0), clientId, byte(p.caps), p.port, pubkey, }) p.QueueMessage(msg) @@ -469,8 +470,8 @@ func (p *Peer) pushPeers() { func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data - if c.Get(0).AsUint() != 3 { - log.Println("Invalid peer version. Require protocol v3") + if c.Get(0).AsUint() != 4 { + log.Println("Invalid peer version. Require protocol v4") p.Stop() return } -- cgit v1.2.3 From 67de76c217f4ff4f2111e5f578b35fb162d64916 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 11 Feb 2014 20:09:58 +0100 Subject: Put leveldb --- peer.go | 2 ++ 1 file changed, 2 insertions(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 5bfec1758..3c36dfc58 100644 --- a/peer.go +++ b/peer.go @@ -496,6 +496,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { } */ + p.CatchupWithPeer() + istr = "inbound" } else { p.CatchupWithPeer() -- cgit v1.2.3 From c2fb9f06ad018d01ce335c82b3542de16045a32d Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 13 Feb 2014 15:12:16 +0100 Subject: Refactoring RlpValue => Value --- peer.go | 123 +++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 80 insertions(+), 43 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 3c36dfc58..cdb3bfcf5 100644 --- a/peer.go +++ b/peer.go @@ -1,7 +1,7 @@ package eth import ( - _ "bytes" + "bytes" "fmt" "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" @@ -123,9 +123,14 @@ type Peer struct { // Indicated whether the node is catching up or not catchingUp bool + + Version string } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() + return &Peer{ outputQueue: make(chan *ethwire.Msg, outputBufferSize), quit: make(chan bool), @@ -135,6 +140,7 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { disconnect: 0, connected: 1, port: 30303, + pubkey: pubkey, } } @@ -148,6 +154,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { connected: 0, disconnect: 0, caps: caps, + Version: fmt.Sprintf("/Ethereum(G) v%s/%s", ethutil.Config.Ver, runtime.GOOS), } // Set up the connection in another goroutine so we don't block the main thread @@ -267,7 +274,7 @@ func (p *Peer) HandleInbound() { } case ethwire.MsgDiscTy: p.Stop() - log.Println("Disconnect peer:", DiscReason(msg.Data.Get(0).AsUint())) + log.Println("Disconnect peer:", DiscReason(msg.Data.Get(0).Uint())) case ethwire.MsgPingTy: // Respond back with pong p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) @@ -279,30 +286,47 @@ func (p *Peer) HandleInbound() { case ethwire.MsgBlockTy: // Get all blocks and process them msg.Data = msg.Data - var block *ethchain.Block - for i := msg.Data.Length() - 1; i >= 0; i-- { - block = ethchain.NewBlockFromRlpValue(ethutil.NewValue(msg.Data.Get(i).AsRaw())) - err := p.ethereum.BlockManager.ProcessBlock(block) + var block, lastBlock *ethchain.Block + var err error + for i := msg.Data.Len() - 1; i >= 0; i-- { + block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) + err = p.ethereum.BlockManager.ProcessBlock(block) if err != nil { log.Println(err) + break + } else { + lastBlock = block } } - // If we're catching up, try to catch up further. - if p.catchingUp && msg.Data.Length() > 1 { - if ethutil.Config.Debug { - blockInfo := p.ethereum.BlockManager.BlockChain().BlockInfo(block) - log.Printf("Synced to block height #%d\n", blockInfo.Number) + if err != nil { + // If the parent is unknown try to catch up with this peer + if ethchain.IsParentErr(err) { + log.Println("Attempting to catch up") + p.catchingUp = false + p.CatchupWithPeer() + } + if ethchain.IsValidationErr(err) { + // TODO + } + } else { + // XXX Do we want to catch up if there were errors? + // If we're catching up, try to catch up further. + if p.catchingUp && msg.Data.Len() > 1 { + if ethutil.Config.Debug && lastBlock != nil { + blockInfo := lastBlock.BlockInfo() + log.Printf("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) + } + p.catchingUp = false + p.CatchupWithPeer() } - p.catchingUp = false - p.CatchupWithPeer() } case ethwire.MsgTxTy: // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and // processing when a new block is found - for i := 0; i < msg.Data.Length(); i++ { + for i := 0; i < msg.Data.Len(); i++ { p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromData(msg.Data.Get(i).Encode())) } case ethwire.MsgGetPeersTy: @@ -317,10 +341,10 @@ func (p *Peer) HandleInbound() { //if p.requestedPeerList { data := msg.Data // Create new list of possible peers for the ethereum to process - peers := make([]string, data.Length()) + peers := make([]string, data.Len()) // Parse each possible peer - for i := 0; i < data.Length(); i++ { - value := ethutil.NewValue(data.Get(i).AsRaw()) + for i := 0; i < data.Len(); i++ { + value := data.Get(i) peers[i] = unpackAddr(value.Get(0), value.Get(1).Uint()) } @@ -333,7 +357,7 @@ func (p *Peer) HandleInbound() { case ethwire.MsgGetChainTy: var parent *ethchain.Block // Length minus one since the very last element in the array is a count - l := msg.Data.Length() - 1 + l := msg.Data.Len() - 1 // Ignore empty get chains if l == 0 { break @@ -345,7 +369,7 @@ func (p *Peer) HandleInbound() { // Check each SHA block hash from the message and determine whether // the SHA is in the database for i := 0; i < l; i++ { - if data := msg.Data.Get(i).AsBytes(); p.ethereum.BlockManager.BlockChain().HasBlock(data) { + if data := msg.Data.Get(i).Bytes(); p.ethereum.BlockManager.BlockChain().HasBlock(data) { parent = p.ethereum.BlockManager.BlockChain().GetBlock(data) break } @@ -359,8 +383,8 @@ func (p *Peer) HandleInbound() { // If no blocks are found we send back a reply with msg not in chain // and the last hash from get chain lastHash := msg.Data.Get(l - 1) - log.Printf("Sending not in chain with hash %x\n", lastHash.AsRaw()) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, []interface{}{lastHash.AsRaw()})) + //log.Printf("Sending not in chain with hash %x\n", lastHash.AsRaw()) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, []interface{}{lastHash.Raw()})) } case ethwire.MsgNotInChainTy: log.Printf("Not in chain %x\n", msg.Data) @@ -368,7 +392,7 @@ func (p *Peer) HandleInbound() { // Unofficial but fun nonetheless case ethwire.MsgTalkTy: - log.Printf("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.AsString()) + log.Printf("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.Str()) } } } @@ -441,9 +465,8 @@ func (p *Peer) pushHandshake() error { data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() - clientId := fmt.Sprintf("/Ethereum(G) v%s/%s", ethutil.Config.Ver, runtime.GOOS) msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(4), uint32(0), clientId, byte(p.caps), p.port, pubkey, + uint32(4), uint32(0), p.Version, byte(p.caps), p.port, pubkey, }) p.QueueMessage(msg) @@ -470,7 +493,7 @@ func (p *Peer) pushPeers() { func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data - if c.Get(0).AsUint() != 4 { + if c.Get(0).Uint() != 4 { log.Println("Invalid peer version. Require protocol v4") p.Stop() return @@ -479,35 +502,49 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID, CAPS, PORT, PUBKEY] p.versionKnown = true - var istr string // If this is an inbound connection send an ack back if p.inbound { - p.pubkey = c.Get(5).AsBytes() - p.port = uint16(c.Get(4).AsUint()) + p.pubkey = c.Get(5).Bytes() + p.port = uint16(c.Get(4).Uint()) // Self connect detection - /* - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() - if bytes.Compare(pubkey, p.pubkey) == 0 { - p.Stop() + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() + if bytes.Compare(pubkey, p.pubkey) == 0 { + p.Stop() - return - } - */ + return + } + + } - p.CatchupWithPeer() + // Catch up with the connected peer + p.CatchupWithPeer() - istr = "inbound" - } else { - p.CatchupWithPeer() + // Set the peer's caps + p.caps = Caps(c.Get(3).Byte()) + // Get a reference to the peers version + p.Version = c.Get(2).Str() - istr = "outbound" + log.Println(p) +} + +func (p *Peer) String() string { + var strBoundType string + if p.inbound { + strBoundType = "inbound" + } else { + strBoundType = "outbound" + } + var strConnectType string + if atomic.LoadInt32(&p.disconnect) == 0 { + strConnectType = "connected" + } else { + strConnectType = "disconnected" } - p.caps = Caps(c.Get(3).AsByte()) + return fmt.Sprintf("peer [%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.Version, p.caps) - log.Printf("peer connect (%s) %v %s [%s]\n", istr, p.conn.RemoteAddr(), c.Get(2).AsString(), p.caps) } func (p *Peer) CatchupWithPeer() { -- cgit v1.2.3 From f6d1bfe45bf3709d7bad40bf563b5c09228622e3 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 14 Feb 2014 23:56:09 +0100 Subject: The great merge --- peer.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index cdb3bfcf5..7b17b8b09 100644 --- a/peer.go +++ b/peer.go @@ -3,9 +3,9 @@ package eth import ( "bytes" "fmt" - "github.com/ethereum/ethchain-go" - "github.com/ethereum/ethutil-go" - "github.com/ethereum/ethwire-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethwire" "log" "net" "runtime" @@ -293,7 +293,7 @@ func (p *Peer) HandleInbound() { err = p.ethereum.BlockManager.ProcessBlock(block) if err != nil { - log.Println(err) + log.Println("bckmsg", err) break } else { lastBlock = block @@ -306,8 +306,7 @@ func (p *Peer) HandleInbound() { log.Println("Attempting to catch up") p.catchingUp = false p.CatchupWithPeer() - } - if ethchain.IsValidationErr(err) { + } else if ethchain.IsValidationErr(err) { // TODO } } else { -- cgit v1.2.3 From e5b97fe03e8789bf4e113946a1935c0ba270ad2b Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 16 Feb 2014 20:33:23 +0100 Subject: Added proper error message --- peer.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 7b17b8b09..926d34eb3 100644 --- a/peer.go +++ b/peer.go @@ -293,7 +293,9 @@ func (p *Peer) HandleInbound() { err = p.ethereum.BlockManager.ProcessBlock(block) if err != nil { - log.Println("bckmsg", err) + if ethutil.Config.Debug { + log.Printf("[PEER] Block (%x) err %v", block.Hash()[:4], err) + } break } else { lastBlock = block -- cgit v1.2.3 From c7623c31650d078184511be796f7a00dde2a25a1 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 18 Feb 2014 01:32:39 +0100 Subject: Changed debug messages --- peer.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 926d34eb3..53fdfa8fc 100644 --- a/peer.go +++ b/peer.go @@ -294,7 +294,9 @@ func (p *Peer) HandleInbound() { if err != nil { if ethutil.Config.Debug { - log.Printf("[PEER] Block (%x) err %v", block.Hash()[:4], err) + log.Printf("[PEER] Block %x failed\n", block.Hash()) + log.Printf("[PEER] %v\n", err) + log.Println(block) } break } else { @@ -467,7 +469,7 @@ func (p *Peer) pushHandshake() error { pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(4), uint32(0), p.Version, byte(p.caps), p.port, pubkey, + uint32(5), uint32(0), p.Version, byte(p.caps), p.port, pubkey, }) p.QueueMessage(msg) @@ -494,7 +496,7 @@ func (p *Peer) pushPeers() { func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data - if c.Get(0).Uint() != 4 { + if c.Get(0).Uint() != 5 { log.Println("Invalid peer version. Require protocol v4") p.Stop() return @@ -527,7 +529,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { // Get a reference to the peers version p.Version = c.Get(2).Str() - log.Println(p) + log.Println("[PEER]", p) } func (p *Peer) String() string { @@ -544,7 +546,7 @@ func (p *Peer) String() string { strConnectType = "disconnected" } - return fmt.Sprintf("peer [%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.Version, p.caps) + return fmt.Sprintf("[%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.Version, p.caps) } -- cgit v1.2.3 From 6dac014978d30883aa556c004f948e66a314d2de Mon Sep 17 00:00:00 2001 From: Sam Boyer <tech@samboyer.org> Date: Tue, 18 Feb 2014 10:47:09 -0500 Subject: Fix a couple errors from go vet --- peer.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 53fdfa8fc..95b526c67 100644 --- a/peer.go +++ b/peer.go @@ -285,7 +285,6 @@ func (p *Peer) HandleInbound() { p.lastPong = time.Now().Unix() case ethwire.MsgBlockTy: // Get all blocks and process them - msg.Data = msg.Data var block, lastBlock *ethchain.Block var err error for i := msg.Data.Len() - 1; i >= 0; i-- { @@ -438,7 +437,7 @@ func (p *Peer) Start() { err := p.pushHandshake() if err != nil { - log.Printf("Peer can't send outbound version ack", err) + log.Println("Peer can't send outbound version ack", err) p.Stop() -- cgit v1.2.3 From 5adbd399463edc5ec800bdcf3524d64313c8add5 Mon Sep 17 00:00:00 2001 From: Sam Boyer <tech@samboyer.org> Date: Tue, 18 Feb 2014 17:20:41 -0500 Subject: Express bit flag constants using iota bitshift. --- peer.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 53fdfa8fc..e64b5b3bd 100644 --- a/peer.go +++ b/peer.go @@ -56,9 +56,9 @@ func (d DiscReason) String() string { type Caps byte const ( - CapPeerDiscTy = 0x01 - CapTxTy = 0x02 - CapChainTy = 0x04 + CapPeerDiscTy = 1 << iota + CapTxTy + CapChainTy CapDefault = CapChainTy | CapTxTy | CapPeerDiscTy ) -- cgit v1.2.3 From 357b4bc14c82d206a8c813291fb3ead01ed29041 Mon Sep 17 00:00:00 2001 From: Sam Boyer <tech@samboyer.org> Date: Tue, 18 Feb 2014 17:24:44 -0500 Subject: Add comment explaining why iota is not used. --- peer.go | 3 +++ 1 file changed, 3 insertions(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index e64b5b3bd..a6481e10c 100644 --- a/peer.go +++ b/peer.go @@ -23,6 +23,9 @@ const ( type DiscReason byte const ( + // Values are given explicitly instead of by iota because these values are + // defined by the wire protocol spec; it is easier for humans to ensure + // correctness when values are explicit. DiscReRequested = 0x00 DiscReTcpSysErr = 0x01 DiscBadProto = 0x02 -- cgit v1.2.3 From 73b9ae95797ce8c38d82cfcb7c793efea268f476 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sat, 22 Feb 2014 01:53:25 +0100 Subject: Updated some of the log statements to use the ethutil logger --- peer.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ed81ddd8e..9538e6500 100644 --- a/peer.go +++ b/peer.go @@ -6,7 +6,6 @@ import ( "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethwire" - "log" "net" "runtime" "strconv" @@ -165,7 +164,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { conn, err := net.DialTimeout("tcp", addr, 30*time.Second) if err != nil { - log.Println("Connection to peer failed", err) + ethutil.Config.Log.Debugln("Connection to peer failed", err) p.Stop() return } @@ -202,7 +201,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { err := ethwire.WriteMessage(p.conn, msg) if err != nil { - log.Println("Can't send message:", err) + ethutil.Config.Log.Debugln("Can't send message:", err) // Stop the client if there was an error writing to it p.Stop() return @@ -264,7 +263,7 @@ func (p *Peer) HandleInbound() { // Wait for a message from the peer msgs, err := ethwire.ReadMessages(p.conn) if err != nil { - log.Println(err) + ethutil.Config.Log.Debugln(err) } for _, msg := range msgs { switch msg.Type { @@ -277,7 +276,7 @@ func (p *Peer) HandleInbound() { } case ethwire.MsgDiscTy: p.Stop() - log.Println("Disconnect peer:", DiscReason(msg.Data.Get(0).Uint())) + ethutil.Config.Log.Infoln("Disconnect peer:", DiscReason(msg.Data.Get(0).Uint())) case ethwire.MsgPingTy: // Respond back with pong p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) @@ -296,9 +295,8 @@ func (p *Peer) HandleInbound() { if err != nil { if ethutil.Config.Debug { - log.Printf("[PEER] Block %x failed\n", block.Hash()) - log.Printf("[PEER] %v\n", err) - log.Println(block) + ethutil.Config.Log.Infof("[PEER] Block %x failed\n", block.Hash()) + ethutil.Config.Log.Infof("[PEER] %v\n", err) } break } else { @@ -309,7 +307,7 @@ func (p *Peer) HandleInbound() { if err != nil { // If the parent is unknown try to catch up with this peer if ethchain.IsParentErr(err) { - log.Println("Attempting to catch up") + ethutil.Config.Log.Infoln("Attempting to catch up") p.catchingUp = false p.CatchupWithPeer() } else if ethchain.IsValidationErr(err) { @@ -321,7 +319,7 @@ func (p *Peer) HandleInbound() { if p.catchingUp && msg.Data.Len() > 1 { if ethutil.Config.Debug && lastBlock != nil { blockInfo := lastBlock.BlockInfo() - log.Printf("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) + ethutil.Config.Log.Infof("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) } p.catchingUp = false p.CatchupWithPeer() @@ -392,12 +390,12 @@ func (p *Peer) HandleInbound() { p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, []interface{}{lastHash.Raw()})) } case ethwire.MsgNotInChainTy: - log.Printf("Not in chain %x\n", msg.Data) + ethutil.Config.Log.Infoln("Not in chain %x\n", msg.Data) // TODO // Unofficial but fun nonetheless case ethwire.MsgTalkTy: - log.Printf("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.Str()) + ethutil.Config.Log.Infoln("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.Str()) } } } @@ -440,7 +438,7 @@ func (p *Peer) Start() { err := p.pushHandshake() if err != nil { - log.Println("Peer can't send outbound version ack", err) + ethutil.Config.Log.Debugln("Peer can't send outbound version ack", err) p.Stop() @@ -499,7 +497,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data if c.Get(0).Uint() != 5 { - log.Println("Invalid peer version. Require protocol v4") + ethutil.Config.Log.Debugln("Invalid peer version. Require protocol v5") p.Stop() return } @@ -531,7 +529,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { // Get a reference to the peers version p.Version = c.Get(2).Str() - log.Println("[PEER]", p) + ethutil.Config.Log.Debugln("[PEER]", p) } func (p *Peer) String() string { @@ -558,7 +556,7 @@ func (p *Peer) CatchupWithPeer() { msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(50)}) p.QueueMessage(msg) - log.Printf("Requesting blockchain %x...\n", p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash()[:4]) + ethutil.Config.Log.Debugln("Requesting blockchain %x...\n", p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash()[:4]) } } -- cgit v1.2.3 From 22e2c3429bee515f69250dfdddc419a389e8ccd6 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 24 Feb 2014 12:12:53 +0100 Subject: Infof rather than infoln --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 9538e6500..a8708206f 100644 --- a/peer.go +++ b/peer.go @@ -390,7 +390,7 @@ func (p *Peer) HandleInbound() { p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, []interface{}{lastHash.Raw()})) } case ethwire.MsgNotInChainTy: - ethutil.Config.Log.Infoln("Not in chain %x\n", msg.Data) + ethutil.Config.Log.Infof("Not in chain %x\n", msg.Data) // TODO // Unofficial but fun nonetheless @@ -556,7 +556,7 @@ func (p *Peer) CatchupWithPeer() { msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(50)}) p.QueueMessage(msg) - ethutil.Config.Log.Debugln("Requesting blockchain %x...\n", p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash()[:4]) + ethutil.Config.Log.Debugf("Requesting blockchain %x...\n", p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash()[:4]) } } -- cgit v1.2.3 From 601340bd464e3ebae0e4fa3407be5fff3bb3fcbf Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 28 Feb 2014 16:45:29 +0100 Subject: Fixed shutting down --- peer.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index a8708206f..970619714 100644 --- a/peer.go +++ b/peer.go @@ -511,9 +511,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.port = uint16(c.Get(4).Uint()) // Self connect detection - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() - if bytes.Compare(pubkey, p.pubkey) == 0 { + key := ethutil.Config.Db.GetKeys()[0] + if bytes.Compare(key.PublicKey, p.pubkey) == 0 { p.Stop() return -- cgit v1.2.3 From c1d0ea7366f1bad134c985dbe1f272d376e5ec9b Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 3 Mar 2014 11:34:04 +0100 Subject: Updated protocol version to 7 --- peer.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 970619714..271c8708e 100644 --- a/peer.go +++ b/peer.go @@ -17,6 +17,8 @@ import ( const ( // The size of the output buffer for writing messages outputBufferSize = 50 + // Current protocol version + ProtocolVersion = 7 ) type DiscReason byte @@ -469,7 +471,7 @@ func (p *Peer) pushHandshake() error { pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(5), uint32(0), p.Version, byte(p.caps), p.port, pubkey, + uint32(ProtocolVersion), uint32(0), p.Version, byte(p.caps), p.port, pubkey, }) p.QueueMessage(msg) @@ -496,7 +498,7 @@ func (p *Peer) pushPeers() { func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data - if c.Get(0).Uint() != 5 { + if c.Get(0).Uint() != ProtocolVersion { ethutil.Config.Log.Debugln("Invalid peer version. Require protocol v5") p.Stop() return -- cgit v1.2.3 From 92f2abdf769f52ea8e5e6d02bf326744e926f5b4 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 5 Mar 2014 10:42:51 +0100 Subject: Partially refactored server/txpool/block manager/block chain The Ethereum structure now complies to a EthManager interface which is being used by the tx pool, block manager and block chain in order to gain access to each other. It's become simpeler. TODO: BlockManager => StateManager --- peer.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 271c8708e..22a4c32fd 100644 --- a/peer.go +++ b/peer.go @@ -18,7 +18,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 7 + ProtocolVersion = 8 ) type DiscReason byte @@ -49,7 +49,7 @@ var discReasonToString = []string{ } func (d DiscReason) String() string { - if len(discReasonToString) > int(d) { + if len(discReasonToString) < int(d) { return "Unknown" } @@ -293,7 +293,8 @@ func (p *Peer) HandleInbound() { var err error for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) - err = p.ethereum.BlockManager.ProcessBlock(block) + // FIXME p.ethereum.BlockManager.DefaultPrepare(block) + err = p.ethereum.StateManager().ProcessBlock(block) if err != nil { if ethutil.Config.Debug { @@ -332,7 +333,7 @@ func (p *Peer) HandleInbound() { // in the TxPool where it will undergo validation and // processing when a new block is found for i := 0; i < msg.Data.Len(); i++ { - p.ethereum.TxPool.QueueTransaction(ethchain.NewTransactionFromData(msg.Data.Get(i).Encode())) + p.ethereum.TxPool().QueueTransaction(ethchain.NewTransactionFromData(msg.Data.Get(i).Encode())) } case ethwire.MsgGetPeersTy: // Flag this peer as a 'requested of new peers' this to @@ -374,15 +375,16 @@ func (p *Peer) HandleInbound() { // Check each SHA block hash from the message and determine whether // the SHA is in the database for i := 0; i < l; i++ { - if data := msg.Data.Get(i).Bytes(); p.ethereum.BlockManager.BlockChain().HasBlock(data) { - parent = p.ethereum.BlockManager.BlockChain().GetBlock(data) + if data := + msg.Data.Get(i).Bytes(); p.ethereum.StateManager().BlockChain().HasBlock(data) { + parent = p.ethereum.BlockChain().GetBlock(data) break } } // If a parent is found send back a reply if parent != nil { - chain := p.ethereum.BlockManager.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) + chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) } else { // If no blocks are found we send back a reply with msg not in chain @@ -554,10 +556,10 @@ func (p *Peer) String() string { func (p *Peer) CatchupWithPeer() { if !p.catchingUp { p.catchingUp = true - msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash(), uint64(50)}) + msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockChain().CurrentBlock.Hash(), uint64(50)}) p.QueueMessage(msg) - ethutil.Config.Log.Debugf("Requesting blockchain %x...\n", p.ethereum.BlockManager.BlockChain().CurrentBlock.Hash()[:4]) + ethutil.Config.Log.Debugf("Requesting blockchain %x...\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4]) } } -- cgit v1.2.3 From b15a4985e89b1fbf67731bde2e4cef45b3fdf347 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 17 Mar 2014 10:33:03 +0100 Subject: Moved on to the state manager --- peer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 22a4c32fd..89b567fb6 100644 --- a/peer.go +++ b/peer.go @@ -293,7 +293,8 @@ func (p *Peer) HandleInbound() { var err error for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) - // FIXME p.ethereum.BlockManager.DefaultPrepare(block) + + p.ethereum.StateManager().PrepareDefault(block) err = p.ethereum.StateManager().ProcessBlock(block) if err != nil { -- cgit v1.2.3 From 2b9b02812e9c6f81b9e5422d5bd4f5ea425412df Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 17 Mar 2014 11:14:00 +0100 Subject: Log --- peer.go | 1 + 1 file changed, 1 insertion(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 89b567fb6..4e927ada4 100644 --- a/peer.go +++ b/peer.go @@ -301,6 +301,7 @@ func (p *Peer) HandleInbound() { if ethutil.Config.Debug { ethutil.Config.Log.Infof("[PEER] Block %x failed\n", block.Hash()) ethutil.Config.Log.Infof("[PEER] %v\n", err) + ethutil.Config.Log.Infoln(block) } break } else { -- cgit v1.2.3 From 344e827061c896a17124a65686bdc3fbbd03d7bb Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 17 Mar 2014 12:08:16 +0100 Subject: Added client string to configuration Clients can set their own client string which will be send to connected peers during the handshake. --- peer.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4e927ada4..24a5e97c9 100644 --- a/peer.go +++ b/peer.go @@ -7,7 +7,6 @@ import ( "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethwire" "net" - "runtime" "strconv" "strings" "sync/atomic" @@ -158,7 +157,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { connected: 0, disconnect: 0, caps: caps, - Version: fmt.Sprintf("/Ethereum(G) v%s/%s", ethutil.Config.Ver, runtime.GOOS), + Version: ethutil.Config.ClientString, } // Set up the connection in another goroutine so we don't block the main thread -- cgit v1.2.3 From ae837c4719855384921fcaadb1a575942dc9833d Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Thu, 20 Mar 2014 11:20:29 +0100 Subject: More mining rework --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4e927ada4..6b914710d 100644 --- a/peer.go +++ b/peer.go @@ -295,7 +295,7 @@ func (p *Peer) HandleInbound() { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) p.ethereum.StateManager().PrepareDefault(block) - err = p.ethereum.StateManager().ProcessBlock(block) + err = p.ethereum.StateManager().ProcessBlock(block, true) if err != nil { if ethutil.Config.Debug { -- cgit v1.2.3 From b52b1fca89fd56549ecc0f086d96a39d6009e568 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Fri, 21 Mar 2014 15:06:23 +0100 Subject: Initial block reorganisation code --- peer.go | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 100 insertions(+), 19 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 6b914710d..2cc940400 100644 --- a/peer.go +++ b/peer.go @@ -126,7 +126,8 @@ type Peer struct { pubkey []byte // Indicated whether the node is catching up or not - catchingUp bool + catchingUp bool + blocksRequested int Version string } @@ -136,15 +137,16 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() return &Peer{ - outputQueue: make(chan *ethwire.Msg, outputBufferSize), - quit: make(chan bool), - ethereum: ethereum, - conn: conn, - inbound: inbound, - disconnect: 0, - connected: 1, - port: 30303, - pubkey: pubkey, + outputQueue: make(chan *ethwire.Msg, outputBufferSize), + quit: make(chan bool), + ethereum: ethereum, + conn: conn, + inbound: inbound, + disconnect: 0, + connected: 1, + port: 30303, + pubkey: pubkey, + blocksRequested: 10, } } @@ -291,11 +293,62 @@ func (p *Peer) HandleInbound() { // Get all blocks and process them var block, lastBlock *ethchain.Block var err error + + // 1. Compare the first block over the wire's prev-hash with the hash of your last block + // 2. If these two values are the same you can just link the chains together. + // [1:0,2:1,3:2] <- Current blocks (format block:previous_block) + // [1:0,2:1,3:2,4:3,5:4] <- incoming blocks + // == [1,2,3,4,5] + // 3. If the values are not the same we will have to go back and calculate the chain with the highest total difficulty + // [1:0,2:1,3:2,11:3,12:11,13:12] + // [1:0,2:1,3:2,4:3,5:4,6:5] + + // [3:2,11:3,12:11,13:12] + // [3:2,4:3,5:4,6:5] + // Heb ik dit blok? + // Nee: heb ik een blok met PrevHash 3? + // Ja: DIVERSION + // Nee; Adding to chain + + // See if we can find a common ancestor + // 1. Get the earliest block in the package. + // 2. Do we have this block? + // 3. Yes: Let's continue what we are doing + // 4. No: Let's request more blocks back. + + if msg.Data.Len()-1 > 1 { + lastBlock = ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len() - 1)) + if p.ethereum.StateManager().BlockChain().HasBlock(lastBlock.Hash()) { + fmt.Println("[PEER] We found a common ancestor, let's continue.") + } else { + fmt.Println("[PEER] No common ancestor found, requesting more blocks.") + p.blocksRequested = p.blocksRequested * 2 + p.catchingUp = false + p.SyncWithBlocks() + } + + for i := msg.Data.Len() - 1; i >= 0; i-- { + block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) + // Do we have this block on our chain? + if p.ethereum.StateManager().BlockChain().HasBlock(block.Hash()) { + fmt.Println("[PEER] Block found, checking next one.") + } else { + // We don't have this block, but we do have a block with the same prevHash, diversion time! + if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) { + fmt.Printf("[PEER] Local and foreign chain have diverted after %x, we are going to get freaky with it!\n", block.PrevHash) + p.ethereum.StateManager().BlockChain().FindCanonicalChain(msg, block.PrevHash) + } else { + fmt.Println("[PEER] Both local and foreign chain have same parent. Continue normally") + } + } + } + } + for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) p.ethereum.StateManager().PrepareDefault(block) - err = p.ethereum.StateManager().ProcessBlock(block, true) + err = p.ethereum.StateManager().ProcessBlock(block, false) if err != nil { if ethutil.Config.Debug { @@ -305,6 +358,7 @@ func (p *Peer) HandleInbound() { } break } else { + ethutil.Config.Log.Infof("[PEER] Block %x added\n", block.Hash()) lastBlock = block } } @@ -314,7 +368,7 @@ func (p *Peer) HandleInbound() { if ethchain.IsParentErr(err) { ethutil.Config.Log.Infoln("Attempting to catch up") p.catchingUp = false - p.CatchupWithPeer() + p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) } else if ethchain.IsValidationErr(err) { // TODO } @@ -327,7 +381,7 @@ func (p *Peer) HandleInbound() { ethutil.Config.Log.Infof("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) } p.catchingUp = false - p.CatchupWithPeer() + p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) } } case ethwire.MsgTxTy: @@ -374,11 +428,11 @@ func (p *Peer) HandleInbound() { // Amount of parents in the canonical chain //amountOfBlocks := msg.Data.Get(l).AsUint() amountOfBlocks := uint64(100) + // Check each SHA block hash from the message and determine whether // the SHA is in the database for i := 0; i < l; i++ { - if data := - msg.Data.Get(i).Bytes(); p.ethereum.StateManager().BlockChain().HasBlock(data) { + if data := msg.Data.Get(i).Bytes(); p.ethereum.StateManager().BlockChain().HasBlock(data) { parent = p.ethereum.BlockChain().GetBlock(data) break } @@ -386,9 +440,12 @@ func (p *Peer) HandleInbound() { // If a parent is found send back a reply if parent != nil { + ethutil.Config.Log.Infof("[PEER] Found conical block, returning chain from: %x ", parent.Hash()) chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) + ethutil.Config.Log.Infof("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) } else { + ethutil.Config.Log.Infof("[PEER] Could not find a similar block") // If no blocks are found we send back a reply with msg not in chain // and the last hash from get chain lastHash := msg.Data.Get(l - 1) @@ -527,7 +584,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { } // Catch up with the connected peer - p.CatchupWithPeer() + // p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) + p.SyncWithBlocks() // Set the peer's caps p.caps = Caps(c.Get(3).Byte()) @@ -554,14 +612,37 @@ func (p *Peer) String() string { return fmt.Sprintf("[%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.Version, p.caps) } +func (p *Peer) SyncWithBlocks() { + if !p.catchingUp { + p.catchingUp = true + // FIXME: THIS SHOULD NOT BE NEEDED + if p.blocksRequested == 0 { + p.blocksRequested = 10 + } + fmt.Printf("Currenb lock %x\n", p.ethereum.BlockChain().CurrentBlock.Hash()) + fmt.Println("Amount:", p.blocksRequested) + blocks := p.ethereum.BlockChain().GetChain(p.ethereum.BlockChain().CurrentBlock.Hash(), p.blocksRequested) + + var hashes []interface{} + for _, block := range blocks { + hashes = append(hashes, block.Hash()) + } + fmt.Printf("Requesting hashes from network: %x", hashes) + + msgInfo := append(hashes, uint64(50)) + + msg := ethwire.NewMessage(ethwire.MsgGetChainTy, msgInfo) + p.QueueMessage(msg) + } +} -func (p *Peer) CatchupWithPeer() { +func (p *Peer) CatchupWithPeer(blockHash []byte) { if !p.catchingUp { p.catchingUp = true - msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{p.ethereum.BlockChain().CurrentBlock.Hash(), uint64(50)}) + msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(50)}) p.QueueMessage(msg) - ethutil.Config.Log.Debugf("Requesting blockchain %x...\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4]) + ethutil.Config.Log.Debugf("Requesting blockchain %x...\n", blockHash[:4]) } } -- cgit v1.2.3 From 274d5cc91c45349ec8d7a1f5a20ef29896b38b2e Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Mon, 24 Mar 2014 10:24:06 +0100 Subject: FindCanonicalChain returns true or false when we are on the Canonical chain or not --- peer.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 2cc940400..22bbe7a4c 100644 --- a/peer.go +++ b/peer.go @@ -316,11 +316,18 @@ func (p *Peer) HandleInbound() { // 3. Yes: Let's continue what we are doing // 4. No: Let's request more blocks back. + // Make sure we are actually receiving anything if msg.Data.Len()-1 > 1 { + // We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find + // common ground to start syncing from lastBlock = ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len() - 1)) if p.ethereum.StateManager().BlockChain().HasBlock(lastBlock.Hash()) { fmt.Println("[PEER] We found a common ancestor, let's continue.") } else { + + // If we can't find a common ancenstor we need to request more blocks. + // FIXME: At one point this won't scale anymore since we are not asking for an offset + // we just keep increasing the amount of blocks. fmt.Println("[PEER] No common ancestor found, requesting more blocks.") p.blocksRequested = p.blocksRequested * 2 p.catchingUp = false @@ -329,14 +336,16 @@ func (p *Peer) HandleInbound() { for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) - // Do we have this block on our chain? + // Do we have this block on our chain? If so we can continue if p.ethereum.StateManager().BlockChain().HasBlock(block.Hash()) { fmt.Println("[PEER] Block found, checking next one.") } else { // We don't have this block, but we do have a block with the same prevHash, diversion time! if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) { fmt.Printf("[PEER] Local and foreign chain have diverted after %x, we are going to get freaky with it!\n", block.PrevHash) - p.ethereum.StateManager().BlockChain().FindCanonicalChain(msg, block.PrevHash) + if p.ethereum.StateManager().BlockChain().FindCanonicalChain(msg, block.PrevHash) { + return + } } else { fmt.Println("[PEER] Both local and foreign chain have same parent. Continue normally") } @@ -358,7 +367,6 @@ func (p *Peer) HandleInbound() { } break } else { - ethutil.Config.Log.Infof("[PEER] Block %x added\n", block.Hash()) lastBlock = block } } -- cgit v1.2.3 From ec6ec62dd4f3c4132c79b33fc20467ba98c16f10 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Mon, 24 Mar 2014 10:56:52 +0100 Subject: Remove some xtra logs --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index b8e75c686..63059bcfb 100644 --- a/peer.go +++ b/peer.go @@ -316,7 +316,7 @@ func (p *Peer) HandleInbound() { // 4. No: Let's request more blocks back. // Make sure we are actually receiving anything - if msg.Data.Len()-1 > 1 { + if msg.Data.Len()-1 > 1 && p.catchingUp { // We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find // common ground to start syncing from lastBlock = ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len() - 1)) -- cgit v1.2.3 From 6253d109389d49e47772597de24cd11874b91338 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Mon, 24 Mar 2014 15:04:29 +0100 Subject: initial testcode for canonical chain --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 63059bcfb..21d55ce6d 100644 --- a/peer.go +++ b/peer.go @@ -342,7 +342,7 @@ func (p *Peer) HandleInbound() { // We don't have this block, but we do have a block with the same prevHash, diversion time! if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) { fmt.Printf("[PEER] Local and foreign chain have diverted after %x, we are going to get freaky with it!\n", block.PrevHash) - if p.ethereum.StateManager().BlockChain().FindCanonicalChain(msg, block.PrevHash) { + if p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) { return } } else { -- cgit v1.2.3 From 43cad6901620ca077e43f195cc5ae4d1c8edb2d0 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 27 Mar 2014 15:42:39 +0100 Subject: Reworked transaction constructors --- peer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 24a5e97c9..82c983927 100644 --- a/peer.go +++ b/peer.go @@ -334,7 +334,8 @@ func (p *Peer) HandleInbound() { // in the TxPool where it will undergo validation and // processing when a new block is found for i := 0; i < msg.Data.Len(); i++ { - p.ethereum.TxPool().QueueTransaction(ethchain.NewTransactionFromData(msg.Data.Get(i).Encode())) + //p.ethereum.TxPool().QueueTransaction(ethchain.NewTransactionFromData(msg.Data.Get(i).Encode())) + p.ethereum.TxPool().QueueTransaction(ethchain.NewTransactionFromValue(msg.Data.Get(i))) } case ethwire.MsgGetPeersTy: // Flag this peer as a 'requested of new peers' this to -- cgit v1.2.3 From b888652201277ab86e9e8c280e75e23ced5e3d38 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 28 Mar 2014 11:20:07 +0100 Subject: Added missing GetTx (0x16) wire message --- peer.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 82c983927..279b0bc7f 100644 --- a/peer.go +++ b/peer.go @@ -334,8 +334,8 @@ func (p *Peer) HandleInbound() { // in the TxPool where it will undergo validation and // processing when a new block is found for i := 0; i < msg.Data.Len(); i++ { - //p.ethereum.TxPool().QueueTransaction(ethchain.NewTransactionFromData(msg.Data.Get(i).Encode())) - p.ethereum.TxPool().QueueTransaction(ethchain.NewTransactionFromValue(msg.Data.Get(i))) + tx := ethchain.NewTransactionFromValue(msg.Data.Get(i)) + p.ethereum.TxPool().QueueTransaction(tx) } case ethwire.MsgGetPeersTy: // Flag this peer as a 'requested of new peers' this to @@ -398,6 +398,16 @@ func (p *Peer) HandleInbound() { case ethwire.MsgNotInChainTy: ethutil.Config.Log.Infof("Not in chain %x\n", msg.Data) // TODO + case ethwire.MsgGetTxsTy: + // Get the current transactions of the pool + txs := p.ethereum.TxPool().CurrentTransactions() + // Get the RlpData values from the txs + txsInterface := make([]interface{}, len(txs)) + for i, tx := range txs { + txsInterface[i] = tx.RlpData() + } + // Broadcast it back to the peer + p.QueueMessage(ethwire.NewMessage(ethwire.MsgTxTy, txsInterface)) // Unofficial but fun nonetheless case ethwire.MsgTalkTy: @@ -562,6 +572,10 @@ func (p *Peer) CatchupWithPeer() { p.QueueMessage(msg) ethutil.Config.Log.Debugf("Requesting blockchain %x...\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4]) + + msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) + p.QueueMessage(msg) + ethutil.Config.Log.Debugln("Requested transactions") } } -- cgit v1.2.3 From 782910eaa76bb31be4c2bcd0f4505b8085acb57c Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Tue, 1 Apr 2014 15:54:29 +0200 Subject: Small tweaks --- peer.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index f2267c29b..0ecd13e60 100644 --- a/peer.go +++ b/peer.go @@ -337,16 +337,16 @@ func (p *Peer) HandleInbound() { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) // Do we have this block on our chain? If so we can continue if p.ethereum.StateManager().BlockChain().HasBlock(block.Hash()) { - fmt.Println("[PEER] Block found, checking next one.") + ethutil.Config.Log.Debugf("[PEER] Block found, checking next one.\n") } else { // We don't have this block, but we do have a block with the same prevHash, diversion time! if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) { - fmt.Printf("[PEER] Local and foreign chain have diverted after %x, we are going to get freaky with it!\n", block.PrevHash) + ethutil.Config.Log.Infof("[PEER] Local and foreign chain have diverted after %x, finding best chain!\n", block.PrevHash) if p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) { return } } else { - fmt.Println("[PEER] Both local and foreign chain have same parent. Continue normally") + ethutil.Config.Log.Debugf("[PEER] Both local and foreign chain have same parent. Continue normally\n") } } } @@ -362,7 +362,6 @@ func (p *Peer) HandleInbound() { if ethutil.Config.Debug { ethutil.Config.Log.Infof("[PEER] Block %x failed\n", block.Hash()) ethutil.Config.Log.Infof("[PEER] %v\n", err) - ethutil.Config.Log.Infoln(block) } break } else { @@ -637,8 +636,6 @@ func (p *Peer) SyncWithBlocks() { if p.blocksRequested == 0 { p.blocksRequested = 10 } - fmt.Printf("Currenb lock %x\n", p.ethereum.BlockChain().CurrentBlock.Hash()) - fmt.Println("Amount:", p.blocksRequested) blocks := p.ethereum.BlockChain().GetChain(p.ethereum.BlockChain().CurrentBlock.Hash(), p.blocksRequested) var hashes []interface{} -- cgit v1.2.3 From 38d6b67b5cfbfb63620a244ea01b5b534917128f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 29 Apr 2014 12:36:27 +0200 Subject: Fixed state problem --- peer.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 0ecd13e60..28ccc324c 100644 --- a/peer.go +++ b/peer.go @@ -449,8 +449,10 @@ func (p *Peer) HandleInbound() { if parent != nil { ethutil.Config.Log.Infof("[PEER] Found conical block, returning chain from: %x ", parent.Hash()) chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) - ethutil.Config.Log.Infof("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) + if len(chain) > 0 { + ethutil.Config.Log.Infof("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) + } } else { ethutil.Config.Log.Infof("[PEER] Could not find a similar block") // If no blocks are found we send back a reply with msg not in chain -- cgit v1.2.3 From d2ab322267e489f47b4b908d060411eb0554a029 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 30 Apr 2014 17:43:48 +0200 Subject: Removed debugging log --- peer.go | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 28ccc324c..4f7005ac4 100644 --- a/peer.go +++ b/peer.go @@ -320,14 +320,11 @@ func (p *Peer) HandleInbound() { // We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find // common ground to start syncing from lastBlock = ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len() - 1)) - if p.ethereum.StateManager().BlockChain().HasBlock(lastBlock.Hash()) { - fmt.Println("[PEER] We found a common ancestor, let's continue.") - } else { - + if !p.ethereum.StateManager().BlockChain().HasBlock(lastBlock.Hash()) { // If we can't find a common ancenstor we need to request more blocks. // FIXME: At one point this won't scale anymore since we are not asking for an offset // we just keep increasing the amount of blocks. - fmt.Println("[PEER] No common ancestor found, requesting more blocks.") + //fmt.Println("[PEER] No common ancestor found, requesting more blocks.") p.blocksRequested = p.blocksRequested * 2 p.catchingUp = false p.SyncWithBlocks() @@ -336,17 +333,13 @@ func (p *Peer) HandleInbound() { for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) // Do we have this block on our chain? If so we can continue - if p.ethereum.StateManager().BlockChain().HasBlock(block.Hash()) { - ethutil.Config.Log.Debugf("[PEER] Block found, checking next one.\n") - } else { + if !p.ethereum.StateManager().BlockChain().HasBlock(block.Hash()) { // We don't have this block, but we do have a block with the same prevHash, diversion time! if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) { - ethutil.Config.Log.Infof("[PEER] Local and foreign chain have diverted after %x, finding best chain!\n", block.PrevHash) + //ethutil.Config.Log.Infof("[PEER] Local and foreign chain have diverted after %x, finding best chain!\n", block.PrevHash) if p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) { return } - } else { - ethutil.Config.Log.Debugf("[PEER] Both local and foreign chain have same parent. Continue normally\n") } } } @@ -644,7 +637,6 @@ func (p *Peer) SyncWithBlocks() { for _, block := range blocks { hashes = append(hashes, block.Hash()) } - fmt.Printf("Requesting hashes from network: %x", hashes) msgInfo := append(hashes, uint64(50)) -- cgit v1.2.3 From e6a68f0c3ab4987fa5e0e35cac765d40ff305aea Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 1 May 2014 22:13:59 +0200 Subject: Removed debug log --- peer.go | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4f7005ac4..80ddc5142 100644 --- a/peer.go +++ b/peer.go @@ -440,14 +440,14 @@ func (p *Peer) HandleInbound() { // If a parent is found send back a reply if parent != nil { - ethutil.Config.Log.Infof("[PEER] Found conical block, returning chain from: %x ", parent.Hash()) + ethutil.Config.Log.Debugf("[PEER] Found conical block, returning chain from: %x ", parent.Hash()) chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) if len(chain) > 0 { - ethutil.Config.Log.Infof("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) + ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) } } else { - ethutil.Config.Log.Infof("[PEER] Could not find a similar block") + ethutil.Config.Log.Debugf("[PEER] Could not find a similar block") // If no blocks are found we send back a reply with msg not in chain // and the last hash from get chain lastHash := msg.Data.Get(l - 1) @@ -455,7 +455,7 @@ func (p *Peer) HandleInbound() { p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, []interface{}{lastHash.Raw()})) } case ethwire.MsgNotInChainTy: - ethutil.Config.Log.Infof("Not in chain %x\n", msg.Data) + ethutil.Config.Log.Debugf("Not in chain %x\n", msg.Data) // TODO case ethwire.MsgGetTxsTy: // Get the current transactions of the pool @@ -478,29 +478,6 @@ func (p *Peer) HandleInbound() { p.Stop() } -func packAddr(address, port string) ([]interface{}, uint16) { - addr := strings.Split(address, ".") - a, _ := strconv.Atoi(addr[0]) - b, _ := strconv.Atoi(addr[1]) - c, _ := strconv.Atoi(addr[2]) - d, _ := strconv.Atoi(addr[3]) - host := []interface{}{int32(a), int32(b), int32(c), int32(d)} - prt, _ := strconv.Atoi(port) - - return host, uint16(prt) -} - -func unpackAddr(value *ethutil.Value, p uint64) string { - a := strconv.Itoa(int(value.Get(0).Uint())) - b := strconv.Itoa(int(value.Get(1).Uint())) - c := strconv.Itoa(int(value.Get(2).Uint())) - d := strconv.Itoa(int(value.Get(3).Uint())) - host := strings.Join([]string{a, b, c, d}, ".") - port := strconv.Itoa(int(p)) - - return net.JoinHostPort(host, port) -} - func (p *Peer) Start() { peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String()) servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) @@ -662,3 +639,26 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) { func (p *Peer) RlpData() []interface{} { return []interface{}{p.host, p.port, p.pubkey} } + +func packAddr(address, port string) ([]interface{}, uint16) { + addr := strings.Split(address, ".") + a, _ := strconv.Atoi(addr[0]) + b, _ := strconv.Atoi(addr[1]) + c, _ := strconv.Atoi(addr[2]) + d, _ := strconv.Atoi(addr[3]) + host := []interface{}{int32(a), int32(b), int32(c), int32(d)} + prt, _ := strconv.Atoi(port) + + return host, uint16(prt) +} + +func unpackAddr(value *ethutil.Value, p uint64) string { + a := strconv.Itoa(int(value.Get(0).Uint())) + b := strconv.Itoa(int(value.Get(1).Uint())) + c := strconv.Itoa(int(value.Get(2).Uint())) + d := strconv.Itoa(int(value.Get(3).Uint())) + host := strings.Join([]string{a, b, c, d}, ".") + port := strconv.Itoa(int(p)) + + return net.JoinHostPort(host, port) +} -- cgit v1.2.3 From 4eb3ad192e58bc42dec4e44b4a8be6cb36473c0f Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Mon, 12 May 2014 12:28:56 +0200 Subject: Made the debug line for invalid peer versions dynamic --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 80ddc5142..9b8b3f2ae 100644 --- a/peer.go +++ b/peer.go @@ -549,7 +549,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data if c.Get(0).Uint() != ProtocolVersion { - ethutil.Config.Log.Debugln("Invalid peer version. Require protocol v5") + ethutil.Config.Log.Debugln("Invalid peer version. Require protocol:", ProtocolVersion) p.Stop() return } -- cgit v1.2.3 From 8b4ed8c505111cb570c7c694675b833ebf0bba21 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Mon, 12 May 2014 13:39:37 +0200 Subject: Properly exchange peer capabilities between peers --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 9b8b3f2ae..54e6af823 100644 --- a/peer.go +++ b/peer.go @@ -146,6 +146,7 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { port: 30303, pubkey: pubkey, blocksRequested: 10, + caps: ethereum.ServerCaps(), } } @@ -573,7 +574,6 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { } // Catch up with the connected peer - // p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) p.SyncWithBlocks() // Set the peer's caps -- cgit v1.2.3 From 5fcbaefd0b20af2a13ad9f6c3359b8c1ca096ba6 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Mon, 12 May 2014 15:43:10 +0200 Subject: Don't forward localhost connections over the public network --- peer.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 54e6af823..d8168e455 100644 --- a/peer.go +++ b/peer.go @@ -534,7 +534,10 @@ func (p *Peer) peersMessage() *ethwire.Msg { outPeers := make([]interface{}, len(p.ethereum.InOutPeers())) // Serialise each peer for i, peer := range p.ethereum.InOutPeers() { - outPeers[i] = peer.RlpData() + // Don't return localhost as valid peer + if !net.ParseIP(peer.conn.RemoteAddr().String()).IsLoopback() { + outPeers[i] = peer.RlpData() + } } // Return the message to the peer with the known list of connected clients -- cgit v1.2.3 From 8fe0864680b40c3fa5e47775856d8ae1997ba003 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Mon, 12 May 2014 16:09:23 +0200 Subject: Only accept peers if we asked for them --- peer.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index d8168e455..359e83566 100644 --- a/peer.go +++ b/peer.go @@ -401,22 +401,22 @@ func (p *Peer) HandleInbound() { case ethwire.MsgPeersTy: // Received a list of peers (probably because MsgGetPeersTy was send) // Only act on message if we actually requested for a peers list - //if p.requestedPeerList { - data := msg.Data - // Create new list of possible peers for the ethereum to process - peers := make([]string, data.Len()) - // Parse each possible peer - for i := 0; i < data.Len(); i++ { - value := data.Get(i) - peers[i] = unpackAddr(value.Get(0), value.Get(1).Uint()) - } + if p.requestedPeerList { + data := msg.Data + // Create new list of possible peers for the ethereum to process + peers := make([]string, data.Len()) + // Parse each possible peer + for i := 0; i < data.Len(); i++ { + value := data.Get(i) + peers[i] = unpackAddr(value.Get(0), value.Get(1).Uint()) + } - // Connect to the list of peers - p.ethereum.ProcessPeerList(peers) - // Mark unrequested again - p.requestedPeerList = false + // Connect to the list of peers + p.ethereum.ProcessPeerList(peers) + // Mark unrequested again + p.requestedPeerList = false - //} + } case ethwire.MsgGetChainTy: var parent *ethchain.Block // Length minus one since the very last element in the array is a count -- cgit v1.2.3 From 52b664b0aec24bffc040da06bbe8be1d3e7e4ab8 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Mon, 12 May 2014 16:30:21 +0200 Subject: Removed peers from peerlist as soon as they disconnect. Might fix #13 We used to wait for the reaping timer to clean up the peerlist, not any longer --- peer.go | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 359e83566..932dbdc18 100644 --- a/peer.go +++ b/peer.go @@ -2,6 +2,7 @@ package eth import ( "bytes" + "container/list" "fmt" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" @@ -515,6 +516,15 @@ func (p *Peer) Stop() { p.writeMessage(ethwire.NewMessage(ethwire.MsgDiscTy, "")) p.conn.Close() } + + // Pre-emptively remove the peer; don't wait for reaping. We already know it's dead if we are here + p.ethereum.peerMut.Lock() + defer p.ethereum.peerMut.Unlock() + eachPeer(p.ethereum.peers, func(peer *Peer, e *list.Element) { + if peer == p { + p.ethereum.peers.Remove(e) + } + }) } func (p *Peer) pushHandshake() error { -- cgit v1.2.3 From 0c1f732c64b7c1380b2f0422ee82d462ea88dc03 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 14 May 2014 11:29:57 +0200 Subject: Do not queue messages if the peer isn't connected (e.g. timing out) --- peer.go | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 932dbdc18..70759f246 100644 --- a/peer.go +++ b/peer.go @@ -187,6 +187,10 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { // Outputs any RLP encoded data to the peer func (p *Peer) QueueMessage(msg *ethwire.Msg) { + if atomic.LoadInt32(&p.connected) != 1 { + return + } + p.outputQueue <- msg } -- cgit v1.2.3 From f4fa0d48cb10f925908062357be965c54370cba9 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 14 May 2014 13:54:40 +0200 Subject: Moved keyring to ethutil & removed old methods. Implements #20 --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 70759f246..433ce161f 100644 --- a/peer.go +++ b/peer.go @@ -581,8 +581,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.port = uint16(c.Get(4).Uint()) // Self connect detection - key := ethutil.Config.Db.GetKeys()[0] - if bytes.Compare(key.PublicKey, p.pubkey) == 0 { + keyPair := ethutil.GetKeyRing().Get(0) + if bytes.Compare(keyPair.PublicKey, p.pubkey) == 0 { p.Stop() return -- cgit v1.2.3 From 3ac74b1e7840720e8ae426c751328ed7595188a8 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Wed, 14 May 2014 13:57:04 +0200 Subject: Implemented IsUpToDate to mark the node as ready to start mining --- peer.go | 2 ++ 1 file changed, 2 insertions(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 70759f246..0f968d664 100644 --- a/peer.go +++ b/peer.go @@ -389,6 +389,8 @@ func (p *Peer) HandleInbound() { p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) } } + + p.catchingUp = false case ethwire.MsgTxTy: // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and -- cgit v1.2.3 From 166853aed94484b327a89a2554312f6739fce8a9 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 14 May 2014 20:35:23 +0200 Subject: Test --- peer.go | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 29f98a4fb..a509178d2 100644 --- a/peer.go +++ b/peer.go @@ -299,28 +299,6 @@ func (p *Peer) HandleInbound() { var block, lastBlock *ethchain.Block var err error - // 1. Compare the first block over the wire's prev-hash with the hash of your last block - // 2. If these two values are the same you can just link the chains together. - // [1:0,2:1,3:2] <- Current blocks (format block:previous_block) - // [1:0,2:1,3:2,4:3,5:4] <- incoming blocks - // == [1,2,3,4,5] - // 3. If the values are not the same we will have to go back and calculate the chain with the highest total difficulty - // [1:0,2:1,3:2,11:3,12:11,13:12] - // [1:0,2:1,3:2,4:3,5:4,6:5] - - // [3:2,11:3,12:11,13:12] - // [3:2,4:3,5:4,6:5] - // Heb ik dit blok? - // Nee: heb ik een blok met PrevHash 3? - // Ja: DIVERSION - // Nee; Adding to chain - - // See if we can find a common ancestor - // 1. Get the earliest block in the package. - // 2. Do we have this block? - // 3. Yes: Let's continue what we are doing - // 4. No: Let's request more blocks back. - // Make sure we are actually receiving anything if msg.Data.Len()-1 > 1 && p.catchingUp { // We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find @@ -342,8 +320,9 @@ func (p *Peer) HandleInbound() { if !p.ethereum.StateManager().BlockChain().HasBlock(block.Hash()) { // We don't have this block, but we do have a block with the same prevHash, diversion time! if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) { - //ethutil.Config.Log.Infof("[PEER] Local and foreign chain have diverted after %x, finding best chain!\n", block.PrevHash) if p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) { + p.catchingUp = false + return } } @@ -375,7 +354,8 @@ func (p *Peer) HandleInbound() { p.catchingUp = false p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) } else if ethchain.IsValidationErr(err) { - // TODO + fmt.Println(err) + p.catchingUp = false } } else { // XXX Do we want to catch up if there were errors? @@ -385,12 +365,20 @@ func (p *Peer) HandleInbound() { blockInfo := lastBlock.BlockInfo() ethutil.Config.Log.Infof("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) } + p.catchingUp = false - p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) + + hash := p.ethereum.BlockChain().CurrentBlock.Hash() + p.CatchupWithPeer(hash) } } - p.catchingUp = false + if lastBlock != nil && err == nil { + fmt.Println("Did proc. no err") + } else { + fmt.Println("other") + } + fmt.Println("length of chain", msg.Data.Len()) case ethwire.MsgTxTy: // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and @@ -453,7 +441,10 @@ func (p *Peer) HandleInbound() { if len(chain) > 0 { ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) + } else { + p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, []interface{})) } + } else { ethutil.Config.Log.Debugf("[PEER] Could not find a similar block") // If no blocks are found we send back a reply with msg not in chain -- cgit v1.2.3 From a6b9ea05e8dc291f69f9384071864a475e7872e6 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 14 May 2014 20:36:21 +0200 Subject: Test --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index a509178d2..3e1e4a181 100644 --- a/peer.go +++ b/peer.go @@ -442,7 +442,7 @@ func (p *Peer) HandleInbound() { ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) } else { - p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, []interface{})) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, []interface{}{})) } } else { -- cgit v1.2.3 From 65f570271cc6bf2ea73a7ba2bf83d92a1ba42986 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 14 May 2014 20:50:37 +0200 Subject: Fixed catching up --- peer.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 3e1e4a181..4093a4902 100644 --- a/peer.go +++ b/peer.go @@ -321,8 +321,6 @@ func (p *Peer) HandleInbound() { // We don't have this block, but we do have a block with the same prevHash, diversion time! if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) { if p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) { - p.catchingUp = false - return } } @@ -373,12 +371,11 @@ func (p *Peer) HandleInbound() { } } - if lastBlock != nil && err == nil { - fmt.Println("Did proc. no err") - } else { - fmt.Println("other") + if msg.Data.Len() == 0 { + // Set catching up to false if + // the peer has nothing left to give + p.catchingUp = false } - fmt.Println("length of chain", msg.Data.Len()) case ethwire.MsgTxTy: // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and -- cgit v1.2.3 From 8730dfdcc2e2b40410a57385e4864d15f2f0336b Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sat, 17 May 2014 14:07:52 +0200 Subject: Changed how changes are being applied to states --- peer.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4093a4902..45ff0a795 100644 --- a/peer.go +++ b/peer.go @@ -331,8 +331,9 @@ func (p *Peer) HandleInbound() { for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) - p.ethereum.StateManager().PrepareDefault(block) - err = p.ethereum.StateManager().ProcessBlock(block, false) + //p.ethereum.StateManager().PrepareDefault(block) + state := p.ethereum.StateManager().CurrentState() + err = p.ethereum.StateManager().ProcessBlock(state, block, false) if err != nil { if ethutil.Config.Debug { -- cgit v1.2.3 From fd19142c0db3d2b6651989f5389944f3e211d84f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 20 May 2014 11:19:07 +0200 Subject: No longer store script directly in the state tree --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 45ff0a795..f84b4d472 100644 --- a/peer.go +++ b/peer.go @@ -18,7 +18,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 8 + ProtocolVersion = 9 ) type DiscReason byte -- cgit v1.2.3 From 12f30e6220354c4a8b08ecf41bb53444143f3660 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Tue, 20 May 2014 11:50:34 +0200 Subject: Refactored a lot of the chain catchup/reorg. --- peer.go | 125 +++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 73 insertions(+), 52 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 45ff0a795..879361b2b 100644 --- a/peer.go +++ b/peer.go @@ -127,6 +127,7 @@ type Peer struct { // Indicated whether the node is catching up or not catchingUp bool + diverted bool blocksRequested int Version string @@ -190,7 +191,6 @@ func (p *Peer) QueueMessage(msg *ethwire.Msg) { if atomic.LoadInt32(&p.connected) != 1 { return } - p.outputQueue <- msg } @@ -268,7 +268,6 @@ func (p *Peer) HandleInbound() { for atomic.LoadInt32(&p.disconnect) == 0 { // HMM? time.Sleep(500 * time.Millisecond) - // Wait for a message from the peer msgs, err := ethwire.ReadMessages(p.conn) if err != nil { @@ -300,32 +299,36 @@ func (p *Peer) HandleInbound() { var err error // Make sure we are actually receiving anything - if msg.Data.Len()-1 > 1 && p.catchingUp { + if msg.Data.Len()-1 > 1 && p.diverted { // We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find // common ground to start syncing from lastBlock = ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len() - 1)) - if !p.ethereum.StateManager().BlockChain().HasBlock(lastBlock.Hash()) { - // If we can't find a common ancenstor we need to request more blocks. - // FIXME: At one point this won't scale anymore since we are not asking for an offset - // we just keep increasing the amount of blocks. - //fmt.Println("[PEER] No common ancestor found, requesting more blocks.") - p.blocksRequested = p.blocksRequested * 2 - p.catchingUp = false - p.SyncWithBlocks() - } - + ethutil.Config.Log.Infof("[PEER] Last block: %x. Checking if we have it locally.\n", lastBlock.Hash()) for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) // Do we have this block on our chain? If so we can continue if !p.ethereum.StateManager().BlockChain().HasBlock(block.Hash()) { // We don't have this block, but we do have a block with the same prevHash, diversion time! if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) { - if p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) { - return + p.diverted = false + if !p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) { + p.SyncWithPeerToLastKnown() } + break } } } + if !p.ethereum.StateManager().BlockChain().HasBlock(lastBlock.Hash()) { + // If we can't find a common ancenstor we need to request more blocks. + // FIXME: At one point this won't scale anymore since we are not asking for an offset + // we just keep increasing the amount of blocks. + p.blocksRequested = p.blocksRequested * 2 + + ethutil.Config.Log.Infof("[PEER] No common ancestor found, requesting %d more blocks.\n", p.blocksRequested) + p.catchingUp = false + p.FindCommonParentBlock() + break + } } for i := msg.Data.Len() - 1; i >= 0; i-- { @@ -346,23 +349,28 @@ func (p *Peer) HandleInbound() { } } + if msg.Data.Len() == 0 { + // Set catching up to false if + // the peer has nothing left to give + p.catchingUp = false + } + if err != nil { // If the parent is unknown try to catch up with this peer if ethchain.IsParentErr(err) { - ethutil.Config.Log.Infoln("Attempting to catch up") + ethutil.Config.Log.Infoln("Attempting to catch up since we don't know the parent") p.catchingUp = false p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) } else if ethchain.IsValidationErr(err) { - fmt.Println(err) + fmt.Println("Err:", err) p.catchingUp = false } } else { - // XXX Do we want to catch up if there were errors? // If we're catching up, try to catch up further. if p.catchingUp && msg.Data.Len() > 1 { - if ethutil.Config.Debug && lastBlock != nil { + if lastBlock != nil { blockInfo := lastBlock.BlockInfo() - ethutil.Config.Log.Infof("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) + ethutil.Config.Log.Debugf("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) } p.catchingUp = false @@ -372,11 +380,6 @@ func (p *Peer) HandleInbound() { } } - if msg.Data.Len() == 0 { - // Set catching up to false if - // the peer has nothing left to give - p.catchingUp = false - } case ethwire.MsgTxTy: // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and @@ -444,7 +447,7 @@ func (p *Peer) HandleInbound() { } } else { - ethutil.Config.Log.Debugf("[PEER] Could not find a similar block") + //ethutil.Config.Log.Debugf("[PEER] Could not find a similar block") // If no blocks are found we send back a reply with msg not in chain // and the last hash from get chain lastHash := msg.Data.Get(l - 1) @@ -452,8 +455,14 @@ func (p *Peer) HandleInbound() { p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, []interface{}{lastHash.Raw()})) } case ethwire.MsgNotInChainTy: - ethutil.Config.Log.Debugf("Not in chain %x\n", msg.Data) - // TODO + ethutil.Config.Log.Debugf("Not in chain: %x\n", msg.Data.Get(0).Bytes()) + if p.diverted == true { + // If were already looking for a common parent and we get here again we need to go deeper + p.blocksRequested = p.blocksRequested * 2 + } + p.diverted = true + p.catchingUp = false + p.FindCommonParentBlock() case ethwire.MsgGetTxsTy: // Get the current transactions of the pool txs := p.ethereum.TxPool().CurrentTransactions() @@ -471,7 +480,6 @@ func (p *Peer) HandleInbound() { } } } - p.Stop() } @@ -581,14 +589,18 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { } - // Catch up with the connected peer - p.SyncWithBlocks() - // Set the peer's caps p.caps = Caps(c.Get(3).Byte()) // Get a reference to the peers version p.Version = c.Get(2).Str() + // Catch up with the connected peer + if !p.ethereum.IsUpToDate() { + ethutil.Config.Log.Debugln("Already syncing up with a peer; sleeping") + time.Sleep(10 * time.Second) + } + p.SyncWithPeerToLastKnown() + ethutil.Config.Log.Debugln("[PEER]", p) } @@ -609,38 +621,47 @@ func (p *Peer) String() string { return fmt.Sprintf("[%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.Version, p.caps) } -func (p *Peer) SyncWithBlocks() { - if !p.catchingUp { - p.catchingUp = true - // FIXME: THIS SHOULD NOT BE NEEDED - if p.blocksRequested == 0 { - p.blocksRequested = 10 - } - blocks := p.ethereum.BlockChain().GetChain(p.ethereum.BlockChain().CurrentBlock.Hash(), p.blocksRequested) +func (p *Peer) SyncWithPeerToLastKnown() { + p.catchingUp = false + p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) +} - var hashes []interface{} - for _, block := range blocks { - hashes = append(hashes, block.Hash()) - } +func (p *Peer) FindCommonParentBlock() { + if p.catchingUp { + return + } - msgInfo := append(hashes, uint64(50)) + p.catchingUp = true + if p.blocksRequested == 0 { + p.blocksRequested = 20 + } + blocks := p.ethereum.BlockChain().GetChain(p.ethereum.BlockChain().CurrentBlock.Hash(), p.blocksRequested) - msg := ethwire.NewMessage(ethwire.MsgGetChainTy, msgInfo) - p.QueueMessage(msg) + var hashes []interface{} + for _, block := range blocks { + hashes = append(hashes, block.Hash()) } -} + msgInfo := append(hashes, uint64(len(hashes))) + + ethutil.Config.Log.Infof("Asking for block from %x (%d total) from %s\n", p.ethereum.BlockChain().CurrentBlock.Hash(), len(hashes), p.conn.RemoteAddr().String()) + + msg := ethwire.NewMessage(ethwire.MsgGetChainTy, msgInfo) + p.QueueMessage(msg) +} func (p *Peer) CatchupWithPeer(blockHash []byte) { if !p.catchingUp { + // Make sure nobody else is catching up when you want to do this p.catchingUp = true msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(50)}) p.QueueMessage(msg) - ethutil.Config.Log.Debugf("Requesting blockchain %x...\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4]) + ethutil.Config.Log.Debugf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) - msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) - p.QueueMessage(msg) - ethutil.Config.Log.Debugln("Requested transactions") + /* + msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) + p.QueueMessage(msg) + */ } } -- cgit v1.2.3 From b4e156e1d723fe53eff238a634f6e83cb9d80492 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 20 May 2014 13:29:46 +0200 Subject: Up protocol version --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4a390f015..993f48d20 100644 --- a/peer.go +++ b/peer.go @@ -18,7 +18,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 9 + ProtocolVersion = 10 ) type DiscReason byte -- cgit v1.2.3 From ad51c85e5d67ca2e64e95786e79d062c4467b4c1 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 20 May 2014 19:19:53 +0200 Subject: Fixed crash --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 993f48d20..b2e751b44 100644 --- a/peer.go +++ b/peer.go @@ -18,7 +18,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 10 + ProtocolVersion = 11 ) type DiscReason byte -- cgit v1.2.3 From 6ef2832083ad9d1e3cb1895f1aa836517dbf042d Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 20 May 2014 22:45:01 +0200 Subject: Upped prot --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index b2e751b44..690281da9 100644 --- a/peer.go +++ b/peer.go @@ -18,7 +18,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 11 + ProtocolVersion = 12 ) type DiscReason byte -- cgit v1.2.3 From cbf221f6b7a48ece543d6141d8a7e9dbf9b8d86d Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 21 May 2014 11:42:20 +0200 Subject: Fixed competing block method --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 690281da9..cd3cc7635 100644 --- a/peer.go +++ b/peer.go @@ -335,8 +335,8 @@ func (p *Peer) HandleInbound() { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) //p.ethereum.StateManager().PrepareDefault(block) - state := p.ethereum.StateManager().CurrentState() - err = p.ethereum.StateManager().ProcessBlock(state, block, false) + //state := p.ethereum.StateManager().CurrentState() + err = p.ethereum.StateManager().Process(block, false) if err != nil { if ethutil.Config.Debug { -- cgit v1.2.3 From 0e9c8568fd689fdee0cce2584ad96ecce60c60d7 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 21 May 2014 12:39:15 +0200 Subject: Re broadcast transactions --- peer.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index cd3cc7635..5c46b73fb 100644 --- a/peer.go +++ b/peer.go @@ -381,6 +381,7 @@ func (p *Peer) HandleInbound() { } case ethwire.MsgTxTy: + fmt.Println("received tx") // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and // processing when a new block is found @@ -658,10 +659,8 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) { ethutil.Config.Log.Debugf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) - /* - msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) - p.QueueMessage(msg) - */ + msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) + p.QueueMessage(msg) } } -- cgit v1.2.3 From 86cf69648efc5029abffbf39f1be7308acb1531e Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 21 May 2014 13:04:40 +0200 Subject: Improved miner so it won't include invalid transactions --- peer.go | 1 - 1 file changed, 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 5c46b73fb..7f81489b6 100644 --- a/peer.go +++ b/peer.go @@ -381,7 +381,6 @@ func (p *Peer) HandleInbound() { } case ethwire.MsgTxTy: - fmt.Println("received tx") // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and // processing when a new block is found -- cgit v1.2.3 From 14787ac148274a84478aa06fd985407b9241cd50 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 22 May 2014 17:33:46 +0200 Subject: Fixed some issues connecting for interop --- peer.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 7f81489b6..7e505d680 100644 --- a/peer.go +++ b/peer.go @@ -18,7 +18,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 12 + ProtocolVersion = 17 ) type DiscReason byte @@ -119,7 +119,7 @@ type Peer struct { // this to prevent receiving false peers. requestedPeerList bool - host []interface{} + host []byte port uint16 caps Caps @@ -134,8 +134,7 @@ type Peer struct { } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() + pubkey := ethutil.GetKeyRing().Get(0).PublicKey[1:] return &Peer{ outputQueue: make(chan *ethwire.Msg, outputBufferSize), @@ -342,6 +341,7 @@ func (p *Peer) HandleInbound() { if ethutil.Config.Debug { ethutil.Config.Log.Infof("[PEER] Block %x failed\n", block.Hash()) ethutil.Config.Log.Infof("[PEER] %v\n", err) + ethutil.Config.Log.Debugln(block) } break } else { @@ -437,7 +437,7 @@ func (p *Peer) HandleInbound() { // If a parent is found send back a reply if parent != nil { - ethutil.Config.Log.Debugf("[PEER] Found conical block, returning chain from: %x ", parent.Hash()) + ethutil.Config.Log.Debugf("[PEER] Found canonical block, returning chain from: %x ", parent.Hash()) chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) if len(chain) > 0 { ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) @@ -531,11 +531,10 @@ func (p *Peer) Stop() { } func (p *Peer) pushHandshake() error { - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes() + pubkey := ethutil.GetKeyRing().Get(0).PublicKey msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(ProtocolVersion), uint32(0), p.Version, byte(p.caps), p.port, pubkey, + uint32(ProtocolVersion), uint32(0), p.Version, byte(p.caps), p.port, pubkey[1:], }) p.QueueMessage(msg) @@ -667,23 +666,24 @@ func (p *Peer) RlpData() []interface{} { return []interface{}{p.host, p.port, p.pubkey} } -func packAddr(address, port string) ([]interface{}, uint16) { +func packAddr(address, port string) ([]byte, uint16) { addr := strings.Split(address, ".") a, _ := strconv.Atoi(addr[0]) b, _ := strconv.Atoi(addr[1]) c, _ := strconv.Atoi(addr[2]) d, _ := strconv.Atoi(addr[3]) - host := []interface{}{int32(a), int32(b), int32(c), int32(d)} + host := []byte{byte(a), byte(b), byte(c), byte(d)} prt, _ := strconv.Atoi(port) return host, uint16(prt) } func unpackAddr(value *ethutil.Value, p uint64) string { - a := strconv.Itoa(int(value.Get(0).Uint())) - b := strconv.Itoa(int(value.Get(1).Uint())) - c := strconv.Itoa(int(value.Get(2).Uint())) - d := strconv.Itoa(int(value.Get(3).Uint())) + byts := value.Bytes() + a := strconv.Itoa(int(byts[0])) + b := strconv.Itoa(int(byts[1])) + c := strconv.Itoa(int(byts[2])) + d := strconv.Itoa(int(byts[3])) host := strings.Join([]string{a, b, c, d}, ".") port := strconv.Itoa(int(p)) -- cgit v1.2.3 From 24a6d87c3f4bc69fdd1c619b36f8b74a61fd8bae Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Mon, 26 May 2014 11:47:47 +0200 Subject: Don't handshake if there is no key yet; first start on Ethereal --- peer.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 7e505d680..d613bf6ff 100644 --- a/peer.go +++ b/peer.go @@ -531,13 +531,16 @@ func (p *Peer) Stop() { } func (p *Peer) pushHandshake() error { - pubkey := ethutil.GetKeyRing().Get(0).PublicKey + keyRing := ethutil.GetKeyRing().Get(0) + if keyRing != nil { + pubkey := keyRing.PublicKey - msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(ProtocolVersion), uint32(0), p.Version, byte(p.caps), p.port, pubkey[1:], - }) + msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ + uint32(ProtocolVersion), uint32(0), p.Version, byte(p.caps), p.port, pubkey[1:], + }) - p.QueueMessage(msg) + p.QueueMessage(msg) + } return nil } -- cgit v1.2.3 From 8fcba0eb1e947061aadeea1059830dbcdfd2ef44 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 29 May 2014 23:54:48 +0200 Subject: fixed test --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index d613bf6ff..3d140608b 100644 --- a/peer.go +++ b/peer.go @@ -440,7 +440,7 @@ func (p *Peer) HandleInbound() { ethutil.Config.Log.Debugf("[PEER] Found canonical block, returning chain from: %x ", parent.Hash()) chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) if len(chain) > 0 { - ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) + //ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) } else { p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, []interface{}{})) -- cgit v1.2.3 From 15e0093e13dde98fb9ff3251203313ab4f0eacd4 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 30 May 2014 11:48:23 +0200 Subject: Fixed issue where the client could crash when sending malformed data --- peer.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 3d140608b..60f2de711 100644 --- a/peer.go +++ b/peer.go @@ -450,9 +450,11 @@ func (p *Peer) HandleInbound() { //ethutil.Config.Log.Debugf("[PEER] Could not find a similar block") // If no blocks are found we send back a reply with msg not in chain // and the last hash from get chain - lastHash := msg.Data.Get(l - 1) - //log.Printf("Sending not in chain with hash %x\n", lastHash.AsRaw()) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, []interface{}{lastHash.Raw()})) + if l > 0 { + lastHash := msg.Data.Get(l - 1) + //log.Printf("Sending not in chain with hash %x\n", lastHash.AsRaw()) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, []interface{}{lastHash.Raw()})) + } } case ethwire.MsgNotInChainTy: ethutil.Config.Log.Debugf("Not in chain: %x\n", msg.Data.Get(0).Bytes()) -- cgit v1.2.3 From f382221b28ab9e886263e37b1eab9c7924a6a0dc Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 30 May 2014 13:04:08 +0200 Subject: Broadcast "peerList" event upon removing or adding peers --- peer.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 60f2de711..6853a949d 100644 --- a/peer.go +++ b/peer.go @@ -2,7 +2,6 @@ package eth import ( "bytes" - "container/list" "fmt" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" @@ -523,13 +522,7 @@ func (p *Peer) Stop() { } // Pre-emptively remove the peer; don't wait for reaping. We already know it's dead if we are here - p.ethereum.peerMut.Lock() - defer p.ethereum.peerMut.Unlock() - eachPeer(p.ethereum.peers, func(peer *Peer, e *list.Element) { - if peer == p { - p.ethereum.peers.Remove(e) - } - }) + p.ethereum.RemovePeer(p) } func (p *Peer) pushHandshake() error { -- cgit v1.2.3 From fb6ff61730ed92ada68c9c5a5b3a6f9976a78161 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Mon, 2 Jun 2014 15:20:27 +0200 Subject: Implemented Public Peer interface --- peer.go | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 6853a949d..71ad91461 100644 --- a/peer.go +++ b/peer.go @@ -129,7 +129,7 @@ type Peer struct { diverted bool blocksRequested int - Version string + version string } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { @@ -160,7 +160,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { connected: 0, disconnect: 0, caps: caps, - Version: ethutil.Config.ClientString, + version: ethutil.Config.ClientString, } // Set up the connection in another goroutine so we don't block the main thread @@ -184,6 +184,34 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { return p } +// Getters +func (p *Peer) Inbound() bool { + return p.inbound +} +func (p *Peer) LastSend() time.Time { + return p.lastSend +} +func (p *Peer) LastPong() int64 { + return p.lastPong +} +func (p *Peer) Host() []byte { + return p.host +} +func (p *Peer) Port() uint16 { + return p.port +} +func (p *Peer) Version() string { + return p.version +} +func (p *Peer) Connected() *int32 { + return &p.connected +} + +// Setters +func (p *Peer) SetVersion(version string) { + p.version = version +} + // Outputs any RLP encoded data to the peer func (p *Peer) QueueMessage(msg *ethwire.Msg) { if atomic.LoadInt32(&p.connected) != 1 { @@ -531,7 +559,7 @@ func (p *Peer) pushHandshake() error { pubkey := keyRing.PublicKey msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(ProtocolVersion), uint32(0), p.Version, byte(p.caps), p.port, pubkey[1:], + uint32(ProtocolVersion), uint32(0), p.version, byte(p.caps), p.port, pubkey[1:], }) p.QueueMessage(msg) @@ -588,8 +616,12 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { // Set the peer's caps p.caps = Caps(c.Get(3).Byte()) + // Get a reference to the peers version - p.Version = c.Get(2).Str() + versionString := c.Get(2).Str() + if len(versionString) > 0 { + p.SetVersion(c.Get(2).Str()) + } // Catch up with the connected peer if !p.ethereum.IsUpToDate() { @@ -615,7 +647,7 @@ func (p *Peer) String() string { strConnectType = "disconnected" } - return fmt.Sprintf("[%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.Version, p.caps) + return fmt.Sprintf("[%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.version, p.caps) } func (p *Peer) SyncWithPeerToLastKnown() { -- cgit v1.2.3 From 2010fea0888991e978e715477516bc374bb29f01 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Tue, 3 Jun 2014 10:42:55 +0200 Subject: Added faux latency for peeroverview --- peer.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 71ad91461..eed5bec30 100644 --- a/peer.go +++ b/peer.go @@ -130,6 +130,10 @@ type Peer struct { blocksRequested int version string + + // We use this to give some kind of pingtime to a node, not very accurate, could be improved. + pingTime time.Duration + pingStartTime time.Time } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { @@ -185,6 +189,9 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { } // Getters +func (p *Peer) PingTime() string { + return p.pingTime.String() +} func (p *Peer) Inbound() bool { return p.inbound } @@ -246,7 +253,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { // Outbound message handler. Outbound messages are handled here func (p *Peer) HandleOutbound() { // The ping timer. Makes sure that every 2 minutes a ping is send to the peer - pingTimer := time.NewTicker(2 * time.Minute) + pingTimer := time.NewTicker(30 * time.Second) serviceTimer := time.NewTicker(5 * time.Minute) out: @@ -255,12 +262,12 @@ out: // Main message queue. All outbound messages are processed through here case msg := <-p.outputQueue: p.writeMessage(msg) - p.lastSend = time.Now() // Ping timer sends a ping to the peer each 2 minutes case <-pingTimer.C: p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) + p.pingStartTime = time.Now() // Service timer takes care of peer broadcasting, transaction // posting or block posting @@ -290,8 +297,8 @@ clean: // Inbound handler. Inbound messages are received here and passed to the appropriate methods func (p *Peer) HandleInbound() { - for atomic.LoadInt32(&p.disconnect) == 0 { + // HMM? time.Sleep(500 * time.Millisecond) // Wait for a message from the peer @@ -319,6 +326,7 @@ func (p *Peer) HandleInbound() { // last pong so the peer handler knows this peer is still // active. p.lastPong = time.Now().Unix() + p.pingTime = time.Now().Sub(p.pingStartTime) case ethwire.MsgBlockTy: // Get all blocks and process them var block, lastBlock *ethchain.Block @@ -531,11 +539,15 @@ func (p *Peer) Start() { return } - // Run the outbound handler in a new goroutine go p.HandleOutbound() // Run the inbound handler in a new goroutine go p.HandleInbound() + // Wait a few seconds for startup and then ask for an initial ping + time.Sleep(2 * time.Second) + p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) + p.pingStartTime = time.Now() + } func (p *Peer) Stop() { -- cgit v1.2.3 From 771f64397fd8638e9a40a4b9ecc64a9b70d6f2e4 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Tue, 10 Jun 2014 13:51:34 +0200 Subject: Stop peers when they don't respond to ping/pong. Might fix ethereum/go-ethereum#78 --- peer.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index eed5bec30..9cc892d8b 100644 --- a/peer.go +++ b/peer.go @@ -18,6 +18,8 @@ const ( outputBufferSize = 50 // Current protocol version ProtocolVersion = 17 + // Interval for ping/pong message + pingPongTimer = 30 * time.Second ) type DiscReason byte @@ -243,7 +245,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { err := ethwire.WriteMessage(p.conn, msg) if err != nil { - ethutil.Config.Log.Debugln("Can't send message:", err) + ethutil.Config.Log.Debugln("[PEER] Can't send message:", err) // Stop the client if there was an error writing to it p.Stop() return @@ -253,7 +255,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { // Outbound message handler. Outbound messages are handled here func (p *Peer) HandleOutbound() { // The ping timer. Makes sure that every 2 minutes a ping is send to the peer - pingTimer := time.NewTicker(30 * time.Second) + pingTimer := time.NewTicker(pingPongTimer) serviceTimer := time.NewTicker(5 * time.Minute) out: @@ -264,8 +266,14 @@ out: p.writeMessage(msg) p.lastSend = time.Now() - // Ping timer sends a ping to the peer each 2 minutes + // Ping timer case <-pingTimer.C: + timeSince := time.Since(time.Unix(p.lastPong, 0)) + if p.pingStartTime.IsZero() == false && timeSince > (pingPongTimer+10*time.Second) { + ethutil.Config.Log.Infof("[PEER] Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince) + p.Stop() + return + } p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) p.pingStartTime = time.Now() @@ -563,6 +571,7 @@ func (p *Peer) Stop() { // Pre-emptively remove the peer; don't wait for reaping. We already know it's dead if we are here p.ethereum.RemovePeer(p) + ethutil.Config.Log.Debugln("[PEER] Stopped peer:", p.conn.RemoteAddr()) } func (p *Peer) pushHandshake() error { -- cgit v1.2.3 From 1b40f69ce5166fbe8a13709caf31f50107fa3bdf Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Tue, 10 Jun 2014 14:59:38 +0200 Subject: Prevent peer stop crash by removing logging --- peer.go | 1 - 1 file changed, 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 9cc892d8b..80975ff81 100644 --- a/peer.go +++ b/peer.go @@ -571,7 +571,6 @@ func (p *Peer) Stop() { // Pre-emptively remove the peer; don't wait for reaping. We already know it's dead if we are here p.ethereum.RemovePeer(p) - ethutil.Config.Log.Debugln("[PEER] Stopped peer:", p.conn.RemoteAddr()) } func (p *Peer) pushHandshake() error { -- cgit v1.2.3 From 9ee6295c752a518603de01e4feaec787c61a5dcf Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 11 Jun 2014 21:55:45 +0200 Subject: Minor changes --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index eed5bec30..acebd2756 100644 --- a/peer.go +++ b/peer.go @@ -17,7 +17,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 17 + ProtocolVersion = 20 ) type DiscReason byte @@ -603,7 +603,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data if c.Get(0).Uint() != ProtocolVersion { - ethutil.Config.Log.Debugln("Invalid peer version. Require protocol:", ProtocolVersion) + ethutil.Config.Log.Debugf("Invalid peer version. Require protocol: %d. Received: %d\n", ProtocolVersion, c.Get(0).Uint()) p.Stop() return } -- cgit v1.2.3 From 3a9d7d318abb3cd01ecd012ae85da5e586436d65 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 12 Jun 2014 10:07:27 +0200 Subject: log changes --- peer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 80975ff81..c7591ac31 100644 --- a/peer.go +++ b/peer.go @@ -153,6 +153,7 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { pubkey: pubkey, blocksRequested: 10, caps: ethereum.ServerCaps(), + version: ethutil.Config.ClientString, } } @@ -579,7 +580,7 @@ func (p *Peer) pushHandshake() error { pubkey := keyRing.PublicKey msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(ProtocolVersion), uint32(0), p.version, byte(p.caps), p.port, pubkey[1:], + uint32(ProtocolVersion), uint32(0), []byte(p.version), byte(p.caps), p.port, pubkey[1:], }) p.QueueMessage(msg) -- cgit v1.2.3 From 81245473486dd680b7121d4b227ca8a57d07b4b1 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 13 Jun 2014 16:06:27 +0200 Subject: Moving a head closer to interop --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 587bc1974..4434715fb 100644 --- a/peer.go +++ b/peer.go @@ -402,7 +402,7 @@ func (p *Peer) HandleInbound() { if err != nil { // If the parent is unknown try to catch up with this peer if ethchain.IsParentErr(err) { - ethutil.Config.Log.Infoln("Attempting to catch up since we don't know the parent") + ethutil.Config.Log.Infoln("Attempting to catch. Parent known") p.catchingUp = false p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) } else if ethchain.IsValidationErr(err) { @@ -414,7 +414,7 @@ func (p *Peer) HandleInbound() { if p.catchingUp && msg.Data.Len() > 1 { if lastBlock != nil { blockInfo := lastBlock.BlockInfo() - ethutil.Config.Log.Debugf("Synced to block height #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) + ethutil.Config.Log.Debugf("Synced chain to #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) } p.catchingUp = false -- cgit v1.2.3 From 63883bf27d8b87f601e1603e9024a279b91bffb7 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sat, 14 Jun 2014 11:46:09 +0200 Subject: Moving closer to interop --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4434715fb..9da2ed002 100644 --- a/peer.go +++ b/peer.go @@ -19,7 +19,7 @@ const ( // Current protocol version ProtocolVersion = 20 // Interval for ping/pong message - pingPongTimer = 30 * time.Second + pingPongTimer = 1 * time.Second ) type DiscReason byte @@ -270,7 +270,7 @@ out: // Ping timer case <-pingTimer.C: timeSince := time.Since(time.Unix(p.lastPong, 0)) - if p.pingStartTime.IsZero() == false && timeSince > (pingPongTimer+10*time.Second) { + if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+10*time.Second) { ethutil.Config.Log.Infof("[PEER] Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince) p.Stop() return -- cgit v1.2.3 From 6d52da58d9337b786a0c869974daa91ce0e34a98 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sat, 14 Jun 2014 15:44:13 +0200 Subject: Logging mechanism --- peer.go | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 9da2ed002..56dd18c65 100644 --- a/peer.go +++ b/peer.go @@ -244,6 +244,8 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { } } + ethutil.Config.Log.Println(ethutil.LogLevelSystem, "<=", msg.Type, msg.Data) + err := ethwire.WriteMessage(p.conn, msg) if err != nil { ethutil.Config.Log.Debugln("[PEER] Can't send message:", err) @@ -264,6 +266,7 @@ out: select { // Main message queue. All outbound messages are processed through here case msg := <-p.outputQueue: + p.writeMessage(msg) p.lastSend = time.Now() @@ -316,6 +319,8 @@ func (p *Peer) HandleInbound() { ethutil.Config.Log.Debugln(err) } for _, msg := range msgs { + ethutil.Config.Log.Println(ethutil.LogLevelSystem, "=>", msg.Type, msg.Data) + switch msg.Type { case ethwire.MsgHandshakeTy: // Version message -- cgit v1.2.3 From b0e023e43248d09cb273d5b6025d28ee718151c0 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 15 Jun 2014 00:04:18 +0200 Subject: Increase ping timeout to 30 seconds --- peer.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 56dd18c65..0c4d76355 100644 --- a/peer.go +++ b/peer.go @@ -19,7 +19,7 @@ const ( // Current protocol version ProtocolVersion = 20 // Interval for ping/pong message - pingPongTimer = 1 * time.Second + pingPongTimer = 2 * time.Second ) type DiscReason byte @@ -266,14 +266,13 @@ out: select { // Main message queue. All outbound messages are processed through here case msg := <-p.outputQueue: - p.writeMessage(msg) p.lastSend = time.Now() // Ping timer case <-pingTimer.C: timeSince := time.Since(time.Unix(p.lastPong, 0)) - if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+10*time.Second) { + if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+30*time.Second) { ethutil.Config.Log.Infof("[PEER] Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince) p.Stop() return -- cgit v1.2.3 From b836267401b731a2cd17c4866a9727b4a05ec124 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 16 Jun 2014 11:13:37 +0200 Subject: .. --- peer.go | 1 - 1 file changed, 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 0c4d76355..07c93e5b4 100644 --- a/peer.go +++ b/peer.go @@ -158,7 +158,6 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { } func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { - p := &Peer{ outputQueue: make(chan *ethwire.Msg, outputBufferSize), quit: make(chan bool), -- cgit v1.2.3 From 22e16f15a69f53934a61978eb18fdf0244a74a99 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Wed, 18 Jun 2014 10:39:42 +0200 Subject: Reduce peer timeout to 10 seconds --- peer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 07c93e5b4..5362b0f77 100644 --- a/peer.go +++ b/peer.go @@ -124,6 +124,7 @@ type Peer struct { port uint16 caps Caps + // This peer's public key pubkey []byte // Indicated whether the node is catching up or not @@ -171,7 +172,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { // Set up the connection in another goroutine so we don't block the main thread go func() { - conn, err := net.DialTimeout("tcp", addr, 30*time.Second) + conn, err := net.DialTimeout("tcp", addr, 10*time.Second) if err != nil { ethutil.Config.Log.Debugln("Connection to peer failed", err) -- cgit v1.2.3 From 1f7917589822d4327147949c610fad3979819ab3 Mon Sep 17 00:00:00 2001 From: Maran <maran.hidskes@gmail.com> Date: Wed, 18 Jun 2014 13:06:48 +0200 Subject: Reworked peers to check for public key duplication and adding peers to peerlist only after the handshake has come in --- peer.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 5362b0f77..2ece9b359 100644 --- a/peer.go +++ b/peer.go @@ -2,6 +2,7 @@ package eth import ( "bytes" + "container/list" "fmt" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" @@ -615,6 +616,30 @@ func (p *Peer) pushPeers() { func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data + // Set pubkey + p.pubkey = c.Get(5).Bytes() + + if p.pubkey == nil { + //ethutil.Config.Log.Debugln("Pubkey required, not supplied in handshake.") + p.Stop() + return + } + + usedPub := 0 + // This peer is already added to the peerlist so we expect to find a double pubkey at least once + + eachPeer(p.ethereum.Peers(), func(peer *Peer, e *list.Element) { + if bytes.Compare(p.pubkey, peer.pubkey) == 0 { + usedPub++ + } + }) + + if usedPub > 0 { + //ethutil.Config.Log.Debugf("Pubkey %x found more then once. Already connected to client.", p.pubkey) + p.Stop() + return + } + if c.Get(0).Uint() != ProtocolVersion { ethutil.Config.Log.Debugf("Invalid peer version. Require protocol: %d. Received: %d\n", ProtocolVersion, c.Get(0).Uint()) p.Stop() @@ -626,7 +651,6 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { // If this is an inbound connection send an ack back if p.inbound { - p.pubkey = c.Get(5).Bytes() p.port = uint16(c.Get(4).Uint()) // Self connect detection @@ -648,6 +672,11 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.SetVersion(c.Get(2).Str()) } + p.ethereum.PushPeer(p) + p.ethereum.reactor.Post("peerList", p.ethereum.Peers()) + + ethutil.Config.Log.Infof("[SERV] Added peer (%s) %d / %d\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers) + // Catch up with the connected peer if !p.ethereum.IsUpToDate() { ethutil.Config.Log.Debugln("Already syncing up with a peer; sleeping") -- cgit v1.2.3 From 0251fae5ccf6984c558d59cd2b36ef89116c061e Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 20 Jun 2014 01:10:39 +0200 Subject: Changed loggers --- peer.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 2ece9b359..b4bde2c1d 100644 --- a/peer.go +++ b/peer.go @@ -419,7 +419,7 @@ func (p *Peer) HandleInbound() { if p.catchingUp && msg.Data.Len() > 1 { if lastBlock != nil { blockInfo := lastBlock.BlockInfo() - ethutil.Config.Log.Debugf("Synced chain to #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) + ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "Synced chain to #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) } p.catchingUp = false @@ -486,7 +486,7 @@ func (p *Peer) HandleInbound() { // If a parent is found send back a reply if parent != nil { - ethutil.Config.Log.Debugf("[PEER] Found canonical block, returning chain from: %x ", parent.Hash()) + ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "[PEER] Found canonical block, returning chain from: %x ", parent.Hash()) chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) if len(chain) > 0 { //ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) @@ -506,7 +506,7 @@ func (p *Peer) HandleInbound() { } } case ethwire.MsgNotInChainTy: - ethutil.Config.Log.Debugf("Not in chain: %x\n", msg.Data.Get(0).Bytes()) + ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "Not in chain: %x\n", msg.Data.Get(0).Bytes()) if p.diverted == true { // If were already looking for a common parent and we get here again we need to go deeper p.blocksRequested = p.blocksRequested * 2 @@ -727,7 +727,7 @@ func (p *Peer) FindCommonParentBlock() { msgInfo := append(hashes, uint64(len(hashes))) - ethutil.Config.Log.Infof("Asking for block from %x (%d total) from %s\n", p.ethereum.BlockChain().CurrentBlock.Hash(), len(hashes), p.conn.RemoteAddr().String()) + ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "Asking for block from %x (%d total) from %s\n", p.ethereum.BlockChain().CurrentBlock.Hash(), len(hashes), p.conn.RemoteAddr().String()) msg := ethwire.NewMessage(ethwire.MsgGetChainTy, msgInfo) p.QueueMessage(msg) @@ -739,7 +739,7 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) { msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(50)}) p.QueueMessage(msg) - ethutil.Config.Log.Debugf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) + ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) p.QueueMessage(msg) -- cgit v1.2.3 From 9350ecd36fe3a30bea4cfd60db9a53787d4d5852 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 23 Jun 2014 11:24:45 +0200 Subject: Do not keep on asking for the same chain --- peer.go | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index b4bde2c1d..ca4168940 100644 --- a/peer.go +++ b/peer.go @@ -138,6 +138,8 @@ type Peer struct { // We use this to give some kind of pingtime to a node, not very accurate, could be improved. pingTime time.Duration pingStartTime time.Time + + lastRequestedBlock *ethchain.Block } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { @@ -351,6 +353,12 @@ func (p *Peer) HandleInbound() { // We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find // common ground to start syncing from lastBlock = ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len() - 1)) + if p.lastRequestedBlock != nil && bytes.Compare(lastBlock.Hash(), p.lastRequestedBlock.Hash()) == 0 { + p.catchingUp = false + continue + } + p.lastRequestedBlock = lastBlock + ethutil.Config.Log.Infof("[PEER] Last block: %x. Checking if we have it locally.\n", lastBlock.Hash()) for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) -- cgit v1.2.3 From b9e8a3e02493d5bbf23cfcab259e66f6ae166612 Mon Sep 17 00:00:00 2001 From: zelig <viktor.tron@gmail.com> Date: Mon, 23 Jun 2014 12:54:10 +0100 Subject: modified logging API - package vars for tagged loggers - weed out spurious fmt.PrintX and log.PrintX logging - tried to second guess loglevel for some :) --- peer.go | 59 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index b4bde2c1d..fd8a33d65 100644 --- a/peer.go +++ b/peer.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethwire" + "github.com/ethereum/eth-go/ethlog" "net" "strconv" "strings" @@ -14,6 +15,8 @@ import ( "time" ) +var peerlogger = ethlog.NewLogger("PEER") + const ( // The size of the output buffer for writing messages outputBufferSize = 50 @@ -176,7 +179,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { conn, err := net.DialTimeout("tcp", addr, 10*time.Second) if err != nil { - ethutil.Config.Log.Debugln("Connection to peer failed", err) + peerlogger.Debugln("Connection to peer failed", err) p.Stop() return } @@ -245,11 +248,11 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { } } - ethutil.Config.Log.Println(ethutil.LogLevelSystem, "<=", msg.Type, msg.Data) + peerlogger.Infoln("<=", msg.Type, msg.Data) err := ethwire.WriteMessage(p.conn, msg) if err != nil { - ethutil.Config.Log.Debugln("[PEER] Can't send message:", err) + peerlogger.Debugln(" Can't send message:", err) // Stop the client if there was an error writing to it p.Stop() return @@ -274,7 +277,7 @@ out: case <-pingTimer.C: timeSince := time.Since(time.Unix(p.lastPong, 0)) if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+30*time.Second) { - ethutil.Config.Log.Infof("[PEER] Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince) + peerlogger.Infof("Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince) p.Stop() return } @@ -316,10 +319,10 @@ func (p *Peer) HandleInbound() { // Wait for a message from the peer msgs, err := ethwire.ReadMessages(p.conn) if err != nil { - ethutil.Config.Log.Debugln(err) + peerlogger.Debugln(err) } for _, msg := range msgs { - ethutil.Config.Log.Println(ethutil.LogLevelSystem, "=>", msg.Type, msg.Data) + peerlogger.Infoln("=>", msg.Type, msg.Data) switch msg.Type { case ethwire.MsgHandshakeTy: @@ -331,7 +334,7 @@ func (p *Peer) HandleInbound() { } case ethwire.MsgDiscTy: p.Stop() - ethutil.Config.Log.Infoln("Disconnect peer:", DiscReason(msg.Data.Get(0).Uint())) + peerlogger.Infoln("Disconnect peer:", DiscReason(msg.Data.Get(0).Uint())) case ethwire.MsgPingTy: // Respond back with pong p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) @@ -351,7 +354,7 @@ func (p *Peer) HandleInbound() { // We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find // common ground to start syncing from lastBlock = ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len() - 1)) - ethutil.Config.Log.Infof("[PEER] Last block: %x. Checking if we have it locally.\n", lastBlock.Hash()) + peerlogger.Infof("Last block: %x. Checking if we have it locally.\n", lastBlock.Hash()) for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) // Do we have this block on our chain? If so we can continue @@ -372,7 +375,7 @@ func (p *Peer) HandleInbound() { // we just keep increasing the amount of blocks. p.blocksRequested = p.blocksRequested * 2 - ethutil.Config.Log.Infof("[PEER] No common ancestor found, requesting %d more blocks.\n", p.blocksRequested) + peerlogger.Infof("No common ancestor found, requesting %d more blocks.\n", p.blocksRequested) p.catchingUp = false p.FindCommonParentBlock() break @@ -388,9 +391,9 @@ func (p *Peer) HandleInbound() { if err != nil { if ethutil.Config.Debug { - ethutil.Config.Log.Infof("[PEER] Block %x failed\n", block.Hash()) - ethutil.Config.Log.Infof("[PEER] %v\n", err) - ethutil.Config.Log.Debugln(block) + peerlogger.Infof("Block %x failed\n", block.Hash()) + peerlogger.Infof("%v\n", err) + peerlogger.Debugln(block) } break } else { @@ -407,7 +410,7 @@ func (p *Peer) HandleInbound() { if err != nil { // If the parent is unknown try to catch up with this peer if ethchain.IsParentErr(err) { - ethutil.Config.Log.Infoln("Attempting to catch. Parent known") + peerlogger.Infoln("Attempting to catch. Parent known") p.catchingUp = false p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) } else if ethchain.IsValidationErr(err) { @@ -419,7 +422,7 @@ func (p *Peer) HandleInbound() { if p.catchingUp && msg.Data.Len() > 1 { if lastBlock != nil { blockInfo := lastBlock.BlockInfo() - ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "Synced chain to #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) + peerlogger.Infof("Synced chain to #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) } p.catchingUp = false @@ -486,17 +489,17 @@ func (p *Peer) HandleInbound() { // If a parent is found send back a reply if parent != nil { - ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "[PEER] Found canonical block, returning chain from: %x ", parent.Hash()) + peerlogger.Infof("Found canonical block, returning chain from: %x ", parent.Hash()) chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) if len(chain) > 0 { - //ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash()) + //peerlogger.Debugf("Returning %d blocks: %x ", len(chain), parent.Hash()) p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) } else { p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, []interface{}{})) } } else { - //ethutil.Config.Log.Debugf("[PEER] Could not find a similar block") + //peerlogger.Debugf("Could not find a similar block") // If no blocks are found we send back a reply with msg not in chain // and the last hash from get chain if l > 0 { @@ -506,7 +509,7 @@ func (p *Peer) HandleInbound() { } } case ethwire.MsgNotInChainTy: - ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "Not in chain: %x\n", msg.Data.Get(0).Bytes()) + peerlogger.Infof("Not in chain: %x\n", msg.Data.Get(0).Bytes()) if p.diverted == true { // If were already looking for a common parent and we get here again we need to go deeper p.blocksRequested = p.blocksRequested * 2 @@ -527,7 +530,7 @@ func (p *Peer) HandleInbound() { // Unofficial but fun nonetheless case ethwire.MsgTalkTy: - ethutil.Config.Log.Infoln("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.Str()) + peerlogger.Infoln("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.Str()) } } } @@ -546,7 +549,7 @@ func (p *Peer) Start() { err := p.pushHandshake() if err != nil { - ethutil.Config.Log.Debugln("Peer can't send outbound version ack", err) + peerlogger.Debugln("Peer can't send outbound version ack", err) p.Stop() @@ -620,7 +623,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.pubkey = c.Get(5).Bytes() if p.pubkey == nil { - //ethutil.Config.Log.Debugln("Pubkey required, not supplied in handshake.") + peerlogger.Warnln("Pubkey required, not supplied in handshake.") p.Stop() return } @@ -635,13 +638,13 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { }) if usedPub > 0 { - //ethutil.Config.Log.Debugf("Pubkey %x found more then once. Already connected to client.", p.pubkey) + peerlogger.Debugf("Pubkey %x found more then once. Already connected to client.", p.pubkey) p.Stop() return } if c.Get(0).Uint() != ProtocolVersion { - ethutil.Config.Log.Debugf("Invalid peer version. Require protocol: %d. Received: %d\n", ProtocolVersion, c.Get(0).Uint()) + peerlogger.Debugf("Invalid peer version. Require protocol: %d. Received: %d\n", ProtocolVersion, c.Get(0).Uint()) p.Stop() return } @@ -675,16 +678,16 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.ethereum.PushPeer(p) p.ethereum.reactor.Post("peerList", p.ethereum.Peers()) - ethutil.Config.Log.Infof("[SERV] Added peer (%s) %d / %d\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers) + ethlogger.Infof("Added peer (%s) %d / %d\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers) // Catch up with the connected peer if !p.ethereum.IsUpToDate() { - ethutil.Config.Log.Debugln("Already syncing up with a peer; sleeping") + peerlogger.Debugln("Already syncing up with a peer; sleeping") time.Sleep(10 * time.Second) } p.SyncWithPeerToLastKnown() - ethutil.Config.Log.Debugln("[PEER]", p) + peerlogger.Debugln(p) } func (p *Peer) String() string { @@ -727,7 +730,7 @@ func (p *Peer) FindCommonParentBlock() { msgInfo := append(hashes, uint64(len(hashes))) - ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "Asking for block from %x (%d total) from %s\n", p.ethereum.BlockChain().CurrentBlock.Hash(), len(hashes), p.conn.RemoteAddr().String()) + peerlogger.Infof("Asking for block from %x (%d total) from %s\n", p.ethereum.BlockChain().CurrentBlock.Hash(), len(hashes), p.conn.RemoteAddr().String()) msg := ethwire.NewMessage(ethwire.MsgGetChainTy, msgInfo) p.QueueMessage(msg) @@ -739,7 +742,7 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) { msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(50)}) p.QueueMessage(msg) - ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) + peerlogger.Infof("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) p.QueueMessage(msg) -- cgit v1.2.3 From a02edf7a9306c9c0b2f0208152347b47f1a4e689 Mon Sep 17 00:00:00 2001 From: zelig <viktor.tron@gmail.com> Date: Wed, 25 Jun 2014 16:40:06 +0100 Subject: put back extra debug detail logging to the right places using logger.DebugDetailf --- peer.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 18d1da455..2dcdea474 100644 --- a/peer.go +++ b/peer.go @@ -250,7 +250,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { } } - peerlogger.Infoln("<=", msg.Type, msg.Data) + peerlogger.DebugDetailln("<=", msg.Type, msg.Data) err := ethwire.WriteMessage(p.conn, msg) if err != nil { @@ -324,7 +324,7 @@ func (p *Peer) HandleInbound() { peerlogger.Debugln(err) } for _, msg := range msgs { - peerlogger.Infoln("=>", msg.Type, msg.Data) + peerlogger.DebugDetailln("=>", msg.Type, msg.Data) switch msg.Type { case ethwire.MsgHandshakeTy: @@ -429,7 +429,7 @@ func (p *Peer) HandleInbound() { if p.catchingUp && msg.Data.Len() > 1 { if lastBlock != nil { blockInfo := lastBlock.BlockInfo() - peerlogger.Infof("Synced chain to #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) + peerlogger.DebugDetailf("Synced chain to #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) } p.catchingUp = false @@ -496,7 +496,7 @@ func (p *Peer) HandleInbound() { // If a parent is found send back a reply if parent != nil { - peerlogger.Infof("Found canonical block, returning chain from: %x ", parent.Hash()) + peerlogger.DebugDetailf("Found canonical block, returning chain from: %x ", parent.Hash()) chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) if len(chain) > 0 { //peerlogger.Debugf("Returning %d blocks: %x ", len(chain), parent.Hash()) @@ -516,7 +516,7 @@ func (p *Peer) HandleInbound() { } } case ethwire.MsgNotInChainTy: - peerlogger.Infof("Not in chain: %x\n", msg.Data.Get(0).Bytes()) + peerlogger.DebugDetailf("Not in chain: %x\n", msg.Data.Get(0).Bytes()) if p.diverted == true { // If were already looking for a common parent and we get here again we need to go deeper p.blocksRequested = p.blocksRequested * 2 @@ -737,7 +737,7 @@ func (p *Peer) FindCommonParentBlock() { msgInfo := append(hashes, uint64(len(hashes))) - peerlogger.Infof("Asking for block from %x (%d total) from %s\n", p.ethereum.BlockChain().CurrentBlock.Hash(), len(hashes), p.conn.RemoteAddr().String()) + peerlogger.DebugDetailf("Asking for block from %x (%d total) from %s\n", p.ethereum.BlockChain().CurrentBlock.Hash(), len(hashes), p.conn.RemoteAddr().String()) msg := ethwire.NewMessage(ethwire.MsgGetChainTy, msgInfo) p.QueueMessage(msg) @@ -749,7 +749,7 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) { msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(50)}) p.QueueMessage(msg) - peerlogger.Infof("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) + peerlogger.DebugDetailf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) p.QueueMessage(msg) -- cgit v1.2.3 From 853053a3b204ddf4ae935e70e0aa5b5d8994493e Mon Sep 17 00:00:00 2001 From: zelig <viktor.tron@gmail.com> Date: Thu, 26 Jun 2014 18:45:57 +0100 Subject: go fmt --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 2dcdea474..e50fd43f9 100644 --- a/peer.go +++ b/peer.go @@ -5,9 +5,9 @@ import ( "container/list" "fmt" "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethwire" - "github.com/ethereum/eth-go/ethlog" "net" "strconv" "strings" -- cgit v1.2.3 From dabaa4cce01586fd8b1b9314073a1d26f35355c8 Mon Sep 17 00:00:00 2001 From: zelig <viktor.tron@gmail.com> Date: Sun, 29 Jun 2014 18:30:05 +0100 Subject: change all modified calls to ethtrie, ethutil and ethcrypto functions --- peer.go | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index e50fd43f9..ffabb8f49 100644 --- a/peer.go +++ b/peer.go @@ -146,7 +146,7 @@ type Peer struct { } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { - pubkey := ethutil.GetKeyRing().Get(0).PublicKey[1:] + pubkey := ethereum.KeyManager().PublicKey()[1:] return &Peer{ outputQueue: make(chan *ethwire.Msg, outputBufferSize), @@ -590,16 +590,12 @@ func (p *Peer) Stop() { } func (p *Peer) pushHandshake() error { - keyRing := ethutil.GetKeyRing().Get(0) - if keyRing != nil { - pubkey := keyRing.PublicKey - - msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(ProtocolVersion), uint32(0), []byte(p.version), byte(p.caps), p.port, pubkey[1:], - }) + pubkey := p.ethereum.KeyManager().PublicKey() + msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ + uint32(ProtocolVersion), uint32(0), []byte(p.version), byte(p.caps), p.port, pubkey[1:], + }) - p.QueueMessage(msg) - } + p.QueueMessage(msg) return nil } @@ -664,8 +660,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.port = uint16(c.Get(4).Uint()) // Self connect detection - keyPair := ethutil.GetKeyRing().Get(0) - if bytes.Compare(keyPair.PublicKey, p.pubkey) == 0 { + pubkey := p.ethereum.KeyManager().PublicKey() + if bytes.Compare(pubkey, p.pubkey) == 0 { p.Stop() return -- cgit v1.2.3 From d0959063d5f67dccc214f43344d88dce25ca167f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 1 Jul 2014 15:28:12 +0200 Subject: Up --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index e50fd43f9..884e296f6 100644 --- a/peer.go +++ b/peer.go @@ -21,7 +21,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 20 + ProtocolVersion = 21 // Interval for ping/pong message pingPongTimer = 2 * time.Second ) -- cgit v1.2.3 From bb2433ca1a953e610396707a67ca5eb73574e81f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 1 Jul 2014 20:32:47 +0200 Subject: Added quitting reason --- peer.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index a4da1591b..8e14c7460 100644 --- a/peer.go +++ b/peer.go @@ -40,17 +40,19 @@ const ( DiscConnDup = 0x05 DiscGenesisErr = 0x06 DiscProtoErr = 0x07 + DiscQuitting = 0x08 ) var discReasonToString = []string{ - "Disconnect requested", - "Disconnect TCP sys error", - "Disconnect bad protocol", - "Disconnect useless peer", - "Disconnect too many peers", - "Disconnect already connected", - "Disconnect wrong genesis block", - "Disconnect incompatible network", + "requested", + "TCP sys error", + "bad protocol", + "useless peer", + "too many peers", + "already connected", + "wrong genesis block", + "incompatible network", + "quitting", } func (d DiscReason) String() string { -- cgit v1.2.3 From 90c2064640984be95e493c57c3dc8dd5134e23e9 Mon Sep 17 00:00:00 2001 From: zelig <viktor.tron@gmail.com> Date: Thu, 3 Jul 2014 17:30:37 +0100 Subject: peer constructors now set version string with ethereum.ClientIdentity().String() --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 8e14c7460..a93d22d93 100644 --- a/peer.go +++ b/peer.go @@ -162,7 +162,7 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { pubkey: pubkey, blocksRequested: 10, caps: ethereum.ServerCaps(), - version: ethutil.Config.ClientString, + version: ethereum.ClientIdentity().String(), } } @@ -175,7 +175,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { connected: 0, disconnect: 0, caps: caps, - version: ethutil.Config.ClientString, + version: ethereum.ClientIdentity().String(), } // Set up the connection in another goroutine so we don't block the main thread -- cgit v1.2.3 From ec040908e9e69e524811b6ade95227a3764de4ae Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 7 Jul 2014 10:52:39 +0200 Subject: Protocol bump --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index a93d22d93..e11ac0a57 100644 --- a/peer.go +++ b/peer.go @@ -21,7 +21,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 21 + ProtocolVersion = 22 // Interval for ping/pong message pingPongTimer = 2 * time.Second ) -- cgit v1.2.3 From 6cb35836a20e54765a06f64d9df667e6742d3cfa Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 7 Jul 2014 16:06:09 +0200 Subject: Upped protocol version number --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index e11ac0a57..cc2863a33 100644 --- a/peer.go +++ b/peer.go @@ -21,7 +21,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 22 + ProtocolVersion = 23 // Interval for ping/pong message pingPongTimer = 2 * time.Second ) -- cgit v1.2.3 From 639f1fd3396419fb712b875cfacc333538fcc4f3 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 10 Jul 2014 15:03:26 +0200 Subject: Log received and send to --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index cc2863a33..13b81d1a8 100644 --- a/peer.go +++ b/peer.go @@ -252,7 +252,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { } } - peerlogger.DebugDetailln("<=", msg.Type, msg.Data) + peerlogger.DebugDetailf("(%v) <= %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data) err := ethwire.WriteMessage(p.conn, msg) if err != nil { @@ -326,7 +326,7 @@ func (p *Peer) HandleInbound() { peerlogger.Debugln(err) } for _, msg := range msgs { - peerlogger.DebugDetailln("=>", msg.Type, msg.Data) + peerlogger.DebugDetailf("(%v) => %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data) switch msg.Type { case ethwire.MsgHandshakeTy: -- cgit v1.2.3 From ee3ba0b1d611401864bf0a646e9608d5ba03be34 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 13 Jul 2014 17:45:39 +0200 Subject: Catch up per 10 --- peer.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 13b81d1a8..0a4f08af5 100644 --- a/peer.go +++ b/peer.go @@ -419,6 +419,16 @@ func (p *Peer) HandleInbound() { if err != nil { // If the parent is unknown try to catch up with this peer if ethchain.IsParentErr(err) { + /* + b := ethchain.NewBlockFromRlpValue(msg.Data.Get(0)) + + peerlogger.Infof("Attempting to catch (%x). Parent known\n", b.Hash()) + p.catchingUp = false + + p.CatchupWithPeer(b.Hash()) + + peerlogger.Infoln(b) + */ peerlogger.Infoln("Attempting to catch. Parent known") p.catchingUp = false p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) @@ -744,7 +754,7 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) { if !p.catchingUp { // Make sure nobody else is catching up when you want to do this p.catchingUp = true - msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(50)}) + msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(10)}) p.QueueMessage(msg) peerlogger.DebugDetailf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) -- cgit v1.2.3 From 2c46bfde8b65c3df0e7ee26955c0e0bd1ddf8873 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 14 Jul 2014 00:37:41 +0200 Subject: Increased block request --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 0a4f08af5..8c622aa5c 100644 --- a/peer.go +++ b/peer.go @@ -754,7 +754,7 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) { if !p.catchingUp { // Make sure nobody else is catching up when you want to do this p.catchingUp = true - msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(10)}) + msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(30)}) p.QueueMessage(msg) peerlogger.DebugDetailf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) -- cgit v1.2.3 From 8820d4e5ac4db36ac6466fb2ee36bcff9e773558 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 15 Jul 2014 20:36:11 +0200 Subject: Decreased timeout --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 8c622aa5c..1e354ca6d 100644 --- a/peer.go +++ b/peer.go @@ -319,7 +319,7 @@ func (p *Peer) HandleInbound() { for atomic.LoadInt32(&p.disconnect) == 0 { // HMM? - time.Sleep(500 * time.Millisecond) + time.Sleep(50 * time.Millisecond) // Wait for a message from the peer msgs, err := ethwire.ReadMessages(p.conn) if err != nil { -- cgit v1.2.3 From 449b9a9d688eaf6a8628a3ae9fa1dd3496f99c71 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 18 Jul 2014 11:57:44 +0200 Subject: Check if version in known + fix --- peer.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 1e354ca6d..a900a3192 100644 --- a/peer.go +++ b/peer.go @@ -328,6 +328,7 @@ func (p *Peer) HandleInbound() { for _, msg := range msgs { peerlogger.DebugDetailf("(%v) => %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data) + nextMsg: switch msg.Type { case ethwire.MsgHandshakeTy: // Version message @@ -373,6 +374,7 @@ func (p *Peer) HandleInbound() { p.diverted = false if !p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) { p.SyncWithPeerToLastKnown() + break nextMsg } break } @@ -385,10 +387,11 @@ func (p *Peer) HandleInbound() { p.blocksRequested = p.blocksRequested * 2 peerlogger.Infof("No common ancestor found, requesting %d more blocks.\n", p.blocksRequested) - p.catchingUp = false p.FindCommonParentBlock() - break + break nextMsg } + + p.catchingUp = false } for i := msg.Data.Len() - 1; i >= 0; i-- { -- cgit v1.2.3 From 61cc2ba7d960b2e82886223b78190d552529cb12 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 18 Jul 2014 13:00:22 +0200 Subject: fixed --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index a900a3192..89032364e 100644 --- a/peer.go +++ b/peer.go @@ -413,7 +413,7 @@ func (p *Peer) HandleInbound() { } } - if msg.Data.Len() == 0 { + if msg.Data.Len() <= 1 { // Set catching up to false if // the peer has nothing left to give p.catchingUp = false -- cgit v1.2.3 From 32d125131f602d63f66ee7eb09439074f0b94a91 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 24 Jul 2014 12:04:15 +0200 Subject: Refactored to new state and vm --- peer.go | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 89032364e..1b8ebb5a4 100644 --- a/peer.go +++ b/peer.go @@ -470,23 +470,20 @@ func (p *Peer) HandleInbound() { p.pushPeers() case ethwire.MsgPeersTy: // Received a list of peers (probably because MsgGetPeersTy was send) - // Only act on message if we actually requested for a peers list - if p.requestedPeerList { - data := msg.Data - // Create new list of possible peers for the ethereum to process - peers := make([]string, data.Len()) - // Parse each possible peer - for i := 0; i < data.Len(); i++ { - value := data.Get(i) - peers[i] = unpackAddr(value.Get(0), value.Get(1).Uint()) - } + data := msg.Data + // Create new list of possible peers for the ethereum to process + peers := make([]string, data.Len()) + // Parse each possible peer + for i := 0; i < data.Len(); i++ { + value := data.Get(i) + peers[i] = unpackAddr(value.Get(0), value.Get(1).Uint()) + } - // Connect to the list of peers - p.ethereum.ProcessPeerList(peers) - // Mark unrequested again - p.requestedPeerList = false + // Connect to the list of peers + p.ethereum.ProcessPeerList(peers) + // Mark unrequested again + p.requestedPeerList = false - } case ethwire.MsgGetChainTy: var parent *ethchain.Block // Length minus one since the very last element in the array is a count -- cgit v1.2.3 From 306b5bcff306bbdc5bc0b1590fca552f4fda41f6 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 24 Jul 2014 12:11:30 +0200 Subject: Changed catching up code & peer handler * Peers should be added no matter what * Catch up with _anyone_ --- peer.go | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 1b8ebb5a4..16340cda5 100644 --- a/peer.go +++ b/peer.go @@ -122,9 +122,6 @@ type Peer struct { // Last received pong message lastPong int64 - // Indicates whether a MsgGetPeersTy was requested of the peer - // this to prevent receiving false peers. - requestedPeerList bool host []byte port uint16 @@ -463,9 +460,6 @@ func (p *Peer) HandleInbound() { p.ethereum.TxPool().QueueTransaction(tx) } case ethwire.MsgGetPeersTy: - // Flag this peer as a 'requested of new peers' this to - // prevent malicious peers being forced. - p.requestedPeerList = true // Peer asked for list of connected peers p.pushPeers() case ethwire.MsgPeersTy: @@ -481,9 +475,6 @@ func (p *Peer) HandleInbound() { // Connect to the list of peers p.ethereum.ProcessPeerList(peers) - // Mark unrequested again - p.requestedPeerList = false - case ethwire.MsgGetChainTy: var parent *ethchain.Block // Length minus one since the very last element in the array is a count @@ -695,11 +686,13 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { ethlogger.Infof("Added peer (%s) %d / %d\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers) - // Catch up with the connected peer - if !p.ethereum.IsUpToDate() { - peerlogger.Debugln("Already syncing up with a peer; sleeping") - time.Sleep(10 * time.Second) - } + /* + // Catch up with the connected peer + if !p.ethereum.IsUpToDate() { + peerlogger.Debugln("Already syncing up with a peer; sleeping") + time.Sleep(10 * time.Second) + } + */ p.SyncWithPeerToLastKnown() peerlogger.Debugln(p) -- cgit v1.2.3 From 6d69ca36a755ea44e7ce4ba7b135afb0b9dbff05 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 24 Jul 2014 12:25:41 +0200 Subject: Peer reconnect attempt --- peer.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 16340cda5..ac4ba82ab 100644 --- a/peer.go +++ b/peer.go @@ -177,10 +177,20 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { // Set up the connection in another goroutine so we don't block the main thread go func() { - conn, err := net.DialTimeout("tcp", addr, 10*time.Second) + var ( + err error + conn net.Conn + ) + + for attempts := 0; attempts < 5; attempts++ { + conn, err = net.DialTimeout("tcp", addr, 10*time.Second) + if err != nil { + peerlogger.Debugf("Peer connection failed. Retrying (%d/5)\n", attempts+1) + } + } if err != nil { - peerlogger.Debugln("Connection to peer failed", err) + peerlogger.Debugln("Connection to peer failed. Giving up.", err) p.Stop() return } -- cgit v1.2.3 From dcf4fad97156f431612ed3915e167ce5a5314588 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 24 Jul 2014 12:30:04 +0200 Subject: Networking code --- peer.go | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ac4ba82ab..c73617ed5 100644 --- a/peer.go +++ b/peer.go @@ -177,18 +177,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { // Set up the connection in another goroutine so we don't block the main thread go func() { - var ( - err error - conn net.Conn - ) - - for attempts := 0; attempts < 5; attempts++ { - conn, err = net.DialTimeout("tcp", addr, 10*time.Second) - if err != nil { - peerlogger.Debugf("Peer connection failed. Retrying (%d/5)\n", attempts+1) - } - } - + conn, err := p.Connect(addr) if err != nil { peerlogger.Debugln("Connection to peer failed. Giving up.", err) p.Stop() @@ -206,6 +195,21 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { return p } +func (self *Peer) Connect(addr string) (conn net.Conn, err error) { + for attempts := 0; attempts < 5; attempts++ { + conn, err = net.DialTimeout("tcp", addr, 10*time.Second) + if err != nil { + peerlogger.Debugf("Peer connection failed. Retrying (%d/5)\n", attempts+1) + continue + } + + // Success + return + } + + return +} + // Getters func (p *Peer) PingTime() string { return p.pingTime.String() -- cgit v1.2.3 From 7ee49c32b70b0bd3e9709865c0b9c43d16c8f18c Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 24 Jul 2014 17:10:54 +0200 Subject: Added update method and general service timer * disable catching up if no block received for longer than 10 seconds --- peer.go | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index c73617ed5..ffba695ca 100644 --- a/peer.go +++ b/peer.go @@ -121,7 +121,8 @@ type Peer struct { versionKnown bool // Last received pong message - lastPong int64 + lastPong int64 + lastBlockReceived time.Time host []byte port uint16 @@ -408,10 +409,7 @@ func (p *Peer) HandleInbound() { for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) - //p.ethereum.StateManager().PrepareDefault(block) - //state := p.ethereum.StateManager().CurrentState() err = p.ethereum.StateManager().Process(block, false) - if err != nil { if ethutil.Config.Debug { peerlogger.Infof("Block %x failed\n", block.Hash()) @@ -422,6 +420,8 @@ func (p *Peer) HandleInbound() { } else { lastBlock = block } + + p.lastBlockReceived = time.Now() } if msg.Data.Len() <= 1 { @@ -561,6 +561,25 @@ func (p *Peer) HandleInbound() { p.Stop() } +// General update method +func (self *Peer) update() { + serviceTimer := time.NewTicker(5 * time.Second) + +out: + for { + select { + case <-serviceTimer.C: + if time.Since(self.lastBlockReceived) > 10*time.Second { + self.catchingUp = false + } + case <-self.quit: + break out + } + } + + serviceTimer.Stop() +} + func (p *Peer) Start() { peerHost, peerPort, _ := net.SplitHostPort(p.conn.LocalAddr().String()) servHost, servPort, _ := net.SplitHostPort(p.conn.RemoteAddr().String()) @@ -583,6 +602,8 @@ func (p *Peer) Start() { go p.HandleOutbound() // Run the inbound handler in a new goroutine go p.HandleInbound() + // Run the general update handler + go p.update() // Wait a few seconds for startup and then ask for an initial ping time.Sleep(2 * time.Second) -- cgit v1.2.3 From 41bd38147c2e5968283facf641b2444c09f53d14 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sat, 26 Jul 2014 11:24:44 +0200 Subject: Clean up and util methods --- peer.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ffba695ca..691a2f575 100644 --- a/peer.go +++ b/peer.go @@ -4,15 +4,16 @@ import ( "bytes" "container/list" "fmt" - "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethlog" - "github.com/ethereum/eth-go/ethutil" - "github.com/ethereum/eth-go/ethwire" "net" "strconv" "strings" "sync/atomic" "time" + + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethlog" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethwire" ) var peerlogger = ethlog.NewLogger("PEER") @@ -197,10 +198,12 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { } func (self *Peer) Connect(addr string) (conn net.Conn, err error) { - for attempts := 0; attempts < 5; attempts++ { + const maxTries = 3 + for attempts := 0; attempts < maxTries; attempts++ { conn, err = net.DialTimeout("tcp", addr, 10*time.Second) if err != nil { - peerlogger.Debugf("Peer connection failed. Retrying (%d/5)\n", attempts+1) + //peerlogger.Debugf("Peer connection failed. Retrying (%d/%d) (%s)\n", attempts+1, maxTries, addr) + time.Sleep(time.Duration(attempts*20) * time.Second) continue } -- cgit v1.2.3 From d1d2b660dcc3c7539940a5e3d5a48ad10487bd8f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 29 Jul 2014 15:55:08 +0200 Subject: Prot --- peer.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 691a2f575..f4314e35c 100644 --- a/peer.go +++ b/peer.go @@ -22,7 +22,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 23 + ProtocolVersion = 25 // Interval for ping/pong message pingPongTimer = 2 * time.Second ) @@ -436,19 +436,20 @@ func (p *Peer) HandleInbound() { if err != nil { // If the parent is unknown try to catch up with this peer if ethchain.IsParentErr(err) { - /* - b := ethchain.NewBlockFromRlpValue(msg.Data.Get(0)) + b := ethchain.NewBlockFromRlpValue(msg.Data.Get(0)) + + peerlogger.Infof("Attempting to catch (%x). Parent unknown\n", b.Hash()) + p.catchingUp = false - peerlogger.Infof("Attempting to catch (%x). Parent known\n", b.Hash()) - p.catchingUp = false + p.CatchupWithPeer(b.Hash()) - p.CatchupWithPeer(b.Hash()) + peerlogger.Infoln(b) - peerlogger.Infoln(b) + /* + peerlogger.Infoln("Attempting to catch. Parent known") + p.catchingUp = false + p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) */ - peerlogger.Infoln("Attempting to catch. Parent known") - p.catchingUp = false - p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) } else if ethchain.IsValidationErr(err) { fmt.Println("Err:", err) p.catchingUp = false -- cgit v1.2.3 From 27f892265312255811867fab83acbeefa1626cec Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 29 Jul 2014 23:34:21 +0200 Subject: Increased block request amount --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index f4314e35c..d977b2086 100644 --- a/peer.go +++ b/peer.go @@ -786,7 +786,7 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) { if !p.catchingUp { // Make sure nobody else is catching up when you want to do this p.catchingUp = true - msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(30)}) + msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(100)}) p.QueueMessage(msg) peerlogger.DebugDetailf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) -- cgit v1.2.3 From 42d47ecfb09ac0b419db5722602d9b02e21f2457 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 30 Jul 2014 11:26:38 +0200 Subject: Removed peer disconnect on pong timeout. Fixes #106 This mechanism wasn't very accurate so it has been removed. --- peer.go | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index d977b2086..4b0523e70 100644 --- a/peer.go +++ b/peer.go @@ -294,12 +294,14 @@ out: // Ping timer case <-pingTimer.C: - timeSince := time.Since(time.Unix(p.lastPong, 0)) - if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+30*time.Second) { - peerlogger.Infof("Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince) - p.Stop() - return - } + /* + timeSince := time.Since(time.Unix(p.lastPong, 0)) + if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+30*time.Second) { + peerlogger.Infof("Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince) + p.Stop() + return + } + */ p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) p.pingStartTime = time.Now() @@ -354,7 +356,7 @@ func (p *Peer) HandleInbound() { } case ethwire.MsgDiscTy: p.Stop() - peerlogger.Infoln("Disconnect peer:", DiscReason(msg.Data.Get(0).Uint())) + peerlogger.Infoln("Disconnect peer: ", DiscReason(msg.Data.Get(0).Uint())) case ethwire.MsgPingTy: // Respond back with pong p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) @@ -363,11 +365,17 @@ func (p *Peer) HandleInbound() { // last pong so the peer handler knows this peer is still // active. p.lastPong = time.Now().Unix() - p.pingTime = time.Now().Sub(p.pingStartTime) + p.pingTime = time.Since(p.pingStartTime) case ethwire.MsgBlockTy: // Get all blocks and process them - var block, lastBlock *ethchain.Block - var err error + //var block, lastBlock *ethchain.Block + //var err error + + var ( + block, lastBlock *ethchain.Block + blockChain = p.ethereum.BlockChain() + err error + ) // Make sure we are actually receiving anything if msg.Data.Len()-1 > 1 && p.diverted { @@ -383,11 +391,11 @@ func (p *Peer) HandleInbound() { for i := msg.Data.Len() - 1; i >= 0; i-- { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) // Do we have this block on our chain? If so we can continue - if !p.ethereum.StateManager().BlockChain().HasBlock(block.Hash()) { + if !blockChain.HasBlock(block.Hash()) { // We don't have this block, but we do have a block with the same prevHash, diversion time! - if p.ethereum.StateManager().BlockChain().HasBlockWithPrevHash(block.PrevHash) { + if blockChain.HasBlockWithPrevHash(block.PrevHash) { p.diverted = false - if !p.ethereum.StateManager().BlockChain().FindCanonicalChainFromMsg(msg, block.PrevHash) { + if !blockChain.FindCanonicalChainFromMsg(msg, block.PrevHash) { p.SyncWithPeerToLastKnown() break nextMsg } -- cgit v1.2.3 From 5ede1224e48fd82961bd4a0b2ec1a3eda0b6d99b Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 1 Aug 2014 10:21:43 +0200 Subject: minor rlp things --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4b0523e70..fa683e488 100644 --- a/peer.go +++ b/peer.go @@ -403,7 +403,7 @@ func (p *Peer) HandleInbound() { } } } - if !p.ethereum.StateManager().BlockChain().HasBlock(lastBlock.Hash()) { + if !blockChain.HasBlock(lastBlock.Hash()) { // If we can't find a common ancenstor we need to request more blocks. // FIXME: At one point this won't scale anymore since we are not asking for an offset // we just keep increasing the amount of blocks. -- cgit v1.2.3 From 7272577fe651a20618cf428475e2e57976c9599d Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 7 Aug 2014 15:11:54 +0200 Subject: Added dns lookup --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index fa683e488..bd20bb2b9 100644 --- a/peer.go +++ b/peer.go @@ -449,7 +449,7 @@ func (p *Peer) HandleInbound() { peerlogger.Infof("Attempting to catch (%x). Parent unknown\n", b.Hash()) p.catchingUp = false - p.CatchupWithPeer(b.Hash()) + p.CatchupWithPeer(b.PrevHash) peerlogger.Infoln(b) -- cgit v1.2.3 From 42d2bc28affe9bbd8d57a5eb3deab804e5c4a206 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sat, 9 Aug 2014 18:10:11 +0100 Subject: Upped protocol version --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index bd20bb2b9..4cbe8b652 100644 --- a/peer.go +++ b/peer.go @@ -22,7 +22,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 25 + ProtocolVersion = 26 // Interval for ping/pong message pingPongTimer = 2 * time.Second ) -- cgit v1.2.3 From eaa2e8900d1036e09b002c4e20fc6e4f9cd031bb Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 21 Aug 2014 14:47:58 +0200 Subject: PoC 6 networking code. * Added block pool for gathering blocks from the network (chunks) * Re wrote syncing --- peer.go | 286 ++++++++++++++++++++++++++-------------------------------------- 1 file changed, 114 insertions(+), 172 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4cbe8b652..4e6fc55d4 100644 --- a/peer.go +++ b/peer.go @@ -4,6 +4,8 @@ import ( "bytes" "container/list" "fmt" + "math" + "math/big" "net" "strconv" "strings" @@ -22,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 26 + ProtocolVersion = 27 // Interval for ping/pong message pingPongTimer = 2 * time.Second ) @@ -125,9 +127,13 @@ type Peer struct { lastPong int64 lastBlockReceived time.Time - host []byte - port uint16 - caps Caps + host []byte + port uint16 + caps Caps + td *big.Int + bestHash []byte + lastReceivedHash []byte + requestedHashes [][]byte // This peer's public key pubkey []byte @@ -345,7 +351,6 @@ func (p *Peer) HandleInbound() { for _, msg := range msgs { peerlogger.DebugDetailf("(%v) => %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data) - nextMsg: switch msg.Type { case ethwire.MsgHandshakeTy: // Version message @@ -354,6 +359,7 @@ func (p *Peer) HandleInbound() { if p.caps.IsCap(CapPeerDiscTy) { p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) } + case ethwire.MsgDiscTy: p.Stop() peerlogger.Infoln("Disconnect peer: ", DiscReason(msg.Data.Get(0).Uint())) @@ -366,117 +372,6 @@ func (p *Peer) HandleInbound() { // active. p.lastPong = time.Now().Unix() p.pingTime = time.Since(p.pingStartTime) - case ethwire.MsgBlockTy: - // Get all blocks and process them - //var block, lastBlock *ethchain.Block - //var err error - - var ( - block, lastBlock *ethchain.Block - blockChain = p.ethereum.BlockChain() - err error - ) - - // Make sure we are actually receiving anything - if msg.Data.Len()-1 > 1 && p.diverted { - // We requested blocks and now we need to make sure we have a common ancestor somewhere in these blocks so we can find - // common ground to start syncing from - lastBlock = ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len() - 1)) - if p.lastRequestedBlock != nil && bytes.Compare(lastBlock.Hash(), p.lastRequestedBlock.Hash()) == 0 { - p.catchingUp = false - continue - } - p.lastRequestedBlock = lastBlock - peerlogger.Infof("Last block: %x. Checking if we have it locally.\n", lastBlock.Hash()) - for i := msg.Data.Len() - 1; i >= 0; i-- { - block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) - // Do we have this block on our chain? If so we can continue - if !blockChain.HasBlock(block.Hash()) { - // We don't have this block, but we do have a block with the same prevHash, diversion time! - if blockChain.HasBlockWithPrevHash(block.PrevHash) { - p.diverted = false - if !blockChain.FindCanonicalChainFromMsg(msg, block.PrevHash) { - p.SyncWithPeerToLastKnown() - break nextMsg - } - break - } - } - } - if !blockChain.HasBlock(lastBlock.Hash()) { - // If we can't find a common ancenstor we need to request more blocks. - // FIXME: At one point this won't scale anymore since we are not asking for an offset - // we just keep increasing the amount of blocks. - p.blocksRequested = p.blocksRequested * 2 - - peerlogger.Infof("No common ancestor found, requesting %d more blocks.\n", p.blocksRequested) - p.FindCommonParentBlock() - break nextMsg - } - - p.catchingUp = false - } - - for i := msg.Data.Len() - 1; i >= 0; i-- { - block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) - - err = p.ethereum.StateManager().Process(block, false) - if err != nil { - if ethutil.Config.Debug { - peerlogger.Infof("Block %x failed\n", block.Hash()) - peerlogger.Infof("%v\n", err) - peerlogger.Debugln(block) - } - break - } else { - lastBlock = block - } - - p.lastBlockReceived = time.Now() - } - - if msg.Data.Len() <= 1 { - // Set catching up to false if - // the peer has nothing left to give - p.catchingUp = false - } - - if err != nil { - // If the parent is unknown try to catch up with this peer - if ethchain.IsParentErr(err) { - b := ethchain.NewBlockFromRlpValue(msg.Data.Get(0)) - - peerlogger.Infof("Attempting to catch (%x). Parent unknown\n", b.Hash()) - p.catchingUp = false - - p.CatchupWithPeer(b.PrevHash) - - peerlogger.Infoln(b) - - /* - peerlogger.Infoln("Attempting to catch. Parent known") - p.catchingUp = false - p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) - */ - } else if ethchain.IsValidationErr(err) { - fmt.Println("Err:", err) - p.catchingUp = false - } - } else { - // If we're catching up, try to catch up further. - if p.catchingUp && msg.Data.Len() > 1 { - if lastBlock != nil { - blockInfo := lastBlock.BlockInfo() - peerlogger.DebugDetailf("Synced chain to #%d %x %x\n", blockInfo.Number, lastBlock.Hash(), blockInfo.Hash) - } - - p.catchingUp = false - - hash := p.ethereum.BlockChain().CurrentBlock.Hash() - p.CatchupWithPeer(hash) - } - } - case ethwire.MsgTxTy: // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and @@ -501,78 +396,114 @@ func (p *Peer) HandleInbound() { // Connect to the list of peers p.ethereum.ProcessPeerList(peers) - case ethwire.MsgGetChainTy: - var parent *ethchain.Block - // Length minus one since the very last element in the array is a count - l := msg.Data.Len() - 1 - // Ignore empty get chains - if l == 0 { - break + case ethwire.MsgGetTxsTy: + // Get the current transactions of the pool + txs := p.ethereum.TxPool().CurrentTransactions() + // Get the RlpData values from the txs + txsInterface := make([]interface{}, len(txs)) + for i, tx := range txs { + txsInterface[i] = tx.RlpData() + } + // Broadcast it back to the peer + p.QueueMessage(ethwire.NewMessage(ethwire.MsgTxTy, txsInterface)) + + case ethwire.MsgGetBlockHashesTy: + if msg.Data.Len() < 2 { + peerlogger.Debugln("err: argument length invalid ", msg.Data.Len()) } - // Amount of parents in the canonical chain - //amountOfBlocks := msg.Data.Get(l).AsUint() - amountOfBlocks := uint64(100) + hash := msg.Data.Get(0).Bytes() + amount := msg.Data.Get(1).Uint() - // Check each SHA block hash from the message and determine whether - // the SHA is in the database - for i := 0; i < l; i++ { - if data := msg.Data.Get(i).Bytes(); p.ethereum.StateManager().BlockChain().HasBlock(data) { - parent = p.ethereum.BlockChain().GetBlock(data) - break + hashes := p.ethereum.BlockChain().GetChainHashesFromHash(hash, amount) + + p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockHashesTy, ethutil.ByteSliceToInterface(hashes))) + + case ethwire.MsgGetBlocksTy: + // Limit to max 300 blocks + max := int(math.Min(float64(msg.Data.Len()), 300.0)) + var blocks []interface{} + + for i := 0; i < max; i++ { + hash := msg.Data.Get(i).Bytes() + block := p.ethereum.BlockChain().GetBlock(hash) + if block != nil { + blocks = append(blocks, block.Value().Raw()) } } - // If a parent is found send back a reply - if parent != nil { - peerlogger.DebugDetailf("Found canonical block, returning chain from: %x ", parent.Hash()) - chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks) - if len(chain) > 0 { - //peerlogger.Debugf("Returning %d blocks: %x ", len(chain), parent.Hash()) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, chain)) - } else { - p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, []interface{}{})) - } + p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, blocks)) - } else { - //peerlogger.Debugf("Could not find a similar block") - // If no blocks are found we send back a reply with msg not in chain - // and the last hash from get chain - if l > 0 { - lastHash := msg.Data.Get(l - 1) - //log.Printf("Sending not in chain with hash %x\n", lastHash.AsRaw()) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgNotInChainTy, []interface{}{lastHash.Raw()})) + case ethwire.MsgBlockHashesTy: + blockPool := p.ethereum.blockPool + + foundCommonHash := false + + it := msg.Data.NewIterator() + for it.Next() { + hash := it.Value().Bytes() + + if blockPool.HasCommonHash(hash) { + foundCommonHash = true + + break } + + blockPool.AddHash(hash) + + p.lastReceivedHash = hash } - case ethwire.MsgNotInChainTy: - peerlogger.DebugDetailf("Not in chain: %x\n", msg.Data.Get(0).Bytes()) - if p.diverted == true { - // If were already looking for a common parent and we get here again we need to go deeper - p.blocksRequested = p.blocksRequested * 2 + + if foundCommonHash { + p.FetchBlocks() + } else { + p.FetchHashes() } - p.diverted = true - p.catchingUp = false - p.FindCommonParentBlock() - case ethwire.MsgGetTxsTy: - // Get the current transactions of the pool - txs := p.ethereum.TxPool().CurrentTransactions() - // Get the RlpData values from the txs - txsInterface := make([]interface{}, len(txs)) - for i, tx := range txs { - txsInterface[i] = tx.RlpData() + case ethwire.MsgBlockTy: + blockPool := p.ethereum.blockPool + + it := msg.Data.NewIterator() + + for it.Next() { + block := ethchain.NewBlockFromRlpValue(it.Value()) + blockPool.SetBlock(block) } - // Broadcast it back to the peer - p.QueueMessage(ethwire.NewMessage(ethwire.MsgTxTy, txsInterface)) - // Unofficial but fun nonetheless - case ethwire.MsgTalkTy: - peerlogger.Infoln("%v says: %s\n", p.conn.RemoteAddr(), msg.Data.Str()) + linked := blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { + p.ethereum.StateManager().Process(block, false) + }) + + if !linked { + p.FetchBlocks() + } } } } + p.Stop() } +func (self *Peer) FetchBlocks() { + blockPool := self.ethereum.blockPool + + hashes := blockPool.Take(100, self) + if len(hashes) > 0 { + self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlocksTy, ethutil.ByteSliceToInterface(hashes))) + } +} + +func (self *Peer) FetchHashes() { + blockPool := self.ethereum.blockPool + + if self.td.Cmp(blockPool.td) >= 0 { + peerlogger.Debugf("Requesting hashes from %x\n", self.lastReceivedHash) + + if !blockPool.HasLatestHash() { + self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(200)})) + } + } +} + // General update method func (self *Peer) update() { serviceTimer := time.NewTicker(5 * time.Second) @@ -643,6 +574,7 @@ func (p *Peer) pushHandshake() error { pubkey := p.ethereum.KeyManager().PublicKey() msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ uint32(ProtocolVersion), uint32(0), []byte(p.version), byte(p.caps), p.port, pubkey[1:], + p.ethereum.BlockChain().TD.Uint64(), p.ethereum.BlockChain().CurrentBlock.Hash(), }) p.QueueMessage(msg) @@ -728,10 +660,15 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.SetVersion(c.Get(2).Str()) } + // Get the td and last hash + p.td = c.Get(6).BigInt() + p.bestHash = c.Get(7).Bytes() + p.lastReceivedHash = p.bestHash + p.ethereum.PushPeer(p) p.ethereum.reactor.Post("peerList", p.ethereum.Peers()) - ethlogger.Infof("Added peer (%s) %d / %d\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers) + ethlogger.Infof("Added peer (%s) %d / %d (TD = %v ~ %x)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, p.td, p.bestHash) /* // Catch up with the connected peer @@ -740,7 +677,12 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { time.Sleep(10 * time.Second) } */ - p.SyncWithPeerToLastKnown() + //p.SyncWithPeerToLastKnown() + + if p.td.Cmp(p.ethereum.BlockChain().TD) > 0 { + p.ethereum.blockPool.AddHash(p.lastReceivedHash) + p.FetchHashes() + } peerlogger.Debugln(p) } -- cgit v1.2.3 From c44f4f32fe9d72634574b909655d159ec153ea7d Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 21 Aug 2014 14:52:21 +0200 Subject: Re-enabled catching up flag --- peer.go | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4e6fc55d4..d841b2ad3 100644 --- a/peer.go +++ b/peer.go @@ -435,6 +435,8 @@ func (p *Peer) HandleInbound() { p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, blocks)) case ethwire.MsgBlockHashesTy: + p.catchingUp = true + blockPool := p.ethereum.blockPool foundCommonHash := false @@ -452,6 +454,8 @@ func (p *Peer) HandleInbound() { blockPool.AddHash(hash) p.lastReceivedHash = hash + + p.lastBlockReceived = time.Now() } if foundCommonHash { @@ -459,14 +463,20 @@ func (p *Peer) HandleInbound() { } else { p.FetchHashes() } + case ethwire.MsgBlockTy: + p.catchingUp = true + blockPool := p.ethereum.blockPool it := msg.Data.NewIterator() for it.Next() { block := ethchain.NewBlockFromRlpValue(it.Value()) + blockPool.SetBlock(block) + + p.lastBlockReceived = time.Now() } linked := blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { -- cgit v1.2.3 From a289a77d5de2a2cfa6b38f294b4ab953ebc1bfb8 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 21 Aug 2014 18:15:09 +0200 Subject: DUP n SWAP n --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index d841b2ad3..ab17466e1 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 27 + ProtocolVersion = 28 // Interval for ping/pong message pingPongTimer = 2 * time.Second ) -- cgit v1.2.3 From 93008e279d947e872099c8029b54f7431178bb29 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 22 Aug 2014 10:58:14 +0200 Subject: Removed old chain code --- peer.go | 57 ++++----------------------------------------------------- 1 file changed, 4 insertions(+), 53 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ab17466e1..79a58d28e 100644 --- a/peer.go +++ b/peer.go @@ -474,7 +474,7 @@ func (p *Peer) HandleInbound() { for it.Next() { block := ethchain.NewBlockFromRlpValue(it.Value()) - blockPool.SetBlock(block) + blockPool.SetBlock(block, p) p.lastBlockReceived = time.Now() } @@ -507,6 +507,7 @@ func (self *Peer) FetchHashes() { if self.td.Cmp(blockPool.td) >= 0 { peerlogger.Debugf("Requesting hashes from %x\n", self.lastReceivedHash) + blockPool.td = self.td if !blockPool.HasLatestHash() { self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(200)})) @@ -625,7 +626,6 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { usedPub := 0 // This peer is already added to the peerlist so we expect to find a double pubkey at least once - eachPeer(p.ethereum.Peers(), func(peer *Peer, e *list.Element) { if bytes.Compare(p.pubkey, peer.pubkey) == 0 { usedPub++ @@ -644,7 +644,6 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { return } - // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID, CAPS, PORT, PUBKEY] p.versionKnown = true // If this is an inbound connection send an ack back @@ -680,15 +679,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { ethlogger.Infof("Added peer (%s) %d / %d (TD = %v ~ %x)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, p.td, p.bestHash) - /* - // Catch up with the connected peer - if !p.ethereum.IsUpToDate() { - peerlogger.Debugln("Already syncing up with a peer; sleeping") - time.Sleep(10 * time.Second) - } - */ - //p.SyncWithPeerToLastKnown() - + // Compare the total TD with the blockchain TD. If remote is higher + // fetch hashes from highest TD node. if p.td.Cmp(p.ethereum.BlockChain().TD) > 0 { p.ethereum.blockPool.AddHash(p.lastReceivedHash) p.FetchHashes() @@ -714,47 +706,6 @@ func (p *Peer) String() string { return fmt.Sprintf("[%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.version, p.caps) } -func (p *Peer) SyncWithPeerToLastKnown() { - p.catchingUp = false - p.CatchupWithPeer(p.ethereum.BlockChain().CurrentBlock.Hash()) -} - -func (p *Peer) FindCommonParentBlock() { - if p.catchingUp { - return - } - - p.catchingUp = true - if p.blocksRequested == 0 { - p.blocksRequested = 20 - } - blocks := p.ethereum.BlockChain().GetChain(p.ethereum.BlockChain().CurrentBlock.Hash(), p.blocksRequested) - - var hashes []interface{} - for _, block := range blocks { - hashes = append(hashes, block.Hash()) - } - - msgInfo := append(hashes, uint64(len(hashes))) - - peerlogger.DebugDetailf("Asking for block from %x (%d total) from %s\n", p.ethereum.BlockChain().CurrentBlock.Hash(), len(hashes), p.conn.RemoteAddr().String()) - - msg := ethwire.NewMessage(ethwire.MsgGetChainTy, msgInfo) - p.QueueMessage(msg) -} -func (p *Peer) CatchupWithPeer(blockHash []byte) { - if !p.catchingUp { - // Make sure nobody else is catching up when you want to do this - p.catchingUp = true - msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(100)}) - p.QueueMessage(msg) - - peerlogger.DebugDetailf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) - - msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) - p.QueueMessage(msg) - } -} func (p *Peer) RlpData() []interface{} { return []interface{}{p.host, p.port, p.pubkey} -- cgit v1.2.3 From 2f362509b813573f533a5be437c140355ddec7fc Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 10 Sep 2014 11:22:19 +0200 Subject: New p2p protocol. NOTE: Needs major refactoring. See #50 --- peer.go | 127 +++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 37 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 79a58d28e..a7259d712 100644 --- a/peer.go +++ b/peer.go @@ -25,6 +25,8 @@ const ( outputBufferSize = 50 // Current protocol version ProtocolVersion = 28 + // Current P2P version + P2PVersion = 0 // Interval for ping/pong message pingPongTimer = 2 * time.Second ) @@ -122,6 +124,7 @@ type Peer struct { // This flag is used by writeMessage to check if messages are allowed // to be send or not. If no version is known all messages are ignored. versionKnown bool + statusKnown bool // Last received pong message lastPong int64 @@ -271,6 +274,14 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { default: // Anything but ack is allowed return } + } else { + if !p.statusKnown { + switch msg.Type { + case ethwire.MsgStatusTy: // Ok + default: // Anything but ack is allowed + return + } + } } peerlogger.DebugDetailf("(%v) <= %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data) @@ -356,9 +367,9 @@ func (p *Peer) HandleInbound() { // Version message p.handleHandshake(msg) - if p.caps.IsCap(CapPeerDiscTy) { - p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) - } + //if p.caps.IsCap(CapPeerDiscTy) { + p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) + //} case ethwire.MsgDiscTy: p.Stop() @@ -396,6 +407,10 @@ func (p *Peer) HandleInbound() { // Connect to the list of peers p.ethereum.ProcessPeerList(peers) + + case ethwire.MsgStatusTy: + // Handle peer's status msg + p.handleStatus(msg) case ethwire.MsgGetTxsTy: // Get the current transactions of the pool txs := p.ethereum.TxPool().CurrentTransactions() @@ -581,6 +596,7 @@ func (p *Peer) Stop() { p.ethereum.RemovePeer(p) } +/* func (p *Peer) pushHandshake() error { pubkey := p.ethereum.KeyManager().PublicKey() msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ @@ -592,6 +608,7 @@ func (p *Peer) pushHandshake() error { return nil } +*/ func (p *Peer) peersMessage() *ethwire.Msg { outPeers := make([]interface{}, len(p.ethereum.InOutPeers())) @@ -612,13 +629,72 @@ func (p *Peer) pushPeers() { p.QueueMessage(p.peersMessage()) } +func (p *Peer) pushHandshake() error { + pubkey := p.ethereum.KeyManager().PublicKey() + msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ + uint32(0), []byte(p.version), []string{"eth"}, p.port, pubkey[1:], + }) + + p.QueueMessage(msg) + + return nil +} + +func (self *Peer) pushStatus() { + const netVersion = 0 + msg := ethwire.NewMessage(ethwire.MsgStatusTy, []interface{}{ + uint32(ProtocolVersion), + netVersion, + self.ethereum.BlockChain().TD.Uint64(), + self.ethereum.BlockChain().CurrentBlock.Hash(), + self.ethereum.BlockChain().Genesis().Hash(), + }) + + self.QueueMessage(msg) +} + +func (self *Peer) handleStatus(msg *ethwire.Msg) { + c := msg.Data + // Set the peer's caps + //p.caps = Caps(c.Get(3).Byte()) + + // Get the td and last hash + self.td = c.Get(6).BigInt() + self.bestHash = c.Get(7).Bytes() + self.lastReceivedHash = self.bestHash + + // Compare the total TD with the blockchain TD. If remote is higher + // fetch hashes from highest TD node. + if self.td.Cmp(self.ethereum.BlockChain().TD) > 0 { + self.ethereum.blockPool.AddHash(self.lastReceivedHash) + self.FetchHashes() + } + + ethlogger.Infof("Peer is [ETH] capable. (TD = %v ~ %x", self.td, self.bestHash) +} + func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data - // Set pubkey - p.pubkey = c.Get(5).Bytes() + var ( + p2pVersion = c.Get(0).Uint() + clientId = c.Get(1).Str() + caps = c.Get(2).Raw() + port = c.Get(3).Uint() + pub = c.Get(4).Bytes() + ) - if p.pubkey == nil { + fmt.Println("PEER CAPS", caps) + + // Check correctness of p2p protocol version + if p2pVersion != P2PVersion { + peerlogger.Debugf("Invalid P2P version. Require protocol %d, received %d\n", P2PVersion, p2pVersion) + p.Stop() + return + } + + // Handle the pub key (validation, uniqueness) + if pub == nil || len(pub) == 0 { peerlogger.Warnln("Pubkey required, not supplied in handshake.") p.Stop() return @@ -627,7 +703,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { usedPub := 0 // This peer is already added to the peerlist so we expect to find a double pubkey at least once eachPeer(p.ethereum.Peers(), func(peer *Peer, e *list.Element) { - if bytes.Compare(p.pubkey, peer.pubkey) == 0 { + if bytes.Compare(pub, peer.pubkey) == 0 { usedPub++ } }) @@ -637,18 +713,11 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.Stop() return } - - if c.Get(0).Uint() != ProtocolVersion { - peerlogger.Debugf("Invalid peer version. Require protocol: %d. Received: %d\n", ProtocolVersion, c.Get(0).Uint()) - p.Stop() - return - } - - p.versionKnown = true + p.pubkey = pub // If this is an inbound connection send an ack back if p.inbound { - p.port = uint16(c.Get(4).Uint()) + p.port = uint16(port) // Self connect detection pubkey := p.ethereum.KeyManager().PublicKey() @@ -659,34 +728,18 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { } } + p.SetVersion(clientId) - // Set the peer's caps - p.caps = Caps(c.Get(3).Byte()) - - // Get a reference to the peers version - versionString := c.Get(2).Str() - if len(versionString) > 0 { - p.SetVersion(c.Get(2).Str()) - } - - // Get the td and last hash - p.td = c.Get(6).BigInt() - p.bestHash = c.Get(7).Bytes() - p.lastReceivedHash = p.bestHash + p.versionKnown = true p.ethereum.PushPeer(p) p.ethereum.reactor.Post("peerList", p.ethereum.Peers()) - ethlogger.Infof("Added peer (%s) %d / %d (TD = %v ~ %x)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, p.td, p.bestHash) - - // Compare the total TD with the blockchain TD. If remote is higher - // fetch hashes from highest TD node. - if p.td.Cmp(p.ethereum.BlockChain().TD) > 0 { - p.ethereum.blockPool.AddHash(p.lastReceivedHash) - p.FetchHashes() - } + ethlogger.Infof("Added peer (%s) %d / %d \n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers) peerlogger.Debugln(p) + + p.pushStatus() } func (p *Peer) String() string { -- cgit v1.2.3 From c0187930dc352c645c223e17364623a68413cb74 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 10 Sep 2014 11:39:11 +0200 Subject: Removed some commented code --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index a7259d712..5ca3ed641 100644 --- a/peer.go +++ b/peer.go @@ -694,7 +694,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { } // Handle the pub key (validation, uniqueness) - if pub == nil || len(pub) == 0 { + if len(pub) == 0 { peerlogger.Warnln("Pubkey required, not supplied in handshake.") p.Stop() return -- cgit v1.2.3 From f63cb278038dddd09aa4527529c43fdb8320f2fa Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 14 Sep 2014 13:42:02 +0200 Subject: tmp --- peer.go | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 5ca3ed641..28b193e82 100644 --- a/peer.go +++ b/peer.go @@ -182,6 +182,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { inbound: false, connected: 0, disconnect: 0, + port: 30303, caps: caps, version: ethereum.ClientIdentity().String(), } @@ -629,17 +630,6 @@ func (p *Peer) pushPeers() { p.QueueMessage(p.peersMessage()) } -func (p *Peer) pushHandshake() error { - pubkey := p.ethereum.KeyManager().PublicKey() - msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(0), []byte(p.version), []string{"eth"}, p.port, pubkey[1:], - }) - - p.QueueMessage(msg) - - return nil -} - func (self *Peer) pushStatus() { const netVersion = 0 msg := ethwire.NewMessage(ethwire.MsgStatusTy, []interface{}{ @@ -673,8 +663,21 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { ethlogger.Infof("Peer is [ETH] capable. (TD = %v ~ %x", self.td, self.bestHash) } +func (p *Peer) pushHandshake() error { + pubkey := p.ethereum.KeyManager().PublicKey() + fmt.Println("pubkey", pubkey) + msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ + uint32(0), []byte(p.version), []string{"eth"}, uint32(p.port), pubkey[1:], + }) + + p.QueueMessage(msg) + + return nil +} + func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data + fmt.Println(c, c.Len()) var ( p2pVersion = c.Get(0).Uint() @@ -684,8 +687,6 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { pub = c.Get(4).Bytes() ) - fmt.Println("PEER CAPS", caps) - // Check correctness of p2p protocol version if p2pVersion != P2PVersion { peerlogger.Debugf("Invalid P2P version. Require protocol %d, received %d\n", P2PVersion, p2pVersion) @@ -735,7 +736,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.ethereum.PushPeer(p) p.ethereum.reactor.Post("peerList", p.ethereum.Peers()) - ethlogger.Infof("Added peer (%s) %d / %d \n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers) + ethlogger.Infof("Added peer (%s) %d / %d (%v)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, caps) peerlogger.Debugln(p) -- cgit v1.2.3 From 9e89dacc6439e915784c43eaa273307f24b40be9 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 14 Sep 2014 13:42:13 +0200 Subject: log removed --- peer.go | 2 -- 1 file changed, 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 28b193e82..7178c4f38 100644 --- a/peer.go +++ b/peer.go @@ -665,7 +665,6 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { func (p *Peer) pushHandshake() error { pubkey := p.ethereum.KeyManager().PublicKey() - fmt.Println("pubkey", pubkey) msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ uint32(0), []byte(p.version), []string{"eth"}, uint32(p.port), pubkey[1:], }) @@ -677,7 +676,6 @@ func (p *Peer) pushHandshake() error { func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := msg.Data - fmt.Println(c, c.Len()) var ( p2pVersion = c.Get(0).Uint() -- cgit v1.2.3 From 742a9b00bc1d587669f1b1bf78a27040e7d474a4 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 14 Sep 2014 13:47:29 +0200 Subject: tmp --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 7178c4f38..ad76b8f37 100644 --- a/peer.go +++ b/peer.go @@ -666,7 +666,7 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { func (p *Peer) pushHandshake() error { pubkey := p.ethereum.KeyManager().PublicKey() msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(0), []byte(p.version), []string{"eth"}, uint32(p.port), pubkey[1:], + uint32(0), []byte(p.version), []string{"eth"}, uint32(30303) /*p.port*/, pubkey[1:], }) p.QueueMessage(msg) -- cgit v1.2.3 From 86d1a26b13a55723a89f7a9101200711a51afbc3 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 14 Sep 2014 14:09:46 +0200 Subject: fixed status message --- peer.go | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ad76b8f37..21d918d2e 100644 --- a/peer.go +++ b/peer.go @@ -634,8 +634,8 @@ func (self *Peer) pushStatus() { const netVersion = 0 msg := ethwire.NewMessage(ethwire.MsgStatusTy, []interface{}{ uint32(ProtocolVersion), - netVersion, - self.ethereum.BlockChain().TD.Uint64(), + uint32(netVersion), + self.ethereum.BlockChain().TD, self.ethereum.BlockChain().CurrentBlock.Hash(), self.ethereum.BlockChain().Genesis().Hash(), }) @@ -645,13 +645,22 @@ func (self *Peer) pushStatus() { func (self *Peer) handleStatus(msg *ethwire.Msg) { c := msg.Data - // Set the peer's caps - //p.caps = Caps(c.Get(3).Byte()) + + var ( + protoVersion = c.Get(0).Uint() + netVersion = c.Get(1).Uint() + td = c.Get(2).BigInt() + bestHash = c.Get(3).Bytes() + genesis = c.Get(4).Bytes() + ) + ethlogger.Infof("gen = %x\n", genesis) // Get the td and last hash - self.td = c.Get(6).BigInt() - self.bestHash = c.Get(7).Bytes() - self.lastReceivedHash = self.bestHash + self.td = td + self.bestHash = bestHash + self.lastReceivedHash = bestHash + + self.statusKnown = true // Compare the total TD with the blockchain TD. If remote is higher // fetch hashes from highest TD node. @@ -660,13 +669,14 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { self.FetchHashes() } - ethlogger.Infof("Peer is [ETH] capable. (TD = %v ~ %x", self.td, self.bestHash) + ethlogger.Infof("Peer is [ETH] capable. (TD = %v ~ %x) %d / %d", self.td, self.bestHash, protoVersion, netVersion) + } func (p *Peer) pushHandshake() error { pubkey := p.ethereum.KeyManager().PublicKey() msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(0), []byte(p.version), []string{"eth"}, uint32(30303) /*p.port*/, pubkey[1:], + P2PVersion, []byte(p.version), []interface{}{"eth"}, uint32(30303) /*p.port*/, pubkey[1:], }) p.QueueMessage(msg) -- cgit v1.2.3 From 74ef22d8247c08b6b827f5e9f1001f8bcce9d0e0 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 14 Sep 2014 14:30:33 +0200 Subject: add it to the list --- peer.go | 1 - 1 file changed, 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 21d918d2e..4cc62887c 100644 --- a/peer.go +++ b/peer.go @@ -486,7 +486,6 @@ func (p *Peer) HandleInbound() { blockPool := p.ethereum.blockPool it := msg.Data.NewIterator() - for it.Next() { block := ethchain.NewBlockFromRlpValue(it.Value()) -- cgit v1.2.3 From 2f614900e82036e3e8f6f6a714efc43e09aca830 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 15 Sep 2014 01:11:01 +0200 Subject: Updated GHOST --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 4cc62887c..349d02097 100644 --- a/peer.go +++ b/peer.go @@ -675,7 +675,7 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { func (p *Peer) pushHandshake() error { pubkey := p.ethereum.KeyManager().PublicKey() msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - P2PVersion, []byte(p.version), []interface{}{"eth"}, uint32(30303) /*p.port*/, pubkey[1:], + P2PVersion, []byte(p.version), []interface{}{"eth"}, p.port, pubkey[1:], }) p.QueueMessage(msg) -- cgit v1.2.3 From 33a0dec8a157b9687ca6038f4deb011f3f1f7bdc Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 15 Sep 2014 15:42:12 +0200 Subject: Improved catching up and refactored --- peer.go | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 349d02097..32885aed8 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 28 + ProtocolVersion = 32 // Current P2P version P2PVersion = 0 // Interval for ping/pong message @@ -276,13 +276,15 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { return } } else { - if !p.statusKnown { - switch msg.Type { - case ethwire.MsgStatusTy: // Ok - default: // Anything but ack is allowed - return + /* + if !p.statusKnown { + switch msg.Type { + case ethwire.MsgStatusTy: // Ok + default: // Anything but ack is allowed + return + } } - } + */ } peerlogger.DebugDetailf("(%v) <= %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data) @@ -488,19 +490,25 @@ func (p *Peer) HandleInbound() { it := msg.Data.NewIterator() for it.Next() { block := ethchain.NewBlockFromRlpValue(it.Value()) + //fmt.Printf("%v %x - %x\n", block.Number, block.Hash()[0:4], block.PrevHash[0:4]) blockPool.SetBlock(block, p) p.lastBlockReceived = time.Now() } - linked := blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { - p.ethereum.StateManager().Process(block, false) + blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { + err := p.ethereum.StateManager().Process(block, false) + if err != nil { + peerlogger.Infoln(err) + } }) - if !linked { - p.FetchBlocks() - } + /* + if !linked { + p.FetchBlocks() + } + */ } } } @@ -596,20 +604,6 @@ func (p *Peer) Stop() { p.ethereum.RemovePeer(p) } -/* -func (p *Peer) pushHandshake() error { - pubkey := p.ethereum.KeyManager().PublicKey() - msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - uint32(ProtocolVersion), uint32(0), []byte(p.version), byte(p.caps), p.port, pubkey[1:], - p.ethereum.BlockChain().TD.Uint64(), p.ethereum.BlockChain().CurrentBlock.Hash(), - }) - - p.QueueMessage(msg) - - return nil -} -*/ - func (p *Peer) peersMessage() *ethwire.Msg { outPeers := make([]interface{}, len(p.ethereum.InOutPeers())) // Serialise each peer -- cgit v1.2.3 From 399256b38403f2e95312250d49fca3cada8956b8 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 15 Sep 2014 22:11:05 +0200 Subject: VM execution fixes Refactoring caused executing issues --- peer.go | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 32885aed8..69aa4b668 100644 --- a/peer.go +++ b/peer.go @@ -497,18 +497,16 @@ func (p *Peer) HandleInbound() { p.lastBlockReceived = time.Now() } + var err error blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { - err := p.ethereum.StateManager().Process(block, false) - if err != nil { - peerlogger.Infoln(err) - } + err = p.ethereum.StateManager().Process(block, false) }) - /* - if !linked { - p.FetchBlocks() - } - */ + if err != nil { + peerlogger.Infoln(err) + } else { + p.FetchBlocks() + } } } } @@ -529,11 +527,10 @@ func (self *Peer) FetchHashes() { blockPool := self.ethereum.blockPool if self.td.Cmp(blockPool.td) >= 0 { - peerlogger.Debugf("Requesting hashes from %x\n", self.lastReceivedHash) blockPool.td = self.td if !blockPool.HasLatestHash() { - self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(200)})) + self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(256)})) } } } -- cgit v1.2.3 From 1549a29c9d6452eefa615baedfccfc5b5f6b7745 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 16 Sep 2014 16:36:27 +0200 Subject: Connect to previous peer --- peer.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 69aa4b668..628953535 100644 --- a/peer.go +++ b/peer.go @@ -680,7 +680,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { var ( p2pVersion = c.Get(0).Uint() clientId = c.Get(1).Str() - caps = c.Get(2).Raw() + caps = c.Get(2) port = c.Get(3).Uint() pub = c.Get(4).Bytes() ) @@ -734,11 +734,17 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.ethereum.PushPeer(p) p.ethereum.reactor.Post("peerList", p.ethereum.Peers()) - ethlogger.Infof("Added peer (%s) %d / %d (%v)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, caps) + ethlogger.Infof("Added peer (%s) %d / %d (%v)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, caps.Raw()) peerlogger.Debugln(p) - p.pushStatus() + capsIt := caps.NewIterator() + for capsIt.Next() { + switch capsIt.Value().Str() { + case "eth": + p.pushStatus() + } + } } func (p *Peer) String() string { -- cgit v1.2.3 From a26c479182375a076833068aa6125724fda647fe Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 17 Sep 2014 15:58:02 +0200 Subject: Added len --- peer.go | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 628953535..aae84f0c0 100644 --- a/peer.go +++ b/peer.go @@ -287,7 +287,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { */ } - peerlogger.DebugDetailf("(%v) <= %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data) + peerlogger.DebugDetailf("(%v) <= %v\n", p.conn.RemoteAddr(), formatMessage(msg)) err := ethwire.WriteMessage(p.conn, msg) if err != nil { @@ -351,6 +351,27 @@ clean: } } +func formatMessage(msg *ethwire.Msg) (ret string) { + ret = fmt.Sprintf("%v ", msg.Type) + + /* + XXX Commented out because I need the log level here to determine + if i should or shouldn't generate this message + */ + switch msg.Type { + case ethwire.MsgPeersTy: + ret += fmt.Sprintf("(%d entries)", msg.Data.Len()) + case ethwire.MsgBlockTy: + b1, b2 := ethchain.NewBlockFromRlpValue(msg.Data.Get(0)), ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len()-1)) + ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), b1.Hash()[0:4], b2.Hash()[0:4]) + case ethwire.MsgBlockHashesTy: + h1, h2 := msg.Data.Get(0).Bytes(), msg.Data.Get(msg.Data.Len()-1).Bytes() + ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), h1[0:4], h2[0:4]) + } + + return +} + // Inbound handler. Inbound messages are received here and passed to the appropriate methods func (p *Peer) HandleInbound() { for atomic.LoadInt32(&p.disconnect) == 0 { @@ -363,7 +384,7 @@ func (p *Peer) HandleInbound() { peerlogger.Debugln(err) } for _, msg := range msgs { - peerlogger.DebugDetailf("(%v) => %v %v\n", p.conn.RemoteAddr(), msg.Type, msg.Data) + peerlogger.DebugDetailf("(%v) => %v\n", p.conn.RemoteAddr(), formatMessage(msg)) switch msg.Type { case ethwire.MsgHandshakeTy: @@ -505,7 +526,10 @@ func (p *Peer) HandleInbound() { if err != nil { peerlogger.Infoln(err) } else { - p.FetchBlocks() + // Don't trigger if there's just one block. + if blockPool.Len() != 0 && msg.Data.Len() > 1 { + p.FetchBlocks() + } } } } @@ -643,7 +667,11 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { bestHash = c.Get(3).Bytes() genesis = c.Get(4).Bytes() ) - ethlogger.Infof("gen = %x\n", genesis) + + if bytes.Compare(self.ethereum.BlockChain().Genesis().Hash(), genesis) != 0 { + ethlogger.Warnf("Invalid genisis hash %x. Disabling [ETH]\n", genesis) + return + } // Get the td and last hash self.td = td @@ -734,17 +762,21 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.ethereum.PushPeer(p) p.ethereum.reactor.Post("peerList", p.ethereum.Peers()) - ethlogger.Infof("Added peer (%s) %d / %d (%v)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, caps.Raw()) - - peerlogger.Debugln(p) - capsIt := caps.NewIterator() + var capsStrs []string for capsIt.Next() { - switch capsIt.Value().Str() { + cap := capsIt.Value().Str() + switch cap { case "eth": p.pushStatus() } + + capsStrs = append(capsStrs, cap) } + + ethlogger.Infof("Added peer (%s) %d / %d (%v)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, capsStrs) + + peerlogger.Debugln(p) } func (p *Peer) String() string { -- cgit v1.2.3 From f3a93b046e45a293b673a955959666ec5389c4eb Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 18 Sep 2014 01:02:15 +0200 Subject: Upped protocol version for VM change --- peer.go | 177 ++++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 101 insertions(+), 76 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index aae84f0c0..8c04864d0 100644 --- a/peer.go +++ b/peer.go @@ -24,9 +24,11 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 32 + ProtocolVersion = 33 // Current P2P version P2PVersion = 0 + // Ethereum network version + NetVersion = 0 // Interval for ping/pong message pingPongTimer = 2 * time.Second ) @@ -72,7 +74,7 @@ func (d DiscReason) String() string { type Caps byte const ( - CapPeerDiscTy = 1 << iota + CapPeerDiscTy Caps = 1 << iota CapTxTy CapChainTy @@ -309,6 +311,14 @@ out: select { // Main message queue. All outbound messages are processed through here case msg := <-p.outputQueue: + if !p.statusKnown { + switch msg.Type { + case ethwire.MsgGetTxsTy, ethwire.MsgGetBlockHashesTy, ethwire.MsgGetBlocksTy, ethwire.MsgBlockHashesTy, ethwire.MsgBlockTy: + peerlogger.Debugln("Blocked outgoing [eth] message to peer without the [eth] cap.") + break + } + } + p.writeMessage(msg) p.lastSend = time.Now() @@ -435,100 +445,106 @@ func (p *Peer) HandleInbound() { case ethwire.MsgStatusTy: // Handle peer's status msg p.handleStatus(msg) - case ethwire.MsgGetTxsTy: - // Get the current transactions of the pool - txs := p.ethereum.TxPool().CurrentTransactions() - // Get the RlpData values from the txs - txsInterface := make([]interface{}, len(txs)) - for i, tx := range txs { - txsInterface[i] = tx.RlpData() - } - // Broadcast it back to the peer - p.QueueMessage(ethwire.NewMessage(ethwire.MsgTxTy, txsInterface)) + } - case ethwire.MsgGetBlockHashesTy: - if msg.Data.Len() < 2 { - peerlogger.Debugln("err: argument length invalid ", msg.Data.Len()) - } + // TMP + if p.statusKnown { + switch msg.Type { + case ethwire.MsgGetTxsTy: + // Get the current transactions of the pool + txs := p.ethereum.TxPool().CurrentTransactions() + // Get the RlpData values from the txs + txsInterface := make([]interface{}, len(txs)) + for i, tx := range txs { + txsInterface[i] = tx.RlpData() + } + // Broadcast it back to the peer + p.QueueMessage(ethwire.NewMessage(ethwire.MsgTxTy, txsInterface)) + + case ethwire.MsgGetBlockHashesTy: + if msg.Data.Len() < 2 { + peerlogger.Debugln("err: argument length invalid ", msg.Data.Len()) + } - hash := msg.Data.Get(0).Bytes() - amount := msg.Data.Get(1).Uint() + hash := msg.Data.Get(0).Bytes() + amount := msg.Data.Get(1).Uint() - hashes := p.ethereum.BlockChain().GetChainHashesFromHash(hash, amount) + hashes := p.ethereum.BlockChain().GetChainHashesFromHash(hash, amount) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockHashesTy, ethutil.ByteSliceToInterface(hashes))) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockHashesTy, ethutil.ByteSliceToInterface(hashes))) - case ethwire.MsgGetBlocksTy: - // Limit to max 300 blocks - max := int(math.Min(float64(msg.Data.Len()), 300.0)) - var blocks []interface{} + case ethwire.MsgGetBlocksTy: + // Limit to max 300 blocks + max := int(math.Min(float64(msg.Data.Len()), 300.0)) + var blocks []interface{} - for i := 0; i < max; i++ { - hash := msg.Data.Get(i).Bytes() - block := p.ethereum.BlockChain().GetBlock(hash) - if block != nil { - blocks = append(blocks, block.Value().Raw()) + for i := 0; i < max; i++ { + hash := msg.Data.Get(i).Bytes() + block := p.ethereum.BlockChain().GetBlock(hash) + if block != nil { + blocks = append(blocks, block.Value().Raw()) + } } - } - p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, blocks)) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, blocks)) - case ethwire.MsgBlockHashesTy: - p.catchingUp = true + case ethwire.MsgBlockHashesTy: + p.catchingUp = true - blockPool := p.ethereum.blockPool + blockPool := p.ethereum.blockPool - foundCommonHash := false + foundCommonHash := false - it := msg.Data.NewIterator() - for it.Next() { - hash := it.Value().Bytes() + it := msg.Data.NewIterator() + for it.Next() { + hash := it.Value().Bytes() - if blockPool.HasCommonHash(hash) { - foundCommonHash = true + if blockPool.HasCommonHash(hash) { + foundCommonHash = true - break - } + break + } - blockPool.AddHash(hash) + blockPool.AddHash(hash) - p.lastReceivedHash = hash + p.lastReceivedHash = hash - p.lastBlockReceived = time.Now() - } - - if foundCommonHash { - p.FetchBlocks() - } else { - p.FetchHashes() - } + p.lastBlockReceived = time.Now() + } - case ethwire.MsgBlockTy: - p.catchingUp = true + if foundCommonHash { + p.FetchBlocks() + } else { + p.FetchHashes() + } - blockPool := p.ethereum.blockPool + case ethwire.MsgBlockTy: + p.catchingUp = true - it := msg.Data.NewIterator() - for it.Next() { - block := ethchain.NewBlockFromRlpValue(it.Value()) - //fmt.Printf("%v %x - %x\n", block.Number, block.Hash()[0:4], block.PrevHash[0:4]) + blockPool := p.ethereum.blockPool - blockPool.SetBlock(block, p) + it := msg.Data.NewIterator() + for it.Next() { + block := ethchain.NewBlockFromRlpValue(it.Value()) + //fmt.Printf("%v %x - %x\n", block.Number, block.Hash()[0:4], block.PrevHash[0:4]) - p.lastBlockReceived = time.Now() - } + blockPool.SetBlock(block, p) - var err error - blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { - err = p.ethereum.StateManager().Process(block, false) - }) + p.lastBlockReceived = time.Now() + } - if err != nil { - peerlogger.Infoln(err) - } else { - // Don't trigger if there's just one block. - if blockPool.Len() != 0 && msg.Data.Len() > 1 { - p.FetchBlocks() + var err error + blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { + err = p.ethereum.StateManager().Process(block, false) + }) + + if err != nil { + peerlogger.Infoln(err) + } else { + // Don't trigger if there's just one block. + if blockPool.Len() != 0 && msg.Data.Len() > 1 { + p.FetchBlocks() + } } } } @@ -645,10 +661,9 @@ func (p *Peer) pushPeers() { } func (self *Peer) pushStatus() { - const netVersion = 0 msg := ethwire.NewMessage(ethwire.MsgStatusTy, []interface{}{ uint32(ProtocolVersion), - uint32(netVersion), + uint32(NetVersion), self.ethereum.BlockChain().TD, self.ethereum.BlockChain().CurrentBlock.Hash(), self.ethereum.BlockChain().Genesis().Hash(), @@ -669,7 +684,17 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { ) if bytes.Compare(self.ethereum.BlockChain().Genesis().Hash(), genesis) != 0 { - ethlogger.Warnf("Invalid genisis hash %x. Disabling [ETH]\n", genesis) + ethlogger.Warnf("Invalid genisis hash %x. Disabling [eth]\n", genesis) + return + } + + if netVersion != NetVersion { + ethlogger.Warnf("Invalid network version %d. Disabling [eth]\n", netVersion) + return + } + + if protoVersion != ProtocolVersion { + ethlogger.Warnf("Invalid protocol version %d. Disabling [eth]\n", protoVersion) return } @@ -687,7 +712,7 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { self.FetchHashes() } - ethlogger.Infof("Peer is [ETH] capable. (TD = %v ~ %x) %d / %d", self.td, self.bestHash, protoVersion, netVersion) + ethlogger.Infof("Peer is [eth] capable. (TD = %v ~ %x) %d / %d", self.td, self.bestHash, protoVersion, netVersion) } -- cgit v1.2.3 From 9ed5b4d90e287de788d9079abab54578064864ba Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 22 Sep 2014 16:28:28 +0200 Subject: Support C++ GetBlockHash by assuming empty = done --- peer.go | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 8c04864d0..67bf4e555 100644 --- a/peer.go +++ b/peer.go @@ -362,22 +362,24 @@ clean: } func formatMessage(msg *ethwire.Msg) (ret string) { - ret = fmt.Sprintf("%v ", msg.Type) + ret = fmt.Sprintf("%v %v", msg.Type, msg.Data) /* XXX Commented out because I need the log level here to determine if i should or shouldn't generate this message */ - switch msg.Type { - case ethwire.MsgPeersTy: - ret += fmt.Sprintf("(%d entries)", msg.Data.Len()) - case ethwire.MsgBlockTy: - b1, b2 := ethchain.NewBlockFromRlpValue(msg.Data.Get(0)), ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len()-1)) - ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), b1.Hash()[0:4], b2.Hash()[0:4]) - case ethwire.MsgBlockHashesTy: - h1, h2 := msg.Data.Get(0).Bytes(), msg.Data.Get(msg.Data.Len()-1).Bytes() - ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), h1[0:4], h2[0:4]) - } + /* + switch msg.Type { + case ethwire.MsgPeersTy: + ret += fmt.Sprintf("(%d entries)", msg.Data.Len()) + case ethwire.MsgBlockTy: + b1, b2 := ethchain.NewBlockFromRlpValue(msg.Data.Get(0)), ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len()-1)) + ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), b1.Hash()[0:4], b2.Hash()[0:4]) + case ethwire.MsgBlockHashesTy: + h1, h2 := msg.Data.Get(0).Bytes(), msg.Data.Get(msg.Data.Len()-1).Bytes() + ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), h1, h2) + } + */ return } @@ -512,7 +514,7 @@ func (p *Peer) HandleInbound() { p.lastBlockReceived = time.Now() } - if foundCommonHash { + if foundCommonHash || msg.Data.Len() == 0 { p.FetchBlocks() } else { p.FetchHashes() -- cgit v1.2.3 From 6800c3665a50f7ac624f4ecbaa474b8a81336143 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 23 Sep 2014 17:55:34 +0200 Subject: Re-added min gas price check on tx pool --- peer.go | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 67bf4e555..34aff5ede 100644 --- a/peer.go +++ b/peer.go @@ -155,6 +155,8 @@ type Peer struct { pingStartTime time.Time lastRequestedBlock *ethchain.Block + + protocolCaps *ethutil.Value } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { @@ -173,20 +175,22 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { blocksRequested: 10, caps: ethereum.ServerCaps(), version: ethereum.ClientIdentity().String(), + protocolCaps: ethutil.NewValue(nil), } } func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { p := &Peer{ - outputQueue: make(chan *ethwire.Msg, outputBufferSize), - quit: make(chan bool), - ethereum: ethereum, - inbound: false, - connected: 0, - disconnect: 0, - port: 30303, - caps: caps, - version: ethereum.ClientIdentity().String(), + outputQueue: make(chan *ethwire.Msg, outputBufferSize), + quit: make(chan bool), + ethereum: ethereum, + inbound: false, + connected: 0, + disconnect: 0, + port: 30303, + caps: caps, + version: ethereum.ClientIdentity().String(), + protocolCaps: ethutil.NewValue(nil), } // Set up the connection in another goroutine so we don't block the main thread @@ -568,7 +572,7 @@ func (self *Peer) FetchBlocks() { func (self *Peer) FetchHashes() { blockPool := self.ethereum.blockPool - if self.td.Cmp(blockPool.td) >= 0 { + if self.statusKnown && self.td.Cmp(blockPool.td) >= 0 { blockPool.td = self.td if !blockPool.HasLatestHash() { @@ -585,7 +589,10 @@ out: for { select { case <-serviceTimer.C: - if time.Since(self.lastBlockReceived) > 10*time.Second { + since := time.Since(self.lastBlockReceived) + if since > 10*time.Second && self.ethereum.blockPool.Len() != 0 && self.IsCap("eth") { + self.FetchHashes() + } else if since > 5*time.Second { self.catchingUp = false } case <-self.quit: @@ -789,6 +796,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.ethereum.PushPeer(p) p.ethereum.reactor.Post("peerList", p.ethereum.Peers()) + p.protocolCaps = caps capsIt := caps.NewIterator() var capsStrs []string for capsIt.Next() { @@ -806,6 +814,17 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { peerlogger.Debugln(p) } +func (self *Peer) IsCap(cap string) bool { + capsIt := self.protocolCaps.NewIterator() + for capsIt.Next() { + if capsIt.Value().Str() == cap { + return true + } + } + + return false +} + func (p *Peer) String() string { var strBoundType string if p.inbound { -- cgit v1.2.3 From 46a496428f2d2a3a0f9ddcb755c825dfc1f73436 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 23 Sep 2014 18:19:51 +0200 Subject: ugh --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 34aff5ede..529a35492 100644 --- a/peer.go +++ b/peer.go @@ -572,7 +572,7 @@ func (self *Peer) FetchBlocks() { func (self *Peer) FetchHashes() { blockPool := self.ethereum.blockPool - if self.statusKnown && self.td.Cmp(blockPool.td) >= 0 { + if self.td.Cmp(blockPool.td) >= 0 { blockPool.td = self.td if !blockPool.HasLatestHash() { -- cgit v1.2.3 From ba43364f36db690528cc62196969414ef5e98833 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 24 Sep 2014 11:41:57 +0200 Subject: tmp --- peer.go | 97 +++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 38 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 529a35492..8224f4831 100644 --- a/peer.go +++ b/peer.go @@ -131,6 +131,7 @@ type Peer struct { // Last received pong message lastPong int64 lastBlockReceived time.Time + LastHashReceived time.Time host []byte port uint16 @@ -176,6 +177,7 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { caps: ethereum.ServerCaps(), version: ethereum.ClientIdentity().String(), protocolCaps: ethutil.NewValue(nil), + td: big.NewInt(0), } } @@ -191,6 +193,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { caps: caps, version: ethereum.ClientIdentity().String(), protocolCaps: ethutil.NewValue(nil), + td: big.NewInt(0), } // Set up the connection in another goroutine so we don't block the main thread @@ -505,6 +508,9 @@ func (p *Peer) HandleInbound() { for it.Next() { hash := it.Value().Bytes() + p.lastReceivedHash = hash + p.LastHashReceived = time.Now() + if blockPool.HasCommonHash(hash) { foundCommonHash = true @@ -512,15 +518,16 @@ func (p *Peer) HandleInbound() { } blockPool.AddHash(hash) - - p.lastReceivedHash = hash - - p.lastBlockReceived = time.Now() } - if foundCommonHash || msg.Data.Len() == 0 { - p.FetchBlocks() - } else { + /* + if foundCommonHash || msg.Data.Len() == 0 { + p.FetchBlocks() + } else { + p.FetchHashes() + } + */ + if !foundCommonHash && msg.Data.Len() != 0 { p.FetchHashes() } @@ -539,19 +546,21 @@ func (p *Peer) HandleInbound() { p.lastBlockReceived = time.Now() } - var err error - blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { - err = p.ethereum.StateManager().Process(block, false) - }) - - if err != nil { - peerlogger.Infoln(err) - } else { - // Don't trigger if there's just one block. - if blockPool.Len() != 0 && msg.Data.Len() > 1 { - p.FetchBlocks() + /* + var err error + blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { + err = p.ethereum.StateManager().Process(block, false) + }) + + if err != nil { + peerlogger.Infoln(err) + } else { + // Don't trigger if there's just one block. + if blockPool.Len() != 0 && msg.Data.Len() > 1 { + p.FetchBlocks() + } } - } + */ } } } @@ -560,10 +569,7 @@ func (p *Peer) HandleInbound() { p.Stop() } -func (self *Peer) FetchBlocks() { - blockPool := self.ethereum.blockPool - - hashes := blockPool.Take(100, self) +func (self *Peer) FetchBlocks(hashes [][]byte) { if len(hashes) > 0 { self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlocksTy, ethutil.ByteSliceToInterface(hashes))) } @@ -572,7 +578,7 @@ func (self *Peer) FetchBlocks() { func (self *Peer) FetchHashes() { blockPool := self.ethereum.blockPool - if self.td.Cmp(blockPool.td) >= 0 { + if self.td.Cmp(self.ethereum.HighestTDPeer()) >= 0 { blockPool.td = self.td if !blockPool.HasLatestHash() { @@ -581,6 +587,10 @@ func (self *Peer) FetchHashes() { } } +func (self *Peer) FetchingHashes() bool { + return time.Since(self.LastHashReceived) < 5*time.Second +} + // General update method func (self *Peer) update() { serviceTimer := time.NewTicker(5 * time.Second) @@ -589,11 +599,22 @@ out: for { select { case <-serviceTimer.C: - since := time.Since(self.lastBlockReceived) - if since > 10*time.Second && self.ethereum.blockPool.Len() != 0 && self.IsCap("eth") { - self.FetchHashes() - } else if since > 5*time.Second { - self.catchingUp = false + if self.IsCap("eth") { + var ( + sinceBlock = time.Since(self.lastBlockReceived) + sinceHash = time.Since(self.LastHashReceived) + ) + + if sinceBlock > 5*time.Second && sinceHash > 5*time.Second { + self.catchingUp = false + } + + if sinceHash > 10*time.Second && self.ethereum.blockPool.Len() != 0 { + // XXX While this is completely and utterly incorrect, in order to do anything on the test net is to do it this way + // Assume that when fetching hashes timeouts, we are done. + //self.FetchHashes() + //self.FetchBlocks() + } } case <-self.quit: break out @@ -761,6 +782,14 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { return } + // Self connect detection + pubkey := p.ethereum.KeyManager().PublicKey() + if bytes.Compare(pubkey[1:], pub) == 0 { + p.Stop() + + return + } + usedPub := 0 // This peer is already added to the peerlist so we expect to find a double pubkey at least once eachPeer(p.ethereum.Peers(), func(peer *Peer, e *list.Element) { @@ -779,16 +808,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { // If this is an inbound connection send an ack back if p.inbound { p.port = uint16(port) - - // Self connect detection - pubkey := p.ethereum.KeyManager().PublicKey() - if bytes.Compare(pubkey, p.pubkey) == 0 { - p.Stop() - - return - } - } + p.SetVersion(clientId) p.versionKnown = true -- cgit v1.2.3 From b66fcf85dfecb13c3ed2b9f46ad6bb257ce84411 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 24 Sep 2014 11:55:02 +0200 Subject: checkp --- peer.go | 53 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 21 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 529a35492..00987c123 100644 --- a/peer.go +++ b/peer.go @@ -131,6 +131,7 @@ type Peer struct { // Last received pong message lastPong int64 lastBlockReceived time.Time + lastHashReceived time.Time host []byte port uint16 @@ -505,6 +506,9 @@ func (p *Peer) HandleInbound() { for it.Next() { hash := it.Value().Bytes() + p.lastReceivedHash = hash + p.lastHashReceived = time.Now() + if blockPool.HasCommonHash(hash) { foundCommonHash = true @@ -512,10 +516,6 @@ func (p *Peer) HandleInbound() { } blockPool.AddHash(hash) - - p.lastReceivedHash = hash - - p.lastBlockReceived = time.Now() } if foundCommonHash || msg.Data.Len() == 0 { @@ -546,12 +546,12 @@ func (p *Peer) HandleInbound() { if err != nil { peerlogger.Infoln(err) - } else { + } /*else { // Don't trigger if there's just one block. if blockPool.Len() != 0 && msg.Data.Len() > 1 { p.FetchBlocks() } - } + }*/ } } } @@ -583,17 +583,28 @@ func (self *Peer) FetchHashes() { // General update method func (self *Peer) update() { - serviceTimer := time.NewTicker(5 * time.Second) + serviceTimer := time.NewTicker(100 * time.Millisecond) out: for { select { case <-serviceTimer.C: - since := time.Since(self.lastBlockReceived) - if since > 10*time.Second && self.ethereum.blockPool.Len() != 0 && self.IsCap("eth") { - self.FetchHashes() - } else if since > 5*time.Second { - self.catchingUp = false + if self.IsCap("eth") { + var ( + sinceBlock = time.Since(self.lastBlockReceived) + sinceHash = time.Since(self.lastHashReceived) + ) + + if sinceBlock > 5*time.Second && sinceHash > 5*time.Second { + self.catchingUp = false + } + + if sinceHash > 10*time.Second && self.ethereum.blockPool.Len() != 0 { + // XXX While this is completely and utterly incorrect, in order to do anything on the test net is to do it this way + // Assume that when fetching hashes timeouts, we are done. + //self.FetchHashes() + self.FetchBlocks() + } } case <-self.quit: break out @@ -761,6 +772,14 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { return } + // Self connect detection + pubkey := p.ethereum.KeyManager().PublicKey() + if bytes.Compare(pubkey[1:], pub) == 0 { + p.Stop() + + return + } + usedPub := 0 // This peer is already added to the peerlist so we expect to find a double pubkey at least once eachPeer(p.ethereum.Peers(), func(peer *Peer, e *list.Element) { @@ -779,16 +798,8 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { // If this is an inbound connection send an ack back if p.inbound { p.port = uint16(port) - - // Self connect detection - pubkey := p.ethereum.KeyManager().PublicKey() - if bytes.Compare(pubkey, p.pubkey) == 0 { - p.Stop() - - return - } - } + p.SetVersion(clientId) p.versionKnown = true -- cgit v1.2.3 From 1fe2d0d0e011b6d6bc6261b69fe955943d9d6e3e Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 24 Sep 2014 19:55:28 +0200 Subject: Peers no longer take care of block processing --- peer.go | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 8224f4831..3bbfb74fa 100644 --- a/peer.go +++ b/peer.go @@ -517,16 +517,9 @@ func (p *Peer) HandleInbound() { break } - blockPool.AddHash(hash) + blockPool.AddHash(hash, p) } - /* - if foundCommonHash || msg.Data.Len() == 0 { - p.FetchBlocks() - } else { - p.FetchHashes() - } - */ if !foundCommonHash && msg.Data.Len() != 0 { p.FetchHashes() } @@ -545,22 +538,6 @@ func (p *Peer) HandleInbound() { p.lastBlockReceived = time.Now() } - - /* - var err error - blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { - err = p.ethereum.StateManager().Process(block, false) - }) - - if err != nil { - peerlogger.Infoln(err) - } else { - // Don't trigger if there's just one block. - if blockPool.Len() != 0 && msg.Data.Len() > 1 { - p.FetchBlocks() - } - } - */ } } } @@ -608,13 +585,6 @@ out: if sinceBlock > 5*time.Second && sinceHash > 5*time.Second { self.catchingUp = false } - - if sinceHash > 10*time.Second && self.ethereum.blockPool.Len() != 0 { - // XXX While this is completely and utterly incorrect, in order to do anything on the test net is to do it this way - // Assume that when fetching hashes timeouts, we are done. - //self.FetchHashes() - //self.FetchBlocks() - } } case <-self.quit: break out @@ -738,7 +708,7 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { // Compare the total TD with the blockchain TD. If remote is higher // fetch hashes from highest TD node. if self.td.Cmp(self.ethereum.BlockChain().TD) > 0 { - self.ethereum.blockPool.AddHash(self.lastReceivedHash) + self.ethereum.blockPool.AddHash(self.lastReceivedHash, self) self.FetchHashes() } -- cgit v1.2.3 From 3aeba50c38e74bc1091895db1cb57e7d93864270 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 24 Sep 2014 21:13:28 +0200 Subject: merge error --- peer.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 06df5fab6..ef346d3ac 100644 --- a/peer.go +++ b/peer.go @@ -311,7 +311,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { func (p *Peer) HandleOutbound() { // The ping timer. Makes sure that every 2 minutes a ping is send to the peer pingTimer := time.NewTicker(pingPongTimer) - serviceTimer := time.NewTicker(5 * time.Minute) + serviceTimer := time.NewTicker(5 * time.Second) out: for { @@ -345,10 +345,8 @@ out: // Service timer takes care of peer broadcasting, transaction // posting or block posting case <-serviceTimer.C: - if p.caps&CapPeerDiscTy > 0 { - msg := p.peersMessage() - p.ethereum.BroadcastMsg(msg) - } + + //p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) case <-p.quit: // Break out of the for loop if a quit message is posted -- cgit v1.2.3 From 5cb4120ef517830e8c45007f138ffd343ccb164a Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 24 Sep 2014 21:20:57 +0200 Subject: queue get peers each 10 seconds --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ef346d3ac..ede3ad4e4 100644 --- a/peer.go +++ b/peer.go @@ -311,7 +311,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { func (p *Peer) HandleOutbound() { // The ping timer. Makes sure that every 2 minutes a ping is send to the peer pingTimer := time.NewTicker(pingPongTimer) - serviceTimer := time.NewTicker(5 * time.Second) + serviceTimer := time.NewTicker(10 * time.Second) out: for { @@ -346,7 +346,7 @@ out: // posting or block posting case <-serviceTimer.C: - //p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) + p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) case <-p.quit: // Break out of the for loop if a quit message is posted -- cgit v1.2.3 From 9ed8dc7384deb932be624699d9f628d3d00ba31e Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 25 Sep 2014 16:57:49 +0200 Subject: Attempt to catch up from unknown block --- peer.go | 1 - 1 file changed, 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ede3ad4e4..6f1ad91e3 100644 --- a/peer.go +++ b/peer.go @@ -221,7 +221,6 @@ func (self *Peer) Connect(addr string) (conn net.Conn, err error) { for attempts := 0; attempts < maxTries; attempts++ { conn, err = net.DialTimeout("tcp", addr, 10*time.Second) if err != nil { - //peerlogger.Debugf("Peer connection failed. Retrying (%d/%d) (%s)\n", attempts+1, maxTries, addr) time.Sleep(time.Duration(attempts*20) * time.Second) continue } -- cgit v1.2.3 From b8354124bebcd3988afd2f41c320f834a69b949e Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 26 Sep 2014 13:45:26 +0200 Subject: Added protocol caps accessors --- peer.go | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 6f1ad91e3..f1fff59af 100644 --- a/peer.go +++ b/peer.go @@ -813,6 +813,10 @@ func (self *Peer) IsCap(cap string) bool { return false } +func (self *Peer) Caps() *ethutil.Value { + return self.protocolCaps +} + func (p *Peer) String() string { var strBoundType string if p.inbound { -- cgit v1.2.3 From 0acdeca3d6df4716d8789444c7bb645c73a27324 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 26 Sep 2014 20:19:01 +0200 Subject: skip messages properly --- peer.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index f1fff59af..00f0a145c 100644 --- a/peer.go +++ b/peer.go @@ -314,14 +314,14 @@ func (p *Peer) HandleOutbound() { out: for { + skip: select { // Main message queue. All outbound messages are processed through here case msg := <-p.outputQueue: if !p.statusKnown { switch msg.Type { - case ethwire.MsgGetTxsTy, ethwire.MsgGetBlockHashesTy, ethwire.MsgGetBlocksTy, ethwire.MsgBlockHashesTy, ethwire.MsgBlockTy: - peerlogger.Debugln("Blocked outgoing [eth] message to peer without the [eth] cap.") - break + case ethwire.MsgStatusTy, ethwire.MsgGetTxsTy, ethwire.MsgTxTy, ethwire.MsgGetBlockHashesTy, ethwire.MsgBlockHashesTy, ethwire.MsgGetBlocksTy, ethwire.MsgBlockTy: + break skip } } -- cgit v1.2.3 From 44d50bc8d2e8bf4a87d01d6ded24d79eb50ee666 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 26 Sep 2014 20:51:31 +0200 Subject: Have you seen my parents, sir? --- peer.go | 1 - 1 file changed, 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 00f0a145c..e3c4c9e10 100644 --- a/peer.go +++ b/peer.go @@ -344,7 +344,6 @@ out: // Service timer takes care of peer broadcasting, transaction // posting or block posting case <-serviceTimer.C: - p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) case <-p.quit: -- cgit v1.2.3 From ea0357bf02b61db94bd0ad8806ba7337a55a4f79 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Sun, 28 Sep 2014 14:52:58 +0200 Subject: Block pool is thread safe --- peer.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index e3c4c9e10..11ec6e003 100644 --- a/peer.go +++ b/peer.go @@ -503,16 +503,15 @@ func (p *Peer) HandleInbound() { it := msg.Data.NewIterator() for it.Next() { hash := it.Value().Bytes() - - p.lastReceivedHash = hash - p.LastHashReceived = time.Now() - if blockPool.HasCommonHash(hash) { foundCommonHash = true break } + p.lastReceivedHash = hash + p.LastHashReceived = time.Now() + blockPool.AddHash(hash, p) } @@ -530,7 +529,7 @@ func (p *Peer) HandleInbound() { block := ethchain.NewBlockFromRlpValue(it.Value()) //fmt.Printf("%v %x - %x\n", block.Number, block.Hash()[0:4], block.PrevHash[0:4]) - blockPool.SetBlock(block, p) + blockPool.Add(block, p) p.lastBlockReceived = time.Now() } @@ -561,7 +560,7 @@ func (self *Peer) FetchHashes() { } func (self *Peer) FetchingHashes() bool { - return time.Since(self.LastHashReceived) < 5*time.Second + return time.Since(self.LastHashReceived) < 200*time.Millisecond } // General update method -- cgit v1.2.3 From ab6ede51d7fedb9270cab08ee732a834be34dab2 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 29 Sep 2014 12:57:51 +0200 Subject: Working on new (blocking) event machine. The new event machine will be used for loose coupling and handle the communications between the services: 1) Block pool finds blocks which "links" with our current canonical chain 2) Posts the blocks on to the event machine 3) State manager receives blocks & processes them 4) Broadcasts new post block event --- peer.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 11ec6e003..f5d0fe4ed 100644 --- a/peer.go +++ b/peer.go @@ -554,7 +554,9 @@ func (self *Peer) FetchHashes() { blockPool.td = self.td if !blockPool.HasLatestHash() { - self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(256)})) + const amount = 256 + peerlogger.Debugf("Fetching hashes (%d)\n", amount) + self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(amount)})) } } } -- cgit v1.2.3 From 3af211dd65d6690afce9976a9f47ab1cdddb8d58 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 30 Sep 2014 23:26:52 +0200 Subject: Implemented WebSocket package --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index f5d0fe4ed..318294509 100644 --- a/peer.go +++ b/peer.go @@ -320,7 +320,7 @@ out: case msg := <-p.outputQueue: if !p.statusKnown { switch msg.Type { - case ethwire.MsgStatusTy, ethwire.MsgGetTxsTy, ethwire.MsgTxTy, ethwire.MsgGetBlockHashesTy, ethwire.MsgBlockHashesTy, ethwire.MsgGetBlocksTy, ethwire.MsgBlockTy: + case ethwire.MsgGetTxsTy, ethwire.MsgTxTy, ethwire.MsgGetBlockHashesTy, ethwire.MsgBlockHashesTy, ethwire.MsgGetBlocksTy, ethwire.MsgBlockTy: break skip } } -- cgit v1.2.3 From a34a971b508e1bc1fbeb3c2d02cbb8686d2491d8 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 2 Oct 2014 01:36:59 +0200 Subject: improved blockchain downloading --- peer.go | 75 +++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 41 insertions(+), 34 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 318294509..b8f850b5a 100644 --- a/peer.go +++ b/peer.go @@ -129,9 +129,9 @@ type Peer struct { statusKnown bool // Last received pong message - lastPong int64 - lastBlockReceived time.Time - LastHashReceived time.Time + lastPong int64 + lastBlockReceived time.Time + doneFetchingHashes bool host []byte port uint16 @@ -164,36 +164,38 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { pubkey := ethereum.KeyManager().PublicKey()[1:] return &Peer{ - outputQueue: make(chan *ethwire.Msg, outputBufferSize), - quit: make(chan bool), - ethereum: ethereum, - conn: conn, - inbound: inbound, - disconnect: 0, - connected: 1, - port: 30303, - pubkey: pubkey, - blocksRequested: 10, - caps: ethereum.ServerCaps(), - version: ethereum.ClientIdentity().String(), - protocolCaps: ethutil.NewValue(nil), - td: big.NewInt(0), + outputQueue: make(chan *ethwire.Msg, outputBufferSize), + quit: make(chan bool), + ethereum: ethereum, + conn: conn, + inbound: inbound, + disconnect: 0, + connected: 1, + port: 30303, + pubkey: pubkey, + blocksRequested: 10, + caps: ethereum.ServerCaps(), + version: ethereum.ClientIdentity().String(), + protocolCaps: ethutil.NewValue(nil), + td: big.NewInt(0), + doneFetchingHashes: true, } } func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { p := &Peer{ - outputQueue: make(chan *ethwire.Msg, outputBufferSize), - quit: make(chan bool), - ethereum: ethereum, - inbound: false, - connected: 0, - disconnect: 0, - port: 30303, - caps: caps, - version: ethereum.ClientIdentity().String(), - protocolCaps: ethutil.NewValue(nil), - td: big.NewInt(0), + outputQueue: make(chan *ethwire.Msg, outputBufferSize), + quit: make(chan bool), + ethereum: ethereum, + inbound: false, + connected: 0, + disconnect: 0, + port: 30303, + caps: caps, + version: ethereum.ClientIdentity().String(), + protocolCaps: ethutil.NewValue(nil), + td: big.NewInt(0), + doneFetchingHashes: true, } // Set up the connection in another goroutine so we don't block the main thread @@ -503,20 +505,22 @@ func (p *Peer) HandleInbound() { it := msg.Data.NewIterator() for it.Next() { hash := it.Value().Bytes() + p.lastReceivedHash = hash + if blockPool.HasCommonHash(hash) { foundCommonHash = true break } - p.lastReceivedHash = hash - p.LastHashReceived = time.Now() - blockPool.AddHash(hash, p) } if !foundCommonHash && msg.Data.Len() != 0 { p.FetchHashes() + } else { + peerlogger.Infof("Found common hash (%x...)\n", p.lastReceivedHash[0:4]) + p.doneFetchingHashes = true } case ethwire.MsgBlockTy: @@ -543,11 +547,15 @@ func (p *Peer) HandleInbound() { func (self *Peer) FetchBlocks(hashes [][]byte) { if len(hashes) > 0 { + peerlogger.Debugf("Fetching blocks (%d)\n", len(hashes)) + self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlocksTy, ethutil.ByteSliceToInterface(hashes))) } } func (self *Peer) FetchHashes() { + self.doneFetchingHashes = false + blockPool := self.ethereum.blockPool if self.td.Cmp(self.ethereum.HighestTDPeer()) >= 0 { @@ -562,7 +570,7 @@ func (self *Peer) FetchHashes() { } func (self *Peer) FetchingHashes() bool { - return time.Since(self.LastHashReceived) < 200*time.Millisecond + return !self.doneFetchingHashes } // General update method @@ -576,10 +584,9 @@ out: if self.IsCap("eth") { var ( sinceBlock = time.Since(self.lastBlockReceived) - sinceHash = time.Since(self.LastHashReceived) ) - if sinceBlock > 5*time.Second && sinceHash > 5*time.Second { + if sinceBlock > 5*time.Second { self.catchingUp = false } } -- cgit v1.2.3 From a75c92000fab997a41479c8f92e62f6b0d3f3434 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 2 Oct 2014 17:03:48 +0200 Subject: Black listing of bad peers --- peer.go | 61 +++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 22 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index b8f850b5a..2806e8a11 100644 --- a/peer.go +++ b/peer.go @@ -39,15 +39,15 @@ const ( // Values are given explicitly instead of by iota because these values are // defined by the wire protocol spec; it is easier for humans to ensure // correctness when values are explicit. - DiscReRequested = 0x00 - DiscReTcpSysErr = 0x01 - DiscBadProto = 0x02 - DiscBadPeer = 0x03 - DiscTooManyPeers = 0x04 - DiscConnDup = 0x05 - DiscGenesisErr = 0x06 - DiscProtoErr = 0x07 - DiscQuitting = 0x08 + DiscRequested DiscReason = iota + DiscReTcpSysErr + DiscBadProto + DiscBadPeer + DiscTooManyPeers + DiscConnDup + DiscGenesisErr + DiscProtoErr + DiscQuitting ) var discReasonToString = []string{ @@ -554,19 +554,22 @@ func (self *Peer) FetchBlocks(hashes [][]byte) { } func (self *Peer) FetchHashes() { - self.doneFetchingHashes = false - blockPool := self.ethereum.blockPool + blockPool.FetchHashes(self) + + /* + if self.td.Cmp(self.ethereum.HighestTDPeer()) >= 0 { + blockPool.td = self.td - if self.td.Cmp(self.ethereum.HighestTDPeer()) >= 0 { - blockPool.td = self.td + if !blockPool.HasLatestHash() { + self.doneFetchingHashes = false - if !blockPool.HasLatestHash() { - const amount = 256 - peerlogger.Debugf("Fetching hashes (%d)\n", amount) - self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(amount)})) + const amount = 256 + peerlogger.Debugf("Fetching hashes (%d)\n", amount) + self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(amount)})) + } } - } + */ } func (self *Peer) FetchingHashes() bool { @@ -631,18 +634,22 @@ func (p *Peer) Start() { } func (p *Peer) Stop() { + p.StopWithReason(DiscRequested) +} + +func (p *Peer) StopWithReason(reason DiscReason) { if atomic.AddInt32(&p.disconnect, 1) != 1 { return } + // Pre-emptively remove the peer; don't wait for reaping. We already know it's dead if we are here + p.ethereum.RemovePeer(p) + close(p.quit) if atomic.LoadInt32(&p.connected) != 0 { - p.writeMessage(ethwire.NewMessage(ethwire.MsgDiscTy, "")) + p.writeMessage(ethwire.NewMessage(ethwire.MsgDiscTy, reason)) p.conn.Close() } - - // Pre-emptively remove the peer; don't wait for reaping. We already know it's dead if we are here - p.ethereum.RemovePeer(p) } func (p *Peer) peersMessage() *ethwire.Msg { @@ -764,6 +771,16 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { return } + // Check for blacklisting + for _, pk := range p.ethereum.blacklist { + if bytes.Compare(pk, pub) == 0 { + peerlogger.Debugf("Blacklisted peer tried to connect (%x...)\n", pubkey[0:4]) + p.StopWithReason(DiscBadPeer) + + return + } + } + usedPub := 0 // This peer is already added to the peerlist so we expect to find a double pubkey at least once eachPeer(p.ethereum.Peers(), func(peer *Peer, e *list.Element) { -- cgit v1.2.3 From 677836cbee1105043335c672b41dc4402e98c227 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 2 Oct 2014 17:35:38 +0200 Subject: Kick off bad peers on bad chains and improved catch up on diverted chain --- peer.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 2806e8a11..763658dd5 100644 --- a/peer.go +++ b/peer.go @@ -202,7 +202,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { go func() { conn, err := p.Connect(addr) if err != nil { - peerlogger.Debugln("Connection to peer failed. Giving up.", err) + //peerlogger.Debugln("Connection to peer failed. Giving up.", err) p.Stop() return } @@ -517,7 +517,9 @@ func (p *Peer) HandleInbound() { } if !foundCommonHash && msg.Data.Len() != 0 { - p.FetchHashes() + if !p.FetchHashes() { + p.doneFetchingHashes = true + } } else { peerlogger.Infof("Found common hash (%x...)\n", p.lastReceivedHash[0:4]) p.doneFetchingHashes = true @@ -553,9 +555,9 @@ func (self *Peer) FetchBlocks(hashes [][]byte) { } } -func (self *Peer) FetchHashes() { +func (self *Peer) FetchHashes() bool { blockPool := self.ethereum.blockPool - blockPool.FetchHashes(self) + return blockPool.FetchHashes(self) /* if self.td.Cmp(self.ethereum.HighestTDPeer()) >= 0 { @@ -718,10 +720,7 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { // Compare the total TD with the blockchain TD. If remote is higher // fetch hashes from highest TD node. - if self.td.Cmp(self.ethereum.BlockChain().TD) > 0 { - self.ethereum.blockPool.AddHash(self.lastReceivedHash, self) - self.FetchHashes() - } + self.FetchHashes() ethlogger.Infof("Peer is [eth] capable. (TD = %v ~ %x) %d / %d", self.td, self.bestHash, protoVersion, netVersion) -- cgit v1.2.3 From 0015ce1e353f52cca818d11f566b9a656fb85f24 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 7 Oct 2014 11:18:46 +0200 Subject: kick of bad peers --- peer.go | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 763658dd5..63def37ed 100644 --- a/peer.go +++ b/peer.go @@ -516,10 +516,11 @@ func (p *Peer) HandleInbound() { blockPool.AddHash(hash, p) } - if !foundCommonHash && msg.Data.Len() != 0 { - if !p.FetchHashes() { - p.doneFetchingHashes = true - } + if !foundCommonHash { + //if !p.FetchHashes() { + // p.doneFetchingHashes = true + //} + p.FetchHashes() } else { peerlogger.Infof("Found common hash (%x...)\n", p.lastReceivedHash[0:4]) p.doneFetchingHashes = true @@ -533,8 +534,6 @@ func (p *Peer) HandleInbound() { it := msg.Data.NewIterator() for it.Next() { block := ethchain.NewBlockFromRlpValue(it.Value()) - //fmt.Printf("%v %x - %x\n", block.Number, block.Hash()[0:4], block.PrevHash[0:4]) - blockPool.Add(block, p) p.lastBlockReceived = time.Now() @@ -557,21 +556,8 @@ func (self *Peer) FetchBlocks(hashes [][]byte) { func (self *Peer) FetchHashes() bool { blockPool := self.ethereum.blockPool - return blockPool.FetchHashes(self) - - /* - if self.td.Cmp(self.ethereum.HighestTDPeer()) >= 0 { - blockPool.td = self.td - if !blockPool.HasLatestHash() { - self.doneFetchingHashes = false - - const amount = 256 - peerlogger.Debugf("Fetching hashes (%d)\n", amount) - self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(amount)})) - } - } - */ + return blockPool.FetchHashes(self) } func (self *Peer) FetchingHashes() bool { -- cgit v1.2.3 From 6de726f16cff6a79939cd9182424c7e9ef678044 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 8 Oct 2014 12:00:03 +0200 Subject: Protocol bump --- peer.go | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 63def37ed..7ed152696 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 33 + ProtocolVersion = 34 // Current P2P version P2PVersion = 0 // Ethereum network version @@ -848,26 +848,23 @@ func (p *Peer) RlpData() []interface{} { return []interface{}{p.host, p.port, p.pubkey} } -func packAddr(address, port string) ([]byte, uint16) { - addr := strings.Split(address, ".") - a, _ := strconv.Atoi(addr[0]) - b, _ := strconv.Atoi(addr[1]) - c, _ := strconv.Atoi(addr[2]) - d, _ := strconv.Atoi(addr[3]) - host := []byte{byte(a), byte(b), byte(c), byte(d)} - prt, _ := strconv.Atoi(port) +func packAddr(address, _port string) (host []byte, port uint16) { + p, _ := strconv.Atoi(_port) + port = uint16(p) - return host, uint16(prt) + h := net.ParseIP(address) + if ip := h.To4(); ip != nil { + host = []byte(ip) + } else { + host = []byte(h) + } + + return } func unpackAddr(value *ethutil.Value, p uint64) string { - byts := value.Bytes() - a := strconv.Itoa(int(byts[0])) - b := strconv.Itoa(int(byts[1])) - c := strconv.Itoa(int(byts[2])) - d := strconv.Itoa(int(byts[3])) - host := strings.Join([]string{a, b, c, d}, ".") - port := strconv.Itoa(int(p)) - - return net.JoinHostPort(host, port) + host, _ := net.IP(value.Bytes()).MarshalText() + prt := strconv.Itoa(int(p)) + + return net.JoinHostPort(string(host), prt) } -- cgit v1.2.3 From 4de3ad1712ce0fdc62b1acc27a3922b192e943c6 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 8 Oct 2014 12:29:49 +0200 Subject: New block message --- peer.go | 3 +++ 1 file changed, 3 insertions(+) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 7ed152696..24dbe88d3 100644 --- a/peer.go +++ b/peer.go @@ -538,7 +538,10 @@ func (p *Peer) HandleInbound() { p.lastBlockReceived = time.Now() } + case ethwire.MsgNewBlockTy: + p.ethereum.blockPool.AddNew(ethchain.NewBlockFromRlpValue(msg.Data), p) } + } } } -- cgit v1.2.3 From bd7aca76e1c68ec4d6f76468a250a83f4edd0545 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 8 Oct 2014 12:33:33 +0200 Subject: Proper new block --- peer.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 24dbe88d3..e9551e066 100644 --- a/peer.go +++ b/peer.go @@ -539,7 +539,15 @@ func (p *Peer) HandleInbound() { p.lastBlockReceived = time.Now() } case ethwire.MsgNewBlockTy: - p.ethereum.blockPool.AddNew(ethchain.NewBlockFromRlpValue(msg.Data), p) + var ( + blockPool = p.ethereum.blockPool + block = ethchain.NewBlockFromRlpValue(msg.Data.Get(0)) + td = msg.Data.Get(1).BigInt() + ) + + if td.Cmp(blockPool.td) > 0 { + p.ethereum.blockPool.AddNew(block, p) + } } } -- cgit v1.2.3 From 36cdab206849c7e363e0b9911553098c3e8ca644 Mon Sep 17 00:00:00 2001 From: Felix Lange <fjl@twurst.com> Date: Tue, 14 Oct 2014 01:58:31 +0200 Subject: all: use (blocking) event package instead of ethreact --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index e9551e066..d66d082bb 100644 --- a/peer.go +++ b/peer.go @@ -802,7 +802,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.versionKnown = true p.ethereum.PushPeer(p) - p.ethereum.reactor.Post("peerList", p.ethereum.Peers()) + p.ethereum.eventMux.Post(PeerListEvent{p.ethereum.Peers()}) p.protocolCaps = caps capsIt := caps.NewIterator() -- cgit v1.2.3 From d7736a7bbbf3d832dd108253fa5dea1de2cb9363 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 17 Oct 2014 17:11:34 +0200 Subject: Quick dirty peer update --- peer.go | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index d66d082bb..52eb20cfc 100644 --- a/peer.go +++ b/peer.go @@ -24,9 +24,9 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 34 + ProtocolVersion = 35 // Current P2P version - P2PVersion = 0 + P2PVersion = 2 // Ethereum network version NetVersion = 0 // Interval for ping/pong message @@ -434,7 +434,7 @@ func (p *Peer) HandleInbound() { } case ethwire.MsgGetPeersTy: // Peer asked for list of connected peers - p.pushPeers() + //p.pushPeers() case ethwire.MsgPeersTy: // Received a list of peers (probably because MsgGetPeersTy was send) data := msg.Data @@ -672,7 +672,7 @@ func (p *Peer) pushPeers() { func (self *Peer) pushStatus() { msg := ethwire.NewMessage(ethwire.MsgStatusTy, []interface{}{ - uint32(ProtocolVersion), + //uint32(ProtocolVersion), uint32(NetVersion), self.ethereum.BlockChain().TD, self.ethereum.BlockChain().CurrentBlock.Hash(), @@ -686,11 +686,11 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { c := msg.Data var ( - protoVersion = c.Get(0).Uint() - netVersion = c.Get(1).Uint() - td = c.Get(2).BigInt() - bestHash = c.Get(3).Bytes() - genesis = c.Get(4).Bytes() + //protoVersion = c.Get(0).Uint() + netVersion = c.Get(0).Uint() + td = c.Get(1).BigInt() + bestHash = c.Get(2).Bytes() + genesis = c.Get(3).Bytes() ) if bytes.Compare(self.ethereum.BlockChain().Genesis().Hash(), genesis) != 0 { @@ -703,10 +703,12 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { return } - if protoVersion != ProtocolVersion { - ethlogger.Warnf("Invalid protocol version %d. Disabling [eth]\n", protoVersion) - return - } + /* + if protoVersion != ProtocolVersion { + ethlogger.Warnf("Invalid protocol version %d. Disabling [eth]\n", protoVersion) + return + } + */ // Get the td and last hash self.td = td @@ -719,14 +721,14 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { // fetch hashes from highest TD node. self.FetchHashes() - ethlogger.Infof("Peer is [eth] capable. (TD = %v ~ %x) %d / %d", self.td, self.bestHash, protoVersion, netVersion) + ethlogger.Infof("Peer is [eth] capable. (TD = %v ~ %x)", self.td, self.bestHash) } func (p *Peer) pushHandshake() error { pubkey := p.ethereum.KeyManager().PublicKey() msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - P2PVersion, []byte(p.version), []interface{}{"eth"}, p.port, pubkey[1:], + P2PVersion, []byte(p.version), []interface{}{"eth", ProtocolVersion}, p.port, pubkey[1:], }) p.QueueMessage(msg) @@ -811,6 +813,12 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { cap := capsIt.Value().Str() switch cap { case "eth": + capsIt.Next() + version := capsIt.Value().Uint() + if version != ProtocolVersion { + ethlogger.Warnf("Invalid protocol version %d. Disabling [eth]\n", version) + continue + } p.pushStatus() } -- cgit v1.2.3 From 097ba56df59293f9225a8ecdc9e1c43a5ad891bb Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 20 Oct 2014 11:53:11 +0200 Subject: Renamed block_chain to chain_manager --- peer.go | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 52eb20cfc..0eb2eb299 100644 --- a/peer.go +++ b/peer.go @@ -476,7 +476,7 @@ func (p *Peer) HandleInbound() { hash := msg.Data.Get(0).Bytes() amount := msg.Data.Get(1).Uint() - hashes := p.ethereum.BlockChain().GetChainHashesFromHash(hash, amount) + hashes := p.ethereum.ChainManager().GetChainHashesFromHash(hash, amount) p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockHashesTy, ethutil.ByteSliceToInterface(hashes))) @@ -487,7 +487,7 @@ func (p *Peer) HandleInbound() { for i := 0; i < max; i++ { hash := msg.Data.Get(i).Bytes() - block := p.ethereum.BlockChain().GetBlock(hash) + block := p.ethereum.ChainManager().GetBlock(hash) if block != nil { blocks = append(blocks, block.Value().Raw()) } @@ -674,9 +674,9 @@ func (self *Peer) pushStatus() { msg := ethwire.NewMessage(ethwire.MsgStatusTy, []interface{}{ //uint32(ProtocolVersion), uint32(NetVersion), - self.ethereum.BlockChain().TD, - self.ethereum.BlockChain().CurrentBlock.Hash(), - self.ethereum.BlockChain().Genesis().Hash(), + self.ethereum.ChainManager().TD, + self.ethereum.ChainManager().CurrentBlock.Hash(), + self.ethereum.ChainManager().Genesis().Hash(), }) self.QueueMessage(msg) @@ -693,7 +693,7 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { genesis = c.Get(3).Bytes() ) - if bytes.Compare(self.ethereum.BlockChain().Genesis().Hash(), genesis) != 0 { + if bytes.Compare(self.ethereum.ChainManager().Genesis().Hash(), genesis) != 0 { ethlogger.Warnf("Invalid genisis hash %x. Disabling [eth]\n", genesis) return } @@ -728,7 +728,7 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { func (p *Peer) pushHandshake() error { pubkey := p.ethereum.KeyManager().PublicKey() msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ - P2PVersion, []byte(p.version), []interface{}{"eth", ProtocolVersion}, p.port, pubkey[1:], + P2PVersion, []byte(p.version), []interface{}{[]interface{}{"eth", ProtocolVersion}}, p.port, pubkey[1:], }) p.QueueMessage(msg) @@ -749,6 +749,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { // Check correctness of p2p protocol version if p2pVersion != P2PVersion { + fmt.Println(p) peerlogger.Debugf("Invalid P2P version. Require protocol %d, received %d\n", P2PVersion, p2pVersion) p.Stop() return @@ -807,16 +808,16 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { p.ethereum.eventMux.Post(PeerListEvent{p.ethereum.Peers()}) p.protocolCaps = caps - capsIt := caps.NewIterator() + + it := caps.NewIterator() var capsStrs []string - for capsIt.Next() { - cap := capsIt.Value().Str() + for it.Next() { + cap := it.Value().Get(0).Str() + ver := it.Value().Get(1).Uint() switch cap { case "eth": - capsIt.Next() - version := capsIt.Value().Uint() - if version != ProtocolVersion { - ethlogger.Warnf("Invalid protocol version %d. Disabling [eth]\n", version) + if ver != ProtocolVersion { + ethlogger.Warnf("Invalid protocol version %d. Disabling [eth]\n", ver) continue } p.pushStatus() -- cgit v1.2.3 From 520fdfe346ab51708f4f1fdfd0b2e42cc919e613 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 21 Oct 2014 13:25:31 +0200 Subject: PoC7 Net --- peer.go | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 0eb2eb299..c5e7b82b5 100644 --- a/peer.go +++ b/peer.go @@ -322,7 +322,7 @@ out: case msg := <-p.outputQueue: if !p.statusKnown { switch msg.Type { - case ethwire.MsgGetTxsTy, ethwire.MsgTxTy, ethwire.MsgGetBlockHashesTy, ethwire.MsgBlockHashesTy, ethwire.MsgGetBlocksTy, ethwire.MsgBlockTy: + case ethwire.MsgTxTy, ethwire.MsgGetBlockHashesTy, ethwire.MsgBlockHashesTy, ethwire.MsgGetBlocksTy, ethwire.MsgBlockTy: break skip } } @@ -457,16 +457,18 @@ func (p *Peer) HandleInbound() { // TMP if p.statusKnown { switch msg.Type { - case ethwire.MsgGetTxsTy: - // Get the current transactions of the pool - txs := p.ethereum.TxPool().CurrentTransactions() - // Get the RlpData values from the txs - txsInterface := make([]interface{}, len(txs)) - for i, tx := range txs { - txsInterface[i] = tx.RlpData() - } - // Broadcast it back to the peer - p.QueueMessage(ethwire.NewMessage(ethwire.MsgTxTy, txsInterface)) + /* + case ethwire.MsgGetTxsTy: + // Get the current transactions of the pool + txs := p.ethereum.TxPool().CurrentTransactions() + // Get the RlpData values from the txs + txsInterface := make([]interface{}, len(txs)) + for i, tx := range txs { + txsInterface[i] = tx.RlpData() + } + // Broadcast it back to the peer + p.QueueMessage(ethwire.NewMessage(ethwire.MsgTxTy, txsInterface)) + */ case ethwire.MsgGetBlockHashesTy: if msg.Data.Len() < 2 { @@ -687,10 +689,10 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { var ( //protoVersion = c.Get(0).Uint() - netVersion = c.Get(0).Uint() - td = c.Get(1).BigInt() - bestHash = c.Get(2).Bytes() - genesis = c.Get(3).Bytes() + netVersion = c.Get(1).Uint() + td = c.Get(2).BigInt() + bestHash = c.Get(3).Bytes() + genesis = c.Get(4).Bytes() ) if bytes.Compare(self.ethereum.ChainManager().Genesis().Hash(), genesis) != 0 { -- cgit v1.2.3 From 27cb0750c1deaed040876abdab1386a6687d7999 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 21 Oct 2014 13:43:30 +0200 Subject: Procotol version bump for uncle list change --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index c5e7b82b5..04ff4af39 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 35 + ProtocolVersion = 36 // Current P2P version P2PVersion = 2 // Ethereum network version -- cgit v1.2.3 From b5beb1aac11af92bfe0f3ed7560b9eb08495ed09 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Wed, 22 Oct 2014 15:22:21 +0200 Subject: added a transfer method to vm env --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 04ff4af39..557c436f6 100644 --- a/peer.go +++ b/peer.go @@ -674,7 +674,7 @@ func (p *Peer) pushPeers() { func (self *Peer) pushStatus() { msg := ethwire.NewMessage(ethwire.MsgStatusTy, []interface{}{ - //uint32(ProtocolVersion), + uint32(ProtocolVersion), uint32(NetVersion), self.ethereum.ChainManager().TD, self.ethereum.ChainManager().CurrentBlock.Hash(), -- cgit v1.2.3 From 11b3f975205fad8a331fa9a0e1d65ada544b84bc Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 27 Oct 2014 17:02:45 +0100 Subject: Upped protocol --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 291ba08e6..31bee1937 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 36 + ProtocolVersion = 37 // Current P2P version P2PVersion = 2 // Ethereum network version -- cgit v1.2.3 From 3ee0461cb5b6e4a5e2d287180afbdb681805a662 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 31 Oct 2014 10:59:17 +0100 Subject: Moved ethchain to chain --- peer.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 31bee1937..ab25e5709 100644 --- a/peer.go +++ b/peer.go @@ -12,7 +12,7 @@ import ( "sync/atomic" "time" - "github.com/ethereum/go-ethereum/ethchain" + "github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/ethlog" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethwire" @@ -155,7 +155,7 @@ type Peer struct { pingTime time.Duration pingStartTime time.Time - lastRequestedBlock *ethchain.Block + lastRequestedBlock *chain.Block protocolCaps *ethutil.Value } @@ -378,7 +378,7 @@ func formatMessage(msg *ethwire.Msg) (ret string) { case ethwire.MsgPeersTy: ret += fmt.Sprintf("(%d entries)", msg.Data.Len()) case ethwire.MsgBlockTy: - b1, b2 := ethchain.NewBlockFromRlpValue(msg.Data.Get(0)), ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len()-1)) + b1, b2 := chain.NewBlockFromRlpValue(msg.Data.Get(0)), ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len()-1)) ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), b1.Hash()[0:4], b2.Hash()[0:4]) case ethwire.MsgBlockHashesTy: h1, h2 := msg.Data.Get(0).Bytes(), msg.Data.Get(msg.Data.Len()-1).Bytes() @@ -429,7 +429,7 @@ func (p *Peer) HandleInbound() { // in the TxPool where it will undergo validation and // processing when a new block is found for i := 0; i < msg.Data.Len(); i++ { - tx := ethchain.NewTransactionFromValue(msg.Data.Get(i)) + tx := chain.NewTransactionFromValue(msg.Data.Get(i)) p.ethereum.TxPool().QueueTransaction(tx) } case ethwire.MsgGetPeersTy: @@ -535,7 +535,7 @@ func (p *Peer) HandleInbound() { it := msg.Data.NewIterator() for it.Next() { - block := ethchain.NewBlockFromRlpValue(it.Value()) + block := chain.NewBlockFromRlpValue(it.Value()) blockPool.Add(block, p) p.lastBlockReceived = time.Now() @@ -543,7 +543,7 @@ func (p *Peer) HandleInbound() { case ethwire.MsgNewBlockTy: var ( blockPool = p.ethereum.blockPool - block = ethchain.NewBlockFromRlpValue(msg.Data.Get(0)) + block = chain.NewBlockFromRlpValue(msg.Data.Get(0)) td = msg.Data.Get(1).BigInt() ) -- cgit v1.2.3 From b1c247231b11f313ca0eedff75ea563926d23f68 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 31 Oct 2014 12:56:05 +0100 Subject: ethlog => logger --- peer.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ab25e5709..36db68023 100644 --- a/peer.go +++ b/peer.go @@ -13,12 +13,12 @@ import ( "time" "github.com/ethereum/go-ethereum/chain" - "github.com/ethereum/go-ethereum/ethlog" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethwire" + "github.com/ethereum/go-ethereum/logger" ) -var peerlogger = ethlog.NewLogger("PEER") +var peerlogger = logger.NewLogger("PEER") const ( // The size of the output buffer for writing messages @@ -696,18 +696,18 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { ) if bytes.Compare(self.ethereum.ChainManager().Genesis().Hash(), genesis) != 0 { - ethlogger.Warnf("Invalid genisis hash %x. Disabling [eth]\n", genesis) + loggerger.Warnf("Invalid genisis hash %x. Disabling [eth]\n", genesis) return } if netVersion != NetVersion { - ethlogger.Warnf("Invalid network version %d. Disabling [eth]\n", netVersion) + loggerger.Warnf("Invalid network version %d. Disabling [eth]\n", netVersion) return } /* if protoVersion != ProtocolVersion { - ethlogger.Warnf("Invalid protocol version %d. Disabling [eth]\n", protoVersion) + loggerger.Warnf("Invalid protocol version %d. Disabling [eth]\n", protoVersion) return } */ @@ -723,7 +723,7 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { // fetch hashes from highest TD node. self.FetchHashes() - ethlogger.Infof("Peer is [eth] capable. (TD = %v ~ %x)", self.td, self.bestHash) + loggerger.Infof("Peer is [eth] capable. (TD = %v ~ %x)", self.td, self.bestHash) } @@ -819,7 +819,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { switch cap { case "eth": if ver != ProtocolVersion { - ethlogger.Warnf("Invalid protocol version %d. Disabling [eth]\n", ver) + loggerger.Warnf("Invalid protocol version %d. Disabling [eth]\n", ver) continue } p.pushStatus() @@ -828,7 +828,7 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { capsStrs = append(capsStrs, cap) } - ethlogger.Infof("Added peer (%s) %d / %d (%v)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, capsStrs) + peerlogger.Infof("Added peer (%s) %d / %d (%v)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, capsStrs) peerlogger.Debugln(p) } -- cgit v1.2.3 From 4914a78c8c650d7fc74570f25a682598aaeb6973 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 31 Oct 2014 14:53:42 +0100 Subject: ethwire => wire --- peer.go | 90 ++++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 36db68023..50daceb83 100644 --- a/peer.go +++ b/peer.go @@ -14,8 +14,8 @@ import ( "github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/ethwire" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/wire" ) var peerlogger = logger.NewLogger("PEER") @@ -112,7 +112,7 @@ type Peer struct { // Net connection conn net.Conn // Output queue which is used to communicate and handle messages - outputQueue chan *ethwire.Msg + outputQueue chan *wire.Msg // Quit channel quit chan bool // Determines whether it's an inbound or outbound peer @@ -164,7 +164,7 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { pubkey := ethereum.KeyManager().PublicKey()[1:] return &Peer{ - outputQueue: make(chan *ethwire.Msg, outputBufferSize), + outputQueue: make(chan *wire.Msg, outputBufferSize), quit: make(chan bool), ethereum: ethereum, conn: conn, @@ -184,7 +184,7 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { p := &Peer{ - outputQueue: make(chan *ethwire.Msg, outputBufferSize), + outputQueue: make(chan *wire.Msg, outputBufferSize), quit: make(chan bool), ethereum: ethereum, inbound: false, @@ -266,14 +266,14 @@ func (p *Peer) SetVersion(version string) { } // Outputs any RLP encoded data to the peer -func (p *Peer) QueueMessage(msg *ethwire.Msg) { +func (p *Peer) QueueMessage(msg *wire.Msg) { if atomic.LoadInt32(&p.connected) != 1 { return } p.outputQueue <- msg } -func (p *Peer) writeMessage(msg *ethwire.Msg) { +func (p *Peer) writeMessage(msg *wire.Msg) { // Ignore the write if we're not connected if atomic.LoadInt32(&p.connected) != 1 { return @@ -281,7 +281,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { if !p.versionKnown { switch msg.Type { - case ethwire.MsgHandshakeTy: // Ok + case wire.MsgHandshakeTy: // Ok default: // Anything but ack is allowed return } @@ -289,7 +289,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { /* if !p.statusKnown { switch msg.Type { - case ethwire.MsgStatusTy: // Ok + case wire.MsgStatusTy: // Ok default: // Anything but ack is allowed return } @@ -299,7 +299,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { peerlogger.DebugDetailf("(%v) <= %v\n", p.conn.RemoteAddr(), formatMessage(msg)) - err := ethwire.WriteMessage(p.conn, msg) + err := wire.WriteMessage(p.conn, msg) if err != nil { peerlogger.Debugln(" Can't send message:", err) // Stop the client if there was an error writing to it @@ -322,7 +322,7 @@ out: case msg := <-p.outputQueue: if !p.statusKnown { switch msg.Type { - case ethwire.MsgTxTy, ethwire.MsgGetBlockHashesTy, ethwire.MsgBlockHashesTy, ethwire.MsgGetBlocksTy, ethwire.MsgBlockTy: + case wire.MsgTxTy, wire.MsgGetBlockHashesTy, wire.MsgBlockHashesTy, wire.MsgGetBlocksTy, wire.MsgBlockTy: break skip } } @@ -340,13 +340,13 @@ out: return } */ - p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) + p.writeMessage(wire.NewMessage(wire.MsgPingTy, "")) p.pingStartTime = time.Now() // Service timer takes care of peer broadcasting, transaction // posting or block posting case <-serviceTimer.C: - p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) + p.QueueMessage(wire.NewMessage(wire.MsgGetPeersTy, "")) case <-p.quit: // Break out of the for loop if a quit message is posted @@ -366,7 +366,7 @@ clean: } } -func formatMessage(msg *ethwire.Msg) (ret string) { +func formatMessage(msg *wire.Msg) (ret string) { ret = fmt.Sprintf("%v %v", msg.Type, msg.Data) /* @@ -375,12 +375,12 @@ func formatMessage(msg *ethwire.Msg) (ret string) { */ /* switch msg.Type { - case ethwire.MsgPeersTy: + case wire.MsgPeersTy: ret += fmt.Sprintf("(%d entries)", msg.Data.Len()) - case ethwire.MsgBlockTy: + case wire.MsgBlockTy: b1, b2 := chain.NewBlockFromRlpValue(msg.Data.Get(0)), ethchain.NewBlockFromRlpValue(msg.Data.Get(msg.Data.Len()-1)) ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), b1.Hash()[0:4], b2.Hash()[0:4]) - case ethwire.MsgBlockHashesTy: + case wire.MsgBlockHashesTy: h1, h2 := msg.Data.Get(0).Bytes(), msg.Data.Get(msg.Data.Len()-1).Bytes() ret += fmt.Sprintf("(%d entries) %x - %x", msg.Data.Len(), h1, h2) } @@ -396,7 +396,7 @@ func (p *Peer) HandleInbound() { // HMM? time.Sleep(50 * time.Millisecond) // Wait for a message from the peer - msgs, err := ethwire.ReadMessages(p.conn) + msgs, err := wire.ReadMessages(p.conn) if err != nil { peerlogger.Debugln(err) } @@ -404,27 +404,27 @@ func (p *Peer) HandleInbound() { peerlogger.DebugDetailf("(%v) => %v\n", p.conn.RemoteAddr(), formatMessage(msg)) switch msg.Type { - case ethwire.MsgHandshakeTy: + case wire.MsgHandshakeTy: // Version message p.handleHandshake(msg) //if p.caps.IsCap(CapPeerDiscTy) { - p.QueueMessage(ethwire.NewMessage(ethwire.MsgGetPeersTy, "")) + p.QueueMessage(wire.NewMessage(wire.MsgGetPeersTy, "")) //} - case ethwire.MsgDiscTy: + case wire.MsgDiscTy: p.Stop() peerlogger.Infoln("Disconnect peer: ", DiscReason(msg.Data.Get(0).Uint())) - case ethwire.MsgPingTy: + case wire.MsgPingTy: // Respond back with pong - p.QueueMessage(ethwire.NewMessage(ethwire.MsgPongTy, "")) - case ethwire.MsgPongTy: + p.QueueMessage(wire.NewMessage(wire.MsgPongTy, "")) + case wire.MsgPongTy: // If we received a pong back from a peer we set the // last pong so the peer handler knows this peer is still // active. p.lastPong = time.Now().Unix() p.pingTime = time.Since(p.pingStartTime) - case ethwire.MsgTxTy: + case wire.MsgTxTy: // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and // processing when a new block is found @@ -432,10 +432,10 @@ func (p *Peer) HandleInbound() { tx := chain.NewTransactionFromValue(msg.Data.Get(i)) p.ethereum.TxPool().QueueTransaction(tx) } - case ethwire.MsgGetPeersTy: + case wire.MsgGetPeersTy: // Peer asked for list of connected peers //p.pushPeers() - case ethwire.MsgPeersTy: + case wire.MsgPeersTy: // Received a list of peers (probably because MsgGetPeersTy was send) data := msg.Data // Create new list of possible peers for the ethereum to process @@ -449,7 +449,7 @@ func (p *Peer) HandleInbound() { // Connect to the list of peers p.ethereum.ProcessPeerList(peers) - case ethwire.MsgStatusTy: + case wire.MsgStatusTy: // Handle peer's status msg p.handleStatus(msg) } @@ -458,7 +458,7 @@ func (p *Peer) HandleInbound() { if p.statusKnown { switch msg.Type { /* - case ethwire.MsgGetTxsTy: + case wire.MsgGetTxsTy: // Get the current transactions of the pool txs := p.ethereum.TxPool().CurrentTransactions() // Get the RlpData values from the txs @@ -467,10 +467,10 @@ func (p *Peer) HandleInbound() { txsInterface[i] = tx.RlpData() } // Broadcast it back to the peer - p.QueueMessage(ethwire.NewMessage(ethwire.MsgTxTy, txsInterface)) + p.QueueMessage(wire.NewMessage(wire.MsgTxTy, txsInterface)) */ - case ethwire.MsgGetBlockHashesTy: + case wire.MsgGetBlockHashesTy: if msg.Data.Len() < 2 { peerlogger.Debugln("err: argument length invalid ", msg.Data.Len()) } @@ -480,9 +480,9 @@ func (p *Peer) HandleInbound() { hashes := p.ethereum.ChainManager().GetChainHashesFromHash(hash, amount) - p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockHashesTy, ethutil.ByteSliceToInterface(hashes))) + p.QueueMessage(wire.NewMessage(wire.MsgBlockHashesTy, ethutil.ByteSliceToInterface(hashes))) - case ethwire.MsgGetBlocksTy: + case wire.MsgGetBlocksTy: // Limit to max 300 blocks max := int(math.Min(float64(msg.Data.Len()), 300.0)) var blocks []interface{} @@ -495,9 +495,9 @@ func (p *Peer) HandleInbound() { } } - p.QueueMessage(ethwire.NewMessage(ethwire.MsgBlockTy, blocks)) + p.QueueMessage(wire.NewMessage(wire.MsgBlockTy, blocks)) - case ethwire.MsgBlockHashesTy: + case wire.MsgBlockHashesTy: p.catchingUp = true blockPool := p.ethereum.blockPool @@ -528,7 +528,7 @@ func (p *Peer) HandleInbound() { p.doneFetchingHashes = true } - case ethwire.MsgBlockTy: + case wire.MsgBlockTy: p.catchingUp = true blockPool := p.ethereum.blockPool @@ -540,7 +540,7 @@ func (p *Peer) HandleInbound() { p.lastBlockReceived = time.Now() } - case ethwire.MsgNewBlockTy: + case wire.MsgNewBlockTy: var ( blockPool = p.ethereum.blockPool block = chain.NewBlockFromRlpValue(msg.Data.Get(0)) @@ -563,7 +563,7 @@ func (self *Peer) FetchBlocks(hashes [][]byte) { if len(hashes) > 0 { peerlogger.Debugf("Fetching blocks (%d)\n", len(hashes)) - self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlocksTy, ethutil.ByteSliceToInterface(hashes))) + self.QueueMessage(wire.NewMessage(wire.MsgGetBlocksTy, ethutil.ByteSliceToInterface(hashes))) } } @@ -629,7 +629,7 @@ func (p *Peer) Start() { // Wait a few seconds for startup and then ask for an initial ping time.Sleep(2 * time.Second) - p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) + p.writeMessage(wire.NewMessage(wire.MsgPingTy, "")) p.pingStartTime = time.Now() } @@ -648,12 +648,12 @@ func (p *Peer) StopWithReason(reason DiscReason) { close(p.quit) if atomic.LoadInt32(&p.connected) != 0 { - p.writeMessage(ethwire.NewMessage(ethwire.MsgDiscTy, reason)) + p.writeMessage(wire.NewMessage(wire.MsgDiscTy, reason)) p.conn.Close() } } -func (p *Peer) peersMessage() *ethwire.Msg { +func (p *Peer) peersMessage() *wire.Msg { outPeers := make([]interface{}, len(p.ethereum.InOutPeers())) // Serialise each peer for i, peer := range p.ethereum.InOutPeers() { @@ -664,7 +664,7 @@ func (p *Peer) peersMessage() *ethwire.Msg { } // Return the message to the peer with the known list of connected clients - return ethwire.NewMessage(ethwire.MsgPeersTy, outPeers) + return wire.NewMessage(wire.MsgPeersTy, outPeers) } // Pushes the list of outbound peers to the client when requested @@ -673,7 +673,7 @@ func (p *Peer) pushPeers() { } func (self *Peer) pushStatus() { - msg := ethwire.NewMessage(ethwire.MsgStatusTy, []interface{}{ + msg := wire.NewMessage(wire.MsgStatusTy, []interface{}{ uint32(ProtocolVersion), uint32(NetVersion), self.ethereum.ChainManager().TD, @@ -684,7 +684,7 @@ func (self *Peer) pushStatus() { self.QueueMessage(msg) } -func (self *Peer) handleStatus(msg *ethwire.Msg) { +func (self *Peer) handleStatus(msg *wire.Msg) { c := msg.Data var ( @@ -729,7 +729,7 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) { func (p *Peer) pushHandshake() error { pubkey := p.ethereum.KeyManager().PublicKey() - msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{ + msg := wire.NewMessage(wire.MsgHandshakeTy, []interface{}{ P2PVersion, []byte(p.version), []interface{}{[]interface{}{"eth", ProtocolVersion}}, p.port, pubkey[1:], }) @@ -738,7 +738,7 @@ func (p *Peer) pushHandshake() error { return nil } -func (p *Peer) handleHandshake(msg *ethwire.Msg) { +func (p *Peer) handleHandshake(msg *wire.Msg) { c := msg.Data var ( -- cgit v1.2.3 From 0c4adeceaeaff7a954fa7103a2200653ef217572 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 4 Nov 2014 01:47:02 +0100 Subject: Properly list caps --- peer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 50daceb83..f5afb4595 100644 --- a/peer.go +++ b/peer.go @@ -673,6 +673,7 @@ func (p *Peer) pushPeers() { } func (self *Peer) pushStatus() { + fmt.Println("push status") msg := wire.NewMessage(wire.MsgStatusTy, []interface{}{ uint32(ProtocolVersion), uint32(NetVersion), @@ -825,7 +826,7 @@ func (p *Peer) handleHandshake(msg *wire.Msg) { p.pushStatus() } - capsStrs = append(capsStrs, cap) + capsStrs = append(capsStrs, fmt.Sprintf("%s/%d", cap, ver)) } peerlogger.Infof("Added peer (%s) %d / %d (%v)\n", p.conn.RemoteAddr(), p.ethereum.Peers().Len(), p.ethereum.MaxPeers, capsStrs) -- cgit v1.2.3 From 429dd2a100f3b9e2b612b59bcb48f79a805cd6f9 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 7 Nov 2014 12:18:48 +0100 Subject: Implemented new miner w/ ui interface for merged mining. Closes #177 * Miner has been rewritten * Added new miner pane * Added option for local txs * Added option to read from MergeMining contract and list them for merged mining --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index f5afb4595..e0b2f7355 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 37 + ProtocolVersion = 39 // Current P2P version P2PVersion = 2 // Ethereum network version @@ -863,7 +863,7 @@ func (p *Peer) String() string { strConnectType = "disconnected" } - return fmt.Sprintf("[%s] (%s) %v %s [%s]", strConnectType, strBoundType, p.conn.RemoteAddr(), p.version, p.caps) + return fmt.Sprintf("[%s] (%s) %v %s", strConnectType, strBoundType, p.conn.RemoteAddr(), p.version) } -- cgit v1.2.3 From cbeebcd47da846e1b8990313f1ff1ffe7d0bf00f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 10 Nov 2014 01:17:31 +0100 Subject: Fixed bloom, updated mining & block processing * Reverted back to process blocks in batches method * Bloom generation and lookup fix * Minor UI changed (mainly debug) --- peer.go | 1 - 1 file changed, 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index e0b2f7355..c8fee2db4 100644 --- a/peer.go +++ b/peer.go @@ -673,7 +673,6 @@ func (p *Peer) pushPeers() { } func (self *Peer) pushStatus() { - fmt.Println("push status") msg := wire.NewMessage(wire.MsgStatusTy, []interface{}{ uint32(ProtocolVersion), uint32(NetVersion), -- cgit v1.2.3 From 6c9e503eb8d41d331d6a74e69539a06590072190 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 11 Nov 2014 22:51:26 +0100 Subject: Removed all implicit logging. Fixed gas issues and jump errors --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index c8fee2db4..45865ea66 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 39 + ProtocolVersion = 40 // Current P2P version P2PVersion = 2 // Ethereum network version -- cgit v1.2.3 From 20d518ee959f1621a5accf1f3432282a6c0d6c3c Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 13 Nov 2014 18:12:12 +0100 Subject: Numerous fixes for consensus. * Removed (buged) C++ specific gas specification for LOG* * Fixed LOG* where mstart went after msize * --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 45865ea66..6fef24ac0 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 40 + ProtocolVersion = 41 // Current P2P version P2PVersion = 2 // Ethereum network version -- cgit v1.2.3 From f6e55962a8cadfb440dd03467017941b96838362 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 14 Nov 2014 13:47:12 +0100 Subject: Fixes for PV41/42 * Don't expand mem on empty value * Removed all coinbase logs for PV42 * Removed C++ bug stuff for LOG* --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 6fef24ac0..b54978854 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 41 + ProtocolVersion = 42 // Current P2P version P2PVersion = 2 // Ethereum network version -- cgit v1.2.3 From a1b6a9ac29d0aa8d29a2c0535bafdb5fe4d4830b Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 18 Nov 2014 16:58:22 +0100 Subject: Begin of moving objects to types package * Block(s) * Transaction(s) --- peer.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index b54978854..fa73da21a 100644 --- a/peer.go +++ b/peer.go @@ -11,8 +11,7 @@ import ( "strings" "sync/atomic" "time" - - "github.com/ethereum/go-ethereum/chain" + "github.com/ethereum/go-ethereum/chain/types" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/wire" @@ -155,7 +154,7 @@ type Peer struct { pingTime time.Duration pingStartTime time.Time - lastRequestedBlock *chain.Block + lastRequestedBlock *types.Block protocolCaps *ethutil.Value } @@ -429,7 +428,7 @@ func (p *Peer) HandleInbound() { // in the TxPool where it will undergo validation and // processing when a new block is found for i := 0; i < msg.Data.Len(); i++ { - tx := chain.NewTransactionFromValue(msg.Data.Get(i)) + tx := types.NewTransactionFromValue(msg.Data.Get(i)) p.ethereum.TxPool().QueueTransaction(tx) } case wire.MsgGetPeersTy: @@ -535,7 +534,7 @@ func (p *Peer) HandleInbound() { it := msg.Data.NewIterator() for it.Next() { - block := chain.NewBlockFromRlpValue(it.Value()) + block := types.NewBlockFromRlpValue(it.Value()) blockPool.Add(block, p) p.lastBlockReceived = time.Now() @@ -543,7 +542,7 @@ func (p *Peer) HandleInbound() { case wire.MsgNewBlockTy: var ( blockPool = p.ethereum.blockPool - block = chain.NewBlockFromRlpValue(msg.Data.Get(0)) + block = types.NewBlockFromRlpValue(msg.Data.Get(0)) td = msg.Data.Get(1).BigInt() ) -- cgit v1.2.3 From f8d0cd9906a1ec4a4a1e95868a279312363f8b49 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 18 Nov 2014 19:44:17 +0100 Subject: Added a callback mechanism to chain adding. Not sure if this is the right approach. Why? BlockChain shouldn't need the "Ethereum" object. BlockChain shouldn't need to worry about notifying listeners or message propagation. --- peer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index fa73da21a..ff3593604 100644 --- a/peer.go +++ b/peer.go @@ -11,6 +11,7 @@ import ( "strings" "sync/atomic" "time" + "github.com/ethereum/go-ethereum/chain/types" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" @@ -23,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 42 + ProtocolVersion = 43 // Current P2P version P2PVersion = 2 // Ethereum network version -- cgit v1.2.3 From a3559c5e1b469890bb8d71e9992175febaae31c7 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 28 Nov 2014 21:38:10 +0100 Subject: updated PV --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index b54978854..86423c816 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 42 + ProtocolVersion = 45 // Current P2P version P2PVersion = 2 // Ethereum network version -- cgit v1.2.3 From 6dc46d3341dc5fa25bd005f9606de258874139be Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Mon, 1 Dec 2014 20:18:09 +0100 Subject: Changed the way transactions are being added to the transaction pool --- peer.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 86423c816..1b5f47f11 100644 --- a/peer.go +++ b/peer.go @@ -430,7 +430,13 @@ func (p *Peer) HandleInbound() { // processing when a new block is found for i := 0; i < msg.Data.Len(); i++ { tx := chain.NewTransactionFromValue(msg.Data.Get(i)) - p.ethereum.TxPool().QueueTransaction(tx) + err := p.ethereum.TxPool().Add(tx) + if err != nil { + peerlogger.Infoln(err) + } else { + peerlogger.Infof("tx OK (%x)\n", tx.Hash()[0:4]) + } + //p.ethereum.TxPool().QueueTransaction(tx) } case wire.MsgGetPeersTy: // Peer asked for list of connected peers -- cgit v1.2.3 From cb4d168ecc9f6c2ecdb1a8f3308f8f3eb9f02376 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 2 Dec 2014 17:22:33 +0100 Subject: Updated LOG to match proper gas in all cases --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 1b5f47f11..5e3f368d0 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 45 + ProtocolVersion = 46 // Current P2P version P2PVersion = 2 // Ethereum network version -- cgit v1.2.3 From 9008b155d3c8d2a32c4c8945f1174243d48d4e90 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 4 Dec 2014 10:28:02 +0100 Subject: Renamed `chain` => `core` --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index ed908265a..0d48faa1e 100644 --- a/peer.go +++ b/peer.go @@ -12,7 +12,7 @@ import ( "sync/atomic" "time" - "github.com/ethereum/go-ethereum/chain/types" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/wire" -- cgit v1.2.3 From 296112848cfe1a9697bbb92a9deb3eb1e04d6276 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 4 Dec 2014 15:13:29 +0100 Subject: Moved block validation as first step --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 0d48faa1e..bf84f6e35 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 46 + ProtocolVersion = 47 // Current P2P version P2PVersion = 2 // Ethereum network version -- cgit v1.2.3 From 73c4ca3a6fcf948f4bc637f5c1b55277cf64c06f Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 4 Dec 2014 15:31:48 +0100 Subject: Upped protocol version --- peer.go | 1 - 1 file changed, 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index bf84f6e35..3b39e45c7 100644 --- a/peer.go +++ b/peer.go @@ -756,7 +756,6 @@ func (p *Peer) handleHandshake(msg *wire.Msg) { // Check correctness of p2p protocol version if p2pVersion != P2PVersion { - fmt.Println(p) peerlogger.Debugf("Invalid P2P version. Require protocol %d, received %d\n", P2PVersion, p2pVersion) p.Stop() return -- cgit v1.2.3 From d80f8bda940a8ae8f6dab1502a46054c06cee5cc Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Fri, 5 Dec 2014 12:32:47 +0100 Subject: Fixed issue in VM where LOG didn't pop anything of the stack --- peer.go | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 3b39e45c7..46ac65247 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 47 + ProtocolVersion = 48 // Current P2P version P2PVersion = 2 // Ethereum network version @@ -129,9 +129,11 @@ type Peer struct { statusKnown bool // Last received pong message - lastPong int64 - lastBlockReceived time.Time - doneFetchingHashes bool + lastPong int64 + lastBlockReceived time.Time + doneFetchingHashes bool + lastHashAt time.Time + lastHashRequestedAt time.Time host []byte port uint16 @@ -327,19 +329,16 @@ out: } } + switch msg.Type { + case wire.MsgGetBlockHashesTy: + p.lastHashRequestedAt = time.Now() + } + p.writeMessage(msg) p.lastSend = time.Now() // Ping timer case <-pingTimer.C: - /* - timeSince := time.Since(time.Unix(p.lastPong, 0)) - if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+30*time.Second) { - peerlogger.Infof("Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince) - p.Stop() - return - } - */ p.writeMessage(wire.NewMessage(wire.MsgPingTy, "")) p.pingStartTime = time.Now() @@ -462,18 +461,6 @@ func (p *Peer) HandleInbound() { // TMP if p.statusKnown { switch msg.Type { - /* - case wire.MsgGetTxsTy: - // Get the current transactions of the pool - txs := p.ethereum.TxPool().CurrentTransactions() - // Get the RlpData values from the txs - txsInterface := make([]interface{}, len(txs)) - for i, tx := range txs { - txsInterface[i] = tx.RlpData() - } - // Broadcast it back to the peer - p.QueueMessage(wire.NewMessage(wire.MsgTxTy, txsInterface)) - */ case wire.MsgGetBlockHashesTy: if msg.Data.Len() < 2 { @@ -508,6 +495,7 @@ func (p *Peer) HandleInbound() { blockPool := p.ethereum.blockPool foundCommonHash := false + p.lastHashAt = time.Now() it := msg.Data.NewIterator() for it.Next() { @@ -524,9 +512,6 @@ func (p *Peer) HandleInbound() { } if !foundCommonHash { - //if !p.FetchHashes() { - // p.doneFetchingHashes = true - //} p.FetchHashes() } else { peerlogger.Infof("Found common hash (%x...)\n", p.lastReceivedHash[0:4]) -- cgit v1.2.3 From df5157c0b0be0feb5366070f7f5d0c6321513bf4 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Tue, 9 Dec 2014 20:28:36 +0100 Subject: PV49 --- peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 46ac65247..331e9de37 100644 --- a/peer.go +++ b/peer.go @@ -24,7 +24,7 @@ const ( // The size of the output buffer for writing messages outputBufferSize = 50 // Current protocol version - ProtocolVersion = 48 + ProtocolVersion = 49 // Current P2P version P2PVersion = 2 // Ethereum network version -- cgit v1.2.3 From 2d09e67713757e2a80eb614562c97f962af36cf7 Mon Sep 17 00:00:00 2001 From: obscuren <geffobscura@gmail.com> Date: Thu, 18 Dec 2014 13:17:24 +0100 Subject: Updated to new methods --- peer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'peer.go') diff --git a/peer.go b/peer.go index 331e9de37..13f0239d4 100644 --- a/peer.go +++ b/peer.go @@ -666,8 +666,8 @@ func (self *Peer) pushStatus() { msg := wire.NewMessage(wire.MsgStatusTy, []interface{}{ uint32(ProtocolVersion), uint32(NetVersion), - self.ethereum.ChainManager().TD, - self.ethereum.ChainManager().CurrentBlock.Hash(), + self.ethereum.ChainManager().Td(), + self.ethereum.ChainManager().CurrentBlock().Hash(), self.ethereum.ChainManager().Genesis().Hash(), }) -- cgit v1.2.3