Merge PR #5005: Add support for halt-time
This commit is contained in:
+41
-7
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
@@ -214,6 +215,24 @@ func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) (res abci.ResponseDeliv
|
||||
func (app *BaseApp) Commit() (res abci.ResponseCommit) {
|
||||
header := app.deliverState.ctx.BlockHeader()
|
||||
|
||||
var halt bool
|
||||
|
||||
switch {
|
||||
case app.haltHeight > 0 && uint64(header.Height) >= app.haltHeight:
|
||||
halt = true
|
||||
|
||||
case app.haltTime > 0 && header.Time.Unix() >= int64(app.haltTime):
|
||||
halt = true
|
||||
}
|
||||
|
||||
if halt {
|
||||
app.halt()
|
||||
|
||||
// Note: State is not actually committed when halted. Logs from Tendermint
|
||||
// can be ignored.
|
||||
return abci.ResponseCommit{}
|
||||
}
|
||||
|
||||
// Write the DeliverTx state which is cache-wrapped and commit the MultiStore.
|
||||
// The write to the DeliverTx state writes all state transitions to the root
|
||||
// MultiStore (app.cms) so when Commit() is called is persists those values.
|
||||
@@ -230,18 +249,33 @@ func (app *BaseApp) Commit() (res abci.ResponseCommit) {
|
||||
// empty/reset the deliver state
|
||||
app.deliverState = nil
|
||||
|
||||
defer func() {
|
||||
if app.haltHeight > 0 && uint64(header.Height) == app.haltHeight {
|
||||
app.logger.Info("halting node per configuration", "height", app.haltHeight)
|
||||
os.Exit(0)
|
||||
}
|
||||
}()
|
||||
|
||||
return abci.ResponseCommit{
|
||||
Data: commitID.Hash,
|
||||
}
|
||||
}
|
||||
|
||||
// halt attempts to gracefully shutdown the node via SIGINT and SIGTERM falling
|
||||
// back on os.Exit if both fail.
|
||||
func (app *BaseApp) halt() {
|
||||
app.logger.Info("halting node per configuration", "height", app.haltHeight, "time", app.haltTime)
|
||||
|
||||
p, err := os.FindProcess(os.Getpid())
|
||||
if err == nil {
|
||||
// attempt cascading signals in case SIGINT fails (os dependent)
|
||||
sigIntErr := p.Signal(syscall.SIGINT)
|
||||
sigTermErr := p.Signal(syscall.SIGTERM)
|
||||
|
||||
if sigIntErr == nil || sigTermErr == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Resort to exiting immediately if the process could not be found or killed
|
||||
// via SIGINT/SIGTERM signals.
|
||||
app.logger.Info("failed to send SIGINT/SIGTERM; exiting...")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Query implements the ABCI interface. It delegates to CommitMultiStore if it
|
||||
// implements Queryable.
|
||||
func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||
|
||||
+10
-3
@@ -100,9 +100,12 @@ type BaseApp struct {
|
||||
// flag for sealing options and parameters to a BaseApp
|
||||
sealed bool
|
||||
|
||||
// height at which to halt the chain and gracefully shutdown
|
||||
// block height at which to halt the chain and gracefully shutdown
|
||||
haltHeight uint64
|
||||
|
||||
// minimum block time (in Unix seconds) at which to halt the chain and gracefully shutdown
|
||||
haltTime uint64
|
||||
|
||||
// application's version string
|
||||
appVersion string
|
||||
}
|
||||
@@ -341,8 +344,12 @@ func (app *BaseApp) setMinGasPrices(gasPrices sdk.DecCoins) {
|
||||
app.minGasPrices = gasPrices
|
||||
}
|
||||
|
||||
func (app *BaseApp) setHaltHeight(height uint64) {
|
||||
app.haltHeight = height
|
||||
func (app *BaseApp) setHaltHeight(haltHeight uint64) {
|
||||
app.haltHeight = haltHeight
|
||||
}
|
||||
|
||||
func (app *BaseApp) setHaltTime(haltTime uint64) {
|
||||
app.haltTime = haltTime
|
||||
}
|
||||
|
||||
func (app *BaseApp) setInterBlockCache(cache sdk.MultiStorePersistentCache) {
|
||||
|
||||
+8
-3
@@ -29,9 +29,14 @@ func SetMinGasPrices(gasPricesStr string) func(*BaseApp) {
|
||||
return func(bap *BaseApp) { bap.setMinGasPrices(gasPrices) }
|
||||
}
|
||||
|
||||
// SetHaltHeight returns a BaseApp option function that sets the halt height.
|
||||
func SetHaltHeight(height uint64) func(*BaseApp) {
|
||||
return func(bap *BaseApp) { bap.setHaltHeight(height) }
|
||||
// SetHaltHeight returns a BaseApp option function that sets the halt block height.
|
||||
func SetHaltHeight(blockHeight uint64) func(*BaseApp) {
|
||||
return func(bap *BaseApp) { bap.setHaltHeight(blockHeight) }
|
||||
}
|
||||
|
||||
// SetHaltTime returns a BaseApp option function that sets the halt block time.
|
||||
func SetHaltTime(haltTime uint64) func(*BaseApp) {
|
||||
return func(bap *BaseApp) { bap.setHaltTime(haltTime) }
|
||||
}
|
||||
|
||||
// SetInterBlockCache provides a BaseApp option function that sets the
|
||||
|
||||
Reference in New Issue
Block a user