diff --git a/dapps/valuetransfers/packages/tangle/tangle.go b/dapps/valuetransfers/packages/tangle/tangle.go index 95aa24d75cb19aab8d20ffb83e93f37035cbe657..b28aec89023e29310aab1b42d3f4186c768a1b9e 100644 --- a/dapps/valuetransfers/packages/tangle/tangle.go +++ b/dapps/valuetransfers/packages/tangle/tangle.go @@ -1264,6 +1264,7 @@ func (tangle *Tangle) bookTransaction(cachedTransaction *transaction.CachedTrans conflictingInputs := make([]transaction.OutputID, 0) conflictingInputsOfFirstConsumers := make(map[transaction.ID][]transaction.OutputID) + finalizedConflictingSpenderFound := false if !transactionToBook.Inputs().ForEach(func(outputID transaction.OutputID) bool { cachedOutput := tangle.TransactionOutput(outputID) defer cachedOutput.Release() @@ -1294,6 +1295,17 @@ func (tangle *Tangle) bookTransaction(cachedTransaction *transaction.CachedTrans conflictingInputsOfFirstConsumers[firstConsumerID] = append(conflictingInputsOfFirstConsumers[firstConsumerID], outputID) } + // check if any of the consumers were finalized already + if !finalizedConflictingSpenderFound { + tangle.Consumers(outputID).Consume(func(consumer *Consumer) { + if !finalizedConflictingSpenderFound { + tangle.TransactionMetadata(consumer.TransactionID()).Consume(func(metadata *TransactionMetadata) { + finalizedConflictingSpenderFound = metadata.Preferred() && metadata.Finalized() + }) + } + }) + } + // mark input as conflicting conflictingInputs = append(conflictingInputs, outputID) @@ -1357,16 +1369,18 @@ func (tangle *Tangle) bookTransaction(cachedTransaction *transaction.CachedTrans return true }) - // fork the conflicting transactions into their own branch - for consumerID, conflictingInputs := range conflictingInputsOfFirstConsumers { - _, decisionFinalized, forkedErr := tangle.Fork(consumerID, conflictingInputs) - if forkedErr != nil { - err = forkedErr + // fork the conflicting transactions into their own branch if a decision is still pending + if decisionPending = !finalizedConflictingSpenderFound; decisionPending { + for consumerID, conflictingInputs := range conflictingInputsOfFirstConsumers { + _, decisionFinalized, forkedErr := tangle.Fork(consumerID, conflictingInputs) + if forkedErr != nil { + err = forkedErr - return - } + return + } - decisionPending = decisionPending || !decisionFinalized + decisionPending = decisionPending || !decisionFinalized + } } transactionBooked = true diff --git a/dapps/valuetransfers/packages/tangle/tangle_test.go b/dapps/valuetransfers/packages/tangle/tangle_test.go index dab6589cc4d360d0fa88d0651f74a08000749a05..c3f897ee104df06eb1d7897829aa4e2d09ae5982 100644 --- a/dapps/valuetransfers/packages/tangle/tangle_test.go +++ b/dapps/valuetransfers/packages/tangle/tangle_test.go @@ -106,7 +106,7 @@ func TestBookTransaction(t *testing.T) { transactionBooked, decisionPending, err := tangle.bookTransaction(cachedTransaction, cachedTransactionMetadata) require.NoError(t, err) assert.True(t, transactionBooked, "transactionBooked") - assert.False(t, decisionPending, "decisionPending") + assert.True(t, decisionPending, "decisionPending") // assert that branchID is the same as the MasterBranchID assert.Equal(t, branchmanager.MasterBranchID, txMetadata.BranchID())