From 3a3fa0d3f037c7ca4aaf993eae87120a6220bf4b Mon Sep 17 00:00:00 2001 From: Ori Newman Date: Sun, 2 Oct 2022 23:42:14 +0300 Subject: [PATCH] Add lock file to kaspawallet (#2154) * Add lock file to kaspawallet * Add a possible explanation to password error Co-authored-by: msutton --- cmd/kaspawallet/create.go | 5 +++++ cmd/kaspawallet/daemon/server/server.go | 5 +++++ cmd/kaspawallet/keys/keys.go | 26 +++++++++++++++++++++++++ cmd/kaspawallet/send.go | 6 ++++++ go.mod | 2 +- go.sum | 10 +++------- version/version.go | 2 +- 7 files changed, 47 insertions(+), 9 deletions(-) diff --git a/cmd/kaspawallet/create.go b/cmd/kaspawallet/create.go index 2773fc9f1..69268a6ed 100644 --- a/cmd/kaspawallet/create.go +++ b/cmd/kaspawallet/create.go @@ -78,6 +78,11 @@ func create(conf *createConfig) error { return err } + err = file.TryLock() + if err != nil { + return err + } + err = file.Save() if err != nil { return err diff --git a/cmd/kaspawallet/daemon/server/server.go b/cmd/kaspawallet/daemon/server/server.go index 0640cff4e..55d9ce74a 100644 --- a/cmd/kaspawallet/daemon/server/server.go +++ b/cmd/kaspawallet/daemon/server/server.go @@ -77,6 +77,11 @@ func Start(params *dagconfig.Params, listen, rpcServer string, keysFilePath stri return (errors.Wrapf(err, "Error reading keys file %s", keysFilePath)) } + err = keysFile.TryLock() + if err != nil { + return err + } + serverInstance := &server{ rpcClient: rpcClient, params: params, diff --git a/cmd/kaspawallet/keys/keys.go b/cmd/kaspawallet/keys/keys.go index dceb9f7be..78676416d 100644 --- a/cmd/kaspawallet/keys/keys.go +++ b/cmd/kaspawallet/keys/keys.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "github.com/gofrs/flock" "os" "path/filepath" "runtime" @@ -400,3 +401,28 @@ func decryptMnemonic(numThreads uint8, encryptedPrivateKey *EncryptedMnemonic, p return string(decrypted), nil } + +// flockMap is a map that holds all lock file handlers. This map guarantees that +// the associated locked file handler will never get cleaned by the GC, because +// once they are cleaned the associated file will be unlocked. +var flockMap = make(map[string]*flock.Flock) + +// TryLock tries to acquire an exclusive lock for the file. +func (d *File) TryLock() error { + if _, ok := flockMap[d.path]; ok { + return errors.Errorf("file %s is already locked", d.path) + } + + lockFile := flock.New(d.path + ".lock") + flockMap[d.path] = lockFile + + success, err := lockFile.TryLock() + if err != nil { + return err + } + + if !success { + return errors.Errorf("%s is locked and cannot be used. Make sure that no other active wallet command is using it.", d.path) + } + return nil +} diff --git a/cmd/kaspawallet/send.go b/cmd/kaspawallet/send.go index c251f984f..2385d7397 100644 --- a/cmd/kaspawallet/send.go +++ b/cmd/kaspawallet/send.go @@ -3,6 +3,8 @@ package main import ( "context" "fmt" + "os" + "strings" "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client" "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb" @@ -49,6 +51,10 @@ func send(conf *sendConfig) error { } mnemonics, err := keysFile.DecryptMnemonics(conf.Password) if err != nil { + if strings.Contains(err.Error(), "message authentication failed") { + fmt.Fprintf(os.Stderr, "Password decryption failed. Sometimes this is a result of not "+ + "specifying the same keys file used by the wallet daemon process.\n") + } return err } diff --git a/go.mod b/go.mod index 31aab2975..52f9343df 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd github.com/btcsuite/winsvc v1.0.0 github.com/davecgh/go-spew v1.1.1 + github.com/gofrs/flock v0.8.1 github.com/golang/protobuf v1.5.2 github.com/jessevdk/go-flags v1.4.0 github.com/jrick/logrotate v1.0.0 @@ -28,6 +29,5 @@ require ( golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect golang.org/x/text v0.3.5 // indirect google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08 // indirect - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect ) diff --git a/go.sum b/go.sum index ed42be015..f391787b8 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,8 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -118,8 +120,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea h1:+WiDlPBBaO+h9vPNZi8uJ3k4BkKQB7Iow3aqwHVA5hI= -golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -155,8 +155,6 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 h1:TLkBREm4nIsEcexnCjgQd5GQWaHcqMzwQV0TX9pq8S0= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -167,12 +165,10 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= diff --git a/version/version.go b/version/version.go index bc80ce20e..8548c4c01 100644 --- a/version/version.go +++ b/version/version.go @@ -11,7 +11,7 @@ const validCharacters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs const ( appMajor uint = 0 appMinor uint = 12 - appPatch uint = 7 + appPatch uint = 8 ) // appBuild is defined as a variable so it can be overridden during the build