diff --git a/src/Makefile.am b/src/Makefile.am index ff237475925..4e591464242 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -75,6 +75,7 @@ BITCOIN_CORE_H = \ coins.h \ compat.h \ core.h \ + core_io.h \ crypter.h \ db.h \ hash.h \ @@ -185,6 +186,8 @@ libbitcoin_common_a_SOURCES = \ chainparams.cpp \ coins.cpp \ core.cpp \ + core_read.cpp \ + core_write.cpp \ hash.cpp \ key.cpp \ keystore.cpp \ diff --git a/src/core_io.h b/src/core_io.h new file mode 100644 index 00000000000..257dac36271 --- /dev/null +++ b/src/core_io.h @@ -0,0 +1,14 @@ +#ifndef __BITCOIN_CORE_IO_H__ +#define __BITCOIN_CORE_IO_H__ + +#include + +class CTransaction; + +// core_read.cpp +extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); + +// core_write.cpp +extern std::string EncodeHexTx(const CTransaction& tx); + +#endif // __BITCOIN_CORE_IO_H__ diff --git a/src/core_read.cpp b/src/core_read.cpp new file mode 100644 index 00000000000..937dcd9c122 --- /dev/null +++ b/src/core_read.cpp @@ -0,0 +1,25 @@ + +#include +#include "core_io.h" +#include "core.h" +#include "serialize.h" + +using namespace std; + +bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx) +{ + if (!IsHex(strHexTx)) + return false; + + vector txData(ParseHex(strHexTx)); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + try { + ssData >> tx; + } + catch (std::exception &e) { + return false; + } + + return true; +} + diff --git a/src/core_write.cpp b/src/core_write.cpp new file mode 100644 index 00000000000..960974df893 --- /dev/null +++ b/src/core_write.cpp @@ -0,0 +1,15 @@ + +#include "core_io.h" +#include "core.h" +#include "serialize.h" +#include "util.h" + +using namespace std; + +string EncodeHexTx(const CTransaction& tx) +{ + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + return HexStr(ssTx.begin(), ssTx.end()); +} + diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index cbb4ab2f8bb..edab427cbfa 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -10,6 +10,7 @@ #include "main.h" #include "miner.h" #include "pow.h" +#include "core_io.h" #ifdef ENABLE_WALLET #include "db.h" #include "wallet.h" @@ -472,9 +473,7 @@ Value getblocktemplate(const Array& params, bool fHelp) Object entry; - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); - ssTx << tx; - entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end()))); + entry.push_back(Pair("data", EncodeHexTx(tx))); entry.push_back(Pair("hash", txHash.GetHex())); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 1efe38e830a..a7aeb8f00b0 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -5,6 +5,7 @@ #include "base58.h" #include "core.h" +#include "core_io.h" #include "init.h" #include "keystore.h" #include "main.h" @@ -182,9 +183,7 @@ Value getrawtransaction(const Array& params, bool fHelp) if (!GetTransaction(hash, tx, hashBlock, true)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); - ssTx << tx; - string strHex = HexStr(ssTx.begin(), ssTx.end()); + string strHex = EncodeHexTx(tx); if (!fVerbose) return strHex; @@ -388,9 +387,7 @@ Value createrawtransaction(const Array& params, bool fHelp) rawTx.vout.push_back(out); } - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << rawTx; - return HexStr(ss.begin(), ss.end()); + return EncodeHexTx(rawTx); } Value decoderawtransaction(const Array& params, bool fHelp) @@ -444,15 +441,12 @@ Value decoderawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("decoderawtransaction", "\"hexstring\"") ); - vector txData(ParseHexV(params[0], "argument")); - CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + RPCTypeCheck(params, list_of(str_type)); + CTransaction tx; - try { - ssData >> tx; - } - catch (std::exception &e) { + + if (!DecodeHexTx(tx, params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); - } Object result; TxToJSON(tx, 0, result); @@ -723,9 +717,7 @@ Value signrawtransaction(const Array& params, bool fHelp) } Object result; - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); - ssTx << mergedTx; - result.push_back(Pair("hex", HexStr(ssTx.begin(), ssTx.end()))); + result.push_back(Pair("hex", EncodeHexTx(mergedTx))); result.push_back(Pair("complete", fComplete)); return result; @@ -754,25 +746,18 @@ Value sendrawtransaction(const Array& params, bool fHelp) + HelpExampleRpc("sendrawtransaction", "\"signedhex\"") ); + RPCTypeCheck(params, list_of(str_type)(bool_type)); // parse hex string from parameter - vector txData(ParseHexV(params[0], "parameter")); - CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); CTransaction tx; + if (!DecodeHexTx(tx, params[0].get_str())) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + uint256 hashTx = tx.GetHash(); bool fOverrideFees = false; if (params.size() > 1) fOverrideFees = params[1].get_bool(); - // deserialize binary data stream - try { - ssData >> tx; - } - catch (std::exception &e) { - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); - } - const uint256 &hashTx = tx.GetHash(); - CCoinsViewCache &view = *pcoinsTip; CCoins existingCoins; bool fHaveMempool = mempool.exists(hashTx); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 5b83fe900ec..667ca33ce1c 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -4,6 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" +#include "core_io.h" #include "rpcserver.h" #include "init.h" #include "net.h" @@ -1550,9 +1551,7 @@ Value gettransaction(const Array& params, bool fHelp) ListTransactions(wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); - ssTx << static_cast(wtx); - string strHex = HexStr(ssTx.begin(), ssTx.end()); + string strHex = EncodeHexTx(static_cast(wtx)); entry.push_back(Pair("hex", strHex)); return entry;