diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -60,6 +60,10 @@ //! notifications to the GUI should go away when GUI and wallet can directly //! communicate with each other without going through the node //! (https://github.com/bitcoin/bitcoin/pull/15288#discussion_r253321096). +//! +//! * The handleRpc, registerRpcs, rpcEnableDeprecated methods and other RPC +//! methods can go away if wallets listen for HTTP requests on their own +//! ports instead of registering to handle requests on the node HTTP port. class Chain { public: virtual ~Chain() {} @@ -271,6 +275,17 @@ //! needs to remain valid until Handler is disconnected. virtual std::unique_ptr handleRpc(const CRPCCommand &command) = 0; + //! Check if deprecated RPC is enabled. + virtual bool rpcEnableDeprecated(const std::string &method) = 0; + + //! Run function after given number of seconds. Cancel any previous calls + //! with same name. + virtual void rpcRunLater(const std::string &name, std::function fn, + int64_t seconds) = 0; + + //! Current RPC serialization flags. + virtual int rpcSerializationFlags() = 0; + //! Synchronously send TransactionAddedToMempool notifications about all //! current mempool transactions to the specified handler and return after //! the last one is sent. These notifications aren't coordinated with async diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -378,6 +378,14 @@ handleRpc(const CRPCCommand &command) override { return std::make_unique(command); } + bool rpcEnableDeprecated(const std::string &method) override { + return IsDeprecatedRPCEnabled(gArgs, method); + } + void rpcRunLater(const std::string &name, std::function fn, + int64_t seconds) override { + RPCRunLater(name, std::move(fn), seconds); + } + int rpcSerializationFlags() override { return RPCSerializationFlags(); } void requestMempoolTransactions(Notifications ¬ifications) override { LOCK2(::cs_main, ::g_mempool.cs); for (const CTxMemPoolEntry &entry : ::g_mempool.mapTx) { diff --git a/src/policy/policy.h b/src/policy/policy.h --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -120,7 +120,8 @@ * @return True if all outputs (scriptPubKeys) use only standard transaction * forms */ -bool IsStandardTx(const CTransaction &tx, std::string &reason); +bool IsStandardTx(const CTransaction &tx, bool permit_bare_multisig, + const CFeeRate &dust_relay_fee, std::string &reason); /** * Check for standard transaction types @@ -142,4 +143,12 @@ int64_t GetVirtualTransactionInputSize(const CTxIn &txin, int64_t nSigOpCount, unsigned int bytes_per_sigop); +static inline int64_t GetVirtualTransactionSize(const CTransaction &tx) { + return GetVirtualTransactionSize(tx, 0, 0); +} + +static inline int64_t GetVirtualTransactionInputSize(const CTxIn &tx) { + return GetVirtualTransactionInputSize(tx, 0, 0); +} + #endif // BITCOIN_POLICY_POLICY_H diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -69,7 +69,8 @@ return true; } -bool IsStandardTx(const CTransaction &tx, std::string &reason) { +bool IsStandardTx(const CTransaction &tx, bool permit_bare_multisig, + const CFeeRate &dust_relay_fee, std::string &reason) { if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) { reason = "version"; return false; @@ -106,10 +107,10 @@ if (whichType == TX_NULL_DATA) { nDataOut++; - } else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) { + } else if ((whichType == TX_MULTISIG) && (!permit_bare_multisig)) { reason = "bare-multisig"; return false; - } else if (IsDust(txout, ::dustRelayFee)) { + } else if (IsDust(txout, dust_relay_fee)) { reason = "dust"; return false; } diff --git a/src/policy/settings.h b/src/policy/settings.h --- a/src/policy/settings.h +++ b/src/policy/settings.h @@ -11,15 +11,25 @@ #include class CFeeRate; +class CTransaction; // Policy settings which are configurable at runtime. extern CFeeRate dustRelayFee; extern uint32_t nBytesPerSigOp; extern bool fIsBareMultisigStd; +static inline bool IsStandardTx(const CTransaction &tx, std::string &reason) { + return IsStandardTx(tx, ::fIsBareMultisigStd, ::dustRelayFee, reason); +} + static inline int64_t GetVirtualTransactionSize(int64_t nSize, int64_t nSigOpCount) { return GetVirtualTransactionSize(nSize, nSigOpCount, ::nBytesPerSigOp); } +static inline int64_t GetVirtualTransactionSize(const CTransaction &tx, + int64_t sigop_cost) { + return GetVirtualTransactionSize(tx, sigop_cost, ::nBytesPerSigOp); +} + #endif // BITCOIN_POLICY_SETTINGS_H diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2127,7 +2127,8 @@ nullptr /* filter_label */); entry.pushKV("details", details); - std::string strHex = EncodeHexTx(*wtx.tx, RPCSerializationFlags()); + std::string strHex = + EncodeHexTx(*wtx.tx, pwallet->chain().rpcSerializationFlags()); entry.pushKV("hex", strHex); return entry; @@ -2379,7 +2380,7 @@ // wallet before the following callback is called. If a valid shared pointer // is acquired in the callback then the wallet is still loaded. std::weak_ptr weak_wallet = wallet; - RPCRunLater( + pwallet->chain().rpcRunLater( strprintf("lockwallet(%s)", pwallet->GetName()), [weak_wallet] { if (auto shared_wallet = weak_wallet.lock()) { diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1417,7 +1417,6 @@ } void CWallet::BlockUntilSyncedToCurrentChain() { - AssertLockNotHeld(cs_main); AssertLockNotHeld(cs_wallet); {