From 36fc348a1104d7df09a124ea7552807d0fbe0773 Mon Sep 17 00:00:00 2001 From: matthew-pilot Date: Fri, 29 May 2026 20:38:46 +0000 Subject: [PATCH] fix: make SaveIdentity atomic (temp+rename+fsync via fsutil.AtomicWrite) (PILOT-248) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace os.WriteFile with fsutil.AtomicWrite to prevent truncated identity files from crashes mid-write. Previously a crash between file-open and the final write could leave a 0-byte or partial JSON file — next daemon start would fail to unmarshal and regenerate a new identity, losing the peer trust graph. --- crypto/identity.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crypto/identity.go b/crypto/identity.go index ef5bbfc..b735e9c 100644 --- a/crypto/identity.go +++ b/crypto/identity.go @@ -11,6 +11,8 @@ import ( "log/slog" "os" "path/filepath" + + "github.com/pilot-protocol/common/fsutil" ) // Identity holds an Ed25519 keypair for a node. @@ -95,7 +97,9 @@ func SaveIdentity(path string, id *Identity) error { return fmt.Errorf("marshal identity: %w", err) } - if err := os.WriteFile(path, data, 0600); err != nil { + // AtomicWrite prevents a truncated identity file from a crash + // mid-write (temp + rename + fsync pattern). + if err := fsutil.AtomicWrite(path, data); err != nil { return fmt.Errorf("write identity: %w", err) } return nil