peer: declare QueueMessage()'s doneChan as send only.

This ensures the channel passed to QueueMessage is writable and that
QueueMessage will not read from the channel (write-only).

This change is merely a safety change.  If a user of the API passes
a read-only channel to QueueMessage, it will now be caught at compile
time instead of panicking during runtime.

Also update internal functions.
This commit is contained in:
David Hill 2016-04-06 14:50:27 -04:00 committed by Dave Collins
parent 391d5e4a01
commit c1861bc8fa
2 changed files with 8 additions and 8 deletions

View File

@ -298,7 +298,7 @@ func newNetAddress(addr net.Addr, services wire.ServiceFlag) (*wire.NetAddress,
// shutdown)
type outMsg struct {
msg wire.Message
doneChan chan struct{}
doneChan chan<- struct{}
}
// stallControlCmd represents the command of a stall control message.
@ -1897,7 +1897,7 @@ cleanup:
// QueueMessage adds the passed bitcoin message to the peer send queue.
//
// This function is safe for concurrent access.
func (p *Peer) QueueMessage(msg wire.Message, doneChan chan struct{}) {
func (p *Peer) QueueMessage(msg wire.Message, doneChan chan<- struct{}) {
// Avoid risk of deadlock if goroutine already exited. The goroutine
// we will be sending to hangs around until it knows for a fact that
// it is marked as disconnected and *then* it drains the channels.

View File

@ -921,7 +921,7 @@ func (s *server) RemoveRebroadcastInventory(iv *wire.InvVect) {
// pushTxMsg sends a tx message for the provided transaction hash to the
// connected peer. An error is returned if the transaction hash is not known.
func (s *server) pushTxMsg(sp *serverPeer, sha *wire.ShaHash, doneChan, waitChan chan struct{}) error {
func (s *server) pushTxMsg(sp *serverPeer, sha *wire.ShaHash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
// Attempt to fetch the requested transaction from the pool. A
// call could be made to check for existence first, but simply trying
// to fetch a missing transaction results in the same behavior.
@ -948,7 +948,7 @@ func (s *server) pushTxMsg(sp *serverPeer, sha *wire.ShaHash, doneChan, waitChan
// pushBlockMsg sends a block message for the provided block hash to the
// connected peer. An error is returned if the block hash is not known.
func (s *server) pushBlockMsg(sp *serverPeer, sha *wire.ShaHash, doneChan, waitChan chan struct{}) error {
func (s *server) pushBlockMsg(sp *serverPeer, sha *wire.ShaHash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
blk, err := s.db.FetchBlockBySha(sha)
if err != nil {
peerLog.Tracef("Unable to fetch requested block sha %v: %v",
@ -967,7 +967,7 @@ func (s *server) pushBlockMsg(sp *serverPeer, sha *wire.ShaHash, doneChan, waitC
// We only send the channel for this message if we aren't sending
// an inv straight after.
var dc chan struct{}
var dc chan<- struct{}
continueHash := sp.continueHash
sendInv := continueHash != nil && continueHash.IsEqual(sha)
if !sendInv {
@ -999,7 +999,7 @@ func (s *server) pushBlockMsg(sp *serverPeer, sha *wire.ShaHash, doneChan, waitC
// the connected peer. Since a merkle block requires the peer to have a filter
// loaded, this call will simply be ignored if there is no filter loaded. An
// error is returned if the block hash is not known.
func (s *server) pushMerkleBlockMsg(sp *serverPeer, sha *wire.ShaHash, doneChan, waitChan chan struct{}) error {
func (s *server) pushMerkleBlockMsg(sp *serverPeer, sha *wire.ShaHash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
// Do not send a response if the peer doesn't have a filter loaded.
if !sp.filter.IsLoaded() {
if doneChan != nil {
@ -1030,7 +1030,7 @@ func (s *server) pushMerkleBlockMsg(sp *serverPeer, sha *wire.ShaHash, doneChan,
// Send the merkleblock. Only send the done channel with this message
// if no transactions will be sent afterwards.
var dc chan struct{}
var dc chan<- struct{}
if len(matchedTxIndices) == 0 {
dc = doneChan
}
@ -1040,7 +1040,7 @@ func (s *server) pushMerkleBlockMsg(sp *serverPeer, sha *wire.ShaHash, doneChan,
blkTransactions := blk.MsgBlock().Transactions
for i, txIndex := range matchedTxIndices {
// Only send the done channel on the final transaction.
var dc chan struct{}
var dc chan<- struct{}
if i == len(matchedTxIndices)-1 {
dc = doneChan
}