diff --git a/ton/transactions.go b/ton/transactions.go index a3f2888c..473f9465 100644 --- a/ton/transactions.go +++ b/ton/transactions.go @@ -5,12 +5,13 @@ import ( "context" "errors" "fmt" + "strings" + "time" + "github.com/xssnick/tonutils-go/address" "github.com/xssnick/tonutils-go/tl" "github.com/xssnick/tonutils-go/tlb" "github.com/xssnick/tonutils-go/tvm/cell" - "strings" - "time" ) func init() { @@ -176,16 +177,17 @@ func (c *APIClient) GetTransaction(ctx context.Context, block *BlockIDExt, addr } func (c *APIClient) SubscribeOnTransactions(workerCtx context.Context, addr *address.Address, lastProcessedLT uint64, channel chan<- *tlb.Transaction) { - defer func() { - close(channel) - }() + defer close(channel) wait := 0 * time.Second + timer := time.NewTimer(wait) + defer timer.Stop() + for { select { case <-workerCtx.Done(): return - case <-time.After(wait): + case <-timer.C: } wait = 3 * time.Second @@ -193,6 +195,7 @@ func (c *APIClient) SubscribeOnTransactions(workerCtx context.Context, addr *add master, err := c.CurrentMasterchainInfo(ctx) cancel() if err != nil { + timer.Reset(wait) continue } @@ -200,15 +203,18 @@ func (c *APIClient) SubscribeOnTransactions(workerCtx context.Context, addr *add acc, err := c.GetAccount(ctx, master, addr) cancel() if err != nil { + timer.Reset(wait) continue } if !acc.IsActive || acc.LastTxLT == 0 { // no transactions + timer.Reset(wait) continue } if lastProcessedLT == acc.LastTxLT { // already processed all + timer.Reset(wait) continue } @@ -216,12 +222,15 @@ func (c *APIClient) SubscribeOnTransactions(workerCtx context.Context, addr *add lastHash, lastLT := acc.LastTxHash, acc.LastTxLT waitList := 0 * time.Second + listTimer := time.NewTimer(waitList) + list: for { select { case <-workerCtx.Done(): + listTimer.Stop() return - case <-time.After(waitList): + case <-listTimer.C: } ctx, cancel = context.WithTimeout(workerCtx, 10*time.Second) @@ -230,9 +239,11 @@ func (c *APIClient) SubscribeOnTransactions(workerCtx context.Context, addr *add if err != nil { if lsErr, ok := err.(LSError); ok && lsErr.Code == -400 { // lt not in db error + listTimer.Stop() return } waitList = 3 * time.Second + listTimer.Reset(waitList) continue } @@ -255,8 +266,11 @@ func (c *APIClient) SubscribeOnTransactions(workerCtx context.Context, addr *add lastLT, lastHash = res[len(res)-1].PrevTxLT, res[len(res)-1].PrevTxHash transactions = append(transactions, res...) waitList = 0 * time.Second + listTimer.Reset(waitList) } + listTimer.Stop() + if len(transactions) > 0 { lastProcessedLT = transactions[0].LT // mark last transaction as known to not trigger twice @@ -271,6 +285,8 @@ func (c *APIClient) SubscribeOnTransactions(workerCtx context.Context, addr *add wait = 0 * time.Second } + + timer.Reset(wait) } }