Skip to content

Commit

Permalink
[PSL-1214] handle duplicate burn-txid edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
j-rafique committed Jul 10, 2024
1 parent 9b5a2bd commit 99fcad1
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 2 deletions.
4 changes: 2 additions & 2 deletions mixins/pasteld_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ func (pt *PastelHandler) GetBurnAddress() string {
func (pt *PastelHandler) ValidateBurnTxID(ctx context.Context, burnTxnID string, estimatedFee float64) error {
var err error

if err := pt.checkBurnTxID(ctx, burnTxnID); err != nil {
if err := pt.CheckBurnTxID(ctx, burnTxnID); err != nil {
log.WithContext(ctx).WithError(err).Errorf("duplicate burnTXID")
err = errors.Errorf("validated burnTXID :%w", err)
return err
Expand All @@ -329,7 +329,7 @@ func (pt *PastelHandler) ValidateBurnTxID(ctx context.Context, burnTxnID string,
return nil
}

func (pt *PastelHandler) checkBurnTxID(ctx context.Context, burnTXID string) error {
func (pt *PastelHandler) CheckBurnTxID(ctx context.Context, burnTXID string) error {
actionTickets, err := pt.PastelClient.FindActionRegTicketsByLabel(ctx, burnTXID)
if err != nil {
return fmt.Errorf("action reg tickets by label: %w", err)
Expand Down
67 changes: 67 additions & 0 deletions walletnode/api/services/cascade.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ func (service *CascadeAPIHandler) StartProcessing(ctx context.Context, p *cascad
}
sortedRelatedFiles := service.register.SortFilesWithHigherAmounts(relatedFiles)

err = service.checkBurnTxIDsValidForRegistration(ctx, sortedBurnTxids, sortedRelatedFiles)
if err != nil {
log.WithContext(ctx).WithField("related_volumes", len(relatedFiles)).
WithError(err).
WithField("burn_txids", len(p.BurnTxids)).
Error("given burn-tx-ids are not valid")
return nil, cascade.MakeBadRequest(errors.New("given burn txids are not valid"))
}

var taskIDs []string
for index, file := range sortedRelatedFiles {
burnTxID := sortedBurnTxids[index]
Expand Down Expand Up @@ -558,12 +567,30 @@ func (service *CascadeAPIHandler) Restore(ctx context.Context, p *cascade.Restor
if unConcludedVolume.RegTxid == "" {
logger.WithField("volume_name", unConcludedVolume.FileID).Info("find a volume with no registration, trying again...")

<<<<<<< Updated upstream
burnTxId, err := service.register.GetBurnTxIdByAmount(ctx, int64(unConcludedVolume.ReqBurnTxnAmount))
if err != nil {
log.WithContext(ctx).WithField("amount", int64(unConcludedVolume.ReqBurnTxnAmount)).WithError(err).Error("error getting burn TxId for amount")
return nil, cascade.MakeInternalServerError(err)
}
logger.WithField("volume_name", unConcludedVolume.FileID).Info("estimated fee has been burned, sending for registration")
=======
var burnTxId string
if service.IsBurnTxIDValidForRecovery(ctx, v.BurnTxnID, v.ReqAmount-10) {
log.WithContext(ctx).WithField("burn_txid", v.BurnTxnID).Info("existing burn-txid is valid")
burnTxId = v.BurnTxnID
} else {
log.WithContext(ctx).WithField("burn_txid", v.BurnTxnID).Info("existing burn-txid is not valid, burning the new txid")

burnTxId, err = service.register.GetBurnTxIdByAmount(ctx, int64(v.ReqBurnTxnAmount))
if err != nil {
log.WithContext(ctx).WithField("amount", int64(v.ReqBurnTxnAmount)).WithError(err).Error("error getting burn TxId for amount")
return nil, cascade.MakeInternalServerError(err)
}

logger.WithField("volume_name", v.FileID).Info("estimated fee has been burned, sending for registration")
}
>>>>>>> Stashed changes

addTaskPayload := &common.AddTaskPayload{
FileID: unConcludedVolume.FileID,
Expand All @@ -577,7 +604,13 @@ func (service *CascadeAPIHandler) Restore(ctx context.Context, p *cascade.Restor
addTaskPayload.SpendableAddress = p.SpendableAddress
}

<<<<<<< Updated upstream
_, err = service.register.ProcessFile(ctx, *unConcludedVolume, addTaskPayload)
=======
service.register.Worker.Tasks()

_, err = service.register.ProcessFile(ctx, *v, addTaskPayload)
>>>>>>> Stashed changes
if err != nil {
log.WithContext(ctx).WithField("file_id", unConcludedVolume.FileID).WithError(err).Error("error processing un-concluded volume")
continue
Expand Down Expand Up @@ -633,6 +666,40 @@ func (service *CascadeAPIHandler) Restore(ctx context.Context, p *cascade.Restor
}, nil
}

func (service *CascadeAPIHandler) checkBurnTxIDsValidForRegistration(ctx context.Context, burnTxIDs []string, files types.Files) error {
if isDuplicateExists(burnTxIDs) {
return errors.New("duplicate burn-tx-ids provided")
}

for _, bid := range burnTxIDs {
if err := service.register.CheckBurnTxIDTicketDuplication(ctx, bid); err != nil {
return err
}
}

for i := 0; i < len(files); i++ {
err := service.register.ValidBurnTxnAmount(ctx, burnTxIDs[i], files[i].ReqBurnTxnAmount)
if err != nil {
return err
}
}

return nil
}

func (service *CascadeAPIHandler) IsBurnTxIDValidForRecovery(ctx context.Context, burnTxID string, estimatedFee float64) bool {
if err := service.register.CheckBurnTxIDTicketDuplication(ctx, burnTxID); err != nil {
return false
}

err := service.register.ValidateBurnTxn(ctx, burnTxID, estimatedFee)
if err != nil {
return false
}

return true
}

// NewCascadeAPIHandler returns the swagger OpenAPI implementation.
func NewCascadeAPIHandler(config *Config, filesMap *sync.Map, register *cascaderegister.CascadeRegistrationService, download *download.NftDownloadingService) *CascadeAPIHandler {
return &CascadeAPIHandler{
Expand Down
29 changes: 29 additions & 0 deletions walletnode/services/cascaderegister/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,35 @@ func (service *CascadeRegistrationService) RegisterVolumeTicket(ctx context.Cont
return txID, nil
}

func (service *CascadeRegistrationService) CheckBurnTxIDTicketDuplication(ctx context.Context, burnTxID string) error {
err := service.pastelHandler.CheckBurnTxID(ctx, burnTxID)
if err != nil {
return err
}

return nil
}

func (service *CascadeRegistrationService) ValidBurnTxnAmount(ctx context.Context, burnTxID string, estimatedFee float64) error {
txnDetail, err := service.pastelHandler.PastelClient.GetTransaction(ctx, burnTxID)
if err != nil {
return err
}

burnTxnAmount := math.Round(math.Abs(txnDetail.Amount)*100) / 100
estimatedFeeAmount := math.Round(estimatedFee*100) / 100

if burnTxnAmount >= estimatedFeeAmount {
return nil
}

return errors.New("the amounts are not equal")
}

func (service *CascadeRegistrationService) ValidateBurnTxn(ctx context.Context, burnTxID string, estimatedFee float64) error {
return service.pastelHandler.ValidateBurnTxID(ctx, burnTxID, estimatedFee)
}

// NewService returns a new Service instance
func NewService(config *Config, pastelClient pastel.Client, nodeClient node.ClientInterface,
fileStorage storage.FileStorageInterface, db storage.KeyValue,
Expand Down

0 comments on commit 99fcad1

Please sign in to comment.