// handleMemPoolMsg is invoked when a peer receives a mempool bitcoin message. // It creates and sends an inventory message with the contents of the memory // pool up to the maximum inventory allowed per message. func (p *peer) handleMemPoolMsg(msg *btcwire.MsgMemPool) { // Generate inventory message with the available transactions in the // transaction memory pool. Limit it to the max allowed inventory // per message. The the NewMsgInvSizeHint function automatically limits // the passed hint to the maximum allowed, so it's safe to pass it // without double checking it here. hashes := p.server.txMemPool.TxShas() invMsg := btcwire.NewMsgInvSizeHint(uint(len(hashes))) for i, hash := range hashes { // Another thread might have removed the transaction from the // pool since the initial query. if !p.server.txMemPool.IsTransactionInPool(hash) { continue } iv := btcwire.NewInvVect(btcwire.InvTypeTx, hash) invMsg.AddInvVect(iv) if i+1 >= btcwire.MaxInvPerMsg { break } } // Send the inventory message if there is anything to send. if len(invMsg.InvList) > 0 { p.QueueMessage(invMsg, nil) } }
// TestInv tests the MsgInv API. func TestInv(t *testing.T) { pver := btcwire.ProtocolVersion // Ensure the command is expected value. wantCmd := "inv" msg := btcwire.NewMsgInv() if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgInv: wrong command - got %v want %v", cmd, wantCmd) } // Ensure max payload is expected value for latest protocol version. // Num inventory vectors (varInt) + max allowed inventory vectors. wantPayload := uint32(1800009) maxPayload := msg.MaxPayloadLength(pver) if maxPayload != wantPayload { t.Errorf("MaxPayloadLength: wrong max payload length for "+ "protocol version %d - got %v, want %v", pver, maxPayload, wantPayload) } // Ensure inventory vectors are added properly. hash := btcwire.ShaHash{} iv := btcwire.NewInvVect(btcwire.InvTypeBlock, &hash) err := msg.AddInvVect(iv) if err != nil { t.Errorf("AddInvVect: %v", err) } if msg.InvList[0] != iv { t.Errorf("AddInvVect: wrong invvect added - got %v, want %v", spew.Sprint(msg.InvList[0]), spew.Sprint(iv)) } // Ensure adding more than the max allowed inventory vectors per // message returns an error. for i := 0; i < btcwire.MaxInvPerMsg; i++ { err = msg.AddInvVect(iv) } if err == nil { t.Errorf("AddInvVect: expected error on too many inventory " + "vectors not received") } // Ensure creating the message with a size hint larger than the max // works as expected. msg = btcwire.NewMsgInvSizeHint(btcwire.MaxInvPerMsg + 1) wantCap := btcwire.MaxInvPerMsg if cap(msg.InvList) != wantCap { t.Errorf("NewMsgInvSizeHint: wrong cap for size hint - "+ "got %v, want %v", cap(msg.InvList), wantCap) } return }