func (c *OneConnection) ProcessGetBlockTxn(pl []byte) { if len(pl) < 34 { println(c.ConnID, "GetBlockTxnShort") c.DoS("GetBlockTxnShort") return } hash := btc.NewUint256(pl[:32]) crec := GetchBlockForBIP152(hash) if crec == nil { fmt.Println(c.ConnID, "GetBlockTxn aborting for", hash.String()) return } req := bytes.NewReader(pl[32:]) indexes_length, _ := btc.ReadVLen(req) if indexes_length == 0 { println(c.ConnID, "GetBlockTxnEmpty") c.DoS("GetBlockTxnEmpty") return } var exp_idx uint64 msg := new(bytes.Buffer) msg.Write(hash.Hash[:]) btc.WriteVlen(msg, indexes_length) for { idx, er := btc.ReadVLen(req) if er != nil { println(c.ConnID, "GetBlockTxnERR") c.DoS("GetBlockTxnERR") return } idx += exp_idx if int(idx) >= len(crec.Block.Txs) { println(c.ConnID, "GetBlockTxnIdx+") c.DoS("GetBlockTxnIdx+") return } if c.Node.SendCmpctVer == 2 { msg.Write(crec.Block.Txs[idx].Raw) // coinbase - index 0 } else { crec.Block.Txs[idx].WriteSerialized(msg) // coinbase - index 0 } if indexes_length == 1 { break } indexes_length-- exp_idx = idx + 1 } c.SendRawMsg("blocktxn", msg.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 /*|| 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 (c *OneConnection) 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") c.DoS("AddrError") //println("ParseAddr:", n, e) break } a := peersdb.NewPeer(buf[:]) if !sys.ValidIp4(a.Ip4[:]) { c.Misbehave("AddrLocal", 2) } 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(peersdb.ExpirePeerAfter)) { k := qdb.KeyType(a.UniqID()) v := peersdb.PeerDB.Get(k) if v != nil { a.Banned = peersdb.NewPeer(v[:]).Banned } peersdb.PeerDB.Put(k, a.Bytes()) } else { common.CountSafe("AddrStale") } } else { c.Misbehave("AddrFuture", 5) } } }
func parse_addr(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 { COUNTER("ADER") break } a := peersdb.NewPeer(buf[:]) if !sys.ValidIp4(a.Ip4[:]) { COUNTER("ADNO") } 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(peersdb.ExpirePeerAfter)) { k := qdb.KeyType(a.UniqID()) v := peersdb.PeerDB.Get(k) if v != nil { a.Banned = peersdb.NewPeer(v[:]).Banned } peersdb.PeerDB.Put(k, a.Bytes()) } else { COUNTER("ADST") } } else { COUNTER("ADFU") } } }
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() } } }
// Parese network's "addr" message func (c *OneConnection) 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") c.DoS("AddrError") //println("ParseAddr:", n, e) break } a := peersdb.NewPeer(buf[:]) if !sys.ValidIp4(a.Ip4[:]) { //common.CountSafe("AddrLocal") if c.Misbehave("AddrLocal", 1) { break } //print(c.PeerAddr.Ip(), " ", c.Node.Agent, " ", c.Node.Version, " addr local ", a.String(), "\n> ") } 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(peersdb.ExpirePeerAfter)) { k := qdb.KeyType(a.UniqID()) v := peersdb.PeerDB.Get(k) if v != nil { a.Banned = peersdb.NewPeer(v[:]).Banned } a.Time = uint32(time.Now().Add(-5 * time.Minute).Unix()) // add new peers as not just alive peersdb.PeerDB.Put(k, a.Bytes()) } else { common.CountSafe("AddrStale") } } else { if c.Misbehave("AddrFuture", 50) { break } } } }
// 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) HandleHeaders(pl []byte) (new_headers_got int) { var highest_block_found uint32 c.X.GetHeadersInProgress = false b := bytes.NewReader(pl) cnt, e := btc.ReadVLen(b) if e != nil { println("HandleHeaders:", e.Error(), c.PeerAddr.Ip()) return } if cnt > 0 { MutexRcv.Lock() defer MutexRcv.Unlock() for i := 0; i < int(cnt); i++ { var hdr [81]byte n, _ := b.Read(hdr[:]) if n != 81 { println("HandleHeaders: pl too short", c.PeerAddr.Ip()) c.DoS("HdrErr1") return } if hdr[80] != 0 { fmt.Println("Unexpected value of txn_count from", c.PeerAddr.Ip()) c.DoS("HdrErr2") return } sta, b2g := c.ProcessNewHeader(hdr[:]) if b2g == nil { if sta == PH_STATUS_FATAL { //println("c.DoS(BadHeader)") c.DoS("BadHeader") return } else if sta == PH_STATUS_ERROR { //println("c.Misbehave(BadHeader)") c.Misbehave("BadHeader", 50) // do it 20 times and you are banned } } else { if sta == PH_STATUS_NEW { new_headers_got++ } if b2g.Block.Height > highest_block_found { highest_block_found = b2g.Block.Height } if c.Node.Height < b2g.Block.Height { c.Node.Height = b2g.Block.Height } c.X.GetBlocksDataNow = true b2g.TmPreproc = time.Now() } } } c.Mutex.Lock() c.X.LastHeadersEmpty = highest_block_found <= c.X.LastHeadersHeightAsk c.X.TotalNewHeadersCount += new_headers_got if new_headers_got == 0 { c.X.AllHeadersReceived = true } c.Mutex.Unlock() 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.BIdx()]; 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()) } }
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]) c.Mutex.Lock() c.InvStore(typ, h[4:36]) c.Mutex.Unlock() common.CountSafe(fmt.Sprintf("GetdataType-%x", typ)) if typ == MSG_BLOCK || typ == MSG_WITNESS_BLOCK { crec, _, er := common.BlockChain.Blocks.BlockGetExt(btc.NewUint256(h[4:])) //bl, _, er := common.BlockChain.Blocks.BlockGet(btc.NewUint256(h[4:])) if er == nil { bl := crec.Data if typ == MSG_BLOCK { // remove witness data from the block if crec.Block == nil { crec.Block, _ = btc.NewBlock(bl) } if crec.Block.OldData == nil { crec.Block.BuildTxList() } //println("block size", len(crec.Data), "->", len(bl)) bl = crec.Block.OldData } c.SendRawMsg("block", bl) } else { notfound = append(notfound, h[:]...) } } else if typ == MSG_TX || typ == MSG_WITNESS_TX { // transaction TxMutex.Lock() if tx, ok := TransactionsToSend[btc.NewUint256(h[4:]).BIdx()]; ok && tx.Blocked == 0 { tx.SentCnt++ tx.Lastsent = time.Now() TxMutex.Unlock() if tx.SegWit == nil || typ == MSG_WITNESS_TX { c.SendRawMsg("tx", tx.Data) } else { c.SendRawMsg("tx", tx.Serialize()) } } else { TxMutex.Unlock() notfound = append(notfound, h[:]...) } } else if typ == MSG_CMPCT_BLOCK { c.SendCmpctBlk(btc.NewUint256(h[4:])) } 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, uint64(len(notfound)/36)) buf.Write(notfound) c.SendRawMsg("notfound", buf.Bytes()) } }