Skip to content

Commit

Permalink
birthday: Set correctly for existing wallets.
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeGruffins committed Nov 5, 2024
1 parent 1d9f076 commit ad3b010
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 4 deletions.
4 changes: 4 additions & 0 deletions chain/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,10 @@ func (s *Syncer) Run(ctx context.Context) (err error) {
log.Infof("Transactions synced through block %v height %d", &tipHash, tipHeight)
}

if err := s.wallet.CheckBirthState(ctx, rescanPoint); err != nil {
return err
}

err = s.waitRPCSync(ctx, int64(tipHeight))
if err != nil {
return err
Expand Down
5 changes: 5 additions & 0 deletions spv/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -1774,6 +1774,11 @@ func (s *Syncer) initialSyncRescan(ctx context.Context) error {
if err != nil {
return err
}

if err := s.wallet.CheckBirthState(ctx, rescanPoint); err != nil {
return err
}

if rescanPoint == nil {
// The wallet is already up to date with transactions in all
// blocks. Load the data filters to check for transactions in
Expand Down
9 changes: 7 additions & 2 deletions wallet/rescan.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,9 +497,13 @@ func (w *Wallet) rescanPoint(dbtx walletdb.ReadTx) (*chainhash.Hash, error) {
return &rescanPoint, nil
}

// SetBirthState sets the birthday state in the database.
// SetBirthState sets the birthday state in the database. This should be called
// before syncing is started.
func (w *Wallet) SetBirthState(ctx context.Context, bs *udb.BirthdayState) error {
const op errors.Op = "wallet.SetBirthState"
if bs == nil {
return errors.E(op, errors.Invalid, "nil birthday state")
}
err := walletdb.Update(ctx, w.db, func(dbtx walletdb.ReadWriteTx) error {
return udb.SetBirthState(dbtx, bs)
})
Expand All @@ -509,7 +513,8 @@ func (w *Wallet) SetBirthState(ctx context.Context, bs *udb.BirthdayState) error
return nil
}

// BirthState returns the birthday state.
// BirthState returns the birthday state. Will return a nil state if none has
// been set.
func (w *Wallet) BirthState(ctx context.Context) (bs *udb.BirthdayState, err error) {
const op errors.Op = "wallet.BirthState"
err = walletdb.View(ctx, w.db, func(dbtx walletdb.ReadTx) error {
Expand Down
6 changes: 4 additions & 2 deletions wallet/udb/txmined.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,8 @@ type BirthdayState struct {
SetFromHeight, SetFromTime bool
}

// SetBirthState sets the birthday state in the database.
// SetBirthState sets the birthday state in the database. *BirthdayState must
// not be nil.
//
// [0:1] Options (1 byte)
// [1:33] Birthblock block header hash (32 bytes)
Expand Down Expand Up @@ -361,7 +362,8 @@ func SetBirthState(dbtx walletdb.ReadWriteTx, bs *BirthdayState) error {
return ns.Put(rootBirthState, v)
}

// BirthState returns the current birthday state.
// BirthState returns the current birthday state. Will return nil if none has
// been set.
func BirthState(dbtx walletdb.ReadTx) *BirthdayState {
ns := dbtx.ReadBucket(wtxmgrBucketKey)
const (
Expand Down
81 changes: 81 additions & 0 deletions wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -5813,3 +5813,84 @@ func (w *Wallet) ProcessedTickets(ctx context.Context) ([]*VSPTicket, error) {

return managedTickets, nil
}

// CheckBirthState sets the wallet birthstate if required and if we already have
// enough info to do so.
func (w *Wallet) CheckBirthState(ctx context.Context, rescanPoint *chainhash.Hash) error {
birthState, err := w.BirthState(ctx)
if err != nil {
return err
}

if birthState != nil && (birthState.SetFromTime || birthState.SetFromHeight) {
var syncedHeader *wire.BlockHeader
if rescanPoint != nil {
syncedHeader, err = w.BlockHeader(ctx, rescanPoint)
if err != nil {
return err
}
} else {
tipHash, _ := w.MainChainTip(ctx)
syncedHeader, err = w.BlockHeader(ctx, &tipHash)
if err != nil {
return err
}
}
if birthState.SetFromTime {
if syncedHeader.Timestamp.After(birthState.Time) {
h := syncedHeader
for {
if h.Height == 0 {
bh := h.BlockHash()
birthState.Hash = bh
birthState.Height = 0
birthState.SetFromTime = false
if err := w.SetBirthState(ctx, birthState); err != nil {
return err
}
log.Infof("Set wallet birthday to block 0 (%v).", bh)
break
}
h, err = w.BlockHeader(ctx, &h.PrevBlock)
if err != nil {
return err
}
if h.Timestamp.Before(birthState.Time) {
bh := h.PrevBlock
height := h.Height - 1
birthState.Hash = bh
birthState.Height = height
birthState.SetFromTime = false
if err := w.SetBirthState(ctx, birthState); err != nil {
return err
}
log.Infof("Set wallet birthday to block %d (%v).", height, bh)
break
}
}
}
}
if birthState.SetFromHeight {
if syncedHeader.Height >= birthState.Height {
h := syncedHeader
for {
if h.Height == birthState.Height {
bh := h.BlockHash()
birthState.Hash = bh
birthState.SetFromHeight = false
if err := w.SetBirthState(ctx, birthState); err != nil {
return err
}
log.Infof("Set wallet birthday to block %d (%v).", h.Height, bh)
break
}
h, err = w.BlockHeader(ctx, &h.PrevBlock)
if err != nil {
return err
}
}
}
}
}
return nil
}

0 comments on commit ad3b010

Please sign in to comment.