Skip to content

Commit

Permalink
Merge pull request #120 from SiaFoundation/nate/fix-reset-wallet-loop
Browse files Browse the repository at this point in the history
Update wallet key when reset
  • Loading branch information
n8maninger committed Jul 16, 2023
2 parents 2abf31d + 2925095 commit 49d7f35
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 12 deletions.
23 changes: 17 additions & 6 deletions chain/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"strings"
"sync"
"time"

"gitlab.com/NebulousLabs/encoding"
"go.sia.tech/core/consensus"
Expand All @@ -15,6 +16,8 @@ import (
stypes "go.sia.tech/siad/types"
)

const maxSyncTime = time.Hour

var (
// ErrBlockNotFound is returned when a block is not found.
ErrBlockNotFound = errors.New("block not found")
Expand Down Expand Up @@ -48,9 +51,10 @@ type Manager struct {
cs modules.ConsensusSet
network *consensus.Network

close chan struct{}
mu sync.Mutex
tip consensus.State
close chan struct{}
mu sync.Mutex
tip consensus.State
synced bool
}

// ProcessConsensusChange implements the modules.ConsensusSetSubscriber interface.
Expand All @@ -64,6 +68,7 @@ func (m *Manager) ProcessConsensusChange(cc modules.ConsensusChange) {
Height: uint64(cc.BlockHeight),
},
}
m.synced = synced(cc.AppliedBlocks[len(cc.AppliedBlocks)-1].Timestamp)
}

// Network returns the network name.
Expand Down Expand Up @@ -91,7 +96,9 @@ func (m *Manager) Close() error {

// Synced returns true if the chain manager is synced with the consensus set.
func (m *Manager) Synced() bool {
return m.cs.Synced()
m.mu.Lock()
defer m.mu.Unlock()
return m.synced
}

// BlockAtHeight returns the block at the given height.
Expand Down Expand Up @@ -139,6 +146,10 @@ func (m *Manager) Subscribe(s modules.ConsensusSetSubscriber, ccID modules.Conse
return nil
}

func synced(timestamp stypes.Timestamp) bool {
return time.Since(time.Unix(int64(timestamp), 0)) <= maxSyncTime
}

// NewManager creates a new chain manager.
func NewManager(cs modules.ConsensusSet) (*Manager, error) {
height := cs.Height()
Expand All @@ -157,8 +168,8 @@ func NewManager(cs modules.ConsensusSet) (*Manager, error) {
Height: uint64(height),
},
},

close: make(chan struct{}),
synced: synced(block.Timestamp),
close: make(chan struct{}),
}

if err := cs.ConsensusSetSubscribe(m, modules.ConsensusChangeRecent, m.close); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions persist/sqlite/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,13 @@ func (s *Store) VerifyWalletKey(seedHash types.Hash256) error {

// ResetWallet resets the wallet to its initial state. This is used when a
// consensus subscription error occurs.
func (s *Store) ResetWallet() error {
func (s *Store) ResetWallet(seedHash types.Hash256) error {
return s.transaction(func(tx txn) error {
if _, err := tx.Exec(`DELETE FROM wallet_utxos`); err != nil {
return fmt.Errorf("failed to delete wallet utxos: %w", err)
} else if _, err := tx.Exec(`DELETE FROM wallet_transactions`); err != nil {
return fmt.Errorf("failed to delete wallet transactions: %w", err)
} else if _, err := tx.Exec(`UPDATE global_settings SET wallet_last_processed_change=NULL, wallet_height=NULL`); err != nil {
} else if _, err := tx.Exec(`UPDATE global_settings SET wallet_last_processed_change=NULL, wallet_height=NULL, wallet_hash=?`, sqlHash256(seedHash)); err != nil {
return fmt.Errorf("failed to reset wallet settings: %w", err)
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion wallet/persist.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type (
UpdateWallet(ccID modules.ConsensusChangeID, height uint64, fn func(UpdateTransaction) error) error
// ResetWallet resets the wallet to its initial state. This is used when a
// consensus subscription error occurs.
ResetWallet() error
ResetWallet(seedHash types.Hash256) error
// VerifyWalletKey checks that the wallet seed matches the existing seed
// hash. This detects if the user's recovery phrase has changed and the
// wallet needs to rescan.
Expand Down
7 changes: 4 additions & 3 deletions wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -733,10 +733,11 @@ func NewSingleAddressWallet(priv types.PrivateKey, cm ChainManager, tp Transacti
return nil, fmt.Errorf("failed to get last wallet change: %w", err)
}

if err := store.VerifyWalletKey(types.HashBytes(priv[:])); errors.Is(err, ErrDifferentSeed) {
seedHash := types.HashBytes(priv[:])
if err := store.VerifyWalletKey(seedHash); errors.Is(err, ErrDifferentSeed) {
changeID = modules.ConsensusChangeBeginning
scanHeight = 0
if err := store.ResetWallet(); err != nil {
if err := store.ResetWallet(seedHash); err != nil {
return nil, fmt.Errorf("failed to reset wallet: %w", err)
}
log.Info("wallet reset due to seed change")
Expand Down Expand Up @@ -769,7 +770,7 @@ func NewSingleAddressWallet(priv types.PrivateKey, cm ChainManager, tp Transacti
sw.log.Error("failed to subscribe to consensus changes", zap.Error(err))
if errors.Is(err, chain.ErrInvalidChangeID) {
// reset change ID and subscribe again
if err := store.ResetWallet(); err != nil {
if err := store.ResetWallet(seedHash); err != nil {
sw.log.Fatal("failed to reset wallet", zap.Error(err))
} else if err = cm.Subscribe(sw, modules.ConsensusChangeBeginning, sw.tg.Done()); err != nil {
sw.log.Fatal("failed to reset consensus change subscription", zap.Error(err))
Expand Down

0 comments on commit 49d7f35

Please sign in to comment.