diff --git a/doc/protocol.md b/doc/protocol.md
index caf5187fb..59c6e45d2 100644
--- a/doc/protocol.md
+++ b/doc/protocol.md
@@ -50,6 +50,7 @@ The type number is the identifier used in `RequestResponseHeader` (defined in `h
- `RequestAssets`, type 52, defined in `assets.h`.
- `RespondAssets` and `RespondAssetsWithSiblings`, type 53, defined in `assets.h`.
- `TryAgain`, type 54, defined in `common_response.h`.
+- `RequestedCustomMiningVerification`, type 55, defined in `custom_mining.h`.
- `SpecialCommand`, type 255, defined in `special_command.h`.
Addon messages (supported if addon is enabled):
diff --git a/src/Qubic.vcxproj b/src/Qubic.vcxproj
index c74e46d1d..78fd4205e 100644
--- a/src/Qubic.vcxproj
+++ b/src/Qubic.vcxproj
@@ -65,6 +65,7 @@
+
diff --git a/src/Qubic.vcxproj.filters b/src/Qubic.vcxproj.filters
index 7c1a63f75..0e4ca5e06 100644
--- a/src/Qubic.vcxproj.filters
+++ b/src/Qubic.vcxproj.filters
@@ -241,6 +241,9 @@
contracts
+
+ network_messages
+
diff --git a/src/network_messages/all.h b/src/network_messages/all.h
index 4e4eda970..873a8ee43 100644
--- a/src/network_messages/all.h
+++ b/src/network_messages/all.h
@@ -15,3 +15,4 @@
#include "tick.h"
#include "transactions.h"
#include "system_info.h"
+#include "custom_mining.h"
diff --git a/src/network_messages/custom_mining.h b/src/network_messages/custom_mining.h
new file mode 100644
index 000000000..db9876b84
--- /dev/null
+++ b/src/network_messages/custom_mining.h
@@ -0,0 +1,14 @@
+#pragma once
+
+struct RequestedCustomMiningVerification
+{
+ enum
+ {
+ type = 55,
+ };
+ unsigned long long everIncreasingNonceAndCommandType;
+ unsigned long long taskIndex;
+ unsigned int nonce;
+ unsigned int padding; // use later
+};
+
diff --git a/src/qubic.cpp b/src/qubic.cpp
index bdf1bfd3b..3fb697522 100644
--- a/src/qubic.cpp
+++ b/src/qubic.cpp
@@ -209,6 +209,7 @@ static CustomMiningSharesCounter gCustomMiningSharesCounter;
static volatile char gCustomMiningSharesCountLock = 0;
static char gIsInCustomMiningState = 0;
static volatile char gIsInCustomMiningStateLock = 0;
+static unsigned long long gCustomMinninglatestOperatorNonce = 0;
struct revenueScore
{
@@ -242,6 +243,7 @@ struct
unsigned int numberOfMiners;
unsigned int numberOfTransactions;
unsigned long long lastLogId;
+ unsigned char customMiningSharesCounterData[CustomMiningSharesCounter::_customMiningSolutionCounterDataSize];
} nodeStateBuffer;
#endif
static bool saveComputer(CHAR16* directory = NULL);
@@ -540,23 +542,23 @@ static void processBroadcastMessage(const unsigned long long processorNumber, Re
customMiningMessageCounters[i]++;
// Only record shares in idle phase
- char recordSolutions = 0;
- ACQUIRE(gIsInCustomMiningStateLock);
- recordSolutions = gIsInCustomMiningState;
- RELEASE(gIsInCustomMiningStateLock);
-
- if (recordSolutions)
- {
- // Record the solution
- const CustomMiningSolution* solution = ((CustomMiningSolution*)((unsigned char*)request + sizeof(BroadcastMessage)));
-
- // Check the computor idx of this solution
- unsigned short computorID = solution->nonce % NUMBER_OF_COMPUTORS;
-
- ACQUIRE(gCustomMiningSharesCountLock);
- gCustomMiningSharesCount[computorID]++;
- RELEASE(gCustomMiningSharesCountLock);
- }
+ //char recordSolutions = 0;
+ //ACQUIRE(gIsInCustomMiningStateLock);
+ //recordSolutions = gIsInCustomMiningState;
+ //RELEASE(gIsInCustomMiningStateLock);
+
+ //if (recordSolutions)
+ //{
+ // // Record the solution
+ // const CustomMiningSolution* solution = ((CustomMiningSolution*)((unsigned char*)request + sizeof(BroadcastMessage)));
+
+ // // Check the computor idx of this solution
+ // unsigned short computorID = solution->nonce % NUMBER_OF_COMPUTORS;
+
+ // ACQUIRE(gCustomMiningSharesCountLock);
+ // gCustomMiningSharesCount[computorID]++;
+ // RELEASE(gCustomMiningSharesCountLock);
+ //}
}
break;
@@ -1264,6 +1266,39 @@ static void processRequestSystemInfo(Peer* peer, RequestResponseHeader* header)
enqueueResponse(peer, sizeof(respondedSystemInfo), RESPOND_SYSTEM_INFO, header->dejavu(), &respondedSystemInfo);
}
+static void processCustomMiningRequest(Peer* peer, RequestResponseHeader* header)
+{
+ RequestedCustomMiningVerification* request = header->getPayload();
+ if (header->size() >= sizeof(RequestResponseHeader) + sizeof(RequestedCustomMiningVerification) + SIGNATURE_SIZE
+ && (request->everIncreasingNonceAndCommandType & 0xFFFFFFFFFFFFFF) > gCustomMinninglatestOperatorNonce)
+ {
+ unsigned char digest[32];
+ KangarooTwelve(request, header->size() - sizeof(RequestResponseHeader) - SIGNATURE_SIZE, digest, sizeof(digest));
+ if (verify(operatorPublicKey.m256i_u8, digest, ((const unsigned char*)header + (header->size() - SIGNATURE_SIZE))))
+ {
+ gCustomMinninglatestOperatorNonce = request->everIncreasingNonceAndCommandType & 0xFFFFFFFFFFFFFF;
+
+ // Update the share counting
+ // Only record shares in idle phase
+ char recordSolutions = 0;
+ ACQUIRE(gIsInCustomMiningStateLock);
+ recordSolutions = gIsInCustomMiningState;
+ RELEASE(gIsInCustomMiningStateLock);
+
+ if (recordSolutions)
+ {
+ // Check the computor idx of this solution
+ const unsigned short computorID = request->nonce % NUMBER_OF_COMPUTORS;
+
+ ACQUIRE(gCustomMiningSharesCountLock);
+ gCustomMiningSharesCount[computorID]++;
+ RELEASE(gCustomMiningSharesCountLock);
+ }
+
+ }
+ }
+}
+
static void processSpecialCommand(Peer* peer, RequestResponseHeader* header)
{
SpecialCommand* request = header->getPayload();
@@ -1681,6 +1716,12 @@ static void requestProcessor(void* ProcedureArgument)
}
break;
+ case RequestedCustomMiningVerification::type:
+ {
+ processCustomMiningRequest(peer, header);
+ }
+ break;
+
case SpecialCommand::type:
{
processSpecialCommand(peer, header);
@@ -4078,6 +4119,7 @@ static bool saveAllNodeStates()
nodeStateBuffer.numberOfTransactions = numberOfTransactions;
nodeStateBuffer.lastLogId = logger.logId;
voteCounter.saveAllDataToArray(nodeStateBuffer.voteCounterData);
+ gCustomMiningSharesCounter.saveAllDataToArray(nodeStateBuffer.customMiningSharesCounterData);
CHAR16 NODE_STATE_FILE_NAME[] = L"snapshotNodeMiningState";
savedSize = save(NODE_STATE_FILE_NAME, sizeof(nodeStateBuffer), (unsigned char*)&nodeStateBuffer, directory);
@@ -4216,6 +4258,7 @@ static bool loadAllNodeStates()
logger.logId = nodeStateBuffer.lastLogId;
loadMiningSeedFromFile = true;
voteCounter.loadAllDataFromArray(nodeStateBuffer.voteCounterData);
+ gCustomMiningSharesCounter.loadAllDataFromArray(nodeStateBuffer.customMiningSharesCounterData);
// update own computor indices
for (unsigned int i = 0; i < NUMBER_OF_COMPUTORS; i++)