Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.h
Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
WalletCreationStatus CreateWallet(const CChainParams ¶ms, | WalletCreationStatus CreateWallet(const CChainParams ¶ms, | ||||
interfaces::Chain &chain, | interfaces::Chain &chain, | ||||
const SecureString &passphrase, | const SecureString &passphrase, | ||||
uint64_t wallet_creation_flags, | uint64_t wallet_creation_flags, | ||||
const std::string &name, std::string &error, | const std::string &name, std::string &error, | ||||
std::vector<std::string> &warnings, | std::vector<std::string> &warnings, | ||||
std::shared_ptr<CWallet> &result); | std::shared_ptr<CWallet> &result); | ||||
//! Default for -keypool | |||||
static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000; | |||||
//! -paytxfee default | //! -paytxfee default | ||||
constexpr Amount DEFAULT_PAY_TX_FEE = Amount::zero(); | constexpr Amount DEFAULT_PAY_TX_FEE = Amount::zero(); | ||||
//! -fallbackfee default | //! -fallbackfee default | ||||
static const Amount DEFAULT_FALLBACK_FEE = Amount::zero(); | static const Amount DEFAULT_FALLBACK_FEE = Amount::zero(); | ||||
//! -mintxfee default | //! -mintxfee default | ||||
static const Amount DEFAULT_TRANSACTION_MINFEE_PER_KB = 1000 * SATOSHI; | static const Amount DEFAULT_TRANSACTION_MINFEE_PER_KB = 1000 * SATOSHI; | ||||
//! minimum recommended increment for BIP 125 replacement txs | //! minimum recommended increment for BIP 125 replacement txs | ||||
static const Amount WALLET_INCREMENTAL_RELAY_FEE(5000 * SATOSHI); | static const Amount WALLET_INCREMENTAL_RELAY_FEE(5000 * SATOSHI); | ||||
Show All 38 Lines | static const std::map<std::string, WalletFlags> WALLET_FLAG_MAP{ | ||||
{"blank", WALLET_FLAG_BLANK_WALLET}, | {"blank", WALLET_FLAG_BLANK_WALLET}, | ||||
{"key_origin_metadata", WALLET_FLAG_KEY_ORIGIN_METADATA}, | {"key_origin_metadata", WALLET_FLAG_KEY_ORIGIN_METADATA}, | ||||
{"disable_private_keys", WALLET_FLAG_DISABLE_PRIVATE_KEYS}, | {"disable_private_keys", WALLET_FLAG_DISABLE_PRIVATE_KEYS}, | ||||
}; | }; | ||||
extern const std::map<uint64_t, std::string> WALLET_FLAG_CAVEATS; | extern const std::map<uint64_t, std::string> WALLET_FLAG_CAVEATS; | ||||
/** | /** | ||||
* A key from a CWallet's keypool | |||||
* | |||||
* The wallet holds one (for pre HD-split wallets) or several keypools. These | |||||
* are sets of keys that have not yet been used to provide addresses or receive | |||||
* change. | |||||
* | |||||
* The Bitcoin ABC wallet was originally a collection of unrelated private | |||||
* keys with their associated addresses. If a non-HD wallet generated a | |||||
* key/address, gave that address out and then restored a backup from before | |||||
* that key's generation, then any funds sent to that address would be | |||||
* lost definitively. | |||||
* | |||||
* The keypool was implemented to avoid this scenario (commit: 10384941). The | |||||
* wallet would generate a set of keys (100 by default). When a new public key | |||||
* was required, either to give out as an address or to use in a change output, | |||||
* it would be drawn from the keypool. The keypool would then be topped up to | |||||
* maintain 100 keys. This ensured that as long as the wallet hadn't used more | |||||
* than 100 keys since the previous backup, all funds would be safe, since a | |||||
* restored wallet would be able to scan for all owned addresses. | |||||
* | |||||
* A keypool also allowed encrypted wallets to give out addresses without | |||||
* having to be decrypted to generate a new private key. | |||||
* | |||||
* With the introduction of HD wallets (commit: f1902510), the keypool | |||||
* essentially became an address look-ahead pool. Restoring old backups can no | |||||
* longer definitively lose funds as long as the addresses used were from the | |||||
* wallet's HD seed (since all private keys can be rederived from the seed). | |||||
* However, if many addresses were used since the backup, then the wallet may | |||||
* not know how far ahead in the HD chain to look for its addresses. The | |||||
* keypool is used to implement a 'gap limit'. The keypool maintains a set of | |||||
* keys (by default 1000) ahead of the last used key and scans for the | |||||
* addresses of those keys. This avoids the risk of not seeing transactions | |||||
* involving the wallet's addresses, or of re-using the same address. | |||||
* | |||||
* The HD-split wallet feature added a second keypool (commit: 02592f4c). There | |||||
* is an external keypool (for addresses to hand out) and an internal keypool | |||||
* (for change addresses). | |||||
* | |||||
* Keypool keys are stored in the wallet/keystore's keymap. The keypool data is | |||||
* stored as sets of indexes in the wallet (setInternalKeyPool, | |||||
* setExternalKeyPool and set_pre_split_keypool), and a map from the key to the | |||||
* index (m_pool_key_to_index). The CKeyPool object is used to | |||||
* serialize/deserialize the pool data to/from the database. | |||||
*/ | |||||
class CKeyPool { | |||||
public: | |||||
//! The time at which the key was generated. Set in AddKeypoolPubKeyWithDB | |||||
int64_t nTime; | |||||
//! The public key | |||||
CPubKey vchPubKey; | |||||
//! Whether this keypool entry is in the internal keypool (for change | |||||
//! outputs) | |||||
bool fInternal; | |||||
//! Whether this key was generated for a keypool before the wallet was | |||||
//! upgraded to HD-split | |||||
bool m_pre_split; | |||||
CKeyPool(); | |||||
CKeyPool(const CPubKey &vchPubKeyIn, bool internalIn); | |||||
ADD_SERIALIZE_METHODS; | |||||
template <typename Stream, typename Operation> | |||||
inline void SerializationOp(Stream &s, Operation ser_action) { | |||||
int nVersion = s.GetVersion(); | |||||
if (!(s.GetType() & SER_GETHASH)) { | |||||
READWRITE(nVersion); | |||||
} | |||||
READWRITE(nTime); | |||||
READWRITE(vchPubKey); | |||||
if (ser_action.ForRead()) { | |||||
try { | |||||
READWRITE(fInternal); | |||||
} catch (std::ios_base::failure &) { | |||||
/** | |||||
* flag as external address if we can't read the internal | |||||
* boolean (this will be the case for any wallet before the HD | |||||
* chain split version) | |||||
*/ | |||||
fInternal = false; | |||||
} | |||||
try { | |||||
READWRITE(m_pre_split); | |||||
} catch (std::ios_base::failure &) { | |||||
/** | |||||
* flag as postsplit address if we can't read the m_pre_split | |||||
* boolean (this will be the case for any wallet that upgrades | |||||
* to HD chain split) | |||||
*/ | |||||
m_pre_split = false; | |||||
} | |||||
} else { | |||||
READWRITE(fInternal); | |||||
READWRITE(m_pre_split); | |||||
} | |||||
} | |||||
}; | |||||
/** | |||||
* A wrapper to reserve an address from a wallet | * A wrapper to reserve an address from a wallet | ||||
* | * | ||||
* ReserveDestination is used to reserve an address. | * ReserveDestination is used to reserve an address. | ||||
* It is currently only used inside of CreateTransaction. | * It is currently only used inside of CreateTransaction. | ||||
* | * | ||||
* Instantiating a ReserveDestination does not reserve an address. To do so, | * Instantiating a ReserveDestination does not reserve an address. To do so, | ||||
* GetReservedDestination() needs to be called on the object. Once an address | * GetReservedDestination() needs to be called on the object. Once an address | ||||
* has been reserved, call KeepDestination() on the ReserveDestination object to | * has been reserved, call KeepDestination() on the ReserveDestination object to | ||||
▲ Show 20 Lines • Show All 1,467 Lines • Show Last 20 Lines |