Skip to content

Commit

Permalink
Feat: started implementing error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
hmoog committed Apr 10, 2022
1 parent e9ae091 commit f8f8194
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
28 changes: 19 additions & 9 deletions packages/ledger/dataflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,7 @@ func (d *dataFlow) processTransaction() (dataFlow *dataflow.DataFlow[*dataFlowPa
d.ledger.booker.checkAlreadyBookedCommand,
d.checkTransaction().ChainedCommand,
d.ledger.booker.bookTransactionCommand,
).WithErrorCallback(func(err error, params *dataFlowParams) {
if errors.Is(err, ErrTransactionUnsolid) {
return
}

d.ledger.Events.Error.Trigger(err)

// TODO: mark Transaction as invalid and trigger invalid event
})
).WithErrorCallback(d.handleError)
}

// checkTransaction returns a DataFlow that checks the validity of a Transaction.
Expand All @@ -56,6 +48,24 @@ func (d *dataFlow) checkTransaction() (dataFlow *dataflow.DataFlow[*dataFlowPara
)
}

// handleError handles any kind of error that is encountered while processing the DataFlows.
func (d *dataFlow) handleError(err error, params *dataFlowParams) {
if errors.Is(err, ErrTransactionUnsolid) {
return
}

if errors.Is(err, ErrTransactionInvalid) {
d.ledger.Events.TransactionInvalid.Trigger(&TransactionInvalidEvent{
TransactionID: params.Transaction.ID(),
Reason: err,
})

return
}

d.ledger.Events.Error.Trigger(err)
}

// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////

// region dataFlowParams ///////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
16 changes: 16 additions & 0 deletions packages/ledger/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ type Events struct {
// TransactionBranchIDUpdated is an event that gets triggered whenever the Branch of a Transaction is updated.
TransactionBranchIDUpdated *event.Event[*TransactionBranchIDUpdatedEvent]

TransactionInvalid *event.Event[*TransactionInvalidEvent]

// Error is event that gets triggered whenever an error occurs while processing a Transaction.
Error *event.Event[error]
}
Expand All @@ -34,6 +36,7 @@ func newEvents() (new *Events) {
TransactionBooked: event.New[*TransactionBookedEvent](),
TransactionForked: event.New[*TransactionForkedEvent](),
TransactionBranchIDUpdated: event.New[*TransactionBranchIDUpdatedEvent](),
TransactionInvalid: event.New[*TransactionInvalidEvent](),
Error: event.New[error](),
}
}
Expand Down Expand Up @@ -92,3 +95,16 @@ type TransactionBranchIDUpdatedEvent struct {
}

// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////

// region TransactionInvalidEvent //////////////////////////////////////////////////////////////////////////////////////

// TransactionInvalidEvent is a container that acts as a dictionary for the TransactionInvalid event related parameters.
type TransactionInvalidEvent struct {
// TransactionID contains the identifier of the Transaction that was found to be invalid.
TransactionID utxo.TransactionID

// Reason contains the error that caused the Transaction to be considered invalid.
Reason error
}

// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
9 changes: 9 additions & 0 deletions packages/ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func New(options ...Option) (ledger *Ledger) {
ledger.processConsumingTransactions(event.Outputs.IDs())
}))

ledger.Events.TransactionInvalid.Attach(event.NewClosure[*TransactionInvalidEvent](func(event *TransactionInvalidEvent) {
ledger.PruneTransaction(event.TransactionID)
}))

return ledger
}

Expand All @@ -76,6 +80,11 @@ func (l *Ledger) StoreAndProcessTransaction(tx utxo.Transaction) (err error) {
return l.dataFlow.storeAndProcessTransaction().Run(newDataFlowParams(NewTransaction(tx)))
}

// PruneTransaction removes a Transaction from the Ledger (e.g. after it was orphaned or found to be invalid).
func (l *Ledger) PruneTransaction(txID utxo.TransactionID) {
// TODO: IMPLEMENT PRUNING LOGIC
}

// processTransaction tries to book a single Transaction.
func (l *Ledger) processTransaction(tx *Transaction) (err error) {
l.mutex.Lock(tx.ID())
Expand Down

0 comments on commit f8f8194

Please sign in to comment.