From cf966bd43c897ced544c59444fde23ac17846e5f Mon Sep 17 00:00:00 2001
From: Bartek Wrona <wrona@syncad.com>
Date: Wed, 26 Feb 2025 15:59:04 +0100
Subject: [PATCH] Wax-Core functionality specific to transaction serialization
 extended by ability to optionally strip signatures container (and get exact
 buffer as the input for transaction hash calculation)

---
 core/protobuf_protocol_impl.hpp |  4 ++--
 core/protobuf_protocol_impl.inl | 10 ++++++----
 core/protocol_impl.hpp          |  7 +++++--
 core/protocol_impl.inl          | 11 ++++++-----
 4 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/core/protobuf_protocol_impl.hpp b/core/protobuf_protocol_impl.hpp
index 61a51ef30..e5084fa1c 100644
--- a/core/protobuf_protocol_impl.hpp
+++ b/core/protobuf_protocol_impl.hpp
@@ -19,7 +19,7 @@ public:
   std::vector<std::string> cpp_operation_get_impacted_accounts(const std::string& operation) const;
   std::vector<std::string> cpp_transaction_get_impacted_accounts(const std::string& transaction) const;
 
-  binary_data cpp_generate_binary_transaction_metadata(const std::string& transaction, bool use_hf26_serialization)const;
+  binary_data cpp_generate_binary_transaction_metadata(const std::string& transaction, bool use_hf26_serialization, bool strip_to_unsigned_transaction)const;
   binary_data cpp_generate_binary_operation_metadata(const std::string& operation, bool use_hf26_serialization)const;
 
   result cpp_validate_operation(const std::string& operation);
@@ -28,7 +28,7 @@ public:
   result cpp_calculate_legacy_transaction_id(const std::string& transaction);
   result cpp_calculate_sig_digest(const std::string& transaction, const std::string& chain_id);
   result cpp_calculate_legacy_sig_digest(const std::string& transaction, const std::string& chain_id);
-  result cpp_serialize_transaction(const std::string& transaction);
+  result cpp_serialize_transaction(const std::string& transaction, bool strip_to_unsigned_transaction);
   result cpp_deserialize_transaction(const std::string& transaction);
   required_authority_collection_t cpp_collect_transaction_required_authorities(const std::string& transaction);
 
diff --git a/core/protobuf_protocol_impl.inl b/core/protobuf_protocol_impl.inl
index 40784363d..d61093f0a 100644
--- a/core/protobuf_protocol_impl.inl
+++ b/core/protobuf_protocol_impl.inl
@@ -480,13 +480,14 @@ std::vector<std::string> proto_protocol_impl<FoundationProvider>::cpp_transactio
 }
 
 template <class FoundationProvider>
-binary_data proto_protocol_impl<FoundationProvider>::cpp_generate_binary_transaction_metadata(const std::string& transaction, bool use_hf26_serialization) const
+binary_data proto_protocol_impl<FoundationProvider>::cpp_generate_binary_transaction_metadata(const std::string& transaction, bool use_hf26_serialization, bool strip_to_unsigned_transaction) const
 {
   protocol_impl<FoundationProvider> provider;
 
   return provider.cpp_generate_binary_transaction_metadata(
     cpp_proto_to_api_impl(transaction),
-    use_hf26_serialization
+    use_hf26_serialization,
+    strip_to_unsigned_transaction
   );
 }
 
@@ -585,13 +586,14 @@ typename proto_protocol_impl<FoundationProvider>::required_authority_collection_
 }
 
 template <class FoundationProvider>
-result proto_protocol_impl<FoundationProvider>::cpp_serialize_transaction(const std::string& transaction)
+result proto_protocol_impl<FoundationProvider>::cpp_serialize_transaction(const std::string& transaction, bool strip_to_unsigned_transaction)
 {
   return method_wrapper([&](result& _result)
     {
       protocol_impl<FoundationProvider> provider;
       _result = provider.cpp_serialize_transaction(
-        cpp_proto_to_api_impl(transaction)
+        cpp_proto_to_api_impl(transaction),
+        strip_to_unsigned_transaction
       );
     });
 }
diff --git a/core/protocol_impl.hpp b/core/protocol_impl.hpp
index 83ba9ea55..8ea6d72b5 100644
--- a/core/protocol_impl.hpp
+++ b/core/protocol_impl.hpp
@@ -38,7 +38,7 @@ public:
   std::vector<std::string> cpp_operation_get_impacted_accounts(const std::string& operation) const;
   std::vector<std::string> cpp_transaction_get_impacted_accounts(const std::string& transaction) const;
 
-  binary_data cpp_generate_binary_transaction_metadata(const std::string& transaction, bool use_hf26_serialization)const;
+  binary_data cpp_generate_binary_transaction_metadata(const std::string& transaction, bool use_hf26_serialization, bool strip_to_unsigned_transaction)const;
   binary_data cpp_generate_binary_operation_metadata(const std::string& operation, bool use_hf26_serialization)const;
 
   result cpp_validate_operation(const std::string& operation);
@@ -59,8 +59,11 @@ public:
 
   /** Allows to perform binary serialization of specified transaction.
   *   Uses HF26 serialization form.
+  *
+  *  @param transaction - JSON form of transaction to serialize
+  *  @param strip_to_unsigned_transaction - if true, then only unsigned part of transaction will be serialized (signature container is always stripped)
   */
-  result cpp_serialize_transaction(const std::string& transaction);
+  result cpp_serialize_transaction(const std::string& transaction, bool strip_to_unsigned_transaction);
 
   /** Allows to restore a transaction object from HF26 binary serialization form.
   *   Returns a JSON form of deserialized transaction.
diff --git a/core/protocol_impl.inl b/core/protocol_impl.inl
index f7c76b824..6c536720c 100644
--- a/core/protocol_impl.inl
+++ b/core/protocol_impl.inl
@@ -71,13 +71,13 @@ std::vector<std::string> protocol_impl<FoundationProvider>::cpp_transaction_get_
 
 template <class FoundationProvider>
 inline
-binary_data protocol_impl<FoundationProvider>::cpp_generate_binary_transaction_metadata(const std::string& transaction, bool use_hf26_serialization) const
+binary_data protocol_impl<FoundationProvider>::cpp_generate_binary_transaction_metadata(const std::string& transaction, bool use_hf26_serialization, bool strip_to_unsigned_transaction) const
 {
   fc::variant _v = fc::json::from_string(transaction, fc::json::format_validation_mode::full);
 
   hive::protocol::signed_transaction _transaction = _v.as<hive::protocol::signed_transaction>();
 
-  return cpp::generate_binary_transaction_metadata(_transaction, use_hf26_serialization);
+  return cpp::generate_binary_transaction_metadata(_transaction, use_hf26_serialization, strip_to_unsigned_transaction);
 }
 
 template <class FoundationProvider>
@@ -120,7 +120,8 @@ result protocol_impl<FoundationProvider>::cpp_calculate_transaction_id(const std
 {
   return method_wrapper([&](result& _result)
     {
-      _result.content = get_transaction(transaction).id(hive::protocol::transaction_serialization_type::hf26).str();
+      const auto txId = get_transaction(transaction).id(hive::protocol::transaction_serialization_type::hf26);
+      _result.content = txId.str();
     });
 }
 
@@ -162,13 +163,13 @@ result protocol_impl<FoundationProvider>::cpp_calculate_legacy_sig_digest(const
 
 template <class FoundationProvider>
 inline
-result protocol_impl<FoundationProvider>::cpp_serialize_transaction(const std::string& transaction)
+result protocol_impl<FoundationProvider>::cpp_serialize_transaction(const std::string& transaction, bool strip_to_unsigned_transaction)
 {
   return method_wrapper([&](result& _result)
     {
       const auto _transaction = get_transaction(transaction);
 
-      _result.content = serialize_transaction(_transaction);
+      _result.content = serialize_transaction(_transaction, true, strip_to_unsigned_transaction);
     });
 }
 
-- 
GitLab