Skip to content

Commit

Permalink
Improve rVASP error handling (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
pdeziel authored Jul 6, 2022
1 parent cf90603 commit 1338796
Show file tree
Hide file tree
Showing 9 changed files with 304 additions and 239 deletions.
30 changes: 18 additions & 12 deletions lib/python/rvaspy/rvaspy/api_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 7 additions & 5 deletions pkg/rvasp/async.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ func (s *TRISA) handleAsync(ctx context.Context) {

now := time.Now()
txloop:
for _, tx := range transactions {
for _, transaction := range transactions {
tx := &transaction

// Verify pending transaction is old enough
if now.Before(tx.NotBefore) {
continue
Expand All @@ -78,21 +80,21 @@ txloop:
// Verify pending transaction has not expired
if now.After(tx.NotAfter) {
log.Info().Uint("id", tx.ID).Time("not_after", tx.NotAfter).Msg("transaction expired")
tx.State = pb.TransactionState_EXPIRED
tx.SetState(pb.TransactionState_EXPIRED)
if err = s.parent.db.Save(&tx).Error; err != nil {
log.Error().Err(err).Uint("id", tx.ID).Msg("could not save expired transaction")
}
continue txloop
}

// Acknowledge the transaction with the originator
if err = s.acknowledgeTransaction(&tx); err != nil {
if err = s.acknowledgeTransaction(tx); err != nil {
log.Warn().Err(err).Uint("id", tx.ID).Msg("could not acknowledge transaction")
tx.State = pb.TransactionState_FAILED
tx.SetState(pb.TransactionState_FAILED)
}

// Save the updated transaction in the database
if err = s.parent.db.Save(&tx).Error; err != nil {
if err = s.parent.db.Save(tx).Error; err != nil {
log.Error().Err(err).Uint("id", tx.ID).Msg("could not save completed transaction")
}
}
Expand Down
20 changes: 14 additions & 6 deletions pkg/rvasp/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,13 @@ func (d *DB) LookupWallet(address string) *gorm.DB {
// MakeTransaction returns a new Transaction from the originator and beneficiary
// wallet addresses. Note: this does not store the transaction in the database to allow
// the caller to modify the transaction fields before storage.
func (d *DB) MakeTransaction(originator string, beneficiary string) (Transaction, error) {
func (d *DB) MakeTransaction(originator string, beneficiary string) (*Transaction, error) {
var originatorIdentity, beneficiaryIdentity Identity

// Fetch originator identity record
if err := d.LookupIdentity(originator).FirstOrInit(&originatorIdentity, Identity{}).Error; err != nil {
log.Error().Err(err).Msg("could not lookup originator identity")
return Transaction{}, status.Errorf(codes.FailedPrecondition, "could not lookup originator identity: %s", err)
return nil, status.Errorf(codes.FailedPrecondition, "could not lookup originator identity: %s", err)
}

// If originator identity does not exist then create it
Expand All @@ -127,14 +127,14 @@ func (d *DB) MakeTransaction(originator string, beneficiary string) (Transaction

if err := d.Create(&originatorIdentity).Error; err != nil {
log.Error().Err(err).Msg("could not save originator identity")
return Transaction{}, status.Errorf(codes.FailedPrecondition, "could not save originator identity: %s", err)
return nil, status.Errorf(codes.FailedPrecondition, "could not save originator identity: %s", err)
}
}

// Fetch beneficiary identity record
if err := d.LookupIdentity(beneficiary).FirstOrInit(&beneficiaryIdentity, Identity{}).Error; err != nil {
log.Error().Err(err).Msg("could not lookup beneficiary identity")
return Transaction{}, status.Errorf(codes.FailedPrecondition, "could not lookup beneficiary identity: %s", err)
return nil, status.Errorf(codes.FailedPrecondition, "could not lookup beneficiary identity: %s", err)
}

// If the beneficiary identity does not exist then create it
Expand All @@ -144,15 +144,16 @@ func (d *DB) MakeTransaction(originator string, beneficiary string) (Transaction

if err := d.Create(&beneficiaryIdentity).Error; err != nil {
log.Error().Err(err).Msg("could not save beneficiary identity")
return Transaction{}, status.Errorf(codes.FailedPrecondition, "could not save beneficiary identity: %s", err)
return nil, status.Errorf(codes.FailedPrecondition, "could not save beneficiary identity: %s", err)
}
}

return Transaction{
return &Transaction{
Envelope: uuid.New().String(),
Originator: originatorIdentity,
Beneficiary: beneficiaryIdentity,
State: pb.TransactionState_AWAITING,
StateString: pb.TransactionState_AWAITING.String(),
Timestamp: time.Now(),
Vasp: d.vasp,
}, nil
Expand Down Expand Up @@ -260,6 +261,7 @@ type Transaction struct {
Amount decimal.Decimal `gorm:"type:decimal(15,8)"`
Debit bool `gorm:"not null"`
State pb.TransactionState `gorm:"not null;default:0"`
StateString string `gorm:"column:state_string;not null"`
Timestamp time.Time `gorm:"not null"`
NotBefore time.Time `gorm:"not null"`
NotAfter time.Time `gorm:"not null"`
Expand All @@ -274,6 +276,12 @@ func (Transaction) TableName() string {
return "transactions"
}

// Set the transaction state to a new value
func (t *Transaction) SetState(state pb.TransactionState) {
t.State = state
t.StateString = state.String()
}

// Identity holds raw data for an originator or a beneficiary that was sent as
// part of the transaction process. This should not be stored in the wallet since the
// wallet is a representation of the local VASPs knowledge about customers and bercause
Expand Down
Loading

0 comments on commit 1338796

Please sign in to comment.