@@ -29,15 +29,15 @@ import (
2929)
3030
3131const (
32- // Version information
33- VERSION = "0.2.1"
32+ Version = "0.3.1"
33+ DefaultBackupPeriodSeconds = 300 // (5 minutes)
3434)
3535
3636func main () {
3737 app := & cli.Command {
3838 Name : "mpcium" ,
3939 Usage : "Multi-Party Computation node for threshold signatures" ,
40- Version : VERSION ,
40+ Version : Version ,
4141 Commands : []* cli.Command {
4242 {
4343 Name : "start" ,
@@ -72,7 +72,7 @@ func main() {
7272 Name : "version" ,
7373 Usage : "Display detailed version information" ,
7474 Action : func (ctx context.Context , c * cli.Command ) error {
75- fmt .Printf ("mpcium version %s\n " , VERSION )
75+ fmt .Printf ("mpcium version %s\n " , Version )
7676 return nil
7777 },
7878 },
@@ -104,13 +104,21 @@ func runNode(ctx context.Context, c *cli.Command) error {
104104 }
105105
106106 consulClient := infra .GetConsulClient (environment )
107- badgerKV := NewBadgerKV (nodeName )
108- defer badgerKV .Close ()
109-
110107 keyinfoStore := keyinfo .NewStore (consulClient .KV ())
111108 peers := LoadPeersFromConsul (consulClient )
112109 nodeID := GetIDFromName (nodeName , peers )
113110
111+ badgerKV := NewBadgerKV (nodeName , nodeID )
112+ defer badgerKV .Close ()
113+
114+ // Start background backup job
115+ backupEnabled := viper .GetBool ("backup_enabled" )
116+ if backupEnabled {
117+ backupPeriodSeconds := viper .GetInt ("backup_period_seconds" )
118+ stopBackup := StartPeriodicBackup (ctx , badgerKV , backupPeriodSeconds )
119+ defer stopBackup ()
120+ }
121+
114122 identityStore , err := identity .NewFileStore ("identity" , nodeName , decryptPrivateKey )
115123 if err != nil {
116124 logger .Fatal ("Failed to create identity store" , err )
@@ -384,7 +392,7 @@ func GetIDFromName(name string, peers []config.Peer) string {
384392 return nodeID
385393}
386394
387- func NewBadgerKV (nodeName string ) * kvstore.BadgerKVStore {
395+ func NewBadgerKV (nodeName , nodeID string ) * kvstore.BadgerKVStore {
388396 // Badger KV DB
389397 // Use configured db_path or default to current directory + "db"
390398 basePath := viper .GetString ("db_path" )
@@ -393,17 +401,55 @@ func NewBadgerKV(nodeName string) *kvstore.BadgerKVStore {
393401 }
394402 dbPath := filepath .Join (basePath , nodeName )
395403
396- badgerKv , err := kvstore .NewBadgerKVStore (
397- dbPath ,
398- []byte (viper .GetString ("badger_password" )),
399- )
404+ // Use configured backup_dir or default to current directory + "backups"
405+ backupDir := viper .GetString ("backup_dir" )
406+ if backupDir == "" {
407+ backupDir = filepath .Join ("." , "backups" )
408+ }
409+
410+ // Create BadgerConfig struct
411+ config := kvstore.BadgerConfig {
412+ NodeID : nodeName ,
413+ EncryptionKey : []byte (viper .GetString ("badger_password" )),
414+ BackupEncryptionKey : []byte (viper .GetString ("badger_password" )), // Using same key for backup encryption
415+ BackupDir : backupDir ,
416+ DBPath : dbPath ,
417+ }
418+
419+ badgerKv , err := kvstore .NewBadgerKVStore (config )
400420 if err != nil {
401421 logger .Fatal ("Failed to create badger kv store" , err )
402422 }
403- logger .Info ("Connected to badger kv store" , "path" , dbPath )
423+ logger .Info ("Connected to badger kv store" , "path" , dbPath , "backup_dir" , backupDir )
404424 return badgerKv
405425}
406426
427+ func StartPeriodicBackup (ctx context.Context , badgerKV * kvstore.BadgerKVStore , periodSeconds int ) func () {
428+ if periodSeconds <= 0 {
429+ periodSeconds = DefaultBackupPeriodSeconds
430+ }
431+ backupTicker := time .NewTicker (time .Duration (periodSeconds ) * time .Second )
432+ backupCtx , backupCancel := context .WithCancel (ctx )
433+ go func () {
434+ for {
435+ select {
436+ case <- backupCtx .Done ():
437+ logger .Info ("Backup background job stopped" )
438+ return
439+ case <- backupTicker .C :
440+ logger .Info ("Running periodic BadgerDB backup..." )
441+ err := badgerKV .Backup ()
442+ if err != nil {
443+ logger .Error ("Periodic BadgerDB backup failed" , err )
444+ } else {
445+ logger .Info ("Periodic BadgerDB backup completed successfully" )
446+ }
447+ }
448+ }
449+ }()
450+ return backupCancel
451+ }
452+
407453func GetNATSConnection (environment string ) (* nats.Conn , error ) {
408454 url := viper .GetString ("nats.url" )
409455 opts := []nats.Option {
0 commit comments