Skip to content

Commit e10342d

Browse files
committed
go/consensus/cometbft/apps/keymanager: Apply policy at epoch boundary
1 parent 0ff844e commit e10342d

11 files changed

Lines changed: 379 additions & 139 deletions

File tree

.changelog/6300.breaking.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
go/consensus/cometbft/apps/keymanager: Apply policy at epoch boundary

go/consensus/cometbft/apps/keymanager/secrets/state/interop/interop.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ func InitializeTestKeyManagerSecretsState(ctx context.Context, mkvs mkvs.Tree) e
109109
Checksum: nil,
110110
Nodes: nil,
111111
Policy: nil,
112+
NextPolicy: nil,
112113
RSK: nil,
113114
},
114115
{
@@ -120,8 +121,9 @@ func InitializeTestKeyManagerSecretsState(ctx context.Context, mkvs mkvs.Tree) e
120121
signers[0].Public(),
121122
signers[1].Public(),
122123
},
123-
Policy: &sigPolicy,
124-
RSK: nil,
124+
Policy: &sigPolicy,
125+
NextPolicy: nil,
126+
RSK: nil,
125127
},
126128
} {
127129
if err = state.SetStatus(ctx, status); err != nil {

go/consensus/cometbft/apps/keymanager/secrets/status.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ func generateStatus( // nolint: gocyclo
4343
Policy: oldStatus.Policy,
4444
}
4545

46+
// Transition to the scheduled policy.
47+
if oldStatus.NextPolicy != nil {
48+
status.Policy = oldStatus.NextPolicy
49+
}
50+
4651
// Data needed to count the nodes that have replicated the proposal for the next master secret.
4752
var (
4853
nextGeneration uint64

go/consensus/cometbft/apps/keymanager/secrets/txs.go

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import (
1212
"github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/keymanager/common"
1313
secretsState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/keymanager/secrets/state"
1414
registryState "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/apps/registry/state"
15+
"github.com/oasisprotocol/oasis-core/go/consensus/cometbft/features"
1516
"github.com/oasisprotocol/oasis-core/go/keymanager/secrets"
1617
registry "github.com/oasisprotocol/oasis-core/go/registry/api"
18+
"github.com/oasisprotocol/oasis-core/go/upgrade/migrations"
1719
)
1820

1921
func (ext *secretsExt) updatePolicy(
@@ -34,20 +36,20 @@ func (ext *secretsExt) updatePolicy(
3436
}
3537

3638
// Get the existing policy document, if one exists.
37-
oldStatus, err := state.Status(ctx, kmRt.ID)
39+
status, err := state.Status(ctx, kmRt.ID)
3840
switch err {
3941
case nil:
4042
case secrets.ErrNoSuchStatus:
4143
// This must be a new key manager runtime.
42-
oldStatus = &secrets.Status{
44+
status = &secrets.Status{
4345
ID: kmRt.ID,
4446
}
4547
default:
4648
return err
4749
}
4850

4951
// Validate the tx.
50-
if err = secrets.SanityCheckSignedPolicySGX(oldStatus.Policy, sigPol); err != nil {
52+
if err = secrets.SanityCheckSignedPolicySGX(status.Policy, sigPol); err != nil {
5153
return err
5254
}
5355

@@ -70,40 +72,50 @@ func (ext *secretsExt) updatePolicy(
7072
return nil
7173
}
7274

73-
// Ok, as far as we can tell the new policy is valid, apply it.
74-
//
75-
// Note: The key manager cohort responsible for servicing this ID
76-
// will be unresponsive for a minimum of one epoch as a new cohort
77-
// will only be formed on the epoch transition. If replication
78-
// is in the picture, the replication process will take an
79-
// additional epoch.
80-
//
81-
// TODO: It would be possible to update the cohort on each
82-
// node-reregistration, but I'm not sure how often the policy
83-
// will get updated.
84-
epoch, err := ext.state.GetCurrentEpoch(ctx)
75+
// Schedule the policy to take effect in the next epoch.
76+
status.NextPolicy = sigPol
77+
78+
// Support legacy behavior where the policy was applied immediately.
79+
ok, err := features.IsFeatureVersion(ctx, migrations.Version242)
8580
if err != nil {
8681
return err
8782
}
83+
if !ok {
84+
// Ok, as far as we can tell the new policy is valid, apply it.
85+
//
86+
// Note: The key manager cohort responsible for servicing this ID
87+
// will be unresponsive for a minimum of one epoch as a new cohort
88+
// will only be formed on the epoch transition. If replication
89+
// is in the picture, the replication process will take an
90+
// additional epoch.
91+
//
92+
// TODO: It would be possible to update the cohort on each
93+
// node-reregistration, but I'm not sure how often the policy
94+
// will get updated.
95+
epoch, err := ext.state.GetCurrentEpoch(ctx)
96+
if err != nil {
97+
return err
98+
}
8899

89-
regParams, err := regState.ConsensusParameters(ctx)
90-
if err != nil {
91-
return err
100+
regParams, err := regState.ConsensusParameters(ctx)
101+
if err != nil {
102+
return err
103+
}
104+
105+
nodes, _ := regState.Nodes(ctx)
106+
registry.SortNodeList(nodes)
107+
status = generateStatus(ctx, kmRt, status, nil, nodes, regParams, epoch)
92108
}
93109

94-
nodes, _ := regState.Nodes(ctx)
95-
registry.SortNodeList(nodes)
96-
oldStatus.Policy = sigPol
97-
newStatus := generateStatus(ctx, kmRt, oldStatus, nil, nodes, regParams, epoch)
98-
if err := state.SetStatus(ctx, newStatus); err != nil {
110+
if err := state.SetStatus(ctx, status); err != nil {
99111
ctx.Logger().Error("keymanager: failed to set key manager status",
100112
"err", err,
101113
)
102114
return fmt.Errorf("keymanager: failed to set key manager status: %w", err)
103115
}
104116

105117
ctx.EmitEvent(tmapi.NewEventBuilder(ext.appName).TypedAttribute(&secrets.StatusUpdateEvent{
106-
Statuses: []*secrets.Status{newStatus},
118+
Statuses: []*secrets.Status{status},
107119
}))
108120

109121
return nil

0 commit comments

Comments
 (0)