Auto merge of #3336 - arcalinea:expiryheight-createrawtransaction, r=bitcartel
Take expiryheight as param to createrawtransaction Addresses #3333
This commit is contained in:
commit
a11e6aaacc
|
@ -6,6 +6,7 @@
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import assert_equal, initialize_chain_clean, \
|
from test_framework.util import assert_equal, initialize_chain_clean, \
|
||||||
start_nodes, connect_nodes_bi, wait_and_assert_operationid_status
|
start_nodes, connect_nodes_bi, wait_and_assert_operationid_status
|
||||||
|
from test_framework.authproxy import JSONRPCException
|
||||||
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
|
@ -46,6 +47,13 @@ class WalletOverwinterTxTest (BitcoinTestFramework):
|
||||||
assert_equal(bci['consensus']['nextblock'], '00000000')
|
assert_equal(bci['consensus']['nextblock'], '00000000')
|
||||||
assert_equal(bci['upgrades']['5ba81b19']['status'], 'pending')
|
assert_equal(bci['upgrades']['5ba81b19']['status'], 'pending')
|
||||||
|
|
||||||
|
# Cannot use the expiryheight parameter of createrawtransaction if Overwinter is not active in the next block
|
||||||
|
try:
|
||||||
|
self.nodes[0].createrawtransaction([], {}, 0, 99)
|
||||||
|
except JSONRPCException,e:
|
||||||
|
errorString = e.error['message']
|
||||||
|
assert_equal("Invalid parameter, expiryheight can only be used if Overwinter is active when the transaction is mined" in errorString, True)
|
||||||
|
|
||||||
# Node 0 sends transparent funds to Node 2
|
# Node 0 sends transparent funds to Node 2
|
||||||
tsendamount = Decimal('1.0')
|
tsendamount = Decimal('1.0')
|
||||||
txid_transparent = self.nodes[0].sendtoaddress(taddr2, tsendamount)
|
txid_transparent = self.nodes[0].sendtoaddress(taddr2, tsendamount)
|
||||||
|
@ -92,6 +100,24 @@ class WalletOverwinterTxTest (BitcoinTestFramework):
|
||||||
assert_equal(bci['consensus']['nextblock'], '5ba81b19')
|
assert_equal(bci['consensus']['nextblock'], '5ba81b19')
|
||||||
assert_equal(bci['upgrades']['5ba81b19']['status'], 'pending')
|
assert_equal(bci['upgrades']['5ba81b19']['status'], 'pending')
|
||||||
|
|
||||||
|
# Test using expiryheight parameter of createrawtransaction when Overwinter is active in the next block
|
||||||
|
errorString = ""
|
||||||
|
try:
|
||||||
|
self.nodes[0].createrawtransaction([], {}, 0, 499999999)
|
||||||
|
except JSONRPCException,e:
|
||||||
|
errorString = e.error['message']
|
||||||
|
assert_equal("", errorString)
|
||||||
|
try:
|
||||||
|
self.nodes[0].createrawtransaction([], {}, 0, -1)
|
||||||
|
except JSONRPCException,e:
|
||||||
|
errorString = e.error['message']
|
||||||
|
assert_equal("Invalid parameter, expiryheight must be nonnegative and less than 500000000" in errorString, True)
|
||||||
|
try:
|
||||||
|
self.nodes[0].createrawtransaction([], {}, 0, 500000000)
|
||||||
|
except JSONRPCException,e:
|
||||||
|
errorString = e.error['message']
|
||||||
|
assert_equal("Invalid parameter, expiryheight must be nonnegative and less than 500000000" in errorString, True)
|
||||||
|
|
||||||
# Node 0 sends transparent funds to Node 3
|
# Node 0 sends transparent funds to Node 3
|
||||||
tsendamount = Decimal('1.0')
|
tsendamount = Decimal('1.0')
|
||||||
txid_transparent = self.nodes[0].sendtoaddress(taddr3, tsendamount)
|
txid_transparent = self.nodes[0].sendtoaddress(taddr3, tsendamount)
|
||||||
|
|
|
@ -77,6 +77,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||||
{ "createrawtransaction", 0 },
|
{ "createrawtransaction", 0 },
|
||||||
{ "createrawtransaction", 1 },
|
{ "createrawtransaction", 1 },
|
||||||
{ "createrawtransaction", 2 },
|
{ "createrawtransaction", 2 },
|
||||||
|
{ "createrawtransaction", 3 },
|
||||||
{ "signrawtransaction", 1 },
|
{ "signrawtransaction", 1 },
|
||||||
{ "signrawtransaction", 2 },
|
{ "signrawtransaction", 2 },
|
||||||
{ "sendrawtransaction", 1 },
|
{ "sendrawtransaction", 1 },
|
||||||
|
@ -189,4 +190,3 @@ UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::s
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -410,9 +410,9 @@ UniValue verifytxoutproof(const UniValue& params, bool fHelp)
|
||||||
|
|
||||||
UniValue createrawtransaction(const UniValue& params, bool fHelp)
|
UniValue createrawtransaction(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() < 2 || params.size() > 3)
|
if (fHelp || params.size() < 2 || params.size() > 4)
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...} ( locktime )\n"
|
"createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...} ( locktime ) ( expiryheight )\n"
|
||||||
"\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
|
"\nCreate a transaction spending the given inputs and sending to the given addresses.\n"
|
||||||
"Returns hex-encoded raw transaction.\n"
|
"Returns hex-encoded raw transaction.\n"
|
||||||
"Note that the transaction's inputs are not signed, and\n"
|
"Note that the transaction's inputs are not signed, and\n"
|
||||||
|
@ -434,6 +434,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
|
||||||
" ,...\n"
|
" ,...\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
|
"3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
|
||||||
|
"4. expiryheight (numeric, optional, default=" + strprintf("%d", DEFAULT_TX_EXPIRY_DELTA) + ") Expiry height of transaction (if Overwinter is active)\n"
|
||||||
"\nResult:\n"
|
"\nResult:\n"
|
||||||
"\"transaction\" (string) hex string of the transaction\n"
|
"\"transaction\" (string) hex string of the transaction\n"
|
||||||
|
|
||||||
|
@ -443,7 +444,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
|
||||||
);
|
);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM), true);
|
RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM)(UniValue::VNUM), true);
|
||||||
if (params[0].isNull() || params[1].isNull())
|
if (params[0].isNull() || params[1].isNull())
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null");
|
||||||
|
|
||||||
|
@ -454,12 +455,6 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
|
||||||
CMutableTransaction rawTx = CreateNewContextualCMutableTransaction(
|
CMutableTransaction rawTx = CreateNewContextualCMutableTransaction(
|
||||||
Params().GetConsensus(), nextBlockHeight);
|
Params().GetConsensus(), nextBlockHeight);
|
||||||
|
|
||||||
if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
|
||||||
if (rawTx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD){
|
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "nExpiryHeight must be less than TX_EXPIRY_HEIGHT_THRESHOLD.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params.size() > 2 && !params[2].isNull()) {
|
if (params.size() > 2 && !params[2].isNull()) {
|
||||||
int64_t nLockTime = params[2].get_int64();
|
int64_t nLockTime = params[2].get_int64();
|
||||||
if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
|
if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max())
|
||||||
|
@ -467,6 +462,18 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
|
||||||
rawTx.nLockTime = nLockTime;
|
rawTx.nLockTime = nLockTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params.size() > 3 && !params[3].isNull()) {
|
||||||
|
if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
|
||||||
|
int64_t nExpiryHeight = params[3].get_int64();
|
||||||
|
if (nExpiryHeight < 0 || nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, expiryheight must be nonnegative and less than %d.", TX_EXPIRY_HEIGHT_THRESHOLD));
|
||||||
|
}
|
||||||
|
rawTx.nExpiryHeight = nExpiryHeight;
|
||||||
|
} else {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expiryheight can only be used if Overwinter is active when the transaction is mined");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t idx = 0; idx < inputs.size(); idx++) {
|
for (size_t idx = 0; idx < inputs.size(); idx++) {
|
||||||
const UniValue& input = inputs[idx];
|
const UniValue& input = inputs[idx];
|
||||||
const UniValue& o = input.get_obj();
|
const UniValue& o = input.get_obj();
|
||||||
|
|
|
@ -73,6 +73,8 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams)
|
||||||
BOOST_CHECK_THROW(CallRPC("createrawtransaction {} {}"), runtime_error);
|
BOOST_CHECK_THROW(CallRPC("createrawtransaction {} {}"), runtime_error);
|
||||||
BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [] {}"));
|
BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [] {}"));
|
||||||
BOOST_CHECK_THROW(CallRPC("createrawtransaction [] {} extra"), runtime_error);
|
BOOST_CHECK_THROW(CallRPC("createrawtransaction [] {} extra"), runtime_error);
|
||||||
|
BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [] {} 0"));
|
||||||
|
BOOST_CHECK_THROW(CallRPC("createrawtransaction [] {} 0 0"), runtime_error); // Overwinter is not active
|
||||||
|
|
||||||
BOOST_CHECK_THROW(CallRPC("decoderawtransaction"), runtime_error);
|
BOOST_CHECK_THROW(CallRPC("decoderawtransaction"), runtime_error);
|
||||||
BOOST_CHECK_THROW(CallRPC("decoderawtransaction null"), runtime_error);
|
BOOST_CHECK_THROW(CallRPC("decoderawtransaction null"), runtime_error);
|
||||||
|
|
Loading…
Reference in New Issue