Skip to content

Commit 6c0654e

Browse files
committed
add read-only mode for key-value store and update store-info command
1 parent 4a66f9e commit 6c0654e

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

pkg/cmd/store.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ var StoreP2PInspectCmd = &cobra.Command{
7171
Use: "store-info",
7272
Short: "Inspect the go-header (P2P) stores and display their tail/head entries",
7373
Long: `Opens the datastore used by the node's go-header services and reports
74-
the current height, head, and tail information for both the header and data stores.`,
74+
the current height, head, and tail information for both the header and data stores.
75+
The datastore is opened in read-only mode so that it can run against mounted snapshots
76+
or other read-only environments without requiring write access.`,
7577
RunE: func(cmd *cobra.Command, args []string) error {
7678
nodeConfig, err := ParseConfig(cmd)
7779
if err != nil {
@@ -85,7 +87,7 @@ the current height, head, and tail information for both the header and data stor
8587

8688
dbName := resolveDBName(cmd)
8789

88-
rawStore, err := store.NewDefaultKVStore(nodeConfig.RootDir, nodeConfig.DBPath, dbName)
90+
rawStore, err := store.NewDefaultReadOnlyKVStore(nodeConfig.RootDir, nodeConfig.DBPath, dbName)
8991
if err != nil {
9092
return fmt.Errorf("failed to open datastore: %w", err)
9193
}

pkg/store/kv.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,22 @@ import (
1313

1414
// NewDefaultKVStore creates instance of default key-value store.
1515
func NewDefaultKVStore(rootDir, dbPath, dbName string) (ds.Batching, error) {
16+
return newDefaultKVStore(rootDir, dbPath, dbName, nil)
17+
}
18+
19+
// NewDefaultReadOnlyKVStore creates a key-value store opened in badger's read-only mode.
20+
//
21+
// This is useful for tools that only inspect state (such as store-info) where the
22+
// underlying data directory might be mounted read-only.
23+
func NewDefaultReadOnlyKVStore(rootDir, dbPath, dbName string) (ds.Batching, error) {
24+
opts := badger4.DefaultOptions
25+
opts.Options = opts.Options.WithReadOnly(true)
26+
return newDefaultKVStore(rootDir, dbPath, dbName, &opts)
27+
}
28+
29+
func newDefaultKVStore(rootDir, dbPath, dbName string, options *badger4.Options) (ds.Batching, error) {
1630
path := filepath.Join(rootify(rootDir, dbPath), dbName)
17-
return badger4.NewDatastore(path, nil)
31+
return badger4.NewDatastore(path, options)
1832
}
1933

2034
// PrefixEntries retrieves all entries in the datastore whose keys have the supplied prefix

pkg/store/kv_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package store
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
ds "github.com/ipfs/go-datastore"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestNewDefaultReadOnlyKVStore(t *testing.T) {
12+
t.Parallel()
13+
14+
ctx := context.Background()
15+
rootDir := t.TempDir()
16+
const dbPath = "db"
17+
const dbName = "test"
18+
19+
writable, err := NewDefaultKVStore(rootDir, dbPath, dbName)
20+
require.NoError(t, err)
21+
require.NoError(t, writable.Put(ctx, ds.NewKey("/foo"), []byte("bar")))
22+
require.NoError(t, writable.Close())
23+
24+
readOnly, err := NewDefaultReadOnlyKVStore(rootDir, dbPath, dbName)
25+
require.NoError(t, err)
26+
t.Cleanup(func() {
27+
_ = readOnly.Close()
28+
})
29+
30+
val, err := readOnly.Get(ctx, ds.NewKey("/foo"))
31+
require.NoError(t, err)
32+
require.Equal(t, []byte("bar"), val)
33+
34+
err = readOnly.Put(ctx, ds.NewKey("/foo"), []byte("baz"))
35+
require.Error(t, err, "writing to a read-only store should fail")
36+
}

pkg/sync/sync_service.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ func (syncService *SyncService[H]) WriteToStoreAndBroadcast(ctx context.Context,
169169
}
170170

171171
syncService.logger.Error().Err(err).Msg("failed to broadcast")
172+
panic(err)
172173
}
173174

174175
return nil

0 commit comments

Comments
 (0)