decred.org/dcrwallet/v3@v3.1.0/wallet/checkpoints.go (about)

     1  // Copyright (c) 2022 The Decred developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package wallet
     6  
     7  import (
     8  	"decred.org/dcrwallet/v3/errors"
     9  	"decred.org/dcrwallet/v3/wallet/walletdb"
    10  	"github.com/decred/dcrd/chaincfg/chainhash"
    11  	"github.com/decred/dcrd/wire"
    12  )
    13  
    14  func mustParseHash(s string) chainhash.Hash {
    15  	h, err := chainhash.NewHashFromStr(s)
    16  	if err != nil {
    17  		panic(err)
    18  	}
    19  	return *h
    20  }
    21  
    22  var testnet3block962928Hash = mustParseHash("0000004fd1b267fd39111d456ff557137824538e6f6776168600e56002e23b93")
    23  
    24  // CheckpointHash returns the block hash of a checkpoint block for the network
    25  // and height, or nil if there is no checkpoint.
    26  func CheckpointHash(network wire.CurrencyNet, height int32) *chainhash.Hash {
    27  	if network == wire.TestNet3 {
    28  		switch height {
    29  		case 962928:
    30  			return &testnet3block962928Hash
    31  		}
    32  	}
    33  	return nil
    34  }
    35  
    36  // BadCheckpoint returns whether a block hash violates a checkpoint rule for the
    37  // network and block height.
    38  func BadCheckpoint(network wire.CurrencyNet, hash *chainhash.Hash, height int32) bool {
    39  	ckpt := CheckpointHash(network, height)
    40  	if ckpt != nil && *ckpt != *hash {
    41  		return true
    42  	}
    43  	return false
    44  }
    45  
    46  func (w *Wallet) rollbackInvalidCheckpoints(dbtx walletdb.ReadWriteTx) error {
    47  	txmgrNs := dbtx.ReadWriteBucket(wtxmgrNamespaceKey)
    48  	var checkpoints []int32
    49  	if w.chainParams.Net == wire.TestNet3 {
    50  		checkpoints = []int32{962928}
    51  	}
    52  	for _, height := range checkpoints {
    53  		h, err := w.txStore.GetMainChainBlockHashForHeight(txmgrNs, height)
    54  		if errors.Is(err, errors.NotExist) {
    55  			continue
    56  		}
    57  		if err != nil {
    58  			return err
    59  		}
    60  		ckpt := CheckpointHash(w.chainParams.Net, height)
    61  		if h != *ckpt {
    62  			err := w.txStore.Rollback(dbtx, height)
    63  			if err != nil {
    64  				return err
    65  			}
    66  		}
    67  	}
    68  	return nil
    69  }