Пример #1
0
func (c *oneConnection) VerMsg(pl []byte) error {
	if len(pl) >= 46 {
		c.node.version = binary.LittleEndian.Uint32(pl[0:4])
		c.node.services = binary.LittleEndian.Uint64(pl[4:12])
		c.node.timestamp = binary.LittleEndian.Uint64(pl[12:20])
		if MyExternalAddr == nil {
			MyExternalAddr = btc.NewNetAddr(pl[20:46]) // These bytes should know our external IP
			MyExternalAddr.Port = DefaultTcpPort
		}
		if len(pl) >= 86 {
			//fmt.Println("From:", btc.NewNetAddr(pl[46:72]).String())
			//fmt.Println("Nonce:", hex.EncodeToString(pl[72:80]))
			le, of := btc.VLen(pl[80:])
			of += 80
			c.node.agent = string(pl[of : of+le])
			of += le
			if len(pl) >= of+4 {
				c.node.height = binary.LittleEndian.Uint32(pl[of : of+4])
				/*of += 4
				if len(pl) >= of+1 {
					fmt.Println("Relay:", pl[of])
				}*/
			}
		}
	} else {
		return errors.New("Version message too short")
	}
	c.SendRawMsg("verack", []byte{})
	if c.listen {
		c.SendVersion()
	}
	return nil
}
Пример #2
0
func (c *OneConnection) ProcessInv(pl []byte) {
	if len(pl) < 37 {
		println(c.PeerAddr.Ip(), "inv payload too short", len(pl))
		return
	}
	c.InvsRecieved++

	cnt, of := btc.VLen(pl)
	if len(pl) != of+36*cnt {
		println("inv payload length mismatch", len(pl), of, cnt)
	}

	var blinv2ask []byte

	for i := 0; i < cnt; i++ {
		typ := binary.LittleEndian.Uint32(pl[of : of+4])
		common.CountSafe(fmt.Sprint("InvGot", typ))
		if typ == 2 {
			if blockWanted(pl[of+4 : of+36]) {
				blinv2ask = append(blinv2ask, pl[of+4:of+36]...)
			}
		} else if typ == 1 {
			if common.CFG.TXPool.Enabled {
				c.TxInvNotify(pl[of+4 : of+36])
			}
		}
		of += 36
	}

	if len(blinv2ask) > 0 {
		bu := new(bytes.Buffer)
		btc.WriteVlen(bu, uint32(len(blinv2ask)/32))
		for i := 0; i < len(blinv2ask); i += 32 {
			bh := btc.NewUint256(blinv2ask[i : i+32])
			c.Mutex.Lock()
			c.GetBlockInProgress[bh.BIdx()] = &oneBlockDl{hash: bh, start: time.Now()}
			c.Mutex.Unlock()
			binary.Write(bu, binary.LittleEndian, uint32(2))
			bu.Write(bh.Hash[:])
		}
		c.SendRawMsg("getdata", bu.Bytes())
	}

	return
}
Пример #3
0
func (c *oneConnection) ProcessInv(pl []byte) {
	if len(pl) < 37 {
		println("inv payload too short")
		return
	}

	cnt, of := btc.VLen(pl)
	if len(pl) != of+36*cnt {
		println("inv payload length mismatch", len(pl), of, cnt)
	}

	var blocks2get [][32]byte
	var txs uint32
	for i := 0; i < cnt; i++ {
		typ := binary.LittleEndian.Uint32(pl[of : of+4])
		if typ == 2 {
			if InvsNotify(pl[of+4 : of+36]) {
				var inv [32]byte
				copy(inv[:], pl[of+4:of+36])
				blocks2get = append(blocks2get, inv)
			}
		} else {
			txs++
		}
		of += 36
	}
	if dbg > 1 {
		println(c.addr.Ip(), "ProcessInv:", cnt, "tot /", txs, "txs -> get", len(blocks2get), "blocks")
	}

	if len(blocks2get) > 0 {
		msg := make([]byte, 9 /*maxvlen*/ +len(blocks2get)*36)
		le := btc.PutVlen(msg, len(blocks2get))
		for i := range blocks2get {
			binary.LittleEndian.PutUint32(msg[le:le+4], 2)
			copy(msg[le+4:le+36], blocks2get[i][:])
			le += 36
		}
		if dbg > 0 {
			println("getdata for", len(blocks2get), "/", cnt, "blocks", le)
		}
		c.SendRawMsg("getdata", msg[:le])
	}
	return
}
Пример #4
0
func (c *OneConnection) HandleVersion(pl []byte) error {
	if len(pl) >= 80 /*Up to, includiong, the nonce */ {
		c.Mutex.Lock()
		c.Node.Version = binary.LittleEndian.Uint32(pl[0:4])
		if bytes.Equal(pl[72:80], nonce[:]) {
			c.Mutex.Unlock()
			return errors.New("Connecting to ourselves")
		}
		if c.Node.Version < MIN_PROTO_VERSION {
			c.Mutex.Unlock()
			return errors.New("Client version too low")
		}
		c.Node.Services = binary.LittleEndian.Uint64(pl[4:12])
		c.Node.Timestamp = binary.LittleEndian.Uint64(pl[12:20])
		c.Mutex.Unlock()
		if ValidIp4(pl[40:44]) {
			ExternalIpMutex.Lock()
			ip4 := binary.BigEndian.Uint32(pl[40:44])
			ExternalIp4[ip4] = [2]uint{ExternalIp4[ip4][0] + 1, uint(time.Now().Unix())}
			ExternalIpMutex.Unlock()
		}
		if len(pl) >= 86 {
			c.Mutex.Lock()
			le, of := btc.VLen(pl[80:])
			of += 80
			c.Node.Agent = string(pl[of : of+le])
			of += le
			if len(pl) >= of+4 {
				c.Node.Height = binary.LittleEndian.Uint32(pl[of : of+4])
				of += 4
				if len(pl) > of && pl[of] == 0 {
					c.Node.DoNotRelayTxs = true
				}
			}
			c.Mutex.Unlock()
		}
	} else {
		return errors.New("common.Version message too short")
	}
	c.SendRawMsg("verack", []byte{})
	return nil
}