Skip to content

Commit

Permalink
Move halt epoch from genesis to node-local configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
kostko committed Feb 24, 2023
1 parent 387ab1c commit a874809
Show file tree
Hide file tree
Showing 16 changed files with 36 additions and 57 deletions.
1 change: 1 addition & 0 deletions .changelog/5200.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Move halt epoch from genesis to node-local configuration
4 changes: 2 additions & 2 deletions go/consensus/tendermint/abci/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type ApplicationConfig struct { // nolint: maligned
DataDir string
StorageBackend string
Pruning PruneConfig
HaltEpochHeight beacon.EpochTime
HaltEpoch beacon.EpochTime
HaltBlockHeight uint64
MinGasPrice uint64

Expand Down Expand Up @@ -443,7 +443,7 @@ func (mux *abciMux) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginB
// On transition, trigger halt hooks.
mux.logger.Info("BeginBlock: halt mode transition, emitting empty block",
"block_height", blockHeight,
"epoch", mux.state.haltEpochHeight,
"epoch", currentEpoch,
)
mux.logger.Debug("dispatching halt hooks before halt point")
mux.dispatchHaltHooks(blockHeight, currentEpoch, nil)
Expand Down
8 changes: 4 additions & 4 deletions go/consensus/tendermint/abci/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type applicationState struct { // nolint: maligned
timeSource beacon.Backend

haltMode bool
haltEpochHeight beacon.EpochTime
haltEpoch beacon.EpochTime
haltBlockHeight uint64

minGasPrice quantity.Quantity
Expand Down Expand Up @@ -265,7 +265,7 @@ func (s *applicationState) shouldHalt(ctx *api.Context) bool {
"halt_block_height", s.haltBlockHeight,
)
s.haltMode = true
} else {
} else if s.haltEpoch > 0 {
// Otherwise, check to see if the epoch will be equal to
// the halt epoch (if any).
currentEpoch, err := s.GetEpoch(ctx, h)
Expand All @@ -276,7 +276,7 @@ func (s *applicationState) shouldHalt(ctx *api.Context) bool {
)
return false
}
s.haltMode = currentEpoch == s.haltEpochHeight
s.haltMode = currentEpoch == s.haltEpoch
}

return s.haltMode
Expand Down Expand Up @@ -589,7 +589,7 @@ func newApplicationState(ctx context.Context, upgrader upgrade.Backend, cfg *App
prunerNotifyCh: channels.NewRingChannel(1),
pruneInterval: cfg.Pruning.PruneInterval,
upgrader: upgrader,
haltEpochHeight: cfg.HaltEpochHeight,
haltEpoch: cfg.HaltEpoch,
haltBlockHeight: cfg.HaltBlockHeight,
minGasPrice: minGasPrice,
ownTxSigner: cfg.OwnTxSigner,
Expand Down
8 changes: 8 additions & 0 deletions go/consensus/tendermint/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ type Config struct {
// Transaction submission configuration.
Submission SubmissionConfig `yaml:"submission,omitempty"`

// Epoch at which to force-shutdown the node (in epochs).
HaltEpoch uint64 `yaml:"halt_epoch,omitempty"`

// Height at which to force-shutdown the node (in blocks).
HaltHeight uint64 `yaml:"halt_height,omitempty"`

Expand Down Expand Up @@ -152,6 +155,10 @@ func (c *Config) Validate() error {
return fmt.Errorf("p2p.recv_rate must be >= 0")
}

if c.HaltHeight > 0 && c.HaltEpoch > 0 {
return fmt.Errorf("only one of {halt_epoch, halt_height} can be set")
}

if c.StateSync.Enabled {
if c.StateSync.TrustPeriod < 1*time.Second {
return fmt.Errorf("state sync enabled, but state_sync.trust_period is zero")
Expand Down Expand Up @@ -189,6 +196,7 @@ func DefaultConfig() Config {
GasPrice: 0,
MaxFee: 0,
},
HaltEpoch: 0,
HaltHeight: 0,
UpgradeStopDelay: 60 * time.Second,
Prune: PruneConfig{
Expand Down
1 change: 0 additions & 1 deletion go/consensus/tendermint/full/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ func NewArchive(
Strategy: abci.PruneNone,
PruneInterval: time.Hour * 100, // Irrelevant as pruning is disabled.
},
HaltEpochHeight: srv.genesis.HaltEpoch,
OwnTxSigner: srv.identity.NodeSigner.Public(),
DisableCheckpointer: true,
InitialHeight: uint64(srv.genesis.Height),
Expand Down
1 change: 0 additions & 1 deletion go/consensus/tendermint/full/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,6 @@ func (n *commonNode) StateToGenesis(ctx context.Context, blockHeight int64) (*ge
return &genesisAPI.Document{
Height: blockHeight,
ChainID: genesisDoc.ChainID,
HaltEpoch: genesisDoc.HaltEpoch,
Time: blk.Header.Time,
Beacon: *beaconGenesis,
Registry: *registryGenesis,
Expand Down
2 changes: 1 addition & 1 deletion go/consensus/tendermint/full/full.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ func (t *fullService) lazyInit() error { // nolint: gocyclo
DataDir: filepath.Join(t.dataDir, tmcommon.StateDir),
StorageBackend: db.GetBackendName(),
Pruning: pruneCfg,
HaltEpochHeight: t.genesis.HaltEpoch,
HaltEpoch: beaconAPI.EpochTime(config.GlobalConfig.Consensus.HaltEpoch),
HaltBlockHeight: config.GlobalConfig.Consensus.HaltHeight,
MinGasPrice: config.GlobalConfig.Consensus.MinGasPrice,
OwnTxSigner: t.identity.NodeSigner.Public(),
Expand Down
3 changes: 0 additions & 3 deletions go/genesis/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ type Document struct {
Governance governance.Genesis `json:"governance"`
// Consensus is the consensus genesis state.
Consensus consensus.Genesis `json:"consensus"`
// HaltEpoch is the epoch height at which the network will stop processing
// any transactions and will halt.
HaltEpoch beacon.EpochTime `json:"halt_epoch"`
// Extra data is arbitrary extra data that is part of the
// genesis block but is otherwise ignored by the protocol.
ExtraData map[string][]byte `json:"extra_data"`
Expand Down
4 changes: 0 additions & 4 deletions go/genesis/api/sanity_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,5 @@ func (d *Document) SanityCheck() error {
return err
}

if d.HaltEpoch < epoch {
return fmt.Errorf("genesis: sanity check failed: halt epoch is in the past")
}

return nil
}
1 change: 0 additions & 1 deletion go/oasis-node/cmd/debug/dumpdb/dumpdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ func doDumpDB(cmd *cobra.Command, args []string) {
Height: qs.BlockHeight(),
Time: time.Now(), // XXX: Make this deterministic?
ChainID: oldDoc.ChainID,
HaltEpoch: oldDoc.HaltEpoch,
ExtraData: oldDoc.ExtraData,
}

Expand Down
10 changes: 3 additions & 7 deletions go/oasis-node/cmd/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"encoding/json"
"errors"
"fmt"
"math"
"os"
"strconv"
"strings"
Expand Down Expand Up @@ -53,7 +52,6 @@ const (
cfgStaking = "staking"
cfgBlockHeight = "height"
cfgChainID = "chain.id"
cfgHaltEpoch = "halt.epoch"
cfgInitialHeight = "initial_height"

// Registry config flags.
Expand Down Expand Up @@ -180,10 +178,9 @@ func doInitGenesis(cmd *cobra.Command, args []string) {

// Build the genesis state, if any.
doc := &genesis.Document{
Height: viper.GetInt64(cfgInitialHeight),
ChainID: chainID,
Time: time.Now(),
HaltEpoch: beacon.EpochTime(viper.GetUint64(cfgHaltEpoch)),
Height: viper.GetInt64(cfgInitialHeight),
ChainID: chainID,
Time: time.Now(),
}
entities := viper.GetStringSlice(viperEntity)
runtimes := viper.GetStringSlice(cfgRuntime)
Expand Down Expand Up @@ -785,7 +782,6 @@ func init() {
initGenesisFlags.String(cfgStaking, "", "path to staking genesis file")
initGenesisFlags.StringSlice(cfgKeyManager, nil, "path to key manager genesis status file")
initGenesisFlags.String(cfgChainID, "", "genesis chain id")
initGenesisFlags.Uint64(cfgHaltEpoch, math.MaxUint64, "genesis halt epoch height")
initGenesisFlags.Int64(cfgInitialHeight, 1, "initial block height")

// Registry config flags.
Expand Down
4 changes: 0 additions & 4 deletions go/oasis-test-runner/oasis/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,6 @@ func (net *Network) MakeGenesis() error {
"--genesis.file", net.GenesisPath(),
"--chain.id", genesisTestHelpers.TestChainID,
"--initial_height", strconv.FormatInt(net.cfg.InitialHeight, 10),
"--halt.epoch", strconv.FormatUint(net.cfg.HaltEpoch, 10),
"--consensus.backend", net.cfg.Consensus.Backend,
"--consensus.tendermint.timeout_commit", net.cfg.Consensus.Parameters.TimeoutCommit.String(),
"--registry.enable_runtime_governance_models", "entity,runtime",
Expand Down Expand Up @@ -980,9 +979,6 @@ func New(env *env.Env, cfg *NetworkCfg) (*Network, error) {
if cfgCopy.InitialHeight == 0 {
cfgCopy.InitialHeight = defaultInitialHeight
}
if cfgCopy.HaltEpoch == 0 {
cfgCopy.HaltEpoch = defaultHaltEpoch
}

net := &Network{
logger: logging.GetLogger("oasis/" + env.Name()),
Expand Down
3 changes: 1 addition & 2 deletions go/oasis-test-runner/oasis/oasis.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"crypto/x509"
"fmt"
"math"
"net"
"os"
"os/exec"
Expand Down Expand Up @@ -35,7 +34,6 @@ const (
defaultConsensusBackend = "tendermint"
defaultEpochtimeTendermintInterval = 30
defaultInitialHeight = 1
defaultHaltEpoch = math.MaxUint64

defaultConsensusTimeoutCommit = 1 * time.Second

Expand Down Expand Up @@ -256,6 +254,7 @@ func (n *Node) Start() error {

n.Config.Consensus.Submission.GasPrice = n.consensus.SubmissionGasPrice
n.Config.Consensus.MinGasPrice = n.consensus.MinGasPrice
n.Config.Consensus.HaltEpoch = n.net.cfg.HaltEpoch

// Initialize node command-line arguments.
args := newArgBuilder().debugDontBlameOasis().debugAllowTestKeys()
Expand Down
8 changes: 4 additions & 4 deletions go/oasis-test-runner/scenario/e2e/e2e.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,15 +365,15 @@ func (sc *E2E) DumpRestoreNetwork(
}
}

// If network is used, enable shorter per-node socket paths, because some e2e test datadir
// exceed maximum unix socket path length.
fixture.Network.UseShortGrpcSocketPaths = true

var err error
if sc.Net, err = fixture.Create(childEnv); err != nil {
return err
}

// If network is used, enable shorter per-node socket paths, because some e2e test datadir
// exceed maximum unix socket path length.
sc.Net.Config().UseShortGrpcSocketPaths = true

return nil
}

Expand Down
21 changes: 6 additions & 15 deletions go/oasis-test-runner/scenario/e2e/runtime/halt_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package runtime
import (
"context"
"fmt"
"math"
"reflect"

beacon "github.com/oasisprotocol/oasis-core/go/beacon/api"
Expand Down Expand Up @@ -168,8 +167,7 @@ func (sc *haltRestoreImpl) Run(childEnv *env.Env) error { // nolint: gocyclo
// works with restored state.
sc.Logger.Info("starting the network again")

// Update halt epoch in the exported genesis so the network doesn't
// instantly halt.
// Ensure compute runtime in genesis is in expected state.
genesisFileProvider, err := genesis.NewFileProvider(files[0])
if err != nil {
sc.Logger.Error("failed getting genesis file provider",
Expand All @@ -185,15 +183,7 @@ func (sc *haltRestoreImpl) Run(childEnv *env.Env) error { // nolint: gocyclo
)
return err
}
genesisDoc.HaltEpoch = math.MaxUint64
if err = genesisDoc.WriteFileJSON(files[0]); err != nil {
sc.Logger.Error("failed to update genesis",
"err", err,
)
return err
}

// Ensure compute runtime in genesis is in expected state.
var rtList []*registry.Runtime
switch sc.suspendRuntime {
case true:
Expand All @@ -217,19 +207,20 @@ func (sc *haltRestoreImpl) Run(childEnv *env.Env) error { // nolint: gocyclo
return fmt.Errorf("runtime not in expected state")
}

// Disable halt epoch so the network doesn't instantly halt.
fixture.Network.HaltEpoch = 0
// Use the updated genesis file.
fixture.Network.GenesisFile = files[0]
// Make sure to not overwrite the entity.
fixture.Entities[1].Restore = true
// If network is used, enable shorter per-node socket paths, because some e2e test datadir
// exceed maximum unix socket path length.
fixture.Network.UseShortGrpcSocketPaths = true

if sc.Net, err = fixture.Create(childEnv); err != nil {
return err
}

// If network is used, enable shorter per-node socket paths, because some e2e test datadir exceed maximum unix
// socket path length.
sc.Net.Config().UseShortGrpcSocketPaths = true

newTestClient := sc.testClient.Clone().(*LongTermTestClient)
sc.runtimeImpl.testClient = newTestClient.WithMode(ModePart2).WithSeed("second_seed")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package runtime
import (
"context"
"fmt"
"math"
"reflect"

genesis "github.com/oasisprotocol/oasis-core/go/genesis/file"
Expand Down Expand Up @@ -97,8 +96,7 @@ func (sc *haltRestoreNonMockImpl) Run(childEnv *env.Env) error { // nolint: gocy
// works with restored state.
sc.Logger.Info("starting the network again")

// Update halt epoch in the exported genesis so the network doesn't
// instantly halt.
// Update genesis file.
genesisFileProvider, err := genesis.NewFileProvider(files[0])
if err != nil {
sc.Logger.Error("failed getting genesis file provider",
Expand All @@ -114,7 +112,6 @@ func (sc *haltRestoreNonMockImpl) Run(childEnv *env.Env) error { // nolint: gocy
)
return err
}
genesisDoc.HaltEpoch = math.MaxUint64
genesisDoc.Beacon.Parameters.VRFParameters.Interval -= 5 // Reduce interval.
if err = genesisDoc.WriteFileJSON(files[0]); err != nil {
sc.Logger.Error("failed to update genesis",
Expand All @@ -123,19 +120,20 @@ func (sc *haltRestoreNonMockImpl) Run(childEnv *env.Env) error { // nolint: gocy
return err
}

// Disable halt epoch so the network doesn't instantly halt.
fixture.Network.HaltEpoch = 0
// Use the updated genesis file.
fixture.Network.GenesisFile = files[0]
// Make sure to not overwrite the entity.
fixture.Entities[1].Restore = true
// If network is used, enable shorter per-node socket paths, because some e2e test datadir
// exceed maximum unix socket path length.
fixture.Network.UseShortGrpcSocketPaths = true

if sc.Net, err = fixture.Create(childEnv); err != nil {
return err
}

// If network is used, enable shorter per-node socket paths, because some e2e test datadir
// exceed maximum unix socket path length.
sc.Net.Config().UseShortGrpcSocketPaths = true

newTestClient := sc.testClient.Clone().(*LongTermTestClient)
sc.runtimeImpl.testClient = newTestClient.WithMode(ModePart2).WithSeed("second_seed")

Expand Down

0 comments on commit a874809

Please sign in to comment.