Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions block.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

type Block[T any] struct {
Hash common.Hash `json:"blockHash"`
Parent common.Hash `json:"parentHash"`
Number uint64 `json:"blockNum"`
TS uint64 `json:"blockTS"` // unix ts
Data T `json:"blockData"`
Expand Down
70 changes: 70 additions & 0 deletions writer_with_verify_hash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package ethwal

import (
"context"
"fmt"

"github.com/0xsequence/ethkit/go-ethereum/common"
)

type BlockHashGetter func(ctx context.Context, blockNum uint64) (common.Hash, error)

func BlockHashGetterFromReader[T any](options Options) BlockHashGetter {
return func(ctx context.Context, blockNum uint64) (common.Hash, error) {
reader, err := NewReader[T](options)
if err != nil {
return common.Hash{}, fmt.Errorf("failed to create reader: %w", err)
}
defer reader.Close()

err = reader.Seek(ctx, blockNum-1)
if err != nil {
return common.Hash{}, fmt.Errorf("failed to seek to block %d: %w", blockNum, err)
}

block, err := reader.Read(ctx)
if err != nil {
return common.Hash{}, fmt.Errorf("failed to read block %d: %w", blockNum, err)
}
return block.Hash, nil
}
}

type writerWithVerifyHash[T any] struct {
Writer[T]

blockHashGetter BlockHashGetter

prevHash common.Hash
}

var _ Writer[any] = (*writerWithVerifyHash[any])(nil)

func NewWriterWithVerifyHash[T any](writer Writer[T], blockHashGetter BlockHashGetter) Writer[T] {
return &writerWithVerifyHash[T]{Writer: writer, blockHashGetter: blockHashGetter}
}

func (w *writerWithVerifyHash[T]) Write(ctx context.Context, b Block[T]) error {
var err error
if w.prevHash == (common.Hash{}) && b.Number > 1 {
w.prevHash, err = w.blockHashGetter(ctx, b.Number-1)
if err != nil {
return fmt.Errorf("failed to get block hash: %w", err)
}
}

if b.Parent != w.prevHash {
w.prevHash = common.Hash{}
return fmt.Errorf("parent hash mismatch, expected %s, got %s",
w.prevHash.String(), b.Parent.String())
}

err = w.Writer.Write(ctx, b)
if err != nil {
w.prevHash = common.Hash{}
return fmt.Errorf("failed to write block: %w", err)
}

w.prevHash = b.Hash
return nil
}
Loading