Skip to content

Commit 5ef2633

Browse files
committed
add data hash
1 parent d6c16e6 commit 5ef2633

4 files changed

Lines changed: 15 additions & 40 deletions

File tree

block/internal/syncing/syncer.go

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,33 +30,6 @@ import (
3030

3131
var _ BlockSyncer = (*Syncer)(nil)
3232

33-
// getTrustedHeader loads and verifies the trusted header from the store
34-
func (s *Syncer) getTrustedHeader(ctx context.Context) (*types.SignedHeader, error) {
35-
if s.config.P2P.TrustedHeight == 0 {
36-
return nil, fmt.Errorf("trusted_height is not configured")
37-
}
38-
39-
// Load the signed header from the store
40-
header, err := s.store.GetHeader(ctx, s.config.P2P.TrustedHeight)
41-
if err != nil {
42-
return nil, fmt.Errorf("failed to load trusted header at height %d: %w", s.config.P2P.TrustedHeight, err)
43-
}
44-
45-
// Verify the header hash matches the trusted hash
46-
expectedHash := s.config.P2P.TrustedHeaderHash
47-
actualHash := header.Hash().String()
48-
if actualHash != expectedHash {
49-
return nil, fmt.Errorf("trusted header hash mismatch at height %d: expected %s, got %s",
50-
s.config.P2P.TrustedHeight, expectedHash, actualHash)
51-
}
52-
53-
s.logger.Info().Uint64("height", s.config.P2P.TrustedHeight).
54-
Str("hash", actualHash).
55-
Msg("trusted header loaded and verified")
56-
57-
return header, nil
58-
}
59-
6033
// forcedInclusionGracePeriodConfig contains internal configuration for forced inclusion grace periods.
6134
type forcedInclusionGracePeriodConfig struct {
6235
// basePeriod is the base number of additional epochs allowed for including forced inclusion transactions
@@ -337,9 +310,9 @@ func (s *Syncer) initializeState() error {
337310
s.logger.Info().Uint64("trusted_height", s.config.P2P.TrustedHeight).Msg("initializing state from trusted height")
338311

339312
// Load and verify the trusted header
340-
trustedHeader, err := s.getTrustedHeader(s.ctx)
313+
trustedHeader, err := s.store.GetHeader(s.ctx, s.config.P2P.TrustedHeight)
341314
if err != nil {
342-
return fmt.Errorf("failed to load trusted header: %w", err)
315+
return fmt.Errorf("failed to load trusted header at height %d: %w", s.config.P2P.TrustedHeight, err)
343316
}
344317

345318
// Initialize new chain state from the trusted header

pkg/config/config.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ type P2PConfig struct {
281281
BlockedPeers string `mapstructure:"blocked_peers" yaml:"blocked_peers" comment:"Comma-separated list of peer IDs to block from connecting"`
282282
AllowedPeers string `mapstructure:"allowed_peers" yaml:"allowed_peers" comment:"Comma-separated list of peer IDs to allow connections from"`
283283
TrustedHeight uint64 `mapstructure:"trusted_height" yaml:"trusted_height" comment:"Block height to trust for sync initialization. When set, sync starts from this height instead of genesis. Must be accompanied by trusted_header_hash for security."`
284-
TrustedHeaderHash string `mapstructure:"trusted_header_hash" yaml:"trusted_header_hash" comment:"Hash of the trusted header for security verification. This should be the hex-encoded hash of the header at trusted_height. Prevents against history rewrites during sync."`
284+
TrustedHeaderHash string `mapstructure:"trusted_header_hash" yaml:"trusted_header_hash" comment:"Hash of the trusted header for security verification."`
285+
TrustedDataHash string `mapstructure:"trusted_data_hash" yaml:"trusted_data_hash" comment:"Hash of the trusted data for security verification."`
285286
}
286287

287288
// SignerConfig contains all signer configuration parameters
@@ -381,8 +382,8 @@ func (c *Config) Validate() error {
381382
}
382383

383384
// Validate trusted height configuration
384-
if c.P2P.TrustedHeight > 0 && c.P2P.TrustedHeaderHash == "" {
385-
return fmt.Errorf("trusted_height (%d) is set but trusted_header_hash is empty. When using trusted_height, trusted_header_hash must also be provided for security verification",
385+
if c.P2P.TrustedHeight > 0 && (c.P2P.TrustedHeaderHash == "" || c.P2P.TrustedDataHash == "") {
386+
return fmt.Errorf("trusted_height (%d) is set but trusted_header_hash or trusted_data_hash is empty. When using trusted_height, both trusted_header_hash and trusted_data_hash must also be provided for security verification",
386387
c.P2P.TrustedHeight)
387388
}
388389

pkg/config/config_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ func TestTrustedHeightValidation(t *testing.T) {
527527
trustedHeight: 100,
528528
trustedHash: "",
529529
expectError: true,
530-
errorMsg: "trusted_height (100) is set but trusted_header_hash is empty",
530+
errorMsg: "trusted_height (100) is set but trusted_header_hash or trusted_data_hash is empty",
531531
},
532532
{
533533
name: "trusted height with valid hash should pass",
@@ -555,6 +555,7 @@ func TestTrustedHeightValidation(t *testing.T) {
555555
cfg.RootDir = t.TempDir()
556556
cfg.P2P.TrustedHeight = tt.trustedHeight
557557
cfg.P2P.TrustedHeaderHash = tt.trustedHash
558+
cfg.P2P.TrustedDataHash = tt.trustedHash
558559

559560
err := cfg.Validate()
560561

pkg/sync/sync_service.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ type SyncService[H store.EntityWithDAHint[H]] struct {
6262

6363
// trustedHeight tracks the configured trusted height for sync initialization
6464
trustedHeight uint64
65-
// trustedHeaderHash is the expected hash of the trusted header
66-
trustedHeaderHash string
65+
// trustedHeaderHash, trustedDataHash is the expected hash of the trusted header
66+
trustedHeaderHash, trustedDataHash string
6767
}
6868

6969
// NewDataSyncService returns a new DataSyncService.
@@ -206,6 +206,7 @@ func (syncService *SyncService[H]) Start(ctx context.Context) error {
206206
// Initialize trusted height configuration
207207
syncService.trustedHeight = syncService.conf.P2P.TrustedHeight
208208
syncService.trustedHeaderHash = syncService.conf.P2P.TrustedHeaderHash
209+
syncService.trustedDataHash = syncService.conf.P2P.TrustedDataHash
209210

210211
// initialize stores from P2P (blocking until genesis is fetched for followers)
211212
// Aggregators (no peers configured) return immediately and initialize on first produced block.
@@ -331,7 +332,7 @@ func (syncService *SyncService[H]) startSubscriber(ctx context.Context) error {
331332
return nil
332333
}
333334

334-
// Height returns the current height stored
335+
// Height returns the current height storeda
335336
func (s *SyncService[H]) Height() uint64 {
336337
return s.store.Height()
337338
}
@@ -439,11 +440,10 @@ func (syncService *SyncService[H]) fetchAndVerifyTrustedHeader(ctx context.Conte
439440
}
440441

441442
// Verify the hash matches
442-
expectedHash := syncService.trustedHeaderHash
443443
actualHash := trusted.Hash().String()
444-
if actualHash != expectedHash {
445-
return fmt.Errorf("trusted header hash mismatch at height %d: expected %s, got %s",
446-
syncService.trustedHeight, expectedHash, actualHash)
444+
if actualHash != syncService.trustedHeaderHash || actualHash != syncService.trustedDataHash {
445+
return fmt.Errorf("trusted header hash mismatch at height %d: expected %s or %s, got %s",
446+
syncService.trustedHeight, syncService.trustedHeaderHash, syncService.trustedDataHash, actualHash)
447447
}
448448

449449
syncService.logger.Info().Uint64("height", syncService.trustedHeight).

0 commit comments

Comments
 (0)