Skip to content

Commit 69ec873

Browse files
authored
Merge pull request #111 from qubic/feature/2025-12-17-remote-command-fee-multiplier
add remote command to get and set execution fee multiplier
2 parents c5f5ff9 + d7e2ef5 commit 69ec873

9 files changed

Lines changed: 166 additions & 0 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ Commands:
138138
Set console logging mode: 0 disabled, 1 low computational cost, 2 full logging. Valid seed and node ip/port are required.
139139
-savesnapshot
140140
Remotely trigger saving snapshot, valid seed and node ip/port are required.
141+
-setexecutionfeemultiplier <NUMERATOR> <DENOMINATOR>
142+
Set the multiplier for the conversion of raw execution time to contract execution fees to ( NUMERATOR / DENOMINATOR ), valid seed and node ip/port are required.
143+
-getexecutionfeemultiplier
144+
Get the current multiplier for the conversion of raw execution time to contract execution fees, valid seed and node ip/port are required.
141145
142146
[SMART CONTRACT COMMANDS]
143147
-callcontractfunction <CONTRACT_INDEX> <CONTRACT_FUNCTION> <INPUT_FORMAT_STRING> <OUTPUT_FORMAT_STRING>

argparser.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ void print_help()
160160
printf("\t\tBroadcast a message on Qubic network, the message will be relayed to discord via bot. Node ip/port are required. Seed for a valid comp is required\t\n");
161161
printf("\t-savesnapshot \n");
162162
printf("\t\tRemotely trigger saving snapshot, valid seed and node ip/port are required.\t\n");
163+
printf("\t-setexecutionfeemultiplier <NUMERATOR> <DENOMINATOR>\n");
164+
printf("\t\tSet the multiplier for the conversion of raw execution time to contract execution fees to ( NUMERATOR / DENOMINATOR ), valid seed and node ip/port are required.\t\n");
165+
printf("\t-getexecutionfeemultiplier\n");
166+
printf("\t\tGet the current multiplier for the conversion of raw execution time to contract execution fees, valid seed and node ip/port are required.\t\n");
167+
163168

164169
printf("\n[SMART CONTRACT COMMANDS]\n");
165170
printf("\t-callcontractfunction <CONTRACT_INDEX> <CONTRACT_FUNCTION> <INPUT_FORMAT_STRING> <OUTPUT_FORMAT_STRING>\n");
@@ -1129,6 +1134,23 @@ void parseArgument(int argc, char** argv)
11291134
CHECK_OVER_PARAMETERS
11301135
break;
11311136
}
1137+
if (strcmp(argv[i], "-setexecutionfeemultiplier") == 0)
1138+
{
1139+
CHECK_NUMBER_OF_PARAMETERS(2)
1140+
g_cmd = SET_EXECUTION_FEE_MULTIPLIER;
1141+
g_executionFeeMultiplierNumerator = charToNumber(argv[i + 1]);
1142+
g_executionFeeMultiplierDenominator = charToNumber(argv[i + 2]);
1143+
i += 3;
1144+
CHECK_OVER_PARAMETERS
1145+
break;
1146+
}
1147+
if (strcmp(argv[i], "-getexecutionfeemultiplier") == 0)
1148+
{
1149+
g_cmd = GET_EXECUTION_FEE_MULTIPLIER;
1150+
i++;
1151+
CHECK_OVER_PARAMETERS
1152+
break;
1153+
}
11321154

11331155
/***********************
11341156
***** QX COMMANDS *****

connection.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ template RespondTxStatus QubicConnection::receivePacketWithHeaderAs<RespondTxSta
325325
template BroadcastComputors QubicConnection::receivePacketWithHeaderAs<BroadcastComputors>();
326326
template RespondContractIPO QubicConnection::receivePacketWithHeaderAs<RespondContractIPO>();
327327
template std::vector<RespondActiveIPO> QubicConnection::getLatestVectorPacketAs<RespondActiveIPO>();
328+
template SpecialCommandExecutionFeeMultiplierRequestAndResponse QubicConnection::receivePacketWithHeaderAs<SpecialCommandExecutionFeeMultiplierRequestAndResponse>();
328329
// QUOTTERY
329330
template qtryBasicInfo_output QubicConnection::receivePacketWithHeaderAs<qtryBasicInfo_output>();
330331
template getBetInfo_output QubicConnection::receivePacketWithHeaderAs<getBetInfo_output>();

defines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
#define SPECIAL_COMMAND_GET_MINING_SCORE_RANKING 14ULL // get the ranking of miners connect to node
5656
#define SPECIAL_COMMAND_SET_CONSOLE_LOGGING_MODE 17ULL // PAUSE key
5757
#define SPECIAL_COMMAND_SAVE_SNAPSHOT 18ULL // F8
58+
#define SPECIAL_COMMAND_SET_EXECUTION_FEE_MULTIPLIER 19ULL
59+
#define SPECIAL_COMMAND_GET_EXECUTION_FEE_MULTIPLIER 20ULL
5860

5961
#define QX_CONTRACT_INDEX 1
6062
#define QX_FEE_FUNCTION_INDEX 1

global.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ char* g_compressTool = nullptr;
4141
uint32_t g_contractIndex = 0;
4242
char g_loggingMode = 0;
4343
char* g_compChatString = nullptr;
44+
uint64_t g_executionFeeMultiplierNumerator = 1;
45+
uint64_t g_executionFeeMultiplierDenominator = 1;
4446

4547
char* g_dumpBinaryFileInput = nullptr;
4648
char* g_dumpBinaryFileOutput = nullptr;

main.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,16 @@ int run(int argc, char* argv[])
379379
sanityCheckSeed(g_seed);
380380
broadcastCompChat(g_nodeIp, g_nodePort, g_seed, g_compChatString);
381381
break;
382+
case SET_EXECUTION_FEE_MULTIPLIER:
383+
sanityCheckNode(g_nodeIp, g_nodePort);
384+
sanityCheckSeed(g_seed);
385+
setExecutionFeeMultiplier(g_nodeIp, g_nodePort, g_seed, g_executionFeeMultiplierNumerator, g_executionFeeMultiplierDenominator);
386+
break;
387+
case GET_EXECUTION_FEE_MULTIPLIER:
388+
sanityCheckNode(g_nodeIp, g_nodePort);
389+
sanityCheckSeed(g_seed);
390+
getExecutionFeeMultiplier(g_nodeIp, g_nodePort, g_seed);
391+
break;
382392
case QUTIL_SEND_TO_MANY_V1:
383393
sanityCheckNode(g_nodeIp, g_nodePort);
384394
sanityCheckSeed(g_seed);

node_utils.cpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2211,3 +2211,111 @@ void saveSnapshot(const char* nodeIp, const int nodePort, const char* seed)
22112211
LOG("Failed to trigger saving snapshot\n");
22122212
}
22132213
}
2214+
2215+
void setExecutionFeeMultiplier(const char* nodeIp, const int nodePort, const char* seed, unsigned long long multiplierNumerator, unsigned long long multiplierDenominator)
2216+
{
2217+
uint8_t privateKey[32] = { 0 };
2218+
uint8_t sourcePublicKey[32] = { 0 };
2219+
uint8_t subseed[32] = { 0 };
2220+
uint8_t digest[32] = { 0 };
2221+
uint8_t signature[64] = { 0 };
2222+
2223+
struct {
2224+
RequestResponseHeader header;
2225+
SpecialCommandExecutionFeeMultiplierRequestAndResponse cmd;
2226+
uint8_t signature[64];
2227+
} packet;
2228+
packet.header.setSize(sizeof(packet));
2229+
packet.header.randomizeDejavu();
2230+
packet.header.setType(PROCESS_SPECIAL_COMMAND);
2231+
uint64_t curTime = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
2232+
uint64_t commandByte = (uint64_t)(SPECIAL_COMMAND_SET_EXECUTION_FEE_MULTIPLIER) << 56;
2233+
packet.cmd.everIncreasingNonceAndCommandType = commandByte | curTime;
2234+
packet.cmd.multiplierNumerator = multiplierNumerator;
2235+
packet.cmd.multiplierDenominator = multiplierDenominator;
2236+
2237+
getSubseedFromSeed((uint8_t*)seed, subseed);
2238+
getPrivateKeyFromSubSeed(subseed, privateKey);
2239+
getPublicKeyFromPrivateKey(privateKey, sourcePublicKey);
2240+
KangarooTwelve((unsigned char*)&packet.cmd,
2241+
sizeof(packet.cmd),
2242+
digest,
2243+
32);
2244+
sign(subseed, sourcePublicKey, digest, signature);
2245+
memcpy(packet.signature, signature, 64);
2246+
auto qc = make_qc(nodeIp, nodePort);
2247+
qc->sendData((uint8_t*)&packet, packet.header.size());
2248+
2249+
SpecialCommandExecutionFeeMultiplierRequestAndResponse response;
2250+
try
2251+
{
2252+
response = qc->receivePacketWithHeaderAs<SpecialCommandExecutionFeeMultiplierRequestAndResponse>();
2253+
}
2254+
catch (std::logic_error)
2255+
{
2256+
memset(&response, 0, sizeof(SpecialCommandExecutionFeeMultiplierRequestAndResponse));
2257+
}
2258+
2259+
if (response.everIncreasingNonceAndCommandType == packet.cmd.everIncreasingNonceAndCommandType)
2260+
{
2261+
LOG("Successfully set execution fee multiplier\n");
2262+
}
2263+
else
2264+
{
2265+
LOG("Failed to set execution fee multiplier\n");
2266+
}
2267+
}
2268+
2269+
void getExecutionFeeMultiplier(const char* nodeIp, const int nodePort, const char* seed)
2270+
{
2271+
uint8_t privateKey[32] = { 0 };
2272+
uint8_t sourcePublicKey[32] = { 0 };
2273+
uint8_t subseed[32] = { 0 };
2274+
uint8_t digest[32] = { 0 };
2275+
uint8_t signature[64] = { 0 };
2276+
2277+
struct {
2278+
RequestResponseHeader header;
2279+
SpecialCommand cmd;
2280+
uint8_t signature[64];
2281+
} packet;
2282+
packet.header.setSize(sizeof(packet));
2283+
packet.header.randomizeDejavu();
2284+
packet.header.setType(PROCESS_SPECIAL_COMMAND);
2285+
uint64_t curTime = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
2286+
uint64_t commandByte = (uint64_t)(SPECIAL_COMMAND_GET_EXECUTION_FEE_MULTIPLIER) << 56;
2287+
packet.cmd.everIncreasingNonceAndCommandType = commandByte | curTime;
2288+
2289+
getSubseedFromSeed((uint8_t*)seed, subseed);
2290+
getPrivateKeyFromSubSeed(subseed, privateKey);
2291+
getPublicKeyFromPrivateKey(privateKey, sourcePublicKey);
2292+
KangarooTwelve((unsigned char*)&packet.cmd,
2293+
sizeof(packet.cmd),
2294+
digest,
2295+
32);
2296+
sign(subseed, sourcePublicKey, digest, signature);
2297+
memcpy(packet.signature, signature, 64);
2298+
auto qc = make_qc(nodeIp, nodePort);
2299+
qc->sendData((uint8_t*)&packet, packet.header.size());
2300+
2301+
SpecialCommandExecutionFeeMultiplierRequestAndResponse response;
2302+
try
2303+
{
2304+
response = qc->receivePacketWithHeaderAs<SpecialCommandExecutionFeeMultiplierRequestAndResponse>();
2305+
}
2306+
catch (std::logic_error)
2307+
{
2308+
memset(&response, 0, sizeof(SpecialCommandExecutionFeeMultiplierRequestAndResponse));
2309+
}
2310+
2311+
if (response.everIncreasingNonceAndCommandType == packet.cmd.everIncreasingNonceAndCommandType)
2312+
{
2313+
LOG("Execution fee multiplier is currently set to:\n");
2314+
LOG("- Numerator: %" PRIu64 "\n", response.multiplierNumerator);
2315+
LOG("- Denominator: %" PRIu64 "\n", response.multiplierDenominator);
2316+
}
2317+
else
2318+
{
2319+
LOG("Failed to get execution fee multiplier\n");
2320+
}
2321+
}

node_utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,5 @@ void syncTime(const char* nodeIp, const int nodePort, const char* seed);
3535
void setLoggingMode(const char* nodeIp, const int nodePort, const char* seed, char mode);
3636
void broadcastCompChat(const char* nodeIp, const int nodePort, const char* seed, char* compChatMsg);
3737
void saveSnapshot(const char* nodeIp, const int nodePort, const char* seed);
38+
void setExecutionFeeMultiplier(const char* nodeIp, const int nodePort, const char* seed, unsigned long long multiplierNumerator, unsigned long long multiplierDenominator);
39+
void getExecutionFeeMultiplier(const char* nodeIp, const int nodePort, const char* seed);

structs.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ enum COMMAND
204204
SHAREHOLDER_VOTE,
205205
SHAREHOLDER_GET_VOTE,
206206
SHAREHOLDER_GET_VOTING_RESULTS,
207+
SET_EXECUTION_FEE_MULTIPLIER,
208+
GET_EXECUTION_FEE_MULTIPLIER,
207209
TOTAL_COMMAND // DO NOT CHANGE THIS
208210
};
209211

@@ -870,6 +872,19 @@ struct SpecialCommandSaveSnapshotRequestAndResponse
870872
}
871873
};
872874

875+
// This struct is used as response for the get command and as request and response for the set command.
876+
struct SpecialCommandExecutionFeeMultiplierRequestAndResponse
877+
{
878+
unsigned long long everIncreasingNonceAndCommandType;
879+
unsigned long long multiplierNumerator;
880+
unsigned long long multiplierDenominator;
881+
882+
static constexpr unsigned char type()
883+
{
884+
return 255;
885+
}
886+
};
887+
873888
#define REQUEST_TX_STATUS 201
874889

875890
struct RequestTxStatus

0 commit comments

Comments
 (0)