Skip to content

Commit 0322ee8

Browse files
committed
add toncenter
1 parent 5b4f860 commit 0322ee8

File tree

1 file changed

+153
-13
lines changed

1 file changed

+153
-13
lines changed

examples/tx-timing/main.go

Lines changed: 153 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,44 @@ package main
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
7+
"net/http"
68
"os"
79
"sort"
810
"sync"
911
"time"
1012

1113
sse "github.com/r3labs/sse/v2"
14+
"github.com/tonkeeper/tonapi-go"
1215
"github.com/tonkeeper/tongo/liteapi"
1316
"github.com/tonkeeper/tongo/tlb"
1417
"github.com/tonkeeper/tongo/ton"
1518
"github.com/tonkeeper/tongo/wallet"
1619
)
1720

1821
const (
19-
numRuns = 20
22+
numRuns = 10
2023
)
2124

2225
type RunResult struct {
23-
SSELatency time.Duration
24-
LiteLatency time.Duration
25-
SSESuccess bool
26-
LiteSuccess bool
26+
SSELatency time.Duration
27+
LiteLatency time.Duration
28+
TonapiLatency time.Duration
29+
ToncenterLatency time.Duration
30+
SSESuccess bool
31+
LiteSuccess bool
32+
TonapiSuccess bool
33+
ToncenterSuccess bool
2734
}
2835

2936
func main() {
3037
seed := ""
31-
destinationStr := ""
3238
apiKey := ""
39+
toncenterApiKey := ""
40+
version := wallet.V4R2
3341
amount := uint64(10_000_000) // 0.01 TON
3442

35-
destination := ton.MustParseAccountID(destinationStr)
36-
3743
cli, err := liteapi.NewClient(liteapi.Testnet())
3844
if err != nil {
3945
fmt.Printf("failed to create liteapi client: %v\n", err)
@@ -46,18 +52,19 @@ func main() {
4652
os.Exit(1)
4753
}
4854

49-
w, err := wallet.New(privateKey, wallet.V3R2, cli)
55+
w, err := wallet.New(privateKey, version, cli)
5056
if err != nil {
5157
fmt.Printf("failed to create wallet: %v\n", err)
5258
os.Exit(1)
5359
}
5460

5561
walletAddress := w.GetAddress()
62+
destination := walletAddress
5663
fmt.Printf("Wallet address: %v\n", walletAddress.ToHuman(true, false))
5764
fmt.Printf("Running %d tests...\n\n", numRuns)
5865

5966
var results []RunResult
60-
var sseLatencies, liteLatencies []time.Duration
67+
var sseLatencies, liteLatencies, tonapiLatencies, toncenterLatencies []time.Duration
6168

6269
for i := 1; i <= numRuns; i++ {
6370
fmt.Printf("=== RUN %d/%d ===\n", i, numRuns)
@@ -68,7 +75,7 @@ func main() {
6875
continue
6976
}
7077

71-
result := runTest(cli, w, walletAddress, destination, amount, apiKey)
78+
result := runTest(cli, w, walletAddress, destination, amount, apiKey, toncenterApiKey)
7279
results = append(results, result)
7380

7481
if result.SSESuccess {
@@ -85,6 +92,15 @@ func main() {
8592
fmt.Printf(" Liteserver: ERROR\n")
8693
}
8794

95+
if result.TonapiSuccess {
96+
tonapiLatencies = append(tonapiLatencies, result.TonapiLatency)
97+
fmt.Printf(" Tonapi: %v\n", result.TonapiLatency)
98+
}
99+
if result.ToncenterSuccess {
100+
toncenterLatencies = append(toncenterLatencies, result.ToncenterLatency)
101+
fmt.Printf(" Toncenter: %v\n", result.ToncenterLatency)
102+
}
103+
88104
fmt.Println()
89105

90106
if i < numRuns {
@@ -117,9 +133,111 @@ func main() {
117133
} else {
118134
fmt.Printf("Liteserver: No successful runs\n")
119135
}
136+
137+
fmt.Println()
138+
139+
if len(tonapiLatencies) > 0 {
140+
fmt.Printf("Tonapi Statistics (%d successful runs):\n", len(tonapiLatencies))
141+
fmt.Printf(" Average: %v\n", average(tonapiLatencies))
142+
fmt.Printf(" Min: %v\n", min(tonapiLatencies))
143+
fmt.Printf(" Max: %v\n", max(tonapiLatencies))
144+
fmt.Printf(" Median: %v\n", median(tonapiLatencies))
145+
} else {
146+
fmt.Printf("Tonapi: No successful runs\n")
147+
}
148+
149+
fmt.Println()
150+
151+
if len(toncenterLatencies) > 0 {
152+
fmt.Printf("Toncenter Statistics (%d successful runs):\n", len(toncenterLatencies))
153+
fmt.Printf(" Average: %v\n", average(toncenterLatencies))
154+
fmt.Printf(" Min: %v\n", min(toncenterLatencies))
155+
fmt.Printf(" Max: %v\n", max(toncenterLatencies))
156+
fmt.Printf(" Median: %v\n", median(toncenterLatencies))
157+
} else {
158+
fmt.Printf("Toncenter: No successful runs\n")
159+
}
160+
120161
}
121162

122-
func runTest(cli *liteapi.Client, w wallet.Wallet, walletAddress ton.AccountID, destination ton.AccountID, amount uint64, apiKey string) RunResult {
163+
func pollTonapi(ctx context.Context, account ton.AccountID, token string, initialLT uint64, foundCh chan<- time.Time) {
164+
ticker := time.NewTicker(50 * time.Millisecond)
165+
defer ticker.Stop()
166+
api, _ := tonapi.NewClient("https://testnet.tonapi.io", tonapi.WithToken(token))
167+
for {
168+
select {
169+
case <-ctx.Done():
170+
return
171+
case <-ticker.C:
172+
txs, err := api.GetBlockchainAccountTransactions(ctx, tonapi.GetBlockchainAccountTransactionsParams{
173+
AccountID: account.String(),
174+
Limit: tonapi.NewOptInt32(3),
175+
})
176+
if err != nil {
177+
if ctx.Err() != nil {
178+
return
179+
}
180+
continue
181+
}
182+
183+
currentLT := uint64(txs.Transactions[0].Lt)
184+
if currentLT > initialLT {
185+
select {
186+
case foundCh <- time.Now():
187+
default:
188+
}
189+
return
190+
}
191+
}
192+
}
193+
}
194+
195+
func pollToncenter(ctx context.Context, account ton.AccountID, token string, initialLT uint64, foundCh chan<- time.Time) {
196+
ticker := time.NewTicker(50 * time.Millisecond)
197+
defer ticker.Stop()
198+
req, _ := http.NewRequest("GET", fmt.Sprintf("https://testnet.toncenter.com/api/v3/transactions?account=%s&limit=3&offset=0&sort=desc", account.String()), nil)
199+
req.Header.Add("X-Api-Key", token)
200+
for {
201+
select {
202+
case <-ctx.Done():
203+
return
204+
case <-ticker.C:
205+
resp, err := http.DefaultClient.Do(req)
206+
if err != nil {
207+
fmt.Println(err)
208+
return
209+
}
210+
if resp.StatusCode != http.StatusOK {
211+
fmt.Printf("unexpected status code: %d\n", resp.StatusCode)
212+
return
213+
}
214+
var body struct {
215+
Transactions []struct {
216+
Lt uint64 `json:"lt,string"`
217+
} `json:"transactions"`
218+
}
219+
err = json.NewDecoder(resp.Body).Decode(&body)
220+
if err != nil {
221+
if ctx.Err() != nil {
222+
fmt.Println(err)
223+
return
224+
}
225+
continue
226+
}
227+
228+
currentLT := uint64(body.Transactions[0].Lt)
229+
if currentLT > initialLT {
230+
select {
231+
case foundCh <- time.Now():
232+
default:
233+
}
234+
return
235+
}
236+
}
237+
}
238+
}
239+
240+
func runTest(cli *liteapi.Client, w wallet.Wallet, walletAddress ton.AccountID, destination ton.AccountID, amount uint64, apiKey, toncenterApikey string) RunResult {
123241
result := RunResult{}
124242

125243
initialState, err := cli.GetAccountState(context.Background(), walletAddress)
@@ -131,6 +249,8 @@ func runTest(cli *liteapi.Client, w wallet.Wallet, walletAddress ton.AccountID,
131249

132250
sseFoundCh := make(chan time.Time, 1)
133251
liteFoundCh := make(chan time.Time, 1)
252+
tonapiFoundCh := make(chan time.Time, 1)
253+
toncenterFoundCh := make(chan time.Time, 1)
134254
ctx, cancel := context.WithCancel(context.Background())
135255
defer cancel()
136256

@@ -141,6 +261,16 @@ func runTest(cli *liteapi.Client, w wallet.Wallet, walletAddress ton.AccountID,
141261
defer wg.Done()
142262
listenSSE(ctx, walletAddress.ToRaw(), apiKey, sseFoundCh)
143263
}()
264+
wg.Add(1)
265+
go func() {
266+
defer wg.Done()
267+
pollTonapi(ctx, walletAddress, apiKey, initialLT, tonapiFoundCh)
268+
}()
269+
wg.Add(1)
270+
go func() {
271+
defer wg.Done()
272+
pollToncenter(ctx, walletAddress, toncenterApikey, initialLT, toncenterFoundCh)
273+
}()
144274

145275
time.Sleep(500 * time.Millisecond)
146276

@@ -170,7 +300,7 @@ func runTest(cli *liteapi.Client, w wallet.Wallet, walletAddress ton.AccountID,
170300

171301
timeout := time.After(60 * time.Second)
172302

173-
for !result.SSESuccess || !result.LiteSuccess {
303+
for !result.SSESuccess || !result.LiteSuccess || !result.TonapiSuccess || !result.ToncenterSuccess {
174304
select {
175305
case t := <-sseFoundCh:
176306
if !result.SSESuccess {
@@ -182,6 +312,16 @@ func runTest(cli *liteapi.Client, w wallet.Wallet, walletAddress ton.AccountID,
182312
result.LiteLatency = t.Sub(sendTime)
183313
result.LiteSuccess = true
184314
}
315+
case t := <-tonapiFoundCh:
316+
if !result.TonapiSuccess {
317+
result.TonapiLatency = t.Sub(sendTime)
318+
result.TonapiSuccess = true
319+
}
320+
case t := <-toncenterFoundCh:
321+
if !result.ToncenterSuccess {
322+
result.ToncenterLatency = t.Sub(sendTime)
323+
result.ToncenterSuccess = true
324+
}
185325
case <-timeout:
186326
cancel()
187327
return result

0 commit comments

Comments
 (0)