Skip to content

Commit 7fafe4a

Browse files
authored
add -print-only <base64 | hex> (#109)
* fix -Werror=stringop-overflow= in release mode * support -print-only <base64 | hex> * fix build error * fix build error
1 parent 3b066b9 commit 7fafe4a

File tree

7 files changed

+111
-10
lines changed

7 files changed

+111
-10
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ SET(FILES ${CMAKE_SOURCE_DIR}/asset_utils.cpp
2222
${CMAKE_SOURCE_DIR}/sc_utils.cpp
2323
${CMAKE_SOURCE_DIR}/test_utils.cpp
2424
${CMAKE_SOURCE_DIR}/wallet_utils.cpp
25+
${CMAKE_SOURCE_DIR}/utils.cpp
2526
)
2627
SET(HEADER_FILES
2728
argparser.h

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ Basic config:
2626
Do action although an error has been detected. Currently only implemented for proposals.
2727
-enabletestcontracts
2828
Enable test contract indices and names for commands using a contract index parameter. This flag has to be passed before the contract index/name. The node to connect to needs to have test contracts running.
29-
29+
-print-only <base64 | hex>
30+
Print the raw transaction data without sending it to the network. Useful for offline signing or broadcasting later.
3031
Commands:
3132
3233
[WALLET COMMANDS]

argparser.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ void print_help()
4343
printf("\t\tDo action although an error has been detected. Currently only implemented for proposals.\n");
4444
printf("\t-enabletestcontracts\n");
4545
printf("\t\tEnable test contract indices and names for commands using a contract index parameter. This flag has to be passed before the contract index/name. The node to connect to needs to have test contracts running.\n");
46+
printf("\t-print-only <base64 | hex>\n");
47+
printf("\t\tPrint the raw transaction data without sending it to the network. Useful for offline signing or broadcasting later.\n");
4648

4749
printf("\nCommands:\n");
4850
printf("\n[WALLET COMMANDS]\n");
@@ -696,6 +698,13 @@ void parseArgument(int argc, char** argv)
696698
++i;
697699
continue;
698700
}
701+
if (strcmp(argv[i], "-print-only") == 0)
702+
{
703+
CHECK_NUMBER_OF_PARAMETERS(1);
704+
g_printToScreen = argv[i+1];
705+
i+=2;
706+
continue;
707+
}
699708

700709
/***************************
701710
***** WALLET COMMANDS *****

connection.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -285,18 +285,30 @@ std::vector<T> QubicConnection::getLatestVectorPacketAs()
285285

286286
int QubicConnection::sendData(uint8_t* buffer, int sz)
287287
{
288-
int size = sz;
289-
int numberOfBytes;
290-
while (size)
291-
{
292-
if ((numberOfBytes = send(mSocket, (char*)buffer, size, 0)) <= 0)
288+
// also skip printing packets of size 8 (typically used during the preparation step, not the final stage)
289+
if (!std::string(g_printToScreen).empty() && sz != 8) {
290+
std::string printType = g_printToScreen;
291+
// Do not print the first 8 bytes (header)
292+
printBytes(buffer + 8, sz - 8, printType);
293+
294+
// this operation may break the normal flow, we need to skip printing error messages to console
295+
if (!std::freopen("/dev/null", "w", stdout)) {}
296+
if (!std::freopen("/dev/null", "w", stderr)) {}
297+
return 0;
298+
} else {
299+
int size = sz;
300+
int numberOfBytes;
301+
while (size)
293302
{
294-
return 0;
303+
if ((numberOfBytes = send(mSocket, (char*)buffer, size, 0)) <= 0)
304+
{
305+
return 0;
306+
}
307+
buffer += numberOfBytes;
308+
size -= numberOfBytes;
295309
}
296-
buffer += numberOfBytes;
297-
size -= numberOfBytes;
310+
return sz - size;
298311
}
299-
return sz - size;
300312
}
301313

302314
template SpecialCommand QubicConnection::receivePacketWithHeaderAs<SpecialCommand>();

utils.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "utils.h"
2+
3+
char* g_printToScreen = (char *)"";

utils.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
#include <string>
55
#include <vector>
66

7+
extern char* g_printToScreen;
8+
9+
static const char B64_TABLE[] =
10+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
11+
712
static void byteToHex(const uint8_t* byte, char* hex, const int sizeInByte)
813
{
914
for (int i = 0; i < sizeInByte; i++)
@@ -96,3 +101,70 @@ static std::string unwrapString(const std::string& str, char wrapperCharFront, c
96101
}
97102
return str;
98103
}
104+
105+
static inline std::string base64_encode(const std::vector<uint8_t> &in) {
106+
std::string out;
107+
int val = 0, valb = -6;
108+
109+
for (uint8_t c : in) {
110+
val = (val << 8) + c;
111+
valb += 8;
112+
while (valb >= 0) {
113+
out.push_back(B64_TABLE[(val >> valb) & 0x3F]);
114+
valb -= 6;
115+
}
116+
}
117+
if (valb > -6)
118+
out.push_back(B64_TABLE[((val << 8) >> (valb + 8)) & 0x3F]);
119+
120+
while (out.size() % 4)
121+
out.push_back('=');
122+
123+
return out;
124+
}
125+
126+
static std::string base64_encode(uint8_t *data, size_t length) {
127+
return base64_encode(std::vector<uint8_t>(data, data + length));
128+
}
129+
130+
static std::vector<uint8_t> base64_decode(const std::string &in) {
131+
static int T[256];
132+
static bool init = false;
133+
134+
if (!init) {
135+
for (int i = 0; i < 256; i++) T[i] = -1;
136+
for (int i = 0; i < 64; i++) T[(unsigned char)B64_TABLE[i]] = i;
137+
init = true;
138+
}
139+
140+
std::vector<uint8_t> out;
141+
int val = 0, valb = -8;
142+
143+
for (unsigned char c : in) {
144+
if (T[c] == -1) continue;
145+
val = (val << 6) + T[c];
146+
valb += 6;
147+
148+
if (valb >= 0) {
149+
out.push_back(uint8_t((val >> valb) & 0xFF));
150+
valb -= 8;
151+
}
152+
}
153+
154+
return out;
155+
}
156+
157+
static void printBytes(uint8_t* data, size_t length, std::string type = "base64") {\
158+
printf("---------------- %s ----------------\n", type.c_str());
159+
if (type == "base64") {
160+
std::string encoded = base64_encode(data, length);
161+
printf("%s\n", encoded.c_str());
162+
} else if (type == "hex") {
163+
for (size_t i = 0; i < length; i++) {
164+
printf("%02x", data[i]);
165+
}
166+
printf("\n");
167+
} else {
168+
printf("Unsupported print type: %s\n", type.c_str());
169+
}
170+
}

wallet_utils.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ void makeCustomTransaction(const char* nodeIp, int nodePort,
265265
const uint8_t* extraData,
266266
uint32_t scheduledTickOffset)
267267
{
268+
if (extraDataSize < 0)
269+
throw std::invalid_argument("extraDataSize < 0");
270+
268271
auto qc = make_qc(nodeIp, nodePort);
269272
uint8_t privateKey[32] = {0};
270273
uint8_t sourcePublicKey[32] = {0};

0 commit comments

Comments
 (0)