From 93ad1f872358ef9619a1e39148ff5d079790aea6 Mon Sep 17 00:00:00 2001
From: binaryFate <binaryfate@users.noreply.github.com>
Date: Fri, 6 Oct 2017 17:55:25 +0200
Subject: [PATCH] Fix #2559: more flexible print_tx daemon command

---
 src/daemon/command_parser_executor.cpp | 19 ++++++++++--
 src/daemon/command_server.cpp          |  2 +-
 src/daemon/rpc_command_executor.cpp    | 42 +++++++++++++++-----------
 src/daemon/rpc_command_executor.h      |  2 +-
 4 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
index af46453cd..9e61e9acd 100644
--- a/src/daemon/command_parser_executor.cpp
+++ b/src/daemon/command_parser_executor.cpp
@@ -187,9 +187,24 @@ bool t_command_parser_executor::print_block(const std::vector<std::string>& args
 
 bool t_command_parser_executor::print_transaction(const std::vector<std::string>& args)
 {
+  bool include_hex = false;
+  bool include_json = false;
+
+  // Assumes that optional flags come after mandatory argument <transaction_hash>
+  for (unsigned int i = 1; i < args.size(); ++i) {
+    if (args[i] == "+hex")
+      include_hex = true;
+    else if (args[i] == "+json")
+      include_json = true;
+    else
+    {
+      std::cout << "unexpected argument: " << args[i] << std::endl;
+      return true;
+    }
+  }
   if (args.empty())
   {
-    std::cout << "expected: print_tx <transaction hash>" << std::endl;
+    std::cout << "expected: print_tx <transaction_hash> [+hex] [+json]" << std::endl;
     return true;
   }
 
@@ -197,7 +212,7 @@ bool t_command_parser_executor::print_transaction(const std::vector<std::string>
   crypto::hash tx_hash;
   if (parse_hash256(str_hash, tx_hash))
   {
-    m_executor.print_transaction(tx_hash);
+    m_executor.print_transaction(tx_hash, include_hex, include_json);
   }
 
   return true;
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index 3f1543857..b134aee61 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -91,7 +91,7 @@ t_command_server::t_command_server(
   m_command_lookup.set_handler(
       "print_tx"
     , std::bind(&t_command_parser_executor::print_transaction, &m_parser, p::_1)
-    , "Print transaction, print_tx <transaction_hash>"
+    , "Print transaction, print_tx <transaction_hash> [+hex] [+json]"
     );
   m_command_lookup.set_handler(
       "is_key_image_spent"
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index ef593237c..cf33ec644 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -693,7 +693,9 @@ bool t_rpc_command_executor::print_block_by_height(uint64_t height) {
   return true;
 }
 
-bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash) {
+bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash,
+  bool include_hex,
+  bool include_json) {
   cryptonote::COMMAND_RPC_GET_TRANSACTIONS::request req;
   cryptonote::COMMAND_RPC_GET_TRANSACTIONS::response res;
 
@@ -728,30 +730,34 @@ bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash) {
         tools::success_msg_writer() << "Found in blockchain at height " << res.txs.front().block_height;
     }
 
-    // first as hex
     const std::string &as_hex = (1 == res.txs.size()) ? res.txs.front().as_hex : res.txs_as_hex.front();
-    tools::success_msg_writer() << as_hex;
+    // Print raw hex if requested
+    if (include_hex)
+      tools::success_msg_writer() << as_hex << std::endl;
 
-    // then as json
-    crypto::hash tx_hash, tx_prefix_hash;
-    cryptonote::transaction tx;
-    cryptonote::blobdata blob;
-    if (!string_tools::parse_hexstr_to_binbuff(as_hex, blob))
+    // Print json if requested
+    if (include_json)
     {
-      tools::fail_msg_writer() << "Failed to parse tx";
-    }
-    else if (!cryptonote::parse_and_validate_tx_from_blob(blob, tx, tx_hash, tx_prefix_hash))
-    {
-      tools::fail_msg_writer() << "Failed to parse tx blob";
-    }
-    else
-    {
-      tools::success_msg_writer() << cryptonote::obj_to_json_str(tx) << std::endl;
+      crypto::hash tx_hash, tx_prefix_hash;
+      cryptonote::transaction tx;
+      cryptonote::blobdata blob;
+      if (!string_tools::parse_hexstr_to_binbuff(as_hex, blob))
+      {
+        tools::fail_msg_writer() << "Failed to parse tx to get json format";
+      }
+      else if (!cryptonote::parse_and_validate_tx_from_blob(blob, tx, tx_hash, tx_prefix_hash))
+      {
+        tools::fail_msg_writer() << "Failed to parse tx blob to get json format";
+      }
+      else
+      {
+        tools::success_msg_writer() << cryptonote::obj_to_json_str(tx) << std::endl;
+      }
     }
   }
   else
   {
-    tools::fail_msg_writer() << "transaction wasn't found: " << transaction_hash << std::endl;
+    tools::fail_msg_writer() << "Transaction wasn't found: " << transaction_hash << std::endl;
   }
 
   return true;
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
index d79707a6f..26db18902 100644
--- a/src/daemon/rpc_command_executor.h
+++ b/src/daemon/rpc_command_executor.h
@@ -95,7 +95,7 @@ public:
 
   bool print_block_by_height(uint64_t height);
 
-  bool print_transaction(crypto::hash transaction_hash);
+  bool print_transaction(crypto::hash transaction_hash, bool include_hex, bool include_json);
 
   bool is_key_image_spent(const crypto::key_image &ki);