diff --git a/apps/evm/single/go.mod b/apps/evm/single/go.mod index db2a1097dc..e04860bf4b 100644 --- a/apps/evm/single/go.mod +++ b/apps/evm/single/go.mod @@ -10,6 +10,7 @@ replace ( github.com/evstack/ev-node/da => ../../../da github.com/evstack/ev-node/execution/evm => ../../../execution/evm github.com/evstack/ev-node/sequencers/single => ../../../sequencers/single + github.com/ipfs/go-datastore => github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4 ) require ( @@ -52,7 +53,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.20.0 // indirect github.com/buger/goterm v1.0.4 // indirect - github.com/celestiaorg/go-header v0.6.6 // indirect + github.com/celestiaorg/go-header v0.7.1 // indirect github.com/celestiaorg/go-libp2p-messenger v0.2.2 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cenkalti/backoff/v5 v5.0.2 // indirect diff --git a/apps/evm/single/go.sum b/apps/evm/single/go.sum index b159c0389a..4cf65b7f2b 100644 --- a/apps/evm/single/go.sum +++ b/apps/evm/single/go.sum @@ -102,8 +102,10 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/celestiaorg/go-header v0.6.6 h1:17GvSXU/w8L1YWHZP4pYm9/4YHA8iy5Ku2wTEKYYkCU= -github.com/celestiaorg/go-header v0.6.6/go.mod h1:RdnlTmsyuNerztNiJiQE5G/EGEH+cErhQ83xNjuGcaQ= +github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4 h1:udw77BU45zmvTV7798FhR1wHFmsFpu4GnA5mubtMcR0= +github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4/go.mod h1:W+pI1NsUsz3tcsAACMtfC+IZdnQTnC/7VfPoJBQuts0= +github.com/celestiaorg/go-header v0.7.1 h1:XG0fQykSjKsCtWl9sY5jZXG12D4Xe59bjklWZ2sWip0= +github.com/celestiaorg/go-header v0.7.1/go.mod h1:eX9iTSPthVEAlEDLux40ZT/olXPGhpxHd+mEzJeDhd0= github.com/celestiaorg/go-libp2p-messenger v0.2.2 h1:osoUfqjss7vWTIZrrDSy953RjQz+ps/vBFE7bychLEc= github.com/celestiaorg/go-libp2p-messenger v0.2.2/go.mod h1:oTCRV5TfdO7V/k6nkx7QjQzGrWuJbupv+0o1cgnY2i4= github.com/celestiaorg/utils v0.1.0 h1:WsP3O8jF7jKRgLNFmlDCwdThwOFMFxg0MnqhkLFVxPo= @@ -439,8 +441,6 @@ github.com/ipfs/go-block-format v0.2.2 h1:uecCTgRwDIXyZPgYspaLXoMiMmxQpSx2aq34eN github.com/ipfs/go-block-format v0.2.2/go.mod h1:vmuefuWU6b+9kIU0vZJgpiJt1yicQz9baHXE8qR+KB8= github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk= -github.com/ipfs/go-datastore v0.8.3 h1:z391GsQyGKUIUof2tPoaZVeDknbt7fNHs6Gqjcw5Jo4= -github.com/ipfs/go-datastore v0.8.3/go.mod h1:raxQ/CreIy9L6MxT71ItfMX12/ASN6EhXJoUFjICQ2M= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger4 v0.1.8 h1:frNczf5CjCVm62RJ5mW5tD/oLQY/9IKAUpKviRV9QAI= diff --git a/apps/grpc/single/go.mod b/apps/grpc/single/go.mod index 8727cd3210..69aa00f276 100644 --- a/apps/grpc/single/go.mod +++ b/apps/grpc/single/go.mod @@ -18,7 +18,7 @@ require ( connectrpc.com/grpcreflect v1.3.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/celestiaorg/go-header v0.6.6 // indirect + github.com/celestiaorg/go-header v0.7.1 // indirect github.com/celestiaorg/go-libp2p-messenger v0.2.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -167,4 +167,5 @@ replace ( github.com/evstack/ev-node/da => ../../../da github.com/evstack/ev-node/execution/grpc => ../../../execution/grpc github.com/evstack/ev-node/sequencers/single => ../../../sequencers/single + github.com/ipfs/go-datastore => github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4 ) diff --git a/apps/grpc/single/go.sum b/apps/grpc/single/go.sum index 49a9ad3d1e..a3735abac3 100644 --- a/apps/grpc/single/go.sum +++ b/apps/grpc/single/go.sum @@ -22,8 +22,10 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/celestiaorg/go-header v0.6.6 h1:17GvSXU/w8L1YWHZP4pYm9/4YHA8iy5Ku2wTEKYYkCU= -github.com/celestiaorg/go-header v0.6.6/go.mod h1:RdnlTmsyuNerztNiJiQE5G/EGEH+cErhQ83xNjuGcaQ= +github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4 h1:udw77BU45zmvTV7798FhR1wHFmsFpu4GnA5mubtMcR0= +github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4/go.mod h1:W+pI1NsUsz3tcsAACMtfC+IZdnQTnC/7VfPoJBQuts0= +github.com/celestiaorg/go-header v0.7.1 h1:XG0fQykSjKsCtWl9sY5jZXG12D4Xe59bjklWZ2sWip0= +github.com/celestiaorg/go-header v0.7.1/go.mod h1:eX9iTSPthVEAlEDLux40ZT/olXPGhpxHd+mEzJeDhd0= github.com/celestiaorg/go-libp2p-messenger v0.2.2 h1:osoUfqjss7vWTIZrrDSy953RjQz+ps/vBFE7bychLEc= github.com/celestiaorg/go-libp2p-messenger v0.2.2/go.mod h1:oTCRV5TfdO7V/k6nkx7QjQzGrWuJbupv+0o1cgnY2i4= github.com/celestiaorg/utils v0.1.0 h1:WsP3O8jF7jKRgLNFmlDCwdThwOFMFxg0MnqhkLFVxPo= @@ -153,8 +155,6 @@ github.com/ipfs/go-block-format v0.2.2 h1:uecCTgRwDIXyZPgYspaLXoMiMmxQpSx2aq34eN github.com/ipfs/go-block-format v0.2.2/go.mod h1:vmuefuWU6b+9kIU0vZJgpiJt1yicQz9baHXE8qR+KB8= github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk= -github.com/ipfs/go-datastore v0.8.3 h1:z391GsQyGKUIUof2tPoaZVeDknbt7fNHs6Gqjcw5Jo4= -github.com/ipfs/go-datastore v0.8.3/go.mod h1:raxQ/CreIy9L6MxT71ItfMX12/ASN6EhXJoUFjICQ2M= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger4 v0.1.8 h1:frNczf5CjCVm62RJ5mW5tD/oLQY/9IKAUpKviRV9QAI= diff --git a/apps/testapp/cmd/rollback.go b/apps/testapp/cmd/rollback.go index e1b0eb519b..0daac766f8 100644 --- a/apps/testapp/cmd/rollback.go +++ b/apps/testapp/cmd/rollback.go @@ -6,8 +6,14 @@ import ( "strconv" kvexecutor "github.com/evstack/ev-node/apps/testapp/kv" + "github.com/evstack/ev-node/node" rollcmd "github.com/evstack/ev-node/pkg/cmd" "github.com/evstack/ev-node/pkg/store" + "github.com/evstack/ev-node/types" + + goheaderstore "github.com/celestiaorg/go-header/store" + ds "github.com/ipfs/go-datastore" + kt "github.com/ipfs/go-datastore/keytransform" "github.com/spf13/cobra" ) @@ -28,13 +34,48 @@ var RollbackCmd = &cobra.Command{ if err != nil { return err } - storeWrapper := store.New(datastore) + + // prefixed evolve db + evolveDB := kt.Wrap(datastore, &kt.PrefixTransform{ + Prefix: ds.NewKey(node.EvPrefix), + }) + + storeWrapper := store.New(evolveDB) executor, err := kvexecutor.NewKVExecutor(nodeConfig.RootDir, nodeConfig.DBPath) if err != nil { return err } + // rollback ev-node goheader state + headerStore, err := goheaderstore.NewStore[*types.SignedHeader]( + evolveDB, + goheaderstore.WithStorePrefix("headerSync"), + goheaderstore.WithMetrics(), + ) + if err != nil { + return err + } + + dataStore, err := goheaderstore.NewStore[*types.Data]( + evolveDB, + goheaderstore.WithStorePrefix("dataSync"), + goheaderstore.WithMetrics(), + ) + if err != nil { + return err + } + + if err := headerStore.Start(ctx); err != nil { + return err + } + defer headerStore.Stop(ctx) + + if err := dataStore.Start(ctx); err != nil { + return err + } + defer dataStore.Stop(ctx) + cmd.Println("Starting rollback operation") currentHeight, err := storeWrapper.Height(ctx) if err != nil { @@ -54,6 +95,15 @@ var RollbackCmd = &cobra.Command{ return fmt.Errorf("rollback failed: %w", err) } + // rollback sync services + if err := headerStore.DeleteTo(ctx, targetHeight); err != nil { + return fmt.Errorf("failed to rollback header sync service state: %w", err) + } + + if err := dataStore.DeleteTo(ctx, targetHeight); err != nil { + return fmt.Errorf("failed to rollback data sync service state: %w", err) + } + // rollback execution store if err := executor.Rollback(ctx, targetHeight); err != nil { return fmt.Errorf("rollback failed: %w", err) diff --git a/apps/testapp/go.mod b/apps/testapp/go.mod index a08a8603e2..3f9f4e1e54 100644 --- a/apps/testapp/go.mod +++ b/apps/testapp/go.mod @@ -7,9 +7,11 @@ replace ( github.com/evstack/ev-node/core => ../../core github.com/evstack/ev-node/da => ../../da github.com/evstack/ev-node/sequencers/single => ../../sequencers/single + github.com/ipfs/go-datastore => github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4 ) require ( + github.com/celestiaorg/go-header v0.7.1 github.com/evstack/ev-node v0.0.0-00010101000000-000000000000 github.com/evstack/ev-node/core v0.0.0-20250312114929-104787ba1a4c github.com/evstack/ev-node/da v0.0.0-00010101000000-000000000000 @@ -24,7 +26,6 @@ require ( connectrpc.com/grpcreflect v1.3.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/celestiaorg/go-header v0.6.6 // indirect github.com/celestiaorg/go-libp2p-messenger v0.2.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/apps/testapp/go.sum b/apps/testapp/go.sum index 49a9ad3d1e..a3735abac3 100644 --- a/apps/testapp/go.sum +++ b/apps/testapp/go.sum @@ -22,8 +22,10 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/celestiaorg/go-header v0.6.6 h1:17GvSXU/w8L1YWHZP4pYm9/4YHA8iy5Ku2wTEKYYkCU= -github.com/celestiaorg/go-header v0.6.6/go.mod h1:RdnlTmsyuNerztNiJiQE5G/EGEH+cErhQ83xNjuGcaQ= +github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4 h1:udw77BU45zmvTV7798FhR1wHFmsFpu4GnA5mubtMcR0= +github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4/go.mod h1:W+pI1NsUsz3tcsAACMtfC+IZdnQTnC/7VfPoJBQuts0= +github.com/celestiaorg/go-header v0.7.1 h1:XG0fQykSjKsCtWl9sY5jZXG12D4Xe59bjklWZ2sWip0= +github.com/celestiaorg/go-header v0.7.1/go.mod h1:eX9iTSPthVEAlEDLux40ZT/olXPGhpxHd+mEzJeDhd0= github.com/celestiaorg/go-libp2p-messenger v0.2.2 h1:osoUfqjss7vWTIZrrDSy953RjQz+ps/vBFE7bychLEc= github.com/celestiaorg/go-libp2p-messenger v0.2.2/go.mod h1:oTCRV5TfdO7V/k6nkx7QjQzGrWuJbupv+0o1cgnY2i4= github.com/celestiaorg/utils v0.1.0 h1:WsP3O8jF7jKRgLNFmlDCwdThwOFMFxg0MnqhkLFVxPo= @@ -153,8 +155,6 @@ github.com/ipfs/go-block-format v0.2.2 h1:uecCTgRwDIXyZPgYspaLXoMiMmxQpSx2aq34eN github.com/ipfs/go-block-format v0.2.2/go.mod h1:vmuefuWU6b+9kIU0vZJgpiJt1yicQz9baHXE8qR+KB8= github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk= -github.com/ipfs/go-datastore v0.8.3 h1:z391GsQyGKUIUof2tPoaZVeDknbt7fNHs6Gqjcw5Jo4= -github.com/ipfs/go-datastore v0.8.3/go.mod h1:raxQ/CreIy9L6MxT71ItfMX12/ASN6EhXJoUFjICQ2M= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger4 v0.1.8 h1:frNczf5CjCVm62RJ5mW5tD/oLQY/9IKAUpKviRV9QAI= diff --git a/go.mod b/go.mod index 8b0d29cda8..685f927093 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,12 @@ retract v0.12.0 // Published by accident replace github.com/evstack/ev-node/core => ./core +replace github.com/ipfs/go-datastore => github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4 + require ( connectrpc.com/connect v1.18.1 connectrpc.com/grpcreflect v1.3.0 - github.com/celestiaorg/go-header v0.6.6 + github.com/celestiaorg/go-header v0.7.1 github.com/celestiaorg/utils v0.1.0 github.com/evstack/ev-node/core v0.0.0-00010101000000-000000000000 github.com/go-kit/kit v0.13.0 diff --git a/go.sum b/go.sum index f5583d2495..e948be321e 100644 --- a/go.sum +++ b/go.sum @@ -22,8 +22,10 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/celestiaorg/go-header v0.6.6 h1:17GvSXU/w8L1YWHZP4pYm9/4YHA8iy5Ku2wTEKYYkCU= -github.com/celestiaorg/go-header v0.6.6/go.mod h1:RdnlTmsyuNerztNiJiQE5G/EGEH+cErhQ83xNjuGcaQ= +github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4 h1:udw77BU45zmvTV7798FhR1wHFmsFpu4GnA5mubtMcR0= +github.com/celestiaorg/go-datastore v0.0.0-20250801131506-48a63ae531e4/go.mod h1:W+pI1NsUsz3tcsAACMtfC+IZdnQTnC/7VfPoJBQuts0= +github.com/celestiaorg/go-header v0.7.1 h1:XG0fQykSjKsCtWl9sY5jZXG12D4Xe59bjklWZ2sWip0= +github.com/celestiaorg/go-header v0.7.1/go.mod h1:eX9iTSPthVEAlEDLux40ZT/olXPGhpxHd+mEzJeDhd0= github.com/celestiaorg/go-libp2p-messenger v0.2.2 h1:osoUfqjss7vWTIZrrDSy953RjQz+ps/vBFE7bychLEc= github.com/celestiaorg/go-libp2p-messenger v0.2.2/go.mod h1:oTCRV5TfdO7V/k6nkx7QjQzGrWuJbupv+0o1cgnY2i4= github.com/celestiaorg/utils v0.1.0 h1:WsP3O8jF7jKRgLNFmlDCwdThwOFMFxg0MnqhkLFVxPo= @@ -151,8 +153,6 @@ github.com/ipfs/go-block-format v0.2.2 h1:uecCTgRwDIXyZPgYspaLXoMiMmxQpSx2aq34eN github.com/ipfs/go-block-format v0.2.2/go.mod h1:vmuefuWU6b+9kIU0vZJgpiJt1yicQz9baHXE8qR+KB8= github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk= -github.com/ipfs/go-datastore v0.8.3 h1:z391GsQyGKUIUof2tPoaZVeDknbt7fNHs6Gqjcw5Jo4= -github.com/ipfs/go-datastore v0.8.3/go.mod h1:raxQ/CreIy9L6MxT71ItfMX12/ASN6EhXJoUFjICQ2M= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger4 v0.1.8 h1:frNczf5CjCVm62RJ5mW5tD/oLQY/9IKAUpKviRV9QAI= diff --git a/pkg/store/store.go b/pkg/store/store.go index 1d911f1e84..845f398cb2 100644 --- a/pkg/store/store.go +++ b/pkg/store/store.go @@ -262,7 +262,8 @@ func (s *DefaultStore) GetMetadata(ctx context.Context, key string) ([]byte, err } // Rollback rolls back block data until the given height from the store. -// NOTE: this function does not rollback metadata. Those should be handled separately. +// NOTE: this function does not rollback metadata. Those should be handled separately if required. +// Other stores are not rolled back either. func (s *DefaultStore) Rollback(ctx context.Context, height uint64) error { batch, err := s.db.Batch(ctx) if err != nil { diff --git a/pkg/sync/sync_service.go b/pkg/sync/sync_service.go index 66056dec5a..ce6bcb5856 100644 --- a/pkg/sync/sync_service.go +++ b/pkg/sync/sync_service.go @@ -117,37 +117,24 @@ func (syncService *SyncService[H]) Store() *goheaderstore.Store[H] { return syncService.store } -func (syncService *SyncService[H]) initStoreAndStartSyncer(ctx context.Context, initial H) error { - if initial.IsZero() { - return errors.New("failed to initialize the store and start syncer") - } - if err := syncService.store.Init(ctx, initial); err != nil { - return err - } - if err := syncService.StartSyncer(ctx); err != nil { - return err - } - return nil -} - -// WriteToStoreAndBroadcast initializes store if needed and broadcasts provided header or block. +// WriteToStoreAndBroadcast initializes store if needed and broadcasts provided header or block. // Note: Only returns an error in case store can't be initialized. Logs error if there's one while broadcasting. func (syncService *SyncService[H]) WriteToStoreAndBroadcast(ctx context.Context, headerOrData H) error { if syncService.genesis.InitialHeight == 0 { return fmt.Errorf("invalid initial height; cannot be zero") } + isGenesis := headerOrData.Height() == syncService.genesis.InitialHeight - // For genesis header/block initialize the store and start the syncer - if isGenesis { - if err := syncService.store.Init(ctx, headerOrData); err != nil { - return errors.New("failed to initialize the store") + if isGenesis { // when starting the syncer for the first time, we have no blocks, so initFromP2P didn't initialize the genesis block. + if err := syncService.initStore(ctx, headerOrData); err != nil { + return fmt.Errorf("failed to initialize the store: %w", err) } } firstStart := false if !syncService.syncerStatus.started.Load() { firstStart = true - if err := syncService.StartSyncer(ctx); err != nil { + if err := syncService.startSyncer(ctx); err != nil { return fmt.Errorf("failed to start syncer after initializing the store: %w", err) } } @@ -162,29 +149,67 @@ func (syncService *SyncService[H]) WriteToStoreAndBroadcast(ctx context.Context, // for starting the syncer. Hence, we ignore the error. // exact reason: validation failed, err header verification failed: known header: '1' <= current '1' (isGenesis && errors.Is(err, pubsub.ValidationError{Reason: pubsub.RejectValidationFailed})) { + return nil } - return fmt.Errorf("failed to broadcast: %w", err) + + syncService.logger.Error().Err(err).Msg("failed to broadcast") } - return nil -} -func (syncService *SyncService[H]) isInitialized() bool { - return syncService.store.Height() > 0 + return nil } // Start is a part of Service interface. func (syncService *SyncService[H]) Start(ctx context.Context) error { peerIDs, err := syncService.setupP2P(ctx) if err != nil { - return err + return fmt.Errorf("failed to setup syncer P2P: %w", err) + } + + if syncService.syncer, err = newSyncer( + syncService.ex, + syncService.store, + syncService.sub, + []goheadersync.Option{goheadersync.WithBlockTime(syncService.conf.Node.BlockTime.Duration)}, + ); err != nil { + return fmt.Errorf("failed to create syncer: %w", err) + } + + return syncService.initFromP2P(ctx, peerIDs) +} + +// startSyncer starts the SyncService's syncer +func (syncService *SyncService[H]) startSyncer(ctx context.Context) error { + if syncService.syncerStatus.isStarted() { + return nil + } + + if err := syncService.syncer.Start(ctx); err != nil { + return fmt.Errorf("failed to start syncer: %w", err) + } + + syncService.syncerStatus.started.Store(true) + return nil +} + +// initStore initializes the store with the given initial header. +// it is a no-op if the store is already initialized. +func (syncService *SyncService[H]) initStore(ctx context.Context, initial H) error { + if initial.IsZero() { + return errors.New("failed to initialize the store") } - if err := syncService.prepareSyncer(ctx); err != nil { - return err + if _, err := syncService.store.Head(ctx); errors.Is(err, header.ErrNotFound) || errors.Is(err, header.ErrEmptyStore) { + if err := syncService.store.Append(ctx, initial); err != nil { + return err + } + + if err := syncService.store.Sync(ctx); err != nil { + return err + } } - return syncService.setFirstAndStart(ctx, peerIDs) + return nil } // setupP2P sets up the P2P configuration for the SyncService and starts the necessary components. @@ -211,7 +236,6 @@ func (syncService *SyncService[H]) setupP2P(ctx context.Context) ([]peer.ID, err if err := syncService.store.Start(ctx); err != nil { return nil, fmt.Errorf("error while starting store: %w", err) } - _, _, network, err := syncService.p2p.Info() if err != nil { return nil, fmt.Errorf("error while fetching the network: %w", err) @@ -224,7 +248,6 @@ func (syncService *SyncService[H]) setupP2P(ctx context.Context) ([]peer.ID, err if err := syncService.p2pServer.Start(ctx); err != nil { return nil, fmt.Errorf("error while starting p2p server: %w", err) } - peerIDs := syncService.getPeerIDs() if syncService.ex, err = newP2PExchange[H](syncService.p2p.Host(), peerIDs, networkID, syncService.genesis.ChainID, syncService.p2p.ConnectionGater()); err != nil { return nil, fmt.Errorf("error while creating exchange: %w", err) @@ -235,60 +258,44 @@ func (syncService *SyncService[H]) setupP2P(ctx context.Context) ([]peer.ID, err return peerIDs, nil } -// prepareSyncer initializes the syncer for the SyncService with the provided options. -// If the initialization is successful and the SyncService is already initialized, -// it starts the syncer by calling StartSyncer. -// Returns error if initialization or starting of syncer fails. -func (syncService *SyncService[H]) prepareSyncer(ctx context.Context) error { - var err error - if syncService.syncer, err = newSyncer( - syncService.ex, - syncService.store, - syncService.sub, - []goheadersync.Option{goheadersync.WithBlockTime(syncService.conf.Node.BlockTime.Duration)}, - ); err != nil { - return err - } - - if syncService.isInitialized() { - if err := syncService.StartSyncer(ctx); err != nil { - return err - } - } - return nil -} - -// setFirstAndStart looks up for the trusted hash or the genesis header/block. +// initFromP2P looks up for the trusted hash or the genesis header/block. // If trusted hash is available, it fetches the trusted header/block (by hash) from peers. // Otherwise, it tries to fetch the genesis header/block by height. -// If trusted header/block is available, syncer is started. -func (syncService *SyncService[H]) setFirstAndStart(ctx context.Context, peerIDs []peer.ID) error { +func (syncService *SyncService[H]) initFromP2P(ctx context.Context, peerIDs []peer.ID) error { + if len(peerIDs) == 0 { + return nil + } + // Look to see if trusted hash is passed, if not get the genesis header/block - var trusted H + var ( + trusted H + err error + ) + // Try fetching the trusted header/block from peers if exists - if len(peerIDs) > 0 { - if syncService.conf.Node.TrustedHash != "" { - trustedHashBytes, err := hex.DecodeString(syncService.conf.Node.TrustedHash) - if err != nil { - return fmt.Errorf("failed to parse the trusted hash for initializing the store: %w", err) - } - - if trusted, err = syncService.ex.Get(ctx, trustedHashBytes); err != nil { - return fmt.Errorf("failed to fetch the trusted header/block for initializing the store: %w", err) - } - } else { - // Try fetching the genesis header/block if available, otherwise fallback to block - var err error - if trusted, err = syncService.ex.GetByHeight(ctx, syncService.genesis.InitialHeight); err != nil { - // Full/light nodes have to wait for aggregator to publish the genesis block - // proposing aggregator can init the store and start the syncer when the first block is published - return fmt.Errorf("failed to fetch the genesis: %w", err) - } + if syncService.conf.Node.TrustedHash != "" { + trustedHashBytes, err := hex.DecodeString(syncService.conf.Node.TrustedHash) + if err != nil { + return fmt.Errorf("failed to parse the trusted hash for initializing the store: %w", err) } - return syncService.initStoreAndStartSyncer(ctx, trusted) + if trusted, err = syncService.ex.Get(ctx, trustedHashBytes); err != nil { + return fmt.Errorf("failed to fetch the trusted header/block for initializing the store: %w", err) + } + } else { + // Try fetching the genesis header/block if available, otherwise fallback to block + if trusted, err = syncService.ex.GetByHeight(ctx, syncService.genesis.InitialHeight); err != nil { + // Full/light nodes have to wait for aggregator to publish the genesis block + // proposing aggregator can init the store and start the syncer when the first block is published + return fmt.Errorf("failed to fetch the genesis: %w", err) + } } - return nil + + if err := syncService.initStore(ctx, trusted); err != nil { + return fmt.Errorf("failed to initialize the store: %w", err) + } + + return syncService.startSyncer(ctx) } // Stop is a part of Service interface. @@ -351,19 +358,6 @@ func newSyncer[H header.Header[H]]( return goheadersync.NewSyncer(ex, store, sub, opts...) } -// StartSyncer starts the SyncService's syncer -func (syncService *SyncService[H]) StartSyncer(ctx context.Context) error { - if syncService.syncerStatus.isStarted() { - return nil - } - err := syncService.syncer.Start(ctx) - if err != nil { - return err - } - syncService.syncerStatus.started.Store(true) - return nil -} - func (syncService *SyncService[H]) getNetworkID(network string) string { return network + "-" + string(syncService.syncType) } diff --git a/sequencers/single/go.mod b/sequencers/single/go.mod index c375a0d094..7bc406e7ff 100644 --- a/sequencers/single/go.mod +++ b/sequencers/single/go.mod @@ -21,7 +21,7 @@ require ( require ( github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/celestiaorg/go-header v0.6.6 // indirect + github.com/celestiaorg/go-header v0.7.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect diff --git a/sequencers/single/go.sum b/sequencers/single/go.sum index bcc7986ac1..7dc856cd0a 100644 --- a/sequencers/single/go.sum +++ b/sequencers/single/go.sum @@ -18,8 +18,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/celestiaorg/go-header v0.6.6 h1:17GvSXU/w8L1YWHZP4pYm9/4YHA8iy5Ku2wTEKYYkCU= -github.com/celestiaorg/go-header v0.6.6/go.mod h1:RdnlTmsyuNerztNiJiQE5G/EGEH+cErhQ83xNjuGcaQ= +github.com/celestiaorg/go-header v0.7.1 h1:XG0fQykSjKsCtWl9sY5jZXG12D4Xe59bjklWZ2sWip0= +github.com/celestiaorg/go-header v0.7.1/go.mod h1:eX9iTSPthVEAlEDLux40ZT/olXPGhpxHd+mEzJeDhd0= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= diff --git a/test/e2e/go.mod b/test/e2e/go.mod index feea5401be..69e8900546 100644 --- a/test/e2e/go.mod +++ b/test/e2e/go.mod @@ -45,7 +45,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.20.0 // indirect github.com/buger/goterm v1.0.4 // indirect - github.com/celestiaorg/go-header v0.6.6 // indirect + github.com/celestiaorg/go-header v0.7.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/compose-spec/compose-go/v2 v2.6.0 // indirect diff --git a/test/e2e/go.sum b/test/e2e/go.sum index 6bfe30c663..25f00b217a 100644 --- a/test/e2e/go.sum +++ b/test/e2e/go.sum @@ -89,8 +89,8 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/celestiaorg/go-header v0.6.6 h1:17GvSXU/w8L1YWHZP4pYm9/4YHA8iy5Ku2wTEKYYkCU= -github.com/celestiaorg/go-header v0.6.6/go.mod h1:RdnlTmsyuNerztNiJiQE5G/EGEH+cErhQ83xNjuGcaQ= +github.com/celestiaorg/go-header v0.7.1 h1:XG0fQykSjKsCtWl9sY5jZXG12D4Xe59bjklWZ2sWip0= +github.com/celestiaorg/go-header v0.7.1/go.mod h1:eX9iTSPthVEAlEDLux40ZT/olXPGhpxHd+mEzJeDhd0= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -337,8 +337,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= -github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18= +github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -599,8 +599,8 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0= -github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM= +github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= +github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= @@ -870,6 +870,8 @@ go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mx go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/dig v1.19.0 h1:BACLhebsYdpQ7IROQ1AGPjrXcP5dF80U3gKoFzbaq/4= go.uber.org/dig v1.19.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.24.0 h1:wE8mruvpg2kiiL1Vqd0CC+tr0/24XIB10Iwp2lLWzkg= diff --git a/test/mocks/external/hstore.go b/test/mocks/external/hstore.go index 8a328b6a89..c484558d9d 100644 --- a/test/mocks/external/hstore.go +++ b/test/mocks/external/hstore.go @@ -108,6 +108,63 @@ func (_c *MockStore_Append_Call[H]) RunAndReturn(run func(context1 context.Conte return _c } +// DeleteTo provides a mock function for the type MockStore +func (_mock *MockStore[H]) DeleteTo(ctx context.Context, to uint64) error { + ret := _mock.Called(ctx, to) + + if len(ret) == 0 { + panic("no return value specified for DeleteTo") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, uint64) error); ok { + r0 = returnFunc(ctx, to) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockStore_DeleteTo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteTo' +type MockStore_DeleteTo_Call[H header.Header[H]] struct { + *mock.Call +} + +// DeleteTo is a helper method to define mock.On call +// - ctx context.Context +// - to uint64 +func (_e *MockStore_Expecter[H]) DeleteTo(ctx interface{}, to interface{}) *MockStore_DeleteTo_Call[H] { + return &MockStore_DeleteTo_Call[H]{Call: _e.mock.On("DeleteTo", ctx, to)} +} + +func (_c *MockStore_DeleteTo_Call[H]) Run(run func(ctx context.Context, to uint64)) *MockStore_DeleteTo_Call[H] { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 uint64 + if args[1] != nil { + arg1 = args[1].(uint64) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockStore_DeleteTo_Call[H]) Return(err error) *MockStore_DeleteTo_Call[H] { + _c.Call.Return(err) + return _c +} + +func (_c *MockStore_DeleteTo_Call[H]) RunAndReturn(run func(ctx context.Context, to uint64) error) *MockStore_DeleteTo_Call[H] { + _c.Call.Return(run) + return _c +} + // Get provides a mock function for the type MockStore func (_mock *MockStore[H]) Get(context1 context.Context, hash header.Hash) (H, error) { ret := _mock.Called(context1, hash) @@ -640,59 +697,104 @@ func (_c *MockStore_Height_Call[H]) RunAndReturn(run func() uint64) *MockStore_H return _c } -// Init provides a mock function for the type MockStore -func (_mock *MockStore[H]) Init(context1 context.Context, v H) error { - ret := _mock.Called(context1, v) +// OnDelete provides a mock function for the type MockStore +func (_mock *MockStore[H]) OnDelete(handler func(ctx context.Context, height uint64) error) { + _mock.Called(handler) + return +} + +// MockStore_OnDelete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OnDelete' +type MockStore_OnDelete_Call[H header.Header[H]] struct { + *mock.Call +} + +// OnDelete is a helper method to define mock.On call +// - handler func(ctx context.Context, height uint64) error +func (_e *MockStore_Expecter[H]) OnDelete(handler interface{}) *MockStore_OnDelete_Call[H] { + return &MockStore_OnDelete_Call[H]{Call: _e.mock.On("OnDelete", handler)} +} + +func (_c *MockStore_OnDelete_Call[H]) Run(run func(handler func(ctx context.Context, height uint64) error)) *MockStore_OnDelete_Call[H] { + _c.Call.Run(func(args mock.Arguments) { + var arg0 func(ctx context.Context, height uint64) error + if args[0] != nil { + arg0 = args[0].(func(ctx context.Context, height uint64) error) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockStore_OnDelete_Call[H]) Return() *MockStore_OnDelete_Call[H] { + _c.Call.Return() + return _c +} + +func (_c *MockStore_OnDelete_Call[H]) RunAndReturn(run func(handler func(ctx context.Context, height uint64) error)) *MockStore_OnDelete_Call[H] { + _c.Run(run) + return _c +} + +// Tail provides a mock function for the type MockStore +func (_mock *MockStore[H]) Tail(context1 context.Context) (H, error) { + ret := _mock.Called(context1) if len(ret) == 0 { - panic("no return value specified for Init") + panic("no return value specified for Tail") } - var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, H) error); ok { - r0 = returnFunc(context1, v) + var r0 H + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context) (H, error)); ok { + return returnFunc(context1) + } + if returnFunc, ok := ret.Get(0).(func(context.Context) H); ok { + r0 = returnFunc(context1) } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(H) + } } - return r0 + if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = returnFunc(context1) + } else { + r1 = ret.Error(1) + } + return r0, r1 } -// MockStore_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' -type MockStore_Init_Call[H header.Header[H]] struct { +// MockStore_Tail_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Tail' +type MockStore_Tail_Call[H header.Header[H]] struct { *mock.Call } -// Init is a helper method to define mock.On call +// Tail is a helper method to define mock.On call // - context1 context.Context -// - v H -func (_e *MockStore_Expecter[H]) Init(context1 interface{}, v interface{}) *MockStore_Init_Call[H] { - return &MockStore_Init_Call[H]{Call: _e.mock.On("Init", context1, v)} +func (_e *MockStore_Expecter[H]) Tail(context1 interface{}) *MockStore_Tail_Call[H] { + return &MockStore_Tail_Call[H]{Call: _e.mock.On("Tail", context1)} } -func (_c *MockStore_Init_Call[H]) Run(run func(context1 context.Context, v H)) *MockStore_Init_Call[H] { +func (_c *MockStore_Tail_Call[H]) Run(run func(context1 context.Context)) *MockStore_Tail_Call[H] { _c.Call.Run(func(args mock.Arguments) { var arg0 context.Context if args[0] != nil { arg0 = args[0].(context.Context) } - var arg1 H - if args[1] != nil { - arg1 = args[1].(H) - } run( arg0, - arg1, ) }) return _c } -func (_c *MockStore_Init_Call[H]) Return(err error) *MockStore_Init_Call[H] { - _c.Call.Return(err) +func (_c *MockStore_Tail_Call[H]) Return(v H, err error) *MockStore_Tail_Call[H] { + _c.Call.Return(v, err) return _c } -func (_c *MockStore_Init_Call[H]) RunAndReturn(run func(context1 context.Context, v H) error) *MockStore_Init_Call[H] { +func (_c *MockStore_Tail_Call[H]) RunAndReturn(run func(context1 context.Context) (H, error)) *MockStore_Tail_Call[H] { _c.Call.Return(run) return _c }