Skip to content

Commit 41eb642

Browse files
committed
go/e2e: Add checkpoints sync interoperability test
1 parent 22497d2 commit 41eb642

File tree

6 files changed

+142
-13
lines changed

6 files changed

+142
-13
lines changed

go/oasis-test-runner/oasis/compute.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type Compute struct { // nolint: maligned
4646
storageBackend string
4747
disablePublicRPC bool
4848
checkpointSyncDisabled bool
49+
legacySyncServerDisabled bool
4950
checkpointCheckInterval time.Duration
5051
checkpointParallelChunker bool
5152
}
@@ -64,6 +65,7 @@ type ComputeCfg struct {
6465
StorageBackend string
6566
DisablePublicRPC bool
6667
CheckpointSyncDisabled bool
68+
LegacySyncServerDisabled bool
6769
CheckpointCheckInterval time.Duration
6870
CheckpointParallelChunker bool
6971
}
@@ -170,6 +172,7 @@ func (worker *Compute) ModifyConfig() error {
170172
worker.Config.Storage.Backend = worker.storageBackend
171173
worker.Config.Storage.PublicRPCEnabled = !worker.disablePublicRPC
172174
worker.Config.Storage.CheckpointSyncDisabled = worker.checkpointSyncDisabled
175+
worker.Config.Storage.LegacySyncServerDisabled = worker.legacySyncServerDisabled
173176
worker.Config.Storage.Checkpointer.Enabled = true
174177
worker.Config.Storage.Checkpointer.CheckInterval = worker.checkpointCheckInterval
175178
worker.Config.Storage.Checkpointer.ParallelChunker = worker.checkpointParallelChunker
@@ -236,6 +239,7 @@ func (net *Network) NewCompute(cfg *ComputeCfg) (*Compute, error) {
236239
sentryIndices: cfg.SentryIndices,
237240
disablePublicRPC: cfg.DisablePublicRPC,
238241
checkpointSyncDisabled: cfg.CheckpointSyncDisabled,
242+
legacySyncServerDisabled: cfg.LegacySyncServerDisabled,
239243
checkpointCheckInterval: cfg.CheckpointCheckInterval,
240244
checkpointParallelChunker: cfg.CheckpointParallelChunker,
241245
sentryPubKey: sentryPubKey,

go/oasis-test-runner/oasis/fixture.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ type ComputeWorkerFixture struct {
411411

412412
CheckpointCheckInterval time.Duration `json:"checkpoint_check_interval,omitempty"`
413413
CheckpointSyncEnabled bool `json:"checkpoint_sync_enabled,omitempty"`
414+
LegacySyncServerDisabled bool `json:"legacy_sync_server_disabled,omitempty"`
414415
CheckpointParallelChunker bool `json:"checkpoint_parallel_chunker,omitempty"`
415416

416417
// Runtimes contains the indexes of the runtimes to enable.
@@ -449,12 +450,13 @@ func (f *ComputeWorkerFixture) Create(net *Network) (*Compute, error) {
449450
CheckpointParallelChunker: f.CheckpointParallelChunker,
450451
// The checkpoint syncing flag is intentionally flipped here.
451452
// Syncing should normally be enabled, but normally disabled in tests.
452-
CheckpointSyncDisabled: !f.CheckpointSyncEnabled,
453-
DisablePublicRPC: f.DisablePublicRPC,
454-
Runtimes: f.Runtimes,
455-
RuntimeConfig: f.RuntimeConfig,
456-
RuntimeProvisioner: f.RuntimeProvisioner,
457-
RuntimeStatePaths: f.RuntimeStatePaths,
453+
CheckpointSyncDisabled: !f.CheckpointSyncEnabled,
454+
LegacySyncServerDisabled: f.LegacySyncServerDisabled,
455+
DisablePublicRPC: f.DisablePublicRPC,
456+
Runtimes: f.Runtimes,
457+
RuntimeConfig: f.RuntimeConfig,
458+
RuntimeProvisioner: f.RuntimeProvisioner,
459+
RuntimeStatePaths: f.RuntimeStatePaths,
458460
})
459461
}
460462

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package runtime
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/env"
9+
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/log"
10+
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/oasis"
11+
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/scenario"
12+
"github.com/oasisprotocol/oasis-core/go/storage/mkvs/checkpoint"
13+
)
14+
15+
// CheckpointSync tests interoperability of the new checkpoint and diff sync
16+
// p2p protocols with the legacy storage sync p2p protocol.
17+
//
18+
// The test checks that hosts that serve both protocols are compatible
19+
// with clients that fallback to both.
20+
//
21+
// To simulate legacy host comment out fallback to the new protocols
22+
// inside storage committee worker and disable registration of new checkpoint
23+
// and diff sync protocols. This is not tested automatically as it would
24+
// further polute existing code and require additional config flags.
25+
var CheckpointSync scenario.Scenario = newCheckpointSyncImpl()
26+
27+
type checkpointSync struct {
28+
Scenario
29+
}
30+
31+
func newCheckpointSyncImpl() scenario.Scenario {
32+
return &checkpointSync{
33+
Scenario: *NewScenario(
34+
"checkpoint-sync",
35+
NewTestClient().WithScenario(SimpleScenario),
36+
),
37+
}
38+
}
39+
40+
func (sc *checkpointSync) Clone() scenario.Scenario {
41+
return &checkpointSync{
42+
Scenario: *sc.Scenario.Clone().(*Scenario),
43+
}
44+
}
45+
46+
func (sc *checkpointSync) Fixture() (*oasis.NetworkFixture, error) {
47+
f, err := sc.Scenario.Fixture()
48+
if err != nil {
49+
return nil, err
50+
}
51+
52+
// Make the first compute worker check for checkpoints more often.
53+
f.ComputeWorkers[0].CheckpointCheckInterval = 1 * time.Second
54+
// Configure runtime for storage checkpointing.
55+
f.Runtimes[1].Storage.CheckpointInterval = 10
56+
f.Runtimes[1].Storage.CheckpointNumKept = 10
57+
f.Runtimes[1].Storage.CheckpointChunkSize = 1 * 1024
58+
// Serve both legacy and new protocols.
59+
for i := range f.ComputeWorkers {
60+
f.ComputeWorkers[i].LegacySyncServerDisabled = false
61+
}
62+
f.ComputeWorkers = append(f.ComputeWorkers, oasis.ComputeWorkerFixture{
63+
NodeFixture: oasis.NodeFixture{
64+
NoAutoStart: true,
65+
},
66+
Entity: 1,
67+
Runtimes: []int{1},
68+
CheckpointSyncEnabled: true,
69+
LogWatcherHandlerFactories: []log.WatcherHandlerFactory{
70+
oasis.LogAssertCheckpointSync(),
71+
},
72+
})
73+
74+
return f, nil
75+
}
76+
77+
func (sc *checkpointSync) Run(ctx context.Context, childEnv *env.Env) error {
78+
if err := sc.Net.Start(); err != nil {
79+
return err
80+
}
81+
82+
if err := sc.WaitForClientSync(ctx); err != nil {
83+
return fmt.Errorf("failed to wait for client sync: %w", err)
84+
}
85+
86+
// Generate some more rounds to trigger checkpointing.
87+
for i := 0; i < 15; i++ {
88+
sc.Logger.Info("submitting transaction to runtime", "seq", i)
89+
if _, err := sc.submitKeyValueRuntimeInsertTx(ctx, KeyValueRuntimeID, uint64(i), "checkpoint", string(i), 0, 0, plaintextTxKind); err != nil {
90+
return err
91+
}
92+
}
93+
94+
// Make sure that the first compute node created checkpoints.
95+
ctrl, err := oasis.NewController(sc.Net.ComputeWorkers()[0].SocketPath())
96+
if err != nil {
97+
return fmt.Errorf("failed to connect with the first compute node: %w", err)
98+
}
99+
if _, err = ctrl.Storage.GetCheckpoints(ctx, &checkpoint.GetCheckpointsRequest{Version: 1, Namespace: KeyValueRuntimeID}); err != nil {
100+
return fmt.Errorf("failed to get checkpoints: %w", err)
101+
}
102+
103+
// Start late compute worker and check if it syncs with a checkpoint.
104+
sc.Logger.Info("running late compute worker")
105+
lateWorker := sc.Net.ComputeWorkers()[len(sc.Net.ComputeWorkers())-1]
106+
if err = lateWorker.Start(); err != nil {
107+
return fmt.Errorf("failed to start late compute worker: %w", err)
108+
}
109+
if err = lateWorker.WaitReady(ctx); err != nil {
110+
return fmt.Errorf("failed to wait for late compute worker to become ready: %w", err)
111+
}
112+
113+
// Wait a bit to give the logger in the node time to sync to disk.
114+
<-time.After(1 * time.Second)
115+
116+
return sc.Net.CheckLogWatchers()
117+
}

go/oasis-test-runner/scenario/e2e/runtime/scenario.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ func RegisterScenarios() error {
342342
StorageSyncFromRegistered,
343343
StorageSyncInconsistent,
344344
StorageEarlyStateSync,
345+
CheckpointSync,
345346
// Sentry test.
346347
Sentry,
347348
// Keymanager tests.

go/worker/storage/committee/node.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,10 @@ func NewNode(
276276
node: n,
277277
})
278278

279-
// Advertise and serve legacy storage sync protocol.
280-
commonNode.P2P.RegisterProtocolServer(synclegacy.NewServer(commonNode.ChainContext, commonNode.Runtime.ID(), localStorage))
279+
if !config.GlobalConfig.Storage.LegacySyncServerDisabled {
280+
// Advertise and serve legacy storage sync protocol.
281+
commonNode.P2P.RegisterProtocolServer(synclegacy.NewServer(commonNode.ChainContext, commonNode.Runtime.ID(), localStorage))
282+
}
281283
// Advertise and serve diff sync protocol server.
282284
commonNode.P2P.RegisterProtocolServer(diffsync.NewServer(commonNode.ChainContext, commonNode.Runtime.ID(), localStorage))
283285
// Advertise and serve checkpoint sync protocol server if checkpoints are enabled.

go/worker/storage/config/config.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ type Config struct {
2020
PublicRPCEnabled bool `yaml:"public_rpc_enabled,omitempty"`
2121
// Disable initial storage sync from checkpoints.
2222
CheckpointSyncDisabled bool `yaml:"checkpoint_sync_disabled,omitempty"`
23+
// Disable serving legacy storage sync p2p protocol.
24+
LegacySyncServerDisabled bool `yaml:"legacy_sync_server_disabled,omitempty"`
2325

2426
// Storage checkpointer configuration.
2527
Checkpointer CheckpointerConfig `yaml:"checkpointer,omitempty"`
@@ -47,11 +49,12 @@ func (c *Config) Validate() error {
4749
// DefaultConfig returns the default configuration settings.
4850
func DefaultConfig() Config {
4951
return Config{
50-
Backend: "auto",
51-
MaxCacheSize: "64mb",
52-
FetcherCount: 4,
53-
PublicRPCEnabled: false,
54-
CheckpointSyncDisabled: false,
52+
Backend: "auto",
53+
MaxCacheSize: "64mb",
54+
FetcherCount: 4,
55+
PublicRPCEnabled: false,
56+
CheckpointSyncDisabled: false,
57+
LegacySyncServerDisabled: false,
5558
Checkpointer: CheckpointerConfig{
5659
Enabled: false,
5760
CheckInterval: 1 * time.Minute,

0 commit comments

Comments
 (0)