From 2b32f47d2c17aaee655d56fd91c95798652b1116 Mon Sep 17 00:00:00 2001 From: obscuren 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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