Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Move node key to config directory and enable loading of multiple identities #5592

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d426681
Restructure PostSupervisor to require NodeID on StartSession and Prep…
fasmat Feb 21, 2024
b283295
Load multiple identities during startup
fasmat Feb 21, 2024
6217b6a
Update Recovery for multi-smesher
fasmat Feb 22, 2024
4ffc167
Fix recovery for multi-smeshing
fasmat Feb 22, 2024
1987a82
Add tests
fasmat Feb 22, 2024
900d1d6
Extend checkpoint tests with multi-smeshing setups
fasmat Feb 23, 2024
b1df1b7
Update Node tests
fasmat Feb 24, 2024
7af1f17
Fix node tests
fasmat Feb 24, 2024
30b2db0
Fix failing tests
fasmat Feb 24, 2024
49b26cd
Update CHANGELOG
fasmat Feb 26, 2024
a814bc8
Make sure duplicate keys are detected
fasmat Feb 26, 2024
dae6819
Update post
fasmat Feb 27, 2024
ec8c89b
Review feedback
fasmat Feb 27, 2024
0d92a9a
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Feb 27, 2024
39607a8
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Feb 28, 2024
3047f22
Review feedback
fasmat Feb 28, 2024
23366a6
Use maps instead of slices for deduplication
fasmat Feb 28, 2024
f1ce011
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Feb 28, 2024
801e7b1
Fix failing tests
fasmat Feb 28, 2024
4db9f0e
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Feb 29, 2024
7d26955
Fix failing tests
fasmat Feb 29, 2024
ecaca50
Fix flaky test
fasmat Feb 29, 2024
246599b
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Feb 29, 2024
94d7a12
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Feb 29, 2024
f89edef
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Feb 29, 2024
dfed9a2
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Mar 1, 2024
d775a9c
Fix logging
fasmat Mar 1, 2024
9fdf414
Run test e2e test with random post size
fasmat Mar 1, 2024
cf73444
Update post dependency
fasmat Mar 1, 2024
fe73b3f
Add initial post verification to builder
fasmat Mar 1, 2024
949095c
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Mar 1, 2024
43eff2a
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Mar 1, 2024
62528e5
Fix failing tests
fasmat Mar 1, 2024
ee3cc19
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Mar 1, 2024
b802f65
Update systest makefile
fasmat Mar 1, 2024
e395c8f
Downgrade post-rs
fasmat Mar 1, 2024
c2f9543
Downgrade post
fasmat Mar 1, 2024
d265586
Update CHANGELOG.md
fasmat Mar 4, 2024
310f272
Update CHANGELOG with info that multi-smeshing is still in testing
fasmat Mar 4, 2024
aaf6d26
Merge remote-tracking branch 'origin/develop' into 5089-move-key-to-c…
fasmat Mar 4, 2024
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
58 changes: 58 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,57 @@ configuration is as follows:
}
```

#### Extend go-spacemesh with option to manage multiple identities/PoST services

A node can now manage multiple identities and will manage the lifecycle for those identities. This reduces the amount of
data that is needed to be broadcasted / fetched from the network and reduces the amount of data that needs to be stored
locally, because only one database is needed for all identities instead of one for each identity.

To ensure you are eligible for rewards of any given identity, the associated PoST service must be running and connected
to the node during the cyclegap set in the node's configuration. After successfully broadcasting the ATX and registering
at a PoET server the PoST services can be stopped with only the node having to be online.

This change moves the private keys associated for an identity from the PoST data directory to the node's data directory
and into the folder `identities` (i.e. if `state.sql` is in folder `data` the keys will now be stored in `data/identities`).
The node will automatically migrate the `key.bin` file from the PoST data directory during the first startup and copy
it to the new location as `identity.key`. The content of the file stays unchanged (= the private key of the identity hex-encoded).

##### Adding new identities/PoST services to a node

To add a new identity to a node, initialize PoST data with `postcli` and let it generate a new private key for you:

```shell
./postcli -provider=2 -numUnits=4 -datadir=/path/to/data \
-commitmentAtxId=c230c51669d1fcd35860131e438e234726b2bd5f9adbbd91bd88a718e7e98ecb
```

Make sure to replace `provider` with your provider of choice and `numUnits` with the number of PoST units you want to
initialize. The `commitmentAtxId` is the commitment ATX ID for the identity you want to initialize. For details on the
usage of `postcli` please refer to [postcli README](https://github.com/spacemeshos/post/cmd/postcli/README.md).

During initialization `postcli` will generate a new private key and store it in the PoST data directory as `key.bin`.
Copy this file to your `data/identities` directory and rename it to `xxx.key` where `xxx` is a unique identifier for
the identity. The node will automatically pick up the new identity and manage its lifecycle after a restart.

Setup the `post-service` [binary](https://github.com/spacemeshos/post-rs/releases) or
[docker image](https://hub.docker.com/r/spacemeshos/post-service/tags) with the data and configure it to connect to your
node. For details refer to the [post-service README](https://github.com/spacemeshos/post-rs/blob/main/service/README.md).

##### Migrating existing identities/PoST services to a node
fasmat marked this conversation as resolved.
Show resolved Hide resolved

If you have multiple nodes running and want to migrate to use only one node for all identities:

1. Stop all nodes.
2. Copy the `key.bin` files from the PoST data directories of all nodes to the data directory of the node you want to
use for both identities and into the folder `data/identities`. Rename the files to `xxx.key` where `xxx` is a unique
identifier for each identity.
3. Start the node managing the identities.
4. For every identity setup a post service to use the existing PoST data for that identity and connect to the node.
For details refer to the [post-service README](https://github.com/spacemeshos/post-rs/blob/main/service/README.md).

**WARNING:** DO NOT run multiple nodes with the same identity at the same time. This will result in an equivocation
and permanent ineligibility for rewards.

### Highlights

* [#5293](https://github.com/spacemeshos/go-spacemesh/pull/5293) change poet servers configuration
Expand All @@ -100,6 +151,13 @@ configuration is as follows:
Publishing is blocked during sync because `Syncer::ListenToATXGossip()` returns false, and thus every malicious ATX being
synced was causing an error resulting in an interruption of sync.

* [#5592](https://gihtub.com/spacemeshos/go-spacemesh/pull/5592)
Extend node with option to have multiple PoST services connect. This allows users to run multiple PoST services,
without the need to run multiple nodes. A node can now manage multiple identities and will manage the lifecycle of
those identities.
To collect rewards for every identity, the associated PoST service must be running and connected to the node during
the cyclegap set in the node's configuration.

### Features

### Improvements
Expand Down
6 changes: 3 additions & 3 deletions activation/e2e/activation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ func Test_BuilderWithMultipleClients(t *testing.T) {
opts := opts
eg.Go(func() error {
validator := activation.NewMocknipostValidator(ctrl)
mgr, err := activation.NewPostSetupManager(sig.NodeID(), cfg, logger, cdb, goldenATX, syncer, validator)
mgr, err := activation.NewPostSetupManager(cfg, logger, cdb, goldenATX, syncer, validator)
require.NoError(t, err)

opts.DataDir = t.TempDir()
initPost(t, mgr, opts)
t.Cleanup(launchPostSupervisor(t, logger, mgr, grpcCfg, opts))
initPost(t, mgr, opts, sig.NodeID())
t.Cleanup(launchPostSupervisor(t, logger, mgr, sig.NodeID(), grpcCfg, opts))

require.Eventually(t, func() bool {
_, err := svc.Client(sig.NodeID())
Expand Down
25 changes: 13 additions & 12 deletions activation/e2e/nipost_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func launchPostSupervisor(
tb testing.TB,
log *zap.Logger,
mgr *activation.PostSetupManager,
id types.NodeID,
cfg grpcserver.Config,
postOpts activation.PostSetupOpts,
) func() {
Expand All @@ -76,7 +77,7 @@ func launchPostSupervisor(
ps, err := activation.NewPostSupervisor(log, cmdCfg, postCfg, provingOpts, mgr)
require.NoError(tb, err)
require.NotNil(tb, ps)
require.NoError(tb, ps.Start(postOpts))
require.NoError(tb, ps.Start(postOpts, id))
return func() { assert.NoError(tb, ps.Stop(false)) }
}

Expand All @@ -99,12 +100,12 @@ func launchServer(tb testing.TB, services ...grpcserver.ServiceAPI) (grpcserver.
return cfg, func() { assert.NoError(tb, server.Close()) }
}

func initPost(tb testing.TB, mgr *activation.PostSetupManager, opts activation.PostSetupOpts) {
func initPost(tb testing.TB, mgr *activation.PostSetupManager, opts activation.PostSetupOpts, id types.NodeID) {
tb.Helper()

// Create data.
require.NoError(tb, mgr.PrepareInitializer(context.Background(), opts))
require.NoError(tb, mgr.StartSession(context.Background()))
require.NoError(tb, mgr.PrepareInitializer(context.Background(), opts, id))
require.NoError(tb, mgr.StartSession(context.Background(), id))
require.Equal(tb, activation.PostSetupStateComplete, mgr.Status().State)
}

Expand All @@ -128,14 +129,14 @@ func TestNIPostBuilderWithClients(t *testing.T) {
})

validator := activation.NewMocknipostValidator(ctrl)
mgr, err := activation.NewPostSetupManager(sig.NodeID(), cfg, logger, cdb, goldenATX, syncer, validator)
mgr, err := activation.NewPostSetupManager(cfg, logger, cdb, goldenATX, syncer, validator)
require.NoError(t, err)

opts := activation.DefaultPostSetupOpts()
opts.DataDir = t.TempDir()
opts.ProviderID.SetUint32(initialization.CPUProviderID())
opts.Scrypt.N = 2 // Speedup initialization in tests.
initPost(t, mgr, opts)
initPost(t, mgr, opts, sig.NodeID())

// ensure that genesis aligns with layer timings
genesis := time.Now().Add(layerDuration).Round(layerDuration)
Expand Down Expand Up @@ -173,7 +174,7 @@ func TestNIPostBuilderWithClients(t *testing.T) {
grpcCfg, cleanup := launchServer(t, svc)
t.Cleanup(cleanup)

t.Cleanup(launchPostSupervisor(t, logger, mgr, grpcCfg, opts))
t.Cleanup(launchPostSupervisor(t, logger, mgr, sig.NodeID(), grpcCfg, opts))

require.Eventually(t, func() bool {
_, err := svc.Client(sig.NodeID())
Expand Down Expand Up @@ -274,7 +275,7 @@ func TestNewNIPostBuilderNotInitialized(t *testing.T) {
})

validator := activation.NewMocknipostValidator(ctrl)
mgr, err := activation.NewPostSetupManager(sig.NodeID(), cfg, logger, cdb, goldenATX, syncer, validator)
mgr, err := activation.NewPostSetupManager(cfg, logger, cdb, goldenATX, syncer, validator)
require.NoError(t, err)

// ensure that genesis aligns with layer timings
Expand Down Expand Up @@ -325,7 +326,7 @@ func TestNewNIPostBuilderNotInitialized(t *testing.T) {
opts.DataDir = t.TempDir()
opts.ProviderID.SetUint32(initialization.CPUProviderID())
opts.Scrypt.N = 2 // Speedup initialization in tests.
t.Cleanup(launchPostSupervisor(t, logger, mgr, grpcCfg, opts))
t.Cleanup(launchPostSupervisor(t, logger, mgr, sig.NodeID(), grpcCfg, opts))

require.Eventually(t, func() bool {
_, err := svc.Client(sig.NodeID())
Expand Down Expand Up @@ -393,12 +394,12 @@ func Test_NIPostBuilderWithMultipleClients(t *testing.T) {
sig := sig
opts := opts
eg.Go(func() error {
mgr, err := activation.NewPostSetupManager(sig.NodeID(), cfg, logger, cdb, goldenATX, syncer, validator)
mgr, err := activation.NewPostSetupManager(cfg, logger, cdb, goldenATX, syncer, validator)
require.NoError(t, err)

opts.DataDir = t.TempDir()
initPost(t, mgr, opts)
t.Cleanup(launchPostSupervisor(t, logger, mgr, grpcCfg, opts))
initPost(t, mgr, opts, sig.NodeID())
t.Cleanup(launchPostSupervisor(t, logger, mgr, sig.NodeID(), grpcCfg, opts))

require.Eventually(t, func() bool {
_, err := svc.Client(sig.NodeID())
Expand Down
6 changes: 3 additions & 3 deletions activation/e2e/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ func TestValidator_Validate(t *testing.T) {
return synced
})

mgr, err := activation.NewPostSetupManager(sig.NodeID(), cfg, logger, cdb, goldenATX, syncer, validator)
mgr, err := activation.NewPostSetupManager(cfg, logger, cdb, goldenATX, syncer, validator)
require.NoError(t, err)

opts := activation.DefaultPostSetupOpts()
opts.DataDir = t.TempDir()
opts.ProviderID.SetUint32(initialization.CPUProviderID())
opts.Scrypt.N = 2 // Speedup initialization in tests.
initPost(t, mgr, opts)
initPost(t, mgr, opts, sig.NodeID())

// ensure that genesis aligns with layer timings
genesis := time.Now().Add(layerDuration).Round(layerDuration)
Expand Down Expand Up @@ -87,7 +87,7 @@ func TestValidator_Validate(t *testing.T) {
grpcCfg, cleanup := launchServer(t, svc)
t.Cleanup(cleanup)

t.Cleanup(launchPostSupervisor(t, logger, mgr, grpcCfg, opts))
t.Cleanup(launchPostSupervisor(t, logger, mgr, sig.NodeID(), grpcCfg, opts))

require.Eventually(t, func() bool {
_, err := svc.Client(sig.NodeID())
Expand Down
4 changes: 2 additions & 2 deletions activation/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ type atxProvider interface {
// This interface is used by the atx builder and currently implemented by the PostSetupManager.
// Eventually most of the functionality will be moved to the PoSTClient.
type postSetupProvider interface {
PrepareInitializer(ctx context.Context, opts PostSetupOpts) error
StartSession(context context.Context) error
PrepareInitializer(ctx context.Context, opts PostSetupOpts, id types.NodeID) error
StartSession(context context.Context, id types.NodeID) error
Status() *PostSetupStatus
Reset() error
}
Expand Down
24 changes: 12 additions & 12 deletions activation/mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading