Merge #12336: Remove deprecated rpc options
db1cbcc
[RPC] Remove deprecated addmultisigaddress return format (John Newbery)cb28a0b
[RPC] Remove deprecated createmultisig object (John Newbery)ed45c82
[tests] Remove test for deprecated createmultsig option (John Newbery)d066a1c
[rpc] Remove deprecated getmininginfo RPC option (John Newbery)c6f09c2
[rpc] remove deprecated estimatefee RPC (John Newbery)a8e437a
[tests] Remove estimatefee from rpc_deprecated.py test (John Newbery)a5623b1
[tests] Remove tests for deprecated estimatefee RPC (John Newbery)d119f2e
[tests] Fix style warnings in feature_fee_estimation.py (John Newbery) Pull request description: There were some RPC/RPC options deprecated in v0.16. Those can now be removed from master since v0.16 has been branched. - `estimatefee` RPC has been removed. The `feature_fee_estimation.py` test has been updated to remove the RPC, but doesn't yet have good coverage of the replacement RPC `estimatesmartfee`. Improving the test coverage should be done in a new PR. (#11031) - the `errors` field returned by `getmininginfo` has been deprecated and replaced by a `warning` field. (#10858) - providing addresses as inputs to `createmultisig` has been deprecated. Users should use `addmultisigaddress` instead (#11415) - The return format from `addmultisigaddress` has changed (#11415) `getwitnessaddress` was also deprecated in v0.16 and can be removed, but many tests are using that RPC, so it's a larger job to remove. It should be removed in a separate PR (possibly after #11739 and #11398 have been merged and the segwit test code tidied up) Tree-SHA512: 8ffaa5f6094131339b9e9e468e8b141de4b144697d2271efa2992b80b12eb97849ade3da8df5c1c9400ed4c04e6a029926550a3e5846d2029b644f9e84ac7124
This commit is contained in:
commit
3843780fd8
6 changed files with 87 additions and 170 deletions
|
@ -114,7 +114,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||||
{ "pruneblockchain", 0, "height" },
|
{ "pruneblockchain", 0, "height" },
|
||||||
{ "keypoolrefill", 0, "newsize" },
|
{ "keypoolrefill", 0, "newsize" },
|
||||||
{ "getrawmempool", 0, "verbose" },
|
{ "getrawmempool", 0, "verbose" },
|
||||||
{ "estimatefee", 0, "nblocks" },
|
|
||||||
{ "estimatesmartfee", 0, "conf_target" },
|
{ "estimatesmartfee", 0, "conf_target" },
|
||||||
{ "estimaterawfee", 0, "conf_target" },
|
{ "estimaterawfee", 0, "conf_target" },
|
||||||
{ "estimaterawfee", 1, "threshold" },
|
{ "estimaterawfee", 1, "threshold" },
|
||||||
|
|
|
@ -201,7 +201,6 @@ UniValue getmininginfo(const JSONRPCRequest& request)
|
||||||
" \"pooledtx\": n (numeric) The size of the mempool\n"
|
" \"pooledtx\": n (numeric) The size of the mempool\n"
|
||||||
" \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
|
" \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
|
||||||
" \"warnings\": \"...\" (string) any network and blockchain warnings\n"
|
" \"warnings\": \"...\" (string) any network and blockchain warnings\n"
|
||||||
" \"errors\": \"...\" (string) DEPRECATED. Same as warnings. Only shown when bitcoind is started with -deprecatedrpc=getmininginfo\n"
|
|
||||||
"}\n"
|
"}\n"
|
||||||
"\nExamples:\n"
|
"\nExamples:\n"
|
||||||
+ HelpExampleCli("getmininginfo", "")
|
+ HelpExampleCli("getmininginfo", "")
|
||||||
|
@ -219,11 +218,7 @@ UniValue getmininginfo(const JSONRPCRequest& request)
|
||||||
obj.push_back(Pair("networkhashps", getnetworkhashps(request)));
|
obj.push_back(Pair("networkhashps", getnetworkhashps(request)));
|
||||||
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
|
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
|
||||||
obj.push_back(Pair("chain", Params().NetworkIDString()));
|
obj.push_back(Pair("chain", Params().NetworkIDString()));
|
||||||
if (IsDeprecatedRPCEnabled("getmininginfo")) {
|
|
||||||
obj.push_back(Pair("errors", GetWarnings("statusbar")));
|
|
||||||
} else {
|
|
||||||
obj.push_back(Pair("warnings", GetWarnings("statusbar")));
|
obj.push_back(Pair("warnings", GetWarnings("statusbar")));
|
||||||
}
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,43 +767,8 @@ UniValue submitblock(const JSONRPCRequest& request)
|
||||||
|
|
||||||
UniValue estimatefee(const JSONRPCRequest& request)
|
UniValue estimatefee(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
if (request.fHelp || request.params.size() != 1)
|
throw JSONRPCError(RPC_METHOD_DEPRECATED, "estimatefee was removed in v0.17.\n"
|
||||||
throw std::runtime_error(
|
"Clients should use estimatesmartfee.");
|
||||||
"estimatefee nblocks\n"
|
|
||||||
"\nDEPRECATED. Please use estimatesmartfee for more intelligent estimates."
|
|
||||||
"\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n"
|
|
||||||
"confirmation within nblocks blocks. Uses virtual transaction size of transaction\n"
|
|
||||||
"as defined in BIP 141 (witness data is discounted).\n"
|
|
||||||
"\nArguments:\n"
|
|
||||||
"1. nblocks (numeric, required)\n"
|
|
||||||
"\nResult:\n"
|
|
||||||
"n (numeric) estimated fee-per-kilobyte\n"
|
|
||||||
"\n"
|
|
||||||
"A negative value is returned if not enough transactions and blocks\n"
|
|
||||||
"have been observed to make an estimate.\n"
|
|
||||||
"-1 is always returned for nblocks == 1 as it is impossible to calculate\n"
|
|
||||||
"a fee that is high enough to get reliably included in the next block.\n"
|
|
||||||
"\nExample:\n"
|
|
||||||
+ HelpExampleCli("estimatefee", "6")
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!IsDeprecatedRPCEnabled("estimatefee")) {
|
|
||||||
throw JSONRPCError(RPC_METHOD_DEPRECATED, "estimatefee is deprecated and will be fully removed in v0.17. "
|
|
||||||
"To use estimatefee in v0.16, restart bitcoind with -deprecatedrpc=estimatefee.\n"
|
|
||||||
"Projects should transition to using estimatesmartfee before upgrading to v0.17");
|
|
||||||
}
|
|
||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VNUM});
|
|
||||||
|
|
||||||
int nBlocks = request.params[0].get_int();
|
|
||||||
if (nBlocks < 1)
|
|
||||||
nBlocks = 1;
|
|
||||||
|
|
||||||
CFeeRate feeRate = ::feeEstimator.estimateFee(nBlocks);
|
|
||||||
if (feeRate == CFeeRate(0))
|
|
||||||
return -1.0;
|
|
||||||
|
|
||||||
return ValueFromAmount(feeRate.GetFeePerK());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue estimatesmartfee(const JSONRPCRequest& request)
|
UniValue estimatesmartfee(const JSONRPCRequest& request)
|
||||||
|
@ -986,7 +946,7 @@ static const CRPCCommand commands[] =
|
||||||
|
|
||||||
{ "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} },
|
{ "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} },
|
||||||
|
|
||||||
{ "util", "estimatefee", &estimatefee, {"nblocks"} },
|
{ "hidden", "estimatefee", &estimatefee, {} },
|
||||||
{ "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} },
|
{ "util", "estimatesmartfee", &estimatesmartfee, {"conf_target", "estimate_mode"} },
|
||||||
|
|
||||||
{ "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} },
|
{ "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} },
|
||||||
|
|
|
@ -262,9 +262,6 @@ UniValue createmultisig(const JSONRPCRequest& request)
|
||||||
std::string msg = "createmultisig nrequired [\"key\",...]\n"
|
std::string msg = "createmultisig nrequired [\"key\",...]\n"
|
||||||
"\nCreates a multi-signature address with n signature of m keys required.\n"
|
"\nCreates a multi-signature address with n signature of m keys required.\n"
|
||||||
"It returns a json object with the address and redeemScript.\n"
|
"It returns a json object with the address and redeemScript.\n"
|
||||||
"DEPRECATION WARNING: Using addresses with createmultisig is deprecated. Clients must\n"
|
|
||||||
"transition to using addmultisigaddress to create multisig addresses with addresses known\n"
|
|
||||||
"to the wallet before upgrading to v0.17. To use the deprecated functionality, start bitcoind with -deprecatedrpc=createmultisig\n"
|
|
||||||
"\nArguments:\n"
|
"\nArguments:\n"
|
||||||
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
|
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
|
||||||
"2. \"keys\" (string, required) A json array of hex-encoded public keys\n"
|
"2. \"keys\" (string, required) A json array of hex-encoded public keys\n"
|
||||||
|
@ -297,15 +294,8 @@ UniValue createmultisig(const JSONRPCRequest& request)
|
||||||
if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) {
|
if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) {
|
||||||
pubkeys.push_back(HexToPubKey(keys[i].get_str()));
|
pubkeys.push_back(HexToPubKey(keys[i].get_str()));
|
||||||
} else {
|
} else {
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
CWallet* const pwallet = GetWalletForJSONRPCRequest(request);
|
|
||||||
if (IsDeprecatedRPCEnabled("createmultisig") && EnsureWalletIsAvailable(pwallet, false)) {
|
|
||||||
pubkeys.push_back(AddrToPubKey(pwallet, keys[i].get_str()));
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\nNote that from v0.16, createmultisig no longer accepts addresses."
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\nNote that from v0.16, createmultisig no longer accepts addresses."
|
||||||
" Clients must transition to using addmultisigaddress to create multisig addresses with addresses known to the wallet before upgrading to v0.17."
|
" Users must use addmultisigaddress to create multisig addresses with addresses known to the wallet.", keys[i].get_str()));
|
||||||
" To use the deprecated functionality, start bitcoind with -deprecatedrpc=createmultisig", keys[i].get_str()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1192,10 +1192,6 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
|
||||||
" \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
|
" \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
|
||||||
" \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
|
" \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"\nResult (DEPRECATED. To see this result in v0.16 instead, please start bitcoind with -deprecatedrpc=addmultisigaddress).\n"
|
|
||||||
" clients should transition to the new output api before upgrading to v0.17.\n"
|
|
||||||
"\"address\" (string) A bitcoin address associated with the keys.\n"
|
|
||||||
|
|
||||||
"\nExamples:\n"
|
"\nExamples:\n"
|
||||||
"\nAdd a multisig address from 2 addresses\n"
|
"\nAdd a multisig address from 2 addresses\n"
|
||||||
+ HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
|
+ HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
|
||||||
|
@ -1238,11 +1234,6 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
|
||||||
CTxDestination dest = pwallet->AddAndGetDestinationForScript(inner, output_type);
|
CTxDestination dest = pwallet->AddAndGetDestinationForScript(inner, output_type);
|
||||||
pwallet->SetAddressBook(dest, strAccount, "send");
|
pwallet->SetAddressBook(dest, strAccount, "send");
|
||||||
|
|
||||||
// Return old style interface
|
|
||||||
if (IsDeprecatedRPCEnabled("addmultisigaddress")) {
|
|
||||||
return EncodeDestination(dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
result.pushKV("address", EncodeDestination(dest));
|
result.pushKV("address", EncodeDestination(dest));
|
||||||
result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
|
result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
|
||||||
|
@ -3260,8 +3251,8 @@ UniValue bumpfee(const JSONRPCRequest& request)
|
||||||
"If the change output is not big enough to cover the increased fee, the command will currently fail\n"
|
"If the change output is not big enough to cover the increased fee, the command will currently fail\n"
|
||||||
"instead of adding new inputs to compensate. (A future implementation could improve this.)\n"
|
"instead of adding new inputs to compensate. (A future implementation could improve this.)\n"
|
||||||
"The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
|
"The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
|
||||||
"By default, the new fee will be calculated automatically using estimatefee.\n"
|
"By default, the new fee will be calculated automatically using estimatesmartfee.\n"
|
||||||
"The user can specify a confirmation target for estimatefee.\n"
|
"The user can specify a confirmation target for estimatesmartfee.\n"
|
||||||
"Alternatively, the user can specify totalFee, or use RPC settxfee to set a higher fee rate.\n"
|
"Alternatively, the user can specify totalFee, or use RPC settxfee to set a higher fee rate.\n"
|
||||||
"At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
|
"At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
|
||||||
"returned by getnetworkinfo) to enter the node's mempool.\n"
|
"returned by getnetworkinfo) to enter the node's mempool.\n"
|
||||||
|
|
|
@ -3,39 +3,47 @@
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test fee estimation code."""
|
"""Test fee estimation code."""
|
||||||
|
from decimal import Decimal
|
||||||
|
import random
|
||||||
|
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
|
||||||
from test_framework.util import *
|
|
||||||
from test_framework.script import CScript, OP_1, OP_DROP, OP_2, OP_HASH160, OP_EQUAL, hash160, OP_TRUE
|
|
||||||
from test_framework.mininode import CTransaction, CTxIn, CTxOut, COutPoint, ToHex, COIN
|
from test_framework.mininode import CTransaction, CTxIn, CTxOut, COutPoint, ToHex, COIN
|
||||||
|
from test_framework.script import CScript, OP_1, OP_DROP, OP_2, OP_HASH160, OP_EQUAL, hash160, OP_TRUE
|
||||||
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
|
from test_framework.util import (
|
||||||
|
assert_equal,
|
||||||
|
assert_greater_than,
|
||||||
|
assert_greater_than_or_equal,
|
||||||
|
connect_nodes,
|
||||||
|
satoshi_round,
|
||||||
|
sync_blocks,
|
||||||
|
sync_mempools,
|
||||||
|
)
|
||||||
|
|
||||||
# Construct 2 trivial P2SH's and the ScriptSigs that spend them
|
# Construct 2 trivial P2SH's and the ScriptSigs that spend them
|
||||||
# So we can create many transactions without needing to spend
|
# So we can create many transactions without needing to spend
|
||||||
# time signing.
|
# time signing.
|
||||||
redeem_script_1 = CScript([OP_1, OP_DROP])
|
REDEEM_SCRIPT_1 = CScript([OP_1, OP_DROP])
|
||||||
redeem_script_2 = CScript([OP_2, OP_DROP])
|
REDEEM_SCRIPT_2 = CScript([OP_2, OP_DROP])
|
||||||
P2SH_1 = CScript([OP_HASH160, hash160(redeem_script_1), OP_EQUAL])
|
P2SH_1 = CScript([OP_HASH160, hash160(REDEEM_SCRIPT_1), OP_EQUAL])
|
||||||
P2SH_2 = CScript([OP_HASH160, hash160(redeem_script_2), OP_EQUAL])
|
P2SH_2 = CScript([OP_HASH160, hash160(REDEEM_SCRIPT_2), OP_EQUAL])
|
||||||
|
|
||||||
# Associated ScriptSig's to spend satisfy P2SH_1 and P2SH_2
|
# Associated ScriptSig's to spend satisfy P2SH_1 and P2SH_2
|
||||||
SCRIPT_SIG = [CScript([OP_TRUE, redeem_script_1]), CScript([OP_TRUE, redeem_script_2])]
|
SCRIPT_SIG = [CScript([OP_TRUE, REDEEM_SCRIPT_1]), CScript([OP_TRUE, REDEEM_SCRIPT_2])]
|
||||||
|
|
||||||
global log
|
|
||||||
|
|
||||||
def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment):
|
def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment):
|
||||||
"""
|
"""Create and send a transaction with a random fee.
|
||||||
Create and send a transaction with a random fee.
|
|
||||||
The transaction pays to a trivial P2SH script, and assumes that its inputs
|
The transaction pays to a trivial P2SH script, and assumes that its inputs
|
||||||
are of the same form.
|
are of the same form.
|
||||||
The function takes a list of confirmed outputs and unconfirmed outputs
|
The function takes a list of confirmed outputs and unconfirmed outputs
|
||||||
and attempts to use the confirmed list first for its inputs.
|
and attempts to use the confirmed list first for its inputs.
|
||||||
It adds the newly created outputs to the unconfirmed list.
|
It adds the newly created outputs to the unconfirmed list.
|
||||||
Returns (raw transaction, fee)
|
Returns (raw transaction, fee)."""
|
||||||
"""
|
|
||||||
# It's best to exponentially distribute our random fees
|
# It's best to exponentially distribute our random fees
|
||||||
# because the buckets are exponentially spaced.
|
# because the buckets are exponentially spaced.
|
||||||
# Exponentially distributed from 1-128 * fee_increment
|
# Exponentially distributed from 1-128 * fee_increment
|
||||||
rand_fee = float(fee_increment)*(1.1892**random.randint(0,28))
|
rand_fee = float(fee_increment) * (1.1892 ** random.randint(0, 28))
|
||||||
# Total fee ranges from min_fee to min_fee + 127*fee_increment
|
# Total fee ranges from min_fee to min_fee + 127*fee_increment
|
||||||
fee = min_fee - fee_increment + satoshi_round(rand_fee)
|
fee = min_fee - fee_increment + satoshi_round(rand_fee)
|
||||||
tx = CTransaction()
|
tx = CTransaction()
|
||||||
|
@ -50,95 +58,69 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee
|
||||||
total_in += t["amount"]
|
total_in += t["amount"]
|
||||||
tx.vin.append(CTxIn(COutPoint(int(t["txid"], 16), t["vout"]), b""))
|
tx.vin.append(CTxIn(COutPoint(int(t["txid"], 16), t["vout"]), b""))
|
||||||
if total_in <= amount + fee:
|
if total_in <= amount + fee:
|
||||||
raise RuntimeError("Insufficient funds: need %d, have %d"%(amount+fee, total_in))
|
raise RuntimeError("Insufficient funds: need %d, have %d" % (amount + fee, total_in))
|
||||||
tx.vout.append(CTxOut(int((total_in - amount - fee)*COIN), P2SH_1))
|
tx.vout.append(CTxOut(int((total_in - amount - fee) * COIN), P2SH_1))
|
||||||
tx.vout.append(CTxOut(int(amount*COIN), P2SH_2))
|
tx.vout.append(CTxOut(int(amount * COIN), P2SH_2))
|
||||||
# These transactions don't need to be signed, but we still have to insert
|
# These transactions don't need to be signed, but we still have to insert
|
||||||
# the ScriptSig that will satisfy the ScriptPubKey.
|
# the ScriptSig that will satisfy the ScriptPubKey.
|
||||||
for inp in tx.vin:
|
for inp in tx.vin:
|
||||||
inp.scriptSig = SCRIPT_SIG[inp.prevout.n]
|
inp.scriptSig = SCRIPT_SIG[inp.prevout.n]
|
||||||
txid = from_node.sendrawtransaction(ToHex(tx), True)
|
txid = from_node.sendrawtransaction(ToHex(tx), True)
|
||||||
unconflist.append({ "txid" : txid, "vout" : 0 , "amount" : total_in - amount - fee})
|
unconflist.append({"txid": txid, "vout": 0, "amount": total_in - amount - fee})
|
||||||
unconflist.append({ "txid" : txid, "vout" : 1 , "amount" : amount})
|
unconflist.append({"txid": txid, "vout": 1, "amount": amount})
|
||||||
|
|
||||||
return (ToHex(tx), fee)
|
return (ToHex(tx), fee)
|
||||||
|
|
||||||
def split_inputs(from_node, txins, txouts, initial_split = False):
|
def split_inputs(from_node, txins, txouts, initial_split=False):
|
||||||
"""
|
"""Generate a lot of inputs so we can generate a ton of transactions.
|
||||||
We need to generate a lot of inputs so we can generate a ton of transactions.
|
|
||||||
This function takes an input from txins, and creates and sends a transaction
|
This function takes an input from txins, and creates and sends a transaction
|
||||||
which splits the value into 2 outputs which are appended to txouts.
|
which splits the value into 2 outputs which are appended to txouts.
|
||||||
Previously this was designed to be small inputs so they wouldn't have
|
Previously this was designed to be small inputs so they wouldn't have
|
||||||
a high coin age when the notion of priority still existed.
|
a high coin age when the notion of priority still existed."""
|
||||||
"""
|
|
||||||
prevtxout = txins.pop()
|
prevtxout = txins.pop()
|
||||||
tx = CTransaction()
|
tx = CTransaction()
|
||||||
tx.vin.append(CTxIn(COutPoint(int(prevtxout["txid"], 16), prevtxout["vout"]), b""))
|
tx.vin.append(CTxIn(COutPoint(int(prevtxout["txid"], 16), prevtxout["vout"]), b""))
|
||||||
|
|
||||||
half_change = satoshi_round(prevtxout["amount"]/2)
|
half_change = satoshi_round(prevtxout["amount"] / 2)
|
||||||
rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000")
|
rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000")
|
||||||
tx.vout.append(CTxOut(int(half_change*COIN), P2SH_1))
|
tx.vout.append(CTxOut(int(half_change * COIN), P2SH_1))
|
||||||
tx.vout.append(CTxOut(int(rem_change*COIN), P2SH_2))
|
tx.vout.append(CTxOut(int(rem_change * COIN), P2SH_2))
|
||||||
|
|
||||||
# If this is the initial split we actually need to sign the transaction
|
# If this is the initial split we actually need to sign the transaction
|
||||||
# Otherwise we just need to insert the proper ScriptSig
|
# Otherwise we just need to insert the proper ScriptSig
|
||||||
if (initial_split) :
|
if (initial_split):
|
||||||
completetx = from_node.signrawtransaction(ToHex(tx))["hex"]
|
completetx = from_node.signrawtransaction(ToHex(tx))["hex"]
|
||||||
else :
|
else:
|
||||||
tx.vin[0].scriptSig = SCRIPT_SIG[prevtxout["vout"]]
|
tx.vin[0].scriptSig = SCRIPT_SIG[prevtxout["vout"]]
|
||||||
completetx = ToHex(tx)
|
completetx = ToHex(tx)
|
||||||
txid = from_node.sendrawtransaction(completetx, True)
|
txid = from_node.sendrawtransaction(completetx, True)
|
||||||
txouts.append({ "txid" : txid, "vout" : 0 , "amount" : half_change})
|
txouts.append({"txid": txid, "vout": 0, "amount": half_change})
|
||||||
txouts.append({ "txid" : txid, "vout" : 1 , "amount" : rem_change})
|
txouts.append({"txid": txid, "vout": 1, "amount": rem_change})
|
||||||
|
|
||||||
|
def check_estimates(node, fees_seen, max_invalid):
|
||||||
|
"""Call estimatesmartfee and verify that the estimates meet certain invariants."""
|
||||||
|
|
||||||
def check_estimates(node, fees_seen, max_invalid, print_estimates = True):
|
|
||||||
"""
|
|
||||||
This function calls estimatefee and verifies that the estimates
|
|
||||||
meet certain invariants.
|
|
||||||
"""
|
|
||||||
all_estimates = [ node.estimatefee(i) for i in range(1,26) ]
|
|
||||||
if print_estimates:
|
|
||||||
log.info([str(all_estimates[e-1]) for e in [1,2,3,6,15,25]])
|
|
||||||
delta = 1.0e-6 # account for rounding error
|
delta = 1.0e-6 # account for rounding error
|
||||||
last_e = max(fees_seen)
|
last_feerate = float(max(fees_seen))
|
||||||
for e in [x for x in all_estimates if x >= 0]:
|
all_smart_estimates = [node.estimatesmartfee(i) for i in range(1, 26)]
|
||||||
# Estimates should be within the bounds of what transactions fees actually were:
|
for i, e in enumerate(all_smart_estimates): # estimate is for i+1
|
||||||
if float(e)+delta < min(fees_seen) or float(e)-delta > max(fees_seen):
|
feerate = float(e["feerate"])
|
||||||
|
assert_greater_than(feerate, 0)
|
||||||
|
|
||||||
|
if feerate + delta < min(fees_seen) or feerate - delta > max(fees_seen):
|
||||||
raise AssertionError("Estimated fee (%f) out of range (%f,%f)"
|
raise AssertionError("Estimated fee (%f) out of range (%f,%f)"
|
||||||
%(float(e), min(fees_seen), max(fees_seen)))
|
% (feerate, min(fees_seen), max(fees_seen)))
|
||||||
# Estimates should be monotonically decreasing
|
if feerate - delta > last_feerate:
|
||||||
if float(e)-delta > last_e:
|
|
||||||
raise AssertionError("Estimated fee (%f) larger than last fee (%f) for lower number of confirms"
|
raise AssertionError("Estimated fee (%f) larger than last fee (%f) for lower number of confirms"
|
||||||
%(float(e),float(last_e)))
|
% (feerate, last_feerate))
|
||||||
last_e = e
|
last_feerate = feerate
|
||||||
valid_estimate = False
|
|
||||||
invalid_estimates = 0
|
|
||||||
for i,e in enumerate(all_estimates): # estimate is for i+1
|
|
||||||
if e >= 0:
|
|
||||||
valid_estimate = True
|
|
||||||
if i >= 13: # for n>=14 estimatesmartfee(n/2) should be at least as high as estimatefee(n)
|
|
||||||
assert(node.estimatesmartfee((i+1)//2)["feerate"] > float(e) - delta)
|
|
||||||
|
|
||||||
|
if i == 0:
|
||||||
|
assert_equal(e["blocks"], 2)
|
||||||
else:
|
else:
|
||||||
invalid_estimates += 1
|
assert_greater_than_or_equal(i + 1, e["blocks"])
|
||||||
|
|
||||||
# estimatesmartfee should still be valid
|
|
||||||
approx_estimate = node.estimatesmartfee(i+1)["feerate"]
|
|
||||||
answer_found = node.estimatesmartfee(i+1)["blocks"]
|
|
||||||
assert(approx_estimate > 0)
|
|
||||||
assert(answer_found > i+1)
|
|
||||||
|
|
||||||
# Once we're at a high enough confirmation count that we can give an estimate
|
|
||||||
# We should have estimates for all higher confirmation counts
|
|
||||||
if valid_estimate:
|
|
||||||
raise AssertionError("Invalid estimate appears at higher confirm count than valid estimate")
|
|
||||||
|
|
||||||
# Check on the expected number of different confirmation counts
|
|
||||||
# that we might not have valid estimates for
|
|
||||||
if invalid_estimates > max_invalid:
|
|
||||||
raise AssertionError("More than (%d) invalid estimates"%(max_invalid))
|
|
||||||
return all_estimates
|
|
||||||
|
|
||||||
|
|
||||||
class EstimateFeeTest(BitcoinTestFramework):
|
class EstimateFeeTest(BitcoinTestFramework):
|
||||||
def set_test_params(self):
|
def set_test_params(self):
|
||||||
|
@ -151,7 +133,7 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||||
which we will use to generate our transactions.
|
which we will use to generate our transactions.
|
||||||
"""
|
"""
|
||||||
self.add_nodes(3, extra_args=[["-maxorphantx=1000", "-whitelist=127.0.0.1"],
|
self.add_nodes(3, extra_args=[["-maxorphantx=1000", "-whitelist=127.0.0.1"],
|
||||||
["-blockmaxsize=17000", "-maxorphantx=1000", "-deprecatedrpc=estimatefee"],
|
["-blockmaxsize=17000", "-maxorphantx=1000"],
|
||||||
["-blockmaxsize=8000", "-maxorphantx=1000"]])
|
["-blockmaxsize=8000", "-maxorphantx=1000"]])
|
||||||
# Use node0 to mine blocks for input splitting
|
# Use node0 to mine blocks for input splitting
|
||||||
# Node1 mines small blocks but that are bigger than the expected transaction rate.
|
# Node1 mines small blocks but that are bigger than the expected transaction rate.
|
||||||
|
@ -160,7 +142,6 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||||
# Node2 is a stingy miner, that
|
# Node2 is a stingy miner, that
|
||||||
# produces too small blocks (room for only 55 or so transactions)
|
# produces too small blocks (room for only 55 or so transactions)
|
||||||
|
|
||||||
|
|
||||||
def transact_and_mine(self, numblocks, mining_node):
|
def transact_and_mine(self, numblocks, mining_node):
|
||||||
min_fee = Decimal("0.00001")
|
min_fee = Decimal("0.00001")
|
||||||
# We will now mine numblocks blocks generating on average 100 transactions between each block
|
# We will now mine numblocks blocks generating on average 100 transactions between each block
|
||||||
|
@ -169,14 +150,14 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||||
# resorting to tx's that depend on the mempool when those run out
|
# resorting to tx's that depend on the mempool when those run out
|
||||||
for i in range(numblocks):
|
for i in range(numblocks):
|
||||||
random.shuffle(self.confutxo)
|
random.shuffle(self.confutxo)
|
||||||
for j in range(random.randrange(100-50,100+50)):
|
for j in range(random.randrange(100 - 50, 100 + 50)):
|
||||||
from_index = random.randint(1,2)
|
from_index = random.randint(1, 2)
|
||||||
(txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo,
|
(txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo,
|
||||||
self.memutxo, Decimal("0.005"), min_fee, min_fee)
|
self.memutxo, Decimal("0.005"), min_fee, min_fee)
|
||||||
tx_kbytes = (len(txhex) // 2) / 1000.0
|
tx_kbytes = (len(txhex) // 2) / 1000.0
|
||||||
self.fees_per_kb.append(float(fee)/tx_kbytes)
|
self.fees_per_kb.append(float(fee) / tx_kbytes)
|
||||||
sync_mempools(self.nodes[0:3], wait=.1)
|
sync_mempools(self.nodes[0:3], wait=.1)
|
||||||
mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"]
|
mined = mining_node.getblock(mining_node.generate(1)[0], True)["tx"]
|
||||||
sync_blocks(self.nodes[0:3], wait=.1)
|
sync_blocks(self.nodes[0:3], wait=.1)
|
||||||
# update which txouts are confirmed
|
# update which txouts are confirmed
|
||||||
newmem = []
|
newmem = []
|
||||||
|
@ -191,10 +172,6 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||||
self.log.info("This test is time consuming, please be patient")
|
self.log.info("This test is time consuming, please be patient")
|
||||||
self.log.info("Splitting inputs so we can generate tx's")
|
self.log.info("Splitting inputs so we can generate tx's")
|
||||||
|
|
||||||
# Make log handler available to helper functions
|
|
||||||
global log
|
|
||||||
log = self.log
|
|
||||||
|
|
||||||
# Start node0
|
# Start node0
|
||||||
self.start_node(0)
|
self.start_node(0)
|
||||||
self.txouts = []
|
self.txouts = []
|
||||||
|
@ -210,13 +187,13 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||||
# Use txouts to monitor the available utxo, since these won't be tracked in wallet
|
# Use txouts to monitor the available utxo, since these won't be tracked in wallet
|
||||||
reps = 0
|
reps = 0
|
||||||
while (reps < 5):
|
while (reps < 5):
|
||||||
#Double txouts to txouts2
|
# Double txouts to txouts2
|
||||||
while (len(self.txouts)>0):
|
while (len(self.txouts) > 0):
|
||||||
split_inputs(self.nodes[0], self.txouts, self.txouts2)
|
split_inputs(self.nodes[0], self.txouts, self.txouts2)
|
||||||
while (len(self.nodes[0].getrawmempool()) > 0):
|
while (len(self.nodes[0].getrawmempool()) > 0):
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
#Double txouts2 to txouts
|
# Double txouts2 to txouts
|
||||||
while (len(self.txouts2)>0):
|
while (len(self.txouts2) > 0):
|
||||||
split_inputs(self.nodes[0], self.txouts2, self.txouts)
|
split_inputs(self.nodes[0], self.txouts2, self.txouts)
|
||||||
while (len(self.nodes[0].getrawmempool()) > 0):
|
while (len(self.nodes[0].getrawmempool()) > 0):
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
|
|
|
@ -4,24 +4,24 @@
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test deprecation of RPC calls."""
|
"""Test deprecation of RPC calls."""
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import assert_raises_rpc_error
|
|
||||||
|
|
||||||
class DeprecatedRpcTest(BitcoinTestFramework):
|
class DeprecatedRpcTest(BitcoinTestFramework):
|
||||||
def set_test_params(self):
|
def set_test_params(self):
|
||||||
self.num_nodes = 2
|
self.num_nodes = 2
|
||||||
self.setup_clean_chain = True
|
self.setup_clean_chain = True
|
||||||
self.extra_args = [[], ["-deprecatedrpc=estimatefee", "-deprecatedrpc=createmultisig"]]
|
self.extra_args = [[], []]
|
||||||
|
|
||||||
def run_test(self):
|
def run_test(self):
|
||||||
self.log.info("estimatefee: Shows deprecated message")
|
# This test should be used to verify correct behaviour of deprecated
|
||||||
assert_raises_rpc_error(-32, 'estimatefee is deprecated', self.nodes[0].estimatefee, 1)
|
# RPC methods with and without the -deprecatedrpc flags. For example:
|
||||||
|
#
|
||||||
self.log.info("Using -deprecatedrpc=estimatefee bypasses the error")
|
# self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses")
|
||||||
self.nodes[1].estimatefee(1)
|
# assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()])
|
||||||
|
# self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()])
|
||||||
self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses")
|
#
|
||||||
assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()])
|
# There are currently no deprecated RPC methods in master, so this
|
||||||
self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()])
|
# test is currently empty.
|
||||||
|
pass
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
DeprecatedRpcTest().main()
|
DeprecatedRpcTest().main()
|
||||||
|
|
Loading…
Reference in a new issue