diff --git a/packages/ledgerstate/ledgerstate_test.go b/packages/ledgerstate/ledgerstate_test.go index 6c36a10338f778cd05f74d2028581108792a8bef..4727db2de3e83282fb1f3ed6f789213f94b9c9b3 100644 --- a/packages/ledgerstate/ledgerstate_test.go +++ b/packages/ledgerstate/ledgerstate_test.go @@ -152,32 +152,23 @@ func spend(ledgerState *LedgerState, transferOutputReferences ...*TransferOutput transferHash := generateRandomTransferHash() addressHash := generateRandomAddressHash() - transfer := NewTransfer(transferHash).AddOutput( - addressHash, NewColoredBalance(iota_, uint64(len(transferOutputReferences))*1337), - ) - for _, transferOutputReference := range transferOutputReferences { - transfer.AddInput(transferOutputReference) - } - - if err := ledgerState.BookTransfer(transfer); err != nil { - panic(err) - } - - result = NewTransferOutputReference(transferHash, addressHash) + totalInputBalance := uint64(0) - return -} + transfer := NewTransfer(transferHash) + for _, transferOutputReference := range transferOutputReferences { + ledgerState.GetTransferOutput(transferOutputReference).Consume(func(object objectstorage.StorableObject) { + transferOutput := object.(*TransferOutput) -func spend2(ledgerState *LedgerState, transferOutputReferences ...*TransferOutputReference) (result *TransferOutputReference) { - transferHash := generateRandomTransferHash() - addressHash := generateRandomAddressHash() + for _, coloredBalance := range transferOutput.GetBalances() { + totalInputBalance += coloredBalance.GetValue() + } + }) - transfer := NewTransfer(transferHash).AddOutput( - addressHash, NewColoredBalance(iota_, uint64(len(transferOutputReferences))*2*1337), - ) - for _, transferOutputReference := range transferOutputReferences { transfer.AddInput(transferOutputReference) } + transfer.AddOutput( + addressHash, NewColoredBalance(iota_, totalInputBalance), + ) if err := ledgerState.BookTransfer(transfer); err != nil { panic(err) @@ -195,7 +186,7 @@ func TestElevateAggregatedReality(t *testing.T) { doubleSpentOutputs1 := doubleSpend(ledgerState, transferOutputs[0]) doubleSpentOutputs2 := doubleSpend(ledgerState, transferOutputs[1]) normalSpend := spend(ledgerState, transferOutputs[2]) - _ = doubleSpend(ledgerState, normalSpend) + doubleSpentOutputs3 := doubleSpend(ledgerState, normalSpend) // send funds from one of the double spends further spentInput := spend(ledgerState, doubleSpentOutputs1[1]) @@ -207,10 +198,13 @@ func TestElevateAggregatedReality(t *testing.T) { spend(ledgerState, doubleSpentOutputs1[1]) // double spend funds of aggregated reality - spend(ledgerState, spentInput, doubleSpentOutputs2[0]) + //spend(ledgerState, spentInput, doubleSpentOutputs2[0]) // spend funds of conflict in aggregated reality further - spend2(ledgerState, outputOfAggregatedReality) + //lastOutputOfAggregatedReality := spend(ledgerState, outputOfAggregatedReality) + + //spend(ledgerState, lastOutputOfAggregatedReality, doubleSpentOutputs3[1]) + spend(ledgerState, spend(ledgerState, spend(ledgerState, outputOfAggregatedReality, spend(ledgerState, doubleSpentOutputs3[1])))) time.Sleep(1000 * time.Millisecond) diff --git a/packages/ledgerstate/outputs.png b/packages/ledgerstate/outputs.png index 3c9f53b9f5faaac17c0e4f188387bc0bdc5b8232..d681a69339839d9272253fc74b47ed3d313af085 100644 Binary files a/packages/ledgerstate/outputs.png and b/packages/ledgerstate/outputs.png differ diff --git a/packages/ledgerstate/realities.png b/packages/ledgerstate/realities.png index 789f1c48bb59962df9ec5af99bcfb7410b387968..081531cd0633c8945012907f4023596c4c9cc3b8 100644 Binary files a/packages/ledgerstate/realities.png and b/packages/ledgerstate/realities.png differ diff --git a/packages/ledgerstate/reality.go b/packages/ledgerstate/reality.go index 5be5e02ac4cc1c0f79c1ab55a1501e0d2ced86c8..62a15f7c3802a003c105ec8ca977359e011b8f1a 100644 --- a/packages/ledgerstate/reality.go +++ b/packages/ledgerstate/reality.go @@ -127,6 +127,33 @@ func (reality *Reality) GetParentRealities() map[RealityId]*objectstorage.Cached return parentRealities } +// Returns +func (reality *Reality) GetParentConflictRealities() map[RealityId]*objectstorage.CachedObject { + if !reality.IsAggregated() { + return reality.GetParentRealities() + } else { + parentConflictRealities := make(map[RealityId]*objectstorage.CachedObject) + + reality.collectParentConflictRealities(parentConflictRealities) + + return parentConflictRealities + } +} + +func (reality *Reality) collectParentConflictRealities(parentConflictRealities map[RealityId]*objectstorage.CachedObject) { + for realityId, cachedParentReality := range reality.GetParentRealities() { + parentReality := cachedParentReality.Get().(*Reality) + + if !parentReality.IsAggregated() { + parentConflictRealities[realityId] = cachedParentReality + } else { + parentReality.collectParentConflictRealities(parentConflictRealities) + + cachedParentReality.Release() + } + } +} + // [DONE] Returns a map of all ancestor realities (up till the MAIN_REALITY). They have to manually be "released" when // they are not needed anymore. func (reality *Reality) GetAncestorRealities() (result map[RealityId]*objectstorage.CachedObject) { diff --git a/packages/ledgerstate/visualizer.go b/packages/ledgerstate/visualizer.go index 53c700a7017371550f76ad0922cc011a2928a273..44552e1dd7c30fc95eb3de38951158198bbe2462 100644 --- a/packages/ledgerstate/visualizer.go +++ b/packages/ledgerstate/visualizer.go @@ -100,7 +100,7 @@ func (visualizer *Visualizer) getRealitySubGraph(realityId RealityId) *dot.Graph parentRealities := reality.GetParentRealityIds() switch true { case len(parentRealities) > 1: - realityGraph = visualizer.getRealitySubGraph(MAIN_REALITY_ID).Subgraph(visualizer.generateRealityName(parentRealities.ToList()...), dot.ClusterOption{}) + realityGraph = visualizer.getRealitySubGraph(MAIN_REALITY_ID).Subgraph("AGGREGATED REALITY [ "+visualizer.generateRealityName(realityId)+" ]", dot.ClusterOption{}) visualizer.styleRealitySubGraph(realityGraph, realityTypeAggregated) @@ -112,7 +112,7 @@ func (visualizer *Visualizer) getRealitySubGraph(realityId RealityId) *dot.Graph //dummyNode.Attr("width", "0") case len(parentRealities) == 1: for parentRealityId := range parentRealities { - realityGraph = visualizer.getRealitySubGraph(parentRealityId).Subgraph(visualizer.generateRealityName(realityId), dot.ClusterOption{}) + realityGraph = visualizer.getRealitySubGraph(parentRealityId).Subgraph("REALITY [ "+visualizer.generateRealityName(realityId)+" ]", dot.ClusterOption{}) visualizer.styleRealitySubGraph(realityGraph, realityTypeDefault) } @@ -148,29 +148,31 @@ func (visualizer *Visualizer) styleRealitySubGraph(realitySubGraph *dot.Graph, r } } -func (visualizer *Visualizer) generateRealityName(realityIds ...RealityId) string { - if len(realityIds) > 1 { - result := "AGGREGATED REALITY [ " +func (visualizer *Visualizer) generateRealityName(realityId RealityId) (result string) { + visualizer.ledgerState.GetReality(realityId).Consume(func(object objectstorage.StorableObject) { + reality := object.(*Reality) - realityIdCount := len(realityIds) - for id, realityId := range realityIds { - if id == realityIdCount-1 { - result += strings.Trim(realityId.String(), "\x00") - } else { - result += strings.Trim(realityId.String(), "\x00") + " + " - } - } + if reality.IsAggregated() { + parentConflictRealities := reality.GetParentConflictRealities() + realityIdCount := len(parentConflictRealities) + counter := 1 + for realityId, parentConflictReality := range parentConflictRealities { + result += visualizer.generateRealityName(realityId) + + if counter != realityIdCount { + result += " + " + } - result += " ]" + counter++ - return result - } else { - if realityIds[0] == MAIN_REALITY_ID { - return strings.Trim(realityIds[0].String(), "\x00") + parentConflictReality.Release() + } + } else { + result = strings.Trim(realityId.String(), "\x00") } + }) - return "REALITY [ " + strings.Trim(realityIds[0].String(), "\x00") + " ]" - } + return } type realityType int