Skip to content

Commit c7c0c6b

Browse files
committed
[PSL-1214] handle duplicate burn-txid edge cases
1 parent 43db4a5 commit c7c0c6b

File tree

3 files changed

+88
-7
lines changed

3 files changed

+88
-7
lines changed

mixins/pasteld_handler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ func (pt *PastelHandler) GetBurnAddress() string {
302302
func (pt *PastelHandler) ValidateBurnTxID(ctx context.Context, burnTxnID string, estimatedFee float64) error {
303303
var err error
304304

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

332-
func (pt *PastelHandler) checkBurnTxID(ctx context.Context, burnTXID string) error {
332+
func (pt *PastelHandler) CheckBurnTxID(ctx context.Context, burnTXID string) error {
333333
actionTickets, err := pt.PastelClient.FindActionRegTicketsByLabel(ctx, burnTXID)
334334
if err != nil {
335335
return fmt.Errorf("action reg tickets by label: %w", err)

walletnode/api/services/cascade.go

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,15 @@ func (service *CascadeAPIHandler) StartProcessing(ctx context.Context, p *cascad
178178
}
179179
sortedRelatedFiles := service.register.SortFilesWithHigherAmounts(relatedFiles)
180180

181+
err = service.checkBurnTxIDsValidForRegistration(ctx, sortedBurnTxids, sortedRelatedFiles)
182+
if err != nil {
183+
log.WithContext(ctx).WithField("related_volumes", len(relatedFiles)).
184+
WithError(err).
185+
WithField("burn_txids", len(p.BurnTxids)).
186+
Error("given burn-tx-ids are not valid")
187+
return nil, cascade.MakeBadRequest(errors.New("given burn txids are not valid"))
188+
}
189+
181190
var taskIDs []string
182191
for index, file := range sortedRelatedFiles {
183192
burnTxID := sortedBurnTxids[index]
@@ -587,12 +596,21 @@ func (service *CascadeAPIHandler) Restore(ctx context.Context, p *cascade.Restor
587596
volumesWithPendingRegistration++
588597
logger.WithField("volume_name", v.FileID).Info("find a volume with no registration, trying again...")
589598

590-
burnTxId, err := service.register.GetBurnTxIdByAmount(ctx, int64(v.ReqBurnTxnAmount))
591-
if err != nil {
592-
log.WithContext(ctx).WithField("amount", int64(v.ReqBurnTxnAmount)).WithError(err).Error("error getting burn TxId for amount")
593-
return nil, cascade.MakeInternalServerError(err)
599+
var burnTxId string
600+
if service.IsBurnTxIDValidForRecovery(ctx, v.BurnTxnID, v.ReqAmount-10) {
601+
log.WithContext(ctx).WithField("burn_txid", v.BurnTxnID).Info("existing burn-txid is valid")
602+
burnTxId = v.BurnTxnID
603+
} else {
604+
log.WithContext(ctx).WithField("burn_txid", v.BurnTxnID).Info("existing burn-txid is not valid, burning the new txid")
605+
606+
burnTxId, err = service.register.GetBurnTxIdByAmount(ctx, int64(v.ReqBurnTxnAmount))
607+
if err != nil {
608+
log.WithContext(ctx).WithField("amount", int64(v.ReqBurnTxnAmount)).WithError(err).Error("error getting burn TxId for amount")
609+
return nil, cascade.MakeInternalServerError(err)
610+
}
611+
612+
logger.WithField("volume_name", v.FileID).Info("estimated fee has been burned, sending for registration")
594613
}
595-
logger.WithField("volume_name", v.FileID).Info("estimated fee has been burned, sending for registration")
596614

597615
addTaskPayload := &common.AddTaskPayload{
598616
FileID: v.FileID,
@@ -668,6 +686,40 @@ func (service *CascadeAPIHandler) Restore(ctx context.Context, p *cascade.Restor
668686
}, nil
669687
}
670688

689+
func (service *CascadeAPIHandler) checkBurnTxIDsValidForRegistration(ctx context.Context, burnTxIDs []string, files types.Files) error {
690+
if isDuplicateExists(burnTxIDs) {
691+
return errors.New("duplicate burn-tx-ids provided")
692+
}
693+
694+
for _, bid := range burnTxIDs {
695+
if err := service.register.CheckBurnTxIDTicketDuplication(ctx, bid); err != nil {
696+
return err
697+
}
698+
}
699+
700+
for i := 0; i < len(files); i++ {
701+
err := service.register.ValidBurnTxnAmount(ctx, burnTxIDs[i], files[i].ReqBurnTxnAmount)
702+
if err != nil {
703+
return err
704+
}
705+
}
706+
707+
return nil
708+
}
709+
710+
func (service *CascadeAPIHandler) IsBurnTxIDValidForRecovery(ctx context.Context, burnTxID string, estimatedFee float64) bool {
711+
if err := service.register.CheckBurnTxIDTicketDuplication(ctx, burnTxID); err != nil {
712+
return false
713+
}
714+
715+
err := service.register.ValidateBurnTxn(ctx, burnTxID, estimatedFee)
716+
if err != nil {
717+
return false
718+
}
719+
720+
return true
721+
}
722+
671723
// NewCascadeAPIHandler returns the swagger OpenAPI implementation.
672724
func NewCascadeAPIHandler(config *Config, filesMap *sync.Map, register *cascaderegister.CascadeRegistrationService, download *download.NftDownloadingService) *CascadeAPIHandler {
673725
return &CascadeAPIHandler{

walletnode/services/cascaderegister/service.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,35 @@ func (service *CascadeRegistrationService) RegisterVolumeTicket(ctx context.Cont
714714
return txID, nil
715715
}
716716

717+
func (service *CascadeRegistrationService) CheckBurnTxIDTicketDuplication(ctx context.Context, burnTxID string) error {
718+
err := service.pastelHandler.CheckBurnTxID(ctx, burnTxID)
719+
if err != nil {
720+
return err
721+
}
722+
723+
return nil
724+
}
725+
726+
func (service *CascadeRegistrationService) ValidBurnTxnAmount(ctx context.Context, burnTxID string, estimatedFee float64) error {
727+
txnDetail, err := service.pastelHandler.PastelClient.GetTransaction(ctx, burnTxID)
728+
if err != nil {
729+
return err
730+
}
731+
732+
burnTxnAmount := math.Round(math.Abs(txnDetail.Amount)*100) / 100
733+
estimatedFeeAmount := math.Round(estimatedFee*100) / 100
734+
735+
if burnTxnAmount >= estimatedFeeAmount {
736+
return nil
737+
}
738+
739+
return errors.New("the amounts are not equal")
740+
}
741+
742+
func (service *CascadeRegistrationService) ValidateBurnTxn(ctx context.Context, burnTxID string, estimatedFee float64) error {
743+
return service.pastelHandler.ValidateBurnTxID(ctx, burnTxID, estimatedFee)
744+
}
745+
717746
// NewService returns a new Service instance
718747
func NewService(config *Config, pastelClient pastel.Client, nodeClient node.ClientInterface,
719748
fileStorage storage.FileStorageInterface, db storage.KeyValue,

0 commit comments

Comments
 (0)