lnd icon indicating copy to clipboard operation
lnd copied to clipboard

Writefile transactional

Open gregwebs opened this issue 2 years ago • 9 comments

Change Description

This PR is on top of #6723 which can be closed in favor of this one. This addresses issue #6720 to call fsync when writing to files.

Steps to Test

This is quite difficult to test as a manual integration test. I added some unit test cases that can be reviewed.

Pull Request Checklist

Testing

  • [x] Your PR passes all CI checks.
  • [X] Tests covering the positive and negative (error paths) are included.

Code Style and Documentation

gregwebs avatar Jul 26 '22 14:07 gregwebs

@gregwebs I saw #6769 but I haven't found any other build that the linter fails on the same line. Linter would pass if we use the value and not the pointer, but I might want to check what's causing it.

I added some changes so itest could work 👇🏼
diff --git a/io/io_test.go b/io/io_test.go
index 97f8a7aa3..2d6047500 100644
--- a/io/io_test.go
+++ b/io/io_test.go
@@ -54,16 +54,16 @@ func TestWriteFileTransactional(t *testing.T) {
 
 	// Changing the permission to read-only will cause the write to fail
 	// transactional first writes to a tmp file and then renames
-	tmp_name := filename + ".tmp"
-	_, err := os.Stat(tmp_name)
+	tmpName := filename + ".tmp"
+	_, err := os.Stat(tmpName)
 	if err == nil {
-		t.Fatalf("WriteFileTransactional tmp exists %s: %v", tmp_name, err)
+		t.Fatalf("WriteFileTransactional tmp exists %s: %v", tmpName, err)
 	}
-	if fh, err := os.Create(tmp_name); err != nil {
+	if fh, err := os.Create(tmpName); err != nil {
 		t.Fatalf("Error setting up read-only %s: %v", filename, err)
 		fh.Close()
 	}
-	if err := os.Chmod(tmp_name, 0444); err != nil {
+	if err := os.Chmod(tmpName, 0444); err != nil {
 		t.Fatalf("Error changing to read-only %s: %v", filename, err)
 	}
 
@@ -78,9 +78,9 @@ func TestWriteFileTransactional(t *testing.T) {
 	}
 	ensureFileContents(t, filename, data1)
 
-	_, err = os.Stat(tmp_name)
+	_, err = os.Stat(tmpName)
 	if err == nil {
-		t.Fatalf("WriteFileTransactional tmp exists %s: %v", tmp_name, err)
+		t.Fatalf("WriteFileTransactional tmp exists %s: %v", tmpName, err)
 	}
 }
 
diff --git a/io/write.go b/io/write.go
index bc9f3588a..2918e8283 100644
--- a/io/write.go
+++ b/io/write.go
@@ -33,7 +33,7 @@ func WriteFileTransactional(file string, fileBytes []byte, perm fs.FileMode) err
 	err := os.Rename(tmpName, file)
 	if err != nil {
 		// Ignore this error and return the prior error
-		// This may be unecessary but shouldn't cause a problem
+		// This may be unnecessary but shouldn't cause a problem
 		_ = os.Remove(file)
 	}
 	return err
diff --git a/lnrpc/chainrpc/chainnotifier_server.go b/lnrpc/chainrpc/chainnotifier_server.go
index d1de7b988..e1e206c02 100644
--- a/lnrpc/chainrpc/chainnotifier_server.go
+++ b/lnrpc/chainrpc/chainnotifier_server.go
@@ -7,7 +7,6 @@ import (
 	"bytes"
 	"context"
 	"errors"
-	"os"
 	"path/filepath"
 	"sync"
 
diff --git a/lnrpc/invoicesrpc/invoices_server.go b/lnrpc/invoicesrpc/invoices_server.go
index ca5d811d9..ff46d95bf 100644
--- a/lnrpc/invoicesrpc/invoices_server.go
+++ b/lnrpc/invoicesrpc/invoices_server.go
@@ -6,7 +6,6 @@ package invoicesrpc
 import (
 	"context"
 	"fmt"
-	"os"
 	"path/filepath"
 
 	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
diff --git a/lnrpc/signrpc/signer_server.go b/lnrpc/signrpc/signer_server.go
index 45b88d89c..278668e51 100644
--- a/lnrpc/signrpc/signer_server.go
+++ b/lnrpc/signrpc/signer_server.go
@@ -8,7 +8,6 @@ import (
 	"context"
 	"crypto/sha256"
 	"fmt"
-	"os"
 	"path/filepath"
 
 	"github.com/btcsuite/btcd/btcec/v2"
diff --git a/lnrpc/walletrpc/walletkit_server.go b/lnrpc/walletrpc/walletkit_server.go
index ad6d4a0c7..5f2786910 100644
--- a/lnrpc/walletrpc/walletkit_server.go
+++ b/lnrpc/walletrpc/walletkit_server.go
@@ -10,7 +10,6 @@ import (
 	"errors"
 	"fmt"
 	"math"
-	"os"
 	"path/filepath"
 	"time"

mauricepoirrier avatar Jul 27 '22 00:07 mauricepoirrier

@gregwebs I saw #6769 but I haven't found any other build that the linter fails on the same line. Linter would pass if we use the value and not the pointer, but I might want to check what's causing it.

Oh, it fails on me on my local machine for master as well. I haven't seen a single open PR that is passing so thought it must be affecting others as well. It is a very strange failure: I cannot explain it.

I added some changes so itest could work 👇🏼

Awesome, thank you, I will apply that!

gregwebs avatar Jul 27 '22 01:07 gregwebs

@Crypt-iQ please take a look again.

gregwebs avatar Aug 01 '22 12:08 gregwebs

Is there a reason to go against best practice and use a bool, or do you also prefer an enum type?

Either way, it seems clear to me that a transactional write would be preferable for this project. I have a commit here that uses an existing library that also maintains permissions and works on windows: https://github.com/gregwebs/lnd/commit/72886227e04b608fd564874495f1cab6a1e6af51

gregwebs avatar Aug 11 '22 13:08 gregwebs

Is there a reason to go against best practice and use a bool, or do you also prefer an enum type?

An enum is fine

Either way, it seems clear to me that a transactional write would be preferable for this project. I have a commit here that uses an existing library that also maintains permissions and works on windows: https://github.com/gregwebs/lnd/commit/72886227e04b608fd564874495f1cab6a1e6af51

In a different PR sure, but I don't think we should be adding dependencies if we don't need to

Crypt-iQ avatar Aug 11 '22 14:08 Crypt-iQ

I lost my bandwidth to follow through on this, perhaps @mauricepoirrier would like to. I will comment back here if I am able to pick it back up.

gregwebs avatar Aug 18 '22 17:08 gregwebs

@gregwebs, remember to re-request review from reviewers when ready

lightninglabs-deploy avatar Sep 15 '22 19:09 lightninglabs-deploy

@gregwebs if you need some help, I can pick up this issue.

adam2k avatar Sep 23 '22 17:09 adam2k

@gregwebs if you need some help, I can pick up this issue.

That would be great if you can take over the issue.

gregwebs avatar Sep 24 '22 13:09 gregwebs

@gregwebs, remember to re-request review from reviewers when ready

lightninglabs-deploy avatar Nov 14 '22 05:11 lightninglabs-deploy

@gregwebs, remember to re-request review from reviewers when ready

lightninglabs-deploy avatar Nov 21 '22 06:11 lightninglabs-deploy

@gregwebs in order to have write access I opened a new PR #7192. I squashed the commits but still part of release notes :)

Any review is welcome! cc: @Crypt-iQ

mauricepoirrier avatar Nov 22 '22 02:11 mauricepoirrier

Replaced by https://github.com/lightningnetwork/lnd/pull/7192.

guggero avatar Nov 22 '22 10:11 guggero