Skip to content

Commit ed8d693

Browse files
committed
Merge #9194: Add option to return non-segwit serialization via rpc
412bab2 Adapt ZMQ/rest serialization to take rpcserialversion arg (instagibbs) bc7ff8d Add option to return non-segwit serialization via rpc (Gregory Sanders)
2 parents 7d5d449 + 412bab2 commit ed8d693

File tree

11 files changed

+45
-13
lines changed

11 files changed

+45
-13
lines changed

qa/rpc-tests/segwit.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from test_framework.address import script_to_p2sh, key_to_p2pkh
1414
from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG
1515
from io import BytesIO
16+
from test_framework.mininode import FromHex
1617

1718
NODE_0 = 0
1819
NODE_1 = 1
@@ -84,8 +85,8 @@ def __init__(self):
8485

8586
def setup_network(self):
8687
self.nodes = []
87-
self.nodes.append(start_node(0, self.options.tmpdir, ["-logtimemicros", "-debug", "-walletprematurewitness"]))
88-
self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"]))
88+
self.nodes.append(start_node(0, self.options.tmpdir, ["-logtimemicros", "-debug", "-walletprematurewitness", "-rpcserialversion=0"]))
89+
self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-rpcserialversion=2"]))
8990
self.nodes.append(start_node(2, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=536870915", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"]))
9091
connect_nodes(self.nodes[1], 0)
9192
connect_nodes(self.nodes[2], 1)
@@ -211,7 +212,20 @@ def run_test(self):
211212
block = self.nodes[2].generate(1) #block 432 (first block with new rules; 432 = 144 * 3)
212213
sync_blocks(self.nodes)
213214
assert_equal(len(self.nodes[2].getrawmempool()), 0)
214-
assert_equal(len(self.nodes[2].getblock(block[0])["tx"]), 5)
215+
segwit_tx_list = self.nodes[2].getblock(block[0])["tx"]
216+
assert_equal(len(segwit_tx_list), 5)
217+
218+
print("Verify block and transaction serialization rpcs return differing serializations depending on rpc serialization flag")
219+
# Note: node1 has version 2, which is simply >0 and will catch future upgrades in tests
220+
assert(self.nodes[2].getblock(block[0], False) != self.nodes[0].getblock(block[0], False))
221+
assert(self.nodes[1].getblock(block[0], False) == self.nodes[2].getblock(block[0], False))
222+
for i in range(len(segwit_tx_list)):
223+
tx = FromHex(CTransaction(), self.nodes[2].gettransaction(segwit_tx_list[i])["hex"])
224+
assert(self.nodes[2].getrawtransaction(segwit_tx_list[i]) != self.nodes[0].getrawtransaction(segwit_tx_list[i]))
225+
assert(self.nodes[1].getrawtransaction(segwit_tx_list[i], 0) == self.nodes[2].getrawtransaction(segwit_tx_list[i]))
226+
assert(self.nodes[0].getrawtransaction(segwit_tx_list[i]) != self.nodes[2].gettransaction(segwit_tx_list[i])["hex"])
227+
assert(self.nodes[1].getrawtransaction(segwit_tx_list[i]) == self.nodes[2].gettransaction(segwit_tx_list[i])["hex"])
228+
assert(self.nodes[0].getrawtransaction(segwit_tx_list[i]) == bytes_to_hex_str(tx.serialize_without_witness()))
215229

216230
print("Verify witness txs without witness data are invalid after the fork")
217231
self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][2], False)

src/core_io.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strN
2626

2727
// core_write.cpp
2828
std::string FormatScript(const CScript& script);
29-
std::string EncodeHexTx(const CTransaction& tx);
29+
std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0);
3030
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
3131
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry);
3232

src/core_write.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode)
116116
return str;
117117
}
118118

119-
string EncodeHexTx(const CTransaction& tx)
119+
string EncodeHexTx(const CTransaction& tx, const int serialFlags)
120120
{
121-
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
121+
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | serialFlags);
122122
ssTx << tx;
123123
return HexStr(ssTx.begin(), ssTx.end());
124124
}

src/init.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ std::string HelpMessage(HelpMessageMode mode)
380380
strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort()));
381381
strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy"));
382382
strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE));
383+
strUsage += HelpMessageOpt("-rpcserialversion", strprintf(_("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(>0) (default: %d)"), DEFAULT_RPC_SERIALIZE_VERSION));
383384
strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect"));
384385
strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
385386
strUsage += HelpMessageOpt("-torcontrol=<ip>:<port>", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL));
@@ -984,6 +985,9 @@ bool AppInitParameterInteraction()
984985
if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS))
985986
nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM);
986987

988+
if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) < 0)
989+
return InitError("rpcserialversion must be non-negative.");
990+
987991
nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
988992

989993
fEnableReplacement = GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT);

src/rest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ static bool rest_block(HTTPRequest* req,
228228
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
229229
}
230230

231-
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
231+
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
232232
ssBlock << block;
233233

234234
switch (rf) {
@@ -368,7 +368,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)
368368
if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))
369369
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
370370

371-
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
371+
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
372372
ssTx << tx;
373373

374374
switch (rf) {

src/rpc/blockchain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ UniValue getblock(const JSONRPCRequest& request)
751751

752752
if (!fVerbose)
753753
{
754-
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
754+
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
755755
ssBlock << block;
756756
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
757757
return strHex;

src/rpc/rawtransaction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
223223
if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))
224224
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
225225

226-
string strHex = EncodeHexTx(*tx);
226+
string strHex = EncodeHexTx(*tx, RPCSerializationFlags());
227227

228228
if (!fVerbose)
229229
return strHex;

src/rpc/server.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,12 @@ void RPCRunLater(const std::string& name, boost::function<void(void)> func, int6
497497
deadlineTimers.emplace(name, std::unique_ptr<RPCTimerBase>(timerInterface->NewTimer(func, nSeconds*1000)));
498498
}
499499

500+
int RPCSerializationFlags()
501+
{
502+
int flag = 0;
503+
if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0)
504+
flag |= SERIALIZE_TRANSACTION_NO_WITNESS;
505+
return flag;
506+
}
507+
500508
CRPCTable tableRPC;

src/rpc/server.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include <univalue.h>
2121

22+
static const unsigned int DEFAULT_RPC_SERIALIZE_VERSION = 1;
23+
2224
class CRPCCommand;
2325

2426
namespace RPCServer
@@ -198,4 +200,7 @@ void StopRPC();
198200
std::string JSONRPCExecBatch(const UniValue& vReq);
199201
void RPCNotifyBlockChange(bool ibd, const CBlockIndex *);
200202

203+
// Retrieves any serialization flags requested in command line argument
204+
int RPCSerializationFlags();
205+
201206
#endif // BITCOIN_RPCSERVER_H

src/wallet/rpcwallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,7 @@ UniValue gettransaction(const JSONRPCRequest& request)
17921792
ListTransactions(wtx, "*", 0, false, details, filter);
17931793
entry.push_back(Pair("details", details));
17941794

1795-
string strHex = EncodeHexTx(static_cast<CTransaction>(wtx));
1795+
string strHex = EncodeHexTx(static_cast<CTransaction>(wtx), RPCSerializationFlags());
17961796
entry.push_back(Pair("hex", strHex));
17971797

17981798
return entry;

0 commit comments

Comments
 (0)