Skip to content

Commit

Permalink
Merge branch 'main' into fix/remove-decoding-bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
Ja7ad authored Feb 8, 2025
2 parents c4382ef + c159188 commit 5a09c8c
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 3 deletions.
1 change: 1 addition & 0 deletions cmd/wallet/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func main() {
buildAllAddrCmd(rootCmd)
buildAllHistoryCmd(rootCmd)
buildInfoCmd(rootCmd)
buildNeuterCmd(rootCmd)

err := rootCmd.Execute()
if err != nil {
Expand Down
35 changes: 35 additions & 0 deletions cmd/wallet/neuter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"fmt"

"github.com/ipfs/boxo/util"
"github.com/pactus-project/pactus/cmd"
"github.com/spf13/cobra"
)

func buildNeuterCmd(parentCmd *cobra.Command) {
neuterCmd := &cobra.Command{
Use: "neuter",
Short: "convert full wallet to neutered wallet and can only be used to retrieve balances or stakes",
}
parentCmd.AddCommand(neuterCmd)

neuterCmd.Run = func(_ *cobra.Command, _ []string) {
wlt, err := openWallet()
cmd.FatalErrorCheck(err)

path := wlt.Path() + ".neutered"

if util.FileExists(path) {
cmd.FatalErrorCheck(fmt.Errorf("neutered wallet already exists, at %s", path))
}

neuteredWallet := wlt.Neuter(path)

err = neuteredWallet.Save()
cmd.FatalErrorCheck(err)

cmd.PrintSuccessMsgf("neutered wallet created at %s", path)
}
}
File renamed without changes.
59 changes: 56 additions & 3 deletions util/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,19 +208,72 @@ func MoveDirectory(srcDir, dstDir string) error {
return fmt.Errorf("destination directory %s already exists", dstDir)
}

// Get the parent directory of the destination directory
parentDir := filepath.Dir(dstDir)
if err := Mkdir(parentDir); err != nil {
return fmt.Errorf("failed to create parent directories for %s: %w", dstDir, err)
}

if err := os.Rename(srcDir, dstDir); err != nil {
return fmt.Errorf("failed to move directory from %s to %s: %w", srcDir, dstDir, err)
err := os.Rename(srcDir, dstDir)
if err != nil {
// To prevent invalid cross-device link perform a manual copy
if err := copyDirectory(srcDir, dstDir); err != nil {
return fmt.Errorf("failed to move directory from %s to %s: %w", srcDir, dstDir, err)
}

// Remove source directory after successful copy
if err := os.RemoveAll(srcDir); err != nil {
return fmt.Errorf("failed to remove source directory %s: %w", srcDir, err)
}
}

return nil
}

func copyDirectory(src, dst string) error {
return filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

relPath, err := filepath.Rel(src, path)
if err != nil {
return err
}
dstPath := filepath.Join(dst, relPath)

if info.IsDir() {
return os.MkdirAll(dstPath, info.Mode())
}

return copyFile(path, dstPath, info)
})
}

func copyFile(src, dst string, info os.FileInfo) error {
input, err := os.Open(src)
if err != nil {
return err
}
defer func() {
_ = input.Close()
}()

out, err := os.Create(dst)
if err != nil {
return err
}
defer func() {
_ = out.Close()
}()

if _, err = io.Copy(out, input); err != nil {
return err
}

// Preserve file permissions
return os.Chmod(dst, info.Mode())
}

// SanitizeArchivePath mitigates the "Zip Slip" vulnerability by sanitizing archive file paths.
// It ensures that the file path is contained within the specified base directory to prevent directory
// traversal attacks. For more details on the vulnerability, see https://snyk.io/research/zip-slip-vulnerability.
Expand Down
15 changes: 15 additions & 0 deletions wallet/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ func (s *Store) ToBytes() ([]byte, error) {
return json.MarshalIndent(s, " ", " ")
}

func (s *Store) Clone() *Store {
clonedVault := *s.Vault // Assuming Vault has proper pointer handling internally
clonedHistory := s.History

return &Store{
Version: s.Version,
UUID: s.UUID,
CreatedAt: s.CreatedAt,
Network: s.Network,
VaultCRC: s.VaultCRC,
Vault: &clonedVault,
History: clonedHistory,
}
}

func (s *Store) ValidateCRC() error {
crc := s.calcVaultCRC()
if s.VaultCRC != crc {
Expand Down
13 changes: 13 additions & 0 deletions wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,3 +548,16 @@ func (w *Wallet) Info() *Info {
CreatedAt: w.store.CreatedAt,
}
}

// Neuter clones the wallet and neuters it and saves it at the given path.
func (w *Wallet) Neuter(path string) *Wallet {
clonedStore := w.store.Clone()
clonedStore.Vault = w.store.Vault.Neuter()

neuteredWallet := &Wallet{
store: clonedStore,
path: path,
}

return neuteredWallet
}

0 comments on commit 5a09c8c

Please # to comment.