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

Fix: fixes a race condition in solidification

parent c0c74641
No related branches found
No related tags found
No related merge requests found
...@@ -1164,7 +1164,7 @@ func (tangle *Tangle) processSolidificationStackEntry(solidificationStack *list. ...@@ -1164,7 +1164,7 @@ func (tangle *Tangle) processSolidificationStackEntry(solidificationStack *list.
} }
// book the solid entities // book the solid entities
transactionBooked, _, decisionPending, bookingErr := tangle.book(solidificationStackEntry.Retain()) transactionBooked, payloadBooked, decisionPending, bookingErr := tangle.book(solidificationStackEntry.Retain())
if bookingErr != nil { if bookingErr != nil {
tangle.Events.Error.Trigger(bookingErr) tangle.Events.Error.Trigger(bookingErr)
...@@ -1177,9 +1177,12 @@ func (tangle *Tangle) processSolidificationStackEntry(solidificationStack *list. ...@@ -1177,9 +1177,12 @@ func (tangle *Tangle) processSolidificationStackEntry(solidificationStack *list.
// trigger events and schedule check of approvers / consumers // trigger events and schedule check of approvers / consumers
if transactionBooked { if transactionBooked {
tangle.Events.TransactionBooked.Trigger(solidificationStackEntry.CachedTransaction, solidificationStackEntry.CachedTransactionMetadata, decisionPending) tangle.Events.TransactionBooked.Trigger(solidificationStackEntry.CachedTransaction, solidificationStackEntry.CachedTransactionMetadata, decisionPending)
tangle.ForEachConsumers(currentTransaction, tangle.createValuePayloadFutureConeIterator(solidificationStack, processedPayloads))
}
if payloadBooked {
tangle.ForeachApprovers(currentPayload.ID(), tangle.createValuePayloadFutureConeIterator(solidificationStack, processedPayloads))
} }
tangle.ForEachConsumers(currentTransaction, tangle.createValuePayloadFutureConeIterator(solidificationStack, processedPayloads))
tangle.ForeachApprovers(currentPayload.ID(), tangle.createValuePayloadFutureConeIterator(solidificationStack, processedPayloads))
} }
func (tangle *Tangle) book(entitiesToBook *valuePayloadPropagationStackEntry) (transactionBooked bool, payloadBooked bool, decisionPending bool, err error) { func (tangle *Tangle) book(entitiesToBook *valuePayloadPropagationStackEntry) (transactionBooked bool, payloadBooked bool, decisionPending bool, err error) {
...@@ -1333,6 +1336,14 @@ func (tangle *Tangle) bookPayload(cachedPayload *payload.CachedPayload, cachedPa ...@@ -1333,6 +1336,14 @@ func (tangle *Tangle) bookPayload(cachedPayload *payload.CachedPayload, cachedPa
return return
} }
branchBranchID := tangle.payloadBranchID(valueObject.BranchID())
trunkBranchID := tangle.payloadBranchID(valueObject.TrunkID())
transactionBranchID := transactionMetadata.BranchID()
if branchBranchID == branchmanager.UndefinedBranchID || trunkBranchID == branchmanager.UndefinedBranchID || transactionBranchID == branchmanager.UndefinedBranchID {
return
}
// abort if the payload has been marked as solid before // abort if the payload has been marked as solid before
if !valueObjectMetadata.setSolid(true) { if !valueObjectMetadata.setSolid(true) {
return return
...@@ -1341,16 +1352,6 @@ func (tangle *Tangle) bookPayload(cachedPayload *payload.CachedPayload, cachedPa ...@@ -1341,16 +1352,6 @@ func (tangle *Tangle) bookPayload(cachedPayload *payload.CachedPayload, cachedPa
// trigger event if payload became solid // trigger event if payload became solid
tangle.Events.PayloadSolid.Trigger(cachedPayload, cachedPayloadMetadata) tangle.Events.PayloadSolid.Trigger(cachedPayload, cachedPayloadMetadata)
branchBranchID := tangle.payloadBranchID(valueObject.BranchID())
trunkBranchID := tangle.payloadBranchID(valueObject.TrunkID())
transactionBranchID := transactionMetadata.BranchID()
if branchBranchID == branchmanager.UndefinedBranchID ||
trunkBranchID == branchmanager.UndefinedBranchID ||
transactionBranchID == branchmanager.UndefinedBranchID {
return
}
cachedAggregatedBranch, err := tangle.BranchManager().AggregateBranches([]branchmanager.BranchID{branchBranchID, trunkBranchID, transactionBranchID}...) cachedAggregatedBranch, err := tangle.BranchManager().AggregateBranches([]branchmanager.BranchID{branchBranchID, trunkBranchID, transactionBranchID}...)
if err != nil { if err != nil {
return return
......
...@@ -341,16 +341,16 @@ func TestReverseTransactionSolidification(t *testing.T) { ...@@ -341,16 +341,16 @@ func TestReverseTransactionSolidification(t *testing.T) {
// check if outputs are found in database // check if outputs are found in database
transactions[i].Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool { transactions[i].Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool {
cachedOutput := tangle.TransactionOutput(transaction.NewOutputID(address, transactions[i].ID())) cachedOutput := tangle.TransactionOutput(transaction.NewOutputID(address, transactions[i].ID()))
assert.Truef(t, cachedOutput.Consume(func(output *Output) { require.Truef(t, cachedOutput.Consume(func(output *Output) {
// only the last outputs in chain should not be spent // only the last outputs in chain should not be spent
if i+txChains >= countTotal { if i+txChains >= countTotal {
assert.Equalf(t, 0, output.ConsumerCount(), "the output should not be spent") require.Equalf(t, 0, output.ConsumerCount(), "the output should not be spent")
} else { } else {
assert.Equalf(t, 1, output.ConsumerCount(), "the output should be spent") require.Equalf(t, 1, output.ConsumerCount(), "the output should be spent")
} }
assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1)}, output.Balances()) require.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1)}, output.Balances())
assert.Equalf(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch") require.Equalf(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch")
assert.Truef(t, output.Solid(), "the output is not solid") require.Truef(t, output.Solid(), "the output is not solid")
}), "output not found in database for tx %s", transactions[i]) }), "output not found in database for tx %s", transactions[i])
return true return true
}) })
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment