mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-13 21:31:23 +00:00
Mempool WAL is still created by default in home directory, leads to permission errors (#2758)
* only invoke InitWAL/CloseWAL if WalPath is not empty Closes #2717 * panic if WAL is not initialized when calling CloseWAL * add a changelog entry
This commit is contained in:
committed by
Ethan Buchman
parent
7246ffc48f
commit
b8a9b0bf78
@ -25,3 +25,4 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
|
|||||||
### IMPROVEMENTS:
|
### IMPROVEMENTS:
|
||||||
|
|
||||||
### BUG FIXES:
|
### BUG FIXES:
|
||||||
|
- [mempool] fix a bug where we create a WAL despite `wal_dir` being empty
|
||||||
|
@ -497,6 +497,11 @@ func (cfg *MempoolConfig) WalDir() string {
|
|||||||
return rootify(cfg.WalPath, cfg.RootDir)
|
return rootify(cfg.WalPath, cfg.RootDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WalEnabled returns true if the WAL is enabled.
|
||||||
|
func (cfg *MempoolConfig) WalEnabled() bool {
|
||||||
|
return cfg.WalPath != ""
|
||||||
|
}
|
||||||
|
|
||||||
// ValidateBasic performs basic validation (checking param bounds, etc.) and
|
// ValidateBasic performs basic validation (checking param bounds, etc.) and
|
||||||
// returns an error if any check fails.
|
// returns an error if any check fails.
|
||||||
func (cfg *MempoolConfig) ValidateBasic() error {
|
func (cfg *MempoolConfig) ValidateBasic() error {
|
||||||
|
@ -213,39 +213,33 @@ func WithMetrics(metrics *Metrics) MempoolOption {
|
|||||||
return func(mem *Mempool) { mem.metrics = metrics }
|
return func(mem *Mempool) { mem.metrics = metrics }
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloseWAL closes and discards the underlying WAL file.
|
// InitWAL creates a directory for the WAL file and opens a file itself.
|
||||||
// Any further writes will not be relayed to disk.
|
//
|
||||||
func (mem *Mempool) CloseWAL() bool {
|
// *panics* if can't create directory or open file.
|
||||||
if mem == nil {
|
// *not thread safe*
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
mem.proxyMtx.Lock()
|
|
||||||
defer mem.proxyMtx.Unlock()
|
|
||||||
|
|
||||||
if mem.wal == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if err := mem.wal.Close(); err != nil && mem.logger != nil {
|
|
||||||
mem.logger.Error("Mempool.CloseWAL", "err", err)
|
|
||||||
}
|
|
||||||
mem.wal = nil
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mem *Mempool) InitWAL() {
|
func (mem *Mempool) InitWAL() {
|
||||||
walDir := mem.config.WalDir()
|
walDir := mem.config.WalDir()
|
||||||
if walDir != "" {
|
|
||||||
err := cmn.EnsureDir(walDir, 0700)
|
err := cmn.EnsureDir(walDir, 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmn.PanicSanity(errors.Wrap(err, "Error ensuring Mempool wal dir"))
|
panic(errors.Wrap(err, "Error ensuring Mempool WAL dir"))
|
||||||
}
|
}
|
||||||
af, err := auto.OpenAutoFile(walDir + "/wal")
|
af, err := auto.OpenAutoFile(walDir + "/wal")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmn.PanicSanity(errors.Wrap(err, "Error opening Mempool wal file"))
|
panic(errors.Wrap(err, "Error opening Mempool WAL file"))
|
||||||
}
|
}
|
||||||
mem.wal = af
|
mem.wal = af
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseWAL closes and discards the underlying WAL file.
|
||||||
|
// Any further writes will not be relayed to disk.
|
||||||
|
func (mem *Mempool) CloseWAL() {
|
||||||
|
mem.proxyMtx.Lock()
|
||||||
|
defer mem.proxyMtx.Unlock()
|
||||||
|
|
||||||
|
if err := mem.wal.Close(); err != nil {
|
||||||
|
mem.logger.Error("Error closing WAL", "err", err)
|
||||||
}
|
}
|
||||||
|
mem.wal = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock locks the mempool. The consensus must be able to hold lock to safely update.
|
// Lock locks the mempool. The consensus must be able to hold lock to safely update.
|
||||||
|
@ -369,15 +369,12 @@ func TestMempoolCloseWAL(t *testing.T) {
|
|||||||
|
|
||||||
// 7. Invoke CloseWAL() and ensure it discards the
|
// 7. Invoke CloseWAL() and ensure it discards the
|
||||||
// WAL thus any other write won't go through.
|
// WAL thus any other write won't go through.
|
||||||
require.True(t, mempool.CloseWAL(), "CloseWAL should CloseWAL")
|
mempool.CloseWAL()
|
||||||
mempool.CheckTx(types.Tx([]byte("bar")), nil)
|
mempool.CheckTx(types.Tx([]byte("bar")), nil)
|
||||||
sum2 := checksumFile(walFilepath, t)
|
sum2 := checksumFile(walFilepath, t)
|
||||||
require.Equal(t, sum1, sum2, "expected no change to the WAL after invoking CloseWAL() since it was discarded")
|
require.Equal(t, sum1, sum2, "expected no change to the WAL after invoking CloseWAL() since it was discarded")
|
||||||
|
|
||||||
// 8. Second CloseWAL should do nothing
|
// 8. Sanity check to ensure that the WAL file still exists
|
||||||
require.False(t, mempool.CloseWAL(), "CloseWAL should CloseWAL")
|
|
||||||
|
|
||||||
// 9. Sanity check to ensure that the WAL file still exists
|
|
||||||
m3, err := filepath.Glob(filepath.Join(rootDir, "*"))
|
m3, err := filepath.Glob(filepath.Join(rootDir, "*"))
|
||||||
require.Nil(t, err, "successful globbing expected")
|
require.Nil(t, err, "successful globbing expected")
|
||||||
require.Equal(t, 1, len(m3), "expecting the wal match in")
|
require.Equal(t, 1, len(m3), "expecting the wal match in")
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
"github.com/tendermint/go-amino"
|
|
||||||
|
|
||||||
|
amino "github.com/tendermint/go-amino"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
bc "github.com/tendermint/tendermint/blockchain"
|
bc "github.com/tendermint/tendermint/blockchain"
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
@ -279,7 +279,9 @@ func NewNode(config *cfg.Config,
|
|||||||
)
|
)
|
||||||
mempoolLogger := logger.With("module", "mempool")
|
mempoolLogger := logger.With("module", "mempool")
|
||||||
mempool.SetLogger(mempoolLogger)
|
mempool.SetLogger(mempoolLogger)
|
||||||
|
if config.Mempool.WalEnabled() {
|
||||||
mempool.InitWAL() // no need to have the mempool wal during tests
|
mempool.InitWAL() // no need to have the mempool wal during tests
|
||||||
|
}
|
||||||
mempoolReactor := mempl.NewMempoolReactor(config.Mempool, mempool)
|
mempoolReactor := mempl.NewMempoolReactor(config.Mempool, mempool)
|
||||||
mempoolReactor.SetLogger(mempoolLogger)
|
mempoolReactor.SetLogger(mempoolLogger)
|
||||||
|
|
||||||
@ -586,6 +588,11 @@ func (n *Node) OnStop() {
|
|||||||
// TODO: gracefully disconnect from peers.
|
// TODO: gracefully disconnect from peers.
|
||||||
n.sw.Stop()
|
n.sw.Stop()
|
||||||
|
|
||||||
|
// stop mempool WAL
|
||||||
|
if n.config.Mempool.WalEnabled() {
|
||||||
|
n.mempoolReactor.Mempool.CloseWAL()
|
||||||
|
}
|
||||||
|
|
||||||
if err := n.transport.Close(); err != nil {
|
if err := n.transport.Close(); err != nil {
|
||||||
n.Logger.Error("Error closing transport", "err", err)
|
n.Logger.Error("Error closing transport", "err", err)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user