-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(monitor): bootstrap monitor from db (#34)
This PR enables the monitor to start from the last processed confirmed header, we also save the epoch References [issue](https://github.com/babylonchain/vigilante/issues/156).
- Loading branch information
Showing
23 changed files
with
585 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package config | ||
|
||
import ( | ||
"fmt" | ||
"github.com/lightningnetwork/lnd/kvdb" | ||
"time" | ||
) | ||
|
||
const ( | ||
defaultDbName = "vigilante.db" | ||
) | ||
|
||
type DBConfig struct { | ||
// DBPath is the directory path in which the database file should be | ||
// stored. | ||
DBPath string `long:"dbpath" description:"The directory path in which the database file should be stored."` | ||
|
||
// DBFileName is the name of the database file. | ||
DBFileName string `long:"dbfilename" description:"The name of the database file."` | ||
|
||
// NoFreelistSync, if true, prevents the database from syncing its | ||
// freelist to disk, resulting in improved performance at the expense of | ||
// increased startup time. | ||
NoFreelistSync bool `long:"nofreelistsync" description:"Prevents the database from syncing its freelist to disk, resulting in improved performance at the expense of increased startup time."` | ||
|
||
// AutoCompact specifies if a Bolt based database backend should be | ||
// automatically compacted on startup (if the minimum age of the | ||
// database file is reached). This will require additional disk space | ||
// for the compacted copy of the database but will result in an overall | ||
// lower database size after the compaction. | ||
AutoCompact bool `long:"autocompact" description:"Specifies if a Bolt based database backend should be automatically compacted on startup (if the minimum age of the database file is reached). This will require additional disk space for the compacted copy of the database but will result in an overall lower database size after the compaction."` | ||
|
||
// AutoCompactMinAge specifies the minimum time that must have passed | ||
// since a bolt database file was last compacted for the compaction to | ||
// be considered again. | ||
AutoCompactMinAge time.Duration `long:"autocompactminage" description:"Specifies the minimum time that must have passed since a bolt database file was last compacted for the compaction to be considered again."` | ||
|
||
// DBTimeout specifies the timeout value to use when opening the wallet | ||
// database. | ||
DBTimeout time.Duration `long:"dbtimeout" description:"Specifies the timeout value to use when opening the wallet database."` | ||
} | ||
|
||
func DefaultDBConfig() *DBConfig { | ||
return DefaultDBConfigWithHomePath(defaultAppDataDir) | ||
} | ||
|
||
func DefaultDBConfigWithHomePath(homePath string) *DBConfig { | ||
return &DBConfig{ | ||
DBPath: DataDir(homePath), | ||
DBFileName: defaultDbName, | ||
NoFreelistSync: true, | ||
AutoCompact: false, | ||
AutoCompactMinAge: kvdb.DefaultBoltAutoCompactMinAge, | ||
DBTimeout: kvdb.DefaultDBTimeout, | ||
} | ||
} | ||
|
||
func (cfg *DBConfig) ToBoltBackendConfig() *kvdb.BoltBackendConfig { | ||
return &kvdb.BoltBackendConfig{ | ||
DBPath: cfg.DBPath, | ||
DBFileName: cfg.DBFileName, | ||
NoFreelistSync: cfg.NoFreelistSync, | ||
AutoCompact: cfg.AutoCompact, | ||
AutoCompactMinAge: cfg.AutoCompactMinAge, | ||
DBTimeout: cfg.DBTimeout, | ||
} | ||
} | ||
|
||
func (cfg *DBConfig) Validate() error { | ||
if cfg.DBPath == "" { | ||
return fmt.Errorf("DB path cannot be empty") | ||
} | ||
|
||
if cfg.DBFileName == "" { | ||
return fmt.Errorf("DB file name cannot be empty") | ||
} | ||
return nil | ||
} | ||
|
||
func (cfg *DBConfig) GetDbBackend() (kvdb.Backend, error) { | ||
return kvdb.GetBoltBackend(cfg.ToBoltBackendConfig()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
//go:build e2e | ||
// +build e2e | ||
|
||
package e2etest | ||
|
||
import ( | ||
"fmt" | ||
bbnclient "github.com/babylonlabs-io/babylon/client/client" | ||
"github.com/babylonlabs-io/vigilante/btcclient" | ||
"github.com/babylonlabs-io/vigilante/metrics" | ||
"github.com/babylonlabs-io/vigilante/monitor" | ||
"github.com/babylonlabs-io/vigilante/reporter" | ||
"github.com/babylonlabs-io/vigilante/submitter" | ||
"github.com/babylonlabs-io/vigilante/testutil" | ||
"github.com/babylonlabs-io/vigilante/types" | ||
"github.com/btcsuite/btcd/chaincfg" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
promtestutil "github.com/prometheus/client_golang/prometheus/testutil" | ||
"github.com/stretchr/testify/require" | ||
"go.uber.org/zap" | ||
"time" | ||
|
||
"testing" | ||
) | ||
|
||
// TestMonitorBootstrap - validates that after a restart monitor bootstraps from DB | ||
func TestMonitorBootstrap(t *testing.T) { | ||
numMatureOutputs := uint32(150) | ||
|
||
tm := StartManager(t, numMatureOutputs, 2) | ||
defer tm.Stop(t) | ||
|
||
backend, err := btcclient.NewNodeBackend( | ||
btcclient.ToBitcoindConfig(tm.Config.BTC), | ||
&chaincfg.RegressionNetParams, | ||
&btcclient.EmptyHintCache{}, | ||
) | ||
require.NoError(t, err) | ||
|
||
err = backend.Start() | ||
require.NoError(t, err) | ||
|
||
dbBackend := testutil.MakeTestBackend(t) | ||
|
||
monitorMetrics := metrics.NewMonitorMetrics() | ||
genesisPath := fmt.Sprintf("%s/config/genesis.json", tm.Config.Babylon.KeyDirectory) | ||
genesisInfo, err := types.GetGenesisInfoFromFile(genesisPath) | ||
require.NoError(t, err) | ||
|
||
tm.Config.Submitter.PollingIntervalSeconds = 1 | ||
subAddr, _ := sdk.AccAddressFromBech32(submitterAddrStr) | ||
|
||
// create submitter | ||
vigilantSubmitter, _ := submitter.New( | ||
&tm.Config.Submitter, | ||
logger, | ||
tm.BTCClient, | ||
tm.BabylonClient, | ||
subAddr, | ||
tm.Config.Common.RetrySleepTime, | ||
tm.Config.Common.MaxRetrySleepTime, | ||
tm.Config.Common.MaxRetryTimes, | ||
metrics.NewSubmitterMetrics(), | ||
) | ||
|
||
vigilantSubmitter.Start() | ||
defer vigilantSubmitter.Stop() | ||
|
||
vigilantReporter, err := reporter.New( | ||
&tm.Config.Reporter, | ||
logger, | ||
tm.BTCClient, | ||
tm.BabylonClient, | ||
backend, | ||
tm.Config.Common.RetrySleepTime, | ||
tm.Config.Common.MaxRetrySleepTime, | ||
metrics.NewReporterMetrics(), | ||
) | ||
require.NoError(t, err) | ||
|
||
defer func() { | ||
vigilantSubmitter.Stop() | ||
vigilantSubmitter.WaitForShutdown() | ||
}() | ||
|
||
mon, err := monitor.New( | ||
&tm.Config.Monitor, | ||
&tm.Config.Common, | ||
zap.NewNop(), | ||
genesisInfo, | ||
tm.BabylonClient, | ||
tm.BTCClient, | ||
backend, | ||
monitorMetrics, | ||
dbBackend, | ||
) | ||
require.NoError(t, err) | ||
vigilantReporter.Start() | ||
defer vigilantReporter.Stop() | ||
|
||
go func() { | ||
ticker := time.NewTicker(3 * time.Second) | ||
timer := time.NewTimer(15 * time.Second) | ||
defer timer.Stop() | ||
defer ticker.Stop() | ||
for { | ||
select { | ||
case <-ticker.C: | ||
tm.mineBlock(t) | ||
case <-timer.C: | ||
return | ||
} | ||
} | ||
}() | ||
|
||
go mon.Start(genesisInfo.GetBaseBTCHeight()) | ||
|
||
time.Sleep(15 * time.Second) | ||
mon.Stop() | ||
|
||
// use a new bbn client | ||
babylonClient, err := bbnclient.New(&tm.Config.Babylon, nil) | ||
require.NoError(t, err) | ||
defer babylonClient.Stop() | ||
|
||
mon, err = monitor.New( | ||
&tm.Config.Monitor, | ||
&tm.Config.Common, | ||
zap.NewNop(), | ||
genesisInfo, | ||
babylonClient, | ||
tm.BTCClient, | ||
backend, | ||
monitorMetrics, | ||
dbBackend, | ||
) | ||
require.NoError(t, err) | ||
go mon.Start(genesisInfo.GetBaseBTCHeight()) | ||
|
||
defer mon.Stop() | ||
|
||
require.Zero(t, promtestutil.ToFloat64(mon.Metrics().InvalidBTCHeadersCounter)) | ||
require.Zero(t, promtestutil.ToFloat64(mon.Metrics().InvalidEpochsCounter)) | ||
require.Eventually(t, func() bool { | ||
return mon.BTCScanner.GetBaseHeight() > genesisInfo.GetBaseBTCHeight() | ||
}, eventuallyWaitTimeOut, eventuallyPollTime) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.