Merge #7957: [RPC][Bitcoin-TX] Add support for sequence number
ae357d5
[Bitcoin-Tx] Add tests for sequence number support (Jonas Schnelli)e59336f
[bitcoin-tx] allow to set nSequence number over the in= command (Jonas Schnelli)a946bb6
[RPC] createrawtransaction: add option to set the sequence number per input (Jonas Schnelli)
This commit is contained in:
commit
79004d4ae6
6 changed files with 41 additions and 8 deletions
|
@ -138,5 +138,11 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
|
assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
|
||||||
|
|
||||||
|
inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 1000}]
|
||||||
|
outputs = { self.nodes[0].getnewaddress() : 1 }
|
||||||
|
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
|
||||||
|
decrawtx= self.nodes[0].decoderawtransaction(rawtx)
|
||||||
|
assert_equal(decrawtx['vin'][0]['sequence'], 1000)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
RawTransactionsTest().main()
|
RawTransactionsTest().main()
|
||||||
|
|
|
@ -71,7 +71,7 @@ static bool AppInitRawTx(int argc, char* argv[])
|
||||||
strUsage = HelpMessageGroup(_("Commands:"));
|
strUsage = HelpMessageGroup(_("Commands:"));
|
||||||
strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
|
strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
|
||||||
strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
|
strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
|
||||||
strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX"));
|
strUsage += HelpMessageOpt("in=TXID:VOUT(:SEQUENCE_NUMBER)", _("Add input to TX"));
|
||||||
strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
|
strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
|
||||||
strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
|
strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
|
||||||
strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
|
strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
|
||||||
|
@ -181,15 +181,15 @@ static void MutateTxLocktime(CMutableTransaction& tx, const string& cmdVal)
|
||||||
|
|
||||||
static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
|
static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
|
||||||
{
|
{
|
||||||
|
std::vector<std::string> vStrInputParts;
|
||||||
|
boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
|
||||||
|
|
||||||
// separate TXID:VOUT in string
|
// separate TXID:VOUT in string
|
||||||
size_t pos = strInput.find(':');
|
if (vStrInputParts.size()<2)
|
||||||
if ((pos == string::npos) ||
|
|
||||||
(pos == 0) ||
|
|
||||||
(pos == (strInput.size() - 1)))
|
|
||||||
throw runtime_error("TX input missing separator");
|
throw runtime_error("TX input missing separator");
|
||||||
|
|
||||||
// extract and validate TXID
|
// extract and validate TXID
|
||||||
string strTxid = strInput.substr(0, pos);
|
string strTxid = vStrInputParts[0];
|
||||||
if ((strTxid.size() != 64) || !IsHex(strTxid))
|
if ((strTxid.size() != 64) || !IsHex(strTxid))
|
||||||
throw runtime_error("invalid TX input txid");
|
throw runtime_error("invalid TX input txid");
|
||||||
uint256 txid(uint256S(strTxid));
|
uint256 txid(uint256S(strTxid));
|
||||||
|
@ -198,13 +198,18 @@ static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
|
||||||
static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz;
|
static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz;
|
||||||
|
|
||||||
// extract and validate vout
|
// extract and validate vout
|
||||||
string strVout = strInput.substr(pos + 1, string::npos);
|
string strVout = vStrInputParts[1];
|
||||||
int vout = atoi(strVout);
|
int vout = atoi(strVout);
|
||||||
if ((vout < 0) || (vout > (int)maxVout))
|
if ((vout < 0) || (vout > (int)maxVout))
|
||||||
throw runtime_error("invalid TX input vout");
|
throw runtime_error("invalid TX input vout");
|
||||||
|
|
||||||
|
// extract the optional sequence number
|
||||||
|
uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max();
|
||||||
|
if (vStrInputParts.size() > 2)
|
||||||
|
nSequenceIn = atoi(vStrInputParts[2]);
|
||||||
|
|
||||||
// append to transaction input list
|
// append to transaction input list
|
||||||
CTxIn txin(txid, vout);
|
CTxIn txin(txid, vout, CScript(), nSequenceIn);
|
||||||
tx.vin.push_back(txin);
|
tx.vin.push_back(txin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -334,6 +334,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
|
||||||
" {\n"
|
" {\n"
|
||||||
" \"txid\":\"id\", (string, required) The transaction id\n"
|
" \"txid\":\"id\", (string, required) The transaction id\n"
|
||||||
" \"vout\":n (numeric, required) The output number\n"
|
" \"vout\":n (numeric, required) The output number\n"
|
||||||
|
" \"sequence\":n (numeric, optional) The sequence number\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" ,...\n"
|
" ,...\n"
|
||||||
" ]\n"
|
" ]\n"
|
||||||
|
@ -384,6 +385,12 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
|
||||||
|
|
||||||
uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());
|
uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());
|
||||||
|
|
||||||
|
// set the sequence number if passed in the parameters object
|
||||||
|
const UniValue& sequenceObj = find_value(o, "sequence");
|
||||||
|
if (sequenceObj.isNum())
|
||||||
|
nSequence = sequenceObj.get_int();
|
||||||
|
|
||||||
CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
|
CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
|
||||||
|
|
||||||
rawTx.vin.push_back(in);
|
rawTx.vin.push_back(in);
|
||||||
|
|
|
@ -86,5 +86,18 @@
|
||||||
"outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
|
"outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
|
||||||
"outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"],
|
"outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"],
|
||||||
"output_cmp": "txcreatedata2.hex"
|
"output_cmp": "txcreatedata2.hex"
|
||||||
|
},
|
||||||
|
{ "exec": "./bitcoin-tx",
|
||||||
|
"args":
|
||||||
|
["-create",
|
||||||
|
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:4294967293",
|
||||||
|
"outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"],
|
||||||
|
"output_cmp": "txcreatedata_seq0.hex"
|
||||||
|
},
|
||||||
|
{ "exec": "./bitcoin-tx",
|
||||||
|
"args":
|
||||||
|
["01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000",
|
||||||
|
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"],
|
||||||
|
"output_cmp": "txcreatedata_seq1.hex"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
1
src/test/data/txcreatedata_seq0.hex
Normal file
1
src/test/data/txcreatedata_seq0.hex
Normal file
|
@ -0,0 +1 @@
|
||||||
|
01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000
|
1
src/test/data/txcreatedata_seq1.hex
Normal file
1
src/test/data/txcreatedata_seq1.hex
Normal file
|
@ -0,0 +1 @@
|
||||||
|
01000000021f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff1f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000010000000180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000
|
Loading…
Reference in a new issue