diff --git a/common/os.go b/common/os.go index bab5fbce6..2d65683b8 100644 --- a/common/os.go +++ b/common/os.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "io/ioutil" "os" "os/signal" ) @@ -26,3 +27,26 @@ func Exit(s string) { fmt.Printf(s + "\n") os.Exit(1) } + +// Writes to newBytes to filePath. +// Guaranteed not to lose *both* oldBytes and newBytes, +// (assuming that the OS is perfect) +func AtomicWriteFile(filePath string, newBytes []byte) error { + // If a file already exists there, copy to filePath+".bak" (overwrite anything) + if _, err := os.Stat(filePath); !os.IsNotExist(err) { + fileBytes, err := ioutil.ReadFile(filePath) + if err != nil { + return fmt.Errorf("Failed to read file %v. %v", filePath, err) + } + err = ioutil.WriteFile(filePath+".bak", fileBytes, 0600) + if err != nil { + return fmt.Errorf("Failed to write file %v. %v", filePath+".bak", err) + } + } + // Write newBytes to filePath. + err := ioutil.WriteFile(filePath, newBytes, 0600) + if err != nil { + return fmt.Errorf("Failed to write file %v. %v", filePath, err) + } + return nil +} diff --git a/config/config.go b/config/config.go index 23ed290b5..739b4d154 100644 --- a/config/config.go +++ b/config/config.go @@ -37,6 +37,7 @@ var defaultConfig = `# This is a TOML config file. Network = "tendermint_testnet0" ListenAddr = "0.0.0.0:8080" +NodeName = "anon_dev" # First node to connect to. Command-line overridable. SeedNode = "188.166.55.222:8080" diff --git a/p2p/addrbook.go b/p2p/addrbook.go index 893cf1c9e..f8abe28ee 100644 --- a/p2p/addrbook.go +++ b/p2p/addrbook.go @@ -319,14 +319,12 @@ func (a *AddrBook) saveToFile(filePath string) { Addrs: addrs, } - w, err := os.Create(filePath) + jsonBytes, err := json.MarshalIndent(aJSON, "", "\t") if err != nil { - log.Error("Error opening file", "file", filePath, "error", err) + log.Error("Failed to save AddrBook to file", "err", err) return } - defer w.Close() - jsonBytes, err := json.MarshalIndent(aJSON, "", "\t") - _, err = w.Write(jsonBytes) + err = AtomicWriteFile(filePath, jsonBytes) if err != nil { log.Error("Failed to save AddrBook to file", "file", filePath, "error", err) } diff --git a/state/priv_validator.go b/state/priv_validator.go index 17839a500..ed5dff713 100644 --- a/state/priv_validator.go +++ b/state/priv_validator.go @@ -99,8 +99,9 @@ func (privVal *PrivValidator) Save() { func (privVal *PrivValidator) save() { jsonBytes := binary.JSONBytes(privVal) - err := ioutil.WriteFile(privVal.filename, jsonBytes, 0700) + err := AtomicWriteFile(privVal.filename, jsonBytes) if err != nil { + // `@; BOOM!!! panic(err) } }