func (bs *Bitswap) ReceiveMessage(ctx context.Context, p peer.ID, incoming bsmsg.BitSwapMessage) { // This call records changes to wantlists, blocks received, // and number of bytes transfered. bs.engine.MessageReceived(p, incoming) // TODO: this is bad, and could be easily abused. // Should only track *useful* messages in ledger iblocks := incoming.Blocks() if len(iblocks) == 0 { return } // quickly send out cancels, reduces chances of duplicate block receives var keys []key.Key for _, block := range iblocks { if _, found := bs.wm.wl.Contains(block.Key()); !found { log.Info("received un-asked-for block: %s", block) continue } keys = append(keys, block.Key()) } bs.wm.CancelWants(keys) wg := sync.WaitGroup{} for _, block := range iblocks { wg.Add(1) go func(b *blocks.Block) { defer wg.Done() bs.counterLk.Lock() bs.blocksRecvd++ has, err := bs.blockstore.Has(b.Key()) if err != nil { bs.counterLk.Unlock() log.Infof("blockstore.Has error: %s", err) return } if err == nil && has { bs.dupBlocksRecvd++ } brecvd := bs.blocksRecvd bdup := bs.dupBlocksRecvd bs.counterLk.Unlock() if has { return } k := b.Key() log.Event(ctx, "Bitswap.GetBlockRequest.End", &k) log.Debugf("got block %s from %s (%d,%d)", b, p, brecvd, bdup) hasBlockCtx, cancel := context.WithTimeout(ctx, hasBlockTimeout) if err := bs.HasBlock(hasBlockCtx, b); err != nil { log.Warningf("ReceiveMessage HasBlock error: %s", err) } cancel() }(block) } wg.Wait() }
func msgToStream(ctx context.Context, s inet.Stream, msg bsmsg.BitSwapMessage) error { deadline := time.Now().Add(sendMessageTimeout) if dl, ok := ctx.Deadline(); ok { deadline = dl } if err := s.SetWriteDeadline(deadline); err != nil { log.Warningf("error setting deadline: %s", err) } switch s.Protocol() { case ProtocolBitswap: if err := msg.ToNetV1(s); err != nil { log.Debugf("error: %s", err) return err } case ProtocolBitswapOne, ProtocolBitswapNoVers: if err := msg.ToNetV0(s); err != nil { log.Debugf("error: %s", err) return err } default: return fmt.Errorf("unrecognized protocol on remote: %s", s.Protocol()) } if err := s.SetWriteDeadline(time.Time{}); err != nil { log.Warningf("error resetting deadline: %s", err) } return nil }
func (e *Engine) MessageSent(p peer.ID, m bsmsg.BitSwapMessage) error { l := e.findOrCreate(p) for _, block := range m.Blocks() { l.SentBytes(len(block.Data())) l.wantList.Remove(block.Key()) e.peerRequestQueue.Remove(block.Key(), p) } return nil }
// MessageReceived performs book-keeping. Returns error if passed invalid // arguments. func (e *Engine) MessageReceived(p peer.ID, m bsmsg.BitSwapMessage) error { e.lock.Lock() defer e.lock.Unlock() if len(m.Wantlist()) == 0 && len(m.Blocks()) == 0 { log.Debugf("received empty message from %s", p) } newWorkExists := false defer func() { if newWorkExists { e.signalNewWork() } }() l := e.findOrCreate(p) if m.Full() { l.wantList = wl.New() } for _, entry := range m.Wantlist() { if entry.Cancel { log.Debugf("cancel %s", entry.Key) l.CancelWant(entry.Key) e.peerRequestQueue.Remove(entry.Key, p) } else { log.Debugf("wants %s - %d", entry.Key, entry.Priority) l.Wants(entry.Key, entry.Priority) if exists, err := e.bs.Has(entry.Key); err == nil && exists { e.peerRequestQueue.Push(entry.Entry, p) newWorkExists = true } } } for _, block := range m.Blocks() { log.Debugf("got block %s %d bytes", block.Key(), len(block.Data)) l.ReceivedBytes(len(block.Data)) for _, l := range e.ledgerMap { if entry, ok := l.WantListContains(block.Key()); ok { e.peerRequestQueue.Push(entry, l.Partner) newWorkExists = true } } } return nil }
func (bs *Bitswap) ReceiveMessage(ctx context.Context, p peer.ID, incoming bsmsg.BitSwapMessage) { // This call records changes to wantlists, blocks received, // and number of bytes transfered. bs.engine.MessageReceived(p, incoming) // TODO: this is bad, and could be easily abused. // Should only track *useful* messages in ledger iblocks := incoming.Blocks() if len(iblocks) == 0 { return } // quickly send out cancels, reduces chances of duplicate block receives var keys []key.Key for _, block := range iblocks { if _, found := bs.wm.wl.Contains(block.Key()); !found { log.Info("received un-asked-for block: %s", block) continue } keys = append(keys, block.Key()) } bs.wm.CancelWants(keys) wg := sync.WaitGroup{} for _, block := range iblocks { wg.Add(1) go func(b *blocks.Block) { defer wg.Done() if err := bs.updateReceiveCounters(b.Key()); err != nil { return // ignore error, is either logged previously, or ErrAlreadyHaveBlock } k := b.Key() log.Event(ctx, "Bitswap.GetBlockRequest.End", &k) log.Debugf("got block %s from %s", b, p) hasBlockCtx, cancel := context.WithTimeout(ctx, hasBlockTimeout) defer cancel() if err := bs.HasBlock(hasBlockCtx, b); err != nil { log.Warningf("ReceiveMessage HasBlock error: %s", err) } }(block) } wg.Wait() }
func msgToStream(s inet.Stream, msg bsmsg.BitSwapMessage) error { switch s.Protocol() { case ProtocolBitswap: if err := msg.ToNetV1(s); err != nil { log.Debugf("error: %s", err) return err } case ProtocolBitswapOne, ProtocolBitswapNoVers: if err := msg.ToNetV0(s); err != nil { log.Debugf("error: %s", err) return err } default: return fmt.Errorf("unrecognized protocol on remote: %s", s.Protocol()) } return nil }
func (bsnet *impl) SendMessage( ctx context.Context, p peer.ID, outgoing bsmsg.BitSwapMessage) error { s, err := bsnet.newStreamToPeer(ctx, p) if err != nil { return err } defer s.Close() if err := outgoing.ToNet(s); err != nil { log.Debugf("error: %s", err) return err } return err }
// MessageReceived performs book-keeping. Returns error if passed invalid // arguments. func (e *Engine) MessageReceived(p peer.ID, m bsmsg.BitSwapMessage) error { if len(m.Wantlist()) == 0 && len(m.Blocks()) == 0 { log.Debugf("received empty message from %s", p) } newWorkExists := false defer func() { if newWorkExists { e.signalNewWork() } }() l := e.findOrCreate(p) l.lk.Lock() defer l.lk.Unlock() if m.Full() { l.wantList = wl.New() } for _, entry := range m.Wantlist() { if entry.Cancel { log.Debugf("%s cancel %s", p, entry.Cid) l.CancelWant(entry.Cid) e.peerRequestQueue.Remove(entry.Cid, p) } else { log.Debugf("wants %s - %d", entry.Cid, entry.Priority) l.Wants(entry.Cid, entry.Priority) if exists, err := e.bs.Has(entry.Cid); err == nil && exists { e.peerRequestQueue.Push(entry.Entry, p) newWorkExists = true } } } for _, block := range m.Blocks() { log.Debugf("got block %s %d bytes", block, len(block.RawData())) l.ReceivedBytes(len(block.RawData())) } return nil }
func (bsnet *impl) SendRequest( ctx context.Context, p peer.ID, outgoing bsmsg.BitSwapMessage) (bsmsg.BitSwapMessage, error) { s, err := bsnet.newStreamToPeer(ctx, p) if err != nil { return nil, err } defer s.Close() if err := outgoing.ToNet(s); err != nil { log.Debugf("error: %s", err) return nil, err } incoming, err := bsmsg.FromNet(s) if err != nil { log.Debugf("error: %s", err) return incoming, err } return incoming, nil }
func (s *streamMessageSender) SendMsg(msg bsmsg.BitSwapMessage) error { return msg.ToNet(s.s) }