diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index 60bca6c7a..99cdd226a 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -1,20 +1,47 @@ // Copyright (c) 2018 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include +#include + +#include +#include namespace interfaces { namespace { - class ChainImpl : public Chain {}; + class LockImpl : public Chain::Lock {}; + + class LockingStateImpl : public LockImpl, + public UniqueLock { + using UniqueLock::UniqueLock; + }; + + class ChainImpl : public Chain { + public: + std::unique_ptr lock(bool try_lock) override { + auto result = std::make_unique( + ::cs_main, "cs_main", __FILE__, __LINE__, try_lock); + if (try_lock && result && !*result) { + return {}; + } + // std::move necessary on some compilers due to conversion from + // LockingStateImpl to Lock pointer + return std::move(result); + } + std::unique_ptr assumeLocked() override { + return std::make_unique(); + } + }; } // namespace std::unique_ptr MakeChain() { return std::make_unique(); } } // namespace interfaces diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index 1a03a7705..dd3304bba 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -1,43 +1,62 @@ // Copyright (c) 2018 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_INTERFACES_CHAIN_H #define BITCOIN_INTERFACES_CHAIN_H #include #include #include namespace interfaces { //! Interface for giving wallet processes access to blockchain state. class Chain { public: virtual ~Chain() {} + + //! Interface for querying locked chain state, used by legacy code that + //! assumes state won't change between calls. New code should avoid using + //! the Lock interface and instead call higher-level Chain methods + //! that return more information so the chain doesn't need to stay locked + //! between calls. + class Lock { + public: + virtual ~Lock() {} + }; + + //! Return Lock interface. Chain is locked when this is called, and + //! unlocked when the returned interface is freed. + virtual std::unique_ptr lock(bool try_lock = false) = 0; + + //! Return Lock interface assuming chain is already locked. This + //! method is temporary and is only used in a few places to avoid changing + //! behavior while code is transitioned to use the Chain::Lock interface. + virtual std::unique_ptr assumeLocked() = 0; }; //! Interface to let node manage chain clients (wallets, or maybe tools for //! monitoring and analysis in the future). class ChainClient { public: virtual ~ChainClient() {} }; //! Return implementation of Chain interface. std::unique_ptr MakeChain(); //! Return implementation of ChainClient interface for a wallet client. This //! function will be undefined in builds where ENABLE_WALLET is false. //! //! Currently, wallets are the only chain clients. But in the future, other //! types of chain clients could be added, such as tools for monitoring, //! analysis, or fee estimation. These clients need to expose their own //! MakeXXXClient functions returning their implementations of the ChainClient //! interface. std::unique_ptr MakeWalletClient(Chain &chain, std::vector wallet_filenames); } // namespace interfaces #endif // BITCOIN_INTERFACES_CHAIN_H diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index 8146c88f6..e3fa1ff9d 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -1,479 +1,496 @@ // Copyright (c) 2018 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include #include #include #include #include #include