diff --git a/dapps/faucet/dapp.go b/dapps/faucet/dapp.go
index 977c18282320c210a775323b453de02e6a343535..0fe4a8ac1107d37573e42cdebeb2c5a81ffbbffd 100644
--- a/dapps/faucet/dapp.go
+++ b/dapps/faucet/dapp.go
@@ -8,10 +8,9 @@ import (
 
 	faucet "github.com/iotaledger/goshimmer/dapps/faucet/packages"
 	faucetpayload "github.com/iotaledger/goshimmer/dapps/faucet/packages/payload"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
 	"github.com/iotaledger/goshimmer/packages/pow"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/config"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/hive.go/daemon"
@@ -100,7 +99,7 @@ func configure(*node.Plugin) {
 	Faucet()
 
 	fundingWorkerPool = workerpool.New(func(task workerpool.Task) {
-		msg := task.Param(0).(*message.Message)
+		msg := task.Param(0).(*tangle.Message)
 		addr := msg.Payload().(*faucetpayload.Payload).Address()
 		msg, txID, err := Faucet().SendFunds(msg)
 		if err != nil {
diff --git a/dapps/faucet/packages/faucet.go b/dapps/faucet/packages/faucet.go
index 2e4d57e448dd16f27abe05606f4a16b8a2f595ab..f56c288a976e762f81f80b94edc07258d21b2118 100644
--- a/dapps/faucet/packages/faucet.go
+++ b/dapps/faucet/packages/faucet.go
@@ -12,9 +12,9 @@ import (
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance"
-	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle"
+	valuetangle "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/issuer"
 	"github.com/iotaledger/hive.go/datastructure/orderedmap"
 )
@@ -73,7 +73,7 @@ func (f *Faucet) addAddressToBlacklist(addr address.Address) {
 }
 
 // SendFunds sends IOTA tokens to the address from faucet request.
-func (f *Faucet) SendFunds(msg *message.Message) (m *message.Message, txID string, err error) {
+func (f *Faucet) SendFunds(msg *tangle.Message) (m *tangle.Message, txID string, err error) {
 	// ensure that only one request is being processed any given time
 	f.Lock()
 	defer f.Unlock()
@@ -143,7 +143,7 @@ func (f *Faucet) collectUTXOsForFunding() (outputIds []transaction.OutputID, add
 	// get a list of address for inputs
 	for i = 0; total > 0; i++ {
 		addr := f.seed.Address(i).Address
-		valuetransfers.Tangle().OutputsOnAddress(addr).Consume(func(output *tangle.Output) {
+		valuetransfers.Tangle().OutputsOnAddress(addr).Consume(func(output *valuetangle.Output) {
 			if output.ConsumerCount() > 0 || total == 0 {
 				return
 			}
diff --git a/dapps/faucet/packages/faucet_test.go b/dapps/faucet/packages/faucet_test.go
index 2e5853b8c536808afd7559c607c9a8089d64610f..2dfda0bc95086f2f571b1e192bf117ed78b42857 100644
--- a/dapps/faucet/packages/faucet_test.go
+++ b/dapps/faucet/packages/faucet_test.go
@@ -12,8 +12,7 @@ import (
 
 	faucet "github.com/iotaledger/goshimmer/dapps/faucet/packages/payload"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	data "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 )
 
 func TestIsFaucetReq(t *testing.T) {
@@ -25,9 +24,9 @@ func TestIsFaucetReq(t *testing.T) {
 		require.NoError(t, err)
 		return
 	}
-	faucetMsg := message.New(
-		message.EmptyID,
-		message.EmptyID,
+	faucetMsg := tangle.NewMessage(
+		tangle.EmptyMessageID,
+		tangle.EmptyMessageID,
 		time.Now(),
 		local.PublicKey(),
 		0,
@@ -36,13 +35,13 @@ func TestIsFaucetReq(t *testing.T) {
 		ed25519.EmptySignature,
 	)
 
-	dataMsg := message.New(
-		message.EmptyID,
-		message.EmptyID,
+	dataMsg := tangle.NewMessage(
+		tangle.EmptyMessageID,
+		tangle.EmptyMessageID,
 		time.Now(),
 		local.PublicKey(),
 		0,
-		data.NewData([]byte("data")),
+		tangle.NewDataPayload([]byte("data")),
 		0,
 		ed25519.EmptySignature,
 	)
diff --git a/dapps/faucet/packages/payload/payload.go b/dapps/faucet/packages/payload/payload.go
index 3d2b39e8a5c3d285d1fd1231daa4b2d368e8fd4f..f9e73a977d61b26f327a53cbf67406b262902d44 100644
--- a/dapps/faucet/packages/payload/payload.go
+++ b/dapps/faucet/packages/payload/payload.go
@@ -8,13 +8,12 @@ import (
 	// Only want to use init
 	_ "golang.org/x/crypto/blake2b"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
 	"github.com/iotaledger/goshimmer/packages/pow"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/hive.go/marshalutil"
 	"github.com/iotaledger/hive.go/stringify"
 
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
 )
 
 const (
@@ -24,13 +23,13 @@ const (
 
 // Payload represents a request which contains an address for the faucet to send funds to.
 type Payload struct {
-	payloadType payload.Type
+	payloadType tangle.PayloadType
 	address     address.Address
 	nonce       uint64
 }
 
 // Type represents the identifier for the faucet Payload type.
-var Type = payload.Type(2)
+var Type = tangle.PayloadType(2)
 var powWorker = pow.New(crypto.BLAKE2b_512, 1)
 
 // New is the constructor of a Payload and creates a new Payload object from the given details.
@@ -52,7 +51,7 @@ func New(addr address.Address, powTarget int) (*Payload, error) {
 }
 
 func init() {
-	payload.RegisterType(Type, ObjectName, PayloadUnmarshaler)
+	tangle.RegisterPayloadType(Type, ObjectName, PayloadUnmarshaler)
 }
 
 // FromBytes parses the marshaled version of a Payload into an object.
@@ -96,39 +95,39 @@ func FromBytes(bytes []byte) (result *Payload, consumedBytes int, err error) {
 }
 
 // Type returns the type of the faucet Payload.
-func (faucetPayload *Payload) Type() payload.Type {
-	return faucetPayload.payloadType
+func (p *Payload) Type() tangle.PayloadType {
+	return p.payloadType
 }
 
 // Address returns the address of the faucet Payload.
-func (faucetPayload *Payload) Address() address.Address {
-	return faucetPayload.address
+func (p *Payload) Address() address.Address {
+	return p.address
 }
 
 // Bytes marshals the data payload into a sequence of bytes.
-func (faucetPayload *Payload) Bytes() []byte {
+func (p *Payload) Bytes() []byte {
 	// initialize helper
 	marshalUtil := marshalutil.New()
 
 	// marshal the payload specific information
 	marshalUtil.WriteUint32(uint32(address.Length + pow.NonceBytes))
-	marshalUtil.WriteUint32(faucetPayload.Type())
-	marshalUtil.WriteBytes(faucetPayload.address.Bytes())
-	marshalUtil.WriteUint64(faucetPayload.nonce)
+	marshalUtil.WriteUint32(p.Type())
+	marshalUtil.WriteBytes(p.address.Bytes())
+	marshalUtil.WriteUint64(p.nonce)
 
 	// return result
 	return marshalUtil.Bytes()
 }
 
 // String returns a human readable version of faucet payload (for debug purposes).
-func (faucetPayload *Payload) String() string {
+func (p *Payload) String() string {
 	return stringify.Struct("FaucetPayload",
-		stringify.StructField("address", faucetPayload.Address().String()),
+		stringify.StructField("address", p.Address().String()),
 	)
 }
 
 // PayloadUnmarshaler sets the generic unmarshaler.
-func PayloadUnmarshaler(data []byte) (payload payload.Payload, err error) {
+func PayloadUnmarshaler(data []byte) (payload tangle.Payload, err error) {
 	payload, _, err = FromBytes(data)
 	if err != nil {
 		err = fmt.Errorf("failed to unmarshal faucet payload from bytes: %w", err)
@@ -138,6 +137,6 @@ func PayloadUnmarshaler(data []byte) (payload payload.Payload, err error) {
 }
 
 // IsFaucetReq checks if the message is faucet payload.
-func IsFaucetReq(msg *message.Message) bool {
+func IsFaucetReq(msg *tangle.Message) bool {
 	return msg.Payload().Type() == Type
 }
diff --git a/dapps/faucet/packages/payload/payload_test.go b/dapps/faucet/packages/payload/payload_test.go
index 7bf0a0b6891ef1efd7cc1ece384bf0af0f334b99..5635d765fee37f7b2623afa53c0cb9e48b54eff6 100644
--- a/dapps/faucet/packages/payload/payload_test.go
+++ b/dapps/faucet/packages/payload/payload_test.go
@@ -10,7 +10,7 @@ import (
 	"github.com/stretchr/testify/assert"
 
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 )
 
 func ExamplePayload() {
@@ -24,9 +24,9 @@ func ExamplePayload() {
 	}
 
 	// 2. build actual message
-	tx := message.New(
-		message.EmptyID,
-		message.EmptyID,
+	tx := tangle.NewMessage(
+		tangle.EmptyMessageID,
+		tangle.EmptyMessageID,
 		time.Now(),
 		local.PublicKey(),
 		0,
diff --git a/dapps/networkdelay/dapp.go b/dapps/networkdelay/dapp.go
index 65098f91a0dbe33fb3a5a0c7f066d62376315976..b72c09f7fc634740e92e62c6251378882ef721cb 100644
--- a/dapps/networkdelay/dapp.go
+++ b/dapps/networkdelay/dapp.go
@@ -4,7 +4,7 @@ import (
 	"sync"
 	"time"
 
-	messageTangle "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/local"
 	"github.com/iotaledger/goshimmer/plugins/config"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
@@ -76,7 +76,7 @@ func configure(_ *node.Plugin) {
 	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(onReceiveMessageFromMessageLayer))
 }
 
-func onReceiveMessageFromMessageLayer(cachedMessageEvent *messageTangle.CachedMessageEvent) {
+func onReceiveMessageFromMessageLayer(cachedMessageEvent *tangle.CachedMessageEvent) {
 	defer cachedMessageEvent.Message.Release()
 	defer cachedMessageEvent.MessageMetadata.Release()
 
diff --git a/dapps/networkdelay/object.go b/dapps/networkdelay/object.go
index 3b5c2980436555da77b02f96a7b5857a44f55e6f..a331e4b12cfe62122bc82e65501755f860058898 100644
--- a/dapps/networkdelay/object.go
+++ b/dapps/networkdelay/object.go
@@ -4,7 +4,7 @@ import (
 	"fmt"
 	"sync"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/hive.go/marshalutil"
 	"github.com/iotaledger/hive.go/stringify"
 	"github.com/mr-tron/base58"
@@ -131,15 +131,15 @@ func (o *Object) String() string {
 // region Payload implementation ///////////////////////////////////////////////////////////////////////////////////////
 
 // Type represents the identifier which addresses the network delay Object type.
-const Type = payload.Type(189)
+const Type = tangle.PayloadType(189)
 
 // Type returns the type of the Object.
-func (o *Object) Type() payload.Type {
+func (o *Object) Type() tangle.PayloadType {
 	return Type
 }
 
 func init() {
-	payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) {
+	tangle.RegisterPayloadType(Type, ObjectName, func(data []byte) (payload tangle.Payload, err error) {
 		payload, _, err = FromBytes(data)
 
 		return
diff --git a/dapps/valuetransfers/dapp.go b/dapps/valuetransfers/dapp.go
index 0b28fd31cd98943a949098fc553ec1c75e688d43..27ccee4fdd3d5039afcaab3738ba651efb98288b 100644
--- a/dapps/valuetransfers/dapp.go
+++ b/dapps/valuetransfers/dapp.go
@@ -8,11 +8,11 @@ import (
 
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/consensus"
 	valuepayload "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload"
-	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle"
+	valuetangle "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tipmanager"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
-	messageTangle "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/packages/vote"
 	"github.com/iotaledger/goshimmer/plugins/config"
 	"github.com/iotaledger/goshimmer/plugins/database"
@@ -53,14 +53,14 @@ var (
 	appOnce sync.Once
 
 	// _tangle represents the value tangle that is used to express votes on value transactions.
-	_tangle    *tangle.Tangle
+	_tangle    *valuetangle.Tangle
 	tangleOnce sync.Once
 
 	// fcob contains the fcob consensus logic.
 	fcob *consensus.FCOB
 
 	// ledgerState represents the ledger state, that keeps track of the liked branches and offers an API to access funds.
-	ledgerState *tangle.LedgerState
+	ledgerState *valuetangle.LedgerState
 
 	// log holds a reference to the logger used by this app.
 	log *logger.Logger
@@ -68,7 +68,7 @@ var (
 	tipManager     *tipmanager.TipManager
 	tipManagerOnce sync.Once
 
-	valueObjectFactory     *tangle.ValueObjectFactory
+	valueObjectFactory     *valuetangle.ValueObjectFactory
 	valueObjectFactoryOnce sync.Once
 )
 
@@ -82,9 +82,9 @@ func App() *node.Plugin {
 
 // Tangle gets the tangle instance.
 // tangle represents the value tangle that is used to express votes on value transactions.
-func Tangle() *tangle.Tangle {
+func Tangle() *valuetangle.Tangle {
 	tangleOnce.Do(func() {
-		_tangle = tangle.New(database.Store())
+		_tangle = valuetangle.New(database.Store())
 	})
 	return _tangle
 }
@@ -97,7 +97,7 @@ func FCOB() *consensus.FCOB {
 
 // LedgerState gets the ledgerState instance.
 // ledgerState represents the ledger state, that keeps track of the liked branches and offers an API to access funds.
-func LedgerState() *tangle.LedgerState {
+func LedgerState() *valuetangle.LedgerState {
 	return ledgerState
 }
 
@@ -109,12 +109,12 @@ func configure(_ *node.Plugin) {
 	_tangle = Tangle()
 
 	// configure LedgerState
-	ledgerState = tangle.NewLedgerState(Tangle())
+	ledgerState = valuetangle.NewLedgerState(Tangle())
 
 	// read snapshot file
 	snapshotFilePath := config.Node().GetString(CfgValueLayerSnapshotFile)
 	if len(snapshotFilePath) != 0 {
-		snapshot := tangle.Snapshot{}
+		snapshot := valuetangle.Snapshot{}
 		f, err := os.Open(snapshotFilePath)
 		if err != nil {
 			log.Panic("can not open snapshot file:", err)
@@ -134,11 +134,11 @@ func configure(_ *node.Plugin) {
 	tipManager = TipManager()
 	valueObjectFactory = ValueObjectFactory()
 
-	_tangle.Events.PayloadLiked.Attach(events.NewClosure(func(cachedPayloadEvent *tangle.CachedPayloadEvent) {
+	_tangle.Events.PayloadLiked.Attach(events.NewClosure(func(cachedPayloadEvent *valuetangle.CachedPayloadEvent) {
 		cachedPayloadEvent.PayloadMetadata.Release()
 		cachedPayloadEvent.Payload.Consume(tipManager.AddTip)
 	}))
-	_tangle.Events.PayloadDisliked.Attach(events.NewClosure(func(cachedPayloadEvent *tangle.CachedPayloadEvent) {
+	_tangle.Events.PayloadDisliked.Attach(events.NewClosure(func(cachedPayloadEvent *valuetangle.CachedPayloadEvent) {
 		cachedPayloadEvent.PayloadMetadata.Release()
 		cachedPayloadEvent.Payload.Consume(tipManager.RemoveTip)
 	}))
@@ -167,7 +167,7 @@ func configure(_ *node.Plugin) {
 	}))
 
 	// register SignatureFilter in Parser
-	messagelayer.MessageParser().AddMessageFilter(tangle.NewSignatureFilter())
+	messagelayer.MessageParser().AddMessageFilter(valuetangle.NewSignatureFilter())
 
 	// subscribe to message-layer
 	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(onReceiveMessageFromMessageLayer))
@@ -186,7 +186,7 @@ func run(*node.Plugin) {
 	runFPC()
 }
 
-func onReceiveMessageFromMessageLayer(cachedMessageEvent *messageTangle.CachedMessageEvent) {
+func onReceiveMessageFromMessageLayer(cachedMessageEvent *tangle.CachedMessageEvent) {
 	defer cachedMessageEvent.Message.Release()
 	defer cachedMessageEvent.MessageMetadata.Release()
 
@@ -221,9 +221,9 @@ func TipManager() *tipmanager.TipManager {
 }
 
 // ValueObjectFactory returns the ValueObjectFactory singleton.
-func ValueObjectFactory() *tangle.ValueObjectFactory {
+func ValueObjectFactory() *valuetangle.ValueObjectFactory {
 	valueObjectFactoryOnce.Do(func() {
-		valueObjectFactory = tangle.NewValueObjectFactory(Tangle(), TipManager())
+		valueObjectFactory = valuetangle.NewValueObjectFactory(Tangle(), TipManager())
 	})
 	return valueObjectFactory
 }
@@ -235,7 +235,7 @@ func AwaitTransactionToBeBooked(txID transaction.ID, maxAwait time.Duration) err
 	// reason the same transaction gets booked multiple times
 	exit := make(chan struct{})
 	defer close(exit)
-	closure := events.NewClosure(func(cachedTransactionBookEvent *tangle.CachedTransactionBookEvent) {
+	closure := events.NewClosure(func(cachedTransactionBookEvent *valuetangle.CachedTransactionBookEvent) {
 		defer cachedTransactionBookEvent.Transaction.Release()
 		defer cachedTransactionBookEvent.TransactionMetadata.Release()
 		if cachedTransactionBookEvent.Transaction.Unwrap().ID() != txID {
diff --git a/dapps/valuetransfers/packages/payload/payload.go b/dapps/valuetransfers/packages/payload/payload.go
index f191d2060ad7a51a769a376318c781c34b51915c..5db6de0388715fd27eaf456eb8ca9e99a52f29f0 100644
--- a/dapps/valuetransfers/packages/payload/payload.go
+++ b/dapps/valuetransfers/packages/payload/payload.go
@@ -10,7 +10,7 @@ import (
 	"golang.org/x/crypto/blake2b"
 
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 )
 
 const (
@@ -119,122 +119,122 @@ func Parse(marshalUtil *marshalutil.MarshalUtil) (result *Payload, err error) {
 }
 
 // ID returns the identifier if the Payload.
-func (payload *Payload) ID() ID {
+func (p *Payload) ID() ID {
 	// acquire lock for reading id
-	payload.idMutex.RLock()
+	p.idMutex.RLock()
 
 	// return if id has been calculated already
-	if payload.id != nil {
-		defer payload.idMutex.RUnlock()
+	if p.id != nil {
+		defer p.idMutex.RUnlock()
 
-		return *payload.id
+		return *p.id
 	}
 
 	// switch to write lock
-	payload.idMutex.RUnlock()
-	payload.idMutex.Lock()
-	defer payload.idMutex.Unlock()
+	p.idMutex.RUnlock()
+	p.idMutex.Lock()
+	defer p.idMutex.Unlock()
 
 	// return if id has been calculated in the mean time
-	if payload.id != nil {
-		return *payload.id
+	if p.id != nil {
+		return *p.id
 	}
 
 	// otherwise calculate the id
 	marshalUtil := marshalutil.New(IDLength + IDLength + transaction.IDLength)
-	marshalUtil.WriteBytes(payload.parent1PayloadID.Bytes())
-	marshalUtil.WriteBytes(payload.parent2PayloadID.Bytes())
-	marshalUtil.WriteBytes(payload.Transaction().ID().Bytes())
+	marshalUtil.WriteBytes(p.parent1PayloadID.Bytes())
+	marshalUtil.WriteBytes(p.parent2PayloadID.Bytes())
+	marshalUtil.WriteBytes(p.Transaction().ID().Bytes())
 
 	var id ID = blake2b.Sum256(marshalUtil.Bytes())
-	payload.id = &id
+	p.id = &id
 
 	return id
 }
 
 // Parent1ID returns the first Payload that is referenced by this Payload.
-func (payload *Payload) Parent1ID() ID {
-	return payload.parent1PayloadID
+func (p *Payload) Parent1ID() ID {
+	return p.parent1PayloadID
 }
 
 // Parent2ID returns the second Payload that is referenced by this Payload.
-func (payload *Payload) Parent2ID() ID {
-	return payload.parent2PayloadID
+func (p *Payload) Parent2ID() ID {
+	return p.parent2PayloadID
 }
 
 // Transaction returns the Transaction that is being attached in this Payload.
-func (payload *Payload) Transaction() *transaction.Transaction {
-	return payload.transaction
+func (p *Payload) Transaction() *transaction.Transaction {
+	return p.transaction
 }
 
 // Bytes returns a marshaled version of this Payload.
-func (payload *Payload) Bytes() []byte {
-	return payload.ObjectStorageValue()
+func (p *Payload) Bytes() []byte {
+	return p.ObjectStorageValue()
 }
 
-func (payload *Payload) String() string {
+func (p *Payload) String() string {
 	return stringify.Struct("Payload",
-		stringify.StructField("id", payload.ID()),
-		stringify.StructField("parent1", payload.Parent1ID()),
-		stringify.StructField("parent2", payload.Parent2ID()),
-		stringify.StructField("transfer", payload.Transaction()),
+		stringify.StructField("id", p.ID()),
+		stringify.StructField("parent1", p.Parent1ID()),
+		stringify.StructField("parent2", p.Parent2ID()),
+		stringify.StructField("transfer", p.Transaction()),
 	)
 }
 
 // region Payload implementation ///////////////////////////////////////////////////////////////////////////////////////
 
 // Type represents the identifier which addresses the value Payload type.
-const Type = payload.Type(1)
+const Type = tangle.PayloadType(1)
 
 // Type returns the type of the Payload.
-func (payload *Payload) Type() payload.Type {
+func (p *Payload) Type() tangle.PayloadType {
 	return Type
 }
 
 // ObjectStorageValue returns the bytes that represent all remaining information (not stored in the key) of a marshaled
 // Parent2.
-func (payload *Payload) ObjectStorageValue() (bytes []byte) {
+func (p *Payload) ObjectStorageValue() (bytes []byte) {
 	// acquire lock for reading bytes
-	payload.bytesMutex.RLock()
+	p.bytesMutex.RLock()
 
 	// return if bytes have been determined already
-	if bytes = payload.bytes; bytes != nil {
-		defer payload.bytesMutex.RUnlock()
+	if bytes = p.bytes; bytes != nil {
+		defer p.bytesMutex.RUnlock()
 
 		return
 	}
 
 	// switch to write lock
-	payload.bytesMutex.RUnlock()
-	payload.bytesMutex.Lock()
-	defer payload.bytesMutex.Unlock()
+	p.bytesMutex.RUnlock()
+	p.bytesMutex.Lock()
+	defer p.bytesMutex.Unlock()
 
 	// return if bytes have been determined in the mean time
-	if bytes = payload.bytes; bytes != nil {
+	if bytes = p.bytes; bytes != nil {
 		return
 	}
 
 	// retrieve bytes of transfer
-	transferBytes := payload.Transaction().ObjectStorageValue()
+	transferBytes := p.Transaction().ObjectStorageValue()
 
 	// marshal fields
 	payloadLength := IDLength + IDLength + len(transferBytes)
 	marshalUtil := marshalutil.New(marshalutil.UINT32_SIZE + marshalutil.UINT32_SIZE + payloadLength)
 	marshalUtil.WriteUint32(uint32(payloadLength))
 	marshalUtil.WriteUint32(Type)
-	marshalUtil.WriteBytes(payload.parent1PayloadID.Bytes())
-	marshalUtil.WriteBytes(payload.parent2PayloadID.Bytes())
+	marshalUtil.WriteBytes(p.parent1PayloadID.Bytes())
+	marshalUtil.WriteBytes(p.parent2PayloadID.Bytes())
 	marshalUtil.WriteBytes(transferBytes)
 	bytes = marshalUtil.Bytes()
 
 	// store result
-	payload.bytes = bytes
+	p.bytes = bytes
 
 	return
 }
 
 func init() {
-	payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) {
+	tangle.RegisterPayloadType(Type, ObjectName, func(data []byte) (payload tangle.Payload, err error) {
 		payload, _, err = FromBytes(data)
 
 		return
@@ -242,19 +242,19 @@ func init() {
 }
 
 // define contract (ensure that the struct fulfills the corresponding interface)
-var _ payload.Payload = &Payload{}
+var _ tangle.Payload = &Payload{}
 
 // endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 // region StorableObject implementation ////////////////////////////////////////////////////////////////////////////////
 
 // ObjectStorageKey returns the bytes that are used a key when storing the  Payload in an objectstorage.
-func (payload *Payload) ObjectStorageKey() []byte {
-	return payload.ID().Bytes()
+func (p *Payload) ObjectStorageKey() []byte {
+	return p.ID().Bytes()
 }
 
 // Update is disabled but needs to be implemented to be compatible with the objectstorage.
-func (payload *Payload) Update(other objectstorage.StorableObject) {
+func (p *Payload) Update(other objectstorage.StorableObject) {
 	panic("a Payload should never be updated")
 }
 
@@ -273,20 +273,20 @@ type CachedPayload struct {
 }
 
 // Retain wraps the underlying method to return a new "wrapped object".
-func (cachedPayload *CachedPayload) Retain() *CachedPayload {
-	return &CachedPayload{cachedPayload.CachedObject.Retain()}
+func (c *CachedPayload) Retain() *CachedPayload {
+	return &CachedPayload{c.CachedObject.Retain()}
 }
 
 // Consume wraps the underlying method to return the correctly typed objects in the callback.
-func (cachedPayload *CachedPayload) Consume(consumer func(payload *Payload)) bool {
-	return cachedPayload.CachedObject.Consume(func(object objectstorage.StorableObject) {
+func (c *CachedPayload) Consume(consumer func(payload *Payload)) bool {
+	return c.CachedObject.Consume(func(object objectstorage.StorableObject) {
 		consumer(object.(*Payload))
 	})
 }
 
 // Unwrap provides a way to "Get" a type casted version of the underlying object.
-func (cachedPayload *CachedPayload) Unwrap() *Payload {
-	untypedTransaction := cachedPayload.Get()
+func (c *CachedPayload) Unwrap() *Payload {
+	untypedTransaction := c.Get()
 	if untypedTransaction == nil {
 		return nil
 	}
diff --git a/dapps/valuetransfers/packages/payload/payload_test.go b/dapps/valuetransfers/packages/payload/payload_test.go
index 5dc5fb2783bb321fb3482b26bf4fae8f3cde45b6..3b0f87613b80ba71b7a75fedc3b1836fe50eb8be 100644
--- a/dapps/valuetransfers/packages/payload/payload_test.go
+++ b/dapps/valuetransfers/packages/payload/payload_test.go
@@ -12,7 +12,7 @@ import (
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 )
 
 func ExamplePayload() {
@@ -45,12 +45,12 @@ func ExamplePayload() {
 	)
 
 	// 3. build actual transaction (the base layer creates this and wraps the ontology provided payload)
-	tx := message.New(
+	tx := tangle.NewMessage(
 		// parent1 in "network tangle" ontology (filled by tipSelector)
-		message.EmptyID,
+		tangle.EmptyMessageID,
 
 		// parent2 in "network tangle" ontology (filled by tipSelector)
-		message.EmptyID,
+		tangle.EmptyMessageID,
 
 		// the time when the transaction was created
 		time.Now(),
diff --git a/dapps/valuetransfers/packages/tangle/payloadapprover.go b/dapps/valuetransfers/packages/tangle/payloadapprover.go
index b24c65400cd28f4b7cec6ad2c7cba51a7c10bf45..6489960e8f29ebf1e23ef29fc055b1941c555ddb 100644
--- a/dapps/valuetransfers/packages/tangle/payloadapprover.go
+++ b/dapps/valuetransfers/packages/tangle/payloadapprover.go
@@ -40,11 +40,11 @@ func PayloadApproverFromBytes(bytes []byte) (result *PayloadApprover, consumedBy
 func ParsePayloadApprover(marshalUtil *marshalutil.MarshalUtil) (result *PayloadApprover, err error) {
 	result = &PayloadApprover{}
 	if result.referencedPayloadID, err = payload.ParseID(marshalUtil); err != nil {
-		err = fmt.Errorf("failed to parse payload id of approver: %w", err)
+		err = fmt.Errorf("failed to parse referenced payload id of approver: %w", err)
 		return
 	}
 	if result.approvingPayloadID, err = payload.ParseID(marshalUtil); err != nil {
-		err = fmt.Errorf("failed to parse payload id of approver: %w", err)
+		err = fmt.Errorf("failed to parse approving payload id of approver: %w", err)
 		return
 	}
 
diff --git a/dapps/valuetransfers/packages/tangle/signature_filter.go b/dapps/valuetransfers/packages/tangle/signature_filter.go
index a7e7e2cc0c254f4248237d4d44a9d5f39bd8d065..abc3d802bd8fd6f82709fcc210294b558275045e 100644
--- a/dapps/valuetransfers/packages/tangle/signature_filter.go
+++ b/dapps/valuetransfers/packages/tangle/signature_filter.go
@@ -5,15 +5,14 @@ import (
 	"sync"
 
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/hive.go/autopeering/peer"
 )
 
 // SignatureFilter represents a filter for the MessageParser that filters out transactions with an invalid signature.
 type SignatureFilter struct {
-	onAcceptCallback      func(message *message.Message, peer *peer.Peer)
-	onRejectCallback      func(message *message.Message, err error, peer *peer.Peer)
+	onAcceptCallback      func(message *tangle.Message, peer *peer.Peer)
+	onRejectCallback      func(message *tangle.Message, err error, peer *peer.Peer)
 	onAcceptCallbackMutex sync.RWMutex
 	onRejectCallbackMutex sync.RWMutex
 }
@@ -25,7 +24,7 @@ func NewSignatureFilter() *SignatureFilter {
 
 // Filter get's called whenever a new message is received. It rejects the message, if the message is not a valid value
 // message.
-func (filter *SignatureFilter) Filter(message *message.Message, peer *peer.Peer) {
+func (filter *SignatureFilter) Filter(message *tangle.Message, peer *peer.Peer) {
 	// accept message if the message is not a value message (it will be checked by other filters)
 	valuePayload := message.Payload()
 	if valuePayload.Type() != payload.Type {
@@ -54,7 +53,7 @@ func (filter *SignatureFilter) Filter(message *message.Message, peer *peer.Peer)
 }
 
 // OnAccept registers the given callback as the acceptance function of the filter.
-func (filter *SignatureFilter) OnAccept(callback func(message *message.Message, peer *peer.Peer)) {
+func (filter *SignatureFilter) OnAccept(callback func(message *tangle.Message, peer *peer.Peer)) {
 	filter.onAcceptCallbackMutex.Lock()
 	defer filter.onAcceptCallbackMutex.Unlock()
 
@@ -62,7 +61,7 @@ func (filter *SignatureFilter) OnAccept(callback func(message *message.Message,
 }
 
 // OnReject registers the given callback as the rejection function of the filter.
-func (filter *SignatureFilter) OnReject(callback func(message *message.Message, err error, peer *peer.Peer)) {
+func (filter *SignatureFilter) OnReject(callback func(message *tangle.Message, err error, peer *peer.Peer)) {
 	filter.onRejectCallbackMutex.Lock()
 	defer filter.onRejectCallbackMutex.Unlock()
 
@@ -70,7 +69,7 @@ func (filter *SignatureFilter) OnReject(callback func(message *message.Message,
 }
 
 // getAcceptCallback returns the callback that is executed when a message passes the filter.
-func (filter *SignatureFilter) getAcceptCallback() func(message *message.Message, peer *peer.Peer) {
+func (filter *SignatureFilter) getAcceptCallback() func(message *tangle.Message, peer *peer.Peer) {
 	filter.onAcceptCallbackMutex.RLock()
 	defer filter.onAcceptCallbackMutex.RUnlock()
 
@@ -78,7 +77,7 @@ func (filter *SignatureFilter) getAcceptCallback() func(message *message.Message
 }
 
 // getRejectCallback returns the callback that is executed when a message is blocked by the filter.
-func (filter *SignatureFilter) getRejectCallback() func(message *message.Message, err error, peer *peer.Peer) {
+func (filter *SignatureFilter) getRejectCallback() func(message *tangle.Message, err error, peer *peer.Peer) {
 	filter.onRejectCallbackMutex.RLock()
 	defer filter.onRejectCallbackMutex.RUnlock()
 
@@ -86,4 +85,4 @@ func (filter *SignatureFilter) getRejectCallback() func(message *message.Message
 }
 
 // interface contract (allow the compiler to check if the implementation has all of the required methods).
-var _ messageparser.MessageFilter = &SignatureFilter{}
+var _ tangle.MessageFilter = &SignatureFilter{}
diff --git a/dapps/valuetransfers/packages/tangle/signature_filter_test.go b/dapps/valuetransfers/packages/tangle/signature_filter_test.go
index c8640ad5d295d75bafde03f6c1f88f4c2f5a94c3..1cb93f673908da24bd03d4af3b11811f10938252 100644
--- a/dapps/valuetransfers/packages/tangle/signature_filter_test.go
+++ b/dapps/valuetransfers/packages/tangle/signature_filter_test.go
@@ -9,11 +9,7 @@ import (
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance"
 	valuePayload "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser"
-	messagePayload "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tipselector"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/hive.go/autopeering/peer"
 	"github.com/iotaledger/hive.go/events"
 	"github.com/iotaledger/hive.go/identity"
@@ -28,7 +24,7 @@ func TestSignatureFilter(t *testing.T) {
 
 	// create helper instances
 	seed := newSeed()
-	messageFactory := messagefactory.New(mapdb.NewMapDB(), []byte("sequenceKey"), identity.GenerateLocalIdentity(), tipselector.New())
+	messageFactory := tangle.NewMessageFactory(mapdb.NewMapDB(), []byte("sequenceKey"), identity.GenerateLocalIdentity(), tangle.NewMessageTipSelector())
 
 	// 1. test value message without signatures
 	{
@@ -84,14 +80,14 @@ func TestSignatureFilter(t *testing.T) {
 	// 3. test message with an invalid value payload
 	{
 		// create a data payload
-		marshalUtil := marshalutil.New(messagePayload.NewData([]byte("test")).Bytes())
+		marshalUtil := marshalutil.New(tangle.NewDataPayload([]byte("test")).Bytes())
 
 		// set the type to be a value payload
 		marshalUtil.WriteSeek(4)
 		marshalUtil.WriteUint32(valuePayload.Type)
 
 		// parse modified bytes back into a payload object
-		dataPayload, _, err := messagePayload.DataFromBytes(marshalUtil.Bytes())
+		dataPayload, _, err := tangle.DataPayloadFromBytes(marshalUtil.Bytes())
 		require.NoError(t, err)
 
 		// parse message bytes
@@ -108,9 +104,9 @@ func TestSignatureFilter(t *testing.T) {
 
 // newSyncMessageParser creates a wrapped MessageParser that works synchronously by using a WaitGroup to wait for the
 // parse result.
-func newSyncMessageParser(messageFilters ...messageparser.MessageFilter) (tester *syncMessageParser) {
+func newSyncMessageParser(messageFilters ...tangle.MessageFilter) (tester *syncMessageParser) {
 	// initialize MessageParser
-	messageParser := messageparser.New()
+	messageParser := tangle.NewMessageParser()
 	for _, messageFilter := range messageFilters {
 		messageParser.AddMessageFilter(messageFilter)
 	}
@@ -121,7 +117,7 @@ func newSyncMessageParser(messageFilters ...messageparser.MessageFilter) (tester
 	}
 
 	// setup async behavior (store result + mark WaitGroup done)
-	messageParser.Events.BytesRejected.Attach(events.NewClosure(func(bytesRejectedEvent *messageparser.BytesRejectedEvent, err error) {
+	messageParser.Events.BytesRejected.Attach(events.NewClosure(func(bytesRejectedEvent *tangle.BytesRejectedEvent, err error) {
 		tester.result = &messageParserResult{
 			accepted: false,
 			message:  nil,
@@ -131,7 +127,7 @@ func newSyncMessageParser(messageFilters ...messageparser.MessageFilter) (tester
 
 		tester.wg.Done()
 	}))
-	messageParser.Events.MessageRejected.Attach(events.NewClosure(func(msgRejectedEvent *messageparser.MessageRejectedEvent, err error) {
+	messageParser.Events.MessageRejected.Attach(events.NewClosure(func(msgRejectedEvent *tangle.MessageRejectedEvent, err error) {
 		tester.result = &messageParserResult{
 			accepted: false,
 			message:  msgRejectedEvent.Message,
@@ -141,7 +137,7 @@ func newSyncMessageParser(messageFilters ...messageparser.MessageFilter) (tester
 
 		tester.wg.Done()
 	}))
-	messageParser.Events.MessageParsed.Attach(events.NewClosure(func(msgParsedEvent *messageparser.MessageParsedEvent) {
+	messageParser.Events.MessageParsed.Attach(events.NewClosure(func(msgParsedEvent *tangle.MessageParsedEvent) {
 		tester.result = &messageParserResult{
 			accepted: true,
 			message:  msgParsedEvent.Message,
@@ -157,13 +153,13 @@ func newSyncMessageParser(messageFilters ...messageparser.MessageFilter) (tester
 
 // syncMessageParser is a wrapper for the MessageParser that allows to parse Messages synchronously.
 type syncMessageParser struct {
-	messageParser *messageparser.MessageParser
+	messageParser *tangle.MessageParser
 	result        *messageParserResult
 	wg            sync.WaitGroup
 }
 
 // Parse parses the message bytes into a message. It either gets accepted or rejected.
-func (tester *syncMessageParser) Parse(messageBytes []byte, peer *peer.Peer) (bool, *message.Message, *peer.Peer, error) {
+func (tester *syncMessageParser) Parse(messageBytes []byte, peer *peer.Peer) (bool, *tangle.Message, *peer.Peer, error) {
 	tester.wg.Add(1)
 	tester.messageParser.Parse(messageBytes, peer)
 	tester.wg.Wait()
@@ -175,7 +171,7 @@ func (tester *syncMessageParser) Parse(messageBytes []byte, peer *peer.Peer) (bo
 // WaitGroup is done waiting.
 type messageParserResult struct {
 	accepted bool
-	message  *message.Message
+	message  *tangle.Message
 	peer     *peer.Peer
 	err      error
 }
diff --git a/packages/binary/drng/payload/payload.go b/packages/binary/drng/payload/payload.go
index e3f1c0a6de78e4db23921745105c83ab96709b97..bf679c27c89ab2fbda2d2795392f2dc21f0c0c73 100644
--- a/packages/binary/drng/payload/payload.go
+++ b/packages/binary/drng/payload/payload.go
@@ -5,7 +5,7 @@ import (
 	"sync"
 
 	"github.com/iotaledger/goshimmer/packages/binary/drng/payload/header"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/hive.go/marshalutil"
 	"github.com/iotaledger/hive.go/stringify"
 )
@@ -127,10 +127,10 @@ func (payload *Payload) String() string {
 // region Payload implementation ///////////////////////////////////////////////////////////////////////////////////////
 
 // Type defines the type of the drng payload.
-var Type = payload.Type(111)
+var Type = tangle.PayloadType(111)
 
 // Type returns the type of the drng payload.
-func (payload *Payload) Type() payload.Type {
+func (payload *Payload) Type() tangle.PayloadType {
 	return Type
 }
 
@@ -140,7 +140,7 @@ func (payload *Payload) Marshal() (bytes []byte, err error) {
 }
 
 func init() {
-	payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) {
+	tangle.RegisterPayloadType(Type, ObjectName, func(data []byte) (payload tangle.Payload, err error) {
 		payload, _, err = FromBytes(data)
 
 		return
diff --git a/packages/binary/drng/subtypes/collectivebeacon/payload/payload.go b/packages/binary/drng/subtypes/collectivebeacon/payload/payload.go
index 46bed289ed81ca17a6bf6d99b2e5b956c1825566..84808da40482e898a46c660465874504147e22aa 100644
--- a/packages/binary/drng/subtypes/collectivebeacon/payload/payload.go
+++ b/packages/binary/drng/subtypes/collectivebeacon/payload/payload.go
@@ -8,7 +8,7 @@ import (
 
 	drngPayload "github.com/iotaledger/goshimmer/packages/binary/drng/payload"
 	"github.com/iotaledger/goshimmer/packages/binary/drng/payload/header"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/hive.go/marshalutil"
 )
 
@@ -109,23 +109,23 @@ func FromBytes(bytes []byte) (result *Payload, consumedBytes int, err error) {
 }
 
 // Bytes returns the collective beacon payload bytes.
-func (payload *Payload) Bytes() (bytes []byte) {
+func (p *Payload) Bytes() (bytes []byte) {
 	// acquire lock for reading bytes
-	payload.bytesMutex.RLock()
+	p.bytesMutex.RLock()
 
 	// return if bytes have been determined already
-	if bytes = payload.bytes; bytes != nil {
-		payload.bytesMutex.RUnlock()
+	if bytes = p.bytes; bytes != nil {
+		p.bytesMutex.RUnlock()
 		return
 	}
 
 	// switch to write lock
-	payload.bytesMutex.RUnlock()
-	payload.bytesMutex.Lock()
-	defer payload.bytesMutex.Unlock()
+	p.bytesMutex.RUnlock()
+	p.bytesMutex.Lock()
+	defer p.bytesMutex.Unlock()
 
 	// return if bytes have been determined in the mean time
-	if bytes = payload.bytes; bytes != nil {
+	if bytes = p.bytes; bytes != nil {
 		return
 	}
 
@@ -134,41 +134,41 @@ func (payload *Payload) Bytes() (bytes []byte) {
 	marshalUtil := marshalutil.New(marshalutil.UINT32_SIZE + marshalutil.UINT32_SIZE + payloadLength)
 	marshalUtil.WriteUint32(uint32(payloadLength))
 	marshalUtil.WriteUint32(drngPayload.Type)
-	marshalUtil.WriteBytes(payload.Header.Bytes())
-	marshalUtil.WriteUint64(payload.Round)
-	marshalUtil.WriteBytes(payload.PrevSignature)
-	marshalUtil.WriteBytes(payload.Signature)
-	marshalUtil.WriteBytes(payload.Dpk)
+	marshalUtil.WriteBytes(p.Header.Bytes())
+	marshalUtil.WriteUint64(p.Round)
+	marshalUtil.WriteBytes(p.PrevSignature)
+	marshalUtil.WriteBytes(p.Signature)
+	marshalUtil.WriteBytes(p.Dpk)
 
 	bytes = marshalUtil.Bytes()
 
 	// store result
-	payload.bytes = bytes
+	p.bytes = bytes
 
 	return
 }
 
-func (payload *Payload) String() string {
+func (p *Payload) String() string {
 	return stringify.Struct("Payload",
-		stringify.StructField("type", uint64(payload.Header.PayloadType)),
-		stringify.StructField("instance", uint64(payload.Header.InstanceID)),
-		stringify.StructField("round", payload.Round),
-		stringify.StructField("prevSignature", payload.PrevSignature),
-		stringify.StructField("signature", payload.Signature),
-		stringify.StructField("distributedPK", payload.Dpk),
+		stringify.StructField("type", uint64(p.Header.PayloadType)),
+		stringify.StructField("instance", uint64(p.Header.InstanceID)),
+		stringify.StructField("round", p.Round),
+		stringify.StructField("prevSignature", p.PrevSignature),
+		stringify.StructField("signature", p.Signature),
+		stringify.StructField("distributedPK", p.Dpk),
 	)
 }
 
 // region Payload implementation ///////////////////////////////////////////////////////////////////////////////////////
 
 // Type returns the collective beacon payload type.
-func (payload *Payload) Type() payload.Type {
+func (p *Payload) Type() tangle.PayloadType {
 	return drngPayload.Type
 }
 
 // Marshal marshals the collective beacon payload into bytes.
-func (payload *Payload) Marshal() (bytes []byte, err error) {
-	return payload.Bytes(), nil
+func (p *Payload) Marshal() (bytes []byte, err error) {
+	return p.Bytes(), nil
 }
 
 // // endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/packages/binary/messagelayer/message/id.go b/packages/binary/messagelayer/message/id.go
deleted file mode 100644
index 3ac24f93da19afae00fcb639b1707727398afa25..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/message/id.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package message
-
-import (
-	"fmt"
-
-	"github.com/iotaledger/hive.go/marshalutil"
-	"github.com/mr-tron/base58"
-)
-
-// ContentID identifies the content of a message without its parent1/parent2 ids.
-type ContentID = ID
-
-// ID identifies a message in its entirety. Unlike the sole content id, it also incorporates
-// the parent1 and parent2 ids.
-type ID [IDLength]byte
-
-// NewID creates a new message id.
-func NewID(base58EncodedString string) (result ID, err error) {
-	bytes, err := base58.Decode(base58EncodedString)
-	if err != nil {
-		return
-	}
-
-	if len(bytes) != IDLength {
-		err = fmt.Errorf("length of base58 formatted message id is wrong")
-
-		return
-	}
-
-	copy(result[:], bytes)
-
-	return
-}
-
-// IDFromBytes unmarshals a message id from a sequence of bytes.
-func IDFromBytes(bytes []byte) (result ID, consumedBytes int, err error) {
-	// check arguments
-	if len(bytes) < IDLength {
-		err = fmt.Errorf("bytes not long enough to encode a valid message id")
-	}
-
-	// calculate result
-	copy(result[:], bytes)
-
-	// return the number of bytes we processed
-	consumedBytes = IDLength
-
-	return
-}
-
-// ParseID is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package.
-func ParseID(marshalUtil *marshalutil.MarshalUtil) (ID, error) {
-	id, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return IDFromBytes(data) })
-	if err != nil {
-		return ID{}, err
-	}
-	return id.(ID), nil
-}
-
-// MarshalBinary marshals the ID into bytes.
-func (id *ID) MarshalBinary() (result []byte, err error) {
-	return id.Bytes(), nil
-}
-
-// UnmarshalBinary unmarshals the bytes into an ID.
-func (id *ID) UnmarshalBinary(data []byte) (err error) {
-	copy(id[:], data)
-
-	return
-}
-
-// Bytes returns the bytes of the ID.
-func (id ID) Bytes() []byte {
-	return id[:]
-}
-
-// String returns the base58 encode of the ID.
-func (id ID) String() string {
-	return base58.Encode(id[:])
-}
-
-// EmptyID is an empty id.
-var EmptyID = ID{}
-
-// IDLength defines the length of an ID.
-const IDLength = 64
diff --git a/packages/binary/messagelayer/message/message.go b/packages/binary/messagelayer/message/message.go
deleted file mode 100644
index 0ea9d7a2f8260fad608c85f596611d46c09385dd..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/message/message.go
+++ /dev/null
@@ -1,342 +0,0 @@
-package message
-
-import (
-	"fmt"
-	"sync"
-	"time"
-
-	"github.com/iotaledger/hive.go/crypto/ed25519"
-	"github.com/iotaledger/hive.go/marshalutil"
-	"github.com/iotaledger/hive.go/objectstorage"
-	"github.com/iotaledger/hive.go/stringify"
-	"golang.org/x/crypto/blake2b"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-)
-
-// Message represents the core message for the base layer Tangle.
-type Message struct {
-	// base functionality of StorableObject
-	objectstorage.StorableObjectFlags
-
-	// core properties (get sent over the wire)
-	parent1ID       ID
-	parent2ID       ID
-	issuerPublicKey ed25519.PublicKey
-	issuingTime     time.Time
-	sequenceNumber  uint64
-	payload         payload.Payload
-	nonce           uint64
-	signature       ed25519.Signature
-
-	// derived properties
-	id             *ID
-	idMutex        sync.RWMutex
-	contentID      *ContentID
-	contentIDMutex sync.RWMutex
-	bytes          []byte
-	bytesMutex     sync.RWMutex
-}
-
-// New creates a new message with the details provided by the issuer.
-func New(parent1ID ID, parent2ID ID, issuingTime time.Time, issuerPublicKey ed25519.PublicKey, sequenceNumber uint64, payload payload.Payload, nonce uint64, signature ed25519.Signature) (result *Message) {
-	return &Message{
-		parent1ID:       parent1ID,
-		parent2ID:       parent2ID,
-		issuerPublicKey: issuerPublicKey,
-		issuingTime:     issuingTime,
-		sequenceNumber:  sequenceNumber,
-		payload:         payload,
-		nonce:           nonce,
-		signature:       signature,
-	}
-}
-
-// FromBytes parses the given bytes into a message.
-func FromBytes(bytes []byte) (result *Message, consumedBytes int, err error) {
-	marshalUtil := marshalutil.New(bytes)
-	result, err = Parse(marshalUtil)
-	consumedBytes = marshalUtil.ReadOffset()
-
-	return
-}
-
-// Parse parses a Message using the given marshal util.
-func Parse(marshalUtil *marshalutil.MarshalUtil) (result *Message, err error) {
-	// determine read offset before starting to parse
-	readOffsetStart := marshalUtil.ReadOffset()
-
-	// parse information
-	result = &Message{}
-	if result.parent1ID, err = ParseID(marshalUtil); err != nil {
-		return
-	}
-	if result.parent2ID, err = ParseID(marshalUtil); err != nil {
-		return
-	}
-	if result.issuerPublicKey, err = ed25519.ParsePublicKey(marshalUtil); err != nil {
-		return
-	}
-	if result.issuingTime, err = marshalUtil.ReadTime(); err != nil {
-		return
-	}
-	if result.sequenceNumber, err = marshalUtil.ReadUint64(); err != nil {
-		return
-	}
-	if result.payload, err = payload.Parse(marshalUtil); err != nil {
-		return
-	}
-	if result.nonce, err = marshalUtil.ReadUint64(); err != nil {
-		return
-	}
-	if result.signature, err = ed25519.ParseSignature(marshalUtil); err != nil {
-		return
-	}
-
-	// retrieve the number of bytes we processed
-	readOffsetEnd := marshalUtil.ReadOffset()
-
-	// store marshaled version as a copy
-	result.bytes, err = marshalUtil.ReadBytes(readOffsetEnd-readOffsetStart, readOffsetStart)
-	if err != nil {
-		err = fmt.Errorf("error trying to copy raw source bytes: %w", err)
-
-		return
-	}
-
-	return
-}
-
-// FromObjectStorage gets called when we restore a message from the ObjectStorage.
-func FromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) {
-	// parse the message
-	message, err := Parse(marshalutil.New(data))
-	if err != nil {
-		return
-	}
-
-	// parse the ID from they key
-	id, err := ParseID(marshalutil.New(key))
-	if err != nil {
-		return
-	}
-	message.id = &id
-
-	// assign result
-	result = message
-
-	return
-}
-
-// VerifySignature verifies the signature of the message.
-func (message *Message) VerifySignature() bool {
-	msgBytes := message.Bytes()
-	signature := message.Signature()
-
-	contentLength := len(msgBytes) - len(signature)
-	content := msgBytes[:contentLength]
-
-	return message.issuerPublicKey.VerifySignature(content, signature)
-}
-
-// ID returns the id of the message which is made up of the content id and parent1/parent2 ids.
-// This id can be used for merkle proofs.
-func (message *Message) ID() (result ID) {
-	message.idMutex.RLock()
-
-	if message.id == nil {
-		message.idMutex.RUnlock()
-
-		message.idMutex.Lock()
-		defer message.idMutex.Unlock()
-		if message.id != nil {
-			result = *message.id
-			return
-		}
-		result = message.calculateID()
-		message.id = &result
-		return
-	}
-
-	result = *message.id
-	message.idMutex.RUnlock()
-	return
-}
-
-// Parent1ID returns the id of the parent1 message.
-func (message *Message) Parent1ID() ID {
-	return message.parent1ID
-}
-
-// Parent2ID returns the id of the parent2 message.
-func (message *Message) Parent2ID() ID {
-	return message.parent2ID
-}
-
-// IssuerPublicKey returns the public key of the message issuer.
-func (message *Message) IssuerPublicKey() ed25519.PublicKey {
-	return message.issuerPublicKey
-}
-
-// IssuingTime returns the time when this message was created.
-func (message *Message) IssuingTime() time.Time {
-	return message.issuingTime
-}
-
-// SequenceNumber returns the sequence number of this message.
-func (message *Message) SequenceNumber() uint64 {
-	return message.sequenceNumber
-}
-
-// Payload returns the payload of the message.
-func (message *Message) Payload() payload.Payload {
-	return message.payload
-}
-
-// Nonce returns the nonce of the message.
-func (message *Message) Nonce() uint64 {
-	return message.nonce
-}
-
-// Signature returns the signature of the message.
-func (message *Message) Signature() ed25519.Signature {
-	return message.signature
-}
-
-// ContentID returns the content id of the message which is made up of all the
-// parts of the message minus the parent1 and parent2 ids.
-func (message *Message) ContentID() (result ContentID) {
-	message.contentIDMutex.RLock()
-	if message.contentID == nil {
-		message.contentIDMutex.RUnlock()
-
-		message.contentIDMutex.Lock()
-		defer message.contentIDMutex.Unlock()
-		if message.contentID != nil {
-			result = *message.contentID
-			return
-		}
-		result = message.calculateContentID()
-		message.contentID = &result
-		return
-	}
-
-	result = *message.contentID
-	message.contentIDMutex.RUnlock()
-	return
-}
-
-// calculates the message id.
-func (message *Message) calculateID() ID {
-	return blake2b.Sum512(
-		marshalutil.New(IDLength + IDLength + payload.IDLength).
-			WriteBytes(message.parent1ID.Bytes()).
-			WriteBytes(message.parent2ID.Bytes()).
-			WriteBytes(message.ContentID().Bytes()).
-			Bytes(),
-	)
-}
-
-// calculates the content id of the message.
-func (message *Message) calculateContentID() ContentID {
-	// compute content id from the message data (except parent1 and parent2 ids)
-	return blake2b.Sum512(message.Bytes()[2*IDLength:])
-}
-
-// Bytes returns the message in serialized byte form.
-func (message *Message) Bytes() []byte {
-	message.bytesMutex.RLock()
-	if message.bytes != nil {
-		defer message.bytesMutex.RUnlock()
-
-		return message.bytes
-	}
-
-	message.bytesMutex.RUnlock()
-	message.bytesMutex.RLock()
-	defer message.bytesMutex.RUnlock()
-
-	if message.bytes != nil {
-		return message.bytes
-	}
-
-	// marshal result
-	marshalUtil := marshalutil.New()
-	marshalUtil.WriteBytes(message.parent1ID.Bytes())
-	marshalUtil.WriteBytes(message.parent2ID.Bytes())
-	marshalUtil.WriteBytes(message.issuerPublicKey.Bytes())
-	marshalUtil.WriteTime(message.issuingTime)
-	marshalUtil.WriteUint64(message.sequenceNumber)
-	marshalUtil.WriteBytes(message.payload.Bytes())
-	marshalUtil.WriteUint64(message.nonce)
-	marshalUtil.WriteBytes(message.signature.Bytes())
-
-	message.bytes = marshalUtil.Bytes()
-
-	return message.bytes
-}
-
-// ObjectStorageKey returns the key of the stored message object.
-// This returns the bytes of the message ID.
-func (message *Message) ObjectStorageKey() []byte {
-	return message.ID().Bytes()
-}
-
-// ObjectStorageValue returns the value stored in object storage.
-// This returns the bytes of message.
-func (message *Message) ObjectStorageValue() []byte {
-	return message.Bytes()
-}
-
-// Update updates the object with the values of another object.
-// Since a Message is immutable, this function is not implemented and panics.
-func (message *Message) Update(objectstorage.StorableObject) {
-	panic("messages should never be overwritten and only stored once to optimize IO")
-}
-
-func (message *Message) String() string {
-	return stringify.Struct("Message",
-		stringify.StructField("id", message.ID()),
-		stringify.StructField("parent1Id", message.Parent1ID()),
-		stringify.StructField("parent2Id", message.Parent2ID()),
-		stringify.StructField("issuer", message.IssuerPublicKey()),
-		stringify.StructField("issuingTime", message.IssuingTime()),
-		stringify.StructField("sequenceNumber", message.SequenceNumber()),
-		stringify.StructField("payload", message.Payload()),
-		stringify.StructField("nonce", message.Nonce()),
-		stringify.StructField("signature", message.Signature()),
-	)
-}
-
-// CachedMessage defines a cached message.
-// A wrapper for a cached object.
-type CachedMessage struct {
-	objectstorage.CachedObject
-}
-
-// Retain registers a new consumer for the cached message.
-func (cachedMessage *CachedMessage) Retain() *CachedMessage {
-	return &CachedMessage{cachedMessage.CachedObject.Retain()}
-}
-
-// Consume consumes the cached object and releases it when the callback is done.
-// It returns true if the callback was called.
-func (cachedMessage *CachedMessage) Consume(consumer func(msg *Message)) bool {
-	return cachedMessage.CachedObject.Consume(func(object objectstorage.StorableObject) {
-		consumer(object.(*Message))
-	})
-}
-
-// Unwrap returns the message wrapped by the cached message.
-// If the wrapped object cannot be cast to a Message or has been deleted, it returns nil.
-func (cachedMessage *CachedMessage) Unwrap() *Message {
-	untypedMessage := cachedMessage.Get()
-	if untypedMessage == nil {
-		return nil
-	}
-	typeCastedMessage := untypedMessage.(*Message)
-	if typeCastedMessage == nil || typeCastedMessage.IsDeleted() {
-		return nil
-	}
-	return typeCastedMessage
-}
diff --git a/packages/binary/messagelayer/messagefactory/events.go b/packages/binary/messagelayer/messagefactory/events.go
deleted file mode 100644
index 873b0aca65fffed325b455f3bdb758c27f89b6ca..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messagefactory/events.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package messagefactory
-
-import (
-	"github.com/iotaledger/hive.go/events"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-)
-
-// Events represents events happening on a message factory.
-type Events struct {
-	// Fired when a message is built including tips, sequence number and other metadata.
-	MessageConstructed *events.Event
-	// Fired when an error occurred.
-	Error *events.Event
-}
-
-func newEvents() *Events {
-	return &Events{
-		MessageConstructed: events.NewEvent(messageConstructedEvent),
-		Error:              events.NewEvent(events.ErrorCaller),
-	}
-}
-
-func messageConstructedEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*message.Message))(params[0].(*message.Message))
-}
diff --git a/packages/binary/messagelayer/messagefactory/messagefactory.go b/packages/binary/messagelayer/messagefactory/messagefactory.go
deleted file mode 100644
index c1b0123867d06b4ded655dbc829caac9e2b29cf3..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messagefactory/messagefactory.go
+++ /dev/null
@@ -1,155 +0,0 @@
-package messagefactory
-
-import (
-	"fmt"
-	"sync"
-	"time"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-	"github.com/iotaledger/hive.go/crypto/ed25519"
-	"github.com/iotaledger/hive.go/identity"
-	"github.com/iotaledger/hive.go/kvstore"
-)
-
-const storeSequenceInterval = 100
-
-var (
-	// ZeroWorker is a PoW worker that always returns 0 as the nonce.
-	ZeroWorker = WorkerFunc(func([]byte) (uint64, error) { return 0, nil })
-)
-
-// A TipSelector selects two tips, parent2 and parent1, for a new message to attach to.
-type TipSelector interface {
-	Tips() (parent1 message.ID, parent2 message.ID)
-}
-
-// A Worker performs the PoW for the provided message in serialized byte form.
-type Worker interface {
-	DoPOW([]byte) (nonce uint64, err error)
-}
-
-// MessageFactory acts as a factory to create new messages.
-type MessageFactory struct {
-	Events        *Events
-	sequence      *kvstore.Sequence
-	localIdentity *identity.LocalIdentity
-	selector      TipSelector
-
-	worker        Worker
-	workerMutex   sync.RWMutex
-	issuanceMutex sync.Mutex
-}
-
-// New creates a new message factory.
-func New(store kvstore.KVStore, sequenceKey []byte, localIdentity *identity.LocalIdentity, selector TipSelector) *MessageFactory {
-	sequence, err := kvstore.NewSequence(store, sequenceKey, storeSequenceInterval)
-	if err != nil {
-		panic(fmt.Sprintf("could not create message sequence number: %v", err))
-	}
-
-	return &MessageFactory{
-		Events:        newEvents(),
-		sequence:      sequence,
-		localIdentity: localIdentity,
-		selector:      selector,
-		worker:        ZeroWorker,
-	}
-}
-
-// SetWorker sets the PoW worker to be used for the messages.
-func (m *MessageFactory) SetWorker(worker Worker) {
-	m.workerMutex.Lock()
-	defer m.workerMutex.Unlock()
-	m.worker = worker
-}
-
-// IssuePayload creates a new message including sequence number and tip selection and returns it.
-// It also triggers the MessageConstructed event once it's done, which is for example used by the plugins to listen for
-// messages that shall be attached to the tangle.
-func (m *MessageFactory) IssuePayload(p payload.Payload) (*message.Message, error) {
-	payloadLen := len(p.Bytes())
-	if payloadLen > payload.MaxPayloadSize {
-		err := fmt.Errorf("%w: %d bytes", payload.ErrMaxPayloadSizeExceeded, payloadLen)
-		m.Events.Error.Trigger(err)
-		return nil, err
-	}
-
-	m.issuanceMutex.Lock()
-	defer m.issuanceMutex.Unlock()
-	sequenceNumber, err := m.sequence.Next()
-	if err != nil {
-		err = fmt.Errorf("could not create sequence number: %w", err)
-		m.Events.Error.Trigger(err)
-		return nil, err
-	}
-
-	parent1ID, parent2ID := m.selector.Tips()
-	issuingTime := time.Now()
-	issuerPublicKey := m.localIdentity.PublicKey()
-
-	// do the PoW
-	nonce, err := m.doPOW(parent1ID, parent2ID, issuingTime, issuerPublicKey, sequenceNumber, p)
-	if err != nil {
-		err = fmt.Errorf("pow failed: %w", err)
-		m.Events.Error.Trigger(err)
-		return nil, err
-	}
-
-	// create the signature
-	signature := m.sign(parent1ID, parent2ID, issuingTime, issuerPublicKey, sequenceNumber, p, nonce)
-
-	msg := message.New(
-		parent1ID,
-		parent2ID,
-		issuingTime,
-		issuerPublicKey,
-		sequenceNumber,
-		p,
-		nonce,
-		signature,
-	)
-	m.Events.MessageConstructed.Trigger(msg)
-	return msg, nil
-}
-
-// Shutdown closes the messageFactory and persists the sequence number.
-func (m *MessageFactory) Shutdown() {
-	if err := m.sequence.Release(); err != nil {
-		m.Events.Error.Trigger(fmt.Errorf("could not release message sequence number: %w", err))
-	}
-}
-
-func (m *MessageFactory) doPOW(parent1ID message.ID, parent2ID message.ID, issuingTime time.Time, key ed25519.PublicKey, seq uint64, payload payload.Payload) (uint64, error) {
-	// create a dummy message to simplify marshaling
-	dummy := message.New(parent1ID, parent2ID, issuingTime, key, seq, payload, 0, ed25519.EmptySignature).Bytes()
-
-	m.workerMutex.RLock()
-	defer m.workerMutex.RUnlock()
-	return m.worker.DoPOW(dummy)
-}
-
-func (m *MessageFactory) sign(parent1ID message.ID, parent2ID message.ID, issuingTime time.Time, key ed25519.PublicKey, seq uint64, payload payload.Payload, nonce uint64) ed25519.Signature {
-	// create a dummy message to simplify marshaling
-	dummy := message.New(parent1ID, parent2ID, issuingTime, key, seq, payload, nonce, ed25519.EmptySignature)
-	dummyBytes := dummy.Bytes()
-
-	contentLength := len(dummyBytes) - len(dummy.Signature())
-	return m.localIdentity.Sign(dummyBytes[:contentLength])
-}
-
-// The TipSelectorFunc type is an adapter to allow the use of ordinary functions as tip selectors.
-type TipSelectorFunc func() (message.ID, message.ID)
-
-// Tips calls f().
-func (f TipSelectorFunc) Tips() (message.ID, message.ID) {
-	return f()
-}
-
-// The WorkerFunc type is an adapter to allow the use of ordinary functions as a PoW performer.
-type WorkerFunc func([]byte) (uint64, error)
-
-// DoPOW calls f(msg).
-func (f WorkerFunc) DoPOW(msg []byte) (uint64, error) {
-	return f(msg)
-}
diff --git a/packages/binary/messagelayer/messagefactory/messagefactory_test.go b/packages/binary/messagelayer/messagefactory/messagefactory_test.go
deleted file mode 100644
index ff566d393c663d5a57fc57c232bbcf7b05ccf60c..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messagefactory/messagefactory_test.go
+++ /dev/null
@@ -1,163 +0,0 @@
-package messagefactory
-
-import (
-	"context"
-	"crypto"
-	"crypto/ed25519"
-	"sync"
-	"sync/atomic"
-	"testing"
-	"time"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-	"github.com/iotaledger/goshimmer/packages/pow"
-	"github.com/iotaledger/hive.go/events"
-	"github.com/iotaledger/hive.go/identity"
-	"github.com/iotaledger/hive.go/kvstore/mapdb"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	_ "golang.org/x/crypto/blake2b"
-)
-
-const (
-	sequenceKey   = "seq"
-	targetPOW     = 10
-	totalMessages = 2000
-)
-
-func TestMessageFactory_BuildMessage(t *testing.T) {
-	msgFactory := New(
-		mapdb.NewMapDB(),
-		[]byte(sequenceKey),
-		identity.GenerateLocalIdentity(),
-		TipSelectorFunc(func() (message.ID, message.ID) { return message.EmptyID, message.EmptyID }),
-	)
-	defer msgFactory.Shutdown()
-
-	// keep track of sequence numbers
-	sequenceNumbers := sync.Map{}
-
-	// attach to event and count
-	countEvents := uint64(0)
-	msgFactory.Events.MessageConstructed.Attach(events.NewClosure(func(msg *message.Message) {
-		atomic.AddUint64(&countEvents, 1)
-	}))
-
-	t.Run("CheckProperties", func(t *testing.T) {
-		p := payload.NewData([]byte("TestCheckProperties"))
-		msg, err := msgFactory.IssuePayload(p)
-		require.NoError(t, err)
-
-		assert.NotNil(t, msg.Parent1ID())
-		assert.NotNil(t, msg.Parent2ID())
-
-		// time in range of 0.1 seconds
-		assert.InDelta(t, time.Now().UnixNano(), msg.IssuingTime().UnixNano(), 100000000)
-
-		// check payload
-		assert.Equal(t, p, msg.Payload())
-
-		// check total events and sequence number
-		assert.EqualValues(t, 1, countEvents)
-		assert.EqualValues(t, 0, msg.SequenceNumber())
-
-		sequenceNumbers.Store(msg.SequenceNumber(), true)
-	})
-
-	// create messages in parallel
-	t.Run("ParallelCreation", func(t *testing.T) {
-		for i := 1; i < totalMessages; i++ {
-			t.Run("test", func(t *testing.T) {
-				t.Parallel()
-
-				p := payload.NewData([]byte("TestParallelCreation"))
-				msg, err := msgFactory.IssuePayload(p)
-				require.NoError(t, err)
-
-				assert.NotNil(t, msg.Parent1ID())
-				assert.NotNil(t, msg.Parent2ID())
-
-				// time in range of 0.1 seconds
-				assert.InDelta(t, time.Now().UnixNano(), msg.IssuingTime().UnixNano(), 100000000)
-
-				// check payload
-				assert.Equal(t, p, msg.Payload())
-
-				sequenceNumbers.Store(msg.SequenceNumber(), true)
-			})
-		}
-	})
-
-	// check total events and sequence number
-	assert.EqualValues(t, totalMessages, countEvents)
-
-	max := uint64(0)
-	countSequence := 0
-	sequenceNumbers.Range(func(key, value interface{}) bool {
-		seq := key.(uint64)
-		val := value.(bool)
-		if val != true {
-			return false
-		}
-
-		// check for max sequence number
-		if seq > max {
-			max = seq
-		}
-		countSequence++
-		return true
-	})
-	assert.EqualValues(t, totalMessages-1, max)
-	assert.EqualValues(t, totalMessages, countSequence)
-}
-
-func TestMessageFactory_POW(t *testing.T) {
-	msgFactory := New(
-		mapdb.NewMapDB(),
-		[]byte(sequenceKey),
-		identity.GenerateLocalIdentity(),
-		TipSelectorFunc(func() (message.ID, message.ID) { return message.EmptyID, message.EmptyID }),
-	)
-	defer msgFactory.Shutdown()
-
-	worker := pow.New(crypto.BLAKE2b_512, 1)
-
-	msgFactory.SetWorker(WorkerFunc(func(msgBytes []byte) (uint64, error) {
-		content := msgBytes[:len(msgBytes)-ed25519.SignatureSize-8]
-		return worker.Mine(context.Background(), content, targetPOW)
-	}))
-
-	msg, err := msgFactory.IssuePayload(payload.NewData([]byte("test")))
-	require.NoError(t, err)
-
-	msgBytes := msg.Bytes()
-	content := msgBytes[:len(msgBytes)-ed25519.SignatureSize-8]
-
-	zeroes, err := worker.LeadingZerosWithNonce(content, msg.Nonce())
-	assert.GreaterOrEqual(t, zeroes, targetPOW)
-	assert.NoError(t, err)
-}
-
-func TestWorkerFunc_PayloadSize(t *testing.T) {
-	msgFactory := New(
-		mapdb.NewMapDB(),
-		[]byte(sequenceKey),
-		identity.GenerateLocalIdentity(),
-		TipSelectorFunc(func() (message.ID, message.ID) { return message.EmptyID, message.EmptyID }),
-	)
-	defer msgFactory.Shutdown()
-
-	// issue message with max allowed payload size
-	// dataPayload headers: type|32bit + size|32bit
-	data := make([]byte, payload.MaxPayloadSize-4-4)
-	msg, err := msgFactory.IssuePayload(payload.NewData(data))
-	require.NoError(t, err)
-	assert.Truef(t, payload.MaxMessageSize == len(msg.Bytes()), "message size should be exactly %d bytes but is %d", payload.MaxMessageSize, len(msg.Bytes()))
-
-	// issue message bigger than max allowed payload size
-	data = make([]byte, payload.MaxPayloadSize)
-	msg, err = msgFactory.IssuePayload(payload.NewData(data))
-	require.Error(t, err)
-	assert.Nil(t, msg)
-}
diff --git a/packages/binary/messagelayer/messageparser/builtinfilters/message_signature_filter.go b/packages/binary/messagelayer/messageparser/builtinfilters/message_signature_filter.go
deleted file mode 100644
index 02ba960c4e183af9dd7b084c798accaf1d14e458..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messageparser/builtinfilters/message_signature_filter.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package builtinfilters
-
-import (
-	"fmt"
-	"sync"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/hive.go/autopeering/peer"
-)
-
-// ErrInvalidSignature is returned when a message contains an invalid signature.
-var ErrInvalidSignature = fmt.Errorf("invalid signature")
-
-// MessageSignatureFilter filters messages based on whether their signatures are valid.
-type MessageSignatureFilter struct {
-	onAcceptCallback func(msg *message.Message, peer *peer.Peer)
-	onRejectCallback func(msg *message.Message, err error, peer *peer.Peer)
-
-	onAcceptCallbackMutex sync.RWMutex
-	onRejectCallbackMutex sync.RWMutex
-}
-
-// NewMessageSignatureFilter creates a new message signature filter.
-func NewMessageSignatureFilter() *MessageSignatureFilter {
-	return &MessageSignatureFilter{}
-}
-
-// Filter filters up on the given bytes and peer and calls the acceptance callback
-// if the input passes or the rejection callback if the input is rejected.
-func (filter *MessageSignatureFilter) Filter(msg *message.Message, peer *peer.Peer) {
-	if msg.VerifySignature() {
-		filter.getAcceptCallback()(msg, peer)
-		return
-	}
-	filter.getRejectCallback()(msg, ErrInvalidSignature, peer)
-}
-
-// OnAccept registers the given callback as the acceptance function of the filter.
-func (filter *MessageSignatureFilter) OnAccept(callback func(msg *message.Message, peer *peer.Peer)) {
-	filter.onAcceptCallbackMutex.Lock()
-	filter.onAcceptCallback = callback
-	filter.onAcceptCallbackMutex.Unlock()
-}
-
-// OnReject registers the given callback as the rejection function of the filter.
-func (filter *MessageSignatureFilter) OnReject(callback func(msg *message.Message, err error, peer *peer.Peer)) {
-	filter.onRejectCallbackMutex.Lock()
-	filter.onRejectCallback = callback
-	filter.onRejectCallbackMutex.Unlock()
-}
-
-func (filter *MessageSignatureFilter) getAcceptCallback() (result func(msg *message.Message, peer *peer.Peer)) {
-	filter.onAcceptCallbackMutex.RLock()
-	result = filter.onAcceptCallback
-	filter.onAcceptCallbackMutex.RUnlock()
-	return
-}
-
-func (filter *MessageSignatureFilter) getRejectCallback() (result func(msg *message.Message, err error, peer *peer.Peer)) {
-	filter.onRejectCallbackMutex.RLock()
-	result = filter.onRejectCallback
-	filter.onRejectCallbackMutex.RUnlock()
-	return
-}
diff --git a/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter.go b/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter.go
deleted file mode 100644
index 0147ec3730374158de774f3623c90ac24c8faeca..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter.go
+++ /dev/null
@@ -1,99 +0,0 @@
-package builtinfilters
-
-import (
-	"crypto/ed25519"
-	"errors"
-	"fmt"
-	"sync"
-
-	"github.com/iotaledger/goshimmer/packages/pow"
-	"github.com/iotaledger/hive.go/autopeering/peer"
-)
-
-var (
-	// ErrInvalidPOWDifficultly is returned when the nonce of a message does not fulfill the PoW difficulty.
-	ErrInvalidPOWDifficultly = errors.New("invalid PoW")
-	// ErrMessageTooSmall is returned when the message does not contain enough data for the PoW.
-	ErrMessageTooSmall = errors.New("message too small")
-)
-
-// PowFilter is a message bytes filter validating the PoW nonce.
-type PowFilter struct {
-	worker     *pow.Worker
-	difficulty int
-
-	mu             sync.Mutex
-	acceptCallback func([]byte, *peer.Peer)
-	rejectCallback func([]byte, error, *peer.Peer)
-}
-
-// NewPowFilter creates a new PoW bytes filter.
-func NewPowFilter(worker *pow.Worker, difficulty int) *PowFilter {
-	return &PowFilter{
-		worker:     worker,
-		difficulty: difficulty,
-	}
-}
-
-// Filter checks whether the given bytes pass the PoW validation and calls the corresponding callback.
-func (f *PowFilter) Filter(msgBytes []byte, p *peer.Peer) {
-	if err := f.validate(msgBytes); err != nil {
-		f.reject(msgBytes, err, p)
-		return
-	}
-	f.accept(msgBytes, p)
-}
-
-// OnAccept registers the given callback as the acceptance function of the filter.
-func (f *PowFilter) OnAccept(callback func([]byte, *peer.Peer)) {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	f.acceptCallback = callback
-}
-
-// OnReject registers the given callback as the rejection function of the filter.
-func (f *PowFilter) OnReject(callback func([]byte, error, *peer.Peer)) {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	f.rejectCallback = callback
-}
-
-func (f *PowFilter) accept(msgBytes []byte, p *peer.Peer) {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	if f.acceptCallback != nil {
-		f.acceptCallback(msgBytes, p)
-	}
-}
-
-func (f *PowFilter) reject(msgBytes []byte, err error, p *peer.Peer) {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	if f.rejectCallback != nil {
-		f.rejectCallback(msgBytes, err, p)
-	}
-}
-
-func (f *PowFilter) validate(msgBytes []byte) error {
-	content, err := powData(msgBytes)
-	if err != nil {
-		return err
-	}
-	zeros, err := f.worker.LeadingZeros(content)
-	if err != nil {
-		return err
-	}
-	if zeros < f.difficulty {
-		return fmt.Errorf("%w: leading zeros %d for difficulty %d", ErrInvalidPOWDifficultly, zeros, f.difficulty)
-	}
-	return nil
-}
-
-// powData returns the bytes over which PoW should be computed.
-func powData(msgBytes []byte) ([]byte, error) {
-	contentLength := len(msgBytes) - ed25519.SignatureSize
-	if contentLength < pow.NonceBytes {
-		return nil, ErrMessageTooSmall
-	}
-	return msgBytes[:contentLength], nil
-}
diff --git a/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter_test.go b/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter_test.go
deleted file mode 100644
index aec79fdd9134ad6fa3d8baee1b45aafa0c00f994..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messageparser/builtinfilters/pow_filter_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package builtinfilters
-
-import (
-	"context"
-	"crypto"
-	"errors"
-	"testing"
-	"time"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-	"github.com/iotaledger/goshimmer/packages/pow"
-	"github.com/iotaledger/hive.go/autopeering/peer"
-	"github.com/iotaledger/hive.go/crypto/ed25519"
-	"github.com/stretchr/testify/mock"
-	"github.com/stretchr/testify/require"
-	_ "golang.org/x/crypto/blake2b" // required by crypto.BLAKE2b_512
-)
-
-var (
-	testPayload    = payload.NewData([]byte("test"))
-	testPeer       *peer.Peer
-	testWorker     = pow.New(crypto.BLAKE2b_512, 1)
-	testDifficulty = 10
-)
-
-func TestPowFilter_Filter(t *testing.T) {
-	filter := NewPowFilter(testWorker, testDifficulty)
-
-	// set callbacks
-	m := &callbackMock{}
-	filter.OnAccept(m.Accept)
-	filter.OnReject(m.Reject)
-
-	t.Run("reject small message", func(t *testing.T) {
-		m.On("Reject", mock.Anything, mock.MatchedBy(func(err error) bool { return errors.Is(err, ErrMessageTooSmall) }), testPeer)
-		filter.Filter(nil, testPeer)
-	})
-
-	msg := newTestMessage(0)
-	msgBytes := msg.Bytes()
-
-	t.Run("reject invalid nonce", func(t *testing.T) {
-		m.On("Reject", msgBytes, mock.MatchedBy(func(err error) bool { return errors.Is(err, ErrInvalidPOWDifficultly) }), testPeer)
-		filter.Filter(msgBytes, testPeer)
-	})
-
-	nonce, err := testWorker.Mine(context.Background(), msgBytes[:len(msgBytes)-len(msg.Signature())-pow.NonceBytes], testDifficulty)
-	require.NoError(t, err)
-
-	msgPOW := newTestMessage(nonce)
-	msgPOWBytes := msgPOW.Bytes()
-
-	t.Run("accept valid nonce", func(t *testing.T) {
-		zeroes, err := testWorker.LeadingZeros(msgPOWBytes[:len(msgPOWBytes)-len(msgPOW.Signature())])
-		require.NoError(t, err)
-		require.GreaterOrEqual(t, zeroes, testDifficulty)
-
-		m.On("Accept", msgPOWBytes, testPeer)
-		filter.Filter(msgPOWBytes, testPeer)
-	})
-
-	m.AssertExpectations(t)
-}
-
-type callbackMock struct{ mock.Mock }
-
-func (m *callbackMock) Accept(msg []byte, p *peer.Peer)            { m.Called(msg, p) }
-func (m *callbackMock) Reject(msg []byte, err error, p *peer.Peer) { m.Called(msg, err, p) }
-
-func newTestMessage(nonce uint64) *message.Message {
-	return message.New(message.EmptyID, message.EmptyID, time.Time{}, ed25519.PublicKey{}, 0, testPayload, nonce, ed25519.Signature{})
-}
diff --git a/packages/binary/messagelayer/messageparser/builtinfilters/recently_seen_bytes_filter.go b/packages/binary/messagelayer/messageparser/builtinfilters/recently_seen_bytes_filter.go
deleted file mode 100644
index 855d79426db2487b2badb2c2eab690db85fbf81b..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messageparser/builtinfilters/recently_seen_bytes_filter.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package builtinfilters
-
-import (
-	"fmt"
-	"sync"
-
-	"github.com/iotaledger/hive.go/autopeering/peer"
-	"github.com/iotaledger/hive.go/bytesfilter"
-)
-
-// ErrReceivedDuplicateBytes is returned when duplicated bytes are rejected.
-var ErrReceivedDuplicateBytes = fmt.Errorf("received duplicate bytes")
-
-// RecentlySeenBytesFilter filters so that bytes which were recently seen don't pass the filter.
-type RecentlySeenBytesFilter struct {
-	bytesFilter      *bytesfilter.BytesFilter
-	onAcceptCallback func(bytes []byte, peer *peer.Peer)
-	onRejectCallback func(bytes []byte, err error, peer *peer.Peer)
-
-	onAcceptCallbackMutex sync.RWMutex
-	onRejectCallbackMutex sync.RWMutex
-}
-
-// NewRecentlySeenBytesFilter creates a new recently seen bytes filter.
-func NewRecentlySeenBytesFilter() *RecentlySeenBytesFilter {
-	return &RecentlySeenBytesFilter{
-		bytesFilter: bytesfilter.New(100000),
-	}
-}
-
-// Filter filters up on the given bytes and peer and calls the acceptance callback
-// if the input passes or the rejection callback if the input is rejected.
-func (filter *RecentlySeenBytesFilter) Filter(bytes []byte, peer *peer.Peer) {
-	if filter.bytesFilter.Add(bytes) {
-		filter.getAcceptCallback()(bytes, peer)
-		return
-	}
-	filter.getRejectCallback()(bytes, ErrReceivedDuplicateBytes, peer)
-}
-
-// OnAccept registers the given callback as the acceptance function of the filter.
-func (filter *RecentlySeenBytesFilter) OnAccept(callback func(bytes []byte, peer *peer.Peer)) {
-	filter.onAcceptCallbackMutex.Lock()
-	filter.onAcceptCallback = callback
-	filter.onAcceptCallbackMutex.Unlock()
-}
-
-// OnReject registers the given callback as the rejection function of the filter.
-func (filter *RecentlySeenBytesFilter) OnReject(callback func(bytes []byte, err error, peer *peer.Peer)) {
-	filter.onRejectCallbackMutex.Lock()
-	filter.onRejectCallback = callback
-	filter.onRejectCallbackMutex.Unlock()
-}
-
-func (filter *RecentlySeenBytesFilter) getAcceptCallback() (result func(bytes []byte, peer *peer.Peer)) {
-	filter.onAcceptCallbackMutex.Lock()
-	result = filter.onAcceptCallback
-	filter.onAcceptCallbackMutex.Unlock()
-	return
-}
-
-func (filter *RecentlySeenBytesFilter) getRejectCallback() (result func(bytes []byte, err error, peer *peer.Peer)) {
-	filter.onRejectCallbackMutex.Lock()
-	result = filter.onRejectCallback
-	filter.onRejectCallbackMutex.Unlock()
-	return
-}
diff --git a/packages/binary/messagelayer/messageparser/bytes_filter.go b/packages/binary/messagelayer/messageparser/bytes_filter.go
deleted file mode 100644
index 7c62a45982127604f7e4bfb84ca94fda93e4d10c..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messageparser/bytes_filter.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package messageparser
-
-import (
-	"github.com/iotaledger/hive.go/autopeering/peer"
-)
-
-// BytesFilter filters based on byte slices and peers.
-type BytesFilter interface {
-	// Filter filters up on the given bytes and peer and calls the acceptance callback
-	// if the input passes or the rejection callback if the input is rejected.
-	Filter(bytes []byte, peer *peer.Peer)
-	// OnAccept registers the given callback as the acceptance function of the filter.
-	OnAccept(callback func(bytes []byte, peer *peer.Peer))
-	// OnReject registers the given callback as the rejection function of the filter.
-	OnReject(callback func(bytes []byte, err error, peer *peer.Peer))
-}
diff --git a/packages/binary/messagelayer/messageparser/events.go b/packages/binary/messagelayer/messageparser/events.go
deleted file mode 100644
index b10316d01075f2c4e744354714bd00f90ff7bc3b..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messageparser/events.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package messageparser
-
-import (
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/hive.go/autopeering/peer"
-	"github.com/iotaledger/hive.go/events"
-)
-
-// Events represents events happening on a message parser.
-type Events struct {
-	// Fired when a message was parsed.
-	MessageParsed *events.Event
-	// Fired when submitted bytes are rejected by a filter.
-	BytesRejected *events.Event
-	// Fired when a message got rejected by a filter.
-	MessageRejected *events.Event
-}
-
-// MessageParsedEvent represents the parameters of messageParsedEvent
-type MessageParsedEvent struct {
-	Message *message.Message
-	Peer    *peer.Peer
-}
-
-// BytesRejectedEvent represents the parameters of bytesRejectedEvent
-type BytesRejectedEvent struct {
-	Bytes []byte
-	Peer  *peer.Peer
-}
-
-// MessageRejectedEvent represents the parameters of messageRejectedEvent
-type MessageRejectedEvent struct {
-	Message *message.Message
-	Peer    *peer.Peer
-}
-
-func newEvents() *Events {
-	return &Events{
-		MessageParsed:   events.NewEvent(messageParsedEvent),
-		BytesRejected:   events.NewEvent(bytesRejectedEvent),
-		MessageRejected: events.NewEvent(messageRejectedEvent),
-	}
-}
-
-func messageParsedEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*MessageParsedEvent))(params[0].(*MessageParsedEvent))
-}
-
-func bytesRejectedEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*BytesRejectedEvent, error))(params[0].(*BytesRejectedEvent), params[1].(error))
-}
-
-func messageRejectedEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*MessageRejectedEvent, error))(params[0].(*MessageRejectedEvent), params[1].(error))
-}
diff --git a/packages/binary/messagelayer/messageparser/message_filter.go b/packages/binary/messagelayer/messageparser/message_filter.go
deleted file mode 100644
index b883f3d12025fb5b2b3c6d54cc7c502b28e291c0..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messageparser/message_filter.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package messageparser
-
-import (
-	"github.com/iotaledger/hive.go/autopeering/peer"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-)
-
-// MessageFilter filters based on messages and peers.
-type MessageFilter interface {
-	// Filter filters up on the given message and peer and calls the acceptance callback
-	// if the input passes or the rejection callback if the input is rejected.
-	Filter(msg *message.Message, peer *peer.Peer)
-	// OnAccept registers the given callback as the acceptance function of the filter.
-	OnAccept(callback func(msg *message.Message, peer *peer.Peer))
-	// OnAccept registers the given callback as the rejection function of the filter.
-	OnReject(callback func(msg *message.Message, err error, peer *peer.Peer))
-}
diff --git a/packages/binary/messagelayer/messageparser/message_parser.go b/packages/binary/messagelayer/messageparser/message_parser.go
deleted file mode 100644
index 05c4f5c089ad25111e2b213c85f10f57dd603231..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messageparser/message_parser.go
+++ /dev/null
@@ -1,129 +0,0 @@
-package messageparser
-
-import (
-	"sync"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser/builtinfilters"
-
-	"github.com/iotaledger/hive.go/autopeering/peer"
-	"github.com/iotaledger/hive.go/typeutils"
-)
-
-// MessageParser parses messages and bytes and emits corresponding events for parsed and rejected messages.
-type MessageParser struct {
-	bytesFilters   []BytesFilter
-	messageFilters []MessageFilter
-	Events         *Events
-
-	byteFiltersModified    typeutils.AtomicBool
-	messageFiltersModified typeutils.AtomicBool
-	bytesFiltersMutex      sync.Mutex
-	messageFiltersMutex    sync.Mutex
-}
-
-// New creates a new message parser.
-func New() (result *MessageParser) {
-	result = &MessageParser{
-		bytesFilters:   make([]BytesFilter, 0),
-		messageFilters: make([]MessageFilter, 0),
-		Events:         newEvents(),
-	}
-
-	// add builtin filters
-	result.AddBytesFilter(builtinfilters.NewRecentlySeenBytesFilter())
-	result.AddMessageFilter(builtinfilters.NewMessageSignatureFilter())
-	return
-}
-
-// Parse parses the given message bytes.
-func (messageParser *MessageParser) Parse(messageBytes []byte, peer *peer.Peer) {
-	messageParser.setupBytesFilterDataFlow()
-	messageParser.setupMessageFilterDataFlow()
-	messageParser.bytesFilters[0].Filter(messageBytes, peer)
-}
-
-// AddBytesFilter adds the given bytes filter to the parser.
-func (messageParser *MessageParser) AddBytesFilter(filter BytesFilter) {
-	messageParser.bytesFiltersMutex.Lock()
-	messageParser.bytesFilters = append(messageParser.bytesFilters, filter)
-	messageParser.bytesFiltersMutex.Unlock()
-	messageParser.byteFiltersModified.Set()
-}
-
-// AddMessageFilter adds a new message filter to the parser.
-func (messageParser *MessageParser) AddMessageFilter(filter MessageFilter) {
-	messageParser.messageFiltersMutex.Lock()
-	messageParser.messageFilters = append(messageParser.messageFilters, filter)
-	messageParser.messageFiltersMutex.Unlock()
-	messageParser.messageFiltersModified.Set()
-}
-
-// sets up the byte filter data flow chain.
-func (messageParser *MessageParser) setupBytesFilterDataFlow() {
-	if !messageParser.byteFiltersModified.IsSet() {
-		return
-	}
-
-	messageParser.bytesFiltersMutex.Lock()
-	if messageParser.byteFiltersModified.IsSet() {
-		messageParser.byteFiltersModified.SetTo(false)
-
-		numberOfBytesFilters := len(messageParser.bytesFilters)
-		for i := 0; i < numberOfBytesFilters; i++ {
-			if i == numberOfBytesFilters-1 {
-				messageParser.bytesFilters[i].OnAccept(messageParser.parseMessage)
-			} else {
-				messageParser.bytesFilters[i].OnAccept(messageParser.bytesFilters[i+1].Filter)
-			}
-			messageParser.bytesFilters[i].OnReject(func(bytes []byte, err error, peer *peer.Peer) {
-				messageParser.Events.BytesRejected.Trigger(&BytesRejectedEvent{
-					Bytes: bytes,
-					Peer:  peer}, err)
-			})
-		}
-	}
-	messageParser.bytesFiltersMutex.Unlock()
-}
-
-// sets up the message filter data flow chain.
-func (messageParser *MessageParser) setupMessageFilterDataFlow() {
-	if !messageParser.messageFiltersModified.IsSet() {
-		return
-	}
-
-	messageParser.messageFiltersMutex.Lock()
-	if messageParser.messageFiltersModified.IsSet() {
-		messageParser.messageFiltersModified.SetTo(false)
-
-		numberOfMessageFilters := len(messageParser.messageFilters)
-		for i := 0; i < numberOfMessageFilters; i++ {
-			if i == numberOfMessageFilters-1 {
-				messageParser.messageFilters[i].OnAccept(func(msg *message.Message, peer *peer.Peer) {
-					messageParser.Events.MessageParsed.Trigger(&MessageParsedEvent{
-						Message: msg,
-						Peer:    peer})
-				})
-			} else {
-				messageParser.messageFilters[i].OnAccept(messageParser.messageFilters[i+1].Filter)
-			}
-			messageParser.messageFilters[i].OnReject(func(msg *message.Message, err error, peer *peer.Peer) {
-				messageParser.Events.MessageRejected.Trigger(&MessageRejectedEvent{
-					Message: msg,
-					Peer:    peer}, err)
-			})
-		}
-	}
-	messageParser.messageFiltersMutex.Unlock()
-}
-
-// parses the given message and emits
-func (messageParser *MessageParser) parseMessage(bytes []byte, peer *peer.Peer) {
-	if parsedMessage, _, err := message.FromBytes(bytes); err != nil {
-		messageParser.Events.BytesRejected.Trigger(&BytesRejectedEvent{
-			Bytes: bytes,
-			Peer:  peer}, err)
-	} else {
-		messageParser.messageFilters[0].Filter(parsedMessage, peer)
-	}
-}
diff --git a/packages/binary/messagelayer/messageparser/message_parser_test.go b/packages/binary/messagelayer/messageparser/message_parser_test.go
deleted file mode 100644
index fe0ab7fbe0e67b574fda2aa778702d2b69f15449..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messageparser/message_parser_test.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package messageparser
-
-import (
-	"strconv"
-	"testing"
-	"time"
-
-	"github.com/iotaledger/hive.go/crypto/ed25519"
-	"github.com/iotaledger/hive.go/events"
-	"github.com/labstack/gommon/log"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-)
-
-func BenchmarkMessageParser_ParseBytesSame(b *testing.B) {
-	msgBytes := newTestMessage("Test").Bytes()
-	msgParser := New()
-
-	b.ResetTimer()
-
-	for i := 0; i < b.N; i++ {
-		msgParser.Parse(msgBytes, nil)
-	}
-}
-
-func BenchmarkMessageParser_ParseBytesDifferent(b *testing.B) {
-	messageBytes := make([][]byte, b.N)
-	for i := 0; i < b.N; i++ {
-		messageBytes[i] = newTestMessage("Test" + strconv.Itoa(i)).Bytes()
-	}
-
-	msgParser := New()
-
-	b.ResetTimer()
-
-	for i := 0; i < b.N; i++ {
-		msgParser.Parse(messageBytes[i], nil)
-	}
-}
-
-func TestMessageParser_ParseMessage(t *testing.T) {
-	msg := newTestMessage("Test")
-
-	msgParser := New()
-	msgParser.Parse(msg.Bytes(), nil)
-
-	msgParser.Events.MessageParsed.Attach(events.NewClosure(func(msgParsedEvent *MessageParsedEvent) {
-		log.Infof("parsed message")
-	}))
-}
-
-func newTestMessage(payloadString string) *message.Message {
-	return message.New(message.EmptyID, message.EmptyID, time.Now(), ed25519.PublicKey{}, 0, payload.NewData([]byte(payloadString)), 0, ed25519.Signature{})
-}
diff --git a/packages/binary/messagelayer/messagerequester/constants.go b/packages/binary/messagelayer/messagerequester/constants.go
deleted file mode 100644
index 7d26d3e96bb5eaa2d23c4b413bfdac4bc47800cf..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messagerequester/constants.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package messagerequester
-
-import (
-	"time"
-)
-
-const (
-	// DefaultRetryInterval defines the Default Retry Interval of the message requester.
-	DefaultRetryInterval = 10 * time.Second
-)
diff --git a/packages/binary/messagelayer/messagerequester/events.go b/packages/binary/messagelayer/messagerequester/events.go
deleted file mode 100644
index 74465a1b5a47d5cbde34cbeb70f30fe4cb609116..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messagerequester/events.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package messagerequester
-
-import (
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/hive.go/events"
-)
-
-// Events represents events happening on a message requester.
-type Events struct {
-	// Fired when a request for a given message should be sent.
-	SendRequest *events.Event
-	// MissingMessageAppeared is triggered when a message is actually present in the node's db although it was still being requested.
-	MissingMessageAppeared *events.Event
-}
-
-// SendRequestEvent represents the parameters of sendRequestEvent
-type SendRequestEvent struct {
-	ID message.ID
-}
-
-// MissingMessageAppearedEvent represents the parameters of missingMessageAppearedEvent
-type MissingMessageAppearedEvent struct {
-	ID message.ID
-}
-
-func newEvents() *Events {
-	return &Events{
-		SendRequest:            events.NewEvent(sendRequestEvent),
-		MissingMessageAppeared: events.NewEvent(missingMessageAppearedEvent),
-	}
-}
-
-func sendRequestEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*SendRequestEvent))(params[0].(*SendRequestEvent))
-}
-
-func missingMessageAppearedEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*MissingMessageAppearedEvent))(params[0].(*MissingMessageAppearedEvent))
-}
diff --git a/packages/binary/messagelayer/messagerequester/messagerequester.go b/packages/binary/messagelayer/messagerequester/messagerequester.go
deleted file mode 100644
index a6ba73120e237e6452f466003b56e394a4c64366..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messagerequester/messagerequester.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package messagerequester
-
-import (
-	"sync"
-	"time"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-)
-
-// the maximum amount of requests before we abort
-const maxRequestThreshold = 500
-
-// MessageRequester takes care of requesting messages.
-type MessageRequester struct {
-	scheduledRequests map[message.ID]*time.Timer
-	options           *Options
-	Events            *Events
-
-	scheduledRequestsMutex sync.RWMutex
-}
-
-// MessageExistsFunc is a function that tells if a message exists.
-type MessageExistsFunc func(messageId message.ID) bool
-
-// New creates a new message requester.
-func New(missingMessages []message.ID, optionalOptions ...Option) *MessageRequester {
-	requester := &MessageRequester{
-		scheduledRequests: make(map[message.ID]*time.Timer),
-		options:           newOptions(optionalOptions),
-		Events:            newEvents(),
-	}
-
-	// add requests for all missing messages
-	requester.scheduledRequestsMutex.Lock()
-	defer requester.scheduledRequestsMutex.Unlock()
-
-	for _, id := range missingMessages {
-		requester.scheduledRequests[id] = time.AfterFunc(requester.options.retryInterval, requester.createReRequest(id, 0))
-	}
-
-	return requester
-}
-
-// StartRequest initiates a regular triggering of the StartRequest event until it has been stopped using StopRequest.
-func (requester *MessageRequester) StartRequest(id message.ID) {
-	requester.scheduledRequestsMutex.Lock()
-
-	// ignore already scheduled requests
-	if _, exists := requester.scheduledRequests[id]; exists {
-		requester.scheduledRequestsMutex.Unlock()
-		return
-	}
-
-	// schedule the next request and trigger the event
-	requester.scheduledRequests[id] = time.AfterFunc(requester.options.retryInterval, requester.createReRequest(id, 0))
-	requester.scheduledRequestsMutex.Unlock()
-	requester.Events.SendRequest.Trigger(&SendRequestEvent{ID: id})
-}
-
-// StopRequest stops requests for the given message to further happen.
-func (requester *MessageRequester) StopRequest(id message.ID) {
-	requester.scheduledRequestsMutex.Lock()
-	defer requester.scheduledRequestsMutex.Unlock()
-
-	if timer, ok := requester.scheduledRequests[id]; ok {
-		timer.Stop()
-		delete(requester.scheduledRequests, id)
-	}
-}
-
-func (requester *MessageRequester) reRequest(id message.ID, count int) {
-	requester.Events.SendRequest.Trigger(&SendRequestEvent{ID: id})
-
-	// as we schedule a request at most once per id we do not need to make the trigger and the re-schedule atomic
-	requester.scheduledRequestsMutex.Lock()
-	defer requester.scheduledRequestsMutex.Unlock()
-
-	// reschedule, if the request has not been stopped in the meantime
-	if _, exists := requester.scheduledRequests[id]; exists {
-		// increase the request counter
-		count++
-
-		// if we have requested too often => stop the requests
-		if count > maxRequestThreshold {
-			delete(requester.scheduledRequests, id)
-
-			return
-		}
-
-		requester.scheduledRequests[id] = time.AfterFunc(requester.options.retryInterval, requester.createReRequest(id, count))
-		return
-	}
-}
-
-// RequestQueueSize returns the number of scheduled message requests.
-func (requester *MessageRequester) RequestQueueSize() int {
-	requester.scheduledRequestsMutex.RLock()
-	defer requester.scheduledRequestsMutex.RUnlock()
-	return len(requester.scheduledRequests)
-}
-
-func (requester *MessageRequester) createReRequest(msgID message.ID, count int) func() {
-	return func() { requester.reRequest(msgID, count) }
-}
diff --git a/packages/binary/messagelayer/messagerequester/options.go b/packages/binary/messagelayer/messagerequester/options.go
deleted file mode 100644
index 816118147af126a781a8e696c8835e455858af5f..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/messagerequester/options.go
+++ /dev/null
@@ -1,32 +0,0 @@
-package messagerequester
-
-import (
-	"time"
-)
-
-// Options holds options for a message requester.
-type Options struct {
-	retryInterval time.Duration
-}
-
-func newOptions(optionalOptions []Option) *Options {
-	result := &Options{
-		retryInterval: 10 * time.Second,
-	}
-
-	for _, optionalOption := range optionalOptions {
-		optionalOption(result)
-	}
-
-	return result
-}
-
-// Option is a function which inits an option.
-type Option func(*Options)
-
-// RetryInterval creates an option which sets the retry interval to the given value.
-func RetryInterval(interval time.Duration) Option {
-	return func(args *Options) {
-		args.retryInterval = interval
-	}
-}
diff --git a/packages/binary/messagelayer/payload/data.go b/packages/binary/messagelayer/payload/data.go
deleted file mode 100644
index 6623a7f503687410fbd47a077b020481e61bde68..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/payload/data.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package payload
-
-import (
-	"github.com/iotaledger/hive.go/marshalutil"
-	"github.com/iotaledger/hive.go/stringify"
-)
-
-// DataType is the message type of a data payload.
-var DataType = Type(0)
-
-// Data represents a payload which just contains a blob of data.
-type Data struct {
-	payloadType Type
-	data        []byte
-}
-
-// NewData creates new data payload.
-func NewData(data []byte) *Data {
-	return &Data{
-		payloadType: DataType,
-		data:        data,
-	}
-}
-
-// DataFromBytes creates a new data payload from the given bytes.
-func DataFromBytes(bytes []byte) (result *Data, consumedBytes int, err error) {
-	marshalUtil := marshalutil.New(bytes)
-	result, err = ParseData(marshalUtil)
-	consumedBytes = marshalUtil.ReadOffset()
-
-	return
-}
-
-// ParseData parses a new data payload out of the given marshal util.
-func ParseData(marshalUtil *marshalutil.MarshalUtil) (result *Data, err error) {
-	// parse information
-	result = &Data{}
-	payloadBytes, err := marshalUtil.ReadUint32()
-	if err != nil {
-		return
-	}
-	result.payloadType, err = marshalUtil.ReadUint32()
-	if err != nil {
-		return
-	}
-	result.data, err = marshalUtil.ReadBytes(int(payloadBytes))
-	if err != nil {
-		return
-	}
-
-	return
-}
-
-// Type returns the payload type.
-func (dataPayload *Data) Type() Type {
-	return dataPayload.payloadType
-}
-
-// Data returns the data of the data payload.
-func (dataPayload *Data) Data() []byte {
-	return dataPayload.data
-}
-
-// Bytes marshals the data payload into a sequence of bytes.
-func (dataPayload *Data) Bytes() []byte {
-	// initialize helper
-	marshalUtil := marshalutil.New()
-
-	// marshal the payload specific information
-	marshalUtil.WriteUint32(uint32(len(dataPayload.data)))
-	marshalUtil.WriteUint32(dataPayload.Type())
-	marshalUtil.WriteBytes(dataPayload.data[:])
-
-	// return result
-	return marshalUtil.Bytes()
-}
-
-func (dataPayload *Data) String() string {
-	return stringify.Struct("Data",
-		stringify.StructField("type", int(dataPayload.Type())),
-		stringify.StructField("data", string(dataPayload.Data())),
-	)
-}
-
-// GenericPayloadUnmarshaler is an unmarshaler for the generic data payload type.
-func GenericPayloadUnmarshaler(data []byte) (payload Payload, err error) {
-	payload, _, err = DataFromBytes(data)
-
-	return
-}
diff --git a/packages/binary/messagelayer/payload/id.go b/packages/binary/messagelayer/payload/id.go
deleted file mode 100644
index ca5bc407e6f47600f201ea04ec9aa625306a8003..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/payload/id.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package payload
-
-import "github.com/mr-tron/base58"
-
-// ID represents the id of a data payload.
-type ID [IDLength]byte
-
-// Bytes returns the id as a byte slice backed by the original array,
-// therefore it should not be modified.
-func (id ID) Bytes() []byte {
-	return id[:]
-}
-
-func (id ID) String() string {
-	return base58.Encode(id[:])
-}
-
-// IDLength is the length of a data payload id.
-const IDLength = 64
diff --git a/packages/binary/messagelayer/payload/payload.go b/packages/binary/messagelayer/payload/payload.go
deleted file mode 100644
index bdf235ecc7854694caf23982a5d8c384ece2cd79..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/payload/payload.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package payload
-
-import (
-	"fmt"
-
-	"github.com/iotaledger/hive.go/marshalutil"
-)
-
-const (
-	// ObjectName defines the name of the data object.
-	ObjectName = "data"
-
-	// MaxMessageSize defines the maximum size of a message.
-	MaxMessageSize = 64 * 1024
-
-	// MaxPayloadSize defines the maximum size of a payload.
-	// parent1ID + parent2ID + issuerPublicKey + issuingTime + sequenceNumber + nonce + signature
-	MaxPayloadSize = MaxMessageSize - 64 - 64 - 32 - 8 - 8 - 8 - 64
-)
-
-var (
-	// ErrMaxPayloadSizeExceeded is returned if the maximum payload size is exceeded.
-	ErrMaxPayloadSizeExceeded = fmt.Errorf("maximum payload size of %d bytes exceeded", MaxPayloadSize)
-)
-
-func init() {
-	// register the generic unmarshaler
-	SetGenericUnmarshaler(GenericPayloadUnmarshaler)
-
-	// register the generic data payload type
-	RegisterType(DataType, ObjectName, GenericPayloadUnmarshaler)
-}
-
-// Payload represents some kind of payload of data which only gains meaning by having
-// corresponding node logic processing payloads of a given type.
-type Payload interface {
-	// Type returns the type of the payload.
-	Type() Type
-
-	// Bytes returns the payload bytes.
-	Bytes() []byte
-
-	// String returns a human-friendly representation of the payload.
-	String() string
-}
-
-// FromBytes unmarshals bytes into a payload.
-func FromBytes(bytes []byte) (result Payload, consumedBytes int, err error) {
-	// initialize helper
-	marshalUtil := marshalutil.New(bytes)
-
-	// calculate result
-	payloadSize, err := marshalUtil.ReadUint32()
-	if err != nil {
-		return
-	}
-
-	if payloadSize > MaxPayloadSize {
-		err = fmt.Errorf("%w: %d", ErrMaxPayloadSizeExceeded, payloadSize)
-		return
-	}
-
-	payloadType, err := marshalUtil.ReadUint32()
-	if err != nil {
-		return
-	}
-
-	marshalUtil.ReadSeek(marshalUtil.ReadOffset() - marshalutil.UINT32_SIZE*2)
-	payloadBytes, err := marshalUtil.ReadBytes(int(payloadSize) + 8)
-	if err != nil {
-		return
-	}
-
-	readOffset := marshalUtil.ReadOffset()
-	result, err = GetUnmarshaler(payloadType)(payloadBytes)
-	if err != nil {
-		// fallback to the generic unmarshaler if registered type fails to unmarshal
-		marshalUtil.ReadSeek(readOffset)
-		result, err = genericUnmarshaler(payloadBytes)
-		if err != nil {
-			return
-		}
-	}
-
-	// return the number of bytes we processed
-	consumedBytes = marshalUtil.ReadOffset()
-	return
-}
-
-// Parse parses a payload by using the given marshal util.
-func Parse(marshalUtil *marshalutil.MarshalUtil) (Payload, error) {
-	payload, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return FromBytes(data) })
-	if err != nil {
-		return nil, err
-	}
-	return payload.(Payload), nil
-}
diff --git a/packages/binary/messagelayer/payload/type.go b/packages/binary/messagelayer/payload/type.go
deleted file mode 100644
index 4f2241bd0200994057b80240baf53d7373e3068e..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/payload/type.go
+++ /dev/null
@@ -1,4 +0,0 @@
-package payload
-
-// Type represents the type id of a payload.
-type Type = uint32
diff --git a/packages/binary/messagelayer/payload/type_register.go b/packages/binary/messagelayer/payload/type_register.go
deleted file mode 100644
index 728119f25cb73e2b3efebe78f041915c5d8037c6..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/payload/type_register.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package payload
-
-import (
-	"sync"
-)
-
-// Unmarshaler takes some data and unmarshals it into a payload.
-type Unmarshaler func(data []byte) (Payload, error)
-
-// Definition defines the properties of a payload type.
-type Definition struct {
-	Name string
-	Unmarshaler
-}
-
-var (
-	typeRegister       = make(map[Type]Definition)
-	typeRegisterMutex  sync.RWMutex
-	genericUnmarshaler Unmarshaler
-)
-
-// RegisterType registers a payload type with the given unmarshaler.
-func RegisterType(payloadType Type, payloadName string, unmarshaler Unmarshaler) {
-	typeRegisterMutex.Lock()
-	typeRegister[payloadType] = Definition{
-		Name:        payloadName,
-		Unmarshaler: unmarshaler,
-	}
-	typeRegisterMutex.Unlock()
-}
-
-// GetUnmarshaler returns the unmarshaler for the given type if known or
-// the generic unmarshaler if the given payload type has no associated unmarshaler.
-func GetUnmarshaler(payloadType Type) Unmarshaler {
-	typeRegisterMutex.RLock()
-	defer typeRegisterMutex.RUnlock()
-
-	if definition, exists := typeRegister[payloadType]; exists {
-		return definition.Unmarshaler
-	}
-
-	return genericUnmarshaler
-}
-
-// SetGenericUnmarshaler sets the generic unmarshaler.
-func SetGenericUnmarshaler(unmarshaler Unmarshaler) {
-	genericUnmarshaler = unmarshaler
-}
-
-// Name returns the name of a given payload type.
-func Name(payloadType Type) string {
-	typeRegisterMutex.RLock()
-	defer typeRegisterMutex.RUnlock()
-	if definition, exists := typeRegister[payloadType]; exists {
-		return definition.Name
-	}
-	return ObjectName
-}
diff --git a/packages/binary/messagelayer/tangle/approver.go b/packages/binary/messagelayer/tangle/approver.go
deleted file mode 100644
index e5d162de400e4f4abad512533ced10b282924390..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/tangle/approver.go
+++ /dev/null
@@ -1,147 +0,0 @@
-package tangle
-
-import (
-	"github.com/iotaledger/hive.go/marshalutil"
-	"github.com/iotaledger/hive.go/objectstorage"
-	"github.com/iotaledger/hive.go/stringify"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-)
-
-// Approver is an approver of a given referenced message.
-type Approver struct {
-	objectstorage.StorableObjectFlags
-	// the message which got referenced by the approver message.
-	referencedMessageID message.ID
-	// the message which approved/referenced the given referenced message.
-	approverMessageID message.ID
-}
-
-// NewApprover creates a new approver relation to the given approved/referenced message.
-func NewApprover(referencedMessageID message.ID, approverMessageID message.ID) *Approver {
-	approver := &Approver{
-		referencedMessageID: referencedMessageID,
-		approverMessageID:   approverMessageID,
-	}
-	return approver
-}
-
-// ApproverFromBytes parses the given bytes into an approver.
-func ApproverFromBytes(bytes []byte) (result *Approver, consumedBytes int, err error) {
-	marshalUtil := marshalutil.New(bytes)
-	result, err = ParseApprover(marshalUtil)
-	consumedBytes = marshalUtil.ReadOffset()
-	return
-}
-
-// ParseApprover parses a new approver from the given marshal util.
-func ParseApprover(marshalUtil *marshalutil.MarshalUtil) (result *Approver, err error) {
-	result = &Approver{}
-
-	if result.referencedMessageID, err = message.ParseID(marshalUtil); err != nil {
-		return
-	}
-	if result.approverMessageID, err = message.ParseID(marshalUtil); err != nil {
-		return
-	}
-
-	return
-}
-
-// ApproverFromObjectStorage returns an approver for the given key.
-func ApproverFromObjectStorage(key []byte, _ []byte) (result objectstorage.StorableObject, err error) {
-	result, _, err = ApproverFromBytes(key)
-
-	return
-}
-
-// ReferencedMessageID returns the ID of the message which is referenced by the approver.
-func (approver *Approver) ReferencedMessageID() message.ID {
-	return approver.referencedMessageID
-}
-
-// ApproverMessageID returns the ID of the message which referenced the given approved message.
-func (approver *Approver) ApproverMessageID() message.ID {
-	return approver.approverMessageID
-}
-
-// Bytes returns the bytes of the approver.
-func (approver *Approver) Bytes() []byte {
-	return approver.ObjectStorageKey()
-}
-
-// String returns the string representation of the approver.
-func (approver *Approver) String() string {
-	return stringify.Struct("Approver",
-		stringify.StructField("referencedMessageID", approver.ReferencedMessageID()),
-		stringify.StructField("approverMessageID", approver.ApproverMessageID()),
-	)
-}
-
-// ObjectStorageKey marshals the keys of the stored approver into a byte array.
-// This includes the referencedMessageID and the approverMessageID.
-func (approver *Approver) ObjectStorageKey() []byte {
-	return marshalutil.New().
-		WriteBytes(approver.referencedMessageID.Bytes()).
-		WriteBytes(approver.approverMessageID.Bytes()).
-		Bytes()
-}
-
-// ObjectStorageValue returns the value of the stored approver object.
-func (approver *Approver) ObjectStorageValue() (result []byte) {
-	return
-}
-
-// Update updates the approver.
-// This should should never happen and will panic if attempted.
-func (approver *Approver) Update(other objectstorage.StorableObject) {
-	panic("approvers should never be overwritten and only stored once to optimize IO")
-}
-
-// interface contract (allow the compiler to check if the implementation has all of the required methods).
-var _ objectstorage.StorableObject = &Approver{}
-
-// CachedApprover is a wrapper for a stored cached object representing an approver.
-type CachedApprover struct {
-	objectstorage.CachedObject
-}
-
-// Unwrap unwraps the cached approver into the underlying approver.
-// If stored object cannot be cast into an approver or has been deleted, it returns nil.
-func (cachedApprover *CachedApprover) Unwrap() *Approver {
-	untypedObject := cachedApprover.Get()
-	if untypedObject == nil {
-		return nil
-	}
-
-	typedObject := untypedObject.(*Approver)
-	if typedObject == nil || typedObject.IsDeleted() {
-		return nil
-	}
-
-	return typedObject
-
-}
-
-// Consume consumes the cachedApprover.
-// It releases the object when the callback is done.
-// It returns true if the callback was called.
-func (cachedApprover *CachedApprover) Consume(consumer func(approver *Approver)) (consumed bool) {
-	return cachedApprover.CachedObject.Consume(func(object objectstorage.StorableObject) {
-		consumer(object.(*Approver))
-	})
-}
-
-// CachedApprovers defines a slice of *CachedApprover.
-type CachedApprovers []*CachedApprover
-
-// Consume calls *CachedApprover.Consume on element in the list.
-func (cachedApprovers CachedApprovers) Consume(consumer func(approver *Approver)) (consumed bool) {
-	for _, cachedApprover := range cachedApprovers {
-		consumed = cachedApprover.Consume(func(approver *Approver) {
-			consumer(approver)
-		}) || consumed
-	}
-
-	return
-}
diff --git a/packages/binary/messagelayer/tangle/events.go b/packages/binary/messagelayer/tangle/events.go
deleted file mode 100644
index 4799082bb03be15a4d3a04db5bfa6a871e26147a..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/tangle/events.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package tangle
-
-import (
-	"github.com/iotaledger/hive.go/events"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-)
-
-// Events represents events happening on the base layer Tangle.
-type Events struct {
-	// Fired when a message has been attached.
-	MessageAttached *events.Event
-	// Fired when a message has been solid, i.e. its past cone
-	// is known and in the database.
-	MessageSolid *events.Event
-	// Fired when a message which was previously marked as missing was received.
-	MissingMessageReceived *events.Event
-	// Fired when a message is missing which is needed to solidify a given approver message.
-	MessageMissing *events.Event
-	// Fired when a message was missing for too long and is
-	// therefore considered to be unsolidifiable.
-	MessageUnsolidifiable *events.Event
-	// Fired when a message was removed from storage.
-	MessageRemoved *events.Event
-}
-
-// CachedMessageEvent represents the parameters of cachedMessageEvent
-type CachedMessageEvent struct {
-	Message         *message.CachedMessage
-	MessageMetadata *CachedMessageMetadata
-}
-
-func newEvents() *Events {
-	return &Events{
-		MessageAttached:        events.NewEvent(cachedMessageEvent),
-		MessageSolid:           events.NewEvent(cachedMessageEvent),
-		MissingMessageReceived: events.NewEvent(cachedMessageEvent),
-		MessageMissing:         events.NewEvent(messageIDEvent),
-		MessageUnsolidifiable:  events.NewEvent(messageIDEvent),
-		MessageRemoved:         events.NewEvent(messageIDEvent),
-	}
-}
-
-func messageIDEvent(handler interface{}, params ...interface{}) {
-	handler.(func(message.ID))(params[0].(message.ID))
-}
-
-func cachedMessageEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*CachedMessageEvent))(cachedMessageRetain(params[0].(*CachedMessageEvent)))
-}
-
-func cachedMessageRetain(object *CachedMessageEvent) *CachedMessageEvent {
-	return &CachedMessageEvent{
-		Message:         object.Message.Retain(),
-		MessageMetadata: object.MessageMetadata.Retain(),
-	}
-}
diff --git a/packages/binary/messagelayer/tangle/messagemetadata.go b/packages/binary/messagelayer/tangle/messagemetadata.go
deleted file mode 100644
index 840d1837ca4a58292022d6de9496057126f52d9d..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/tangle/messagemetadata.go
+++ /dev/null
@@ -1,177 +0,0 @@
-package tangle
-
-import (
-	"sync"
-	"time"
-
-	"github.com/iotaledger/hive.go/byteutils"
-	"github.com/iotaledger/hive.go/marshalutil"
-	"github.com/iotaledger/hive.go/objectstorage"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-)
-
-// MessageMetadata defines the metadata for a message.
-type MessageMetadata struct {
-	objectstorage.StorableObjectFlags
-
-	messageID          message.ID
-	receivedTime       time.Time
-	solid              bool
-	solidificationTime time.Time
-
-	solidMutex              sync.RWMutex
-	solidificationTimeMutex sync.RWMutex
-}
-
-// NewMessageMetadata creates a new MessageMetadata from the specified messageID.
-func NewMessageMetadata(messageID message.ID) *MessageMetadata {
-	return &MessageMetadata{
-		messageID:    messageID,
-		receivedTime: time.Now(),
-	}
-}
-
-// MessageMetadataFromBytes unmarshals the given bytes into a MessageMetadata.
-func MessageMetadataFromBytes(bytes []byte) (result *MessageMetadata, consumedBytes int, err error) {
-	marshalUtil := marshalutil.New(bytes)
-	result, err = ParseMessageMetadata(marshalUtil)
-	consumedBytes = marshalUtil.ReadOffset()
-
-	return
-}
-
-// ParseMessageMetadata parses the marshalUtil into a MessageMetadata.
-// If it successfully parses the marshalUtil, it delegates to MessageMetadataFromObjectStorage.
-// Else, delegates to UnmarshalObjectStorageValue.
-func ParseMessageMetadata(marshalUtil *marshalutil.MarshalUtil) (result *MessageMetadata, err error) {
-	result = &MessageMetadata{}
-
-	if result.messageID, err = message.ParseID(marshalUtil); err != nil {
-		return
-	}
-	if result.receivedTime, err = marshalUtil.ReadTime(); err != nil {
-		return
-	}
-	if result.solidificationTime, err = marshalUtil.ReadTime(); err != nil {
-		return
-	}
-	if result.solid, err = marshalUtil.ReadBool(); err != nil {
-		return
-	}
-
-	return
-}
-
-// MessageMetadataFromObjectStorage unmarshals the stored bytes into a MessageMetadata.
-func MessageMetadataFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) {
-	if result, _, err = MessageMetadataFromBytes(byteutils.ConcatBytes(key, data)); err != nil {
-		return
-	}
-
-	return
-}
-
-// ReceivedTime returns the time when the message was received.
-func (messageMetadata *MessageMetadata) ReceivedTime() time.Time {
-	return messageMetadata.receivedTime
-}
-
-// IsSolid returns true if the message represented by this metadata is solid. False otherwise.
-func (messageMetadata *MessageMetadata) IsSolid() (result bool) {
-	messageMetadata.solidMutex.RLock()
-	result = messageMetadata.solid
-	messageMetadata.solidMutex.RUnlock()
-
-	return
-}
-
-// SetSolid sets the message associated with this metadata as solid.
-// It returns true if the solid status is modified. False otherwise.
-func (messageMetadata *MessageMetadata) SetSolid(solid bool) (modified bool) {
-	messageMetadata.solidMutex.RLock()
-	if messageMetadata.solid != solid {
-		messageMetadata.solidMutex.RUnlock()
-
-		messageMetadata.solidMutex.Lock()
-		if messageMetadata.solid != solid {
-			messageMetadata.solid = solid
-			if solid {
-				messageMetadata.solidificationTimeMutex.Lock()
-				messageMetadata.solidificationTime = time.Now()
-				messageMetadata.solidificationTimeMutex.Unlock()
-			}
-
-			messageMetadata.SetModified()
-
-			modified = true
-		}
-		messageMetadata.solidMutex.Unlock()
-
-	} else {
-		messageMetadata.solidMutex.RUnlock()
-	}
-
-	return
-}
-
-// SolidificationTime returns the time when the message was marked to be solid.
-func (messageMetadata *MessageMetadata) SolidificationTime() time.Time {
-	messageMetadata.solidificationTimeMutex.RLock()
-	defer messageMetadata.solidificationTimeMutex.RUnlock()
-
-	return messageMetadata.solidificationTime
-}
-
-// Bytes returns a marshaled version of the whole MessageMetadata object.
-func (messageMetadata *MessageMetadata) Bytes() []byte {
-	return byteutils.ConcatBytes(messageMetadata.ObjectStorageKey(), messageMetadata.ObjectStorageValue())
-}
-
-// ObjectStorageKey returns the key of the stored message metadata object.
-// This returns the bytes of the messageID.
-func (messageMetadata *MessageMetadata) ObjectStorageKey() []byte {
-	return messageMetadata.messageID.Bytes()
-}
-
-// ObjectStorageValue returns the value of the stored message metadata object.
-// This includes the receivedTime, solidificationTime and solid status.
-func (messageMetadata *MessageMetadata) ObjectStorageValue() []byte {
-	return marshalutil.New().
-		WriteTime(messageMetadata.ReceivedTime()).
-		WriteTime(messageMetadata.SolidificationTime()).
-		WriteBool(messageMetadata.IsSolid()).
-		Bytes()
-}
-
-// Update updates the message metadata.
-// This should never happen and will panic if attempted.
-func (messageMetadata *MessageMetadata) Update(other objectstorage.StorableObject) {
-	panic("updates disabled")
-}
-
-var _ objectstorage.StorableObject = &MessageMetadata{}
-
-// CachedMessageMetadata is a wrapper for stored cached object that represents a message metadata.
-type CachedMessageMetadata struct {
-	objectstorage.CachedObject
-}
-
-// Retain registers a new consumer for the cached message metadata.
-func (cachedMessageMetadata *CachedMessageMetadata) Retain() *CachedMessageMetadata {
-	return &CachedMessageMetadata{cachedMessageMetadata.CachedObject.Retain()}
-}
-
-// Unwrap returns the underlying stored message metadata wrapped by the CachedMessageMetadata.
-// If the stored object cannot be cast to MessageMetadata or is deleted, it returns nil.
-func (cachedMessageMetadata *CachedMessageMetadata) Unwrap() *MessageMetadata {
-	untypedObject := cachedMessageMetadata.Get()
-	if untypedObject == nil {
-		return nil
-	}
-	typedObject := untypedObject.(*MessageMetadata)
-	if typedObject == nil || typedObject.IsDeleted() {
-		return nil
-	}
-	return typedObject
-}
diff --git a/packages/binary/messagelayer/tangle/missingmessage.go b/packages/binary/messagelayer/tangle/missingmessage.go
deleted file mode 100644
index 5d691576f7a2073f2778c192aeff23d946e0f7fc..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/tangle/missingmessage.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package tangle
-
-import (
-	"time"
-
-	"github.com/iotaledger/hive.go/byteutils"
-	"github.com/iotaledger/hive.go/marshalutil"
-	"github.com/iotaledger/hive.go/objectstorage"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-)
-
-// MissingMessage represents a missing message.
-type MissingMessage struct {
-	objectstorage.StorableObjectFlags
-
-	messageID    message.ID
-	missingSince time.Time
-}
-
-// NewMissingMessage creates new missing message with the specified messageID.
-func NewMissingMessage(messageID message.ID) *MissingMessage {
-	return &MissingMessage{
-		messageID:    messageID,
-		missingSince: time.Now(),
-	}
-}
-
-// MissingMessageFromBytes parses the given bytes into a MissingMessage.
-func MissingMessageFromBytes(bytes []byte) (result *MissingMessage, consumedBytes int, err error) {
-	marshalUtil := marshalutil.New(bytes)
-	result, err = ParseMissingMessage(marshalUtil)
-	consumedBytes = marshalUtil.ReadOffset()
-	return
-}
-
-// MissingMessageFromObjectStorage creates a MissingMessage from the ObjectStorage.
-func MissingMessageFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) {
-	result, _, err = MissingMessageFromBytes(byteutils.ConcatBytes(key, data))
-
-	return
-}
-
-// ParseMissingMessage parses a MissingMessage from the given marshal util.
-func ParseMissingMessage(marshalUtil *marshalutil.MarshalUtil) (result *MissingMessage, err error) {
-	result = &MissingMessage{}
-
-	if result.messageID, err = message.ParseID(marshalUtil); err != nil {
-		return
-	}
-	if result.missingSince, err = marshalUtil.ReadTime(); err != nil {
-		return
-	}
-
-	return
-}
-
-// MessageID returns the id of the message.
-func (missingMessage *MissingMessage) MessageID() message.ID {
-	return missingMessage.messageID
-}
-
-// MissingSince returns the time since when this message is missing.
-func (missingMessage *MissingMessage) MissingSince() time.Time {
-	return missingMessage.missingSince
-}
-
-// Bytes returns a marshaled version of this MissingMessage.
-func (missingMessage *MissingMessage) Bytes() []byte {
-	return byteutils.ConcatBytes(missingMessage.ObjectStorageKey(), missingMessage.ObjectStorageValue())
-}
-
-// Update update the missing message.
-// It should never happen and will panic if called.
-func (missingMessage *MissingMessage) Update(other objectstorage.StorableObject) {
-	panic("missing messages should never be overwritten and only stored once to optimize IO")
-}
-
-// ObjectStorageKey returns the key of the stored missing message.
-// This returns the bytes of the messageID of the missing message.
-func (missingMessage *MissingMessage) ObjectStorageKey() []byte {
-	return missingMessage.messageID[:]
-}
-
-// ObjectStorageValue returns the value of the stored missing message.
-func (missingMessage *MissingMessage) ObjectStorageValue() (result []byte) {
-	result, err := missingMessage.missingSince.MarshalBinary()
-	if err != nil {
-		panic(err)
-	}
-
-	return
-}
diff --git a/packages/binary/messagelayer/tangle/storageprefixes.go b/packages/binary/messagelayer/tangle/storageprefixes.go
deleted file mode 100644
index 1e3e0ff536b87dc99f9a01d7ac15042999636623..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/tangle/storageprefixes.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package tangle
-
-const (
-	// PrefixMessage defines the storage prefix for message.
-	PrefixMessage byte = iota
-	// PrefixMessageMetadata defines the storage prefix for message metadata.
-	PrefixMessageMetadata
-	// PrefixApprovers defines the storage prefix for approvers.
-	PrefixApprovers
-	// PrefixMissingMessage defines the storage prefix for missing message.
-	PrefixMissingMessage
-)
diff --git a/packages/binary/messagelayer/tangle/tangle.go b/packages/binary/messagelayer/tangle/tangle.go
deleted file mode 100644
index 95e21f0870912c56f97e4daee749b527542cda0e..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/tangle/tangle.go
+++ /dev/null
@@ -1,375 +0,0 @@
-package tangle
-
-import (
-	"container/list"
-	"time"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/storageprefix"
-	"github.com/iotaledger/hive.go/async"
-	"github.com/iotaledger/hive.go/kvstore"
-	"github.com/iotaledger/hive.go/objectstorage"
-	"github.com/iotaledger/hive.go/types"
-)
-
-const (
-	cacheTime = 20 * time.Second
-)
-
-// Tangle represents the base layer of messages.
-type Tangle struct {
-	messageStorage         *objectstorage.ObjectStorage
-	messageMetadataStorage *objectstorage.ObjectStorage
-	approverStorage        *objectstorage.ObjectStorage
-	missingMessageStorage  *objectstorage.ObjectStorage
-
-	Events *Events
-
-	storeMessageWorkerPool async.WorkerPool
-	solidifierWorkerPool   async.WorkerPool
-	shutdown               chan struct{}
-}
-
-// New creates a new Tangle.
-func New(store kvstore.KVStore) (result *Tangle) {
-	osFactory := objectstorage.NewFactory(store, storageprefix.MessageLayer)
-
-	result = &Tangle{
-		shutdown:               make(chan struct{}),
-		messageStorage:         osFactory.New(PrefixMessage, message.FromObjectStorage, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)),
-		messageMetadataStorage: osFactory.New(PrefixMessageMetadata, MessageMetadataFromObjectStorage, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)),
-		approverStorage:        osFactory.New(PrefixApprovers, ApproverFromObjectStorage, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(message.IDLength, message.IDLength), objectstorage.LeakDetectionEnabled(false)),
-		missingMessageStorage:  osFactory.New(PrefixMissingMessage, MissingMessageFromObjectStorage, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)),
-
-		Events: newEvents(),
-	}
-
-	result.solidifierWorkerPool.Tune(1024)
-	result.storeMessageWorkerPool.Tune(1024)
-	return
-}
-
-// AttachMessage attaches a new message to the tangle.
-func (tangle *Tangle) AttachMessage(msg *message.Message) {
-	tangle.storeMessageWorkerPool.Submit(func() { tangle.storeMessageWorker(msg) })
-}
-
-// Message retrieves a message from the tangle.
-func (tangle *Tangle) Message(messageID message.ID) *message.CachedMessage {
-	return &message.CachedMessage{CachedObject: tangle.messageStorage.Load(messageID[:])}
-}
-
-// MessageMetadata retrieves the metadata of a message from the tangle.
-func (tangle *Tangle) MessageMetadata(messageID message.ID) *CachedMessageMetadata {
-	return &CachedMessageMetadata{CachedObject: tangle.messageMetadataStorage.Load(messageID[:])}
-}
-
-// Approvers retrieves the approvers of a message from the tangle.
-func (tangle *Tangle) Approvers(messageID message.ID) CachedApprovers {
-	approvers := make(CachedApprovers, 0)
-	tangle.approverStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool {
-		approvers = append(approvers, &CachedApprover{CachedObject: cachedObject})
-		return true
-	}, messageID[:])
-	return approvers
-}
-
-// DeleteMessage deletes a message and its association to approvees by un-marking the given
-// message as an approver.
-func (tangle *Tangle) DeleteMessage(messageID message.ID) {
-	tangle.Message(messageID).Consume(func(currentMsg *message.Message) {
-		parent1MsgID := currentMsg.Parent1ID()
-		tangle.deleteApprover(parent1MsgID, messageID)
-
-		parent2MsgID := currentMsg.Parent2ID()
-		if parent2MsgID != parent1MsgID {
-			tangle.deleteApprover(parent2MsgID, messageID)
-		}
-
-		tangle.messageMetadataStorage.Delete(messageID[:])
-		tangle.messageStorage.Delete(messageID[:])
-
-		tangle.Events.MessageRemoved.Trigger(messageID)
-	})
-}
-
-// DeleteMissingMessage deletes a message from the missingMessageStorage.
-func (tangle *Tangle) DeleteMissingMessage(messageID message.ID) {
-	tangle.missingMessageStorage.Delete(messageID[:])
-}
-
-// Shutdown marks the tangle as stopped, so it will not accept any new messages (waits for all backgroundTasks to finish).
-func (tangle *Tangle) Shutdown() *Tangle {
-	tangle.storeMessageWorkerPool.ShutdownGracefully()
-	tangle.solidifierWorkerPool.ShutdownGracefully()
-
-	tangle.messageStorage.Shutdown()
-	tangle.messageMetadataStorage.Shutdown()
-	tangle.approverStorage.Shutdown()
-	tangle.missingMessageStorage.Shutdown()
-	close(tangle.shutdown)
-
-	return tangle
-}
-
-// Prune resets the database and deletes all objects (good for testing or "node resets").
-func (tangle *Tangle) Prune() error {
-	for _, storage := range []*objectstorage.ObjectStorage{
-		tangle.messageStorage,
-		tangle.messageMetadataStorage,
-		tangle.approverStorage,
-		tangle.missingMessageStorage,
-	} {
-		if err := storage.Prune(); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-// DBStats returns the number of solid messages and total number of messages in the database (messageMetadataStorage,
-// that should contain the messages as messageStorage), the number of messages in missingMessageStorage, furthermore
-// the average time it takes to solidify messages.
-func (tangle *Tangle) DBStats() (solidCount int, messageCount int, avgSolidificationTime float64, missingMessageCount int) {
-	var sumSolidificationTime time.Duration
-	tangle.messageMetadataStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool {
-		cachedObject.Consume(func(object objectstorage.StorableObject) {
-			msgMetaData := object.(*MessageMetadata)
-			messageCount++
-			received := msgMetaData.ReceivedTime()
-			if msgMetaData.IsSolid() {
-				solidCount++
-				sumSolidificationTime += msgMetaData.solidificationTime.Sub(received)
-			}
-		})
-		return true
-	})
-	if solidCount > 0 {
-		avgSolidificationTime = float64(sumSolidificationTime.Milliseconds()) / float64(solidCount)
-	}
-	tangle.missingMessageStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool {
-		cachedObject.Consume(func(object objectstorage.StorableObject) {
-			missingMessageCount++
-		})
-		return true
-	})
-	return
-}
-
-// MissingMessages return the ids of messages in missingMessageStorage
-func (tangle *Tangle) MissingMessages() (ids []message.ID) {
-	tangle.missingMessageStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool {
-		cachedObject.Consume(func(object objectstorage.StorableObject) {
-			ids = append(ids, object.(*MissingMessage).messageID)
-		})
-
-		return true
-	})
-	return
-}
-
-// worker that stores the message and calls the corresponding storage events.
-func (tangle *Tangle) storeMessageWorker(msg *message.Message) {
-	// store message
-	var cachedMessage *message.CachedMessage
-	_tmp, msgIsNew := tangle.messageStorage.StoreIfAbsent(msg)
-	if !msgIsNew {
-		return
-	}
-	cachedMessage = &message.CachedMessage{CachedObject: _tmp}
-
-	// store message metadata
-	messageID := msg.ID()
-	cachedMsgMetadata := &CachedMessageMetadata{CachedObject: tangle.messageMetadataStorage.Store(NewMessageMetadata(messageID))}
-
-	// store parent1 approver
-	parent1MsgID := msg.Parent1ID()
-	tangle.approverStorage.Store(NewApprover(parent1MsgID, messageID)).Release()
-
-	// store parent2 approver
-	if parent2MsgID := msg.Parent2ID(); parent2MsgID != parent1MsgID {
-		tangle.approverStorage.Store(NewApprover(parent2MsgID, messageID)).Release()
-	}
-
-	// trigger events
-	if tangle.missingMessageStorage.DeleteIfPresent(messageID[:]) {
-		tangle.Events.MissingMessageReceived.Trigger(&CachedMessageEvent{
-			Message:         cachedMessage,
-			MessageMetadata: cachedMsgMetadata})
-	}
-
-	tangle.Events.MessageAttached.Trigger(&CachedMessageEvent{
-		Message:         cachedMessage,
-		MessageMetadata: cachedMsgMetadata})
-
-	// check message solidity
-	tangle.solidifierWorkerPool.Submit(func() {
-		tangle.checkMessageSolidityAndPropagate(cachedMessage, cachedMsgMetadata)
-	})
-}
-
-// checks whether the given message is solid and marks it as missing if it isn't known.
-func (tangle *Tangle) isMessageMarkedAsSolid(messageID message.ID) bool {
-	// return true if the message is the Genesis
-	if messageID == message.EmptyID {
-		return true
-	}
-
-	// retrieve the CachedMessageMetadata and mark it as missing if it doesn't exist
-	msgMetadataCached := &CachedMessageMetadata{tangle.messageMetadataStorage.ComputeIfAbsent(messageID.Bytes(), func(key []byte) objectstorage.StorableObject {
-		// store the missing message and trigger events
-		if cachedMissingMessage, stored := tangle.missingMessageStorage.StoreIfAbsent(NewMissingMessage(messageID)); stored {
-			cachedMissingMessage.Consume(func(object objectstorage.StorableObject) {
-				tangle.Events.MessageMissing.Trigger(messageID)
-			})
-		}
-
-		// do not initialize the metadata here, we execute this in ComputeIfAbsent to be secure from race conditions
-		return nil
-	})}
-	defer msgMetadataCached.Release()
-
-	// return false if the metadata does not exist
-	msgMetadata := msgMetadataCached.Unwrap()
-	if msgMetadata == nil {
-		return false
-	}
-
-	// return the solid flag of the metadata object
-	return msgMetadata.IsSolid()
-}
-
-// checks whether the given message is solid by examining whether its parent1 and
-// parent2 messages are solid.
-func (tangle *Tangle) isMessageSolid(msg *message.Message, msgMetadata *MessageMetadata) bool {
-	if msg == nil || msg.IsDeleted() {
-		return false
-	}
-
-	if msgMetadata == nil || msgMetadata.IsDeleted() {
-		return false
-	}
-
-	if msgMetadata.IsSolid() {
-		return true
-	}
-
-	// as missing messages are requested in isMessageMarkedAsSolid, we want to prevent short-circuit evaluation
-	parent1Solid := tangle.isMessageMarkedAsSolid(msg.Parent1ID())
-	parent2Solid := tangle.isMessageMarkedAsSolid(msg.Parent2ID())
-	return parent1Solid && parent2Solid
-}
-
-// builds up a stack from the given message and tries to solidify into the present.
-// missing messages which are needed for a message to become solid are marked as missing.
-func (tangle *Tangle) checkMessageSolidityAndPropagate(cachedMessage *message.CachedMessage, cachedMsgMetadata *CachedMessageMetadata) {
-
-	popElementsFromStack := func(stack *list.List) (*message.CachedMessage, *CachedMessageMetadata) {
-		currentSolidificationEntry := stack.Front()
-		currentCachedMsg := currentSolidificationEntry.Value.([2]interface{})[0]
-		currentCachedMsgMetadata := currentSolidificationEntry.Value.([2]interface{})[1]
-		stack.Remove(currentSolidificationEntry)
-		return currentCachedMsg.(*message.CachedMessage), currentCachedMsgMetadata.(*CachedMessageMetadata)
-	}
-
-	// initialize the stack
-	solidificationStack := list.New()
-	solidificationStack.PushBack([2]interface{}{cachedMessage, cachedMsgMetadata})
-
-	// processed messages that are supposed to be checked for solidity recursively
-	for solidificationStack.Len() > 0 {
-		currentCachedMessage, currentCachedMsgMetadata := popElementsFromStack(solidificationStack)
-
-		currentMessage := currentCachedMessage.Unwrap()
-		currentMsgMetadata := currentCachedMsgMetadata.Unwrap()
-		if currentMessage == nil || currentMsgMetadata == nil {
-			currentCachedMessage.Release()
-			currentCachedMsgMetadata.Release()
-			continue
-		}
-
-		// mark the message as solid if it has become solid
-		if tangle.isMessageSolid(currentMessage, currentMsgMetadata) && currentMsgMetadata.SetSolid(true) {
-			tangle.Events.MessageSolid.Trigger(&CachedMessageEvent{
-				Message:         currentCachedMessage,
-				MessageMetadata: currentCachedMsgMetadata})
-
-			// auto. push approvers of the newly solid message to propagate solidification
-			tangle.Approvers(currentMessage.ID()).Consume(func(approver *Approver) {
-				approverMessageID := approver.ApproverMessageID()
-				solidificationStack.PushBack([2]interface{}{
-					tangle.Message(approverMessageID),
-					tangle.MessageMetadata(approverMessageID),
-				})
-			})
-		}
-
-		currentCachedMessage.Release()
-		currentCachedMsgMetadata.Release()
-	}
-}
-
-// deletes the given approver association for the given approvee to its approver.
-func (tangle *Tangle) deleteApprover(approvedMessageID message.ID, approvingMessage message.ID) {
-	idToDelete := make([]byte, message.IDLength+message.IDLength)
-	copy(idToDelete[:message.IDLength], approvedMessageID[:])
-	copy(idToDelete[message.IDLength:], approvingMessage[:])
-	tangle.approverStorage.Delete(idToDelete)
-}
-
-// deletes a message and its future cone of messages/approvers.
-// nolint
-func (tangle *Tangle) deleteFutureCone(messageID message.ID) {
-	cleanupStack := list.New()
-	cleanupStack.PushBack(messageID)
-
-	processedMessages := make(map[message.ID]types.Empty)
-	processedMessages[messageID] = types.Void
-
-	for cleanupStack.Len() >= 1 {
-		currentStackEntry := cleanupStack.Front()
-		currentMessageID := currentStackEntry.Value.(message.ID)
-		cleanupStack.Remove(currentStackEntry)
-
-		tangle.DeleteMessage(currentMessageID)
-
-		tangle.Approvers(currentMessageID).Consume(func(approver *Approver) {
-			approverID := approver.ApproverMessageID()
-			if _, messageProcessed := processedMessages[approverID]; !messageProcessed {
-				cleanupStack.PushBack(approverID)
-				processedMessages[approverID] = types.Void
-			}
-		})
-	}
-}
-
-// SolidifierWorkerPoolStatus returns the name and the load of the workerpool.
-func (tangle *Tangle) SolidifierWorkerPoolStatus() (name string, load int) {
-	return "Solidifier", tangle.solidifierWorkerPool.RunningWorkers()
-}
-
-// StoreMessageWorkerPoolStatus returns the name and the load of the workerpool.
-func (tangle *Tangle) StoreMessageWorkerPoolStatus() (name string, load int) {
-	return "StoreMessage", tangle.storeMessageWorkerPool.RunningWorkers()
-}
-
-// RetrieveAllTips returns the tips (i.e., solid messages that are not part of the approvers list).
-// It iterates over the messageMetadataStorage, thus only use this method if necessary.
-// TODO: improve this function.
-func (tangle *Tangle) RetrieveAllTips() (tips []message.ID) {
-	tangle.messageMetadataStorage.ForEach(func(key []byte, cachedMessage objectstorage.CachedObject) bool {
-		cachedMessage.Consume(func(object objectstorage.StorableObject) {
-			messageMetadata := object.(*MessageMetadata)
-			if messageMetadata != nil && messageMetadata.IsSolid() {
-				cachedApprovers := tangle.Approvers(messageMetadata.messageID)
-				if len(cachedApprovers) == 0 {
-					tips = append(tips, messageMetadata.messageID)
-				}
-				cachedApprovers.Consume(func(approver *Approver) {})
-			}
-		})
-		return true
-	})
-	return tips
-}
diff --git a/packages/binary/messagelayer/tangle/tangle_test.go b/packages/binary/messagelayer/tangle/tangle_test.go
deleted file mode 100644
index ce3b1fddfc613322d70a227816b65790463ce64d..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/tangle/tangle_test.go
+++ /dev/null
@@ -1,240 +0,0 @@
-package tangle
-
-import (
-	"fmt"
-	"math/rand"
-	"sync"
-	"sync/atomic"
-	"testing"
-	"time"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-	"github.com/iotaledger/hive.go/crypto/ed25519"
-	"github.com/iotaledger/hive.go/datastructure/randommap"
-	"github.com/iotaledger/hive.go/events"
-	"github.com/iotaledger/hive.go/identity"
-	"github.com/iotaledger/hive.go/kvstore/mapdb"
-	"github.com/iotaledger/hive.go/testutil"
-	"github.com/magiconair/properties/assert"
-	"github.com/stretchr/testify/require"
-)
-
-func BenchmarkTangle_AttachMessage(b *testing.B) {
-	tangle := New(mapdb.NewMapDB())
-	if err := tangle.Prune(); err != nil {
-		b.Error(err)
-
-		return
-	}
-
-	messageBytes := make([]*message.Message, b.N)
-	for i := 0; i < b.N; i++ {
-		messageBytes[i] = newTestMessage("some data")
-		messageBytes[i].Bytes()
-	}
-
-	b.ResetTimer()
-
-	for i := 0; i < b.N; i++ {
-		tangle.AttachMessage(messageBytes[i])
-	}
-
-	tangle.Shutdown()
-}
-
-func TestTangle_AttachMessage(t *testing.T) {
-	messageTangle := New(mapdb.NewMapDB())
-	if err := messageTangle.Prune(); err != nil {
-		t.Error(err)
-
-		return
-	}
-
-	messageTangle.Events.MessageAttached.Attach(events.NewClosure(func(cachedMsgEvent *CachedMessageEvent) {
-		cachedMsgEvent.MessageMetadata.Release()
-
-		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
-			fmt.Println("ATTACHED:", msg.ID())
-		})
-	}))
-
-	messageTangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *CachedMessageEvent) {
-		cachedMsgEvent.MessageMetadata.Release()
-
-		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
-			fmt.Println("SOLID:", msg.ID())
-		})
-	}))
-
-	messageTangle.Events.MessageUnsolidifiable.Attach(events.NewClosure(func(messageId message.ID) {
-		fmt.Println("UNSOLIDIFIABLE:", messageId)
-	}))
-
-	messageTangle.Events.MessageMissing.Attach(events.NewClosure(func(messageId message.ID) {
-		fmt.Println("MISSING:", messageId)
-	}))
-
-	messageTangle.Events.MessageRemoved.Attach(events.NewClosure(func(messageId message.ID) {
-		fmt.Println("REMOVED:", messageId)
-	}))
-
-	newMessageOne := newTestMessage("some data")
-	newMessageTwo := newTestMessage("some other data")
-
-	messageTangle.AttachMessage(newMessageTwo)
-
-	time.Sleep(7 * time.Second)
-
-	messageTangle.AttachMessage(newMessageOne)
-
-	messageTangle.Shutdown()
-}
-
-func TestTangle_MissingMessages(t *testing.T) {
-	// test parameters
-	messageCount := 2000
-	widthOfTheTangle := 2500
-
-	// variables required for the test
-	missingMessagesMap := make(map[message.ID]bool)
-	var missingMessagesMapMutex sync.Mutex
-	wg := sync.WaitGroup{}
-
-	// create badger store
-	badgerDB, err := testutil.BadgerDB(t)
-	require.NoError(t, err)
-
-	// map to keep track of the tips
-	tips := randommap.New()
-	tips.Set(message.EmptyID, message.EmptyID)
-
-	// setup the message factory
-	msgFactory := messagefactory.New(
-		badgerDB,
-		[]byte("sequenceKey"),
-		identity.GenerateLocalIdentity(),
-		messagefactory.TipSelectorFunc(func() (message.ID, message.ID) {
-			return tips.RandomEntry().(message.ID), tips.RandomEntry().(message.ID)
-		}),
-	)
-	defer msgFactory.Shutdown()
-
-	// create a helper function that creates the messages
-	createNewMessage := func() *message.Message {
-		// issue the payload
-		msg, err := msgFactory.IssuePayload(payload.NewData([]byte("0")))
-		require.NoError(t, err)
-
-		// remove a tip if the width of the tangle is reached
-		if tips.Size() >= widthOfTheTangle {
-			if rand.Intn(1000) < 500 {
-				tips.Delete(msg.Parent2ID())
-			} else {
-				tips.Delete(msg.Parent1ID())
-			}
-		}
-
-		// add current message as a tip
-		tips.Set(msg.ID(), msg.ID())
-
-		// return the constructed message
-		return msg
-	}
-
-	// create the tangle
-	tangle := New(badgerDB)
-	if err := tangle.Prune(); err != nil {
-		t.Error(err)
-
-		return
-	}
-
-	// generate the messages we want to solidify
-	preGeneratedMessages := make(map[message.ID]*message.Message)
-	for i := 0; i < messageCount; i++ {
-		msg := createNewMessage()
-
-		preGeneratedMessages[msg.ID()] = msg
-	}
-
-	fmt.Println("PRE-GENERATING MESSAGES: DONE")
-
-	var receivedTransactionsCounter int32
-	tangle.Events.MessageAttached.Attach(events.NewClosure(func(cachedMsgEvent *CachedMessageEvent) {
-		defer cachedMsgEvent.Message.Release()
-		defer cachedMsgEvent.MessageMetadata.Release()
-
-		newReceivedTransactionsCounterValue := atomic.AddInt32(&receivedTransactionsCounter, 1)
-		if newReceivedTransactionsCounterValue%1000 == 0 {
-			fmt.Println("RECEIVED MESSAGES: ", newReceivedTransactionsCounterValue)
-			go fmt.Println("MISSING MESSAGES:", len(tangle.MissingMessages()))
-		}
-	}))
-
-	// increase the counter when a missing message was detected
-	tangle.Events.MessageMissing.Attach(events.NewClosure(func(messageId message.ID) {
-		// attach the message after it has been requested
-		go func() {
-			time.Sleep(50 * time.Millisecond)
-
-			tangle.AttachMessage(preGeneratedMessages[messageId])
-		}()
-
-		missingMessagesMapMutex.Lock()
-		missingMessagesMap[messageId] = true
-		missingMessagesMapMutex.Unlock()
-	}))
-
-	// decrease the counter when a missing message was received
-	tangle.Events.MissingMessageReceived.Attach(events.NewClosure(func(cachedMsgEvent *CachedMessageEvent) {
-		cachedMsgEvent.MessageMetadata.Release()
-		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
-			missingMessagesMapMutex.Lock()
-			delete(missingMessagesMap, msg.ID())
-			missingMessagesMapMutex.Unlock()
-		})
-	}))
-
-	// mark the WaitGroup as done if all messages are solid
-	solidMessageCounter := int32(0)
-	tangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *CachedMessageEvent) {
-		defer cachedMsgEvent.MessageMetadata.Release()
-		defer cachedMsgEvent.Message.Release()
-
-		// print progress status message
-		newSolidCounterValue := atomic.AddInt32(&solidMessageCounter, 1)
-		if newSolidCounterValue%1000 == 0 {
-			fmt.Println("SOLID MESSAGES: ", newSolidCounterValue)
-			go fmt.Println("MISSING MESSAGES:", len(tangle.MissingMessages()))
-		}
-
-		// mark WaitGroup as done when we are done solidifying everything
-		if newSolidCounterValue == int32(messageCount) {
-			fmt.Println("ALL MESSAGES SOLID")
-
-			wg.Done()
-		}
-	}))
-
-	// issue tips to start solidification
-	wg.Add(1)
-	tips.ForEach(func(key interface{}, value interface{}) {
-		tangle.AttachMessage(preGeneratedMessages[key.(message.ID)])
-	})
-
-	// wait for all transactions to become solid
-	wg.Wait()
-
-	// make sure that all MessageMissing events also had a corresponding MissingMessageReceived event
-	assert.Equal(t, len(missingMessagesMap), 0)
-	assert.Equal(t, len(tangle.MissingMessages()), 0)
-
-	// shutdown the tangle
-	tangle.Shutdown()
-}
-
-func newTestMessage(payloadString string) *message.Message {
-	return message.New(message.EmptyID, message.EmptyID, time.Now(), ed25519.PublicKey{}, 0, payload.NewData([]byte(payloadString)), 0, ed25519.Signature{})
-}
diff --git a/packages/binary/messagelayer/test/data_payload_test.go b/packages/binary/messagelayer/test/data_payload_test.go
deleted file mode 100644
index b4497fd190cb185197bbbd2b20900a7b43b59fae..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/test/data_payload_test.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package test
-
-import (
-	"runtime"
-	"sync"
-	"testing"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory"
-	"github.com/iotaledger/goshimmer/plugins/messagelayer"
-	"github.com/iotaledger/hive.go/async"
-	"github.com/iotaledger/hive.go/identity"
-	"github.com/iotaledger/hive.go/kvstore/mapdb"
-	"github.com/stretchr/testify/require"
-
-	"github.com/panjf2000/ants/v2"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-)
-
-func BenchmarkVerifyDataMessages(b *testing.B) {
-	var pool async.WorkerPool
-	pool.Tune(runtime.GOMAXPROCS(0))
-
-	factory := messagefactory.New(mapdb.NewMapDB(), []byte(messagelayer.DBSequenceNumber), identity.GenerateLocalIdentity(), messagefactory.TipSelectorFunc(func() (message.ID, message.ID) { return message.EmptyID, message.EmptyID }))
-
-	messages := make([][]byte, b.N)
-	for i := 0; i < b.N; i++ {
-		msg, err := factory.IssuePayload(payload.NewData([]byte("some data")))
-		require.NoError(b, err)
-		messages[i] = msg.Bytes()
-	}
-
-	b.ResetTimer()
-
-	for i := 0; i < b.N; i++ {
-		currentIndex := i
-		pool.Submit(func() {
-			if msg, _, err := message.FromBytes(messages[currentIndex]); err != nil {
-				b.Error(err)
-			} else {
-				msg.VerifySignature()
-			}
-		})
-	}
-
-	pool.Shutdown()
-}
-
-func BenchmarkVerifySignature(b *testing.B) {
-	pool, _ := ants.NewPool(80, ants.WithNonblocking(false))
-
-	factory := messagefactory.New(mapdb.NewMapDB(), []byte(messagelayer.DBSequenceNumber), identity.GenerateLocalIdentity(), messagefactory.TipSelectorFunc(func() (message.ID, message.ID) { return message.EmptyID, message.EmptyID }))
-
-	messages := make([]*message.Message, b.N)
-	for i := 0; i < b.N; i++ {
-		msg, err := factory.IssuePayload(payload.NewData([]byte("some data")))
-		require.NoError(b, err)
-		messages[i] = msg
-		messages[i].Bytes()
-	}
-	b.ResetTimer()
-
-	var wg sync.WaitGroup
-	for i := 0; i < b.N; i++ {
-		wg.Add(1)
-
-		currentIndex := i
-		if err := pool.Submit(func() {
-			messages[currentIndex].VerifySignature()
-			wg.Done()
-		}); err != nil {
-			b.Error(err)
-			return
-		}
-	}
-
-	wg.Wait()
-}
diff --git a/packages/binary/messagelayer/test/message_test.go b/packages/binary/messagelayer/test/message_test.go
deleted file mode 100644
index 8fd3551f5a853cdfff8e7058703389927621b204..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/test/message_test.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package test
-
-import (
-	"testing"
-	"time"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tipselector"
-	"github.com/iotaledger/goshimmer/plugins/messagelayer"
-	"github.com/iotaledger/hive.go/crypto/ed25519"
-	"github.com/iotaledger/hive.go/identity"
-	"github.com/iotaledger/hive.go/kvstore/mapdb"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-)
-
-func TestMessage_VerifySignature(t *testing.T) {
-	keyPair := ed25519.GenerateKeyPair()
-	pl := payload.NewData([]byte("test"))
-
-	unsigned := message.New(message.EmptyID, message.EmptyID, time.Time{}, keyPair.PublicKey, 0, pl, 0, ed25519.Signature{})
-	assert.False(t, unsigned.VerifySignature())
-
-	unsignedBytes := unsigned.Bytes()
-	signature := keyPair.PrivateKey.Sign(unsignedBytes[:len(unsignedBytes)-ed25519.SignatureSize])
-
-	signed := message.New(message.EmptyID, message.EmptyID, time.Time{}, keyPair.PublicKey, 0, pl, 0, signature)
-	assert.True(t, signed.VerifySignature())
-}
-
-func TestMessage_MarshalUnmarshal(t *testing.T) {
-	msgFactory := messagefactory.New(mapdb.NewMapDB(), []byte(messagelayer.DBSequenceNumber), identity.GenerateLocalIdentity(), tipselector.New())
-	defer msgFactory.Shutdown()
-
-	testMessage, err := msgFactory.IssuePayload(payload.NewData([]byte("test")))
-	require.NoError(t, err)
-	assert.Equal(t, true, testMessage.VerifySignature())
-
-	t.Log(testMessage)
-
-	restoredMessage, _, err := message.FromBytes(testMessage.Bytes())
-
-	if assert.NoError(t, err, err) {
-		assert.Equal(t, testMessage.ID(), restoredMessage.ID())
-		assert.Equal(t, testMessage.Parent1ID(), restoredMessage.Parent1ID())
-		assert.Equal(t, testMessage.Parent2ID(), restoredMessage.Parent2ID())
-		assert.Equal(t, testMessage.IssuerPublicKey(), restoredMessage.IssuerPublicKey())
-		assert.Equal(t, testMessage.IssuingTime().Round(time.Second), restoredMessage.IssuingTime().Round(time.Second))
-		assert.Equal(t, testMessage.SequenceNumber(), restoredMessage.SequenceNumber())
-		assert.Equal(t, testMessage.Nonce(), restoredMessage.Nonce())
-		assert.Equal(t, testMessage.Signature(), restoredMessage.Signature())
-		assert.Equal(t, true, restoredMessage.VerifySignature())
-	}
-}
diff --git a/packages/binary/messagelayer/test/retrievealltips_test.go b/packages/binary/messagelayer/test/retrievealltips_test.go
deleted file mode 100644
index dc6b4f1c8d8d3c588d7c6dba3aae7d0a01d0d252..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/test/retrievealltips_test.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package test
-
-import (
-	"sync"
-	"testing"
-	"time"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
-	"github.com/iotaledger/hive.go/crypto/ed25519"
-	"github.com/iotaledger/hive.go/events"
-	"github.com/iotaledger/hive.go/kvstore/mapdb"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestRetrieveAllTips(t *testing.T) {
-	messageTangle := tangle.New(mapdb.NewMapDB())
-
-	messageA := newTestMessage("A", message.EmptyID, message.EmptyID)
-	messageB := newTestMessage("B", messageA.ID(), message.EmptyID)
-	messageC := newTestMessage("C", messageA.ID(), message.EmptyID)
-
-	var wg sync.WaitGroup
-
-	messageTangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
-		cachedMsgEvent.Message.Release()
-		cachedMsgEvent.MessageMetadata.Release()
-		wg.Done()
-	}))
-
-	wg.Add(3)
-	messageTangle.AttachMessage(messageA)
-	messageTangle.AttachMessage(messageB)
-	messageTangle.AttachMessage(messageC)
-
-	wg.Wait()
-
-	allTips := messageTangle.RetrieveAllTips()
-
-	assert.Equal(t, 2, len(allTips))
-
-	messageTangle.Shutdown()
-}
-
-func newTestMessage(payloadString string, parent1, parent2 message.ID) *message.Message {
-	return message.New(parent1, parent2, time.Now(), ed25519.PublicKey{}, 0, payload.NewData([]byte(payloadString)), 0, ed25519.Signature{})
-}
diff --git a/packages/binary/messagelayer/tipselector/events.go b/packages/binary/messagelayer/tipselector/events.go
deleted file mode 100644
index 6107ed5c957d187dce6ba3660d003fc518904130..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/tipselector/events.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package tipselector
-
-import (
-	"github.com/iotaledger/hive.go/events"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-)
-
-// Events represents event happening on the tip-selector.
-type Events struct {
-	// Fired when a tip is added.
-	TipAdded *events.Event
-	// Fired when a tip is removed.
-	TipRemoved *events.Event
-}
-
-func newEvents() *Events {
-	return &Events{
-		TipAdded:   events.NewEvent(messageIDEvent),
-		TipRemoved: events.NewEvent(messageIDEvent),
-	}
-}
-
-func messageIDEvent(handler interface{}, params ...interface{}) {
-	handler.(func(message.ID))(params[0].(message.ID))
-}
diff --git a/packages/binary/messagelayer/tipselector/tipselector.go b/packages/binary/messagelayer/tipselector/tipselector.go
deleted file mode 100644
index 04d11300049abfed885bf8c3f5c40bef71a98906..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/tipselector/tipselector.go
+++ /dev/null
@@ -1,81 +0,0 @@
-package tipselector
-
-import (
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/hive.go/datastructure/randommap"
-)
-
-// TipSelector manages a map of tips and emits events for their removal and addition.
-type TipSelector struct {
-	tips   *randommap.RandomMap
-	Events *Events
-}
-
-// New creates a new tip-selector.
-func New(tips ...message.ID) *TipSelector {
-	tipSelector := &TipSelector{
-		tips:   randommap.New(),
-		Events: newEvents(),
-	}
-
-	if tips != nil {
-		tipSelector.Set(tips...)
-	}
-
-	return tipSelector
-}
-
-// Set adds the given messageIDs as tips.
-func (tipSelector *TipSelector) Set(tips ...message.ID) {
-	for _, messageID := range tips {
-		tipSelector.tips.Set(messageID, messageID)
-	}
-}
-
-// AddTip adds the given message as a tip.
-func (tipSelector *TipSelector) AddTip(msg *message.Message) {
-	messageID := msg.ID()
-	if tipSelector.tips.Set(messageID, messageID) {
-		tipSelector.Events.TipAdded.Trigger(messageID)
-	}
-
-	parent1MessageID := msg.Parent1ID()
-	if _, deleted := tipSelector.tips.Delete(parent1MessageID); deleted {
-		tipSelector.Events.TipRemoved.Trigger(parent1MessageID)
-	}
-
-	parent2MessageID := msg.Parent2ID()
-	if _, deleted := tipSelector.tips.Delete(parent2MessageID); deleted {
-		tipSelector.Events.TipRemoved.Trigger(parent2MessageID)
-	}
-}
-
-// Tips returns two tips.
-func (tipSelector *TipSelector) Tips() (parent1MessageID, parent2MessageID message.ID) {
-	tip := tipSelector.tips.RandomEntry()
-	if tip == nil {
-		parent1MessageID = message.EmptyID
-		parent2MessageID = message.EmptyID
-
-		return
-	}
-
-	parent2MessageID = tip.(message.ID)
-
-	if tipSelector.tips.Size() == 1 {
-		parent1MessageID = parent2MessageID
-		return
-	}
-
-	parent1MessageID = tipSelector.tips.RandomEntry().(message.ID)
-	for parent1MessageID == parent2MessageID && tipSelector.tips.Size() > 1 {
-		parent1MessageID = tipSelector.tips.RandomEntry().(message.ID)
-	}
-
-	return
-}
-
-// TipCount the amount of current tips.
-func (tipSelector *TipSelector) TipCount() int {
-	return tipSelector.tips.Size()
-}
diff --git a/packages/binary/messagelayer/tipselector/tipselector_test.go b/packages/binary/messagelayer/tipselector/tipselector_test.go
deleted file mode 100644
index 64c8e85b3ef6b4f0de7af606c941f44bb3a92d0c..0000000000000000000000000000000000000000
--- a/packages/binary/messagelayer/tipselector/tipselector_test.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package tipselector
-
-import (
-	"testing"
-	"time"
-
-	"github.com/iotaledger/hive.go/crypto/ed25519"
-	"github.com/stretchr/testify/assert"
-
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
-)
-
-func Test(t *testing.T) {
-	// create tip selector
-	tipSelector := New()
-
-	// check if first tips point to genesis
-	parent11, parent21 := tipSelector.Tips()
-	assert.Equal(t, message.EmptyID, parent11)
-	assert.Equal(t, message.EmptyID, parent21)
-
-	// create a message and attach it
-	message1 := newTestMessage(parent11, parent21, "testmessage1")
-	tipSelector.AddTip(message1)
-
-	// check if the tip shows up in the tip count
-	assert.Equal(t, 1, tipSelector.TipCount())
-
-	// check if next tips point to our first message
-	parent12, parent22 := tipSelector.Tips()
-	assert.Equal(t, message1.ID(), parent12)
-	assert.Equal(t, message1.ID(), parent22)
-
-	// create a 2nd message and attach it
-	message2 := newTestMessage(message.EmptyID, message.EmptyID, "testmessage2")
-	tipSelector.AddTip(message2)
-
-	// check if the tip shows up in the tip count
-	assert.Equal(t, 2, tipSelector.TipCount())
-
-	// attach a message to our two tips
-	parent13, parent23 := tipSelector.Tips()
-	message3 := newTestMessage(parent13, parent23, "testmessage3")
-	tipSelector.AddTip(message3)
-
-	// check if the tip shows replaces the current tips
-	parent14, parent24 := tipSelector.Tips()
-	assert.Equal(t, 1, tipSelector.TipCount())
-	assert.Equal(t, message3.ID(), parent14)
-	assert.Equal(t, message3.ID(), parent24)
-}
-
-func newTestMessage(parent1, parent2 message.ID, payloadString string) *message.Message {
-	return message.New(parent1, parent2, time.Now(), ed25519.PublicKey{}, 0, payload.NewData([]byte(payloadString)), 0, ed25519.Signature{})
-}
diff --git a/packages/binary/spammer/spammer.go b/packages/binary/spammer/spammer.go
index 259ba8fe0abd2d18e32efae1f2ff2082c554b9e0..42f333e35c0e129df59cccbc4a6ea41fdcfea5ac 100644
--- a/packages/binary/spammer/spammer.go
+++ b/packages/binary/spammer/spammer.go
@@ -6,12 +6,11 @@ import (
 
 	"github.com/iotaledger/hive.go/types"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 )
 
 // IssuePayloadFunc is a function which issues a payload.
-type IssuePayloadFunc = func(payload payload.Payload) (*message.Message, error)
+type IssuePayloadFunc = func(payload tangle.Payload) (*tangle.Message, error)
 
 // Spammer spams messages with a static data payload.
 type Spammer struct {
@@ -49,7 +48,7 @@ func (spammer *Spammer) run(rate int, timeUnit time.Duration, processID int64) {
 		}
 
 		// we don't care about errors or the actual issued message
-		_, _ = spammer.issuePayloadFunc(payload.NewData([]byte("SPAM")))
+		_, _ = spammer.issuePayloadFunc(tangle.NewDataPayload([]byte("SPAM")))
 
 		currentSentCounter++
 
diff --git a/packages/gossip/manager.go b/packages/gossip/manager.go
index 2e4e84361b7cf29b3064c6228b7c5ca17a44b64e..4244ccd33233524553c8492faf4ff2b392a5d61a 100644
--- a/packages/gossip/manager.go
+++ b/packages/gossip/manager.go
@@ -6,9 +6,9 @@ import (
 	"runtime"
 	"sync"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
 	pb "github.com/iotaledger/goshimmer/packages/gossip/proto"
 	"github.com/iotaledger/goshimmer/packages/gossip/server"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/hive.go/autopeering/peer"
 	"github.com/iotaledger/hive.go/events"
 	"github.com/iotaledger/hive.go/identity"
@@ -31,7 +31,7 @@ var (
 )
 
 // LoadMessageFunc defines a function that returns the message for the given id.
-type LoadMessageFunc func(messageId message.ID) ([]byte, error)
+type LoadMessageFunc func(messageId tangle.MessageID) ([]byte, error)
 
 // The Manager handles the connected neighbors.
 type Manager struct {
@@ -317,7 +317,7 @@ func (m *Manager) processMessageRequest(data []byte, nbr *Neighbor) {
 		m.log.Debugw("invalid packet", "err", err)
 	}
 
-	msgID, _, err := message.IDFromBytes(packet.GetId())
+	msgID, _, err := tangle.MessageIDFromBytes(packet.GetId())
 	if err != nil {
 		m.log.Debugw("invalid message id:", "err", err)
 	}
diff --git a/packages/gossip/manager_test.go b/packages/gossip/manager_test.go
index be3b18289e64a17bb0fc6df67af7a2b1393cebdb..4af118d46a353af8726f0d98a7b2f7b7ce55b33f 100644
--- a/packages/gossip/manager_test.go
+++ b/packages/gossip/manager_test.go
@@ -6,9 +6,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
 	pb "github.com/iotaledger/goshimmer/packages/gossip/proto"
 	"github.com/iotaledger/goshimmer/packages/gossip/server"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/hive.go/autopeering/peer"
 	"github.com/iotaledger/hive.go/autopeering/peer/service"
 	"github.com/iotaledger/hive.go/events"
@@ -27,7 +27,7 @@ var (
 	testMessageData = []byte("testMsg")
 )
 
-func loadTestMessage(message.ID) ([]byte, error) { return testMessageData, nil }
+func loadTestMessage(tangle.MessageID) ([]byte, error) { return testMessageData, nil }
 
 func TestClose(t *testing.T) {
 	_, teardown, _ := newMockedManager(t, "A")
@@ -336,7 +336,7 @@ func TestMessageRequest(t *testing.T) {
 	// wait for the connections to establish
 	wg.Wait()
 
-	id := message.ID{}
+	id := tangle.MessageID{}
 
 	// mgrA should eventually receive the message
 	mgrA.On("messageReceived", &MessageReceivedEvent{Data: testMessageData, Peer: peerB}).Once()
diff --git a/packages/tangle/message_test.go b/packages/tangle/message_test.go
index afb737e8950ee3875b528ca84a648cd142b7f6c3..c7f5e08a88a092c4e105299592d06c2270d501cf 100644
--- a/packages/tangle/message_test.go
+++ b/packages/tangle/message_test.go
@@ -4,7 +4,6 @@ import (
 	"testing"
 	"time"
 
-	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/hive.go/crypto/ed25519"
 	"github.com/iotaledger/hive.go/identity"
 	"github.com/iotaledger/hive.go/kvstore/mapdb"
@@ -27,7 +26,7 @@ func TestMessage_VerifySignature(t *testing.T) {
 }
 
 func TestMessage_MarshalUnmarshal(t *testing.T) {
-	msgFactory := NewMessageFactory(mapdb.NewMapDB(), []byte(messagelayer.DBSequenceNumber), identity.GenerateLocalIdentity(), NewMessageTipSelector())
+	msgFactory := NewMessageFactory(mapdb.NewMapDB(), []byte(DBSequenceNumber), identity.GenerateLocalIdentity(), NewMessageTipSelector())
 	defer msgFactory.Shutdown()
 
 	testMessage, err := msgFactory.IssuePayload(NewDataPayload([]byte("test")))
diff --git a/packages/tangle/payload_test.go b/packages/tangle/payload_test.go
index 67c5fa5598380572da183acdae8721eb283135b4..92512835a58ca46d87335b11896a8eeefa1b2631 100644
--- a/packages/tangle/payload_test.go
+++ b/packages/tangle/payload_test.go
@@ -5,7 +5,6 @@ import (
 	"sync"
 	"testing"
 
-	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/hive.go/async"
 	"github.com/iotaledger/hive.go/identity"
 	"github.com/iotaledger/hive.go/kvstore/mapdb"
@@ -18,7 +17,7 @@ func BenchmarkVerifyDataMessages(b *testing.B) {
 	var pool async.WorkerPool
 	pool.Tune(runtime.GOMAXPROCS(0))
 
-	factory := NewMessageFactory(mapdb.NewMapDB(), []byte(messagelayer.DBSequenceNumber), identity.GenerateLocalIdentity(), TipSelectorFunc(func() (MessageID, MessageID) { return EmptyMessageID, EmptyMessageID }))
+	factory := NewMessageFactory(mapdb.NewMapDB(), []byte(DBSequenceNumber), identity.GenerateLocalIdentity(), TipSelectorFunc(func() (MessageID, MessageID) { return EmptyMessageID, EmptyMessageID }))
 
 	messages := make([][]byte, b.N)
 	for i := 0; i < b.N; i++ {
@@ -46,7 +45,7 @@ func BenchmarkVerifyDataMessages(b *testing.B) {
 func BenchmarkVerifySignature(b *testing.B) {
 	pool, _ := ants.NewPool(80, ants.WithNonblocking(false))
 
-	factory := NewMessageFactory(mapdb.NewMapDB(), []byte(messagelayer.DBSequenceNumber), identity.GenerateLocalIdentity(), TipSelectorFunc(func() (MessageID, MessageID) { return EmptyMessageID, EmptyMessageID }))
+	factory := NewMessageFactory(mapdb.NewMapDB(), []byte(DBSequenceNumber), identity.GenerateLocalIdentity(), TipSelectorFunc(func() (MessageID, MessageID) { return EmptyMessageID, EmptyMessageID }))
 
 	messages := make([]*Message, b.N)
 	for i := 0; i < b.N; i++ {
diff --git a/packages/tangle/tangle.go b/packages/tangle/tangle.go
index 3d8d33296fdaceadf949b9f282ce2cf4f6759b09..20543e0a371a5ada0ddd5cd4e92eebb335af98cc 100644
--- a/packages/tangle/tangle.go
+++ b/packages/tangle/tangle.go
@@ -23,6 +23,9 @@ const (
 	PrefixMissingMessage
 
 	cacheTime = 20 * time.Second
+
+	// DBSequenceNumber defines the db sequence number.
+	DBSequenceNumber = "seq"
 )
 
 // Tangle represents the base layer of messages.
diff --git a/plugins/dashboard/explorer_routes.go b/plugins/dashboard/explorer_routes.go
index 5664dd87412b78e86ffbafd4bdc354c40db9d800..6e0887a5fe409ed8381560c827d78b80aa08a6ce 100644
--- a/plugins/dashboard/explorer_routes.go
+++ b/plugins/dashboard/explorer_routes.go
@@ -6,8 +6,8 @@ import (
 
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address"
-	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
+	valuetangle "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/goshimmer/plugins/webapi/value/utils"
 	"github.com/labstack/echo"
@@ -40,7 +40,7 @@ type ExplorerMessage struct {
 	Payload interface{} `json:"payload"`
 }
 
-func createExplorerMessage(msg *message.Message) (*ExplorerMessage, error) {
+func createExplorerMessage(msg *tangle.Message) (*ExplorerMessage, error) {
 	messageID := msg.ID()
 	cachedMessageMetadata := messagelayer.Tangle().MessageMetadata(messageID)
 	defer cachedMessageMetadata.Release()
@@ -87,7 +87,7 @@ type SearchResult struct {
 
 func setupExplorerRoutes(routeGroup *echo.Group) {
 	routeGroup.GET("/message/:id", func(c echo.Context) (err error) {
-		messageID, err := message.NewID(c.Param("id"))
+		messageID, err := tangle.NewMessageID(c.Param("id"))
 		if err != nil {
 			return
 		}
@@ -125,8 +125,8 @@ func setupExplorerRoutes(routeGroup *echo.Group) {
 				result.Address = addr
 			}
 
-		case message.IDLength:
-			messageID, err := message.NewID(search)
+		case tangle.MessageIDLength:
+			messageID, err := tangle.NewMessageID(search)
 			if err != nil {
 				return fmt.Errorf("%w: search ID %s", ErrInvalidParameter, search)
 			}
@@ -144,8 +144,8 @@ func setupExplorerRoutes(routeGroup *echo.Group) {
 	})
 }
 
-func findMessage(messageID message.ID) (explorerMsg *ExplorerMessage, err error) {
-	if !messagelayer.Tangle().Message(messageID).Consume(func(msg *message.Message) {
+func findMessage(messageID tangle.MessageID) (explorerMsg *ExplorerMessage, err error) {
+	if !messagelayer.Tangle().Message(messageID).Consume(func(msg *tangle.Message) {
 		explorerMsg, err = createExplorerMessage(msg)
 	}) {
 		err = fmt.Errorf("%w: message %s", ErrNotFound, messageID.String())
@@ -167,7 +167,7 @@ func findAddress(strAddress string) (*ExplorerAddress, error) {
 	// get outputids by address
 	for id, cachedOutput := range valuetransfers.Tangle().OutputsOnAddress(address) {
 
-		cachedOutput.Consume(func(output *tangle.Output) {
+		cachedOutput.Consume(func(output *valuetangle.Output) {
 
 			// iterate balances
 			var b []utils.Balance
@@ -178,7 +178,7 @@ func findAddress(strAddress string) (*ExplorerAddress, error) {
 				})
 			}
 			var solidificationTime int64
-			if !valuetransfers.Tangle().TransactionMetadata(output.TransactionID()).Consume(func(txMeta *tangle.TransactionMetadata) {
+			if !valuetransfers.Tangle().TransactionMetadata(output.TransactionID()).Consume(func(txMeta *valuetangle.TransactionMetadata) {
 				inclusionState.Confirmed = txMeta.Confirmed()
 				inclusionState.Liked = txMeta.Liked()
 				inclusionState.Rejected = txMeta.Rejected()
diff --git a/plugins/dashboard/livefeed.go b/plugins/dashboard/livefeed.go
index 95bf6c5452a336357d9357da193e16616c2a29aa..b7b0ea30d3e7ad92d8a8acb29de5afaf3db26e7f 100644
--- a/plugins/dashboard/livefeed.go
+++ b/plugins/dashboard/livefeed.go
@@ -3,9 +3,8 @@ package dashboard
 import (
 	"time"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/hive.go/daemon"
 	"github.com/iotaledger/hive.go/events"
@@ -18,7 +17,7 @@ var liveFeedWorkerPool *workerpool.WorkerPool
 
 func configureLiveFeed() {
 	liveFeedWorkerPool = workerpool.New(func(task workerpool.Task) {
-		task.Param(0).(*message.CachedMessage).Consume(func(message *message.Message) {
+		task.Param(0).(*tangle.CachedMessage).Consume(func(message *tangle.Message) {
 			broadcastWsMessage(&wsmsg{MsgTypeMessage, &msg{message.ID().String(), 0}})
 		})
 
diff --git a/plugins/dashboard/payload_handler.go b/plugins/dashboard/payload_handler.go
index e7808408f11eea570a18515e3982dda8f3910037..ca69d6bc8c30c30af60a678d7e4f3a657d4631bb 100644
--- a/plugins/dashboard/payload_handler.go
+++ b/plugins/dashboard/payload_handler.go
@@ -8,7 +8,7 @@ import (
 	drngpayload "github.com/iotaledger/goshimmer/packages/binary/drng/payload"
 	drngheader "github.com/iotaledger/goshimmer/packages/binary/drng/payload/header"
 	cb "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectivebeacon/payload"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	syncbeaconpayload "github.com/iotaledger/goshimmer/plugins/syncbeacon/payload"
 	"github.com/iotaledger/hive.go/marshalutil"
 )
@@ -77,13 +77,13 @@ type Balance struct {
 
 // ProcessPayload returns different structs regarding to the
 // payload type.
-func ProcessPayload(p payload.Payload) interface{} {
+func ProcessPayload(p tangle.Payload) interface{} {
 	switch p.Type() {
-	case payload.DataType:
+	case tangle.DataType:
 		// data payload
 		return BasicPayload{
 			ContentTitle: "Data",
-			Content:      p.(*payload.Data).Data(),
+			Content:      p.(*tangle.DataPayload).Data(),
 		}
 	case faucetpayload.Type:
 		// faucet payload
@@ -109,7 +109,7 @@ func ProcessPayload(p payload.Payload) interface{} {
 }
 
 // processDrngPayload handles the subtypes of Drng payload
-func processDrngPayload(p payload.Payload) (dp DrngPayload) {
+func processDrngPayload(p tangle.Payload) (dp DrngPayload) {
 	var subpayload interface{}
 	marshalUtil := marshalutil.New(p.Bytes())
 	drngPayload, _ := drngpayload.Parse(marshalUtil)
@@ -139,7 +139,7 @@ func processDrngPayload(p payload.Payload) (dp DrngPayload) {
 }
 
 // processDrngPayload handles the subtypes of Drng payload
-func processSyncBeaconPayload(p payload.Payload) (dp SyncBeaconPayload) {
+func processSyncBeaconPayload(p tangle.Payload) (dp SyncBeaconPayload) {
 	syncBeaconPayload, ok := p.(*syncbeaconpayload.Payload)
 	if !ok {
 		log.Info("could not cast payload to sync beacon object")
@@ -152,7 +152,7 @@ func processSyncBeaconPayload(p payload.Payload) (dp SyncBeaconPayload) {
 }
 
 // processValuePayload handles Value payload
-func processValuePayload(p payload.Payload) (vp ValuePayload) {
+func processValuePayload(p tangle.Payload) (vp ValuePayload) {
 	marshalUtil := marshalutil.New(p.Bytes())
 	v, _ := valuepayload.Parse(marshalUtil)
 
diff --git a/plugins/dashboard/visualizer.go b/plugins/dashboard/visualizer.go
index 271e8020522fd82aa2b197fe22babeb4edc93930..d33e669cfecee2f131c360aefad4b4c92b46a0ea 100644
--- a/plugins/dashboard/visualizer.go
+++ b/plugins/dashboard/visualizer.go
@@ -1,9 +1,8 @@
 package dashboard
 
 import (
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/hive.go/daemon"
 	"github.com/iotaledger/hive.go/events"
@@ -34,9 +33,9 @@ func configureVisualizer() {
 	visualizerWorkerPool = workerpool.New(func(task workerpool.Task) {
 
 		switch x := task.Param(0).(type) {
-		case *message.CachedMessage:
+		case *tangle.CachedMessage:
 			sendVertex(x, task.Param(1).(*tangle.CachedMessageMetadata))
-		case message.ID:
+		case tangle.MessageID:
 			sendTipInfo(x, task.Param(1).(bool))
 		}
 
@@ -44,7 +43,7 @@ func configureVisualizer() {
 	}, workerpool.WorkerCount(visualizerWorkerCount), workerpool.QueueSize(visualizerWorkerQueueSize))
 }
 
-func sendVertex(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
+func sendVertex(cachedMessage *tangle.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
 	defer cachedMessage.Release()
 	defer cachedMessageMetadata.Release()
 
@@ -60,7 +59,7 @@ func sendVertex(cachedMessage *message.CachedMessage, cachedMessageMetadata *tan
 	}}, true)
 }
 
-func sendTipInfo(messageID message.ID, isTip bool) {
+func sendTipInfo(messageID tangle.MessageID, isTip bool) {
 	broadcastWsMessage(&wsmsg{MsgTypeTipInfo, &tipinfo{
 		ID:    messageID.String(),
 		IsTip: isTip,
@@ -78,11 +77,11 @@ func runVisualizer() {
 		}
 	})
 
-	notifyNewTip := events.NewClosure(func(messageId message.ID) {
+	notifyNewTip := events.NewClosure(func(messageId tangle.MessageID) {
 		visualizerWorkerPool.TrySubmit(messageId, true)
 	})
 
-	notifyDeletedTip := events.NewClosure(func(messageId message.ID) {
+	notifyDeletedTip := events.NewClosure(func(messageId tangle.MessageID) {
 		visualizerWorkerPool.TrySubmit(messageId, false)
 	})
 
diff --git a/plugins/drng/plugin.go b/plugins/drng/plugin.go
index add3f3583824db43146bea1335ae10edaf02fc85..f23131db8dfd878571a2f6d93bc423b015f5bbdb 100644
--- a/plugins/drng/plugin.go
+++ b/plugins/drng/plugin.go
@@ -6,8 +6,7 @@ import (
 	"github.com/iotaledger/goshimmer/packages/binary/drng"
 	"github.com/iotaledger/goshimmer/packages/binary/drng/payload"
 	"github.com/iotaledger/goshimmer/packages/binary/drng/payload/header"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/hive.go/events"
 	"github.com/iotaledger/hive.go/logger"
@@ -46,7 +45,7 @@ func configureEvents() {
 	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
 		cachedMsgEvent.MessageMetadata.Release()
 
-		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
+		cachedMsgEvent.Message.Consume(func(msg *tangle.Message) {
 			if msg.Payload().Type() != payload.Type {
 				return
 			}
diff --git a/plugins/gossip/gossip.go b/plugins/gossip/gossip.go
index 416acde34dffdfa405e32b5f789930039c4b28b6..300efc999a76783cee776c937902f9c9696a1667 100644
--- a/plugins/gossip/gossip.go
+++ b/plugins/gossip/gossip.go
@@ -6,9 +6,9 @@ import (
 	"strconv"
 	"sync"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
 	"github.com/iotaledger/goshimmer/packages/gossip"
 	"github.com/iotaledger/goshimmer/packages/gossip/server"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/autopeering"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/local"
 	"github.com/iotaledger/goshimmer/plugins/config"
@@ -91,7 +91,7 @@ func start(shutdownSignal <-chan struct{}) {
 }
 
 // loads the given message from the message layer and returns it or an error if not found.
-func loadMessage(msgID message.ID) ([]byte, error) {
+func loadMessage(msgID tangle.MessageID) ([]byte, error) {
 	cachedMessage := messagelayer.Tangle().Message(msgID)
 	defer cachedMessage.Release()
 	if !cachedMessage.Exists() {
diff --git a/plugins/gossip/plugin.go b/plugins/gossip/plugin.go
index dff277855685d020aaa16fbc584f8cc5a7e1eed6..2bd6423d61d58bd5ddf2a881bb4d26b56dd267d3 100644
--- a/plugins/gossip/plugin.go
+++ b/plugins/gossip/plugin.go
@@ -4,10 +4,9 @@ import (
 	"sync"
 	"time"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagerequester"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
 	"github.com/iotaledger/goshimmer/packages/gossip"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/autopeering"
 	"github.com/iotaledger/goshimmer/plugins/config"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
@@ -143,7 +142,7 @@ func configureMessageLayer() {
 	}))
 
 	// request missing messages
-	messagelayer.MessageRequester().Events.SendRequest.Attach(events.NewClosure(func(sendRequest *messagerequester.SendRequestEvent) {
+	messagelayer.MessageRequester().Events.SendRequest.Attach(events.NewClosure(func(sendRequest *tangle.SendRequestEvent) {
 		mgr.RequestMessage(sendRequest.ID[:])
 	}))
 }
diff --git a/plugins/gossip/tips_broadcaster.go b/plugins/gossip/tips_broadcaster.go
index fb93099852f083f73ccd27562e9f7a027ef29ef4..529662fc565181c530c5afcf80008233b1cf804f 100644
--- a/plugins/gossip/tips_broadcaster.go
+++ b/plugins/gossip/tips_broadcaster.go
@@ -4,7 +4,7 @@ import (
 	"container/list"
 	"sync"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/hive.go/events"
 	"github.com/iotaledger/hive.go/timeutil"
@@ -15,17 +15,17 @@ const (
 	tipsBroadcasterName = PluginName + "[TipsBroadcaster]"
 )
 
-var tips = tiplist{dict: make(map[message.ID]*list.Element)}
+var tips = tiplist{dict: make(map[tangle.MessageID]*list.Element)}
 
 type tiplist struct {
 	mu sync.Mutex
 
-	dict     map[message.ID]*list.Element
+	dict     map[tangle.MessageID]*list.Element
 	list     list.List
 	iterator *list.Element
 }
 
-func (s *tiplist) AddTip(id message.ID) {
+func (s *tiplist) AddTip(id tangle.MessageID) {
 	s.mu.Lock()
 	defer s.mu.Unlock()
 
@@ -39,7 +39,7 @@ func (s *tiplist) AddTip(id message.ID) {
 	}
 }
 
-func (s *tiplist) RemoveTip(id message.ID) {
+func (s *tiplist) RemoveTip(id tangle.MessageID) {
 	s.mu.Lock()
 	defer s.mu.Unlock()
 
@@ -54,14 +54,14 @@ func (s *tiplist) RemoveTip(id message.ID) {
 	}
 }
 
-func (s *tiplist) Next() message.ID {
+func (s *tiplist) Next() tangle.MessageID {
 	s.mu.Lock()
 	defer s.mu.Unlock()
 
 	if s.iterator == nil {
-		return message.EmptyID
+		return tangle.EmptyMessageID
 	}
-	id := s.iterator.Value.(message.ID)
+	id := s.iterator.Value.(tangle.MessageID)
 	s.next(s.iterator)
 	return id
 }
@@ -94,14 +94,14 @@ func startTipBroadcaster(shutdownSignal <-chan struct{}) {
 // broadcasts the next oldest tip from the tip pool to all connected neighbors.
 func broadcastNextOldestTip() {
 	msgID := tips.Next()
-	if msgID == message.EmptyID {
+	if msgID == tangle.EmptyMessageID {
 		return
 	}
 	broadcastMessage(msgID)
 }
 
 // broadcasts the given message to all neighbors if it exists.
-func broadcastMessage(msgID message.ID) {
+func broadcastMessage(msgID tangle.MessageID) {
 	msgBytes, err := loadMessage(msgID)
 	if err != nil {
 		return
diff --git a/plugins/issuer/plugin.go b/plugins/issuer/plugin.go
index 11c01ec60114f620503053d5d6b28404a0ea3389..2d75f13ba9551d1278f0d202da7cbed85d30712b 100644
--- a/plugins/issuer/plugin.go
+++ b/plugins/issuer/plugin.go
@@ -4,8 +4,7 @@ import (
 	"fmt"
 	goSync "sync"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/goshimmer/plugins/syncbeaconfollower"
 	"github.com/iotaledger/hive.go/node"
@@ -32,7 +31,7 @@ func configure(_ *node.Plugin) {}
 
 // IssuePayload issues a payload to the message layer.
 // If the node is not synchronized an error is returned.
-func IssuePayload(payload payload.Payload) (*message.Message, error) {
+func IssuePayload(payload tangle.Payload) (*tangle.Message, error) {
 	if !syncbeaconfollower.Synced() {
 		return nil, fmt.Errorf("can't issue payload: %w", syncbeaconfollower.ErrNodeNotSynchronized)
 	}
diff --git a/plugins/messagelayer/plugin.go b/plugins/messagelayer/plugin.go
index 571836bced7ec49ea45f6768309a3afa0691d13e..b7972915a2802511e948abd2c89330c9c32b90d4 100644
--- a/plugins/messagelayer/plugin.go
+++ b/plugins/messagelayer/plugin.go
@@ -3,13 +3,8 @@ package messagelayer
 import (
 	"sync"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagerequester"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tipselector"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/local"
 	"github.com/iotaledger/goshimmer/plugins/database"
 	"github.com/iotaledger/hive.go/daemon"
@@ -21,23 +16,21 @@ import (
 const (
 	// PluginName defines the plugin name.
 	PluginName = "MessageLayer"
-	// DBSequenceNumber defines the db sequence number.
-	DBSequenceNumber = "seq"
 )
 
 var (
 	// plugin is the plugin instance of the message layer plugin.
 	plugin           *node.Plugin
 	pluginOnce       sync.Once
-	messageParser    *messageparser.MessageParser
+	messageParser    *tangle.MessageParser
 	msgParserOnce    sync.Once
-	messageRequester *messagerequester.MessageRequester
+	messageRequester *tangle.MessageRequester
 	msgReqOnce       sync.Once
-	tipSelector      *tipselector.TipSelector
+	tipSelector      *tangle.MessageTipSelector
 	tipSelectorOnce  sync.Once
 	_tangle          *tangle.Tangle
 	tangleOnce       sync.Once
-	messageFactory   *messagefactory.MessageFactory
+	messageFactory   *tangle.MessageFactory
 	msgFactoryOnce   sync.Once
 	log              *logger.Logger
 )
@@ -51,17 +44,17 @@ func Plugin() *node.Plugin {
 }
 
 // MessageParser gets the messageParser instance.
-func MessageParser() *messageparser.MessageParser {
+func MessageParser() *tangle.MessageParser {
 	msgParserOnce.Do(func() {
-		messageParser = messageparser.New()
+		messageParser = tangle.NewMessageParser()
 	})
 	return messageParser
 }
 
 // TipSelector gets the tipSelector instance.
-func TipSelector() *tipselector.TipSelector {
+func TipSelector() *tangle.MessageTipSelector {
 	tipSelectorOnce.Do(func() {
-		tipSelector = tipselector.New()
+		tipSelector = tangle.NewMessageTipSelector()
 	})
 	return tipSelector
 }
@@ -76,18 +69,18 @@ func Tangle() *tangle.Tangle {
 }
 
 // MessageFactory gets the messageFactory instance.
-func MessageFactory() *messagefactory.MessageFactory {
+func MessageFactory() *tangle.MessageFactory {
 	msgFactoryOnce.Do(func() {
-		messageFactory = messagefactory.New(database.Store(), []byte(DBSequenceNumber), local.GetInstance().LocalIdentity(), TipSelector())
+		messageFactory = tangle.NewMessageFactory(database.Store(), []byte(tangle.DBSequenceNumber), local.GetInstance().LocalIdentity(), TipSelector())
 	})
 	return messageFactory
 }
 
 // MessageRequester gets the messageRequester instance.
-func MessageRequester() *messagerequester.MessageRequester {
+func MessageRequester() *tangle.MessageRequester {
 	msgReqOnce.Do(func() {
 		// load all missing messages on start up
-		messageRequester = messagerequester.New(Tangle().MissingMessages())
+		messageRequester = tangle.NewMessageRequester(Tangle().MissingMessages())
 	})
 	return messageRequester
 }
@@ -109,7 +102,7 @@ func configure(*node.Plugin) {
 	}))
 
 	// setup messageParser
-	messageParser.Events.MessageParsed.Attach(events.NewClosure(func(msgParsedEvent *messageparser.MessageParsedEvent) {
+	messageParser.Events.MessageParsed.Attach(events.NewClosure(func(msgParsedEvent *tangle.MessageParsedEvent) {
 		// TODO: ADD PEER
 		_tangle.AttachMessage(msgParsedEvent.Message)
 	}))
@@ -118,7 +111,7 @@ func configure(*node.Plugin) {
 	_tangle.Events.MessageMissing.Attach(events.NewClosure(messageRequester.StartRequest))
 	_tangle.Events.MissingMessageReceived.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
 		cachedMsgEvent.MessageMetadata.Release()
-		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
+		cachedMsgEvent.Message.Consume(func(msg *tangle.Message) {
 			messageRequester.StopRequest(msg.ID())
 		})
 	}))
@@ -129,7 +122,7 @@ func configure(*node.Plugin) {
 		cachedMsgEvent.Message.Consume(tipSelector.AddTip)
 	}))
 
-	MessageRequester().Events.MissingMessageAppeared.Attach(events.NewClosure(func(missingMessageAppeared *messagerequester.MissingMessageAppearedEvent) {
+	MessageRequester().Events.MissingMessageAppeared.Attach(events.NewClosure(func(missingMessageAppeared *tangle.MissingMessageAppearedEvent) {
 		_tangle.DeleteMissingMessage(missingMessageAppeared.ID)
 	}))
 }
diff --git a/plugins/metrics/message.go b/plugins/metrics/message.go
index e904172876d5b140baeda89ad954738b67d8cea7..c32fc9cf4db2ba0bdea93ad59166d92ee9c7e2cb 100644
--- a/plugins/metrics/message.go
+++ b/plugins/metrics/message.go
@@ -3,8 +3,8 @@ package metrics
 import (
 	"time"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
 	"github.com/iotaledger/goshimmer/packages/metrics"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/hive.go/syncutils"
 	"go.uber.org/atomic"
@@ -49,7 +49,7 @@ var (
 	measuredReceivedMPS atomic.Uint64
 
 	// Number of messages per payload type since start of the node.
-	messageCountPerPayload = make(map[payload.Type]uint64)
+	messageCountPerPayload = make(map[tangle.PayloadType]uint64)
 
 	// protect map from concurrent read/write.
 	messageCountPerPayloadMutex syncutils.RWMutex
@@ -66,12 +66,12 @@ func MessageTotalCountSinceStart() uint64 {
 }
 
 // MessageCountSinceStartPerPayload returns a map of message payload types and their count since the start of the node.
-func MessageCountSinceStartPerPayload() map[payload.Type]uint64 {
+func MessageCountSinceStartPerPayload() map[tangle.PayloadType]uint64 {
 	messageCountPerPayloadMutex.RLock()
 	defer messageCountPerPayloadMutex.RUnlock()
 
 	// copy the original map
-	copy := make(map[payload.Type]uint64)
+	copy := make(map[tangle.PayloadType]uint64)
 	for key, element := range messageCountPerPayload {
 		copy[key] = element
 	}
@@ -122,7 +122,7 @@ func ReceivedMessagesPerSecond() uint64 {
 
 ////// Handling data updates and measuring //////
 
-func increasePerPayloadCounter(p payload.Type) {
+func increasePerPayloadCounter(p tangle.PayloadType) {
 	messageCountPerPayloadMutex.Lock()
 	defer messageCountPerPayloadMutex.Unlock()
 
diff --git a/plugins/metrics/message_test.go b/plugins/metrics/message_test.go
index 500322be1921695aba417558f7cff6c23685d9c8..54467da57594e6e9a3d2d048e88f7bf49fae8fa5 100644
--- a/plugins/metrics/message_test.go
+++ b/plugins/metrics/message_test.go
@@ -6,8 +6,8 @@ import (
 
 	valuepayload "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload"
 	drngpayload "github.com/iotaledger/goshimmer/packages/binary/drng/payload"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
 	"github.com/iotaledger/goshimmer/packages/metrics"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/hive.go/events"
 	"github.com/magiconair/properties/assert"
@@ -21,13 +21,13 @@ func TestMessageCountPerPayload(t *testing.T) {
 		increasePerPayloadCounter(valuepayload.Type)
 	}
 	assert.Equal(t, MessageTotalCountSinceStart(), (uint64)(10))
-	assert.Equal(t, MessageCountSinceStartPerPayload(), map[payload.Type]uint64{valuepayload.Type: 10})
+	assert.Equal(t, MessageCountSinceStartPerPayload(), map[tangle.PayloadType]uint64{valuepayload.Type: 10})
 	// simulate attaching 5 drng payloads
 	for i := 0; i < 5; i++ {
 		increasePerPayloadCounter(drngpayload.Type)
 	}
 	assert.Equal(t, MessageTotalCountSinceStart(), (uint64)(15))
-	assert.Equal(t, MessageCountSinceStartPerPayload(), map[payload.Type]uint64{valuepayload.Type: 10, drngpayload.Type: 5})
+	assert.Equal(t, MessageCountSinceStartPerPayload(), map[tangle.PayloadType]uint64{valuepayload.Type: 10, drngpayload.Type: 5})
 }
 
 func TestMessageTips(t *testing.T) {
diff --git a/plugins/metrics/plugin.go b/plugins/metrics/plugin.go
index f9ad4e2df4ffe46c7f0d04e54caa8a941990b7e5..5fdd58dae1be6debbd8ff35e127b2b11699ffab5 100644
--- a/plugins/metrics/plugin.go
+++ b/plugins/metrics/plugin.go
@@ -6,10 +6,9 @@ import (
 
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers"
 	valuetangle "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
 	"github.com/iotaledger/goshimmer/packages/metrics"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/packages/vote"
 	"github.com/iotaledger/goshimmer/plugins/analysis/server"
 	"github.com/iotaledger/goshimmer/plugins/autopeering"
@@ -102,7 +101,7 @@ func registerLocalMetrics() {
 
 	}))
 
-	messagelayer.Tangle().Events.MessageRemoved.Attach(events.NewClosure(func(messageId message.ID) {
+	messagelayer.Tangle().Events.MessageRemoved.Attach(events.NewClosure(func(messageId tangle.MessageID) {
 		// MessageRemoved triggered when the message gets removed from database.
 		messageTotalCountDB.Dec()
 	}))
@@ -123,7 +122,7 @@ func registerLocalMetrics() {
 	}))
 
 	// fired when a message gets added to missing message storage
-	messagelayer.Tangle().Events.MessageMissing.Attach(events.NewClosure(func(messageId message.ID) {
+	messagelayer.Tangle().Events.MessageMissing.Attach(events.NewClosure(func(messageId tangle.MessageID) {
 		missingMessageCountDB.Inc()
 	}))
 
diff --git a/plugins/pow/plugin.go b/plugins/pow/plugin.go
index d8056d6dc213d5ae053b483a43a19886fff8eb35..5b4f04d04f5808058a8e04cea3fa16e65ad91210 100644
--- a/plugins/pow/plugin.go
+++ b/plugins/pow/plugin.go
@@ -1,8 +1,7 @@
 package pow
 
 import (
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser/builtinfilters"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/hive.go/logger"
 	"github.com/iotaledger/hive.go/node"
@@ -30,6 +29,6 @@ func run(*node.Plugin) {
 
 	log.Infof("%s started: difficult=%d", PluginName, difficulty)
 
-	messagelayer.MessageParser().AddBytesFilter(builtinfilters.NewPowFilter(worker, difficulty))
-	messagelayer.MessageFactory().SetWorker(messagefactory.WorkerFunc(DoPOW))
+	messagelayer.MessageParser().AddBytesFilter(tangle.NewPowFilter(worker, difficulty))
+	messagelayer.MessageFactory().SetWorker(tangle.WorkerFunc(DoPOW))
 }
diff --git a/plugins/prometheus/tangle.go b/plugins/prometheus/tangle.go
index 710611795bb60890ff2898bc2d8113bf8605a45c..da20c98aa63dbd63bc004c4832e63c3230d66fd8 100644
--- a/plugins/prometheus/tangle.go
+++ b/plugins/prometheus/tangle.go
@@ -1,7 +1,7 @@
 package prometheus
 
 import (
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/metrics"
 	"github.com/prometheus/client_golang/prometheus"
 )
@@ -92,7 +92,7 @@ func collectTangleMetrics() {
 	messageTips.Set(float64(metrics.MessageTips()))
 	msgCountPerPayload := metrics.MessageCountSinceStartPerPayload()
 	for payloadType, count := range msgCountPerPayload {
-		messagePerTypeCount.WithLabelValues(payload.Name(payloadType)).Set(float64(count))
+		messagePerTypeCount.WithLabelValues(tangle.Name(payloadType)).Set(float64(count))
 	}
 	messageTotalCount.Set(float64(metrics.MessageTotalCountSinceStart()))
 	messageTotalCountDB.Set(float64(metrics.MessageTotalCountDB()))
diff --git a/plugins/syncbeacon/payload/payload.go b/plugins/syncbeacon/payload/payload.go
index aaa422dd27c0b9d5053c530b74b0c529adfa9af1..59f4d547ae1cda174998a9fef5a11e0e4e1d9485 100644
--- a/plugins/syncbeacon/payload/payload.go
+++ b/plugins/syncbeacon/payload/payload.go
@@ -3,7 +3,8 @@ package payload
 import (
 	"fmt"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
+
 	"github.com/iotaledger/hive.go/marshalutil"
 	"github.com/iotaledger/hive.go/stringify"
 )
@@ -14,11 +15,11 @@ const (
 )
 
 // Type is the type of the syncbeacon payload.
-var Type = payload.Type(200)
+var Type = tangle.PayloadType(200)
 
 // Payload represents the syncbeacon payload
 type Payload struct {
-	payloadType payload.Type
+	payloadType tangle.PayloadType
 	sentTime    int64
 }
 
@@ -61,7 +62,7 @@ func FromBytes(bytes []byte) (result *Payload, consumedBytes int, err error) {
 }
 
 // Type returns the type of the Payload.
-func (p *Payload) Type() payload.Type {
+func (p *Payload) Type() tangle.PayloadType {
 	return p.payloadType
 }
 
@@ -97,7 +98,7 @@ func IsSyncBeaconPayload(p *Payload) bool {
 }
 
 func init() {
-	payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) {
+	tangle.RegisterPayloadType(Type, ObjectName, func(data []byte) (payload tangle.Payload, err error) {
 		payload, _, err = FromBytes(data)
 
 		return
diff --git a/plugins/syncbeaconfollower/plugin.go b/plugins/syncbeaconfollower/plugin.go
index bbe4a996119ef2e60109d643206388917bd4910e..4e103fae641466f01e92082578a255600beb8801 100644
--- a/plugins/syncbeaconfollower/plugin.go
+++ b/plugins/syncbeaconfollower/plugin.go
@@ -5,9 +5,8 @@ import (
 	"sync"
 	"time"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/config"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	syncbeacon_payload "github.com/iotaledger/goshimmer/plugins/syncbeacon/payload"
@@ -43,7 +42,7 @@ const (
 
 // Status represents the status of a beacon node consisting of latest messageID, sentTime and sync status.
 type Status struct {
-	MsgID    message.ID
+	MsgID    tangle.MessageID
 	SentTime int64
 	Synced   bool
 }
@@ -156,7 +155,7 @@ func configure(_ *node.Plugin) {
 			continue
 		}
 		currentBeacons[pubKey] = &Status{
-			MsgID:    message.EmptyID,
+			MsgID:    tangle.EmptyMessageID,
 			Synced:   false,
 			SentTime: 0,
 		}
@@ -168,7 +167,7 @@ func configure(_ *node.Plugin) {
 
 	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
 		cachedMsgEvent.MessageMetadata.Release()
-		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
+		cachedMsgEvent.Message.Consume(func(msg *tangle.Message) {
 			messagePayload := msg.Payload()
 			if messagePayload.Type() != syncbeacon_payload.Type {
 				return
@@ -201,7 +200,7 @@ func configure(_ *node.Plugin) {
 // handlePayload handles the received payload. It does the following checks:
 // The time that payload was sent is not greater than CfgSyncBeaconMaxTimeWindowSec. If the duration is longer than CfgSyncBeaconMaxTimeWindowSec, we consider that beacon to be out of sync till we receive a newer payload.
 // More than syncPercentage of followed nodes are also synced, the node is set to synced. Otherwise, its set as desynced.
-func handlePayload(syncBeaconPayload *syncbeacon_payload.Payload, issuerPublicKey ed25519.PublicKey, msgID message.ID) {
+func handlePayload(syncBeaconPayload *syncbeacon_payload.Payload, issuerPublicKey ed25519.PublicKey, msgID tangle.MessageID) {
 	synced := true
 	dur := time.Since(time.Unix(0, syncBeaconPayload.SentTime()))
 	if dur.Seconds() > beaconMaxTimeWindowSec {
@@ -240,7 +239,7 @@ func cleanupFollowNodes() {
 	mutex.Lock()
 	defer mutex.Unlock()
 	for publicKey, status := range currentBeacons {
-		if status.MsgID != message.EmptyID {
+		if status.MsgID != tangle.EmptyMessageID {
 			dur := time.Since(time.Unix(0, status.SentTime))
 			if dur.Seconds() > beaconMaxTimeOfflineSec {
 				currentBeacons[publicKey].Synced = false
diff --git a/plugins/webapi/data/plugin.go b/plugins/webapi/data/plugin.go
index 07696d65619fa895f85ad8be19562d10cfff8a14..96a31141d4649223157ea369bd908ff88034a03a 100644
--- a/plugins/webapi/data/plugin.go
+++ b/plugins/webapi/data/plugin.go
@@ -4,7 +4,7 @@ import (
 	"net/http"
 	"sync"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/issuer"
 	"github.com/iotaledger/goshimmer/plugins/webapi"
 	"github.com/iotaledger/hive.go/logger"
@@ -44,7 +44,7 @@ func broadcastData(c echo.Context) error {
 		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
 	}
 
-	msg, err := issuer.IssuePayload(payload.NewData(request.Data))
+	msg, err := issuer.IssuePayload(tangle.NewDataPayload(request.Data))
 	if err != nil {
 		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
 	}
diff --git a/plugins/webapi/message/plugin.go b/plugins/webapi/message/plugin.go
index 0c8c581dd49e3cb13aaffc75959a2d95a778493f..2d00e3458bcc66900c8cbb7cf79db03c1d8589c1 100644
--- a/plugins/webapi/message/plugin.go
+++ b/plugins/webapi/message/plugin.go
@@ -4,7 +4,7 @@ import (
 	"net/http"
 	"sync"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/iotaledger/goshimmer/plugins/webapi"
 	"github.com/iotaledger/hive.go/logger"
@@ -52,7 +52,7 @@ func findMessageByID(c echo.Context) error {
 	for _, id := range request.IDs {
 		log.Info("Received:", id)
 
-		msgID, err := message.NewID(id)
+		msgID, err := tangle.NewMessageID(id)
 		if err != nil {
 			log.Info(err)
 			return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
diff --git a/plugins/webapi/message/sendPayload.go b/plugins/webapi/message/sendPayload.go
index 6dd31009efff57035826e29853a590b04c5c3dd0..769239e80c7e681621baf8e4156ae03843eb368d 100644
--- a/plugins/webapi/message/sendPayload.go
+++ b/plugins/webapi/message/sendPayload.go
@@ -3,7 +3,7 @@ package message
 import (
 	"net/http"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/issuer"
 	"github.com/labstack/echo"
 )
@@ -17,7 +17,7 @@ func sendPayload(c echo.Context) error {
 		return c.JSON(http.StatusBadRequest, MsgResponse{Error: err.Error()})
 	}
 
-	parsedPayload, _, err := payload.FromBytes(request.Payload)
+	parsedPayload, _, err := tangle.PayloadFromBytes(request.Payload)
 	if err != nil {
 		return c.JSON(http.StatusBadRequest, MsgResponse{Error: err.Error()})
 	}
diff --git a/plugins/webapi/tools/message/pastcone/handler.go b/plugins/webapi/tools/message/pastcone/handler.go
index 404d716b97e65ea1e261751431b01b4cb44a8595..b82fe48dd3e2b0b651d0ee82e0ab092f5db66f42 100644
--- a/plugins/webapi/tools/message/pastcone/handler.go
+++ b/plugins/webapi/tools/message/pastcone/handler.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 	"net/http"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/messagelayer"
 	"github.com/labstack/echo"
 )
@@ -18,7 +18,7 @@ func Handler(c echo.Context) error {
 		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
 	}
 
-	msgID, err := message.NewID(request.ID)
+	msgID, err := tangle.NewMessageID(request.ID)
 	if err != nil {
 		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
 	}
@@ -28,14 +28,14 @@ func Handler(c echo.Context) error {
 	stack.PushBack(msgID)
 	// keep track of submitted checks (to not re-add something to the stack that is already in it)
 	// searching in double-linked list is quite expensive, but not in a map
-	submitted := make(map[message.ID]bool)
+	submitted := make(map[tangle.MessageID]bool)
 
 	// process messages in stack, try to request parents until we end up at the genesis
 	for stack.Len() > 0 {
 		checkedMessageCount++
 		// pop the first element from stack
 		currentMsgElement := stack.Front()
-		currentMsgID := currentMsgElement.Value.(message.ID)
+		currentMsgID := currentMsgElement.Value.(tangle.MessageID)
 		stack.Remove(currentMsgElement)
 
 		// ask node if it has it
@@ -55,15 +55,15 @@ func Handler(c echo.Context) error {
 		msgObject.Release()
 		msgMetadataObject.Release()
 
-		if parent2ID == message.EmptyID && msg.Parent1ID() == message.EmptyID {
+		if parent2ID == tangle.EmptyMessageID && msg.Parent1ID() == tangle.EmptyMessageID {
 			// msg only attaches to genesis
 			continue
 		} else {
-			if !submitted[parent2ID] && parent2ID != message.EmptyID {
+			if !submitted[parent2ID] && parent2ID != tangle.EmptyMessageID {
 				stack.PushBack(parent2ID)
 				submitted[parent2ID] = true
 			}
-			if !submitted[parent1ID] && parent1ID != message.EmptyID {
+			if !submitted[parent1ID] && parent1ID != tangle.EmptyMessageID {
 				stack.PushBack(parent1ID)
 				submitted[parent1ID] = true
 			}
diff --git a/tools/integration-tests/tester/tests/testutil.go b/tools/integration-tests/tester/tests/testutil.go
index d6b8c98bd62811ec5fd4e86e8b82bd5da0810ae7..53d6b4a4c89ee75b8b9a48a2aa677bec52c1545f 100644
--- a/tools/integration-tests/tester/tests/testutil.go
+++ b/tools/integration-tests/tester/tests/testutil.go
@@ -13,7 +13,7 @@ import (
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload"
+	"github.com/iotaledger/goshimmer/packages/tangle"
 	"github.com/iotaledger/goshimmer/plugins/webapi/value/utils"
 	"github.com/iotaledger/goshimmer/tools/integration-tests/tester/framework"
 	"github.com/iotaledger/hive.go/types"
@@ -70,7 +70,7 @@ func SendDataMessage(t *testing.T, peer *framework.Peer, data []byte, number int
 		number: number,
 		id:     id,
 		// save payload to be able to compare API response
-		data:            payload.NewData(data).Bytes(),
+		data:            tangle.NewDataPayload(data).Bytes(),
 		issuerPublicKey: peer.Identity.PublicKey().String(),
 	}
 	return id, sent