func (c *one_net_conn) headers(d []byte) { var hdr [81]byte b := bytes.NewReader(d) cnt, er := btc.ReadVLen(b) if er != nil { return } if cnt == 0 /*|| LastBlock.node.Height>=10e3*/ { SetAllHeadersDone(true) return } for i := uint64(0); i < cnt; i++ { if _, er = b.Read(hdr[:]); er != nil { return } if hdr[80] != 0 { fmt.Println(LastBlock.node.Height, "Unexpected value of txn_count") continue } bl, er := btc.NewBlock(hdr[:]) if er == nil { er = chkblock(bl) if er != nil { fmt.Println(er.Error()) os.Exit(1) } } else { fmt.Println(LastBlock.node.Height, er.Error()) } } //fmt.Println("Height:", LastBlock.node.Height) }
// 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") } } }
func (c *oneConnection) ProcessGetBlocks(pl []byte) { b := bytes.NewReader(pl) var ver uint32 e := binary.Read(b, binary.LittleEndian, &ver) if e != nil { println("ProcessGetBlocks:", e.Error(), c.addr.Ip()) return } cnt, e := btc.ReadVLen(b) if e != nil { println("ProcessGetBlocks:", e.Error(), c.addr.Ip()) return } h2get := make([]*btc.Uint256, cnt) var h [32]byte for i := 0; i < int(cnt); i++ { n, _ := b.Read(h[:]) if n != 32 { println("getblocks too short", c.addr.Ip()) return } h2get[i] = btc.NewUint256(h[:]) if dbg > 1 { println(c.addr.Ip(), "getbl", h2get[i].String()) } } n, _ := b.Read(h[:]) if n != 32 { println("getblocks does not have hash_stop", c.addr.Ip()) return } hashstop := btc.NewUint256(h[:]) var maxheight uint32 invs := make(map[[32]byte]bool, 500) for i := range h2get { BlockChain.BlockIndexAccess.Lock() if bl, ok := BlockChain.BlockIndex[h2get[i].BIdx()]; ok { if bl.Height > maxheight { maxheight = bl.Height } addInvBlockBranch(invs, bl, hashstop) } BlockChain.BlockIndexAccess.Unlock() if len(invs) >= 500 { break } } inv := new(bytes.Buffer) btc.WriteVlen(inv, uint32(len(invs))) for k, _ := range invs { binary.Write(inv, binary.LittleEndian, uint32(2)) inv.Write(k[:]) } if dbg > 1 { fmt.Println(c.addr.Ip(), "getblocks", cnt, maxheight, " ...", len(invs), "invs in resp ->", len(inv.Bytes())) } InvsSent++ c.SendRawMsg("inv", inv.Bytes()) }
func (c *one_net_conn) headers(d []byte) { var hdr [81]byte b := bytes.NewReader(d) cnt, er := btc.ReadVLen(b) if er != nil { return } if cnt == 0 { AllHeadersDone = true println("AllHeadersDone - terminate conn") c.broken = true return } for i := uint64(0); i < cnt; i++ { if _, er = b.Read(hdr[:]); er != nil { return } bl, er := btc.NewBlock(hdr[:]) if er == nil { er = chkblock(bl) if er != nil { println(er.Error()) os.Exit(1) } } } println("Height:", LastBlock.Node.Height) }
func (c *OneConnection) ProcessGetData(pl []byte) { //println(c.PeerAddr.Ip(), "getdata") b := bytes.NewReader(pl) cnt, e := btc.ReadVLen(b) if e != nil { println("ProcessGetData:", e.Error(), c.PeerAddr.Ip()) return } for i := 0; i < int(cnt); i++ { var typ uint32 var h [32]byte e = binary.Read(b, binary.LittleEndian, &typ) if e != nil { println("ProcessGetData:", e.Error(), c.PeerAddr.Ip()) return } n, _ := b.Read(h[:]) if n != 32 { println("ProcessGetData: pl too short", c.PeerAddr.Ip()) return } common.CountSafe(fmt.Sprint("GetdataType", typ)) if typ == 2 { uh := btc.NewUint256(h[:]) bl, _, er := common.BlockChain.Blocks.BlockGet(uh) if er == nil { c.SendRawMsg("block", bl) } else { //println("block", uh.String(), er.Error()) } } else if typ == 1 { // transaction uh := btc.NewUint256(h[:]) TxMutex.Lock() if tx, ok := TransactionsToSend[uh.Hash]; ok && tx.Blocked == 0 { tx.SentCnt++ tx.Lastsent = time.Now() TxMutex.Unlock() c.SendRawMsg("tx", tx.Data) if common.DebugLevel > 0 { println("sent tx to", c.PeerAddr.Ip()) } } else { TxMutex.Unlock() } } else { if common.DebugLevel > 0 { println("getdata for type", typ, "not supported yet") } } } }
func (c *oneConnection) ProcessGetData(pl []byte) { //println(c.addr.Ip(), "getdata") b := bytes.NewReader(pl) cnt, e := btc.ReadVLen(b) if e != nil { println("ProcessGetData:", e.Error(), c.addr.Ip()) return } for i := 0; i < int(cnt); i++ { var typ uint32 var h [32]byte e = binary.Read(b, binary.LittleEndian, &typ) if e != nil { println("ProcessGetData:", e.Error(), c.addr.Ip()) return } n, _ := b.Read(h[:]) if n != 32 { println("ProcessGetData: pl too short", c.addr.Ip()) return } if typ == 2 { uh := btc.NewUint256(h[:]) bl, _, er := BlockChain.Blocks.BlockGet(uh) if er == nil { BlockSent++ c.SendRawMsg("block", bl) } else { //println("block", uh.String(), er.Error()) } } else if typ == 1 { // transaction uh := btc.NewUint256(h[:]) if tx, ok := TransactionsToSend[uh.Hash]; ok { c.SendRawMsg("tx", tx) println("sent tx to", c.addr.Ip()) } } else { println("getdata for type", typ, "not supported yet") } } }
func parse_addr(pl []byte) { b := bytes.NewBuffer(pl) cnt, _ := btc.ReadVLen(b) for i := 0; i < int(cnt); i++ { var buf [30]byte var ip4 [4]byte n, e := b.Read(buf[:]) if n != len(buf) || e != nil { fmt.Println("parse_addr:", n, e) break } copy(ip4[:], buf[24:28]) if validip4(ip4[:]) { AddrMutex.Lock() if _, pres := AddrDatbase[ip4]; !pres { AddrDatbase[ip4] = false } AddrMutex.Unlock() } } }
func ParseAddr(pl []byte) { b := bytes.NewBuffer(pl) now := uint32(time.Now().Unix()) 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 { println("ParseAddr:", n, e) break } a := newPeer(buf[:]) if a.Time > now-expirePeerAfter { k := qdb.KeyType(a.UniqID()) v := peerDB.Get(k) if v != nil { a.Banned = newPeer(v[:]).Banned } peerDB.Put(k, a.Bytes()) } } peerDB.Defrag() }
// Read VLen followed by the number of locators // parse the payload of getblocks and getheaders messages func parseLocatorsPayload(pl []byte) (h2get []*btc.Uint256, hashstop *btc.Uint256, er error) { var cnt uint64 var h [32]byte var ver uint32 b := bytes.NewReader(pl) // version if er = binary.Read(b, binary.LittleEndian, &ver); er != nil { return } // hash count cnt, er = btc.ReadVLen(b) if er != nil { return } // block locator hashes if cnt > 0 { h2get = make([]*btc.Uint256, cnt) for i := 0; i < int(cnt); i++ { if _, er = b.Read(h[:]); er != nil { return } h2get[i] = btc.NewUint256(h[:]) } } // hash_stop if _, er = b.Read(h[:]); er != nil { return } hashstop = btc.NewUint256(h[:]) return }
func (c *OneConnection) ProcessGetBlocks(pl []byte) { b := bytes.NewReader(pl) var ver uint32 e := binary.Read(b, binary.LittleEndian, &ver) if e != nil { println("ProcessGetBlocks:", e.Error(), c.PeerAddr.Ip()) common.CountSafe("GetblksNoVer") c.DoS() return } cnt, e := btc.ReadVLen(b) if e != nil { println("ProcessGetBlocks:", e.Error(), c.PeerAddr.Ip()) common.CountSafe("GetblksNoVlen") c.DoS() return } if cnt < 1 { println("ProcessGetBlocks: empty inv list", c.PeerAddr.Ip()) common.CountSafe("GetblksNoInvs") c.DoS() return } h2get := make([]*btc.Uint256, cnt) var h [32]byte for i := 0; i < int(cnt); i++ { n, _ := b.Read(h[:]) if n != 32 { if common.DebugLevel > 0 { println("getblocks too short", c.PeerAddr.Ip()) } common.CountSafe("GetblksTooShort") c.DoS() return } h2get[i] = btc.NewUint256(h[:]) if common.DebugLevel > 2 { println(c.PeerAddr.Ip(), "getbl", h2get[i].String()) } } n, _ := b.Read(h[:]) if n != 32 { if common.DebugLevel > 0 { println("getblocks does not have hash_stop", c.PeerAddr.Ip()) } common.CountSafe("GetblksNoStop") c.DoS() return } hashstop := btc.NewUint256(h[:]) invs := make(map[[32]byte]bool, 500) for i := range h2get { common.BlockChain.BlockIndexAccess.Lock() if bl, ok := common.BlockChain.BlockIndex[h2get[i].BIdx()]; ok { // make sure that this block is in our main chain common.Last.Mutex.Lock() end := common.Last.Block common.Last.Mutex.Unlock() for ; end != nil && end.Height >= bl.Height; end = end.Parent { if end == bl { addInvBlockBranch(invs, bl, hashstop) // Yes - this is the main chain if common.DebugLevel > 0 { fmt.Println(c.PeerAddr.Ip(), "getblocks from", bl.Height, "stop at", hashstop.String(), "->", len(invs), "invs") } if len(invs) > 0 { common.BlockChain.BlockIndexAccess.Unlock() inv := new(bytes.Buffer) btc.WriteVlen(inv, uint32(len(invs))) for k, _ := range invs { binary.Write(inv, binary.LittleEndian, uint32(2)) inv.Write(k[:]) } c.SendRawMsg("inv", inv.Bytes()) return } } } } common.BlockChain.BlockIndexAccess.Unlock() } common.CountSafe("GetblksMissed") return }
func (c *OneConnection) ProcessGetData(pl []byte) { var notfound []byte //println(c.PeerAddr.Ip(), "getdata") b := bytes.NewReader(pl) cnt, e := btc.ReadVLen(b) if e != nil { println("ProcessGetData:", e.Error(), c.PeerAddr.Ip()) return } for i := 0; i < int(cnt); i++ { var typ uint32 var h [36]byte n, _ := b.Read(h[:]) if n != 36 { println("ProcessGetData: pl too short", c.PeerAddr.Ip()) return } typ = binary.LittleEndian.Uint32(h[:4]) common.CountSafe(fmt.Sprint("GetdataType", typ)) if typ == 2 { uh := btc.NewUint256(h[4:]) bl, _, er := common.BlockChain.Blocks.BlockGet(uh) if er == nil { c.SendRawMsg("block", bl) } else { notfound = append(notfound, h[:]...) } } else if typ == 1 { // transaction uh := btc.NewUint256(h[4:]) TxMutex.Lock() if tx, ok := TransactionsToSend[uh.Hash]; ok && tx.Blocked == 0 { tx.SentCnt++ tx.Lastsent = time.Now() TxMutex.Unlock() c.SendRawMsg("tx", tx.Data) } else { TxMutex.Unlock() notfound = append(notfound, h[:]...) } } else { if common.DebugLevel > 0 { println("getdata for type", typ, "not supported yet") } if typ > 0 && typ <= 3 /*3 is a filtered block(we dont support it)*/ { notfound = append(notfound, h[:]...) } } } if len(notfound) > 0 { buf := new(bytes.Buffer) btc.WriteVlen(buf, uint32(len(notfound)/36)) buf.Write(notfound) c.SendRawMsg("notfound", buf.Bytes()) } }