diff --git a/dummy/manager.go b/dummy/manager.go
index 6a58eb981dda9dfa34876d6cfbd9c553e8c5b969..7bc4847134c5b95ebb776f81d04199ad0862878c 100644
--- a/dummy/manager.go
+++ b/dummy/manager.go
@@ -21,20 +21,25 @@ import (
 	"time"
 )
 
+// Manager related thread handling constants.
 const (
+	// The name of the Manager's stoppable.Stoppable
 	dummyTrafficStoppableName = "DummyTraffic"
-	statusChanLen             = 100
+
+	// The amount of statuses in queue that can be placed
+	// by Manager.SetStatus.
+	statusChanLen = 100
 )
 
-// Thread status.
+// The thread status values.
 const (
-	notStarted uint32 = iota
-	running
-	paused
-	stopped
+	notStarted uint32 = iota // Sending thread has not been started
+	running                  // Sending thread is currently operating
+	paused                   // Sending thread is temporarily halted.
+	stopped                  // Sending thread is halted.
 )
 
-// Error messages.
+// Error messages for Manager.
 const (
 	setStatusErr = "Failed to change status of dummy traffic send thread to %t: channel full"
 )
@@ -56,15 +61,17 @@ type Manager struct {
 	// Pauses/Resumes the dummy send thread when triggered
 	statusChan chan bool
 
-	// Cmix interfaces
+	// Interfaces
 	net   cmix.Client
 	store storage.Session
-	rng   *fastRNG.StreamGenerator
+
+	// Generates
+	rng *fastRNG.StreamGenerator
 }
 
 // NewManager creates a Manager object and initialises the
 // dummy traffic sending thread. Note that the Manager does not start sending dummy
-// traffic until True is passed into Manager.SetStatus. The time duration
+// traffic until `True` is passed into Manager.SetStatus. The time duration
 // between each sending operation and the amount of messages sent each interval
 // are randomly generated values with bounds defined by the
 // given parameters below.
@@ -74,9 +81,9 @@ type Manager struct {
 //    each sending cycle.
 //  - avgSendDeltaMS - the average duration, in milliseconds, to wait
 //    between sends.
-//  - randomRangeMS - the upper bound of the interval between sending cycles.
-//    Sends occur every avgSendDeltaMS +/- a random duration with an
-//    upper bound of randomRangeMS
+//  - randomRangeMS - the upper bound of the interval between sending cycles,
+//    in milliseconds. Sends occur every avgSendDeltaMS +/- a random duration
+//    with an upper bound of randomRangeMS.
 func NewManager(maxNumMessages int,
 	avgSendDelta, randomRange time.Duration,
 	net *xxdk.Cmix) *Manager {
@@ -86,7 +93,7 @@ func NewManager(maxNumMessages int,
 }
 
 // newManager builds a new dummy Manager from fields explicitly passed in. This
-// function is a helper function for NewManager to make it easier to test.
+// function is a helper function for NewManager.
 func newManager(maxNumMessages int, avgSendDelta, randomRange time.Duration,
 	net cmix.Client, store storage.Session, rng *fastRNG.StreamGenerator) *Manager {
 	return &Manager{
@@ -102,7 +109,7 @@ func newManager(maxNumMessages int, avgSendDelta, randomRange time.Duration,
 }
 
 // StartDummyTraffic starts the process of sending dummy traffic. This function
-// matches the xxdk.Service type.
+// adheres to xxdk.Service.
 func (m *Manager) StartDummyTraffic() (stoppable.Stoppable, error) {
 	stop := stoppable.NewSingle(dummyTrafficStoppableName)
 	go m.sendThread(stop)
@@ -118,10 +125,10 @@ func (m *Manager) StartDummyTraffic() (stoppable.Stoppable, error) {
 // operation has completed.
 //
 // Params:
-//  - boolean - True: Sending thread is sending dummy messages.
-//  			False: Sending thread is paused/stopped and is not sending dummy messages
+//  - boolean - Input should be true if you want to send dummy messages.
+//  			Input should be false if you want to pause dummy messages.
 // Returns:
-//  - error - if the DummyTraffic.SetStatus is called too frequently, causing the
+//  - error - if the Manager.SetStatus is called too frequently, causing the
 //    internal status channel to fill.
 func (m *Manager) SetStatus(status bool) error {
 	select {
@@ -132,15 +139,16 @@ func (m *Manager) SetStatus(status bool) error {
 	}
 }
 
-// GetStatus returns the current state of the dummy traffic sending thread.
+// GetStatus returns the current state of the Manager's sending thread.
 // Note that this function does not return the status set by the most recent call to
-// SetStatus directly. Instead, this call returns the current status of the sending thread.
+// SetStatus. Instead, this call returns the current status of the sending thread.
 // This is due to the small delay that may occur between calling SetStatus and the
 // sending thread taking into effect that status change.
 //
 // Returns:
-//   - boolean - True: Sending thread is sending dummy messages.
-//  		   - False: Sending thread is paused/stopped and is not sending dummy messages.
+//   - boolean - Returns true if sending thread is sending dummy messages.
+//  	         Returns false if sending thread is paused/stopped and is
+// 	             not sending dummy messages.
 func (m *Manager) GetStatus() bool {
 	switch atomic.LoadUint32(&m.status) {
 	case running:
diff --git a/dummy/manager_test.go b/dummy/manager_test.go
index 7d1b490812b883142060211b9342de8929317257..5ce9cdaee7792078681a22255e53a8039677f041 100644
--- a/dummy/manager_test.go
+++ b/dummy/manager_test.go
@@ -45,7 +45,7 @@ func Test_newManager(t *testing.T) {
 // Tests that Manager.StartDummyTraffic sends dummy messages and that it stops
 // when the stoppable is closed.
 func TestManager_StartDummyTraffic(t *testing.T) {
-	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, false, t)
+	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, t)
 
 	err := m.SetStatus(true)
 	if err != nil {
@@ -104,7 +104,7 @@ func TestManager_StartDummyTraffic(t *testing.T) {
 // can be called multiple times with the same status without it affecting
 // anything. Also tests that the thread quits even when paused.
 func TestManager_SetStatus(t *testing.T) {
-	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, false, t)
+	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, t)
 
 	err := m.SetStatus(false)
 	if err != nil {
@@ -213,7 +213,7 @@ func TestManager_SetStatus(t *testing.T) {
 // Error path: tests that Manager.SetStatus returns an error if the status
 // cannot be set.
 func TestManager_SetStatus_ChannelError(t *testing.T) {
-	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, false, t)
+	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, t)
 
 	// Send the max number of status changes on the channel
 	for i := 0; i < statusChanLen; i++ {
@@ -236,7 +236,7 @@ func TestManager_SetStatus_ChannelError(t *testing.T) {
 // Tests that Manager.GetStatus gets the correct status before the send thread
 // starts, while sending, while paused, and after it is stopped.
 func TestManager_GetStatus(t *testing.T) {
-	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, false, t)
+	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, t)
 
 	err := m.SetStatus(false)
 	if err != nil {
diff --git a/dummy/mockCmix_test.go b/dummy/mockCmix_test.go
index bcee48e70c04c878a6283f154a0d07f6808147dc..f8211be97a777d23f59458416075154dd055e067 100644
--- a/dummy/mockCmix_test.go
+++ b/dummy/mockCmix_test.go
@@ -25,21 +25,23 @@ import (
 
 // mockCmix is a testing structure that adheres to cmix.Client.
 type mockCmix struct {
-	messages map[id.ID][]byte
+	messages map[id.ID]format.Message
 	sync.RWMutex
+	payloadSize int
 }
 
-func newMockCmix() cmix.Client {
+func newMockCmix(payloadSize int) cmix.Client {
 
 	return &mockCmix{
-		messages: make(map[id.ID][]byte),
+		messages:    make(map[id.ID]format.Message),
+		payloadSize: payloadSize,
 	}
 }
 
 func (m *mockCmix) Send(recipient *id.ID, fingerprint format.Fingerprint, service message.Service, payload, mac []byte, cmixParams cmix.CMIXParams) (id.Round, ephemeral.Id, error) {
 	m.Lock()
 	defer m.Unlock()
-	m.messages[*recipient] = fingerprint.Bytes()
+	m.messages[*recipient] = generateMessage(m.payloadSize, fingerprint, service, payload, mac)
 
 	return 0, ephemeral.Id{}, nil
 }
@@ -50,7 +52,7 @@ func (m *mockCmix) GetMsgListLen() int {
 	return len(m.messages)
 }
 
-func (m *mockCmix) GetMsgList() map[id.ID][]byte {
+func (m *mockCmix) GetMsgList() map[id.ID]format.Message {
 	m.RLock()
 	defer m.RUnlock()
 	return m.messages
diff --git a/dummy/random.go b/dummy/random.go
index 8c8a87a6cc0328f136f2444125cde62c92972a0b..a70eb72af368dbf19727a27f439eee2ff68f7a64 100644
--- a/dummy/random.go
+++ b/dummy/random.go
@@ -10,42 +10,78 @@ package dummy
 import (
 	"encoding/binary"
 	"github.com/pkg/errors"
+	"gitlab.com/elixxir/client/cmix/message"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/crypto/csprng"
+	"gitlab.com/xx_network/primitives/id"
 	"time"
 ) // Error messages.
 
+// Error constants for Manager.newRandomCmixMessage and it's helper functions..
 const (
 	payloadSizeRngErr = "failed to generate random payload size: %+v"
+	payloadRngErr     = "failed to generate random payload: %+v"
+	fingerprintRngErr = "failed to generate random fingerprint: %+v"
+	macRngErr         = "failed to generate random MAC: %+v"
+	recipientRngErr   = "failed to generate random recipient: %+v"
 )
 
-// intRng returns, as an int, a non-negative, non-zero random number in [1, n)
-// from the csprng.Source.
-func intRng(n int, rng csprng.Source) (int, error) {
-	v, err := csprng.Generate(8, rng)
+// newRandomCmixMessage returns random format.Message data.
+//
+// Returns in order a:
+//  - Recipient (id.ID)
+//  - Message fingerprint (format.Fingerprint)
+//  - Message service (message.Service)
+//  - Payload ([]byte)
+//  - MAC ([]byte)
+//  - Error if there was an issue randomly generating any of the above data.
+//    The error will specify which of the above failed to be randomly generated.
+func (m *Manager) newRandomCmixMessage(rng csprng.Source) (
+	recipient *id.ID, fingerprint format.Fingerprint,
+	service message.Service,
+	payload, mac []byte, err error) {
+
+	// Generate random recipient
+	recipient, err = id.NewRandomID(rng, id.User)
 	if err != nil {
-		return 0, err
+		return nil, format.Fingerprint{}, message.Service{}, nil, nil,
+			errors.Errorf(recipientRngErr, err)
 	}
 
-	return int(binary.LittleEndian.Uint64(v)%uint64(n-1)) + 1, nil
-}
+	// todo: use error constants above?
+	// Generate random message payload
+	payloadSize := m.store.GetCmixGroup().GetP().ByteLen()
+	payload, err = newRandomPayload(payloadSize, rng)
+	if err != nil {
+		return nil, format.Fingerprint{}, message.Service{}, nil, nil,
+			errors.Errorf(payloadRngErr, err)
+	}
 
-// durationRng returns a duration that is the base duration plus or minus a
-// random duration of max randomRange.
-func durationRng(base, randomRange time.Duration, rng csprng.Source) (
-	time.Duration, error) {
-	delta, err := intRng(int(2*randomRange), rng)
+	// Generate random fingerprint
+	fingerprint, err = newRandomFingerprint(rng)
 	if err != nil {
-		return 0, err
+		return nil, format.Fingerprint{}, message.Service{}, nil, nil,
+			errors.Errorf(fingerprintRngErr, err)
 	}
 
-	return base + randomRange - time.Duration(delta), nil
+	// Generate random MAC
+	mac, err = newRandomMAC(rng)
+	if err != nil {
+		return nil, format.Fingerprint{}, message.Service{}, nil, nil,
+			errors.Errorf(macRngErr, err)
+	}
+
+	// Generate random service
+	service = message.GetRandomService(rng)
+
+	return
 }
 
-// newRandomPayload generates a random payload of a random length.
+// newRandomPayload generates a random payload of a random length
+// within the maxPayloadSize.
 func newRandomPayload(maxPayloadSize int, rng csprng.Source) ([]byte, error) {
 	// Generate random payload size
-	randomPayloadSize, err := intRng(maxPayloadSize, rng)
+	randomPayloadSize, err := randomInt(maxPayloadSize, rng)
 	if err != nil {
 		return nil, errors.Errorf(payloadSizeRngErr, err)
 	}
@@ -86,3 +122,36 @@ func newRandomMAC(rng csprng.Source) ([]byte, error) {
 
 	return mac, nil
 }
+
+//////////////////////////////////////////////////////////////////////////////////
+// Random Duration functions
+//////////////////////////////////////////////////////////////////////////////////
+
+// randomDuration returns a duration that is the base duration plus or minus a
+// random duration of max randomRange.
+func randomDuration(base, randomRange time.Duration, rng csprng.Source) (
+	time.Duration, error) {
+
+	// Generate a random duration
+	delta, err := randomInt(int(2*randomRange), rng)
+	if err != nil {
+		return 0, err
+	}
+
+	return base + randomRange - time.Duration(delta), nil
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// Miscellaneous
+//////////////////////////////////////////////////////////////////////////////////
+
+// randomInt returns, as an int, a non-negative, non-zero random number in [1, n)
+// from the csprng.Source.
+func randomInt(n int, rng csprng.Source) (int, error) {
+	v, err := csprng.Generate(8, rng)
+	if err != nil {
+		return 0, err
+	}
+
+	return int(binary.LittleEndian.Uint64(v)%uint64(n-1)) + 1, nil
+}
diff --git a/dummy/random_test.go b/dummy/random_test.go
index 661986a0416993e211209d009a023c451dd3ff60..3303425c884da1febf5ddecc9b3850b8221e1e33 100644
--- a/dummy/random_test.go
+++ b/dummy/random_test.go
@@ -13,7 +13,7 @@ import (
 	"time"
 )
 
-// Consistency test: tests that intRng returns the expected int when using a
+// Consistency test: tests that randomInt returns the expected int when using a
 // PRNG and that the result is not larger than the max.
 func Test_intRng_Consistency(t *testing.T) {
 	expectedInts := []int{15, 1, 35, 13, 42, 52, 57, 3, 48}
@@ -22,9 +22,9 @@ func Test_intRng_Consistency(t *testing.T) {
 	max := 64
 
 	for i, expected := range expectedInts {
-		v, err := intRng(max, prng)
+		v, err := randomInt(max, prng)
 		if err != nil {
-			t.Errorf("intRng returned an error (%d): %+v", i, err)
+			t.Errorf("randomInt returned an error (%d): %+v", i, err)
 		}
 
 		if v != expected {
@@ -40,7 +40,7 @@ func Test_intRng_Consistency(t *testing.T) {
 	}
 }
 
-// Consistency test: tests that durationRng returns the expected int when using
+// Consistency test: tests that randomDuration returns the expected int when using
 // a PRNG and that the result is within the allowed range.
 func Test_durationRng_Consistency(t *testing.T) {
 	expectedDurations := []time.Duration{
@@ -52,9 +52,9 @@ func Test_durationRng_Consistency(t *testing.T) {
 	base, randomRange := time.Minute, 15*time.Second
 
 	for i, expected := range expectedDurations {
-		v, err := durationRng(base, randomRange, prng)
+		v, err := randomDuration(base, randomRange, prng)
 		if err != nil {
-			t.Errorf("durationRng returned an error (%d): %+v", i, err)
+			t.Errorf("randomDuration returned an error (%d): %+v", i, err)
 		}
 
 		if v != expected {
diff --git a/dummy/send.go b/dummy/send.go
index ffb6fed4247c16675e36e242b63fdfac355d527b..8dc698bc1b51a1bfde473b664d94bb25fca1f5d0 100644
--- a/dummy/send.go
+++ b/dummy/send.go
@@ -8,27 +8,20 @@
 package dummy
 
 import (
-	"gitlab.com/elixxir/client/cmix/message"
+	"gitlab.com/elixxir/client/cmix"
+	"gitlab.com/xx_network/crypto/csprng"
 	"sync"
 	"sync/atomic"
 	"time"
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/cmix"
 	"gitlab.com/elixxir/client/stoppable"
-	"gitlab.com/elixxir/primitives/format"
-	"gitlab.com/xx_network/crypto/csprng"
-	"gitlab.com/xx_network/primitives/id"
 )
 
-// Error messages.
+// Error messages for the Manager.sendThread and its helper functions.
 const (
-	numMsgsRngErr     = "failed to generate random number of messages to send: %+v"
-	payloadRngErr     = "failed to generate random payload: %+v"
-	recipientRngErr   = "failed to generate random recipient: %+v"
-	fingerprintRngErr = "failed to generate random fingerprint: %+v"
-	macRngErr         = "failed to generate random MAC: %+v"
+	numMsgsRngErr = "failed to generate random number of messages to send: %+v"
 )
 
 // sendThread is a thread that sends the dummy messages at random intervals.
@@ -40,152 +33,113 @@ func (m *Manager) sendThread(stop *stoppable.Single) {
 
 	for {
 		select {
-		case <-stop.Quit():
-			m.stopSendThread(stop)
-			return
 		case status := <-m.statusChan:
 			if status {
 				atomic.StoreUint32(&m.status, running)
-				nextSendChanPtr = &(m.randomTimer().C)
+				// Generate random duration
+				rng := m.rng.GetStream()
+				duration, err := randomDuration(m.avgSendDelta, m.randomRange, rng)
+				if err != nil {
+					rng.Close()
+					jww.FATAL.Panicf("Failed to generate random sending interval: %+v", err)
+				}
+				rng.Close()
+
+				// Create timer
+				nextSendChanPtr = &(time.NewTimer(duration).C)
+
 			} else {
 				atomic.StoreUint32(&m.status, paused)
 				nextSendChan = make(<-chan time.Time)
 				nextSendChanPtr = &nextSendChan
 			}
 		case <-*nextSendChanPtr:
-			nextSendChanPtr = &(m.randomTimer().C)
+			// Generate random duration
+			rng := m.rng.GetStream()
+			duration, err := randomDuration(m.avgSendDelta, m.randomRange, rng)
+			if err != nil {
+				rng.Close()
+				jww.FATAL.Panicf("Failed to generate random sending interval: %+v", err)
+			}
+			rng.Close()
 
-			go func() {
-				// get list of random messages and recipients
-				rng := m.rng.GetStream()
-				defer rng.Close()
-				msgs, err := m.newRandomMessages(rng)
-				if err != nil {
-					jww.ERROR.Printf("Failed to generate dummy messages: %+v", err)
-					return
-				}
+			// Create timer
+			nextSendChanPtr = &(time.NewTimer(duration).C)
 
-				err = m.sendMessages(msgs, rng)
+			// Send messages
+			go func() {
+				err := m.sendMessages()
 				if err != nil {
 					jww.ERROR.Printf("Failed to send dummy messages: %+v", err)
 				}
 			}()
+		case <-stop.Quit():
+			m.stopSendThread(stop)
+			return
 
 		}
 	}
 }
 
-// stopSendThread is triggered when the stoppable is triggered. It prints a
-// debug message, sets the thread status to stopped, and sets the status of the
-// stoppable to stopped.
-func (m *Manager) stopSendThread(stop *stoppable.Single) {
-	jww.DEBUG.Print(
-		"Stopping dummy traffic sending thread: stoppable triggered")
-	atomic.StoreUint32(&m.status, stopped)
-	stop.ToStopped()
-}
-
 // sendMessages generates and sends random messages.
-func (m *Manager) sendMessages(msgs map[id.ID]format.Message, rng csprng.Source) error {
-	var sent, i int64
+func (m *Manager) sendMessages() error {
+	var sent int64
 	var wg sync.WaitGroup
 
-	for recipient, msg := range msgs {
-		wg.Add(1)
+	// Randomly generate amount of messages to send
+	rng := m.rng.GetStream()
+	defer rng.Close()
+	numMessages, err := randomInt(m.maxNumMessages+1, rng)
+	if err != nil {
+		return errors.Errorf(numMsgsRngErr, err)
+	}
 
-		go func(i int64, recipient id.ID, msg format.Message) {
+	for i := 0; i < numMessages; i++ {
+		wg.Add(1)
+		go func(localIndex, totalMessages int) {
 			defer wg.Done()
 
-			// Fill the preimage with random data to ensure it is not repeatable
-			p := cmix.GetDefaultCMIXParams()
-			_, _, err := m.net.Send(&recipient, msg.GetKeyFP(),
-				message.GetRandomService(rng), msg.GetContents(), msg.GetMac(), p)
+			err = m.sendMessage(localIndex, totalMessages, rng)
 			if err != nil {
-				jww.WARN.Printf("Failed to send dummy message %d/%d via "+
-					"Send: %+v", i, len(msgs), err)
-			} else {
-				atomic.AddInt64(&sent, 1)
+				jww.ERROR.Printf(err.Error())
 			}
-		}(i, recipient, msg)
-
-		i++
+			// Add to counter of successful sends
+			atomic.AddInt64(&sent, 1)
+		}(i, numMessages)
 	}
 
 	wg.Wait()
-
-	jww.INFO.Printf("Sent %d/%d dummy messages.", sent, len(msgs))
-
+	jww.INFO.Printf("Sent %d/%d dummy messages.", sent, numMessages)
 	return nil
 }
 
-// newRandomMessages returns a map of a random recipients and random messages of
-// a randomly generated length in [1, Manager.maxNumMessages].
-func (m *Manager) newRandomMessages(rng csprng.Source) (
-	map[id.ID]format.Message, error) {
-	numMessages, err := intRng(m.maxNumMessages+1, rng)
-	if err != nil {
-		return nil, errors.Errorf(numMsgsRngErr, err)
-	}
-
-	msgs := make(map[id.ID]format.Message, numMessages)
-
-	for i := 0; i < numMessages; i++ {
-		// Generate random recipient
-		recipient, err := id.NewRandomID(rng, id.User)
-		if err != nil {
-			return nil, errors.Errorf(recipientRngErr, err)
-		}
-
-		msgs[*recipient], err = m.newRandomCmixMessage(rng)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	return msgs, nil
-}
-
-// newRandomCmixMessage returns a new cMix message filled with a randomly
-// generated payload, fingerprint, and MAC.
-func (m *Manager) newRandomCmixMessage(rng csprng.Source) (format.Message, error) {
-	// Create new empty cMix message
-	cMixMsg := format.NewMessage(m.store.GetCmixGroup().GetP().ByteLen())
-
-	// Generate random message
-	randomMsg, err := newRandomPayload(cMixMsg.ContentsSize(), rng)
+// sendMessage is a helper function which generates a sends a single random format.Message
+// to a random recipient.
+func (m *Manager) sendMessage(index, totalMessages int, rng csprng.Source) error {
+	// Generate message data
+	recipient, fp, service, payload, mac, err := m.newRandomCmixMessage(rng)
 	if err != nil {
-		return format.Message{}, errors.Errorf(payloadRngErr, err)
+		return errors.Errorf("Failed to create dummy message %d/%d: %+v",
+			index, totalMessages, err)
 	}
 
-	// Generate random fingerprint
-	fingerprint, err := newRandomFingerprint(rng)
+	// Send message
+	p := cmix.GetDefaultCMIXParams()
+	_, _, err = m.net.Send(recipient, fp, service, payload, mac, p)
 	if err != nil {
-		return format.Message{}, errors.Errorf(fingerprintRngErr, err)
+		return errors.Errorf("Failed to send dummy message %d/%d: %+v",
+			index, totalMessages, err)
 	}
 
-	// Generate random MAC
-	mac, err := newRandomMAC(rng)
-	if err != nil {
-		return format.Message{}, errors.Errorf(macRngErr, err)
-	}
-
-	// Set contents, fingerprint, and MAC, of the cMix message
-	cMixMsg.SetContents(randomMsg)
-	cMixMsg.SetKeyFP(fingerprint)
-	cMixMsg.SetMac(mac)
-
-	return cMixMsg, nil
+	return nil
 }
 
-// randomTimer generates a timer that will trigger after a random duration.
-func (m *Manager) randomTimer() *time.Timer {
-	rng := m.rng.GetStream()
-
-	duration, err := durationRng(m.avgSendDelta, m.randomRange, rng)
-	if err != nil {
-		jww.FATAL.Panicf("Failed to generate random duration to wait to send "+
-			"dummy messages: %+v", err)
-	}
-
-	return time.NewTimer(duration)
+// stopSendThread is triggered when the stoppable is triggered. It prints a
+// debug message, sets the thread status to stopped, and sets the status of the
+// stoppable to stopped.
+func (m *Manager) stopSendThread(stop *stoppable.Single) {
+	jww.DEBUG.Print(
+		"Stopping dummy traffic sending thread: stoppable triggered")
+	atomic.StoreUint32(&m.status, stopped)
+	stop.ToStopped()
 }
diff --git a/dummy/send_test.go b/dummy/send_test.go
index 625a203ae5b2d6beb9a8287d1f7adcfe412deebf..ef776b17ba9084fe07d34ab453ed890ab9b9f0f4 100644
--- a/dummy/send_test.go
+++ b/dummy/send_test.go
@@ -9,7 +9,6 @@ package dummy
 
 import (
 	"bytes"
-	"encoding/base64"
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
@@ -21,7 +20,7 @@ import (
 
 // Tests that Manager.sendThread sends multiple sets of messages.
 func TestManager_sendThread(t *testing.T) {
-	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, false, t)
+	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, t)
 
 	stop := stoppable.NewSingle("sendThreadTest")
 	go m.sendThread(stop)
@@ -86,32 +85,33 @@ func TestManager_sendThread(t *testing.T) {
 
 }
 
-// Tests that Manager.sendMessages sends all the messages with the correct
-// recipient.
-func TestManager_sendMessages(t *testing.T) {
-	m := newTestManager(100, 0, 0, false, t)
-	prng := NewPrng(42)
+// Tests that sendMessage generates random message data using pseudo-RNGs.
+func TestManager_sendMessage(t *testing.T) {
+	m := newTestManager(100, 0, 0, t)
+
+	// Generate two identical RNGs, one for generating expected data (newRandomCmixMessage)
+	// and one for received data (sendMessage)
+	prngOne := NewPrng(42)
+	prngTwo := NewPrng(42)
 
 	// Generate map of recipients and messages
 	msgs := make(map[id.ID]format.Message, m.maxNumMessages)
 	for i := 0; i < m.maxNumMessages; i++ {
-		recipient, err := id.NewRandomID(prng, id.User)
+		// Generate random data
+		recipient, fp, service, payload, mac, err := m.newRandomCmixMessage(prngOne)
 		if err != nil {
-			t.Errorf("Failed to generate random recipient ID (%d): %+v", i, err)
+			t.Fatalf("Failed to generate random cMix message (%d): %+v", i, err)
 		}
 
-		msg, err := m.newRandomCmixMessage(prng)
+		payloadSize := m.store.GetCmixGroup().GetP().ByteLen()
+		msgs[*recipient] = generateMessage(payloadSize, fp, service, payload, mac)
+
+		// Send the messages
+		err = m.sendMessage(i, m.maxNumMessages, prngTwo)
 		if err != nil {
-			t.Errorf("Failed to generate random cMix message (%d): %+v", i, err)
+			t.Errorf("sendMessages returned an error: %+v", err)
 		}
 
-		msgs[*recipient] = msg
-	}
-
-	// Send the messages
-	err := m.sendMessages(msgs, prng)
-	if err != nil {
-		t.Errorf("sendMessages returned an error: %+v", err)
 	}
 
 	// get sent messages
@@ -127,61 +127,46 @@ func TestManager_sendMessages(t *testing.T) {
 	for recipient, msg := range msgs {
 		receivedMsg, exists := receivedMsgs[recipient]
 		if !exists {
-			t.Errorf("Failed to receive message from %s: %+v", &recipient, msg)
-		} else if !reflect.DeepEqual(msg.GetKeyFP().Bytes(), receivedMsg) {
+			t.Errorf("Failed to receive message from %s: %+v", &recipient, msg.Marshal())
+		} else if !reflect.DeepEqual(msg.Marshal(), receivedMsg.Marshal()) {
 			// In mockCmix.Send, we map recipientId to the passed fingerprint.
 			t.Errorf("Received unexpected message for recipient %s."+
-				"\nexpected: %+v\nreceived: %+v", &recipient, msg.GetKeyFP(), receivedMsg)
+				"\nexpected: %+v\nreceived: %+v", &recipient, msg, receivedMsg)
 		}
 	}
 }
 
-// Tests that Manager.newRandomMessages creates a non-empty map of messages and
-// that each message is unique.
-func TestManager_newRandomMessages(t *testing.T) {
-	m := newTestManager(10, 0, 0, false, t)
+// Tests that newRandomCmixMessage generates cMix message data with
+// populated recipient, payload, fingerprint, and MAC.
+func TestManager_newRandomCmixMessage(t *testing.T) {
+	m := newTestManager(0, 0, 0, t)
 	prng := NewPrng(42)
 
-	msgMap, err := m.newRandomMessages(prng)
+	// Generate data
+	recipient, fp, _, payload, mac, err := m.newRandomCmixMessage(prng)
 	if err != nil {
-		t.Errorf("newRandomMessages returned an error: %+v", err)
-	}
-
-	if len(msgMap) == 0 {
-		t.Error("Message map is empty.")
+		t.Fatalf("newRandomCmixMessage returned an error: %+v", err)
 	}
 
-	marshalledMsgs := make(map[string]format.Message, len(msgMap))
-	for _, msg := range msgMap {
-		msgString := base64.StdEncoding.EncodeToString(msg.Marshal())
-		if _, exists := marshalledMsgs[msgString]; exists {
-			t.Errorf("Message not unique.")
-		} else {
-			marshalledMsgs[msgString] = msg
-		}
+	// Check that recipient is not empty data
+	if bytes.Equal(recipient.Bytes(), make([]byte, id.ArrIDLen)) {
+		t.Errorf("Recipient ID not set")
 	}
-}
-
-// Tests that Manager.newRandomCmixMessage generates a cMix message with
-// populated contents, fingerprint, and MAC.
-func TestManager_newRandomCmixMessage(t *testing.T) {
-	m := newTestManager(0, 0, 0, false, t)
-	prng := NewPrng(42)
 
-	cMixMsg, err := m.newRandomCmixMessage(prng)
-	if err != nil {
-		t.Errorf("newRandomCmixMessage returned an error: %+v", err)
-	}
-
-	if bytes.Equal(cMixMsg.GetContents(), make([]byte, len(cMixMsg.GetContents()))) {
+	// Check that payload is not empty data
+	payloadSize := m.store.GetCmixGroup().GetP().ByteLen()
+	if bytes.Equal(payload, make([]byte, payloadSize)) {
 		t.Error("cMix message contents not set.")
 	}
 
-	if cMixMsg.GetKeyFP() == (format.Fingerprint{}) {
+	// Check that fingerprint is not empty data
+	if fp == (format.Fingerprint{}) {
 		t.Error("cMix message fingerprint not set.")
 	}
 
-	if bytes.Equal(cMixMsg.GetMac(), make([]byte, format.MacLen)) {
+	// Check that mac is not empty data
+	if bytes.Equal(mac, make([]byte, format.MacLen)) {
 		t.Error("cMix message MAC not set.")
 	}
+
 }
diff --git a/dummy/utils_test.go b/dummy/utils_test.go
index bef9291f030af9f5d67119e65d5d5ec25640c0bf..a3780867a513a6c497157bd17ccfceef89f2a5ec 100644
--- a/dummy/utils_test.go
+++ b/dummy/utils_test.go
@@ -8,10 +8,11 @@
 package dummy
 
 import (
+	"gitlab.com/elixxir/client/cmix/message"
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/crypto/csprng"
-	"gitlab.com/xx_network/primitives/ndf"
 	"io"
 	"math/rand"
 	"testing"
@@ -36,59 +37,35 @@ func (s *Prng) SetSeed([]byte) error       { return nil }
 // newTestManager creates a new Manager that has groups stored for testing. One
 // of the groups in the list is also returned.
 func newTestManager(maxNumMessages int, avgSendDelta, randomRange time.Duration,
-	sendErr bool, t *testing.T) *Manager {
+	t *testing.T) *Manager {
 	store := storage.InitTestingSession(t)
+	payloadSize := store.GetCmixGroup().GetP().ByteLen()
 	m := &Manager{
 		maxNumMessages: maxNumMessages,
 		avgSendDelta:   avgSendDelta,
 		randomRange:    randomRange,
 		statusChan:     make(chan bool, statusChanLen),
 		store:          store,
-		net:            newMockCmix(),
+		net:            newMockCmix(payloadSize),
 		rng:            fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG),
 	}
 
 	return m
 }
 
-func getNDF() *ndf.NetworkDefinition {
-	return &ndf.NetworkDefinition{
-		E2E: ndf.Group{
-			Prime: "E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D49413394C049B7A" +
-				"8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688B55B3D" +
-				"D2AEDF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E78615" +
-				"75E745D31F8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC" +
-				"6ADC718DD2A3E041023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C" +
-				"4A530E8FFB1BC51DADDF453B0B2717C2BC6669ED76B4BDD5C9FF558E88F2" +
-				"6E5785302BEDBCA23EAC5ACE92096EE8A60642FB61E8F3D24990B8CB12EE" +
-				"448EEF78E184C7242DD161C7738F32BF29A841698978825B4111B4BC3E1E" +
-				"198455095958333D776D8B2BEEED3A1A1A221A6E37E664A64B83981C46FF" +
-				"DDC1A45E3D5211AAF8BFBC072768C4F50D7D7803D2D4F278DE8014A47323" +
-				"631D7E064DE81C0C6BFA43EF0E6998860F1390B5D3FEACAF1696015CB79C" +
-				"3F9C2D93D961120CD0E5F12CBB687EAB045241F96789C38E89D796138E63" +
-				"19BE62E35D87B1048CA28BE389B575E994DCA755471584A09EC723742DC3" +
-				"5873847AEF49F66E43873",
-			Generator: "2",
-		},
-		CMIX: ndf.Group{
-			Prime: "9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642" +
-				"F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757" +
-				"264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F" +
-				"9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091E" +
-				"B51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D" +
-				"0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D3" +
-				"92145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A" +
-				"2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7" +
-				"995FAD5AABBCFBE3EDA2741E375404AE25B",
-			Generator: "5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E2480" +
-				"9670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D" +
-				"1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A33" +
-				"8661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361" +
-				"C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B28" +
-				"5DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD929" +
-				"59859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D83" +
-				"2186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8" +
-				"B6F116F7AD9CF505DF0F998E34AB27514B0FFE7",
-		},
-	}
+// generateMessage is a utility function which generates a format.Message
+// given message data.
+func generateMessage(payloadSize int,
+	fingerprint format.Fingerprint,
+	service message.Service,
+	payload, mac []byte) format.Message {
+
+	// Build message. Will panic if inputs are not correct.
+	msg := format.NewMessage(payloadSize)
+	msg.SetContents(payload)
+	msg.SetKeyFP(fingerprint)
+	msg.SetSIH(service.Hash(msg.GetContents()))
+	msg.SetMac(mac)
+
+	return msg
 }