Skip to content
Snippets Groups Projects
Commit dde7849f authored by Hans Moog's avatar Hans Moog
Browse files

Feat: liked and preferred flag gets correctly propagated

parent 2bb3fb02
No related branches found
No related tags found
No related merge requests found
...@@ -36,6 +36,7 @@ func NewLedgerState(storageId string) *LedgerState { ...@@ -36,6 +36,7 @@ func NewLedgerState(storageId string) *LedgerState {
mainReality := newReality(MAIN_REALITY_ID) mainReality := newReality(MAIN_REALITY_ID)
mainReality.ledgerState = result mainReality.ledgerState = result
mainReality.SetPreferred()
result.realities.Store(mainReality).Release() result.realities.Store(mainReality).Release()
return result return result
...@@ -194,8 +195,7 @@ func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string) ...@@ -194,8 +195,7 @@ func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string)
realityNode.Attr("style", "filled") realityNode.Attr("style", "filled")
realityNode.Attr("shape", "rect") realityNode.Attr("shape", "rect")
realityNode.Attr("color", "#9673A6") realityNode.Attr("color", "#9673A6")
realityNode.Attr("fillcolor", "#DAE8FC") realityNode.Attr("fillcolor", "#E1D5E7")
realityNode.Attr("penwidth", "2.0")
} else { } else {
realityNode = graph.Node("REALITY\n\n" + strings.Trim(reality.id.String(), "\x00") + " (" + strconv.Itoa(int(reality.GetTransferOutputCount())) + " / " + strconv.Itoa(len(reality.subRealityIds)) + ")") realityNode = graph.Node("REALITY\n\n" + strings.Trim(reality.id.String(), "\x00") + " (" + strconv.Itoa(int(reality.GetTransferOutputCount())) + " / " + strconv.Itoa(len(reality.subRealityIds)) + ")")
realityNode.Attr("style", "filled") realityNode.Attr("style", "filled")
...@@ -204,7 +204,7 @@ func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string) ...@@ -204,7 +204,7 @@ func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string)
realityNode.Attr("fillcolor", "#DAE8FC") realityNode.Attr("fillcolor", "#DAE8FC")
} }
if reality.GetLiked() { if reality.IsLiked() {
realityNode.Attr("penwidth", "3.0") realityNode.Attr("penwidth", "3.0")
} }
...@@ -313,12 +313,17 @@ func (ledgerState *LedgerState) AggregateRealities(realityIds ...RealityId) *obj ...@@ -313,12 +313,17 @@ func (ledgerState *LedgerState) AggregateRealities(realityIds ...RealityId) *obj
parentConflictRealities := make(map[RealityId]*objectstorage.CachedObject) parentConflictRealities := make(map[RealityId]*objectstorage.CachedObject)
aggregatedRealityParentIds := make([]RealityId, len(aggregatedRealities)) aggregatedRealityParentIds := make([]RealityId, len(aggregatedRealities))
aggregatedRealityIsPreferred := true
counter := 0 counter := 0
for aggregatedRealityId, cachedAggregatedReality := range aggregatedRealities { for aggregatedRealityId, cachedAggregatedReality := range aggregatedRealities {
aggregatedRealityParentIds[counter] = aggregatedRealityId aggregatedRealityParentIds[counter] = aggregatedRealityId
counter++ counter++
aggregatedReality := cachedAggregatedReality.Get().(*Reality) aggregatedReality := cachedAggregatedReality.Get().(*Reality)
aggregatedRealityIsPreferred = aggregatedRealityIsPreferred && aggregatedReality.IsPreferred()
if !aggregatedReality.IsAggregated() { if !aggregatedReality.IsAggregated() {
parentConflictRealities[aggregatedRealityId] = cachedAggregatedReality parentConflictRealities[aggregatedRealityId] = cachedAggregatedReality
} else { } else {
...@@ -334,6 +339,7 @@ func (ledgerState *LedgerState) AggregateRealities(realityIds ...RealityId) *obj ...@@ -334,6 +339,7 @@ func (ledgerState *LedgerState) AggregateRealities(realityIds ...RealityId) *obj
if newCachedAggregatedReality, err := ledgerState.realities.ComputeIfAbsent(aggregatedRealityId[:], func(key []byte) (object objectstorage.StorableObject, e error) { if newCachedAggregatedReality, err := ledgerState.realities.ComputeIfAbsent(aggregatedRealityId[:], func(key []byte) (object objectstorage.StorableObject, e error) {
aggregatedReality := newReality(aggregatedRealityId, aggregatedRealityParentIds...) aggregatedReality := newReality(aggregatedRealityId, aggregatedRealityParentIds...)
aggregatedReality.ledgerState = ledgerState aggregatedReality.ledgerState = ledgerState
aggregatedReality.SetPreferred(aggregatedRealityIsPreferred)
for _, parentRealityId := range aggregatedRealityParentIds { for _, parentRealityId := range aggregatedRealityParentIds {
ledgerState.GetReality(parentRealityId).Consume(func(object objectstorage.StorableObject) { ledgerState.GetReality(parentRealityId).Consume(func(object objectstorage.StorableObject) {
...@@ -387,6 +393,7 @@ func (ledgerState *LedgerState) Prune() *LedgerState { ...@@ -387,6 +393,7 @@ func (ledgerState *LedgerState) Prune() *LedgerState {
mainReality := newReality(MAIN_REALITY_ID) mainReality := newReality(MAIN_REALITY_ID)
mainReality.ledgerState = ledgerState mainReality.ledgerState = ledgerState
mainReality.SetPreferred()
ledgerState.realities.Store(mainReality).Release() ledgerState.realities.Store(mainReality).Release()
return ledgerState return ledgerState
......
...@@ -216,11 +216,11 @@ func multiSpend(ledgerState *LedgerState, outputCount int, transferOutputReferen ...@@ -216,11 +216,11 @@ func multiSpend(ledgerState *LedgerState, outputCount int, transferOutputReferen
func TestAggregateAggregatedRealities(t *testing.T) { func TestAggregateAggregatedRealities(t *testing.T) {
ledgerState, transferOutputs := initializeLedgerStateWithBalances(3) ledgerState, transferOutputs := initializeLedgerStateWithBalances(3)
multiSpend(ledgerState, 1, transferOutputs[0])
outputs0 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[0])[0]) outputs0 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[0])[0])
multiSpend(ledgerState, 1, transferOutputs[0])
multiSpend(ledgerState, 1, transferOutputs[1])
outputs1 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[1])[0]) outputs1 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[1])[0])
multiSpend(ledgerState, 1, transferOutputs[1])
multiSpend(ledgerState, 1, transferOutputs[2]) multiSpend(ledgerState, 1, transferOutputs[2])
outputs2 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[2])[0]) outputs2 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[2])[0])
...@@ -236,8 +236,8 @@ func TestAggregateAggregatedRealities(t *testing.T) { ...@@ -236,8 +236,8 @@ func TestAggregateAggregatedRealities(t *testing.T) {
objectstorage.WaitForWritesToFlush() objectstorage.WaitForWritesToFlush()
fmt.Println(ledgerState.GenerateRealityVisualization("realities1.png")) _ = ledgerState.GenerateRealityVisualization("realities1.png")
NewVisualizer(ledgerState).RenderTransferOutputs("outputs1.png") _ = NewVisualizer(ledgerState).RenderTransferOutputs("outputs1.png")
multiSpend(ledgerState, 2, outputs0[0], outputs1[0]) multiSpend(ledgerState, 2, outputs0[0], outputs1[0])
...@@ -245,8 +245,8 @@ func TestAggregateAggregatedRealities(t *testing.T) { ...@@ -245,8 +245,8 @@ func TestAggregateAggregatedRealities(t *testing.T) {
objectstorage.WaitForWritesToFlush() objectstorage.WaitForWritesToFlush()
ledgerState.GenerateRealityVisualization("realities2.png") _ = ledgerState.GenerateRealityVisualization("realities2.png")
NewVisualizer(ledgerState).RenderTransferOutputs("outputs2.png") _ = NewVisualizer(ledgerState).RenderTransferOutputs("outputs2.png")
} }
func TestElevateAggregatedReality(t *testing.T) { func TestElevateAggregatedReality(t *testing.T) {
...@@ -268,20 +268,20 @@ func TestElevateAggregatedReality(t *testing.T) { ...@@ -268,20 +268,20 @@ func TestElevateAggregatedReality(t *testing.T) {
spend(ledgerState, doubleSpentOutputs1[1]) spend(ledgerState, doubleSpentOutputs1[1])
// double spend funds of aggregated reality // double spend funds of aggregated reality
//spend(ledgerState, spentInput, doubleSpentOutputs2[0]) // spend(ledgerState, spentInput, doubleSpentOutputs2[0])
// spend funds of conflict in aggregated reality further // spend funds of conflict in aggregated reality further
//lastOutputOfAggregatedReality := spend(ledgerState, outputOfAggregatedReality) // lastOutputOfAggregatedReality := spend(ledgerState, outputOfAggregatedReality)
//spend(ledgerState, lastOutputOfAggregatedReality, doubleSpentOutputs3[1]) // spend(ledgerState, lastOutputOfAggregatedReality, doubleSpentOutputs3[1])
spend(ledgerState, spend(ledgerState, spend(ledgerState, outputOfAggregatedReality, spend(ledgerState, doubleSpentOutputs3[1])))) spend(ledgerState, spend(ledgerState, spend(ledgerState, outputOfAggregatedReality, spend(ledgerState, doubleSpentOutputs3[1]))))
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
objectstorage.WaitForWritesToFlush() objectstorage.WaitForWritesToFlush()
ledgerState.GenerateRealityVisualization("realities.png") _ = ledgerState.GenerateRealityVisualization("realities.png")
NewVisualizer(ledgerState).RenderTransferOutputs("outputs.png") _ = NewVisualizer(ledgerState).RenderTransferOutputs("outputs.png")
} }
func TestElevate(t *testing.T) { func TestElevate(t *testing.T) {
......
packages/ledgerstate/outputs1.png

106 KiB | W: | H:

packages/ledgerstate/outputs1.png

102 KiB | W: | H:

packages/ledgerstate/outputs1.png
packages/ledgerstate/outputs1.png
packages/ledgerstate/outputs1.png
packages/ledgerstate/outputs1.png
  • 2-up
  • Swipe
  • Onion skin
packages/ledgerstate/outputs2.png

121 KiB | W: | H:

packages/ledgerstate/outputs2.png

118 KiB | W: | H:

packages/ledgerstate/outputs2.png
packages/ledgerstate/outputs2.png
packages/ledgerstate/outputs2.png
packages/ledgerstate/outputs2.png
  • 2-up
  • Swipe
  • Onion skin
packages/ledgerstate/realities1.png

101 KiB | W: | H:

packages/ledgerstate/realities1.png

103 KiB | W: | H:

packages/ledgerstate/realities1.png
packages/ledgerstate/realities1.png
packages/ledgerstate/realities1.png
packages/ledgerstate/realities1.png
  • 2-up
  • Swipe
  • Onion skin
packages/ledgerstate/realities2.png

126 KiB | W: | H:

packages/ledgerstate/realities2.png

127 KiB | W: | H:

packages/ledgerstate/realities2.png
packages/ledgerstate/realities2.png
packages/ledgerstate/realities2.png
packages/ledgerstate/realities2.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -21,6 +21,8 @@ type Reality struct { ...@@ -21,6 +21,8 @@ type Reality struct {
conflictIds ConflictIdSet conflictIds ConflictIdSet
conflictIdsMutex sync.RWMutex conflictIdsMutex sync.RWMutex
transferOutputCount uint32 transferOutputCount uint32
preferred bool
preferredMutex sync.RWMutex
liked bool liked bool
likedMutex sync.RWMutex likedMutex sync.RWMutex
...@@ -28,6 +30,135 @@ type Reality struct { ...@@ -28,6 +30,135 @@ type Reality struct {
ledgerState *LedgerState ledgerState *LedgerState
} }
func (reality *Reality) areParentsLiked() (parentsLiked bool) {
parentsLiked = true
for _, cachedParentReality := range reality.GetParentRealities() {
if parentsLiked {
cachedParentReality.Consume(func(object objectstorage.StorableObject) {
parentsLiked = parentsLiked && object.(*Reality).IsLiked()
})
} else {
cachedParentReality.Release()
}
}
return
}
func (reality *Reality) propagateLiked() {
reality.likedMutex.Lock()
reality.liked = true
reality.likedMutex.Unlock()
reality.SetModified()
for _, cachedSubReality := range reality.GetSubRealities() {
if !cachedSubReality.Exists() {
cachedSubReality.Release()
// TODO: SWITCH TO ERR INSTEAD OF PANIC
panic("could not load sub reality")
}
cachedSubReality.Consume(func(object objectstorage.StorableObject) {
subReality := object.(*Reality)
subReality.parentRealityIdsMutex.RLock()
if len(subReality.parentRealityIds) == 1 && subReality.parentRealityIds.Contains(reality.id) {
subReality.parentRealityIdsMutex.RUnlock()
subReality.propagateLiked()
} else {
subReality.parentRealityIdsMutex.RUnlock()
if subReality.areParentsLiked() {
subReality.propagateLiked()
}
}
})
}
}
func (reality *Reality) propagateDisliked() {
reality.likedMutex.Lock()
reality.liked = false
reality.likedMutex.Unlock()
reality.SetModified()
for _, cachedSubReality := range reality.GetSubRealities() {
if !cachedSubReality.Exists() {
cachedSubReality.Release()
// TODO: SWITCH TO ERR INSTEAD OF PANIC
panic("could not load sub reality")
}
cachedSubReality.Consume(func(object objectstorage.StorableObject) {
subReality := object.(*Reality)
if subReality.IsLiked() {
subReality.propagateDisliked()
}
})
}
}
func (reality *Reality) GetSubRealities() (subRealities objectstorage.CachedObjects) {
reality.subRealityIdsMutex.RLock()
subRealities = make(objectstorage.CachedObjects, len(reality.subRealityIds))
i := 0
for subRealityId := range reality.subRealityIds {
subRealities[i] = reality.ledgerState.GetReality(subRealityId)
i++
}
reality.subRealityIdsMutex.RUnlock()
return
}
func (reality *Reality) SetPreferred(preferred ...bool) (updated bool) {
newPreferredValue := len(preferred) == 0 || preferred[0]
reality.preferredMutex.RLock()
if reality.preferred != newPreferredValue {
reality.preferredMutex.RUnlock()
reality.preferredMutex.Lock()
if reality.preferred != newPreferredValue {
reality.preferred = newPreferredValue
if newPreferredValue {
if reality.areParentsLiked() {
reality.propagateLiked()
}
} else {
if reality.IsLiked() {
reality.propagateDisliked()
}
}
updated = true
reality.SetModified()
}
reality.preferredMutex.Unlock()
} else {
reality.preferredMutex.RUnlock()
}
return
}
func (reality *Reality) IsPreferred() (preferred bool) {
reality.preferredMutex.RLock()
preferred = reality.preferred
reality.preferredMutex.RUnlock()
return
}
// region DONE REVIEWING /////////////////////////////////////////////////////////////////////////////////////////////// // region DONE REVIEWING ///////////////////////////////////////////////////////////////////////////////////////////////
// Creates a new Reality with the given id and parents. It is only used internally and therefore "private". // Creates a new Reality with the given id and parents. It is only used internally and therefore "private".
...@@ -45,7 +176,7 @@ func newReality(id RealityId, parentRealities ...RealityId) *Reality { ...@@ -45,7 +176,7 @@ func newReality(id RealityId, parentRealities ...RealityId) *Reality {
return result return result
} }
func (reality *Reality) GetLiked() (liked bool) { func (reality *Reality) IsLiked() (liked bool) {
reality.likedMutex.RLock() reality.likedMutex.RLock()
liked = reality.liked liked = reality.liked
reality.likedMutex.RUnlock() reality.likedMutex.RUnlock()
...@@ -64,6 +195,8 @@ func (reality *Reality) SetLiked(liked ...bool) (likedStatusChanged bool) { ...@@ -64,6 +195,8 @@ func (reality *Reality) SetLiked(liked ...bool) (likedStatusChanged bool) {
if reality.liked != newLikedStatus { if reality.liked != newLikedStatus {
reality.liked = newLikedStatus reality.liked = newLikedStatus
likedStatusChanged = true
reality.SetModified() reality.SetModified()
} }
reality.likedMutex.Unlock() reality.likedMutex.Unlock()
...@@ -479,7 +612,7 @@ func (reality *Reality) createRealityForPreviouslyUnconflictingConsumers(consume ...@@ -479,7 +612,7 @@ func (reality *Reality) createRealityForPreviouslyUnconflictingConsumers(consume
if cachedElevatedReality, realityErr := reality.ledgerState.realities.ComputeIfAbsent(elevatedRealityId[:], func(key []byte) (object objectstorage.StorableObject, e error) { if cachedElevatedReality, realityErr := reality.ledgerState.realities.ComputeIfAbsent(elevatedRealityId[:], func(key []byte) (object objectstorage.StorableObject, e error) {
newReality := newReality(elevatedRealityId, reality.id) newReality := newReality(elevatedRealityId, reality.id)
newReality.ledgerState = reality.ledgerState newReality.ledgerState = reality.ledgerState
newReality.SetLiked() newReality.SetPreferred()
reality.RegisterSubReality(elevatedRealityId) reality.RegisterSubReality(elevatedRealityId)
......
...@@ -12,6 +12,12 @@ func NewRealityIdSet(realityIds ...RealityId) (realityIdSet RealityIdSet) { ...@@ -12,6 +12,12 @@ func NewRealityIdSet(realityIds ...RealityId) (realityIdSet RealityIdSet) {
return return
} }
func (realityIdSet RealityIdSet) Contains(realityId RealityId) bool {
_, exists := realityIdSet[realityId]
return exists
}
func (realityIdSet RealityIdSet) Add(realityId RealityId) RealityIdSet { func (realityIdSet RealityIdSet) Add(realityId RealityId) RealityIdSet {
realityIdSet[realityId] = void realityIdSet[realityId] = void
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment