Skip to content

Commit 42886b7

Browse files
committed
go/worker/storage: Create new runtime storage worker
This worker will be responsible for orchestrating storage operations for the given runtime. This includes: 1. Registering availability 2. Creating checkpoints if configured 3. Pruning state 4. Syncing state (internally init, checkpoint sync and diff sync) Subsequent commit will do the outlined refactor above.
1 parent ce420f1 commit 42886b7

4 files changed

Lines changed: 107 additions & 37 deletions

File tree

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package storage
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/eapache/channels"
8+
"golang.org/x/sync/errgroup"
9+
10+
"github.com/oasisprotocol/oasis-core/go/common/logging"
11+
runtimeAPI "github.com/oasisprotocol/oasis-core/go/runtime/api"
12+
"github.com/oasisprotocol/oasis-core/go/runtime/host"
13+
"github.com/oasisprotocol/oasis-core/go/storage/api"
14+
committeeCommon "github.com/oasisprotocol/oasis-core/go/worker/common/committee"
15+
"github.com/oasisprotocol/oasis-core/go/worker/registration"
16+
storageAPI "github.com/oasisprotocol/oasis-core/go/worker/storage/api"
17+
"github.com/oasisprotocol/oasis-core/go/worker/storage/statesync"
18+
)
19+
20+
// Worker is handling storage operations for a single runtime.
21+
type worker struct {
22+
logger *logging.Logger
23+
stateSync *statesync.Worker
24+
stateSyncBlkCh *channels.InfiniteChannel
25+
}
26+
27+
func newRuntimeWorker(
28+
commonNode *committeeCommon.Node,
29+
rp registration.RoleProvider,
30+
rpRPC registration.RoleProvider,
31+
localStorage api.LocalBackend,
32+
checkpointerCfg *statesync.CheckpointSyncConfig,
33+
) (*worker, error) {
34+
worker := &worker{
35+
logger: logging.GetLogger("worker/storage").With("runtimeID", commonNode.Runtime.ID()),
36+
stateSyncBlkCh: channels.NewInfiniteChannel(),
37+
}
38+
39+
stateSync, err := statesync.New(
40+
commonNode,
41+
rp,
42+
rpRPC,
43+
localStorage,
44+
worker.stateSyncBlkCh,
45+
checkpointerCfg,
46+
)
47+
if err != nil {
48+
return nil, fmt.Errorf("failed to create state sync worker: %w", err)
49+
}
50+
51+
worker.stateSync = stateSync
52+
53+
return worker, nil
54+
}
55+
56+
// NodeHooks implementation.
57+
58+
// HandleNewBlockEarlyLocked is guarded by CrossNode.
59+
func (w *worker) HandleNewBlockEarlyLocked(*runtimeAPI.BlockInfo) {
60+
// Nothing to do here.
61+
}
62+
63+
// HandleNewBlockLocked is guarded by CrossNode.
64+
func (w *worker) HandleNewBlockLocked(bi *runtimeAPI.BlockInfo) {
65+
// Notify the state syncer that there is a new block.
66+
w.stateSyncBlkCh.In() <- bi.RuntimeBlock
67+
}
68+
69+
// HandleRuntimeHostEventLocked is guarded by CrossNode.
70+
func (w *worker) HandleRuntimeHostEventLocked(*host.Event) {
71+
// Nothing to do here.
72+
}
73+
74+
// Initialized returns a channel that will be closed once the worker finished starting up.
75+
func (w *worker) Initialized() <-chan struct{} {
76+
return w.stateSync.Initialized()
77+
}
78+
79+
func (w *worker) GetStatus(ctx context.Context) (*storageAPI.Status, error) {
80+
return w.stateSync.GetStatus(ctx)
81+
}
82+
83+
func (w *worker) PauseCheckpointer(pause bool) error {
84+
return w.stateSync.PauseCheckpointer(pause)
85+
}
86+
87+
func (w *worker) serve(ctx context.Context) error {
88+
w.logger.Info("started")
89+
defer w.logger.Info("stopped")
90+
91+
g, ctx := errgroup.WithContext(ctx)
92+
g.Go(func() error {
93+
return w.stateSync.Serve(ctx)
94+
})
95+
return g.Wait()
96+
}

go/worker/storage/service_internal.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func (w *Worker) GetLastSyncedRound(_ context.Context, request *api.GetLastSynce
1414
return nil, api.ErrRuntimeNotFound
1515
}
1616

17-
round, ioRoot, stateRoot := node.GetLastSynced()
17+
round, ioRoot, stateRoot := node.stateSync.GetLastSynced()
1818
return &api.GetLastSyncedRoundResponse{
1919
Round: round,
2020
IORoot: ioRoot,

go/worker/storage/statesync/state_sync.go

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,9 @@ import (
2424
registryApi "github.com/oasisprotocol/oasis-core/go/registry/api"
2525
roothashApi "github.com/oasisprotocol/oasis-core/go/roothash/api"
2626
"github.com/oasisprotocol/oasis-core/go/roothash/api/block"
27-
runtime "github.com/oasisprotocol/oasis-core/go/runtime/api"
28-
"github.com/oasisprotocol/oasis-core/go/runtime/host"
2927
storageApi "github.com/oasisprotocol/oasis-core/go/storage/api"
3028
"github.com/oasisprotocol/oasis-core/go/storage/mkvs/checkpoint"
3129
dbApi "github.com/oasisprotocol/oasis-core/go/storage/mkvs/db/api"
32-
workerCommon "github.com/oasisprotocol/oasis-core/go/worker/common"
3330
"github.com/oasisprotocol/oasis-core/go/worker/common/committee"
3431
"github.com/oasisprotocol/oasis-core/go/worker/registration"
3532
"github.com/oasisprotocol/oasis-core/go/worker/storage/api"
@@ -40,8 +37,6 @@ import (
4037
)
4138

4239
var (
43-
_ committee.NodeHooks = (*Worker)(nil)
44-
4540
// ErrNonLocalBackend is the error returned when the storage backend doesn't implement the LocalBackend interface.
4641
ErrNonLocalBackend = errors.New("storage: storage backend doesn't support local storage")
4742
)
@@ -150,8 +145,6 @@ type Worker struct {
150145

151146
undefinedRound uint64
152147

153-
workerCommonCfg workerCommon.Config
154-
155148
checkpointer checkpoint.Checkpointer
156149
checkpointSyncCfg *CheckpointSyncConfig
157150
checkpointSyncForced bool
@@ -174,8 +167,8 @@ func New(
174167
commonNode *committee.Node,
175168
roleProvider registration.RoleProvider,
176169
rpcRoleProvider registration.RoleProvider,
177-
workerCommonCfg workerCommon.Config,
178170
localStorage storageApi.LocalBackend,
171+
blockCh *channels.InfiniteChannel,
179172
checkpointSyncCfg *CheckpointSyncConfig,
180173
) (*Worker, error) {
181174
initMetrics()
@@ -188,15 +181,13 @@ func New(
188181

189182
logger: logging.GetLogger("worker/storage/statesync").With("runtime_id", commonNode.Runtime.ID()),
190183

191-
workerCommonCfg: workerCommonCfg,
192-
193184
localStorage: localStorage,
194185

195186
checkpointSyncCfg: checkpointSyncCfg,
196187

197188
status: api.StatusInitializing,
198189

199-
blockCh: channels.NewInfiniteChannel(),
190+
blockCh: blockCh,
200191
diffCh: make(chan *fetchedDiff),
201192
finalizeCh: make(chan finalizeResult),
202193

@@ -327,24 +318,6 @@ func (w *Worker) GetLocalStorage() storageApi.LocalBackend {
327318
return w.localStorage
328319
}
329320

330-
// NodeHooks implementation.
331-
332-
// HandleNewBlockEarlyLocked is guarded by CrossNode.
333-
func (w *Worker) HandleNewBlockEarlyLocked(*runtime.BlockInfo) {
334-
// Nothing to do here.
335-
}
336-
337-
// HandleNewBlockLocked is guarded by CrossNode.
338-
func (w *Worker) HandleNewBlockLocked(bi *runtime.BlockInfo) {
339-
// Notify the state syncer that there is a new block.
340-
w.blockCh.In() <- bi.RuntimeBlock
341-
}
342-
343-
// HandleRuntimeHostEventLocked is guarded by CrossNode.
344-
func (w *Worker) HandleRuntimeHostEventLocked(*host.Event) {
345-
// Nothing to do here.
346-
}
347-
348321
// Watcher implementation.
349322

350323
// GetLastSynced returns the height, IORoot hash and StateRoot hash of the last block that was fully synced to.

go/worker/storage/worker.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type Worker struct {
2929
initCh chan struct{}
3030
quitCh chan struct{}
3131

32-
runtimes map[common.Namespace]*statesync.Worker
32+
runtimes map[common.Namespace]*worker
3333

3434
ctx context.Context
3535
cancel context.CancelFunc
@@ -51,7 +51,7 @@ func New(
5151
logger: logging.GetLogger("worker/storage"),
5252
initCh: make(chan struct{}),
5353
quitCh: make(chan struct{}),
54-
runtimes: make(map[common.Namespace]*statesync.Worker),
54+
runtimes: make(map[common.Namespace]*worker),
5555
ctx: ctx,
5656
cancel: cancel,
5757
}
@@ -99,11 +99,10 @@ func (w *Worker) registerRuntime(commonNode *committeeCommon.Node) error {
9999
return fmt.Errorf("can't create local storage backend: %w", err)
100100
}
101101

102-
worker, err := statesync.New(
102+
worker, err := newRuntimeWorker(
103103
commonNode,
104104
rp,
105105
rpRPC,
106-
w.commonWorker.GetConfig(),
107106
localStorage,
108107
&statesync.CheckpointSyncConfig{
109108
Disabled: config.GlobalConfig.Storage.CheckpointSyncDisabled,
@@ -191,7 +190,7 @@ func (w *Worker) serve(ctx context.Context) error {
191190
g, ctx := errgroup.WithContext(ctx)
192191
for id, r := range w.runtimes {
193192
g.Go(func() error {
194-
err := r.Serve(ctx)
193+
err := r.serve(ctx)
195194
if err != nil {
196195
return fmt.Errorf("state sync worker failed (runtimeID: %s): %w", id, err)
197196
}
@@ -222,9 +221,11 @@ func (w *Worker) Quit() <-chan struct{} {
222221
func (w *Worker) Cleanup() {
223222
}
224223

225-
// GetRuntime returns a storage committee node for the given runtime (if available).
224+
// GetRuntime returns the state sync for the given runtime (if available).
226225
//
227226
// In case the runtime with the specified id was not configured for this node it returns nil.
227+
//
228+
// Sugggestion: This is only used to get status, how about making this GetRuntimeStatus?
228229
func (w *Worker) GetRuntime(id common.Namespace) *statesync.Worker {
229-
return w.runtimes[id]
230+
return w.runtimes[id].stateSync
230231
}

0 commit comments

Comments
 (0)