Skip to content

Commit f82b73b

Browse files
authored
refactor(sync): SyncFromHash as string (#311)
Otherwise, it's ignored by the config toml
1 parent 0bb79c2 commit f82b73b

File tree

3 files changed

+52
-16
lines changed

3 files changed

+52
-16
lines changed

sync/options.go

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package sync
22

33
import (
4+
"encoding/hex"
45
"fmt"
56
"time"
67

@@ -24,14 +25,16 @@ type Parameters struct {
2425
TrustingPeriod time.Duration
2526
// PruningWindow defines the duration within which headers are retained before being pruned.
2627
PruningWindow time.Duration
27-
// SyncFromHash is the hash of the header from which the syncer should start syncing.
28+
// SyncFromHash is the hash of the header from which Syncer should start syncing.
29+
// Zero value to disable. Value updates up and down the chain are gracefully handled by Syncer.
2830
//
2931
// By default, Syncer maintains PruningWindow number of headers. SyncFromHash overrides this default,
3032
// allowing any user to specify a custom starting point.
3133
//
3234
// SyncFromHash has higher priority than SyncFromHeight.
33-
SyncFromHash header.Hash
34-
// SyncFromHeight is the height of the header from which the syncer should start syncing.
35+
SyncFromHash string
36+
// SyncFromHeight is the height of the header from which Syncer should start syncing.
37+
// Zero value to disable. Value updates up and down the chain are gracefully handled by Syncer.
3538
//
3639
// By default, Syncer maintains PruningWindow number of headers. SyncFromHeight overrides this default,
3740
// allowing any user to specify a custom starting point.
@@ -48,6 +51,8 @@ type Parameters struct {
4851
recencyThreshold time.Duration
4952
// metrics is a flag that enables metrics collection.
5053
metrics bool
54+
// hash cache
55+
hash header.Hash
5156
}
5257

5358
// DefaultParameters returns the default params to configure the syncer.
@@ -60,11 +65,32 @@ func DefaultParameters() Parameters {
6065

6166
func (p *Parameters) Validate() error {
6267
if p.TrustingPeriod == 0 {
63-
return fmt.Errorf("invalid trusting period duration: %v", p.TrustingPeriod)
68+
return fmt.Errorf("invalid TrustingPeriod duration: %v", p.TrustingPeriod)
69+
}
70+
if (p.SyncFromHeight == 0 || p.SyncFromHash == "") && p.PruningWindow == 0 {
71+
return fmt.Errorf(
72+
"PruningWindow duration can't be zero when either of SyncFromHeight or SyncFromHash are not set",
73+
)
74+
}
75+
_, err := p.Hash()
76+
if err != nil {
77+
return err
6478
}
6579
return nil
6680
}
6781

82+
func (p *Parameters) Hash() (header.Hash, error) {
83+
if p.hash == nil && len(p.SyncFromHash) > 0 {
84+
hash, err := hex.DecodeString(p.SyncFromHash)
85+
if err != nil {
86+
return nil, fmt.Errorf("invalid SyncFromHash: %w", err)
87+
}
88+
89+
p.hash = hash
90+
}
91+
return p.hash, nil
92+
}
93+
6894
// WithMetrics enables Metrics on Syncer.
6995
func WithMetrics() Option {
7096
return func(p *Parameters) {
@@ -105,7 +131,7 @@ func WithParams(params Parameters) Option {
105131

106132
// WithSyncFromHash sets given header hash a starting point for syncing.
107133
// See [Parameters.SyncFromHash] for details.
108-
func WithSyncFromHash(hash header.Hash) Option {
134+
func WithSyncFromHash(hash string) Option {
109135
return func(p *Parameters) {
110136
p.SyncFromHash = hash
111137
}

sync/syncer_tail.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ func (s *Syncer[H]) subjectiveTail(ctx context.Context, head H) (H, error) {
4747

4848
// renewTail resolves the new actual tail header respecting Syncer parameters.
4949
func (s *Syncer[H]) renewTail(ctx context.Context, oldTail, head H) (newTail H, err error) {
50-
useHash, tailHash := s.tailHash(oldTail)
50+
useHash, tailHash, err := s.tailHash(oldTail)
51+
if err != nil {
52+
return oldTail, err
53+
}
5154
switch {
5255
case useHash:
5356
if tailHash == nil {
@@ -101,7 +104,7 @@ func (s *Syncer[H]) renewTail(ctx context.Context, oldTail, head H) (newTail H,
101104
}
102105

103106
if err := s.store.Append(ctx, newTail); err != nil {
104-
return newTail, fmt.Errorf("appending tail header: %w", err)
107+
return newTail, fmt.Errorf("appending tail header %d: %w", newTail.Height(), err)
105108
}
106109

107110
return newTail, nil
@@ -149,19 +152,22 @@ func (s *Syncer[H]) moveTail(ctx context.Context, from, to H) error {
149152

150153
// tailHash reports whether tail hash should be used and returns it.
151154
// Returns empty hash if it hasn't changed from the old tail hash.
152-
func (s *Syncer[H]) tailHash(oldTail H) (bool, header.Hash) {
153-
hash := s.Params.SyncFromHash
155+
func (s *Syncer[H]) tailHash(oldTail H) (bool, header.Hash, error) {
156+
hash, err := s.Params.Hash()
157+
if err != nil {
158+
return false, nil, err
159+
}
154160
if len(hash) == 0 {
155-
return false, nil
161+
return false, nil, nil
156162
}
157163

158164
updated := oldTail.IsZero() || !bytes.Equal(hash, oldTail.Hash())
159165
if !updated {
160-
return true, nil
166+
return true, nil, nil
161167
}
162168

163169
log.Debugw("tail hash updated", "hash", hash)
164-
return true, hash
170+
return true, hash, nil
165171
}
166172

167173
// tailHeight figures the actual tail height based on the Syncer parameters.

sync/syncer_tail_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func TestSyncer_TailHashOverHeight(t *testing.T) {
3737
localStore,
3838
headertest.NewDummySubscriber(),
3939
WithBlockTime(headertest.HeaderTime),
40-
WithSyncFromHash(startFrom.Hash()),
40+
WithSyncFromHash(startFrom.Hash().String()),
4141
)
4242
require.NoError(t, err)
4343

@@ -195,7 +195,7 @@ func TestSyncer_TailInitialization(t *testing.T) {
195195
},
196196
{
197197
"SyncFromHash",
198-
WithSyncFromHash(expectedTail.Hash()),
198+
WithSyncFromHash(expectedTail.Hash().String()),
199199
func() *headertest.DummyHeader {
200200
return expectedTail
201201
},
@@ -257,8 +257,10 @@ func TestSyncer_TailInitialization(t *testing.T) {
257257
err = syncer.Stop(ctx)
258258
require.NoError(t, err)
259259
expectedTail = test.expectedAfterRestart()
260+
params := DefaultParameters()
261+
syncer.Params = &params
260262
syncer.Params.SyncFromHeight = expectedTail.Height()
261-
syncer.Params.SyncFromHash = expectedTail.Hash()
263+
syncer.Params.SyncFromHash = expectedTail.Hash().String()
262264

263265
// simulate new head
264266
err = remoteStore.Append(ctx, suite.NextHeader())
@@ -271,7 +273,9 @@ func TestSyncer_TailInitialization(t *testing.T) {
271273
// ensure that the Syncer moved to the new tail after restart
272274
storeTail, err = localStore.Tail(ctx)
273275
require.NoError(t, err)
274-
assert.EqualValues(t, expectedTail.Height(), storeTail.Height())
276+
assert.EqualValues(t, int(expectedTail.Height()), int(storeTail.Height()))
277+
t.Log(expectedTail.Hash().String())
278+
t.Log(storeTail.Hash().String())
275279
})
276280
}
277281
}

0 commit comments

Comments
 (0)