Skip to content

Commit

Permalink
Merge pull request #1671 from MonsieurNicolas/printxdr
Browse files Browse the repository at this point in the history
replace "printtx" by "printxdr" (generic)

Reviewed-by: jonjove
  • Loading branch information
latobarita authored Aug 9, 2018
2 parents 9f05983 + 528ba02 commit c5fc4b1
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 27 deletions.
4 changes: 2 additions & 2 deletions docs/software/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ forcescp doesn't change the requirements for quorum so although this node will e
* **--metric METRIC**: Report metric METRIC on exit. Used for gathering a metric cumulatively during a test run.
* **--newdb**: Clears the local database and resets it to the genesis ledger. If you connect to the network after that it will catch up from scratch.
* **--newhist ARCH**: Initialize the named history archive ARCH. ARCH should be one of the history archives you have specified in the stellar-core.cfg. This will write a `.well-known/stellar-history.json` file in the archive root.
* **--printtxn FILE**: Pretty-print a binary file containing a
`TransactionEnvelope`. If FILE is "-", the transaction is read from
* **--printxdr FILE**: Pretty-print a binary file containing an XDR object. If FILE is "-", the XDR object is read from
standard input.
* **--filetype [auto|ledgerheader|meta|result|resultpair|tx|txfee]**: toggle for type used for printxdr (default: auto).
* **--signtxn FILE**: Add a digital signature to a transaction
envelope stored in binary format in FILE, and send the result to
standard output (which should be redirected to a file or piped
Expand Down
71 changes: 64 additions & 7 deletions src/main/dumpxdr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "util/Fs.h"
#include "util/XDROperators.h"
#include "util/XDRStream.h"
#include "util/format.h"
#include <iostream>
#include <regex>
#include <xdrpp/printer.h>
Expand All @@ -27,6 +28,8 @@ extern "C" {
#define isatty _isatty
#endif // MSVC

using namespace std::placeholders;

namespace stellar
{

Expand All @@ -50,7 +53,7 @@ dumpstream(XDRInputFileStream& in)
}

void
dumpxdr(std::string const& filename)
dumpXdrStream(std::string const& filename)
{
std::regex rx(
".*(ledger|bucket|transactions|results|scp)-[[:xdigit:]]+\\.xdr");
Expand Down Expand Up @@ -117,19 +120,73 @@ readFile(const std::string& filename, bool base64 = false)
return {ret.begin(), ret.end()};
}

template <typename T>
void
printOneXdr(xdr::opaque_vec<> const& o, std::string const& desc)
{
T tmp;
xdr::xdr_from_opaque(o, tmp);
std::cout << xdr::xdr_to_string(tmp, desc.c_str()) << std::endl;
}

void
printtxn(const std::string& filename, bool base64)
printXdr(std::string const& filename, std::string const& filetype, bool base64)
{
// need to use this pattern as there is no good way to get a human readable
// type name from a type
#define PRINTONEXDR(T) std::bind(printOneXdr<T>, _1, #T)
auto dumpMap =
std::map<std::string, std::function<void(xdr::opaque_vec<> const&)>>{
{"ledgerheader", PRINTONEXDR(LedgerHeader)},
{"meta", PRINTONEXDR(TransactionMeta)},
{"result", PRINTONEXDR(TransactionResult)},
{"resultpair", PRINTONEXDR(TransactionResultPair)},
{"tx", PRINTONEXDR(TransactionEnvelope)},
{"txfee", PRINTONEXDR(LedgerEntryChanges)}};
#undef PRINTONEXDR

try
{
using xdr::operator<<;
TransactionEnvelope txenv;
xdr::xdr_from_opaque(readFile(filename, base64), txenv);
std::cout << txenv;
auto d = readFile(filename, base64);

if (filetype == "auto")
{
bool processed = false;
for (auto const& it : dumpMap)
{
try
{
it.second(d);
processed = true;
break;
}
catch (xdr::xdr_runtime_error)
{
}
}
if (!processed)
{
throw std::invalid_argument("Could not detect type");
}
}
else
{
auto it = dumpMap.find(filetype);
if (it != dumpMap.end())
{
it->second(d);
}
else
{
throw std::invalid_argument(
fmt::format("unknown filetype {}", filetype));
}
}
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
std::cerr << "Could not decode with type '" << filetype
<< "' : " << e.what() << std::endl;
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/main/dumpxdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ namespace stellar
{

extern const char* signtxn_network_id;
void dumpxdr(std::string const& filename);
void printtxn(std::string const& filename, bool base64);
void dumpXdrStream(std::string const& filename);
void printXdr(std::string const& filename, std::string const& filetype,
bool base64);
void signtxn(std::string const& filename, bool base64);
void priv2pub();
}
36 changes: 20 additions & 16 deletions src/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,12 @@ enum opttag
OPT_METRIC,
OPT_NEWDB,
OPT_NEWHIST,
OPT_PRINTTXN,
OPT_PRINTXDR,
OPT_SEC2PUB,
OPT_SIGNTXN,
OPT_NETID,
OPT_TEST,
OPT_FILETYPE,
OPT_VERSION
};

Expand All @@ -90,7 +91,8 @@ static const struct option stellar_core_options[] = {
{"checkquorum", optional_argument, nullptr, OPT_CHECKQUORUM},
{"base64", no_argument, nullptr, OPT_BASE64},
{"dumpxdr", required_argument, nullptr, OPT_DUMPXDR},
{"printtxn", required_argument, nullptr, OPT_PRINTTXN},
{"printxdr", required_argument, nullptr, OPT_PRINTXDR},
{"filetype", required_argument, nullptr, OPT_FILETYPE},
{"signtxn", required_argument, nullptr, OPT_SIGNTXN},
{"netid", required_argument, nullptr, OPT_NETID},
{"loadxdr", required_argument, nullptr, OPT_LOADXDR},
Expand Down Expand Up @@ -131,16 +133,14 @@ usage(int err = 1)
" Use current as SEQ to catchup to "
"'current' history checkpoint\n"
" --c Send a command to local stellar-core. "
"try "
"'--c help' for more information\n"
"try '--c help' for more information\n"
" --conf FILE Specify a config file ('-' for STDIN, "
"default 'stellar-core.cfg')\n"
" --convertid ID Displays ID in all known forms\n"
" --dumpxdr FILE Dump an XDR file, for debugging\n"
" --loadxdr FILE Load an XDR bucket file, for testing\n"
" --forcescp Next time stellar-core is run, SCP will "
"start "
"with the local ledger rather than waiting to hear from the "
"start with the local ledger rather than waiting to hear from the "
"network.\n"
" --fuzz FILE Run a single fuzz input and exit\n"
" --genfuzz FILE Generate a random fuzzer input file\n"
Expand All @@ -155,19 +155,19 @@ usage(int err = 1)
" --offlineinfo Return information for an offline "
"instance\n"
" --ll LEVEL Set the log level. (redundant with --c "
"ll "
"but "
"you need this form for the tests.)\n"
"ll but you need this form for the tests.)\n"
" LEVEL can be: trace, debug, info, error, "
"fatal\n"
" --metric METRIC Report metric METRIC on exit\n"
" --newdb Creates or restores the DB to the "
"genesis "
"ledger\n"
"genesis ledger\n"
" --newhist ARCH Initialize the named history archive "
"ARCH\n"
" --printtxn FILE Pretty-print one transaction envelope,"
" then quit\n"
" --printxdr FILE Pretty print XDR content from FILE, "
"then quit\n"
" --filetype "
"[auto|ledgerheader|meta|result|resultpair|tx|txfee] toggle for type "
"used for printxdr\n"
" --report-last-history-checkpoint\n"
" Report information about last checkpoint "
"available in history archives\n"
Expand Down Expand Up @@ -718,6 +718,7 @@ main(int argc, char* const* argv)
std::string loadXdrBucket;
std::vector<std::string> newHistories;
std::vector<std::string> metrics;
string filetype = "auto";

int opt;
while ((opt = getopt_long_only(argc, argv, "c:", stellar_core_options,
Expand Down Expand Up @@ -756,11 +757,14 @@ main(int argc, char* const* argv)
StrKeyUtils::logKey(std::cout, std::string(optarg));
return 0;
case OPT_DUMPXDR:
dumpxdr(std::string(optarg));
dumpXdrStream(std::string(optarg));
return 0;
case OPT_PRINTTXN:
printtxn(std::string(optarg), base64);
case OPT_PRINTXDR:
printXdr(std::string(optarg), filetype, base64);
return 0;
case OPT_FILETYPE:
filetype = std::string(optarg);
break;
case OPT_SIGNTXN:
signtxn(std::string(optarg), base64);
return 0;
Expand Down

0 comments on commit c5fc4b1

Please sign in to comment.