mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Merge pull request #4575 from Munkybooty/backports-0.19-pr7
Backports 0.19 pr7
This commit is contained in:
commit
9789a42088
@ -61,21 +61,15 @@ The title of the pull request should be prefixed by the component or area that
|
||||
the pull request affects. Valid areas as:
|
||||
|
||||
- *Consensus* for changes to consensus critical code
|
||||
- *Docs* for changes to the documentation
|
||||
- *Doc* for changes to the documentation
|
||||
- *Qt* for changes to dash-qt
|
||||
- *Log* Changes to log messages
|
||||
- *Mining* for changes to the mining code
|
||||
- *Net* or *P2P* for changes to the peer-to-peer network code
|
||||
- *Refactor* for structural changes that do not change behavior
|
||||
- *RPC/REST/ZMQ* for changes to the RPC, REST or ZMQ APIs
|
||||
- *Scripts and tools* for changes to the scripts and tools
|
||||
- *Tests* for changes to the unit tests or QA tests
|
||||
- *Trivial* should **only** be used for PRs that do not change generated
|
||||
executable code. Notably, refactors (change of function arguments and code
|
||||
reorganization) and changes in behavior should **not** be marked as trivial.
|
||||
Examples of trivial PRs are changes to:
|
||||
- comments
|
||||
- whitespace
|
||||
- variable names
|
||||
- logging and messages
|
||||
- *Test* for changes to the unit tests or QA tests
|
||||
- *Utils and libraries* for changes to the utils and libraries
|
||||
- *Wallet* for changes to the wallet code
|
||||
|
||||
@ -84,10 +78,10 @@ Examples:
|
||||
Consensus: Add new opcode for BIP-XXXX OP_CHECKAWESOMESIG
|
||||
Net: Automatically create hidden service, listen on Tor
|
||||
Qt: Add feed bump button
|
||||
Trivial: Fix typo in init.cpp
|
||||
Log: Fix typo in log message
|
||||
|
||||
Note that translations should not be submitted as pull requests, please see
|
||||
[Translation Process](https://github.com/dashpay/dash/blob/master/doc/translation_process.md)
|
||||
[Translation Process](https://github.com/dashpay/dash/blob/master/doc/translation_process.md)
|
||||
for more information on helping with translations.
|
||||
|
||||
If a pull request is not to be considered for merging (yet), please
|
||||
@ -424,7 +418,7 @@ The project leader is the release manager for each Dash Core release.
|
||||
Copyright
|
||||
---------
|
||||
|
||||
By contributing to this repository, you agree to license your work under the
|
||||
MIT license unless specified otherwise in `contrib/debian/copyright` or at
|
||||
the top of the file itself. Any work contributed where you are not the original
|
||||
By contributing to this repository, you agree to license your work under the
|
||||
MIT license unless specified otherwise in `contrib/debian/copyright` or at
|
||||
the top of the file itself. Any work contributed where you are not the original
|
||||
author must contain its license header with the original author(s) and source.
|
||||
|
@ -43,6 +43,7 @@ $(package)_config_opts += -no-freetype
|
||||
$(package)_config_opts += -no-gif
|
||||
$(package)_config_opts += -no-glib
|
||||
$(package)_config_opts += -no-icu
|
||||
$(package)_config_opts += -no-ico
|
||||
$(package)_config_opts += -no-iconv
|
||||
$(package)_config_opts += -no-kms
|
||||
$(package)_config_opts += -no-linuxfb
|
||||
@ -79,19 +80,35 @@ $(package)_config_opts += -qt-harfbuzz
|
||||
$(package)_config_opts += -system-zlib
|
||||
$(package)_config_opts += -static
|
||||
$(package)_config_opts += -v
|
||||
$(package)_config_opts += -no-feature-bearermanagement
|
||||
$(package)_config_opts += -no-feature-colordialog
|
||||
$(package)_config_opts += -no-feature-commandlineparser
|
||||
$(package)_config_opts += -no-feature-concurrent
|
||||
$(package)_config_opts += -no-feature-dial
|
||||
$(package)_config_opts += -no-feature-filesystemwatcher
|
||||
$(package)_config_opts += -no-feature-fontcombobox
|
||||
$(package)_config_opts += -no-feature-ftp
|
||||
$(package)_config_opts += -no-feature-image_heuristic_mask
|
||||
$(package)_config_opts += -no-feature-keysequenceedit
|
||||
$(package)_config_opts += -no-feature-lcdnumber
|
||||
$(package)_config_opts += -no-feature-pdf
|
||||
$(package)_config_opts += -no-feature-printer
|
||||
$(package)_config_opts += -no-feature-printdialog
|
||||
$(package)_config_opts += -no-feature-concurrent
|
||||
$(package)_config_opts += -no-feature-printer
|
||||
$(package)_config_opts += -no-feature-printpreviewdialog
|
||||
$(package)_config_opts += -no-feature-printpreviewwidget
|
||||
$(package)_config_opts += -no-feature-sessionmanager
|
||||
$(package)_config_opts += -no-feature-sql
|
||||
$(package)_config_opts += -no-feature-statemachine
|
||||
$(package)_config_opts += -no-feature-syntaxhighlighter
|
||||
$(package)_config_opts += -no-feature-textbrowser
|
||||
$(package)_config_opts += -no-feature-textodfwriter
|
||||
$(package)_config_opts += -no-feature-topleveldomain
|
||||
$(package)_config_opts += -no-feature-udpsocket
|
||||
$(package)_config_opts += -no-feature-undocommand
|
||||
$(package)_config_opts += -no-feature-undogroup
|
||||
$(package)_config_opts += -no-feature-undostack
|
||||
$(package)_config_opts += -no-feature-undoview
|
||||
$(package)_config_opts += -no-feature-vnc
|
||||
$(package)_config_opts += -no-feature-wizard
|
||||
$(package)_config_opts += -no-feature-xml
|
||||
|
||||
@ -116,7 +133,6 @@ $(package)_config_opts_linux += -qt-xcb
|
||||
$(package)_config_opts_linux += -no-xcb-xlib
|
||||
$(package)_config_opts_linux += -no-feature-xlib
|
||||
$(package)_config_opts_linux += -system-freetype
|
||||
$(package)_config_opts_linux += -no-feature-sessionmanager
|
||||
$(package)_config_opts_linux += -fontconfig
|
||||
$(package)_config_opts_linux += -no-opengl
|
||||
$(package)_config_opts_linux += -dbus-runtime
|
||||
|
@ -12,7 +12,7 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.18.0**):
|
||||
* [`BIP 31`](https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki): The 'pong' protocol message (and the protocol version bump to 60001) has been implemented since **v0.6.1** ([PR #1081](https://github.com/bitcoin/bitcoin/pull/1081)).
|
||||
* [`BIP 32`](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki): Hierarchical Deterministic Wallets has been implemented since **v0.13.0** ([PR #8035](https://github.com/bitcoin/bitcoin/pull/8035)).
|
||||
* [`BIP 34`](https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki): The rule that requires blocks to contain their height (number) in the coinbase input, and the introduction of version 2 blocks has been implemented since **v0.7.0**. The rule took effect for version 2 blocks as of *block 224413* (March 5th 2013), and version 1 blocks are no longer allowed since *block 227931* (March 25th 2013) ([PR #1526](https://github.com/bitcoin/bitcoin/pull/1526)).
|
||||
* [`BIP 35`](https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki): The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since **v0.7.0** ([PR #1641](https://github.com/bitcoin/bitcoin/pull/1641)).
|
||||
* [`BIP 35`](https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki): The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since **v0.7.0** ([PR #1641](https://github.com/bitcoin/bitcoin/pull/1641)). As of **v0.13.0**, this is only available for `NODE_BLOOM` (BIP 111) peers.
|
||||
* [`BIP 37`](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki): The bloom filtering for transaction relaying, partial Merkle trees for blocks, and the protocol version bump to 70001 (enabling low-bandwidth SPV clients) has been implemented since **v0.8.0** ([PR #1795](https://github.com/bitcoin/bitcoin/pull/1795)).
|
||||
* [`BIP 42`](https://github.com/bitcoin/bips/blob/master/bip-0042.mediawiki): The bug that would have caused the subsidy schedule to resume after block 13440000 was fixed in **v0.9.2** ([PR #3842](https://github.com/bitcoin/bitcoin/pull/3842)).
|
||||
* [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)). Starting *v0.16.0*, whether to send reject messages can be configured with the `-enablebip61` option.
|
||||
|
@ -444,7 +444,7 @@ libdash_server_a_SOURCES += dummywallet.cpp
|
||||
endif
|
||||
|
||||
if ENABLE_ZMQ
|
||||
libdash_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS)
|
||||
libdash_zmq_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS)
|
||||
libdash_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libdash_zmq_a_SOURCES = \
|
||||
zmq/zmqabstractnotifier.cpp \
|
||||
|
@ -309,7 +309,7 @@ public:
|
||||
fDefaultConsistencyChecks = false;
|
||||
fRequireStandard = true;
|
||||
fRequireRoutableExternalIP = true;
|
||||
fMineBlocksOnDemand = false;
|
||||
m_is_test_chain = false;
|
||||
fAllowMultipleAddressesFromGroup = false;
|
||||
fAllowMultiplePorts = false;
|
||||
nLLMQConnectionRetryTimeout = 60;
|
||||
@ -522,7 +522,7 @@ public:
|
||||
fDefaultConsistencyChecks = false;
|
||||
fRequireStandard = false;
|
||||
fRequireRoutableExternalIP = true;
|
||||
fMineBlocksOnDemand = false;
|
||||
m_is_test_chain = true;
|
||||
fAllowMultipleAddressesFromGroup = false;
|
||||
fAllowMultiplePorts = true;
|
||||
nLLMQConnectionRetryTimeout = 60;
|
||||
@ -553,7 +553,6 @@ public:
|
||||
// (the tx=... number in the ChainStateFlushed debug.log lines)
|
||||
0.01 // * estimated number of transactions per second after that timestamp
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@ -722,7 +721,7 @@ public:
|
||||
fDefaultConsistencyChecks = false;
|
||||
fRequireStandard = false;
|
||||
fRequireRoutableExternalIP = true;
|
||||
fMineBlocksOnDemand = false;
|
||||
m_is_test_chain = true;
|
||||
fAllowMultipleAddressesFromGroup = true;
|
||||
fAllowMultiplePorts = true;
|
||||
nLLMQConnectionRetryTimeout = 60;
|
||||
@ -904,9 +903,9 @@ public:
|
||||
vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds.
|
||||
|
||||
fDefaultConsistencyChecks = true;
|
||||
fRequireStandard = false;
|
||||
fRequireStandard = true;
|
||||
fRequireRoutableExternalIP = false;
|
||||
fMineBlocksOnDemand = true;
|
||||
m_is_test_chain = true;
|
||||
fAllowMultipleAddressesFromGroup = true;
|
||||
fAllowMultiplePorts = true;
|
||||
nLLMQConnectionRetryTimeout = 1; // must be lower then the LLMQ signing session timeout so that tests have control over failing behavior
|
||||
|
@ -71,13 +71,15 @@ public:
|
||||
bool RequireStandard() const { return fRequireStandard; }
|
||||
/** Require addresses specified with "-externalip" parameter to be routable */
|
||||
bool RequireRoutableExternalIP() const { return fRequireRoutableExternalIP; }
|
||||
/** If this chain is exclusively used for testing */
|
||||
bool IsTestChain() const { return m_is_test_chain; }
|
||||
uint64_t PruneAfterHeight() const { return nPruneAfterHeight; }
|
||||
/** Minimum free space (in GB) needed for data directory */
|
||||
uint64_t AssumedBlockchainSize() const { return m_assumed_blockchain_size; }
|
||||
/** Minimum free space (in GB) needed for data directory when pruned; Does not include prune target*/
|
||||
uint64_t AssumedChainStateSize() const { return m_assumed_chain_state_size; }
|
||||
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
|
||||
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
|
||||
/** Whether it is possible to mine blocks on demand (no retargeting) */
|
||||
bool MineBlocksOnDemand() const { return consensus.fPowNoRetargeting; }
|
||||
/** Allow multiple addresses to be selected from the same network group (e.g. 192.168.x.x) */
|
||||
bool AllowMultipleAddressesFromGroup() const { return fAllowMultipleAddressesFromGroup; }
|
||||
/** Allow nodes with the same address and multiple ports */
|
||||
@ -130,7 +132,7 @@ protected:
|
||||
bool fDefaultConsistencyChecks;
|
||||
bool fRequireStandard;
|
||||
bool fRequireRoutableExternalIP;
|
||||
bool fMineBlocksOnDemand;
|
||||
bool m_is_test_chain;
|
||||
bool fAllowMultipleAddressesFromGroup;
|
||||
bool fAllowMultiplePorts;
|
||||
int nLLMQConnectionRetryTimeout;
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* CBaseChainParams defines the base parameters (shared between dash-cli and dashd)
|
||||
|
@ -1494,8 +1494,9 @@ bool AppInitParameterInteraction()
|
||||
}
|
||||
|
||||
fRequireStandard = !gArgs.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
|
||||
if (chainparams.RequireStandard() && !fRequireStandard)
|
||||
if (!chainparams.IsTestChain() && !fRequireStandard) {
|
||||
return InitError(strprintf("acceptnonstdtxn is not currently supported for %s chain", chainparams.NetworkIDString()));
|
||||
}
|
||||
nBytesPerSigOp = gArgs.GetArg("-bytespersigop", nBytesPerSigOp);
|
||||
|
||||
if (!g_wallet_init_interface.ParameterInteraction()) return false;
|
||||
@ -2130,7 +2131,9 @@ bool AppInitMain(InitInterfaces& interfaces)
|
||||
break;
|
||||
}
|
||||
|
||||
ResetBlockFailureFlags(nullptr);
|
||||
if (gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL) >= 3) {
|
||||
ResetBlockFailureFlags(nullptr);
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
LogPrintf("%s\n", e.what());
|
||||
|
@ -26,7 +26,8 @@
|
||||
#ifdef ENABLE_WALLET
|
||||
#include <qt/paymentserver.h>
|
||||
#include <qt/walletcontroller.h>
|
||||
#endif
|
||||
#include <qt/walletmodel.h>
|
||||
#endif // ENABLE_WALLET
|
||||
|
||||
#include <interfaces/handler.h>
|
||||
#include <interfaces/node.h>
|
||||
@ -219,12 +220,6 @@ BitcoinApplication::~BitcoinApplication()
|
||||
|
||||
delete window;
|
||||
window = nullptr;
|
||||
#ifdef ENABLE_WALLET
|
||||
delete paymentServer;
|
||||
paymentServer = nullptr;
|
||||
delete m_wallet_controller;
|
||||
m_wallet_controller = nullptr;
|
||||
#endif
|
||||
// Delete Qt-settings if user clicked on "Reset Options"
|
||||
QSettings settings;
|
||||
if(optionsModel && optionsModel->resetSettingsOnShutdown){
|
||||
@ -344,24 +339,21 @@ void BitcoinApplication::initializeResult(bool success)
|
||||
{
|
||||
// Log this only after AppInitMain finishes, as then logging setup is guaranteed complete
|
||||
qInfo() << "Platform customization:" << gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM).c_str();
|
||||
#ifdef ENABLE_WALLET
|
||||
m_wallet_controller = new WalletController(m_node, optionsModel, this);
|
||||
#ifdef ENABLE_BIP70
|
||||
PaymentServer::LoadRootCAs();
|
||||
#endif
|
||||
if (paymentServer) {
|
||||
paymentServer->setOptionsModel(optionsModel);
|
||||
#ifdef ENABLE_BIP70
|
||||
connect(m_wallet_controller, &WalletController::coinsSent, paymentServer, &PaymentServer::fetchPaymentACK);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
clientModel = new ClientModel(m_node, optionsModel);
|
||||
window->setClientModel(clientModel);
|
||||
#ifdef ENABLE_WALLET
|
||||
window->setWalletController(m_wallet_controller);
|
||||
if (WalletModel::isWalletEnabled()) {
|
||||
m_wallet_controller = new WalletController(m_node, optionsModel, this);
|
||||
window->setWalletController(m_wallet_controller);
|
||||
if (paymentServer) {
|
||||
paymentServer->setOptionsModel(optionsModel);
|
||||
#ifdef ENABLE_BIP70
|
||||
PaymentServer::LoadRootCAs();
|
||||
connect(m_wallet_controller, &WalletController::coinsSent, paymentServer, &PaymentServer::fetchPaymentACK);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_WALLET
|
||||
|
||||
// If -min option passed, start window minimized (iconified) or minimized to tray
|
||||
if (!gArgs.GetBoolArg("-min", false)) {
|
||||
@ -579,8 +571,10 @@ int GuiMain(int argc, char* argv[])
|
||||
|
||||
// Start up the payment server early, too, so impatient users that click on
|
||||
// dash: links repeatedly have their payment requests routed to this process:
|
||||
app.createPaymentServer();
|
||||
#endif
|
||||
if (WalletModel::isWalletEnabled()) {
|
||||
app.createPaymentServer();
|
||||
}
|
||||
#endif // ENABLE_WALLET
|
||||
|
||||
/// 9. Main GUI initialization
|
||||
// Install global event filter that makes sure that out-of-focus labels do not contain text cursor.
|
||||
|
@ -269,9 +269,12 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||
return TransactionCreationFailed;
|
||||
}
|
||||
|
||||
// Reject absurdly high fee
|
||||
if (nFeeRequired > m_wallet->getDefaultMaxTxFee())
|
||||
// Reject absurdly high fee. (This can never happen because the
|
||||
// wallet never creates transactions with fee greater than
|
||||
// m_default_max_tx_fee. This merely a belt-and-suspenders check).
|
||||
if (nFeeRequired > m_wallet->getDefaultMaxTxFee()) {
|
||||
return AbsurdFee;
|
||||
}
|
||||
|
||||
return SendCoinsReturn(OK);
|
||||
}
|
||||
|
@ -771,7 +771,10 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
|
||||
|
||||
UniValue sendrawtransaction(const JSONRPCRequest& request)
|
||||
{
|
||||
const RPCHelpMan help{"sendrawtransaction", "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
|
||||
const RPCHelpMan help{"sendrawtransaction", "\nSubmit a raw transaction (serialized, hex-encoded) to local node and network.\n"
|
||||
"\nNote that the transaction will be sent unconditionally to all peers, so using this\n"
|
||||
"for manual rebroadcast may degrade privacy by leaking the transaction's origin, as\n"
|
||||
"nodes will normally not rebroadcast non-wallet transactions already in their mempool.\n"
|
||||
"\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n",
|
||||
{
|
||||
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
|
||||
|
@ -58,6 +58,9 @@ CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_contr
|
||||
// if we don't have enough data for estimateSmartFee, then use fallback fee
|
||||
feerate_needed = wallet.m_fallback_fee;
|
||||
if (feeCalc) feeCalc->reason = FeeReason::FALLBACK;
|
||||
|
||||
// directly return if fallback fee is disabled (feerate 0 == disabled)
|
||||
if (wallet.m_fallback_fee.GetFee(1000) == 0) return feerate_needed;
|
||||
}
|
||||
// Obey mempool min fee when using smart fee estimation
|
||||
CFeeRate min_mempool_feerate = wallet.chain().mempoolMinFee();
|
||||
|
@ -3,6 +3,7 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <init.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <net.h>
|
||||
|
@ -478,9 +478,9 @@ public:
|
||||
const std::string strUnableToLocateCoinJoin1 = "Unable to locate enough non-denominated funds for this transaction.";
|
||||
const std::string strUnableToLocateCoinJoin2 = "Unable to locate enough mixed funds for this transaction. CoinJoin uses exact denominated amounts to send funds, you might simply need to mix some more coins.";
|
||||
const std::string strTransactionTooLarge = "Transaction too large";
|
||||
const std::string strTransactionTooLargeForFeePolicy = "Transaction too large for fee policy";
|
||||
const std::string strChangeIndexOutOfRange = "Change index out of range";
|
||||
const std::string strExceededMaxTries = "Exceeded max tries.";
|
||||
const std::string strMaxFeeExceeded = "Fee exceeds maximum configured by -maxtxfee";
|
||||
|
||||
CreateTransactionTestSetup()
|
||||
{
|
||||
@ -886,13 +886,9 @@ BOOST_FIXTURE_TEST_CASE(CreateTransactionTest, CreateTransactionTestSetup)
|
||||
createOutputEntries(2935);
|
||||
BOOST_CHECK(CreateTransaction(vecOutputEntries, strTransactionTooLarge, false));
|
||||
|
||||
auto prevRate = minRelayTxFee;
|
||||
coinControl.m_feerate = prevRate;
|
||||
coinControl.fOverrideFeeRate = true;
|
||||
minRelayTxFee = CFeeRate(prevRate.GetFeePerK() * 10);
|
||||
BOOST_CHECK(CreateTransaction({{5000, false}}, strTransactionTooLargeForFeePolicy, false));
|
||||
coinControl.m_feerate.reset();
|
||||
minRelayTxFee = prevRate;
|
||||
wallet->m_default_max_tx_fee = 0;
|
||||
BOOST_CHECK(CreateTransaction({{5000, false}}, strMaxFeeExceeded, false));
|
||||
wallet->m_default_max_tx_fee = DEFAULT_TRANSACTION_MAXFEE;
|
||||
|
||||
BOOST_CHECK(CreateTransaction({{5000, false}, {5000, false}, {5000, false}}, strChangeIndexOutOfRange, 4, false));
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string&
|
||||
return LoadWallet(chain, WalletLocation(name), error, warning);
|
||||
}
|
||||
|
||||
const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
||||
const uint256 CWalletTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
||||
|
||||
/** @defgroup mapWallet
|
||||
*
|
||||
@ -3236,11 +3236,6 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
|
||||
}
|
||||
}
|
||||
|
||||
if (nFeeRet > m_default_max_tx_fee) {
|
||||
strFailReason = TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3722,13 +3717,6 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||
|
||||
nFee = GetMinimumFee(*this, nBytes, coin_control, &feeCalc);
|
||||
|
||||
// If we made it here and we aren't even able to meet the relay fee on the next pass, give up
|
||||
// because we must be at the maximum allowed fee.
|
||||
if (nFee < ::minRelayTxFee.GetFee(nBytes)) {
|
||||
strFailReason = _("Transaction too large for fee policy");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -3836,6 +3824,12 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||
}
|
||||
}
|
||||
|
||||
if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) {
|
||||
// eventually allow a fallback fee
|
||||
strFailReason = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nAmountLeft == nFeeRet) {
|
||||
// We either added the change amount to nFeeRet because the change amount was considered
|
||||
// to be dust or the input exactly matches output + fee.
|
||||
@ -3894,6 +3888,11 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||
tx = MakeTransactionRef(std::move(txNew));
|
||||
}
|
||||
|
||||
if (nFeeRet > m_default_max_tx_fee) {
|
||||
strFailReason = TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
|
||||
// Lastly, ensure this tx will pass the mempool's chain limits
|
||||
if (!chain().checkChainLimits(tx)) {
|
||||
@ -5094,8 +5093,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
walletInstance->m_min_fee = CFeeRate(n);
|
||||
}
|
||||
|
||||
// TODO: enable when IsFallbackFeeEnabled is backported
|
||||
// walletInstance->m_allow_fallback_fee = Params().IsFallbackFeeEnabled();
|
||||
walletInstance->m_allow_fallback_fee = Params().IsTestChain();
|
||||
if (gArgs.IsArgSet("-fallbackfee")) {
|
||||
CAmount nFeePerK = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) {
|
||||
@ -5508,7 +5506,7 @@ CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn, bool fInternalIn)
|
||||
fInternal = fInternalIn;
|
||||
}
|
||||
|
||||
void CMerkleTx::SetMerkleBranch(const uint256& block_hash, int posInBlock)
|
||||
void CWalletTx::SetMerkleBranch(const uint256& block_hash, int posInBlock)
|
||||
{
|
||||
// Update the tx's hashBlock
|
||||
hashBlock = block_hash;
|
||||
@ -5517,7 +5515,7 @@ void CMerkleTx::SetMerkleBranch(const uint256& block_hash, int posInBlock)
|
||||
nIndex = posInBlock;
|
||||
}
|
||||
|
||||
int CMerkleTx::GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const
|
||||
int CWalletTx::GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const
|
||||
{
|
||||
if (hashUnset())
|
||||
return 0;
|
||||
@ -5525,7 +5523,7 @@ int CMerkleTx::GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const
|
||||
return locked_chain.getBlockDepth(hashBlock) * (nIndex == -1 ? -1 : 1);
|
||||
}
|
||||
|
||||
bool CMerkleTx::IsLockedByInstantSend() const
|
||||
bool CWalletTx::IsLockedByInstantSend() const
|
||||
{
|
||||
if (fIsChainlocked) {
|
||||
fIsInstantSendLocked = false;
|
||||
@ -5535,7 +5533,7 @@ bool CMerkleTx::IsLockedByInstantSend() const
|
||||
return fIsInstantSendLocked;
|
||||
}
|
||||
|
||||
bool CMerkleTx::IsChainLocked() const
|
||||
bool CWalletTx::IsChainLocked() const
|
||||
{
|
||||
if (!fIsChainlocked) {
|
||||
AssertLockHeld(cs_main);
|
||||
@ -5547,7 +5545,7 @@ bool CMerkleTx::IsChainLocked() const
|
||||
return fIsChainlocked;
|
||||
}
|
||||
|
||||
int CMerkleTx::GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const
|
||||
int CWalletTx::GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const
|
||||
{
|
||||
if (!IsCoinBase())
|
||||
return 0;
|
||||
@ -5556,7 +5554,7 @@ int CMerkleTx::GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const
|
||||
return std::max(0, (COINBASE_MATURITY+1) - chain_depth);
|
||||
}
|
||||
|
||||
bool CMerkleTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
|
||||
bool CWalletTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
|
||||
{
|
||||
// note GetBlocksToMaturity is 0 for non-coinbase tx
|
||||
return GetBlocksToMaturity(locked_chain) > 0;
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <interfaces/handler.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <saltedhasher.h>
|
||||
#include <streams.h>
|
||||
#include <script/ismine.h>
|
||||
#include <tinyformat.h>
|
||||
#include <ui_interface.h>
|
||||
@ -226,82 +225,24 @@ struct COutputEntry
|
||||
int vout;
|
||||
};
|
||||
|
||||
/** A transaction with a merkle branch linking it to the block chain. */
|
||||
/** Legacy class used for deserializing vtxPrev for backwards compatibility.
|
||||
* vtxPrev was removed in commit 93a18a3650292afbb441a47d1fa1b94aeb0164e3,
|
||||
* but old wallet.dat files may still contain vtxPrev vectors of CMerkleTxs.
|
||||
* These need to get deserialized for field alignment when deserializing
|
||||
* a CWalletTx, but the deserialized values are discarded.**/
|
||||
class CMerkleTx
|
||||
{
|
||||
private:
|
||||
/** Constant used in hashBlock to indicate tx has been abandoned */
|
||||
static const uint256 ABANDON_HASH;
|
||||
|
||||
mutable bool fIsChainlocked{false};
|
||||
mutable bool fIsInstantSendLocked{false};
|
||||
|
||||
public:
|
||||
CTransactionRef tx;
|
||||
uint256 hashBlock;
|
||||
|
||||
/* An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest
|
||||
* block in the chain we know this or any in-wallet dependency conflicts
|
||||
* with. Older clients interpret nIndex == -1 as unconfirmed for backward
|
||||
* compatibility.
|
||||
*/
|
||||
int nIndex;
|
||||
|
||||
CMerkleTx()
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
{
|
||||
SetTx(MakeTransactionRef());
|
||||
Init();
|
||||
CTransactionRef tx;
|
||||
uint256 hashBlock;
|
||||
std::vector<uint256> vMerkleBranch;
|
||||
int nIndex;
|
||||
|
||||
s >> tx >> hashBlock >> vMerkleBranch >> nIndex;
|
||||
}
|
||||
|
||||
explicit CMerkleTx(CTransactionRef arg)
|
||||
{
|
||||
SetTx(std::move(arg));
|
||||
Init();
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
hashBlock = uint256();
|
||||
nIndex = -1;
|
||||
}
|
||||
|
||||
void SetTx(CTransactionRef arg)
|
||||
{
|
||||
tx = std::move(arg);
|
||||
}
|
||||
|
||||
SERIALIZE_METHODS(CMerkleTx, obj)
|
||||
{
|
||||
std::vector<uint256> vMerkleBranch; // For compatibility with older versions.
|
||||
READWRITE(obj.tx, obj.hashBlock, vMerkleBranch, obj.nIndex);
|
||||
}
|
||||
|
||||
void SetMerkleBranch(const uint256& block_hash, int posInBlock);
|
||||
|
||||
/**
|
||||
* Return depth of transaction in blockchain:
|
||||
* <0 : conflicts with a transaction this deep in the blockchain
|
||||
* 0 : in memory pool, waiting to be included in a block
|
||||
* >=1 : this many blocks deep in the main chain
|
||||
*/
|
||||
int GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const;
|
||||
bool IsInMainChain(interfaces::Chain::Lock& locked_chain) const { return GetDepthInMainChain(locked_chain) > 0; }
|
||||
bool IsLockedByInstantSend() const;
|
||||
bool IsChainLocked() const;
|
||||
|
||||
/**
|
||||
* @return number of blocks to maturity for this transaction:
|
||||
* 0 : is not a coinbase transaction, or is a mature coinbase transaction
|
||||
* >0 : is a coinbase transaction which matures in this many blocks
|
||||
*/
|
||||
int GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const;
|
||||
bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
|
||||
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
|
||||
void setAbandoned() { hashBlock = ABANDON_HASH; }
|
||||
|
||||
const uint256& GetHash() const { return tx->GetHash(); }
|
||||
bool IsCoinBase() const { return tx->IsCoinBase(); }
|
||||
bool IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const;
|
||||
};
|
||||
|
||||
//Get the marginal bytes of spending the specified output
|
||||
@ -311,11 +252,17 @@ int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet,
|
||||
* A transaction with a bunch of additional info that only the owner cares about.
|
||||
* It includes any unrecorded transactions needed to link it back to the block chain.
|
||||
*/
|
||||
class CWalletTx : public CMerkleTx
|
||||
class CWalletTx
|
||||
{
|
||||
private:
|
||||
const CWallet* pwallet;
|
||||
|
||||
/** Constant used in hashBlock to indicate tx has been abandoned */
|
||||
static const uint256 ABANDON_HASH;
|
||||
|
||||
mutable bool fIsChainlocked{false};
|
||||
mutable bool fIsInstantSendLocked{false};
|
||||
|
||||
public:
|
||||
/**
|
||||
* Key/value map with information about the transaction.
|
||||
@ -373,7 +320,10 @@ public:
|
||||
mutable bool fInMempool;
|
||||
mutable CAmount nChangeCached;
|
||||
|
||||
CWalletTx(const CWallet* pwalletIn, CTransactionRef arg) : CMerkleTx(std::move(arg))
|
||||
CWalletTx(const CWallet* pwalletIn, CTransactionRef arg)
|
||||
: tx(std::move(arg)),
|
||||
hashBlock(uint256()),
|
||||
nIndex(-1)
|
||||
{
|
||||
Init(pwalletIn);
|
||||
}
|
||||
@ -393,10 +343,18 @@ public:
|
||||
nOrderPos = -1;
|
||||
}
|
||||
|
||||
CTransactionRef tx;
|
||||
uint256 hashBlock;
|
||||
/* An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest
|
||||
* block in the chain we know this or any in-wallet dependency conflicts
|
||||
* with. Older clients interpret nIndex == -1 as unconfirmed for backward
|
||||
* compatibility.
|
||||
*/
|
||||
int nIndex;
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const
|
||||
{
|
||||
char fSpent = false;
|
||||
mapValue_t mapValueCopy = mapValue;
|
||||
|
||||
mapValueCopy["fromaccount"] = "";
|
||||
@ -405,20 +363,21 @@ public:
|
||||
mapValueCopy["timesmart"] = strprintf("%u", nTimeSmart);
|
||||
}
|
||||
|
||||
s << static_cast<const CMerkleTx&>(*this);
|
||||
std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev
|
||||
s << vUnused << mapValueCopy << vOrderForm << fTimeReceivedIsTxTime << nTimeReceived << fFromMe << fSpent;
|
||||
std::vector<char> dummy_vector1; //!< Used to be vMerkleBranch
|
||||
std::vector<char> dummy_vector2; //!< Used to be vtxPrev
|
||||
char dummy_char = false; //!< Used to be fSpent
|
||||
s << tx << hashBlock << dummy_vector1 << nIndex << dummy_vector2 << mapValueCopy << vOrderForm << fTimeReceivedIsTxTime << nTimeReceived << fFromMe << dummy_char;
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
{
|
||||
Init(nullptr);
|
||||
char fSpent;
|
||||
|
||||
s >> static_cast<CMerkleTx&>(*this);
|
||||
std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev
|
||||
s >> vUnused >> mapValue >> vOrderForm >> fTimeReceivedIsTxTime >> nTimeReceived >> fFromMe >> fSpent;
|
||||
std::vector<uint256> dummy_vector1; //!< Used to be vMerkleBranch
|
||||
std::vector<CMerkleTx> dummy_vector2; //!< Used to be vtxPrev
|
||||
char dummy_char; //! Used to be fSpent
|
||||
s >> tx >> hashBlock >> dummy_vector1 >> nIndex >> dummy_vector2 >> mapValue >> vOrderForm >> fTimeReceivedIsTxTime >> nTimeReceived >> fFromMe >> dummy_char;
|
||||
|
||||
ReadOrderPos(nOrderPos, mapValue);
|
||||
nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;
|
||||
@ -429,6 +388,11 @@ public:
|
||||
mapValue.erase("timesmart");
|
||||
}
|
||||
|
||||
void SetTx(CTransactionRef arg)
|
||||
{
|
||||
tx = std::move(arg);
|
||||
}
|
||||
|
||||
//! make sure balances are recalculated
|
||||
void MarkDirty()
|
||||
{
|
||||
@ -500,6 +464,33 @@ public:
|
||||
// that we still have the runtime check "AssertLockHeld(pwallet->cs_wallet)"
|
||||
// in place.
|
||||
std::set<uint256> GetConflicts() const NO_THREAD_SAFETY_ANALYSIS;
|
||||
|
||||
void SetMerkleBranch(const uint256& block_hash, int posInBlock);
|
||||
|
||||
/**
|
||||
* Return depth of transaction in blockchain:
|
||||
* <0 : conflicts with a transaction this deep in the blockchain
|
||||
* 0 : in memory pool, waiting to be included in a block
|
||||
* >=1 : this many blocks deep in the main chain
|
||||
*/
|
||||
int GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const;
|
||||
bool IsInMainChain(interfaces::Chain::Lock& locked_chain) const { return GetDepthInMainChain(locked_chain) > 0; }
|
||||
bool IsLockedByInstantSend() const;
|
||||
bool IsChainLocked() const;
|
||||
|
||||
/**
|
||||
* @return number of blocks to maturity for this transaction:
|
||||
* 0 : is not a coinbase transaction, or is a mature coinbase transaction
|
||||
* >0 : is a coinbase transaction which matures in this many blocks
|
||||
*/
|
||||
int GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const;
|
||||
bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
|
||||
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
|
||||
void setAbandoned() { hashBlock = ABANDON_HASH; }
|
||||
|
||||
const uint256& GetHash() const { return tx->GetHash(); }
|
||||
bool IsCoinBase() const { return tx->IsCoinBase(); }
|
||||
bool IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const;
|
||||
};
|
||||
|
||||
struct WalletTxHasher
|
||||
|
@ -136,7 +136,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||
unspent = self.nodes[0].listunspent()
|
||||
tx = CTransaction()
|
||||
tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))]
|
||||
tx.vout = [CTxOut(10, scriptPubKey), CTxOut(11, scriptPubKey)]
|
||||
tx.vout = [CTxOut(10 * COIN, scriptPubKey), CTxOut(11 * COIN, scriptPubKey)]
|
||||
tx.rehash()
|
||||
|
||||
signed_tx = self.nodes[0].signrawtransactionwithwallet(tx.serialize().hex())
|
||||
@ -152,7 +152,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||
# Check that balances are correct
|
||||
self.log.info("Testing balances...")
|
||||
balance0 = self.nodes[1].getaddressbalance("93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB")
|
||||
assert_equal(balance0["balance"], 45 * 100000000 + 21)
|
||||
assert_equal(balance0["balance"], (45 + 21) * 100000000)
|
||||
|
||||
# Check that balances are correct after spending
|
||||
self.log.info("Testing balances after spending...")
|
||||
|
@ -21,7 +21,10 @@ NOT_FINAL_ERROR = "non-BIP68-final (code 64)"
|
||||
class BIP68Test(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 2
|
||||
self.extra_args = [[], ["-acceptnonstdtxn=0"]]
|
||||
self.extra_args = [
|
||||
["-acceptnonstdtxn=1"],
|
||||
["-acceptnonstdtxn=0"],
|
||||
]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
|
@ -82,7 +82,7 @@ class FullBlockTest(BitcoinTestFramework):
|
||||
# which causes RPC to hang, so we need to increase RPC timeouts
|
||||
self.rpc_timeout = 180
|
||||
# Must set '-dip3params=2000:2000' to create pre-dip3 blocks only
|
||||
self.extra_args = [['-dip3params=2000:2000']]
|
||||
self.extra_args = [['-dip3params=2000:2000', '-acceptnonstdtxn=1']] # This is a consensus block test, we don't care about tx policy
|
||||
|
||||
def setup_nodes(self):
|
||||
self.add_nodes(self.num_nodes, self.extra_args)
|
||||
|
@ -59,7 +59,12 @@ def cltv_validate(node, tx, height):
|
||||
class BIP65Test(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [['-whitelist=127.0.0.1', '-dip3params=9000:9000', '-par=1']] # Use only one script thread to get the exact reject reason for testing
|
||||
self.extra_args = [[
|
||||
'-whitelist=127.0.0.1',
|
||||
'-dip3params=9000:9000',
|
||||
'-par=1', # Use only one script thread to get the exact reject reason for testing
|
||||
'-acceptnonstdtxn=1', # cltv_invalidate is nonstandard
|
||||
]]
|
||||
self.setup_clean_chain = True
|
||||
self.rpc_timeout = 120
|
||||
|
||||
|
@ -40,6 +40,11 @@ class ConfArgsTest(BitcoinTestFramework):
|
||||
conf.write("wallet=foo\n")
|
||||
self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Config setting for -wallet only applied on regtest network when in [regtest] section.')
|
||||
|
||||
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
|
||||
conf.write('regtest=0\n') # mainnet
|
||||
conf.write('acceptnonstdtxn=1\n')
|
||||
self.nodes[0].assert_start_raises_init_error(expected_msg='Error: acceptnonstdtxn is not currently supported for main chain')
|
||||
|
||||
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
|
||||
conf.write('nono\n')
|
||||
self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 1: nono, if you intended to specify a negated option, use nono=1 instead')
|
||||
|
@ -19,6 +19,7 @@ DISABLED_OPCODE_ERROR = "non-mandatory-script-verify-flag (Attempted to use a di
|
||||
class DIP0020ActivationTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [["-acceptnonstdtxn=1"]]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
@ -31,7 +32,7 @@ class DIP0020ActivationTest(BitcoinTestFramework):
|
||||
utxos = self.node.listunspent()
|
||||
assert len(utxos) > 0
|
||||
|
||||
# Send some coins to a P2SH address constructed using disabled opcodes
|
||||
# Lock some coins using disabled opcodes
|
||||
utxo = utxos[len(utxos) - 1]
|
||||
value = int(satoshi_round(utxo["amount"] - self.relayfee) * COIN)
|
||||
tx = CTransaction()
|
||||
|
@ -126,9 +126,9 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||
self.num_nodes = 3
|
||||
# mine non-standard txs (e.g. txs with "dust" outputs)
|
||||
self.extra_args = [
|
||||
["-maxorphantxsize=1000", "-whitelist=127.0.0.1"],
|
||||
["-blockmaxsize=17000", "-maxorphantxsize=1000", "-whitelist=127.0.0.1"],
|
||||
["-blockmaxsize=8000", "-maxorphantxsize=1000", "-whitelist=127.0.0.1"]
|
||||
["-acceptnonstdtxn=1", "-maxorphantxsize=1000", "-whitelist=127.0.0.1"],
|
||||
["-acceptnonstdtxn=1", "-blockmaxsize=17000", "-maxorphantxsize=1000", "-whitelist=127.0.0.1"],
|
||||
["-acceptnonstdtxn=1", "-blockmaxsize=8000", "-maxorphantxsize=1000", "-whitelist=127.0.0.1"]
|
||||
]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
|
@ -35,7 +35,7 @@ class MaxUploadTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [["-maxuploadtarget=200", "-blockmaxsize=999000", "-maxtipage="+str(2*60*60*24*7)]]
|
||||
self.extra_args = [["-maxuploadtarget=200", "-blockmaxsize=999000", "-maxtipage="+str(2*60*60*24*7), "-acceptnonstdtxn=1"]]
|
||||
|
||||
# Cache for utxos, as the listunspent may take a long time later in the test
|
||||
self.utxo_cache = []
|
||||
|
@ -38,7 +38,6 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
|
||||
self.extra_args = [[
|
||||
'-txindex',
|
||||
'-reindex', # Need reindex for txindex
|
||||
'-acceptnonstdtxn=0', # Try to mimic main-net
|
||||
]] * self.num_nodes
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
|
@ -13,7 +13,11 @@ class MempoolLimitTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [["-maxmempool=5", "-spendzeroconfchange=0"]]
|
||||
self.extra_args = [[
|
||||
"-acceptnonstdtxn=1",
|
||||
"-maxmempool=5",
|
||||
"-spendzeroconfchange=0",
|
||||
]]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
|
@ -12,7 +12,10 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 2
|
||||
self.extra_args = [["-printpriority=1"]] * 2
|
||||
self.extra_args = [[
|
||||
"-printpriority=1",
|
||||
"-acceptnonstdtxn=1",
|
||||
]] * self.num_nodes
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
|
@ -93,7 +93,10 @@ class CompactBlocksTest(BitcoinTestFramework):
|
||||
self.setup_clean_chain = True
|
||||
# both nodes has the same version
|
||||
self.num_nodes = 2
|
||||
self.extra_args = [["-txindex"]] * 2
|
||||
self.extra_args = [[
|
||||
"-txindex",
|
||||
"-acceptnonstdtxn=1",
|
||||
]] * 2
|
||||
self.utxos = []
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
|
@ -27,6 +27,9 @@ class InvalidTxRequestTest(BitcoinTestFramework):
|
||||
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [[
|
||||
"-acceptnonstdtxn=1",
|
||||
]]
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def bootstrap_p2p(self, *, num_connections=1):
|
||||
@ -100,7 +103,7 @@ class InvalidTxRequestTest(BitcoinTestFramework):
|
||||
self.test_orphan_tx_handling(block1.vtx[0].sha256, False)
|
||||
|
||||
self.log.info('Test orphan transaction handling, resolve via block')
|
||||
self.restart_node(0, ['-persistmempool=0'])
|
||||
self.restart_node(0, ["-acceptnonstdtxn=1", '-persistmempool=0'])
|
||||
self.reconnect_p2p(num_connections=2)
|
||||
self.test_orphan_tx_handling(block2.vtx[0].sha256, True)
|
||||
|
||||
|
@ -42,11 +42,11 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
connect_nodes(self.nodes[0], 3)
|
||||
|
||||
def run_test(self):
|
||||
min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee']
|
||||
self.min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee']
|
||||
# This test is not meant to test fee estimation and we'd like
|
||||
# to be sure all txs are sent at a consistent desired feerate
|
||||
for node in self.nodes:
|
||||
node.settxfee(min_relay_tx_fee)
|
||||
node.settxfee(self.min_relay_tx_fee)
|
||||
|
||||
# if the fee's positive delta is higher than this value tests will fail,
|
||||
# neg. delta always fail the tests.
|
||||
@ -54,13 +54,42 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
# than a minimum sized signature.
|
||||
|
||||
# = 2 bytes * minRelayTxFeePerByte
|
||||
feeTolerance = 2 * min_relay_tx_fee/1000
|
||||
self.fee_tolerance = 2 * self.min_relay_tx_fee / 1000
|
||||
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all()
|
||||
self.nodes[0].generate(121)
|
||||
self.sync_all()
|
||||
|
||||
self.test_change_position()
|
||||
self.test_simple()
|
||||
self.test_simple_two_coins()
|
||||
self.test_simple_two_outputs()
|
||||
self.test_change()
|
||||
self.test_no_change()
|
||||
self.test_invalid_option()
|
||||
self.test_invalid_change_address()
|
||||
self.test_valid_change_address()
|
||||
self.test_coin_selection()
|
||||
self.test_two_vin()
|
||||
self.test_two_vin_two_vout()
|
||||
self.test_invalid_input()
|
||||
self.test_fee_p2pkh()
|
||||
self.test_fee_p2pkh_multi_out()
|
||||
self.test_fee_p2sh()
|
||||
self.test_fee_4of5()
|
||||
self.test_spend_2of2()
|
||||
self.test_locked_wallet()
|
||||
self.test_many_inputs_fee()
|
||||
self.test_many_inputs_send()
|
||||
self.test_op_return()
|
||||
self.test_watchonly()
|
||||
self.test_all_watched_funds()
|
||||
self.test_option_feerate()
|
||||
self.test_address_reuse()
|
||||
self.test_option_subtract_fee_from_outputs()
|
||||
|
||||
def test_change_position(self):
|
||||
# ensure that setting changePosition in fundraw with an exact match is handled properly
|
||||
rawmatch = self.nodes[2].createrawtransaction([], {self.nodes[2].getnewaddress():500})
|
||||
rawmatch = self.nodes[2].fundrawtransaction(rawmatch, {"changePosition":1, "subtractFeeFromOutputs":[0]})
|
||||
@ -68,15 +97,15 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
watchonly_address = self.nodes[0].getnewaddress()
|
||||
watchonly_pubkey = self.nodes[0].getaddressinfo(watchonly_address)["pubkey"]
|
||||
watchonly_amount = Decimal(2000)
|
||||
self.watchonly_amount = Decimal(2000)
|
||||
self.nodes[3].importpubkey(watchonly_pubkey, "", True)
|
||||
watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount)
|
||||
self.watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, self.watchonly_amount)
|
||||
|
||||
# Lock UTXO so nodes[0] doesn't accidentally spend it
|
||||
watchonly_vout = find_vout_for_address(self.nodes[0], watchonly_txid, watchonly_address)
|
||||
self.nodes[0].lockunspent(False, [{"txid": watchonly_txid, "vout": watchonly_vout}])
|
||||
self.watchonly_vout = find_vout_for_address(self.nodes[0], self.watchonly_txid, watchonly_address)
|
||||
self.nodes[0].lockunspent(False, [{"txid": self.watchonly_txid, "vout": self.watchonly_vout}])
|
||||
|
||||
self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10)
|
||||
self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), self.watchonly_amount / 10)
|
||||
|
||||
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 15)
|
||||
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
|
||||
@ -85,6 +114,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
def test_simple(self):
|
||||
###############
|
||||
# simple test #
|
||||
###############
|
||||
@ -93,10 +123,10 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
||||
fee = rawtxfund['fee']
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||
assert len(dec_tx['vin']) > 0 #test that we have enough inputs
|
||||
|
||||
def test_simple_two_coins(self):
|
||||
##############################
|
||||
# simple test with two coins #
|
||||
##############################
|
||||
@ -106,25 +136,11 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
|
||||
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
||||
fee = rawtxfund['fee']
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||
assert len(dec_tx['vin']) > 0 #test if we have enough inputs
|
||||
|
||||
##############################
|
||||
# simple test with two coins #
|
||||
##############################
|
||||
inputs = [ ]
|
||||
outputs = { self.nodes[0].getnewaddress() : 26 }
|
||||
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
|
||||
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
||||
fee = rawtxfund['fee']
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||
assert len(dec_tx['vin']) > 0
|
||||
assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
|
||||
|
||||
|
||||
def test_simple_two_outputs(self):
|
||||
################################
|
||||
# simple test with two outputs #
|
||||
################################
|
||||
@ -134,7 +150,6 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
|
||||
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
||||
fee = rawtxfund['fee']
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||
totalOut = 0
|
||||
for out in dec_tx['vout']:
|
||||
@ -143,7 +158,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert len(dec_tx['vin']) > 0
|
||||
assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
|
||||
|
||||
|
||||
def test_change(self):
|
||||
#########################################################################
|
||||
# test a fundrawtransaction with a VIN greater than the required amount #
|
||||
#########################################################################
|
||||
@ -157,6 +172,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
||||
fee = rawtxfund['fee']
|
||||
self.test_no_change_fee = fee # Use the same fee for the next tx
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||
totalOut = 0
|
||||
for out in dec_tx['vout']:
|
||||
@ -164,14 +180,14 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
|
||||
|
||||
|
||||
def test_no_change(self):
|
||||
#####################################################################
|
||||
# test a fundrawtransaction with which will not get a change output #
|
||||
#####################################################################
|
||||
utx = get_unspent(self.nodes[2].listunspent(), 50)
|
||||
|
||||
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
|
||||
outputs = { self.nodes[0].getnewaddress() : Decimal(50) - fee - feeTolerance }
|
||||
outputs = {self.nodes[0].getnewaddress(): Decimal(50) - self.test_no_change_fee - self.fee_tolerance}
|
||||
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
|
||||
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
|
||||
@ -186,7 +202,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_equal(rawtxfund['changepos'], -1)
|
||||
assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
|
||||
|
||||
|
||||
def test_invalid_option(self):
|
||||
####################################################
|
||||
# test a fundrawtransaction with an invalid option #
|
||||
####################################################
|
||||
@ -203,6 +219,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
# reserveChangeKey was deprecated and is now removed
|
||||
assert_raises_rpc_error(-3, "Unexpected key reserveChangeKey", lambda: self.nodes[2].fundrawtransaction(hexstring=rawtx, options={'reserveChangeKey': True}))
|
||||
|
||||
def test_invalid_change_address(self):
|
||||
############################################################
|
||||
# test a fundrawtransaction with an invalid change address #
|
||||
############################################################
|
||||
@ -216,6 +233,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
assert_raises_rpc_error(-5, "changeAddress must be a valid dash address", self.nodes[2].fundrawtransaction, rawtx, {'changeAddress':'foobar'})
|
||||
|
||||
def test_valid_change_address(self):
|
||||
############################################################
|
||||
# test a fundrawtransaction with a provided change address #
|
||||
############################################################
|
||||
@ -234,7 +252,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
out = dec_tx['vout'][0]
|
||||
assert_equal(change, out['scriptPubKey']['addresses'][0])
|
||||
|
||||
|
||||
def test_coin_selection(self):
|
||||
#########################################################################
|
||||
# test a fundrawtransaction with a VIN smaller than the required amount #
|
||||
#########################################################################
|
||||
@ -252,7 +270,6 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex'])
|
||||
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
||||
fee = rawtxfund['fee']
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||
totalOut = 0
|
||||
matchingOuts = 0
|
||||
@ -269,7 +286,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_equal(matchingOuts, 1)
|
||||
assert_equal(len(dec_tx['vout']), 2)
|
||||
|
||||
|
||||
def test_two_vin(self):
|
||||
###########################################
|
||||
# test a fundrawtransaction with two VINs #
|
||||
###########################################
|
||||
@ -283,7 +300,6 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
|
||||
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
||||
fee = rawtxfund['fee']
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||
totalOut = 0
|
||||
matchingOuts = 0
|
||||
@ -303,6 +319,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
assert_equal(matchingIns, 2) #we now must see two vins identical to vins given as params
|
||||
|
||||
def test_two_vin_two_vout(self):
|
||||
#########################################################
|
||||
# test a fundrawtransaction with two VINs and two vOUTs #
|
||||
#########################################################
|
||||
@ -316,7 +333,6 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
|
||||
|
||||
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
|
||||
fee = rawtxfund['fee']
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
|
||||
totalOut = 0
|
||||
matchingOuts = 0
|
||||
@ -328,16 +344,16 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_equal(matchingOuts, 2)
|
||||
assert_equal(len(dec_tx['vout']), 3)
|
||||
|
||||
def test_invalid_input(self):
|
||||
##############################################
|
||||
# test a fundrawtransaction with invalid vin #
|
||||
##############################################
|
||||
inputs = [ {'txid' : "1c7f966dab21119bac53213a2bc7532bff1fa844c124fd750a7d0b1332440bd1", 'vout' : 0} ] #invalid vin!
|
||||
outputs = { self.nodes[0].getnewaddress() : 10}
|
||||
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
|
||||
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
|
||||
|
||||
assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[2].fundrawtransaction, rawtx)
|
||||
|
||||
def test_fee_p2pkh(self):
|
||||
############################################################
|
||||
#compare fee of a standard pubkeyhash transaction
|
||||
inputs = []
|
||||
@ -351,9 +367,10 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
#compare fee
|
||||
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
|
||||
assert feeDelta >= 0 and feeDelta <= feeTolerance
|
||||
assert feeDelta >= 0 and feeDelta <= self.fee_tolerance
|
||||
############################################################
|
||||
|
||||
def test_fee_p2pkh_multi_out(self):
|
||||
############################################################
|
||||
#compare fee of a standard pubkeyhash transaction with multiple outputs
|
||||
inputs = []
|
||||
@ -366,10 +383,10 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
#compare fee
|
||||
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
|
||||
assert feeDelta >= 0 and feeDelta <= feeTolerance
|
||||
assert feeDelta >= 0 and feeDelta <= self.fee_tolerance
|
||||
############################################################
|
||||
|
||||
|
||||
def test_fee_p2sh(self):
|
||||
############################################################
|
||||
#compare fee of a 2of2 multisig p2sh transaction
|
||||
|
||||
@ -393,10 +410,10 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
#compare fee
|
||||
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
|
||||
assert feeDelta >= 0 and feeDelta <= feeTolerance
|
||||
assert feeDelta >= 0 and feeDelta <= self.fee_tolerance
|
||||
############################################################
|
||||
|
||||
|
||||
def test_fee_4of5(self):
|
||||
############################################################
|
||||
#compare fee of a standard pubkeyhash transaction
|
||||
|
||||
@ -426,10 +443,10 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
#compare fee
|
||||
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
|
||||
assert feeDelta >= 0 and feeDelta <= feeTolerance
|
||||
assert feeDelta >= 0 and feeDelta <= self.fee_tolerance
|
||||
############################################################
|
||||
|
||||
|
||||
def test_spend_2of2(self):
|
||||
############################################################
|
||||
# spend a 2of2 multisig transaction over fundraw
|
||||
|
||||
@ -444,7 +461,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
|
||||
# send 12 DASH to msig addr
|
||||
txId = self.nodes[0].sendtoaddress(mSigObj, 12)
|
||||
self.nodes[0].sendtoaddress(mSigObj, 12)
|
||||
self.sync_all()
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
@ -456,7 +473,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
fundedTx = self.nodes[2].fundrawtransaction(rawtx)
|
||||
|
||||
signedTx = self.nodes[2].signrawtransactionwithwallet(fundedTx['hex'])
|
||||
txId = self.nodes[2].sendrawtransaction(signedTx['hex'])
|
||||
self.nodes[2].sendrawtransaction(signedTx['hex'])
|
||||
self.sync_all()
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
@ -464,6 +481,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
# make sure funds are received at node1
|
||||
assert_equal(oldBalance+Decimal('11.0000000'), self.nodes[1].getbalance())
|
||||
|
||||
def test_locked_wallet(self):
|
||||
############################################################
|
||||
# locked wallet test
|
||||
self.nodes[1].encryptwallet("test")
|
||||
@ -473,7 +491,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
# This test is not meant to test fee estimation and we'd like
|
||||
# to be sure all txs are sent at a consistent desired feerate
|
||||
for node in self.nodes:
|
||||
node.settxfee(min_relay_tx_fee)
|
||||
node.settxfee(self.min_relay_tx_fee)
|
||||
|
||||
connect_nodes(self.nodes[0], 1)
|
||||
connect_nodes(self.nodes[1], 2)
|
||||
@ -481,7 +499,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
connect_nodes(self.nodes[0], 3)
|
||||
# Again lock the watchonly UTXO or nodes[0] may spend it, because
|
||||
# lockunspent is memory-only and thus lost on restart
|
||||
self.nodes[0].lockunspent(False, [{"txid": watchonly_txid, "vout": watchonly_vout}])
|
||||
self.nodes[0].lockunspent(False, [{"txid": self.watchonly_txid, "vout": self.watchonly_vout}])
|
||||
self.sync_all()
|
||||
|
||||
# drain the keypool
|
||||
@ -509,13 +527,14 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
#now we need to unlock
|
||||
self.nodes[1].walletpassphrase("test", 600)
|
||||
signedTx = self.nodes[1].signrawtransactionwithwallet(fundedTx['hex'])
|
||||
txId = self.nodes[1].sendrawtransaction(signedTx['hex'])
|
||||
self.nodes[1].sendrawtransaction(signedTx['hex'])
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
# make sure funds are received at node1
|
||||
assert_equal(oldBalance+Decimal('511.0000000'), self.nodes[0].getbalance())
|
||||
|
||||
def test_many_inputs_fee(self):
|
||||
###############################################
|
||||
# multiple (~19) inputs tx test | Compare fee #
|
||||
###############################################
|
||||
@ -543,9 +562,9 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
#compare fee
|
||||
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
|
||||
assert feeDelta >= 0 and feeDelta <= feeTolerance*19 #~19 inputs
|
||||
|
||||
assert feeDelta >= 0 and feeDelta <= self.fee_tolerance * 19 #~19 inputs
|
||||
|
||||
def test_many_inputs_send(self):
|
||||
#############################################
|
||||
# multiple (~19) inputs tx test | sign/send #
|
||||
#############################################
|
||||
@ -569,12 +588,13 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
|
||||
fundedTx = self.nodes[1].fundrawtransaction(rawtx)
|
||||
fundedAndSignedTx = self.nodes[1].signrawtransactionwithwallet(fundedTx['hex'])
|
||||
txId = self.nodes[1].sendrawtransaction(fundedAndSignedTx['hex'])
|
||||
self.nodes[1].sendrawtransaction(fundedAndSignedTx['hex'])
|
||||
self.sync_all()
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
assert_equal(oldBalance+Decimal('500.19000000'), self.nodes[0].getbalance()) #0.19+block reward
|
||||
|
||||
def test_op_return(self):
|
||||
#####################################################
|
||||
# test fundrawtransaction with OP_RETURN and no vin #
|
||||
#####################################################
|
||||
@ -591,40 +611,41 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
assert_greater_than(len(dec_tx['vin']), 0) # at least one vin
|
||||
assert_equal(len(dec_tx['vout']), 2) # one change output added
|
||||
|
||||
|
||||
def test_watchonly(self):
|
||||
##################################################
|
||||
# test a fundrawtransaction using only watchonly #
|
||||
##################################################
|
||||
|
||||
inputs = []
|
||||
outputs = {self.nodes[2].getnewaddress() : watchonly_amount / 2}
|
||||
outputs = {self.nodes[2].getnewaddress(): self.watchonly_amount / 2}
|
||||
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
|
||||
|
||||
result = self.nodes[3].fundrawtransaction(rawtx, {'includeWatching': True })
|
||||
res_dec = self.nodes[0].decoderawtransaction(result["hex"])
|
||||
assert_equal(len(res_dec["vin"]), 1)
|
||||
assert_equal(res_dec["vin"][0]["txid"], watchonly_txid)
|
||||
assert_equal(res_dec["vin"][0]["txid"], self.watchonly_txid)
|
||||
|
||||
assert "fee" in result.keys()
|
||||
assert_greater_than(result["changepos"], -1)
|
||||
|
||||
def test_all_watched_funds(self):
|
||||
###############################################################
|
||||
# test fundrawtransaction using the entirety of watched funds #
|
||||
###############################################################
|
||||
|
||||
inputs = []
|
||||
outputs = {self.nodes[2].getnewaddress() : watchonly_amount}
|
||||
outputs = {self.nodes[2].getnewaddress(): self.watchonly_amount}
|
||||
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
|
||||
|
||||
# Backward compatibility test (2nd param is includeWatching)
|
||||
result = self.nodes[3].fundrawtransaction(rawtx, True)
|
||||
res_dec = self.nodes[0].decoderawtransaction(result["hex"])
|
||||
assert_equal(len(res_dec["vin"]), 2)
|
||||
assert res_dec["vin"][0]["txid"] == watchonly_txid or res_dec["vin"][1]["txid"] == watchonly_txid
|
||||
assert res_dec["vin"][0]["txid"] == self.watchonly_txid or res_dec["vin"][1]["txid"] == self.watchonly_txid
|
||||
|
||||
assert_greater_than(result["fee"], 0)
|
||||
assert_greater_than(result["changepos"], -1)
|
||||
assert_equal(result["fee"] + res_dec["vout"][result["changepos"]]["value"], watchonly_amount / 10)
|
||||
assert_equal(result["fee"] + res_dec["vout"][result["changepos"]]["value"], self.watchonly_amount / 10)
|
||||
|
||||
signedtx = self.nodes[3].signrawtransactionwithwallet(result["hex"])
|
||||
assert not signedtx["complete"]
|
||||
@ -634,6 +655,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
def test_option_feerate(self):
|
||||
#######################
|
||||
# Test feeRate option #
|
||||
#######################
|
||||
@ -644,18 +666,20 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
inputs = []
|
||||
outputs = {self.nodes[3].getnewaddress() : 1}
|
||||
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
|
||||
result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee)
|
||||
result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee})
|
||||
result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10*min_relay_tx_fee})
|
||||
result = self.nodes[3].fundrawtransaction(rawtx) # uses self.min_relay_tx_fee (set by settxfee)
|
||||
result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2 * self.min_relay_tx_fee})
|
||||
result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10 * self.min_relay_tx_fee})
|
||||
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by -maxtxfee", self.nodes[3].fundrawtransaction, rawtx, {"feeRate": 1})
|
||||
result_fee_rate = result['fee'] * 1000 / count_bytes(result['hex'])
|
||||
assert_fee_amount(result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate)
|
||||
assert_fee_amount(result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate)
|
||||
|
||||
def test_address_reuse(self):
|
||||
################################
|
||||
# Test no address reuse occurs #
|
||||
################################
|
||||
|
||||
rawtx = self.nodes[3].createrawtransaction(inputs=[], outputs={self.nodes[3].getnewaddress(): 1})
|
||||
result3 = self.nodes[3].fundrawtransaction(rawtx)
|
||||
res_dec = self.nodes[0].decoderawtransaction(result3["hex"])
|
||||
changeaddress = ""
|
||||
@ -667,6 +691,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
# Now the change address key should be removed from the keypool
|
||||
assert changeaddress != nextaddr
|
||||
|
||||
def test_option_subtract_fee_from_outputs(self):
|
||||
######################################
|
||||
# Test subtractFeeFromOutputs option #
|
||||
######################################
|
||||
@ -678,11 +703,11 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
outputs = {self.nodes[2].getnewaddress(): 1}
|
||||
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
|
||||
|
||||
result = [self.nodes[3].fundrawtransaction(rawtx), # uses min_relay_tx_fee (set by settxfee)
|
||||
self.nodes[3].fundrawtransaction(rawtx, {"subtractFeeFromOutputs": []}), # empty subtraction list
|
||||
self.nodes[3].fundrawtransaction(rawtx, {"subtractFeeFromOutputs": [0]}), # uses min_relay_tx_fee (set by settxfee)
|
||||
self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee}),
|
||||
self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee, "subtractFeeFromOutputs": [0]})]
|
||||
result = [self.nodes[3].fundrawtransaction(rawtx), # uses self.min_relay_tx_fee (set by settxfee)
|
||||
self.nodes[3].fundrawtransaction(rawtx, {"subtractFeeFromOutputs": []}), # empty subtraction list
|
||||
self.nodes[3].fundrawtransaction(rawtx, {"subtractFeeFromOutputs": [0]}), # uses self.min_relay_tx_fee (set by settxfee)
|
||||
self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2 * self.min_relay_tx_fee}),
|
||||
self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2 * self.min_relay_tx_fee, "subtractFeeFromOutputs": [0]}),]
|
||||
|
||||
dec_tx = [self.nodes[3].decoderawtransaction(tx_['hex']) for tx_ in result]
|
||||
output = [d['vout'][1 - r['changepos']]['value'] for d, r in zip(dec_tx, result)]
|
||||
|
@ -203,6 +203,7 @@ BASE_SCRIPTS = [
|
||||
'feature_governance_objects.py',
|
||||
'rpc_uptime.py',
|
||||
'wallet_resendwallettransactions.py',
|
||||
'wallet_fallbackfee.py',
|
||||
'feature_minchainwork.py',
|
||||
'p2p_unrequested_blocks.py', # NOTE: needs dash_hash to pass
|
||||
'feature_shutdown.py',
|
||||
|
@ -4,20 +4,23 @@
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Test the wallet balance RPC methods."""
|
||||
from decimal import Decimal
|
||||
import struct
|
||||
|
||||
from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE as ADDRESS_WATCHONLY
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_raises_rpc_error,
|
||||
connect_nodes,
|
||||
sync_blocks,
|
||||
)
|
||||
|
||||
RANDOM_COINBASE_ADDRESS = 'ycwedq2f3sz2Yf9JqZsBCQPxp18WU3Hp4J'
|
||||
|
||||
def create_transactions(node, address, amt, fees):
|
||||
# Create and sign raw transactions from node to address for amt.
|
||||
# Creates a transaction for each fee and returns an array
|
||||
# of the raw transactions.
|
||||
utxos = node.listunspent(0)
|
||||
utxos = [u for u in node.listunspent(0) if u['spendable']]
|
||||
|
||||
# Create transactions
|
||||
inputs = []
|
||||
@ -25,14 +28,20 @@ def create_transactions(node, address, amt, fees):
|
||||
for utxo in utxos:
|
||||
inputs.append({"txid": utxo["txid"], "vout": utxo["vout"]})
|
||||
ins_total += utxo['amount']
|
||||
if ins_total > amt:
|
||||
if ins_total >= amt + max(fees):
|
||||
break
|
||||
# make sure there was enough utxos
|
||||
assert ins_total >= amt + max(fees)
|
||||
|
||||
txs = []
|
||||
for fee in fees:
|
||||
outputs = {address: amt, node.getrawchangeaddress(): ins_total - amt - fee}
|
||||
outputs = {address: amt}
|
||||
# prevent 0 change output
|
||||
if ins_total > amt + fee:
|
||||
outputs[node.getrawchangeaddress()] = ins_total - amt - fee
|
||||
raw_tx = node.createrawtransaction(inputs, outputs, 0)
|
||||
raw_tx = node.signrawtransactionwithwallet(raw_tx)
|
||||
assert_equal(raw_tx['complete'], True)
|
||||
txs.append(raw_tx)
|
||||
|
||||
return txs
|
||||
@ -41,21 +50,26 @@ class WalletTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 2
|
||||
self.setup_clean_chain = True
|
||||
self.extra_args = [
|
||||
['-limitdescendantcount=3'], # Limit mempool descendants as a hack to have wallet txs rejected from the mempool
|
||||
[],
|
||||
]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
|
||||
def run_test(self):
|
||||
self.nodes[0].importaddress(ADDRESS_WATCHONLY)
|
||||
# Check that nodes don't own any UTXOs
|
||||
assert_equal(len(self.nodes[0].listunspent()), 0)
|
||||
assert_equal(len(self.nodes[1].listunspent()), 0)
|
||||
|
||||
self.log.info("Mining one block for each node")
|
||||
self.log.info("Mining blocks ...")
|
||||
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
self.nodes[1].generate(1)
|
||||
self.nodes[1].generatetoaddress(100, RANDOM_COINBASE_ADDRESS)
|
||||
self.nodes[1].generatetoaddress(101, ADDRESS_WATCHONLY)
|
||||
self.sync_all()
|
||||
|
||||
assert_equal(self.nodes[0].getbalance(), 500)
|
||||
@ -66,6 +80,8 @@ class WalletTest(BitcoinTestFramework):
|
||||
assert_equal(self.nodes[0].getbalance("*", 1), 500)
|
||||
assert_equal(self.nodes[0].getbalance("*", 1, True), 500)
|
||||
assert_equal(self.nodes[0].getbalance(minconf=1), 500)
|
||||
assert_equal(self.nodes[0].getbalance(minconf=0, include_watchonly=True), 1000)
|
||||
assert_equal(self.nodes[1].getbalance(minconf=0, include_watchonly=True), 500)
|
||||
|
||||
# Send 490 BTC from 0 to 1 and 960 BTC from 1 to 0.
|
||||
txs = create_transactions(self.nodes[0], self.nodes[1].getnewaddress(), 490 , [Decimal('0.01')])
|
||||
@ -83,32 +99,34 @@ class WalletTest(BitcoinTestFramework):
|
||||
|
||||
self.log.info("Test getbalance and getunconfirmedbalance with unconfirmed inputs")
|
||||
|
||||
# getbalance without any arguments includes unconfirmed transactions, but not untrusted transactions
|
||||
assert_equal(self.nodes[0].getbalance(), Decimal('9.99')) # change from node 0's send
|
||||
assert_equal(self.nodes[1].getbalance(), Decimal('29.99')) # change from node 1's send
|
||||
# Same with minconf=0
|
||||
assert_equal(self.nodes[0].getbalance(minconf=0), Decimal('9.99'))
|
||||
assert_equal(self.nodes[1].getbalance(minconf=0), Decimal('29.99'))
|
||||
# getbalance with a minconf incorrectly excludes coins that have been spent more recently than the minconf blocks ago
|
||||
# TODO: fix getbalance tracking of coin spentness depth
|
||||
assert_equal(self.nodes[0].getbalance(minconf=1), Decimal('0'))
|
||||
assert_equal(self.nodes[1].getbalance(minconf=1), Decimal('0'))
|
||||
# getunconfirmedbalance
|
||||
assert_equal(self.nodes[0].getunconfirmedbalance(), Decimal('960')) # output of node 1's spend
|
||||
assert_equal(self.nodes[1].getunconfirmedbalance(), Decimal('0')) # Doesn't include output of node 0's send since it was spent
|
||||
def test_balances(*, fee_node_1=0):
|
||||
# getbalance without any arguments includes unconfirmed transactions, but not untrusted transactions
|
||||
assert_equal(self.nodes[0].getbalance(), Decimal('9.99')) # change from node 0's send
|
||||
assert_equal(self.nodes[1].getbalance(), Decimal('30') - fee_node_1) # change from node 1's send
|
||||
# Same with minconf=0
|
||||
assert_equal(self.nodes[0].getbalance(minconf=0), Decimal('9.99'))
|
||||
assert_equal(self.nodes[1].getbalance(minconf=0), Decimal('30') - fee_node_1)
|
||||
# getbalance with a minconf incorrectly excludes coins that have been spent more recently than the minconf blocks ago
|
||||
# TODO: fix getbalance tracking of coin spentness depth
|
||||
assert_equal(self.nodes[0].getbalance(minconf=1), Decimal('0'))
|
||||
assert_equal(self.nodes[1].getbalance(minconf=1), Decimal('0'))
|
||||
# getunconfirmedbalance
|
||||
assert_equal(self.nodes[0].getunconfirmedbalance(), Decimal('960')) # output of node 1's spend
|
||||
assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], Decimal('960'))
|
||||
assert_equal(self.nodes[1].getunconfirmedbalance(), Decimal('0')) # Doesn't include output of node 0's send since it was spent
|
||||
assert_equal(self.nodes[1].getwalletinfo()["unconfirmed_balance"], Decimal('0'))
|
||||
|
||||
test_balances(fee_node_1=Decimal('0.01'))
|
||||
|
||||
# Node 1 bumps the transaction fee and resends
|
||||
# self.nodes[1].sendrawtransaction(txs[1]['hex']) # disabled, no RBF in Dash
|
||||
#self.nodes[0].sendrawtransaction(txs[1]['hex']) # sending on both nodes is faster than waiting for propagation # disabled, no RBF in Dash
|
||||
self.sync_all()
|
||||
|
||||
self.log.info("Test getbalance and getunconfirmedbalance with conflicted unconfirmed inputs")
|
||||
# test_balances(fee_node_1=Decimal('0.02'))
|
||||
|
||||
assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], Decimal('960')) # output of node 1's send
|
||||
assert_equal(self.nodes[0].getunconfirmedbalance(), Decimal('960'))
|
||||
assert_equal(self.nodes[1].getwalletinfo()["unconfirmed_balance"], Decimal('0')) # Doesn't include output of node 0's send since it was spent
|
||||
assert_equal(self.nodes[1].getunconfirmedbalance(), Decimal('0'))
|
||||
|
||||
self.nodes[1].generatetoaddress(1, RANDOM_COINBASE_ADDRESS)
|
||||
self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY)
|
||||
self.sync_all()
|
||||
|
||||
# balances are correct after the transactions are confirmed
|
||||
@ -118,7 +136,7 @@ class WalletTest(BitcoinTestFramework):
|
||||
# Send total balance away from node 1
|
||||
txs = create_transactions(self.nodes[1], self.nodes[0].getnewaddress(), Decimal('29.98'), [Decimal('0.01')])
|
||||
self.nodes[1].sendrawtransaction(txs[0]['hex'])
|
||||
self.nodes[1].generatetoaddress(2, RANDOM_COINBASE_ADDRESS)
|
||||
self.nodes[1].generatetoaddress(2, ADDRESS_WATCHONLY)
|
||||
self.sync_all()
|
||||
|
||||
# getbalance with a minconf incorrectly excludes coins that have been spent more recently than the minconf blocks ago
|
||||
@ -140,6 +158,52 @@ class WalletTest(BitcoinTestFramework):
|
||||
after = self.nodes[1].getunconfirmedbalance()
|
||||
assert_equal(before + Decimal('0.1'), after)
|
||||
|
||||
# Create 3 more wallet txs, where the last is not accepted to the
|
||||
# mempool because it is the third descendant of the tx above
|
||||
for _ in range(3):
|
||||
# Set amount high enough such that all coins are spent by each tx
|
||||
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 999)
|
||||
|
||||
self.log.info('Check that wallet txs not in the mempool are untrusted')
|
||||
assert txid not in self.nodes[0].getrawmempool()
|
||||
assert_equal(self.nodes[0].gettransaction(txid)['trusted'], False)
|
||||
assert_equal(self.nodes[0].getbalance(minconf=0), 0)
|
||||
|
||||
self.log.info("Test replacement and reorg of non-mempool tx")
|
||||
tx_orig = self.nodes[0].gettransaction(txid)['hex']
|
||||
# Increase fee by 1 coin
|
||||
tx_replace = tx_orig.replace(
|
||||
struct.pack("<q", 999 * 10**8).hex(),
|
||||
struct.pack("<q", 998 * 10**8).hex(),
|
||||
)
|
||||
tx_replace = self.nodes[0].signrawtransactionwithwallet(tx_replace)['hex']
|
||||
# Total balance is given by the sum of outputs of the tx
|
||||
total_amount = sum([o['value'] for o in self.nodes[0].decoderawtransaction(tx_replace)['vout']])
|
||||
self.sync_all()
|
||||
self.nodes[1].sendrawtransaction(hexstring=tx_replace, maxfeerate=0)
|
||||
|
||||
# Now confirm tx_replace
|
||||
block_reorg = self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY)[0]
|
||||
self.sync_all()
|
||||
assert_equal(self.nodes[0].getbalance(minconf=0), total_amount)
|
||||
|
||||
self.log.info('Put txs back into mempool of node 1 (not node 0)')
|
||||
self.nodes[0].invalidateblock(block_reorg)
|
||||
self.nodes[1].invalidateblock(block_reorg)
|
||||
assert_equal(self.nodes[0].getbalance(minconf=0), 0) # wallet txs not in the mempool are untrusted
|
||||
self.nodes[0].generatetoaddress(1, ADDRESS_WATCHONLY)
|
||||
assert_equal(self.nodes[0].getbalance(minconf=0), 0) # wallet txs not in the mempool are untrusted
|
||||
|
||||
# Now confirm tx_orig
|
||||
self.restart_node(1, ['-persistmempool=0', '-checklevel=0'])
|
||||
connect_nodes(self.nodes[0], 1)
|
||||
connect_nodes(self.nodes[1], 0)
|
||||
sync_blocks(self.nodes)
|
||||
self.nodes[1].sendrawtransaction(tx_orig)
|
||||
self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY)
|
||||
self.sync_all()
|
||||
assert_equal(self.nodes[0].getbalance(minconf=0), total_amount + 1) # The reorg recovered our fee of 1 coin
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
WalletTest().main()
|
||||
|
@ -21,8 +21,11 @@ from test_framework.util import (
|
||||
class WalletTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 4
|
||||
self.extra_args = [[
|
||||
"-acceptnonstdtxn=1",
|
||||
'-usehd={:d}'.format(i%2==0),
|
||||
] for i in range(self.num_nodes)]
|
||||
self.setup_clean_chain = True
|
||||
self.extra_args = [['-usehd={:d}'.format(i%2==0)] for i in range(4)]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
|
@ -6,6 +6,7 @@
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_raises_rpc_error,
|
||||
)
|
||||
|
||||
|
||||
@ -18,6 +19,10 @@ class CreateTxWalletTest(BitcoinTestFramework):
|
||||
self.skip_if_no_wallet()
|
||||
|
||||
def run_test(self):
|
||||
self.test_anti_fee_sniping()
|
||||
self.test_tx_size_too_large()
|
||||
|
||||
def test_anti_fee_sniping(self):
|
||||
self.log.info('Check that we have some (old) blocks and that anti-fee-sniping is disabled')
|
||||
self.bump_mocktime(8 * 60 * 60 + 1)
|
||||
assert_equal(self.nodes[0].getblockchaininfo()['blocks'], 200)
|
||||
@ -31,6 +36,40 @@ class CreateTxWalletTest(BitcoinTestFramework):
|
||||
tx = self.nodes[0].decoderawtransaction(self.nodes[0].gettransaction(txid)['hex'])
|
||||
assert 0 < tx['locktime'] <= 201
|
||||
|
||||
def test_tx_size_too_large(self):
|
||||
# More than 10kB of outputs, so that we hit -maxtxfee with a high feerate
|
||||
outputs = {self.nodes[0].getnewaddress(): 0.000025 for i in range(400)}
|
||||
raw_tx = self.nodes[0].createrawtransaction(inputs=[], outputs=outputs)
|
||||
|
||||
for fee_setting in ['-minrelaytxfee=0.01', '-mintxfee=0.01', '-paytxfee=0.01']:
|
||||
self.log.info('Check maxtxfee in combination with {}'.format(fee_setting))
|
||||
self.restart_node(0, extra_args=[fee_setting])
|
||||
assert_raises_rpc_error(
|
||||
-6,
|
||||
"Fee exceeds maximum configured by -maxtxfee",
|
||||
lambda: self.nodes[0].sendmany(dummy="", amounts=outputs),
|
||||
)
|
||||
assert_raises_rpc_error(
|
||||
-4,
|
||||
"Fee exceeds maximum configured by -maxtxfee",
|
||||
lambda: self.nodes[0].fundrawtransaction(hexstring=raw_tx),
|
||||
)
|
||||
|
||||
self.log.info('Check maxtxfee in combination with settxfee')
|
||||
self.restart_node(0)
|
||||
self.nodes[0].settxfee(0.01)
|
||||
assert_raises_rpc_error(
|
||||
-6,
|
||||
"Fee exceeds maximum configured by -maxtxfee",
|
||||
lambda: self.nodes[0].sendmany(dummy="", amounts=outputs),
|
||||
)
|
||||
assert_raises_rpc_error(
|
||||
-4,
|
||||
"Fee exceeds maximum configured by -maxtxfee",
|
||||
lambda: self.nodes[0].fundrawtransaction(hexstring=raw_tx),
|
||||
)
|
||||
self.nodes[0].settxfee(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CreateTxWalletTest().main()
|
||||
|
27
test/functional/wallet_fallbackfee.py
Executable file
27
test/functional/wallet_fallbackfee.py
Executable file
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2017 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Test wallet replace-by-fee capabilities in conjunction with the fallbackfee."""
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_raises_rpc_error
|
||||
|
||||
class WalletRBFTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def run_test(self):
|
||||
self.nodes[0].generate(101)
|
||||
|
||||
# sending a transaction without fee estimations must be possible by default on regtest
|
||||
self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
|
||||
|
||||
# test sending a tx with disabled fallback fee (must fail)
|
||||
self.restart_node(0, extra_args=["-fallbackfee=0"])
|
||||
assert_raises_rpc_error(-4, "Fee estimation failed", lambda: self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1))
|
||||
assert_raises_rpc_error(-4, "Fee estimation failed", lambda: self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1})))
|
||||
assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1}))
|
||||
|
||||
if __name__ == '__main__':
|
||||
WalletRBFTest().main()
|
Loading…
Reference in New Issue
Block a user