Skip to content

Commit ae4ef80

Browse files
Merge pull request #142 from coinbase/patrick/wait-to-start-until-tip
[check:construction] Wait to start check:construction until reaching tip
2 parents 1edd273 + 0babed0 commit ae4ef80

File tree

11 files changed

+224
-27
lines changed

11 files changed

+224
-27
lines changed

cmd/check_construction.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ func runCheckConstructionCmd(cmd *cobra.Command, args []string) {
131131
return constructionTester.WatchEndConditions(ctx)
132132
})
133133

134+
g.Go(func() error {
135+
return tester.LogMemoryLoop(ctx)
136+
})
137+
134138
sigListeners := []context.CancelFunc{cancel}
135139
go handleSignals(&sigListeners)
136140

cmd/check_data.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,14 @@ func runCheckDataCmd(cmd *cobra.Command, args []string) {
141141
return dataTester.WatchEndConditions(ctx)
142142
})
143143

144+
g.Go(func() error {
145+
return tester.LogMemoryLoop(ctx)
146+
})
147+
148+
g.Go(func() error {
149+
return dataTester.StartProgressLogger(ctx)
150+
})
151+
144152
sigListeners := []context.CancelFunc{cancel}
145153
go handleSignals(&sigListeners)
146154

cmd/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,6 @@ var versionCmd = &cobra.Command{
132132
Use: "version",
133133
Short: "Print rosetta-cli version",
134134
Run: func(cmd *cobra.Command, args []string) {
135-
fmt.Println("v0.5.4")
135+
fmt.Println("v0.5.5")
136136
},
137137
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/coinbase/rosetta-cli
33
go 1.13
44

55
require (
6-
github.com/coinbase/rosetta-sdk-go v0.4.6
6+
github.com/coinbase/rosetta-sdk-go v0.4.8
77
github.com/fatih/color v1.9.0
88
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
99
github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c

go.sum

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN
1313
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
1414
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
1515
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
16+
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
1617
github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM=
1718
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
1819
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
@@ -155,6 +156,10 @@ github.com/coinbase/rosetta-sdk-go v0.4.5 h1:5Z+25mm/J1SStzSdTp5e8dlEMtCZRBZdOaT
155156
github.com/coinbase/rosetta-sdk-go v0.4.5/go.mod h1:Luv0AhzZH81eul2hYZ3w0hBGwmFPiexwbntYxihEZck=
156157
github.com/coinbase/rosetta-sdk-go v0.4.6 h1:zX2SLmBF1oFbK0c4QCMwkwcHN9VjenFfIt0Dr8k8JGY=
157158
github.com/coinbase/rosetta-sdk-go v0.4.6/go.mod h1:Luv0AhzZH81eul2hYZ3w0hBGwmFPiexwbntYxihEZck=
159+
github.com/coinbase/rosetta-sdk-go v0.4.7 h1:5KFc0CgLMkKamX++hYUFvE58a5/tCn0wSqpcTnDhRhY=
160+
github.com/coinbase/rosetta-sdk-go v0.4.7/go.mod h1:8d4iN4VSGvLUzl+jRQlvYSLyS9TeY0QZebneWouizqU=
161+
github.com/coinbase/rosetta-sdk-go v0.4.8 h1:+E1TM4q1c5/x/jE9FPI1IZIbNvUWy4tRRgDPLnKzUV4=
162+
github.com/coinbase/rosetta-sdk-go v0.4.8/go.mod h1:8d4iN4VSGvLUzl+jRQlvYSLyS9TeY0QZebneWouizqU=
158163
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
159164
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
160165
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
@@ -198,6 +203,7 @@ github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87/go.mod h1:Mw6PkjjMXWbT
198203
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
199204
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
200205
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
206+
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
201207
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
202208
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
203209
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
@@ -207,6 +213,8 @@ github.com/ethereum/go-ethereum v1.9.20 h1:kk/J5OIoaoz3DRrCXznz3RGi212mHHXwzXlY/
207213
github.com/ethereum/go-ethereum v1.9.20/go.mod h1:JSSTypSMTkGZtAdAChH2wP5dZEvPGh3nUTuDpH+hNrg=
208214
github.com/ethereum/go-ethereum v1.9.21 h1:8qRlhzrItnmUGdVlBzZLI2Tb46S0RdSNjFwICo781ws=
209215
github.com/ethereum/go-ethereum v1.9.21/go.mod h1:RXAVzbGrSGmDkDnHymruTAIEjUR3E4TX0EOpaj702sI=
216+
github.com/ethereum/go-ethereum v1.9.22 h1:/Fea9n2EWJuNJ9oahMq9luqjRBcbW7QWdThbcJl13ek=
217+
github.com/ethereum/go-ethereum v1.9.22/go.mod h1:FQjK3ZwD8C5DYn7ukTmFee36rq1dOMESiUfXr5RUc1w=
210218
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
211219
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
212220
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
@@ -249,6 +257,7 @@ github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26 h1:lMm2hD9Fy0ynom5
249257
github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
250258
github.com/google/addlicense v0.0.0-20200817051935-6f4cd4aacc89 h1:oTppmscIAQ2Y1tcsMDcTLR3z4MN/96/pvIsBSLGl7o8=
251259
github.com/google/addlicense v0.0.0-20200817051935-6f4cd4aacc89/go.mod h1:EMjYTRimagHs1FwlIqKyX3wAM0u3rA+McvlIIWmSamA=
260+
github.com/google/addlicense v0.0.0-20200827091314-d1655b921368 h1:Ds6gDZHoviaQM7r7oMx/cG2qwZc3l5u7cg6gTkxOZNE=
252261
github.com/google/addlicense v0.0.0-20200827091314-d1655b921368/go.mod h1:EMjYTRimagHs1FwlIqKyX3wAM0u3rA+McvlIIWmSamA=
253262
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
254263
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -260,6 +269,7 @@ github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
260269
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
261270
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
262271
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
272+
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
263273
github.com/google/pprof v0.0.0-20181127221834-b4f47329b966/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
264274
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
265275
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
@@ -480,11 +490,19 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh
480490
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
481491
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
482492
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
493+
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
494+
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
495+
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
483496
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
484497
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
485498
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
486499
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
500+
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
501+
golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
487502
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
503+
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
504+
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
505+
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
488506
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
489507
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
490508
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -560,11 +578,13 @@ golang.org/x/tools v0.0.0-20181127232545-e782529d0ddd/go.mod h1:n7NCudcB/nEzxVGm
560578
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
561579
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
562580
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
581+
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
563582
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
564583
golang.org/x/tools v0.0.0-20191024220359-3d91e92cde03 h1:4gtJXHJ9ud0q8MNSDxJsRU/WH+afypbe4Vk4zq+8qow=
565584
golang.org/x/tools v0.0.0-20191024220359-3d91e92cde03/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
566585
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
567586
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
587+
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
568588
golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
569589
golang.org/x/tools v0.0.0-20200729181040-64cdafbe085c/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
570590
golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=

pkg/logger/logger.go

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,6 @@ func (l *Logger) LogDataStats(ctx context.Context) error {
110110
return nil
111111
}
112112

113-
elapsedTime, err := l.CounterStorage.Get(ctx, TimeElapsedCounter)
114-
if err != nil {
115-
return fmt.Errorf("%w cannot get elapsed time", err)
116-
}
117-
118-
if elapsedTime.Sign() == 0 { // wait for at least some elapsed time
119-
return nil
120-
}
121-
122-
blocksPerSecond := new(big.Int).Div(blocks, elapsedTime)
123-
124113
orphans, err := l.CounterStorage.Get(ctx, storage.OrphanCounter)
125114
if err != nil {
126115
return fmt.Errorf("%w cannot get orphan counter", err)
@@ -147,10 +136,9 @@ func (l *Logger) LogDataStats(ctx context.Context) error {
147136
}
148137

149138
statsMessage := fmt.Sprintf(
150-
"[STATS] Blocks: %s (Orphaned: %s, Rate: %s/sec) Transactions: %s Operations: %s",
139+
"[STATS] Blocks: %s (Orphaned: %s) Transactions: %s Operations: %s",
151140
blocks.String(),
152141
orphans.String(),
153-
blocksPerSecond.String(),
154142
txs.String(),
155143
ops.String(),
156144
)
@@ -181,6 +169,54 @@ func (l *Logger) LogDataStats(ctx context.Context) error {
181169
return nil
182170
}
183171

172+
// LogTipEstimate logs information about the remaining blocks to sync.
173+
func (l *Logger) LogTipEstimate(ctx context.Context, tipIndex int64) error {
174+
blocks, err := l.CounterStorage.Get(ctx, storage.BlockCounter)
175+
if err != nil {
176+
return fmt.Errorf("%w cannot get block counter", err)
177+
}
178+
179+
if blocks.Sign() == 0 { // wait for at least 1 block to be processed
180+
return nil
181+
}
182+
183+
orphans, err := l.CounterStorage.Get(ctx, storage.OrphanCounter)
184+
if err != nil {
185+
return fmt.Errorf("%w cannot get orphan counter", err)
186+
}
187+
188+
adjustedBlocks := blocks.Int64() - orphans.Int64()
189+
if tipIndex-adjustedBlocks <= 0 { // return if no blocks to sync
190+
return nil
191+
}
192+
193+
elapsedTime, err := l.CounterStorage.Get(ctx, TimeElapsedCounter)
194+
if err != nil {
195+
return fmt.Errorf("%w cannot get elapsed time", err)
196+
}
197+
198+
if elapsedTime.Sign() == 0 { // wait for at least some elapsed time
199+
return nil
200+
}
201+
202+
blocksPerSecond := new(big.Float).Quo(new(big.Float).SetInt64(adjustedBlocks), new(big.Float).SetInt(elapsedTime))
203+
blocksPerSecondFloat, _ := blocksPerSecond.Float64()
204+
blocksSynced := new(big.Float).Quo(new(big.Float).SetInt64(adjustedBlocks), new(big.Float).SetInt64(tipIndex))
205+
blocksSyncedFloat, _ := blocksSynced.Float64()
206+
207+
statsMessage := fmt.Sprintf(
208+
"[PROGRESS] Blocks Synced: %d/%d (Completed: %f%%, Rate: %f/second) Time Remaining: %s",
209+
adjustedBlocks,
210+
tipIndex,
211+
blocksSyncedFloat*utils.OneHundred,
212+
blocksPerSecondFloat,
213+
utils.TimeToTip(blocksPerSecondFloat, adjustedBlocks, tipIndex),
214+
)
215+
216+
color.Cyan(statsMessage)
217+
return nil
218+
}
219+
184220
// LogConstructionStats logs all construction values in CounterStorage.
185221
func (l *Logger) LogConstructionStats(ctx context.Context, inflightTransactions int) error {
186222
transactionsCreated, err := l.CounterStorage.Get(ctx, storage.TransactionsCreatedCounter)
@@ -227,6 +263,20 @@ func (l *Logger) LogConstructionStats(ctx context.Context, inflightTransactions
227263
return nil
228264
}
229265

266+
// LogMemoryStats logs memory usage information.
267+
func LogMemoryStats(ctx context.Context) {
268+
memUsage := utils.MonitorMemoryUsage(ctx, -1)
269+
statsMessage := fmt.Sprintf(
270+
"[MEMORY] Heap: %fMB Stack: %fMB System: %fMB GCs: %d",
271+
memUsage.Heap,
272+
memUsage.Stack,
273+
memUsage.System,
274+
memUsage.GarbageCollections,
275+
)
276+
277+
color.Cyan(statsMessage)
278+
}
279+
230280
// AddBlockStream writes the next processed block to the end of the
231281
// blockStreamFile output file.
232282
func (l *Logger) AddBlockStream(

pkg/tester/construction.go

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const (
4444
constructionCmdName = "check-construction"
4545

4646
endConditionsCheckInterval = 10 * time.Second
47+
tipWaitInterval = 10 * time.Second
4748
)
4849

4950
// ConstructionTester coordinates the `check:construction` test.
@@ -283,6 +284,47 @@ func (t *ConstructionTester) StartPeriodicLogger(
283284
}
284285
}
285286

287+
func (t *ConstructionTester) checkTip(ctx context.Context) (int64, error) {
288+
status, fetchErr := t.onlineFetcher.NetworkStatusRetry(ctx, t.network, nil)
289+
if fetchErr != nil {
290+
return -1, fmt.Errorf("%w: unable to fetch network status", fetchErr.Err)
291+
}
292+
293+
// If a block has yet to be synced, start syncing from tip.
294+
if utils.AtTip(t.config.TipDelay, status.CurrentBlockTimestamp) {
295+
return status.CurrentBlockIdentifier.Index, nil
296+
}
297+
298+
return -1, nil
299+
}
300+
301+
// waitForTip loops until the Rosetta implementation is at tip.
302+
func (t *ConstructionTester) waitForTip(ctx context.Context) (int64, error) {
303+
tc := time.NewTicker(tipWaitInterval)
304+
defer tc.Stop()
305+
306+
for {
307+
// Don't wait any time before first tick if at tip.
308+
tipIndex, err := t.checkTip(ctx)
309+
if err != nil {
310+
return -1, err
311+
}
312+
313+
if tipIndex != -1 {
314+
return tipIndex, nil
315+
}
316+
317+
log.Println("waiting for implementation to reach tip before testing...")
318+
319+
select {
320+
case <-ctx.Done():
321+
return -1, ctx.Err()
322+
case <-tc.C:
323+
continue
324+
}
325+
}
326+
}
327+
286328
// StartSyncer uses the tester's stateful syncer
287329
// to compute balance changes and track transactions
288330
// for confirmation on-chain.
@@ -293,14 +335,12 @@ func (t *ConstructionTester) StartSyncer(
293335
startIndex := int64(-1)
294336
_, err := t.blockStorage.GetHeadBlockIdentifier(ctx)
295337
if errors.Is(err, storage.ErrHeadBlockNotFound) {
296-
// If a block has yet to be synced, start syncing from tip.
297-
// TODO: make configurable
298-
status, fetchErr := t.onlineFetcher.NetworkStatusRetry(ctx, t.network, nil)
299-
if fetchErr != nil {
300-
return fmt.Errorf("%w: unable to fetch network status", fetchErr.Err)
338+
// If no head block exists, ensure we are at tip before starting. Otherwise,
339+
// we will unnecessarily sync tons of blocks before reaching any that matter.
340+
startIndex, err = t.waitForTip(ctx)
341+
if err != nil {
342+
return fmt.Errorf("%w: unable to wait for tip", err)
301343
}
302-
303-
startIndex = status.CurrentBlockIdentifier.Index
304344
} else if err != nil {
305345
return fmt.Errorf("%w: unable to get last block synced", err)
306346
}

pkg/tester/construction_results.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,10 @@ func ExitConstruction(
240240
counterStorage,
241241
jobStorage,
242242
)
243-
results.Print()
244-
results.Output(config.Construction.ResultsOutputFile)
243+
if results != nil {
244+
results.Print()
245+
results.Output(config.Construction.ResultsOutputFile)
246+
}
245247

246248
os.Exit(status)
247249
}

pkg/tester/data.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,24 @@ func (t *DataTester) StartPeriodicLogger(
355355
// Print stats one last time before exiting
356356
_ = t.logger.LogDataStats(ctx)
357357

358+
return ctx.Err()
359+
case <-tc.C:
360+
_ = t.logger.LogDataStats(ctx)
361+
}
362+
}
363+
}
364+
365+
// StartProgressLogger priunts out periodic
366+
// estimates of sync duration if we are behind tip.
367+
func (t *DataTester) StartProgressLogger(
368+
ctx context.Context,
369+
) error {
370+
tc := time.NewTicker(PeriodicLoggingFrequency)
371+
defer tc.Stop()
372+
373+
for {
374+
select {
375+
case <-ctx.Done():
358376
return ctx.Err()
359377
case <-tc.C:
360378
// Update the elapsed time in counter storage so that
@@ -364,7 +382,14 @@ func (t *DataTester) StartPeriodicLogger(
364382
logger.TimeElapsedCounter,
365383
big.NewInt(periodicLoggingSeconds),
366384
)
367-
_ = t.logger.LogDataStats(ctx)
385+
386+
status, fetchErr := t.fetcher.NetworkStatusRetry(ctx, t.network, nil)
387+
if fetchErr != nil {
388+
log.Printf("%v: unable to get network status\n", fetchErr.Err)
389+
continue
390+
}
391+
392+
_ = t.logger.LogTipEstimate(ctx, status.CurrentBlockIdentifier.Index)
368393
}
369394
}
370395
}

pkg/tester/data_results.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,10 @@ func ExitData(
471471
endCondition,
472472
endConditionDetail,
473473
)
474-
results.Print()
475-
results.Output(config.Data.ResultsOutputFile)
474+
if results != nil {
475+
results.Print()
476+
results.Output(config.Data.ResultsOutputFile)
477+
}
476478

477479
os.Exit(status)
478480
}

0 commit comments

Comments
 (0)