Beispiel #1
0
func NewIncomingPeer(ipstr string) (p *onePeer, e error) {
	x := strings.Index(ipstr, ":")
	if x != -1 {
		ipstr = ipstr[:x] // remove port number
	}
	ip := net.ParseIP(ipstr)
	if ip != nil && len(ip) == 16 {
		if common.IsIPBlocked(ip[12:16]) {
			e = errors.New(ipstr + " is blocked")
			return
		}
		p = new(onePeer)
		copy(p.Ip4[:], ip[12:16])
		p.Services = common.Services
		copy(p.Ip6[:], ip[:12])
		p.Port = common.DefaultTcpPort
		if dbp := PeerDB.Get(qdb.KeyType(p.UniqID())); dbp != nil && NewPeer(dbp).Banned != 0 {
			e = errors.New(p.Ip() + " is banned")
			p = nil
		} else {
			p.Time = uint32(time.Now().Unix())
			p.Save()
		}
	} else {
		e = errors.New("Error parsing IP '" + ipstr + "'")
	}
	return
}
Beispiel #2
0
// Parese network's "addr" message
func ParseAddr(pl []byte) {
	b := bytes.NewBuffer(pl)
	cnt, _ := btc.ReadVLen(b)
	for i := 0; i < int(cnt); i++ {
		var buf [30]byte
		n, e := b.Read(buf[:])
		if n != len(buf) || e != nil {
			common.CountSafe("AddrError")
			//println("ParseAddr:", n, e)
			break
		}
		a := NewPeer(buf[:])
		if !ValidIp4(a.Ip4[:]) {
			common.CountSafe("AddrInvalid")
		} else if time.Unix(int64(a.Time), 0).Before(time.Now().Add(time.Minute)) {
			if time.Now().Before(time.Unix(int64(a.Time), 0).Add(ExpirePeerAfter)) {
				k := qdb.KeyType(a.UniqID())
				v := PeerDB.Get(k)
				if v != nil {
					a.Banned = NewPeer(v[:]).Banned
				}
				PeerDB.Put(k, a.Bytes())
			} else {
				common.CountSafe("AddrStale")
			}
		} else {
			common.CountSafe("AddrInFuture")
		}
	}
}
Beispiel #3
0
func (db *unspentDb) del(idx *TxPrevOut) {
	if db.notifyTx != nil {
		db.notifyTx(idx, nil)
	}
	key := qdb.KeyType(idx.UIdx())
	db.dbN(int(idx.Hash[31]) % NumberOfUnspentSubDBs).Del(key)
}
Beispiel #4
0
func (db *unwindDb) undo(height uint32, unsp *unspentDb) {
	if height != db.lastBlockHeight {
		panic("Unexpected height")
	}

	v := db.dbH(int(height) % NumberOfUnwindSubDBs).Get(qdb.KeyType(height))
	if v == nil {
		panic("Unwind data not found")
	}

	unwindFromReader(bytes.NewReader(v[32:]), unsp)
	db.del(height)

	db.lastBlockHeight--
	v = db.dbH(int(db.lastBlockHeight) % NumberOfUnwindSubDBs).Get(qdb.KeyType(db.lastBlockHeight))
	if v == nil {
		panic("Parent data not found")
	}
	copy(db.lastBlockHash[:], v[:32])
	return
}
Beispiel #5
0
func (db *unspentDb) scanstealth(sa *StealthAddr, walk func([]byte, []byte, uint32, []byte) bool) {
	for i := range db.tdb {
		db.dbN(i).Browse(func(k qdb.KeyType, v []byte) uint32 {
			if stealthIndex(v) {
				vo := binary.LittleEndian.Uint32(v[32:36])
				spend_v := db.dbN(i).GetNoMutex(qdb.KeyType(uint64(k) ^ uint64(vo) ^ uint64(vo+1)))
				if spend_v == nil {
					return qdb.NO_CACHE | qdb.NO_BROWSE
				} else if sa.CheckNonce(v[51:]) {
					if !walk(v[55:], spend_v[0:32], vo+1, spend_v[48:]) {
						return qdb.NO_CACHE | qdb.NO_BROWSE
					}
				}
			}
			return 0
		})
	}
}
Beispiel #6
0
func (db *unspentDb) get(po *TxPrevOut) (res *TxOut, e error) {
	ind := qdb.KeyType(po.UIdx())
	val := db.dbN(int(po.Hash[31]) % NumberOfUnspentSubDBs).Get(ind)
	if val == nil {
		e = errors.New("Unspent not found")
		return
	}

	if len(val) < 48 {
		panic(fmt.Sprint("unspent record too short:", len(val)))
	}

	res = new(TxOut)
	res.Value = binary.LittleEndian.Uint64(val[36:44])
	res.BlockHeight = binary.LittleEndian.Uint32(val[44:48])
	res.Pk_script = make([]byte, len(val)-48)
	copy(res.Pk_script, val[48:])
	return
}
Beispiel #7
0
func (db *unwindDb) commit(changes *btc.BlockChanges, blhash []byte) {
	if db.lastBlockHeight+1 != changes.Height {
		println(db.lastBlockHeight+1, changes.Height)
		panic("Unexpected height")
	}
	db.lastBlockHeight++
	copy(db.lastBlockHash[:], blhash[0:32])

	f := new(bytes.Buffer)
	f.Write(blhash[0:32])
	for k, _ := range changes.AddedTxs {
		writeSpent(f, &k, nil)
	}
	for k, v := range changes.DeledTxs {
		writeSpent(f, &k, v)
	}
	db.dbH(int(changes.Height)%NumberOfUnwindSubDBs).PutExt(qdb.KeyType(changes.Height), f.Bytes(), qdb.NO_CACHE)
	if changes.Height >= UnwindBufferMaxHistory {
		db.del(changes.Height - UnwindBufferMaxHistory)
	}
}
Beispiel #8
0
func (db *unspentDb) add(idx *TxPrevOut, Val_Pk *TxOut) {
	if db.notifyTx != nil {
		db.notifyTx(idx, Val_Pk)
	}
	v := make([]byte, 48+len(Val_Pk.Pk_script))
	copy(v[0:32], idx.Hash[:])
	binary.LittleEndian.PutUint32(v[32:36], idx.Vout)
	binary.LittleEndian.PutUint64(v[36:44], Val_Pk.Value)
	binary.LittleEndian.PutUint32(v[44:48], Val_Pk.BlockHeight)
	copy(v[48:], Val_Pk.Pk_script)
	ind := qdb.KeyType(idx.UIdx())
	var flgz uint32
	if stealthIndex(v) {
		flgz = qdb.YES_CACHE | qdb.YES_BROWSE
	} else {
		if Val_Pk.Value < MinBrowsableOutValue {
			flgz = qdb.NO_CACHE | qdb.NO_BROWSE
		} else if uint(Val_Pk.BlockHeight) < NocacheBlocksBelow {
			flgz = qdb.NO_CACHE
		}
	}
	db.dbN(int(idx.Hash[31])%NumberOfUnspentSubDBs).PutExt(ind, v, flgz)
}
Beispiel #9
0
func (db *unwindDb) commit(changes *BlockChanges, blhash []byte) {
	if db.lastBlockHeight+1 != changes.Height {
		println(db.lastBlockHeight+1, changes.Height)
		panic("Unexpected height")
	}
	db.lastBlockHeight++
	copy(db.lastBlockHash[:], blhash[0:32])

	f := new(bytes.Buffer)
	f.Write(blhash[0:32])
	// cast uin32 to int to properly discover negative diffs:
	if int(changes.LastKnownHeight)-int(changes.Height) < UnwindBufferMaxHistory {
		for k, _ := range changes.AddedTxs {
			writeSpent(f, &k, nil)
		}
		for k, v := range changes.DeledTxs {
			writeSpent(f, &k, v)
		}
	}
	db.dbH(int(changes.Height)%NumberOfUnwindSubDBs).PutExt(qdb.KeyType(changes.Height), f.Bytes(), qdb.NO_CACHE)
	if changes.Height >= UnwindBufferMaxHistory {
		db.del(changes.Height - UnwindBufferMaxHistory)
	}
}
Beispiel #10
0
func (p *onePeer) Save() {
	PeerDB.Put(qdb.KeyType(p.UniqID()), p.Bytes())
}
Beispiel #11
0
func (db *unwindDb) del(height uint32) {
	db.tdb[height%NumberOfUnwindSubDBs].Del(qdb.KeyType(height))
}
Beispiel #12
0
func getUnspIndex(po *TxPrevOut) qdb.KeyType {
	return qdb.KeyType(binary.LittleEndian.Uint64(po.Hash[:8]) ^ uint64(po.Vout))
}