Merge PR #5005: Add support for halt-time

This commit is contained in:
Alexander Bezobchuk
2019-09-09 10:08:10 -04:00
committed by GitHub
parent 2c4faf983b
commit c8d84b4df4
7 changed files with 119 additions and 20 deletions
+41 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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