diff --git a/go.mod b/go.mod
index 03c0c6c0e99dc8945ee1de7a536638a0119f2ff8..3fc5dbd477f12ea2df332810bad1d193bbc8205e 100644
--- a/go.mod
+++ b/go.mod
@@ -14,7 +14,7 @@ require (
 	github.com/golang/protobuf v1.3.2 // indirect
 	github.com/google/open-location-code/go v0.0.0-20190903173953-119bc96a3a51
 	github.com/gorilla/websocket v1.4.1
-	github.com/iotaledger/hive.go v0.0.0-20191202111738-357cee7a1c37
+	github.com/iotaledger/hive.go v0.0.0-20191205213014-6bee840fa69a
 	github.com/iotaledger/iota.go v1.0.0-beta.9
 	github.com/kr/text v0.1.0
 	github.com/labstack/echo v3.3.10+incompatible
diff --git a/go.sum b/go.sum
index d9027fa98ffeaacc105cd871773ffe8c1b967746..6a2724a85c9dc8576ebcdb169a10efee47df2e2d 100644
--- a/go.sum
+++ b/go.sum
@@ -92,6 +92,10 @@ github.com/iotaledger/hive.go v0.0.0-20191125112048-8b1784dd1bce h1:QchbydsqgH7b
 github.com/iotaledger/hive.go v0.0.0-20191125112048-8b1784dd1bce/go.mod h1:1Thhlil4lHzuy53EVvmEbEvWBFY0Tasp4kCBfxBCPIk=
 github.com/iotaledger/hive.go v0.0.0-20191202111738-357cee7a1c37 h1:Vex6W5Oae7xXvVmnCrl7J4o+PCx0FW3paMzXxQDr8H4=
 github.com/iotaledger/hive.go v0.0.0-20191202111738-357cee7a1c37/go.mod h1:1Thhlil4lHzuy53EVvmEbEvWBFY0Tasp4kCBfxBCPIk=
+github.com/iotaledger/hive.go v0.0.0-20191205211001-eafba1daa31e h1:7F9mSTDfFwMlEwkllo2yoc0p2iolrvL0I6RgMcL4h4M=
+github.com/iotaledger/hive.go v0.0.0-20191205211001-eafba1daa31e/go.mod h1:7iqun29a1x0lymTrn0UJ3Z/yy0sUzUpoOZ1OYMrYN20=
+github.com/iotaledger/hive.go v0.0.0-20191205213014-6bee840fa69a h1:mI4GR5wcI5G6vjumuI2KH9r0mf5me3i6mWhDMtkKR04=
+github.com/iotaledger/hive.go v0.0.0-20191205213014-6bee840fa69a/go.mod h1:7iqun29a1x0lymTrn0UJ3Z/yy0sUzUpoOZ1OYMrYN20=
 github.com/iotaledger/iota.go v1.0.0-beta.7 h1:OaUNahPvOdQz2nKcgeAfcUdxlEDlEV3xwLIkwzZ1B/U=
 github.com/iotaledger/iota.go v1.0.0-beta.7/go.mod h1:dMps6iMVU1pf5NDYNKIw4tRsPeC8W3ZWjOvYHOO1PMg=
 github.com/iotaledger/iota.go v1.0.0-beta.9 h1:c654s9pkdhMBkABUvWg+6k91MEBbdtmZXP1xDfQpajg=
diff --git a/packages/ledgerstate/conflict.go b/packages/ledgerstate/conflict.go
index a65dcf570a4f437680a63a591e2626250ac15d46..4ae4e0f750c4f928c10614edc3bfd90c3a1fab33 100644
--- a/packages/ledgerstate/conflict.go
+++ b/packages/ledgerstate/conflict.go
@@ -11,6 +11,8 @@ import (
 )
 
 type Conflict struct {
+	objectstorage.StorableObjectFlags
+
 	id      ConflictId
 	members map[RealityId]empty
 
diff --git a/packages/ledgerstate/ledgerstate.go b/packages/ledgerstate/ledgerstate.go
index e941bfab368a6ad7220165e4b7077fa01f57a994..83ff9dc53cdc973fb7a9a532959fa66d4437664a 100644
--- a/packages/ledgerstate/ledgerstate.go
+++ b/packages/ledgerstate/ledgerstate.go
@@ -142,21 +142,22 @@ func (ledgerState *LedgerState) GetReality(id RealityId) *objectstorage.CachedOb
 	}
 }
 
-func (ledgerState *LedgerState) BookTransfer(transfer *Transfer) error {
+func (ledgerState *LedgerState) BookTransfer(transfer *Transfer) (err error) {
 	inputs := ledgerState.getTransferInputs(transfer)
 
-	targetReality := ledgerState.getTargetReality(inputs)
-	defer targetReality.Release()
+	ledgerState.getTargetReality(inputs).Consume(func(object objectstorage.StorableObject) {
+		targetReality := object.(*Reality)
 
-	if bookingErr := targetReality.Get().(*Reality).bookTransfer(transfer.GetHash(), inputs, transfer.GetOutputs()); bookingErr != nil {
-		return bookingErr
-	}
+		if err = targetReality.bookTransfer(transfer.GetHash(), inputs, transfer.GetOutputs()); err != nil {
+			return
+		}
 
-	if !targetReality.IsStored() {
-		targetReality.Store()
-	}
+		if !targetReality.PersistenceEnabled() {
+			targetReality.Persist()
+		}
+	})
 
-	return nil
+	return
 }
 
 func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string) error {
@@ -299,12 +300,49 @@ func (ledgerState *LedgerState) AggregateRealities(realityIds ...RealityId) *obj
 			}
 		}
 
-		sortedRealityIds := ledgerState.sortRealityIds(aggregatedRealities)
+		parentConflictRealities := make(map[RealityId]*objectstorage.CachedObject)
+		aggregatedRealityParentIds := make([]RealityId, len(aggregatedRealities))
+
+		counter := 0
+		for aggregatedRealityId, cachedAggregatedReality := range aggregatedRealities {
+			aggregatedRealityParentIds[counter] = aggregatedRealityId
+			counter++
+
+			aggregatedReality := cachedAggregatedReality.Get().(*Reality)
+			if !aggregatedReality.IsAggregated() {
+				parentConflictRealities[aggregatedRealityId] = cachedAggregatedReality
+			} else {
+				aggregatedReality.collectParentConflictRealities(parentConflictRealities)
+
+				cachedAggregatedReality.Release()
+			}
+		}
+
+		aggregatedRealityId := ledgerState.generateAggregatedRealityId(ledgerState.sortRealityIds(parentConflictRealities))
+
+		newAggregatedRealityCreated := false
+		if cachedAggregatedReality, err := ledgerState.realities.ComputeIfAbsent(aggregatedRealityId[:], func(key []byte) (object objectstorage.StorableObject, e error) {
+			aggregatedReality := newReality(aggregatedRealityId, aggregatedRealityParentIds...)
+			aggregatedReality.ledgerState = ledgerState
+
+			aggregatedReality.SetModified()
+
+			newAggregatedRealityCreated = true
 
-		aggregatedReality := newReality(ledgerState.generateAggregatedRealityId(sortedRealityIds), sortedRealityIds...)
-		aggregatedReality.ledgerState = ledgerState
+			return aggregatedReality, nil
+		}); err != nil {
+			panic(err)
+		} else {
+			if !newAggregatedRealityCreated {
+				aggregatedReality := cachedAggregatedReality.Get().(*Reality)
 
-		return ledgerState.realities.Prepare(aggregatedReality)
+				for _, realityId := range aggregatedRealityParentIds {
+					aggregatedReality.AddParentReality(realityId)
+				}
+			}
+
+			return cachedAggregatedReality
+		}
 	}
 }
 
diff --git a/packages/ledgerstate/ledgerstate_test.go b/packages/ledgerstate/ledgerstate_test.go
index 4727db2de3e83282fb1f3ed6f789213f94b9c9b3..fc5efc9e7dfa7b13990ac30e29e74e1364a496de 100644
--- a/packages/ledgerstate/ledgerstate_test.go
+++ b/packages/ledgerstate/ledgerstate_test.go
@@ -37,7 +37,7 @@ func init() {
 
 func Benchmark(b *testing.B) {
 	ledgerState := NewLedgerState("testLedger").Prune().AddTransferOutput(
-		transferHash1, addressHash1, NewColoredBalance(eth, 1337),
+		transferHash1, addressHash1, NewColoredBalance(eth, 1024),
 	)
 
 	b.ResetTimer()
@@ -50,7 +50,7 @@ func Benchmark(b *testing.B) {
 		if err := ledgerState.BookTransfer(NewTransfer(newTransferHash).AddInput(
 			NewTransferOutputReference(lastTransferHash, addressHash1),
 		).AddOutput(
-			addressHash1, NewColoredBalance(eth, 1337),
+			addressHash1, NewColoredBalance(eth, 1024),
 		)); err != nil {
 			b.Error(err)
 		}
@@ -61,7 +61,7 @@ func Benchmark(b *testing.B) {
 
 func Test(t *testing.T) {
 	ledgerState := NewLedgerState("testLedger").Prune().AddTransferOutput(
-		transferHash1, addressHash1, NewColoredBalance(eth, 1337), NewColoredBalance(iota_, 1338),
+		transferHash1, addressHash1, NewColoredBalance(eth, 1024), NewColoredBalance(iota_, 1338),
 	)
 
 	ledgerState.CreateReality(pendingReality)
@@ -132,7 +132,7 @@ func initializeLedgerStateWithBalances(numberOfBalances int) (ledgerState *Ledge
 		transferHash := generateRandomTransferHash()
 		addressHash := generateRandomAddressHash()
 
-		ledgerState.AddTransferOutput(transferHash, addressHash, NewColoredBalance(iota_, 1337))
+		ledgerState.AddTransferOutput(transferHash, addressHash, NewColoredBalance(iota_, 1024))
 
 		result = append(result, NewTransferOutputReference(transferHash, addressHash))
 	}
@@ -179,6 +179,87 @@ func spend(ledgerState *LedgerState, transferOutputReferences ...*TransferOutput
 	return
 }
 
+func multiSpend(ledgerState *LedgerState, outputCount int, transferOutputReferences ...*TransferOutputReference) (result []*TransferOutputReference) {
+	transferHash := generateRandomTransferHash()
+
+	transfer := NewTransfer(transferHash)
+
+	totalInputBalance := uint64(0)
+	for _, transferOutputReference := range transferOutputReferences {
+		ledgerState.GetTransferOutput(transferOutputReference).Consume(func(object objectstorage.StorableObject) {
+			transferOutput := object.(*TransferOutput)
+
+			for _, coloredBalance := range transferOutput.GetBalances() {
+				totalInputBalance += coloredBalance.GetValue()
+			}
+		})
+
+		transfer.AddInput(transferOutputReference)
+	}
+
+	for i := 0; i < outputCount; i++ {
+		addressHash := generateRandomAddressHash()
+
+		transfer.AddOutput(
+			addressHash, NewColoredBalance(iota_, totalInputBalance/uint64(outputCount)),
+		)
+
+		result = append(result, NewTransferOutputReference(transferHash, addressHash))
+	}
+
+	if err := ledgerState.BookTransfer(transfer); err != nil {
+		panic(err)
+	}
+
+	return
+}
+
+func TestAggregateAggregatedRealities(t *testing.T) {
+	ledgerState, transferOutputs := initializeLedgerStateWithBalances(3)
+
+	multiSpend(ledgerState, 1, transferOutputs[0])
+	outputs0 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[0])[0])
+
+	multiSpend(ledgerState, 1, transferOutputs[1])
+	outputs1 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[1])[0])
+
+	multiSpend(ledgerState, 1, transferOutputs[2])
+	outputs2 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[2])[0])
+
+	aggregatedOutputs0 := multiSpend(ledgerState, 2, outputs0[0], outputs1[0])
+	aggregatedOutputs1 := multiSpend(ledgerState, 2, outputs1[1], outputs2[1])
+	aggregatedOutputs2 := multiSpend(ledgerState, 2, outputs0[1], outputs2[0])
+
+	multiSpend(ledgerState, 1, aggregatedOutputs0[0], aggregatedOutputs1[0])
+	multiSpend(ledgerState, 1, aggregatedOutputs0[1], aggregatedOutputs2[0])
+
+	time.Sleep(1000 * time.Millisecond)
+
+	objectstorage.WaitForWritesToFlush()
+
+	if err := ledgerState.GenerateRealityVisualization("realities1.png"); err != nil {
+		t.Error(err)
+	}
+
+	if err := NewVisualizer(ledgerState).RenderTransferOutputs("outputs1.png"); err != nil {
+		t.Error(err)
+	}
+
+	multiSpend(ledgerState, 2, outputs0[0], outputs1[0])
+
+	time.Sleep(1000 * time.Millisecond)
+
+	objectstorage.WaitForWritesToFlush()
+
+	if err := ledgerState.GenerateRealityVisualization("realities2.png"); err != nil {
+		t.Error(err)
+	}
+
+	if err := NewVisualizer(ledgerState).RenderTransferOutputs("outputs2.png"); err != nil {
+		t.Error(err)
+	}
+}
+
 func TestElevateAggregatedReality(t *testing.T) {
 	ledgerState, transferOutputs := initializeLedgerStateWithBalances(3)
 
@@ -221,7 +302,7 @@ func TestElevateAggregatedReality(t *testing.T) {
 
 func TestElevate(t *testing.T) {
 	ledgerState := NewLedgerState("testLedger").Prune().AddTransferOutput(
-		transferHash1, addressHash1, NewColoredBalance(eth, 1337), NewColoredBalance(iota_, 1338),
+		transferHash1, addressHash1, NewColoredBalance(eth, 1024), NewColoredBalance(iota_, 1338),
 	)
 
 	// create first legit spend
@@ -230,7 +311,7 @@ func TestElevate(t *testing.T) {
 	).AddOutput(
 		addressHash2, NewColoredBalance(iota_, 1338),
 	).AddOutput(
-		addressHash2, NewColoredBalance(eth, 1337),
+		addressHash2, NewColoredBalance(eth, 1024),
 	)); err != nil {
 		t.Error(err)
 	}
@@ -241,7 +322,7 @@ func TestElevate(t *testing.T) {
 	).AddOutput(
 		addressHash4, NewColoredBalance(iota_, 1338),
 	).AddOutput(
-		addressHash4, NewColoredBalance(eth, 1337),
+		addressHash4, NewColoredBalance(eth, 1024),
 	)); err != nil {
 		t.Error(err)
 	}
@@ -251,7 +332,7 @@ func TestElevate(t *testing.T) {
 	).AddOutput(
 		addressHash4, NewColoredBalance(iota_, 1338),
 	).AddOutput(
-		addressHash4, NewColoredBalance(eth, 1337),
+		addressHash4, NewColoredBalance(eth, 1024),
 	)); err != nil {
 		t.Error(err)
 	}
@@ -275,7 +356,7 @@ func TestElevate(t *testing.T) {
 	).AddOutput(
 		addressHash5, NewColoredBalance(iota_, 1338),
 	).AddOutput(
-		addressHash5, NewColoredBalance(eth, 1337),
+		addressHash5, NewColoredBalance(eth, 1024),
 	)); err != nil {
 		t.Error(err)
 	}
diff --git a/packages/ledgerstate/outputs.png b/packages/ledgerstate/outputs.png
index d681a69339839d9272253fc74b47ed3d313af085..6f2378aae6fd63d8cc32cebf1de4b0d53e3657d6 100644
Binary files a/packages/ledgerstate/outputs.png and b/packages/ledgerstate/outputs.png differ
diff --git a/packages/ledgerstate/outputs1.png b/packages/ledgerstate/outputs1.png
new file mode 100644
index 0000000000000000000000000000000000000000..78638b4ac0d547722553ecba91080eb482cfdfac
Binary files /dev/null and b/packages/ledgerstate/outputs1.png differ
diff --git a/packages/ledgerstate/outputs2.png b/packages/ledgerstate/outputs2.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e5fb6fc2eb50722536f8cebf3237379c06830c8
Binary files /dev/null and b/packages/ledgerstate/outputs2.png differ
diff --git a/packages/ledgerstate/realities.png b/packages/ledgerstate/realities.png
index 081531cd0633c8945012907f4023596c4c9cc3b8..bb6453828ee02fc9679bf7b5ca9488e12feb7cbd 100644
Binary files a/packages/ledgerstate/realities.png and b/packages/ledgerstate/realities.png differ
diff --git a/packages/ledgerstate/realities1.png b/packages/ledgerstate/realities1.png
new file mode 100644
index 0000000000000000000000000000000000000000..73be1b7f5e854ce26112b3021b8a03c534dff7f9
Binary files /dev/null and b/packages/ledgerstate/realities1.png differ
diff --git a/packages/ledgerstate/realities2.png b/packages/ledgerstate/realities2.png
new file mode 100644
index 0000000000000000000000000000000000000000..a6fb2ce1c43c24eb3059ea3a8c840a5b846fa769
Binary files /dev/null and b/packages/ledgerstate/realities2.png differ
diff --git a/packages/ledgerstate/reality.go b/packages/ledgerstate/reality.go
index 62a15f7c3802a003c105ec8ca977359e011b8f1a..afbbcb50b59c0b9b33fa60bfe47f174b1781b6d3 100644
--- a/packages/ledgerstate/reality.go
+++ b/packages/ledgerstate/reality.go
@@ -11,6 +11,8 @@ import (
 )
 
 type Reality struct {
+	objectstorage.StorableObjectFlags
+
 	id                    RealityId
 	parentRealityIds      RealityIdSet
 	parentRealityIdsMutex sync.RWMutex
@@ -52,11 +54,22 @@ func (reality *Reality) GetParentRealityIds() (realityIdSet RealityIdSet) {
 	return
 }
 
-// Sets the set of RealityIds that are the parents of this Reality.
-func (reality *Reality) SetParentRealityIds(parentRealityIds RealityIdSet) {
-	reality.parentRealityIdsMutex.Lock()
-	reality.parentRealityIds = parentRealityIds
-	reality.parentRealityIdsMutex.Unlock()
+// Adds a new parent Reality to this Reality (it is used for aggregating aggregated Realities).
+func (reality *Reality) AddParentReality(realityId RealityId) {
+	reality.parentRealityIdsMutex.RLock()
+	if _, exists := reality.parentRealityIds[realityId]; !exists {
+		reality.parentRealityIdsMutex.RUnlock()
+
+		reality.parentRealityIdsMutex.Lock()
+		if _, exists := reality.parentRealityIds[realityId]; !exists {
+			reality.parentRealityIds[realityId] = void
+
+			reality.SetModified()
+		}
+		reality.parentRealityIdsMutex.Unlock()
+	} else {
+		reality.parentRealityIdsMutex.RUnlock()
+	}
 }
 
 // Returns the amount of TransferOutputs in this Reality.
@@ -102,15 +115,12 @@ func (reality *Reality) DescendsFrom(realityId RealityId) bool {
 	}
 }
 
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// [DONE] Returns a map of all parent realities (one level). They have to manually be "released" when they are not
-// needed anymore.
-func (reality *Reality) GetParentRealities() map[RealityId]*objectstorage.CachedObject {
-	parentRealities := make(map[RealityId]*objectstorage.CachedObject)
+// Returns a map of all parent realities (one level). They have to be "released" manually when they are not needed
+// anymore.
+func (reality *Reality) GetParentRealities() (parentRealities map[RealityId]*objectstorage.CachedObject) {
+	parentRealities = make(map[RealityId]*objectstorage.CachedObject)
 
 	reality.parentRealityIdsMutex.RLock()
-
 	for parentRealityId := range reality.parentRealityIds {
 		loadedParentReality := reality.ledgerState.GetReality(parentRealityId)
 		if !loadedParentReality.Exists() {
@@ -121,13 +131,13 @@ func (reality *Reality) GetParentRealities() map[RealityId]*objectstorage.Cached
 
 		parentRealities[loadedParentReality.Get().(*Reality).id] = loadedParentReality
 	}
-
 	reality.parentRealityIdsMutex.RUnlock()
 
-	return parentRealities
+	return
 }
 
-// Returns
+// Returns a map of all parent realities that are conflicting. Aggregated realities are "transparent". They have to be
+// "released" manually when they are not needed anymore.
 func (reality *Reality) GetParentConflictRealities() map[RealityId]*objectstorage.CachedObject {
 	if !reality.IsAggregated() {
 		return reality.GetParentRealities()
@@ -140,6 +150,8 @@ func (reality *Reality) GetParentConflictRealities() map[RealityId]*objectstorag
 	}
 }
 
+// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 func (reality *Reality) collectParentConflictRealities(parentConflictRealities map[RealityId]*objectstorage.CachedObject) {
 	for realityId, cachedParentReality := range reality.GetParentRealities() {
 		parentReality := cachedParentReality.Get().(*Reality)
@@ -173,7 +185,11 @@ func (reality *Reality) GetAncestorRealities() (result map[RealityId]*objectstor
 // [DONE] Registers the conflict set in the Reality.
 func (reality *Reality) AddConflict(conflictSetId ConflictId) {
 	reality.conflictIdsMutex.Lock()
-	reality.conflictIds[conflictSetId] = void
+	if _, exists := reality.conflictIds[conflictSetId]; !exists {
+		reality.conflictIds[conflictSetId] = void
+
+		reality.SetModified()
+	}
 	reality.conflictIdsMutex.Unlock()
 }
 
@@ -293,8 +309,6 @@ func (reality *Reality) consumeInputs(inputs objectstorage.CachedObjects, transf
 				conflicts = append(conflicts, conflict)
 			}
 		}
-
-		input.Store()
 	}
 
 	return
@@ -331,11 +345,14 @@ func (reality *Reality) createRealityForConsumerOfConflictingInput(consumersOfCo
 			newReality := newReality(elevatedRealityId, reality.id)
 			newReality.ledgerState = reality.ledgerState
 
+			newReality.Persist()
+			newReality.SetModified()
+
 			realityIsNew = true
 
 			return newReality, nil
 		}); err == nil {
-			cachedElevatedReality.Store().Consume(func(object objectstorage.StorableObject) {
+			cachedElevatedReality.Consume(func(object objectstorage.StorableObject) {
 				elevatedReality := object.(*Reality)
 
 				// We register every Conflict with the Reality (independent if it is "new" or not), to reflect its
@@ -369,6 +386,8 @@ func (reality *Reality) elevateTransferOutput(transferOutputReference *TransferO
 	cachedTransferOutputToElevate.Consume(func(object objectstorage.StorableObject) {
 		transferOutputToElevate := object.(*TransferOutput)
 
+		transferOutputToElevate.SetModified()
+
 		if transferOutputToElevate.GetRealityId() == reality.id {
 			err = reality.elevateTransferOutputOfCurrentReality(transferOutputToElevate, newReality)
 		} else {
@@ -410,7 +429,10 @@ func (reality *Reality) elevateTransferOutputOfNestedReality(transferOutput *Tra
 
 	newParentRealities := reality.GetParentRealityIds().Remove(oldParentRealityId).Add(newParentRealityId).ToList()
 
-	reality.ledgerState.AggregateRealities(newParentRealities...).Store().Consume(func(object objectstorage.StorableObject) {
+	reality.ledgerState.AggregateRealities(newParentRealities...).Consume(func(object objectstorage.StorableObject) {
+		object.Persist()
+		object.SetModified()
+
 		err = reality.elevateTransferOutputOfCurrentReality(transferOutput, object.(*Reality))
 	})
 
@@ -442,11 +464,13 @@ func (reality *Reality) bookTransferOutput(transferOutput *TransferOutput) (err
 			reality.ledgerState.GetReality(transferOutputRealityId).Consume(func(object objectstorage.StorableObject) {
 				// decrease transferOutputCount and remove reality if it is empty
 				if object.(*Reality).DecreaseTransferOutputCount() == 0 {
-					reality.ledgerState.realities.Delete(transferOutputRealityId[:])
+					//reality.ledgerState.realities.Delete(transferOutputRealityId[:])
 				}
 			})
 
-			oldTransferOutputBooking.Delete().Release()
+			oldTransferOutputBooking.Consume(func(transferOutputBooking objectstorage.StorableObject) {
+				transferOutputBooking.Delete()
+			})
 		}
 	}
 
diff --git a/packages/ledgerstate/transfer_output.go b/packages/ledgerstate/transfer_output.go
index 9545d2e0b07f378b56abdbd75f1e3026e5955d11..a783ef161ff7857872f8c592bf7439f14d4f2cbb 100644
--- a/packages/ledgerstate/transfer_output.go
+++ b/packages/ledgerstate/transfer_output.go
@@ -9,6 +9,8 @@ import (
 )
 
 type TransferOutput struct {
+	objectstorage.StorableObjectFlags
+
 	transferHash TransferHash
 	addressHash  AddressHash
 	balances     []*ColoredBalance
@@ -109,6 +111,8 @@ func (transferOutput *TransferOutput) addConsumer(consumer TransferHash, outputs
 
 		transferOutput.consumers[consumer] = consumers
 		transferOutput.consumersMutex.Unlock()
+
+		transferOutput.SetModified()
 	}
 
 	return
@@ -125,7 +129,9 @@ func (transferOutput *TransferOutput) markAsSpent() error {
 	} else {
 		transferOutput.ledgerState.storeTransferOutputBooking(newTransferOutputBooking(transferOutput.GetRealityId(), transferOutput.addressHash, true, transferOutput.transferHash)).Release()
 
-		oldTransferOutputBooking.Delete().Release()
+		oldTransferOutputBooking.Consume(func(transferOutputBooking objectstorage.StorableObject) {
+			transferOutputBooking.Delete()
+		})
 	}
 
 	transferOutput.bookingMutex.Unlock()
diff --git a/packages/ledgerstate/transfer_output_booking.go b/packages/ledgerstate/transfer_output_booking.go
index 9e5d1b20f8c72427f37f5dad225913f60cb9842d..c60fde9a6816f56d2efd09d2f633dc5885e0c0d1 100644
--- a/packages/ledgerstate/transfer_output_booking.go
+++ b/packages/ledgerstate/transfer_output_booking.go
@@ -9,6 +9,8 @@ import (
 // region struct + constructor + public api ////////////////////////////////////////////////////////////////////////////
 
 type TransferOutputBooking struct {
+	objectstorage.StorableObjectFlags
+
 	realityId    RealityId
 	addressHash  AddressHash
 	spent        bool