mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
merge bitcoin#13541: sendrawtransaction maxfeerate
This commit is contained in:
parent
06ebacbb9a
commit
c6c307b3f7
@ -111,10 +111,12 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "signrawtransactionwithkey", 2, "prevtxs" },
|
||||
{ "signrawtransactionwithwallet", 1, "prevtxs" },
|
||||
{ "sendrawtransaction", 1, "allowhighfees" },
|
||||
{ "sendrawtransaction", 1, "maxfeerate" },
|
||||
{ "sendrawtransaction", 2, "instantsend" },
|
||||
{ "sendrawtransaction", 3, "bypasslimits" },
|
||||
{ "testmempoolaccept", 0, "rawtxs" },
|
||||
{ "testmempoolaccept", 1, "allowhighfees" },
|
||||
{ "testmempoolaccept", 1, "maxfeerate" },
|
||||
{ "combinerawtransaction", 0, "txs" },
|
||||
{ "fundrawtransaction", 1, "options" },
|
||||
{ "walletcreatefundedpsbt", 0, "inputs" },
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <script/standard.h>
|
||||
#include <txmempool.h>
|
||||
#include <uint256.h>
|
||||
#include <util/moneystr.h>
|
||||
#include <util/validation.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <validation.h>
|
||||
@ -758,7 +759,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
|
||||
"\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n",
|
||||
{
|
||||
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
|
||||
{"allowhighfees", RPCArg::Type::BOOL, /* default */ "false", "Allow high fees"},
|
||||
{"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(maxTxFee), "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kB\n"},
|
||||
{"instantsend", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Deprecated and ignored"},
|
||||
{"bypasslimits", RPCArg::Type::BOOL, /* default_val */ "false", "Bypass transaction policy limits"},
|
||||
},
|
||||
@ -777,21 +778,34 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
|
||||
},
|
||||
}.ToString());
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VBOOL});
|
||||
RPCTypeCheck(request.params, {
|
||||
UniValue::VSTR,
|
||||
UniValueType(), // NUM or BOOL, checked later
|
||||
UniValue::VBOOL
|
||||
});
|
||||
|
||||
// parse hex string from parameter
|
||||
CMutableTransaction mtx;
|
||||
if (!DecodeHexTx(mtx, request.params[0].get_str()))
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
||||
CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
|
||||
bool allowhighfees = false;
|
||||
if (!request.params[1].isNull()) allowhighfees = request.params[1].get_bool();
|
||||
CAmount max_raw_tx_fee = ::maxTxFee;
|
||||
|
||||
// TODO: temporary migration code for old clients. Remove in v0.20
|
||||
if (request.params[1].isBool()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Second argument must be numeric (maxfeerate) and no longer supports a boolean. To allow a transaction with high fees, set maxfeerate to 0.");
|
||||
} else if (request.params[1].isNum()) {
|
||||
CFeeRate fr(AmountFromValue(request.params[1]));
|
||||
max_raw_tx_fee = fr.GetFee(GetVirtualTransactionSize(*tx));
|
||||
} else if (!request.params[1].isNull()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "second argument (maxfeerate) must be numeric");
|
||||
}
|
||||
|
||||
bool bypass_limits = false;
|
||||
if (!request.params[3].isNull()) bypass_limits = request.params[3].get_bool();
|
||||
const CAmount highfee{allowhighfees ? 0 : ::maxTxFee};
|
||||
uint256 txid;
|
||||
std::string err_string;
|
||||
const TransactionError err = BroadcastTransaction(tx, txid, err_string, highfee, bypass_limits);
|
||||
const TransactionError err = BroadcastTransaction(tx, txid, err_string, max_raw_tx_fee, bypass_limits);
|
||||
if (TransactionError::OK != err) {
|
||||
throw JSONRPCTransactionError(err, err_string);
|
||||
}
|
||||
@ -814,7 +828,7 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
|
||||
{"rawtx", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""},
|
||||
},
|
||||
},
|
||||
{"allowhighfees", RPCArg::Type::BOOL, /* default */ "false", "Allow high fees"},
|
||||
{"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(maxTxFee), "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kB\n"},
|
||||
},
|
||||
RPCResult{
|
||||
"[ (array) The result of the mempool acceptance test for each raw transaction in the input array.\n"
|
||||
@ -839,7 +853,11 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
|
||||
}.ToString());
|
||||
}
|
||||
|
||||
RPCTypeCheck(request.params, {UniValue::VARR, UniValue::VBOOL});
|
||||
RPCTypeCheck(request.params, {
|
||||
UniValue::VARR,
|
||||
UniValueType(), // NUM or BOOL, checked later
|
||||
});
|
||||
|
||||
if (request.params[0].get_array().size() != 1) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Array must contain exactly one raw transaction for now");
|
||||
}
|
||||
@ -852,8 +870,14 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
|
||||
const uint256& tx_hash = tx->GetHash();
|
||||
|
||||
CAmount max_raw_tx_fee = ::maxTxFee;
|
||||
if (!request.params[1].isNull() && request.params[1].get_bool()) {
|
||||
max_raw_tx_fee = 0;
|
||||
// TODO: temporary migration code for old clients. Remove in v0.20
|
||||
if (request.params[1].isBool()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Second argument must be numeric (maxfeerate) and no longer supports a boolean. To allow a transaction with high fees, set maxfeerate to 0.");
|
||||
} else if (request.params[1].isNum()) {
|
||||
CFeeRate fr(AmountFromValue(request.params[1]));
|
||||
max_raw_tx_fee = fr.GetFee(GetVirtualTransactionSize(*tx));
|
||||
} else if (!request.params[1].isNull()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "second argument (maxfeerate) must be numeric");
|
||||
}
|
||||
|
||||
UniValue result(UniValue::VARR);
|
||||
@ -1375,10 +1399,10 @@ static const CRPCCommand commands[] =
|
||||
{ "rawtransactions", "createrawtransaction", &createrawtransaction, {"inputs","outputs","locktime"} },
|
||||
{ "rawtransactions", "decoderawtransaction", &decoderawtransaction, {"hexstring"} },
|
||||
{ "rawtransactions", "decodescript", &decodescript, {"hexstring"} },
|
||||
{ "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees","instantsend","bypasslimits"} },
|
||||
{ "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees|maxfeerate","instantsend","bypasslimits"} },
|
||||
{ "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} },
|
||||
{ "rawtransactions", "signrawtransactionwithkey", &signrawtransactionwithkey, {"hexstring","privkeys","prevtxs","sighashtype"} },
|
||||
{ "rawtransactions", "testmempoolaccept", &testmempoolaccept, {"rawtxs","allowhighfees"} },
|
||||
{ "rawtransactions", "testmempoolaccept", &testmempoolaccept, {"rawtxs","allowhighfees|maxfeerate"} },
|
||||
{ "rawtransactions", "decodepsbt", &decodepsbt, {"psbt"} },
|
||||
{ "rawtransactions", "combinepsbt", &combinepsbt, {"txs"} },
|
||||
{ "rawtransactions", "finalizepsbt", &finalizepsbt, {"psbt", "extract"} },
|
||||
|
@ -140,7 +140,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||
tx.rehash()
|
||||
|
||||
signed_tx = self.nodes[0].signrawtransactionwithwallet(tx.serialize().hex())
|
||||
sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
|
||||
sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], 0)
|
||||
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
@ -170,7 +170,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||
tx.vout = [CTxOut(amount, scriptPubKey2)]
|
||||
tx.rehash()
|
||||
signed_tx = self.nodes[0].signrawtransactionwithwallet(tx.serialize().hex())
|
||||
spending_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
|
||||
spending_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], 0)
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
balance1 = self.nodes[1].getaddressbalance(address2)
|
||||
@ -184,7 +184,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||
tx.rehash()
|
||||
|
||||
signed_tx = self.nodes[0].signrawtransactionwithwallet(tx.serialize().hex())
|
||||
sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
|
||||
sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], 0)
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
@ -265,7 +265,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||
tx.vout = [CTxOut(amount, scriptPubKey3)]
|
||||
tx.rehash()
|
||||
signed_tx = self.nodes[2].signrawtransactionwithwallet(tx.serialize().hex())
|
||||
memtxid1 = self.nodes[2].sendrawtransaction(signed_tx["hex"], True)
|
||||
memtxid1 = self.nodes[2].sendrawtransaction(signed_tx["hex"], 0)
|
||||
self.bump_mocktime(2)
|
||||
|
||||
tx2 = CTransaction()
|
||||
@ -279,7 +279,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||
]
|
||||
tx2.rehash()
|
||||
signed_tx2 = self.nodes[2].signrawtransactionwithwallet(tx2.serialize().hex())
|
||||
memtxid2 = self.nodes[2].sendrawtransaction(signed_tx2["hex"], True)
|
||||
memtxid2 = self.nodes[2].sendrawtransaction(signed_tx2["hex"], 0)
|
||||
self.bump_mocktime(2)
|
||||
|
||||
mempool = self.nodes[2].getaddressmempool({"addresses": [address3]})
|
||||
@ -306,7 +306,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||
tx.rehash()
|
||||
self.nodes[2].importprivkey(privKey3)
|
||||
signed_tx3 = self.nodes[2].signrawtransactionwithwallet(tx.serialize().hex())
|
||||
self.nodes[2].sendrawtransaction(signed_tx3["hex"], True)
|
||||
self.nodes[2].sendrawtransaction(signed_tx3["hex"], 0)
|
||||
self.bump_mocktime(2)
|
||||
|
||||
mempool3 = self.nodes[2].getaddressmempool({"addresses": [address3]})
|
||||
@ -338,7 +338,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||
tx.rehash()
|
||||
self.nodes[0].importprivkey(privkey1)
|
||||
signed_tx = self.nodes[0].signrawtransactionwithwallet(tx.serialize().hex())
|
||||
self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
|
||||
self.nodes[0].sendrawtransaction(signed_tx["hex"], 0)
|
||||
|
||||
self.sync_all()
|
||||
mempool_deltas = self.nodes[2].getaddressmempool({"addresses": [address1]})
|
||||
|
@ -129,7 +129,7 @@ class BIP65Test(BitcoinTestFramework):
|
||||
|
||||
# First we show that this tx is valid except for CLTV by getting it
|
||||
# rejected from the mempool for exactly that reason.
|
||||
assert_raises_rpc_error(-26, 'non-mandatory-script-verify-flag (Negative locktime) (code 64)', self.nodes[0].sendrawtransaction, spendtx.serialize().hex(), True)
|
||||
assert_raises_rpc_error(-26, 'non-mandatory-script-verify-flag (Negative locktime) (code 64)', self.nodes[0].sendrawtransaction, spendtx.serialize().hex(), 0)
|
||||
|
||||
# Now we verify that a block with this transaction is also invalid.
|
||||
block.vtx.append(spendtx)
|
||||
|
@ -118,7 +118,7 @@ class BIP66Test(BitcoinTestFramework):
|
||||
|
||||
# First we show that this tx is valid except for DERSIG by getting it
|
||||
# rejected from the mempool for exactly that reason.
|
||||
assert_raises_rpc_error(-26, 'non-mandatory-script-verify-flag (Non-canonical DER signature) (code 64)', self.nodes[0].sendrawtransaction, spendtx.serialize().hex(), True)
|
||||
assert_raises_rpc_error(-26, 'non-mandatory-script-verify-flag (Non-canonical DER signature) (code 64)', self.nodes[0].sendrawtransaction, spendtx.serialize().hex(), 0)
|
||||
|
||||
# Now we verify that a block with this transaction is also invalid.
|
||||
block.vtx.append(spendtx)
|
||||
|
@ -63,7 +63,7 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee
|
||||
# the ScriptSig that will satisfy the ScriptPubKey.
|
||||
for inp in tx.vin:
|
||||
inp.scriptSig = SCRIPT_SIG[inp.prevout.n]
|
||||
txid = from_node.sendrawtransaction(ToHex(tx), True)
|
||||
txid = from_node.sendrawtransaction(hexstring=ToHex(tx), maxfeerate=0)
|
||||
unconflist.append({"txid": txid, "vout": 0, "amount": total_in - amount - fee})
|
||||
unconflist.append({"txid": txid, "vout": 1, "amount": amount})
|
||||
|
||||
@ -93,7 +93,7 @@ def split_inputs(from_node, txins, txouts, initial_split=False):
|
||||
else:
|
||||
tx.vin[0].scriptSig = SCRIPT_SIG[prevtxout["vout"]]
|
||||
completetx = ToHex(tx)
|
||||
txid = from_node.sendrawtransaction(completetx, True)
|
||||
txid = from_node.sendrawtransaction(hexstring=completetx, maxfeerate=0)
|
||||
txouts.append({"txid": txid, "vout": 0, "amount": half_change})
|
||||
txouts.append({"txid": txid, "vout": 1, "amount": rem_change})
|
||||
|
||||
|
@ -60,15 +60,15 @@ class NULLDUMMYTest(BitcoinTestFramework):
|
||||
|
||||
self.log.info("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]")
|
||||
test1txs = [create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, 49)]
|
||||
txid1 = self.nodes[0].sendrawtransaction(test1txs[0].serialize().hex(), True)
|
||||
txid1 = self.nodes[0].sendrawtransaction(test1txs[0].serialize().hex(), 0)
|
||||
test1txs.append(create_transaction(self.nodes[0], txid1, self.ms_address, 48))
|
||||
txid2 = self.nodes[0].sendrawtransaction(test1txs[1].serialize().hex(), True)
|
||||
txid2 = self.nodes[0].sendrawtransaction(test1txs[1].serialize().hex(), 0)
|
||||
self.block_submit(self.nodes[0], test1txs, True)
|
||||
|
||||
self.log.info("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation")
|
||||
test2tx = create_transaction(self.nodes[0], txid2, self.ms_address, 47)
|
||||
trueDummy(test2tx)
|
||||
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test2tx.serialize().hex(), True)
|
||||
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test2tx.serialize().hex(), 0)
|
||||
|
||||
self.log.info("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]")
|
||||
self.block_submit(self.nodes[0], [test2tx], True)
|
||||
@ -77,12 +77,12 @@ class NULLDUMMYTest(BitcoinTestFramework):
|
||||
test4tx = create_transaction(self.nodes[0], test2tx.hash, self.address, 46)
|
||||
test6txs=[CTransaction(test4tx)]
|
||||
trueDummy(test4tx)
|
||||
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test4tx.serialize().hex(), True)
|
||||
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test4tx.serialize().hex(), 0)
|
||||
self.block_submit(self.nodes[0], [test4tx])
|
||||
|
||||
self.log.info("Test 6: NULLDUMMY compliant transactions should be accepted to mempool and in block after activation [432]")
|
||||
for i in test6txs:
|
||||
self.nodes[0].sendrawtransaction(i.serialize().hex(), True)
|
||||
self.nodes[0].sendrawtransaction(i.serialize().hex(), 0)
|
||||
self.block_submit(self.nodes[0], test6txs, True)
|
||||
|
||||
|
||||
|
@ -76,7 +76,7 @@ class SpentIndexTest(BitcoinTestFramework):
|
||||
tx.rehash()
|
||||
|
||||
signed_tx = self.nodes[0].signrawtransactionwithwallet(tx.serialize().hex())
|
||||
txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
|
||||
txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], 0)
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
@ -111,7 +111,7 @@ class SpentIndexTest(BitcoinTestFramework):
|
||||
tx2.rehash()
|
||||
self.nodes[0].importprivkey(privkey)
|
||||
signed_tx2 = self.nodes[0].signrawtransactionwithwallet(tx2.serialize().hex())
|
||||
txid2 = self.nodes[0].sendrawtransaction(signed_tx2["hex"], True)
|
||||
txid2 = self.nodes[0].sendrawtransaction(signed_tx2["hex"], 0)
|
||||
|
||||
# Check the mempool index
|
||||
self.sync_all()
|
||||
|
@ -59,7 +59,7 @@ class TxIndexTest(BitcoinTestFramework):
|
||||
tx.rehash()
|
||||
|
||||
signed_tx = self.nodes[0].signrawtransactionwithwallet(tx.serialize().hex())
|
||||
txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
|
||||
txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], 0)
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
|
@ -70,7 +70,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
|
||||
inputs=[{'txid': coin['txid'], 'vout': coin['vout']}],
|
||||
outputs=[{node.getnewaddress(): 0.3}, {node.getnewaddress(): 49}],
|
||||
))['hex']
|
||||
txid_in_block = node.sendrawtransaction(hexstring=raw_tx_in_block, allowhighfees=True)
|
||||
txid_in_block = node.sendrawtransaction(hexstring=raw_tx_in_block, maxfeerate=0)
|
||||
node.generate(1)
|
||||
self.mempool_size = 0
|
||||
self.check_mempool_result(
|
||||
@ -103,9 +103,9 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
|
||||
self.check_mempool_result(
|
||||
result_expected=[{'txid': tx.rehash(), 'allowed': True}],
|
||||
rawtxs=[tx.serialize().hex()],
|
||||
allowhighfees=True,
|
||||
maxfeerate=0,
|
||||
)
|
||||
node.sendrawtransaction(hexstring=raw_tx_final, allowhighfees=True)
|
||||
node.sendrawtransaction(hexstring=raw_tx_final, maxfeerate=0)
|
||||
self.mempool_size += 1
|
||||
|
||||
self.log.info('A transaction in the mempool')
|
||||
@ -131,7 +131,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
|
||||
|
||||
self.log.info('A transaction that conflicts with an unconfirmed tx')
|
||||
# Send the transaction that replaces the mempool transaction and opts out of replaceability
|
||||
# node.sendrawtransaction(hexstring=tx.serialize().hex(), allowhighfees=True)
|
||||
# node.sendrawtransaction(hexstring=tx.serialize().hex(), maxfeerate=0)
|
||||
# take original raw_tx_0
|
||||
tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0)))
|
||||
tx.vout[0].nValue -= int(4 * fee * COIN) # Set more fee
|
||||
@ -139,7 +139,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
|
||||
self.check_mempool_result(
|
||||
result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': '18: txn-mempool-conflict'}],
|
||||
rawtxs=[tx.serialize().hex()],
|
||||
allowhighfees=True,
|
||||
maxfeerate=0,
|
||||
)
|
||||
|
||||
self.log.info('A transaction with missing inputs, that never existed')
|
||||
@ -155,7 +155,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
|
||||
tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0)))
|
||||
tx.vin[0].prevout.n = 1 # Set vout to 1, to spend the other outpoint (49 coins) of the in-chain-tx we want to double spend
|
||||
raw_tx_1 = node.signrawtransactionwithwallet(tx.serialize().hex())['hex']
|
||||
txid_1 = node.sendrawtransaction(hexstring=raw_tx_1, allowhighfees=True)
|
||||
txid_1 = node.sendrawtransaction(hexstring=raw_tx_1, maxfeerate=0)
|
||||
# Now spend both to "clearly hide" the outputs, ie. remove the coins from the utxo set by spending them
|
||||
raw_tx_spend_both = node.signrawtransactionwithwallet(node.createrawtransaction(
|
||||
inputs=[
|
||||
@ -164,7 +164,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
|
||||
],
|
||||
outputs=[{node.getnewaddress(): 0.1}]
|
||||
))['hex']
|
||||
txid_spend_both = node.sendrawtransaction(hexstring=raw_tx_spend_both, allowhighfees=True)
|
||||
txid_spend_both = node.sendrawtransaction(hexstring=raw_tx_spend_both, maxfeerate=0)
|
||||
node.generate(1)
|
||||
self.mempool_size = 0
|
||||
# Now see if we can add the coins back to the utxo set by sending the exact txs again
|
||||
@ -313,7 +313,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
|
||||
self.check_mempool_result(
|
||||
result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': '64: non-BIP68-final'}],
|
||||
rawtxs=[tx.serialize().hex()],
|
||||
allowhighfees=True,
|
||||
maxfeerate=0,
|
||||
)
|
||||
|
||||
|
||||
|
@ -31,13 +31,13 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
|
||||
b = [ self.nodes[0].getblockhash(n) for n in range(1, 4) ]
|
||||
coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
|
||||
spends1_raw = [ create_raw_transaction(self.nodes[0], txid, node0_address, 500) for txid in coinbase_txids ]
|
||||
spends1_id = [ self.nodes[0].sendrawtransaction(tx, False, False, True) for tx in spends1_raw ]
|
||||
spends1_id = [ self.nodes[0].sendrawtransaction(tx, 0, False, True) for tx in spends1_raw ]
|
||||
|
||||
blocks = []
|
||||
blocks.extend(self.nodes[0].generate(1))
|
||||
|
||||
spends2_raw = [ create_raw_transaction(self.nodes[0], txid, node0_address, 499.99) for txid in spends1_id ]
|
||||
spends2_id = [ self.nodes[0].sendrawtransaction(tx, False, False, True) for tx in spends2_raw ]
|
||||
spends2_id = [ self.nodes[0].sendrawtransaction(tx, 0, False, True) for tx in spends2_raw ]
|
||||
|
||||
blocks.extend(self.nodes[0].generate(1))
|
||||
|
||||
|
@ -234,11 +234,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
txDetails = self.nodes[0].gettransaction(txId, True)
|
||||
rawTx = self.nodes[0].decoderawtransaction(txDetails['hex'])
|
||||
vout = False
|
||||
for outpoint in rawTx['vout']:
|
||||
if outpoint['value'] == Decimal('2.20000000'):
|
||||
vout = outpoint
|
||||
break
|
||||
vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('2.20000000'))
|
||||
|
||||
bal = self.nodes[0].getbalance()
|
||||
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex']}]
|
||||
@ -279,11 +275,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
|
||||
txDetails = self.nodes[0].gettransaction(txId, True)
|
||||
rawTx2 = self.nodes[0].decoderawtransaction(txDetails['hex'])
|
||||
vout = False
|
||||
for outpoint in rawTx2['vout']:
|
||||
if outpoint['value'] == Decimal('2.20000000'):
|
||||
vout = outpoint
|
||||
break
|
||||
vout = next(o for o in rawTx2['vout'] if o['value'] == Decimal('2.20000000'))
|
||||
|
||||
bal = self.nodes[0].getbalance()
|
||||
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "redeemScript" : mSigObjValid['hex']}]
|
||||
@ -375,5 +367,30 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
decrawtx = self.nodes[0].decoderawtransaction(rawtx)
|
||||
assert_equal(decrawtx['version'], 0x7fff)
|
||||
|
||||
self.log.info('sendrawtransaction/testmempoolaccept with maxfeerate')
|
||||
|
||||
txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
|
||||
rawTx = self.nodes[0].getrawtransaction(txId, True)
|
||||
vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('1.00000000'))
|
||||
|
||||
self.sync_all()
|
||||
inputs = [{ "txid" : txId, "vout" : vout['n'] }]
|
||||
outputs = { self.nodes[0].getnewaddress() : Decimal("0.99999000") } # 1000 sat fee
|
||||
rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
|
||||
rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx)
|
||||
assert_equal(rawTxSigned['complete'], True)
|
||||
# 1000 sat fee, ~200 b transaction, fee rate should land around 5 sat/b = 0.00005000 BTC/kB
|
||||
# Thus, testmempoolaccept should reject
|
||||
testres = self.nodes[2].testmempoolaccept([rawTxSigned['hex']], 0.00001000)[0]
|
||||
assert_equal(testres['allowed'], False)
|
||||
assert_equal(testres['reject-reason'], '256: absurdly-high-fee')
|
||||
# and sendrawtransaction should throw
|
||||
assert_raises_rpc_error(-26, "absurdly-high-fee", self.nodes[2].sendrawtransaction, rawTxSigned['hex'], 0.00001000)
|
||||
# And below calls should both succeed
|
||||
testres = self.nodes[2].testmempoolaccept(rawtxs=[rawTxSigned['hex']], maxfeerate=0.00007000)[0]
|
||||
assert_equal(testres['allowed'], True)
|
||||
self.nodes[2].sendrawtransaction(hexstring=rawTxSigned['hex'], maxfeerate=0.00007000)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
RawTransactionsTest().main()
|
||||
|
@ -568,7 +568,7 @@ def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants):
|
||||
|
||||
rawtx = from_node.createrawtransaction(inputs, outputs)
|
||||
signresult = from_node.signrawtransactionwithwallet(rawtx)
|
||||
txid = from_node.sendrawtransaction(signresult["hex"], True)
|
||||
txid = from_node.sendrawtransaction(signresult["hex"], 0)
|
||||
|
||||
return (txid, signresult["hex"], fee)
|
||||
|
||||
@ -642,7 +642,7 @@ def create_lots_of_big_transactions(node, txouts, utxos, num, fee):
|
||||
tx.vout.append(txout)
|
||||
newtx = tx.serialize().hex()
|
||||
signresult = node.signrawtransactionwithwallet(newtx, None, "NONE")
|
||||
txid = node.sendrawtransaction(signresult["hex"], True)
|
||||
txid = node.sendrawtransaction(signresult["hex"], 0)
|
||||
txids.append(txid)
|
||||
return txids
|
||||
|
||||
|
@ -174,8 +174,8 @@ class WalletTest(BitcoinTestFramework):
|
||||
totalfee += fee_per_input
|
||||
|
||||
# Have node 1 (miner) send the transactions
|
||||
self.nodes[1].sendrawtransaction(txns_to_send[0]["hex"])
|
||||
self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"])
|
||||
self.nodes[1].sendrawtransaction(txns_to_send[0]["hex"], 0)
|
||||
self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"], 0)
|
||||
|
||||
# Have node1 mine a block to confirm transactions:
|
||||
self.nodes[1].generate(1)
|
||||
|
Loading…
Reference in New Issue
Block a user