-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
101 lines (84 loc) · 2.89 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package catapult_sync
import (
"context"
"sync"
"time"
"github.com/proximax-storage/go-xpx-chain-sdk/sdk"
"github.com/proximax-storage/go-xpx-chain-sdk/sdk/websocket"
)
// Announce announces transaction, waits till it confirmed and returns hash or error if any
func Announce(ctx context.Context, config *sdk.Config, client websocket.CatapultClient, from *sdk.Account, tx sdk.Transaction, opts ...AnnounceOption) (*ConfirmationResult, error) {
syncer, err := NewTransactionSyncer(ctx, config, from, WithWsClient(client))
if err != nil {
return nil, err
}
defer syncer.Close()
return AnnounceFullSync(ctx, syncer, tx, opts...)
}
// AnnounceMany announces transactions, waits till they all confirmed and returns hashes or error for every
func AnnounceMany(ctx context.Context, config *sdk.Config, client websocket.CatapultClient, from *sdk.Account, txs []sdk.Transaction, opts ...AnnounceOption) ([]*ConfirmationResult, error) {
syncer, err := NewTransactionSyncer(ctx, config, from, WithWsClient(client))
if err != nil {
return nil, err
}
defer syncer.Close()
return AnnounceFullSyncMany(ctx, syncer, txs, opts...)
}
// AnnounceFullSync fully synchronise work with Syncer and handles all the incoming Results
// Also it is a reference on how to handle Results for different manipulation and for any kind of business logic.
func AnnounceFullSync(ctx context.Context, syncer TransactionSyncer, tx sdk.Transaction, opts ...AnnounceOption) (*ConfirmationResult, error) {
var timeout time.Duration
isAggregated := tx.GetAbstractTransaction().Type == sdk.AggregateBonded
if isAggregated {
timeout = tx.GetAbstractTransaction().Deadline.Sub(time.Now())
} else {
timeout = TransactionResultsTimeout
}
timer := time.NewTimer(timeout)
defer timer.Stop()
results := syncer.AnnounceSync(ctx, tx, opts...)
for {
select {
case res := <-results:
switch res.(type) {
case *AnnounceResult:
if res.Err() != nil {
return nil, res.Err()
}
case *ConfirmationResult:
return res.(*ConfirmationResult), nil
}
case <-timer.C:
return nil, ErrCatapultTimeout
case <-ctx.Done():
return nil, ctx.Err()
case <-syncer.Context().Done():
return nil, syncer.Context().Err()
}
}
}
// AnnounceFullSyncMany announces and waits till success or error for every transaction
// returns slices of hashes and errors with results of announcing
func AnnounceFullSyncMany(ctx context.Context, syncer TransactionSyncer, txs []sdk.Transaction, opts ...AnnounceOption) ([]*ConfirmationResult, error) {
var (
errg error
once sync.Once
wg sync.WaitGroup
)
results := make([]*ConfirmationResult, len(txs))
for i, tx := range txs {
wg.Add(1)
go func(i int, tx sdk.Transaction) {
defer wg.Done()
var err error
results[i], err = AnnounceFullSync(ctx, syncer, tx, opts...)
if err != nil {
once.Do(func() {
errg = err
})
}
}(i, tx)
}
wg.Wait()
return results, errg
}