Ejemplo n.º 1
0
func NewEntryRecord(na *wire.NetAddress) *EntryRecord {
	record := &EntryRecord{
		addr:     util.ParseNetAddress(na),
		stamp:    na.Timestamp,
		services: uint64(na.Services),
	}

	return record
}
Ejemplo n.º 2
0
func NewVersionRecord(msg *wire.MsgVersion, ra *net.TCPAddr,
	la *net.TCPAddr) *VersionRecord {
	vr := &VersionRecord{
		Record: Record{
			stamp: time.Now(),
			ra:    ra,
			la:    la,
			cmd:   msg.Command(),
		},

		version:  msg.ProtocolVersion,
		services: uint64(msg.Services),
		sent:     msg.Timestamp,
		raddr:    util.ParseNetAddress(&msg.AddrYou),
		laddr:    util.ParseNetAddress(&msg.AddrMe),
		agent:    msg.UserAgent,
		block:    msg.LastBlock,
		relay:    !msg.DisableRelayTx,
		nonce:    msg.Nonce,
	}

	return vr
}
Ejemplo n.º 3
0
// processMessage does basic processing of the message to be in conformity
// with the bitcoin protocol and then forwards it to the respective filters
func (p *Peer) processMessage(msg wire.Message) {
	ra, ok1 := p.conn.RemoteAddr().(*net.TCPAddr)
	la, ok2 := p.conn.LocalAddr().(*net.TCPAddr)
	if ok1 && ok2 {
		record := convertor.Message(msg, ra, la)
		for _, rec := range p.recs {
			rec.Process(record)
		}
	}

	// if we have not yet received a version message and we receive any other
	// message, the peer is breaking the protocol and we disconnect
	if atomic.LoadUint32(&p.rcvd) == 0 {
		_, ok := msg.(*wire.MsgVersion)
		if !ok {
			p.log.Debug("%v: out of order non-version message", p)
			p.Stop()
			return
		}
	}

	// we read a message from the queue, process it depending on type
	switch m := msg.(type) {

	// version message is valid if we have not received one yet
	// we also try to avoid out-of-date protocol peers and connections to self
	case *wire.MsgVersion:
		if atomic.SwapUint32(&p.rcvd, 1) == 1 {
			p.log.Debug("%v: out of order version message", p)
			p.Stop()
			return
		}

		if m.Nonce == p.nonce {
			p.log.Debug("%v: detected connection to self", p)
			p.Stop()
			return
		}

		if uint32(m.ProtocolVersion) < wire.MultipleAddressVersion {
			p.log.Debug("%v: connected to obsolete peer", p)
			p.Stop()
			return
		}

		// synchronize our protocol version to lowest supported one
		version := atomic.LoadUint32(&p.version)
		version = util.MinUint32(version, uint32(m.ProtocolVersion))
		atomic.StoreUint32(&p.version, version)

		// send the verack message
		p.pushVerAck()

		// if we have not sent our version yet, do so
		// if we have, the handshake is now complete
		if atomic.SwapUint32(&p.sent, 1) != 1 {
			p.pushVersion()
		} else {
			p.mgr.Ready(p)
		}

	// verack messages only matter if we are waiting to finish handshake
	// if we have both received and sent version, it is complete
	case *wire.MsgVerAck:
		if atomic.LoadUint32(&p.sent) == 1 && atomic.LoadUint32(&p.rcvd) == 1 {
			p.mgr.Ready(p)
		}

	// only send a pong message if the protocol version expects it
	case *wire.MsgPing:
		if p.version >= wire.BIP0031Version {
			p.pushPong(m.Nonce)
		}

	case *wire.MsgPong:

	case *wire.MsgGetAddr:

	// if we get an address message, add the addresses to the repository
	case *wire.MsgAddr:
		for _, na := range m.AddrList {
			addr := util.ParseNetAddress(na)
			p.repo.Discovered(addr)
		}

	// if we get an inventory message, ask for the inventory
	case *wire.MsgInv:
		p.pushGetData(m)

	case *wire.MsgGetHeaders:

	case *wire.MsgHeaders:

	case *wire.MsgGetBlocks:

	// if we receive a block message, mark the block hash as known
	case *wire.MsgBlock:
		p.tracker.AddBlock(m.BlockSha())

	case *wire.MsgGetData:

	// if we receive a transaction message, mark the transaction hash as known
	case *wire.MsgTx:
		p.tracker.AddTx(m.TxSha())

	case *wire.MsgAlert:

	default:

	}
}