From 9bd8d24b1408c8d28f1d3d2fe096ce013f46c393 Mon Sep 17 00:00:00 2001 From: CFB-QUBIC Date: Wed, 7 Feb 2024 16:28:25 +0300 Subject: [PATCH 01/17] Added logging of next tick millisecond. --- src/qubic.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qubic.cpp b/src/qubic.cpp index b2f4e92e..ebb45e2a 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -3927,6 +3927,10 @@ static void logInfo() appendText(message, L":"); appendNumber(message, tickData[system.tick + 1 - system.initialTick].second / 10, FALSE); appendNumber(message, tickData[system.tick + 1 - system.initialTick].second % 10, FALSE); + appendText(message, L"."); + appendNumber(message, tickData[system.tick + 1 - system.initialTick].millisecond / 100, FALSE); + appendNumber(message, (tickData[system.tick + 1 - system.initialTick].millisecond % 100) / 10, FALSE); + appendNumber(message, tickData[system.tick + 1 - system.initialTick].millisecond % 10, FALSE); appendText(message, L".) "); } appendNumber(message, numberOfPendingTransactions, TRUE); From 3f627d53188e0350f20757db06d68cd4b7a33dff Mon Sep 17 00:00:00 2001 From: JOETOM <107187448+J0ET0M@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:19:07 +0100 Subject: [PATCH 02/17] added feature to skip forget of known public peers --- src/network_core/peers.h | 52 +++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/src/network_core/peers.h b/src/network_core/peers.h index 30e98872..6ac9d6c2 100644 --- a/src/network_core/peers.h +++ b/src/network_core/peers.h @@ -242,10 +242,54 @@ static void enqueueResponse(Peer* peer, unsigned int dataSize, unsigned char typ RELEASE(responseQueueHeadLock); } +/** +* checks if a given address is a bogon address +* a bogon address is an ip address which should not be used pubicly (e.g. private networks) +* +* @param address the ip address to be checked +* @return true if address is bogon or false if not +*/ +static bool isBogonAddress(const IPv4Address& address) +{ + return (!address.u8[0]) + || (address.u8[0] == 127) + || (address.u8[0] == 10) + || (address.u8[0] == 172 && address.u8[1] >= 16 && address.u8[1] <= 31) + || (address.u8[0] == 192 && address.u8[1] == 168) + || (address.u8[0] == 255); +} + +/** +* checks if a given address was manually set in the initial list of known public peers +* +* @param address the ip address to be checked +* @return true if the ip address is in the Known Public Peers or false if not +*/ +static bool isAddressInKnownPublicPeers(const IPv4Address& address) +{ + // keep this exception to avoid bogon addresses kept for outgoing connections + if (isBogonAddress(address)) + return false; + + for (unsigned int i = 0; i < sizeof(knownPublicPeers) / sizeof(knownPublicPeers[0]); i++) + { + const IPv4Address& peer_ip = *reinterpret_cast(knownPublicPeers[i]); + if (peer_ip == address) + return true; + } + return false; +} + // Forget public peer (no matter if verified or not) if we have more than the minium number of peers static void forgetPublicPeer(const IPv4Address& address) { + // if address is one of our initial peers we don't forget it + if (isAddressInKnownPublicPeers(address)) + { + return; + } + if (listOfPeersIsStatic) { return; @@ -300,14 +344,10 @@ static void penalizePublicPeerRejectedConnection(const IPv4Address& address) } } + static void addPublicPeer(const IPv4Address& address) { - if ((!address.u8[0]) - || (address.u8[0] == 127) - || (address.u8[0] == 10) - || (address.u8[0] == 172 && address.u8[1] >= 16 && address.u8[1] <= 31) - || (address.u8[0] == 192 && address.u8[1] == 168) - || (address.u8[0] == 255)) + if (isBogonAddress(address)) { return; } From 7005b03e951e4b152c0feb45594ac163542853d6 Mon Sep 17 00:00:00 2001 From: CFB-QUBIC Date: Sun, 11 Feb 2024 13:45:58 +0300 Subject: [PATCH 03/17] Removed ability to issue duplicate assets. --- src/assets.h | 11 ++++++++++- src/qubic.cpp | 10 ++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/assets.h b/src/assets.h index ccce0498..b1f1d9c7 100644 --- a/src/assets.h +++ b/src/assets.h @@ -56,7 +56,7 @@ static void deinitAssets() } } -static void issueAsset(const m256i& issuerPublicKey, char name[7], char numberOfDecimalPlaces, char unitOfMeasurement[7], long long numberOfShares, unsigned short managingContractIndex, +static long long issueAsset(const m256i& issuerPublicKey, char name[7], char numberOfDecimalPlaces, char unitOfMeasurement[7], long long numberOfShares, unsigned short managingContractIndex, int* issuanceIndex, int* ownershipIndex, int* possessionIndex) { *issuanceIndex = issuerPublicKey.m256i_u32[0] & (ASSETS_CAPACITY - 1); @@ -105,6 +105,8 @@ static void issueAsset(const m256i& issuerPublicKey, char name[7], char numberOf assetIssuance.numberOfDecimalPlaces = numberOfDecimalPlaces; // Order must be preserved! *((unsigned long long*) assetIssuance.unitOfMeasurement) = *((unsigned long long*) unitOfMeasurement); // Order must be preserved! logAssetIssuance(assetIssuance); + + return numberOfShares; } else { @@ -122,6 +124,13 @@ static void issueAsset(const m256i& issuerPublicKey, char name[7], char numberOf } else { + if (assets[*issuanceIndex].varStruct.issuance.type == ISSUANCE + && ((*((unsigned long long*)assets[*issuanceIndex].varStruct.issuance.name)) & 0xFFFFFFFFFFFFFF) == ((*((unsigned long long*)name)) & 0xFFFFFFFFFFFFFF) + && assets[*issuanceIndex].varStruct.issuance.publicKey == issuerPublicKey) + { + return 0; + } + *issuanceIndex = (*issuanceIndex + 1) & (ASSETS_CAPACITY - 1); goto iteration; diff --git a/src/qubic.cpp b/src/qubic.cpp index ebb45e2a..766c91fc 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -1444,7 +1444,7 @@ static long long __issueAsset(unsigned long long name, const m256i& issuer, char char nameBuffer[7] = { char(name), char(name >> 8), char(name >> 16), char(name >> 24), char(name >> 32), char(name >> 40), char(name >> 48) }; char unitOfMeasurementBuffer[7] = { char(unitOfMeasurement), char(unitOfMeasurement >> 8), char(unitOfMeasurement >> 16), char(unitOfMeasurement >> 24), char(unitOfMeasurement >> 32), char(unitOfMeasurement >> 40), char(unitOfMeasurement >> 48) }; int issuanceIndex, ownershipIndex, possessionIndex; - issueAsset(issuer, nameBuffer, numberOfDecimalPlaces, unitOfMeasurementBuffer, numberOfShares, executedContractIndex, &issuanceIndex, &ownershipIndex, &possessionIndex); + numberOfShares = issueAsset(issuer, nameBuffer, numberOfDecimalPlaces, unitOfMeasurementBuffer, numberOfShares, executedContractIndex, &issuanceIndex, &ownershipIndex, &possessionIndex); return numberOfShares; } @@ -2448,12 +2448,14 @@ static void endEpoch() if (system.epoch < contractDescriptions[contractIndex].constructionEpoch) { IPO* ipo = (IPO*)contractStates[contractIndex]; - const long long finalPrice = ipo->prices[NUMBER_OF_COMPUTORS - 1]; + long long finalPrice = ipo->prices[NUMBER_OF_COMPUTORS - 1]; int issuanceIndex, ownershipIndex, possessionIndex; if (finalPrice) { - m256i zero = _mm256_setzero_si256(); - issueAsset(zero, (char*)contractDescriptions[contractIndex].assetName, 0, CONTRACT_ASSET_UNIT_OF_MEASUREMENT, NUMBER_OF_COMPUTORS, QX_CONTRACT_INDEX, &issuanceIndex, &ownershipIndex, &possessionIndex); + if (!issueAsset(_mm256_setzero_si256(), (char*)contractDescriptions[contractIndex].assetName, 0, CONTRACT_ASSET_UNIT_OF_MEASUREMENT, NUMBER_OF_COMPUTORS, QX_CONTRACT_INDEX, &issuanceIndex, &ownershipIndex, &possessionIndex)) + { + finalPrice = 0; + } } numberOfReleasedEntities = 0; for (unsigned int i = 0; i < NUMBER_OF_COMPUTORS; i++) From f52f8f91ca5f1c27373456724a8fac702108ce26 Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Sun, 11 Feb 2024 14:02:54 +0100 Subject: [PATCH 04/17] Update peer sharing protocol docs --- doc/protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/protocol.md b/doc/protocol.md index 5cf1e8b9..f5add393 100644 --- a/doc/protocol.md +++ b/doc/protocol.md @@ -24,7 +24,7 @@ If an outgoing connection to a verified peer is rejected, the peer loses the ver If an outgoing connection to a non-verified peer is rejected, the peer is removed from the list of peers. If an outgoing connection to a non-verified peer is accepted and an `ExchangePublicPeers` message is received, the peer gets the verified status. If a protocol violation is detected at any moment during communication (allowing to assume the remote end runs something else, not Qubic node), then the IP is removed even if it is verified. -An IP is only removed from the list of peers if the list still has at least 10 entries afterwards. +An IP is only removed from the list of peers if the list still has at least 10 entries afterwards and if it is not in the initial `knownPublicPeers`. ## ... From 3f45da43a996592a64f40bfe5e726d6f9a5da5c1 Mon Sep 17 00:00:00 2001 From: J0ET0M <107187448+J0ET0M@users.noreply.github.com> Date: Sun, 11 Feb 2024 13:20:22 +0000 Subject: [PATCH 05/17] Feature/2024 02 09 system info network message (#52) * added system info request/response * moved system_info.h to folder * remove unrelated check (3 commits squashed) --------- Co-authored-by: Philipp Werner <22914157+philippwerner@users.noreply.github.com> --- src/Qubic.vcxproj | 1 + src/Qubic.vcxproj.filters | 3 +++ src/network_messages/all.h | 1 + src/network_messages/system_info.h | 32 ++++++++++++++++++++++++++++++ src/qubic.cpp | 32 ++++++++++++++++++++++++++++++ src/score.h | 2 ++ 6 files changed, 71 insertions(+) create mode 100644 src/network_messages/system_info.h diff --git a/src/Qubic.vcxproj b/src/Qubic.vcxproj index f700266a..a0053d07 100644 --- a/src/Qubic.vcxproj +++ b/src/Qubic.vcxproj @@ -29,6 +29,7 @@ + diff --git a/src/Qubic.vcxproj.filters b/src/Qubic.vcxproj.filters index d851300d..853d91e1 100644 --- a/src/Qubic.vcxproj.filters +++ b/src/Qubic.vcxproj.filters @@ -105,6 +105,9 @@ network_core + + network_messages + diff --git a/src/network_messages/all.h b/src/network_messages/all.h index 9a94a848..1343e881 100644 --- a/src/network_messages/all.h +++ b/src/network_messages/all.h @@ -13,3 +13,4 @@ #include "special_command.h" #include "tick.h" #include "transactions.h" +#include "system_info.h" diff --git a/src/network_messages/system_info.h b/src/network_messages/system_info.h new file mode 100644 index 00000000..9588c1d7 --- /dev/null +++ b/src/network_messages/system_info.h @@ -0,0 +1,32 @@ +#pragma once + +#include "common_def.h" + +#define REQUEST_SYSTEM_INFO 46 + + +#define RESPOND_SYSTEM_INFO 47 + +struct RespondSystemInfo +{ + short version; + unsigned short epoch; + unsigned int tick; + unsigned int initialTick; + unsigned int latestCreatedTick; + + unsigned short initialMillisecond; + unsigned char initialSecond; + unsigned char initialMinute; + unsigned char initialHour; + unsigned char initialDay; + unsigned char initialMonth; + unsigned char initialYear; + + unsigned int numberOfEntities; + unsigned int numberOfTransactions; + + m256i randomMiningSeed; +}; + +static_assert(sizeof(RespondSystemInfo) == 2 + 2 + 4 + 4 + 4 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 4 + 32 + 4, "Something is wrong with the struct size of RespondSystemInfo."); diff --git a/src/qubic.cpp b/src/qubic.cpp index b2f4e92e..5ac13b8d 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -1020,6 +1020,32 @@ static void processRequestContractFunction(Peer* peer, const unsigned long long } } +static void processRequestSystemInfo(Peer* peer, RequestResponseHeader* header) +{ + RespondSystemInfo respondedSystemInfo; + + respondedSystemInfo.version = system.version; + respondedSystemInfo.epoch = system.epoch; + respondedSystemInfo.tick = system.tick; + respondedSystemInfo.initialTick = system.initialTick; + respondedSystemInfo.latestCreatedTick = system.latestLedTick; + + respondedSystemInfo.initialMillisecond = system.initialMillisecond; + respondedSystemInfo.initialSecond = system.initialSecond; + respondedSystemInfo.initialMinute = system.initialMinute; + respondedSystemInfo.initialHour = system.initialHour; + respondedSystemInfo.initialDay = system.initialDay; + respondedSystemInfo.initialMonth = system.initialMonth; + respondedSystemInfo.initialYear = system.initialYear; + + respondedSystemInfo.numberOfEntities = numberOfEntities; + respondedSystemInfo.numberOfTransactions = numberOfTransactions; + + respondedSystemInfo.randomMiningSeed = score->initialRandomSeed; + + enqueueResponse(peer, sizeof(respondedSystemInfo), RESPOND_SYSTEM_INFO, header->dejavu(), &respondedSystemInfo); +} + static void processSpecialCommand(Peer* peer, RequestResponseHeader* header) { SpecialCommand* request = header->getPayload(); @@ -1281,6 +1307,12 @@ static void requestProcessor(void* ProcedureArgument) } break; + case REQUEST_SYSTEM_INFO: + { + processRequestSystemInfo(peer, header); + } + break; + case SpecialCommand::type: { processSpecialCommand(peer, header); diff --git a/src/score.h b/src/score.h index e408cf32..9c65af09 100644 --- a/src/score.h +++ b/src/score.h @@ -22,6 +22,7 @@ template< struct ScoreFunction { int miningData[dataLength]; + m256i initialRandomSeed; #pragma warning(push) #pragma warning(disable:4293) @@ -71,6 +72,7 @@ struct ScoreFunction void initMiningData(m256i randomSeed) { + initialRandomSeed = randomSeed; // persist the initial random seed to be able to sned it back on system info response random((unsigned char*)&randomSeed, (unsigned char*)&randomSeed, (unsigned char*)miningData, sizeof(miningData)); } From 1507c06c2f48ef09d78e32307184d97961f42e1f Mon Sep 17 00:00:00 2001 From: CFB-QUBIC Date: Mon, 12 Feb 2024 12:36:57 +0300 Subject: [PATCH 06/17] Added QPI::burn(). --- src/logging.h | 17 ++++++++++++++++ src/private_settings.h | 1 + src/qubic.cpp | 41 ++++++++++++++++++++++++++++++++++----- src/smart_contracts.h | 1 + src/smart_contracts/qpi.h | 8 +++++++- 5 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/logging.h b/src/logging.h index f5b94f07..e77cad3b 100644 --- a/src/logging.h +++ b/src/logging.h @@ -40,6 +40,7 @@ struct RespondLog #define CONTRACT_WARNING_MESSAGE 5 #define CONTRACT_INFORMATION_MESSAGE 6 #define CONTRACT_DEBUG_MESSAGE 7 +#define BURNING 8 #define CUSTOM_MESSAGE 255 static volatile char logBufferLocks[sizeof(logReaderPasscodes) / sizeof(logReaderPasscodes[0])] = { 0 }; static char* logBuffers[sizeof(logReaderPasscodes) / sizeof(logReaderPasscodes[0])] = { NULL }; @@ -291,6 +292,22 @@ struct DummyCustomMessage char _terminator; // Only data before "_terminator" are logged }; +struct Burning +{ + m256i sourcePublicKey; + long long amount; + + char _terminator; // Only data before "_terminator" are logged +}; + +template +static void logBurning(T message) +{ +#if LOG_BURNINGS + logMessage(offsetof(T, _terminator), BURNING, &message); +#endif +} + template static void logCustomMessage(T message) { diff --git a/src/private_settings.h b/src/private_settings.h index 8cc34c1b..5f497984 100644 --- a/src/private_settings.h +++ b/src/private_settings.h @@ -26,6 +26,7 @@ static const unsigned char knownPublicPeers[][4] = { #define LOG_CONTRACT_WARNING_MESSAGES 0 #define LOG_CONTRACT_INFO_MESSAGES 0 #define LOG_CONTRACT_DEBUG_MESSAGES 0 +#define LOG_BURNINGS 0 #define LOG_CUSTOM_MESSAGES 0 static unsigned long long logReaderPasscodes[][4] = { {0, 0, 0, 0}, // REMOVE THIS ENTRY AND REPLACE IT WITH YOUR OWN RANDOM NUMBERS IN [0..18446744073709551615] RANGE IF LOGGING IS ENABLED diff --git a/src/qubic.cpp b/src/qubic.cpp index 766c91fc..634cb075 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -1326,6 +1326,39 @@ static const m256i& __arbitrator() return arbitratorPublicKey; } +static long long __burn(long long amount) +{ + if (amount < 0 || amount > MAX_AMOUNT) + { + return -((long long)(MAX_AMOUNT + 1)); + } + + const int index = spectrumIndex(currentContract); + + if (index < 0) + { + return -amount; + } + + const long long remainingAmount = energy(index) - amount; + + if (remainingAmount < 0) + { + return remainingAmount; + } + + if (decreaseEnergy(index, amount)) + { + Contract0State* contract0State = (Contract0State*)contractStates[0]; + contract0State->contractFeeReserves[executedContractIndex] += amount; + + const Burning burning = { currentContract , amount }; + logBurning(burning); + } + + return remainingAmount; +} + static const m256i& __computor(unsigned short computorIndex) { return broadcastedComputors.broadcastComputors.computors.publicKeys[computorIndex % NUMBER_OF_COMPUTORS]; @@ -1523,11 +1556,9 @@ static long long __transfer(const m256i& destination, long long amount) if (decreaseEnergy(index, amount)) { increaseEnergy(destination, amount); - if (amount) - { - const QuTransfer quTransfer = { currentContract , destination , amount }; - logQuTransfer(quTransfer); - } + + const QuTransfer quTransfer = { currentContract , destination , amount }; + logQuTransfer(quTransfer); } return remainingAmount; diff --git a/src/smart_contracts.h b/src/smart_contracts.h index e1d7080b..180040c4 100644 --- a/src/smart_contracts.h +++ b/src/smart_contracts.h @@ -14,6 +14,7 @@ typedef void (*USER_PROCEDURE)(void*, void*, void*); static const m256i& __arbitrator(); +static long long __burn(long long); static void __beginFunctionOrProcedure(const unsigned int); static const m256i& __computor(unsigned short); static unsigned char __day(); diff --git a/src/smart_contracts/qpi.h b/src/smart_contracts/qpi.h index b6f67066..2a1dff96 100644 --- a/src/smart_contracts/qpi.h +++ b/src/smart_contracts/qpi.h @@ -5329,7 +5329,7 @@ namespace QPI } } - // Initialize or reinitialize as empty collection. + // Reinitialize as empty collection. void reset() { setMem(this, sizeof(*this), 0); @@ -5378,6 +5378,12 @@ namespace QPI return ::__arbitrator(); } + static sint64 burn( + sint64 amount + ) { + return ::__burn(amount); + } + static id computor( uint16 computorIndex // [0..675] ) { From f5fc9de61ec363dff0109fd9062566bfd5dc63ab Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Mon, 12 Feb 2024 13:18:39 +0100 Subject: [PATCH 07/17] add special commands to get+set time --- src/network_messages/special_command.h | 23 ++++++++++++++++++++++- src/qubic.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/network_messages/special_command.h b/src/network_messages/special_command.h index 4b111994..3bf9f9db 100644 --- a/src/network_messages/special_command.h +++ b/src/network_messages/special_command.h @@ -83,4 +83,25 @@ struct SpecialCommandToggleMainModeResquestAndResponse }; #define SPECIAL_COMMAND_REFRESH_PEER_LIST 9ULL // F4 #define SPECIAL_COMMAND_FORCE_NEXT_TICK 10ULL // F5 -#define SPECIAL_COMMAND_REISSUE_VOTE 11ULL // F9 \ No newline at end of file +#define SPECIAL_COMMAND_REISSUE_VOTE 11ULL // F9 + + +struct UtcTime +{ + unsigned short year; // 1900 - 9999 + unsigned char month; // 1 - 12 + unsigned char day; // 1 - 31 + unsigned char hour; // 0 - 23 + unsigned char minute; // 0 - 59 + unsigned char second; // 0 - 59 + unsigned char pad1; + unsigned int nanosecond; // 0 - 999,999,999 +}; + +#define SPECIAL_COMMAND_QUERY_TIME 12ULL // send this to node to query time, responds with time read from clock +#define SPECIAL_COMMAND_SEND_TIME 13ULL // send this to node to set time, responds with time read from clock after setting +struct SpecialCommandSendTime +{ + unsigned long long everIncreasingNonceAndCommandType; + UtcTime utcTime; +}; diff --git a/src/qubic.cpp b/src/qubic.cpp index 766c91fc..0e60c4c4 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -1117,6 +1117,31 @@ static void processSpecialCommand(Peer* peer, RequestResponseHeader* header) enqueueResponse(peer, sizeof(SpecialCommand), SpecialCommand::type, header->dejavu(), request); // echo back to indicate success } break; + case SPECIAL_COMMAND_SEND_TIME: + { + // set time + SpecialCommandSendTime* _request = header->getPayload(); + EFI_TIME newTime; + copyMem(&newTime, &_request->utcTime, sizeof(_request->utcTime)); // caution: response.utcTime is subset of time (smaller size) + newTime.TimeZone = 0; + newTime.Daylight = 0; + EFI_STATUS status = rs->SetTime(&newTime); + if (status != EFI_SUCCESS) + { + logStatusToConsole(L"SetTime() failed!", status, __LINE__); + } + } + // this has no break by intention, because SPECIAL_COMMAND_SEND_TIME responds the same way as SPECIAL_COMMAND_QUERY_TIME + case SPECIAL_COMMAND_QUERY_TIME: + { + // send back current time + SpecialCommandSendTime response; + response.everIncreasingNonceAndCommandType = (request->everIncreasingNonceAndCommandType & 0xFFFFFFFFFFFFFF) | (SPECIAL_COMMAND_SEND_TIME << 56); + updateTime(); + copyMem(&response.utcTime, &time, sizeof(response.utcTime)); // caution: response.utcTime is subset of time (smaller size) + enqueueResponse(peer, sizeof(SpecialCommandSendTime), SpecialCommand::type, header->dejavu(), &response); + } + break; } } } From b186a556a46a12cac770c19c840fef3f245a1f95 Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:47:24 +0100 Subject: [PATCH 08/17] Fix bugs in SpecialCommand response --- src/qubic.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qubic.cpp b/src/qubic.cpp index 634cb075..8037652a 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -1053,7 +1053,7 @@ static void processSpecialCommand(Peer* peer, RequestResponseHeader* header) bs->CopyMem(&response.proposal, &system.proposals[_request->computorIndex], sizeof(ComputorProposal)); bs->CopyMem(&response.ballot, &system.ballots[_request->computorIndex], sizeof(ComputorBallot)); - enqueueResponse(peer, sizeof(response), SPECIAL_COMMAND_GET_PROPOSAL_AND_BALLOT_RESPONSE, header->dejavu(), &response); + enqueueResponse(peer, sizeof(response), SpecialCommand::type, header->dejavu(), &response); } } break; @@ -1072,7 +1072,7 @@ static void processSpecialCommand(Peer* peer, RequestResponseHeader* header) response.computorIndex = _request->computorIndex; *((short*)response.padding) = 0; - enqueueResponse(peer, sizeof(response), SPECIAL_COMMAND_SET_PROPOSAL_AND_BALLOT_RESPONSE, header->dejavu(), &response); + enqueueResponse(peer, sizeof(response), SpecialCommand::type, header->dejavu(), &response); } } break; From e1cf9970e62a901e68aff8b69017080658ca596f Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Wed, 14 Feb 2024 12:26:08 +0100 Subject: [PATCH 09/17] Update docs on development workflow / branches --- doc/contributing.md | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/doc/contributing.md b/doc/contributing.md index d09bc71e..380b373e 100644 --- a/doc/contributing.md +++ b/doc/contributing.md @@ -9,11 +9,11 @@ For big changes, such as adding a smart contract, we recommended to discuss with 2. Clone your fork on your local machine. Your remote repository on GitHub is called origin. 3. Add the original GitHub repository as a remote called upstream. 4. If you have created your fork a while ago, pull upstream changes into your local repository. -5. Create a new branch from `develop` or the current `release/epXX` branch. +5. Create a new branch from `develop`. 6. Fix the bug, correct the typo, solve the problem, etc. Make sure to follow the coding guidelines below. 7. Commit your changes to your new branch. Make sure to use a concise but meaningful commit message. 8. Push your branch to the remote origin (your fork on Github). -9. From your fork on GitHub, open a pull request (PR) in your new branch targeting the `develop` or the current `release/epXX` branch of the original repo. In the PR, describe the problem and how your changes solve it. +9. From your fork on GitHub, open a pull request (PR) in your new branch targeting the `develop` branch of the original repo. In the PR, describe the problem and how your changes solve it. 10. If the PR reviewer requests further changes, push them to your branch. The PR will be updated automatically. 11. When your PR is approved and merged, you can pull the changes from upstream to your local repo and delete your extra branch. @@ -22,10 +22,31 @@ For big changes, such as adding a smart contract, we recommended to discuss with We use a mixture of [GitFlow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) and a [trunk-based-process](https://www.atlassian.com/continuous-delivery/continuous-integration/trunk-based-development) with the following branches: -1. `main`: The code base which is officially deployed on computors. Releases are created from this branch. +1. `main`: The code base that is officially deployed on computors. Releases are created from this branch. +Changes should NOT be committed here directly, but merged from other branches after testing. +Exception: If the current release (such as v1.191.0) has a critical bug, the fix may be committed to the main branch directly (followed by creating a bugfix release such as v1.191.1 after testing the fix). + 2. `develop`: Our current testing branch, which will be automatically deployed to the test-net once active. -3. `release/epXX`: Our release branch for a specific epoch when we have specific tasks to work on (e.g. refactoring). May be deployed to test-net too or automatically by merging to dev. -4. `feature/DeveloperName_FeatureName`: When one of us is working on a specific feature that is unsure to be included into the next release, a feature branch should be created from `develop`. May be deployed to test-net. +Most changes should either be committed here or in feature branches. +Feature branches should be created from `develop` and pull requests (PR) should target `develop`. +Before committing to this branch or creating a PR, please check that everything compiles and the automated tests (gtest) run successfully. + +3. `feature/YYYY-MM-DD-FeatureName`: When we are working on a specific feature that is quite complex and/or requires code review, a feature branch should be created from `develop`. +The commits in this branch do not need to be fully functional, but before creating a pull request, you should check that the final commit compiles and the automated tests (gtest) run successfully. +If the code passes the PR review, it can be merged to the develop branch for testing. +(The idea is to test the changes in an accumulated way in the test net, assuming that most changes work and do not require debugging. This should be easier than deploying each feature branch in the test net separately.) +The branch should be deleted after merging with the PR. + +4. `release/v1.XYZ`: This is a release branch for a specific version, usually for a new epoch. +It should be created from the develop branch after testing the new features and agreeing what is supposed to be included in the release. +This branch is then merged to the main branch via PR before creating the release on the main branch. +The branch may be deleted after merging. +However, it may be necessary to later recreate the branch if an old release needs to be fixed or updated, such as for creating the rollback version v1.190.1 for epoch 94. + +For each release, there will be a tag like `v1.XYZ.N`. +The release description should contain the target epoch number and a short change log. + +Mandatory update releases like adding SC or IPO should be published before Sunday (1/2 of the epoch), so that computors can catch up with AUX&MAIN mode and have the new version running the next epoch seamlessly (the following Wednesday). ## Coding guidelines From 1900e967de9172399d51d1caea7c191d1c263066 Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Wed, 14 Feb 2024 13:37:27 +0100 Subject: [PATCH 10/17] Update version, epoch, and initial tick --- src/public_settings.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/public_settings.h b/src/public_settings.h index 79d5e888..e00fcc5e 100644 --- a/src/public_settings.h +++ b/src/public_settings.h @@ -8,11 +8,11 @@ #define NUMBER_OF_SOLUTION_PROCESSORS 2 // do not increase this for this epoch, because there may be issues due too fast ticking #define VERSION_A 1 -#define VERSION_B 192 +#define VERSION_B 193 #define VERSION_C 0 -#define EPOCH 95 -#define TICK 12380000 +#define EPOCH 96 +#define TICK 12499941 // random seed is now obtained from spectrumDigests From 136d01ad684c830c9ee3b72e2ff0307976701cb9 Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Wed, 14 Feb 2024 14:34:00 +0100 Subject: [PATCH 11/17] Reset miner data and solutions for new epoch --- src/qubic.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/qubic.cpp b/src/qubic.cpp index 3eeee6ff..d72d0a31 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -2499,12 +2499,22 @@ static void beginEpoch1of2() score->resetTaskQueue(); score->loadScoreCache(system.epoch); bs->SetMem(minerSolutionFlags, NUMBER_OF_MINER_SOLUTION_FLAGS / 8, 0); - bs->SetMem((void*)minerScores, sizeof(minerScores[0]) * NUMBER_OF_COMPUTORS, 0); + bs->SetMem((void*)minerPublicKeys, sizeof(minerPublicKeys), 0); + bs->SetMem((void*)minerScores, sizeof(minerScores), 0); + numberOfMiners = NUMBER_OF_COMPUTORS; + bs->SetMem(competitorPublicKeys, sizeof(competitorPublicKeys), 0); + bs->SetMem(competitorScores, sizeof(competitorScores), 0); + bs->SetMem(competitorComputorStatuses, sizeof(competitorComputorStatuses), 0); + minimumComputorScore = 0; + minimumCandidateScore = 0; if (solutionThreshold[system.epoch] <= 0 || solutionThreshold[system.epoch] > DATA_LENGTH) { // invalid threshold solutionThreshold[system.epoch] = SOLUTION_THRESHOLD_DEFAULT; } + system.numberOfSolutions = 0; + bs->SetMem(system.solutions, sizeof(system.solutions), 0); + #if LOG_QU_TRANSFERS && LOG_QU_TRANSFERS_TRACK_TRANSFER_ID CurrentTransferId = 0; #endif From 13f1eaa8b80a71ef56ad3ef9b005df493dea714d Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Wed, 14 Feb 2024 14:37:25 +0100 Subject: [PATCH 12/17] Set initial tick for new epoch. The initialTick is set in endEpoch(), which is called by the tickProcessor() before system.tick++. --- src/qubic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qubic.cpp b/src/qubic.cpp index d72d0a31..9f51661e 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -2717,7 +2717,7 @@ static void endEpoch() assetsEndEpoch(reorgBuffer); system.epoch++; - system.initialTick = system.tick; + system.initialTick = system.tick + 1; mainAuxStatus = ((mainAuxStatus & 1) << 1) | ((mainAuxStatus & 2) >> 1); } From a01aa8313003d1b54fbc35884f56bc4a52ce2d35 Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Wed, 14 Feb 2024 15:06:05 +0100 Subject: [PATCH 13/17] Save system file before reset of solutions --- src/qubic.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/qubic.cpp b/src/qubic.cpp index 9f51661e..8ee6bfc4 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -3212,10 +3212,16 @@ static void tickProcessor(void*) { endEpoch(); + // instruct main loop to save system and wait until it is done + systemMustBeSaved = true; + while (systemMustBeSaved) + { + _mm_pause(); + } + beginEpoch1of2(); beginEpoch2of2(); - systemMustBeSaved = true; spectrumMustBeSaved = true; universeMustBeSaved = true; computerMustBeSaved = true; @@ -4688,8 +4694,8 @@ EFI_STATUS efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemTable) if (systemMustBeSaved) { - systemMustBeSaved = false; saveSystem(); + systemMustBeSaved = false; } if (spectrumMustBeSaved) { From d035f9acce0ac4ebba3fd250d0124204159426c9 Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Wed, 14 Feb 2024 15:38:57 +0100 Subject: [PATCH 14/17] Fix initial tick --- src/public_settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/public_settings.h b/src/public_settings.h index e00fcc5e..352d3ca8 100644 --- a/src/public_settings.h +++ b/src/public_settings.h @@ -12,7 +12,7 @@ #define VERSION_C 0 #define EPOCH 96 -#define TICK 12499941 +#define TICK 12499942 // random seed is now obtained from spectrumDigests From 50c9195266b9546f855f8ca2ee864f3757109683 Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Wed, 14 Feb 2024 15:43:50 +0100 Subject: [PATCH 15/17] Reset more system members for new epoch --- src/qubic.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qubic.cpp b/src/qubic.cpp index 8ee6bfc4..d4e7affd 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -2512,8 +2512,12 @@ static void beginEpoch1of2() solutionThreshold[system.epoch] = SOLUTION_THRESHOLD_DEFAULT; } + system.latestOperatorNonce = 0; + bs->SetMem(system.proposals, sizeof(system.proposals), 0); + bs->SetMem(system.ballots, sizeof(system.ballots), 0); system.numberOfSolutions = 0; bs->SetMem(system.solutions, sizeof(system.solutions), 0); + bs->SetMem(system.futureComputors, sizeof(system.futureComputors), 0); #if LOG_QU_TRANSFERS && LOG_QU_TRANSFERS_TRACK_TRANSFER_ID CurrentTransferId = 0; From 7e41b306fb9097e971cfd351bd33068ed3301a1e Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:00:52 +0100 Subject: [PATCH 16/17] Reset another array before beginning of epoch --- src/qubic.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/qubic.cpp b/src/qubic.cpp index d4e7affd..dfbba1cf 100644 --- a/src/qubic.cpp +++ b/src/qubic.cpp @@ -2480,6 +2480,11 @@ static void beginEpoch1of2() bs->SetMem(tickTransactions, FIRST_TICK_TRANSACTION_OFFSET + (((unsigned long long)MAX_NUMBER_OF_TICKS_PER_EPOCH) * NUMBER_OF_TRANSACTIONS_PER_TICK * MAX_TRANSACTION_SIZE / TRANSACTION_SPARSENESS), 0); bs->SetMem(tickTransactionOffsets, sizeof(tickTransactionOffsets), 0); + for (unsigned int i = 0; i < SPECTRUM_CAPACITY; i++) + { + ((Transaction*)&entityPendingTransactions[i * MAX_TRANSACTION_SIZE])->tick = 0; + } + bs->SetMem(solutionPublicationTicks, sizeof(solutionPublicationTicks), 0); bs->SetMem(faultyComputorFlags, sizeof(faultyComputorFlags), 0); @@ -3490,10 +3495,6 @@ static bool initialize() return false; } - for (unsigned int i = 0; i < SPECTRUM_CAPACITY; i++) - { - ((Transaction*)&entityPendingTransactions[i * MAX_TRANSACTION_SIZE])->tick = 0; - } if (status = bs->AllocatePool(EfiRuntimeServicesData, SPECTRUM_CAPACITY * sizeof(::Entity) >= ASSETS_CAPACITY * sizeof(Asset) ? SPECTRUM_CAPACITY * sizeof(::Entity) : ASSETS_CAPACITY * sizeof(Asset), (void**)&reorgBuffer)) { From 27006a64d40ae7ea77502d9362c3f8c75cff5255 Mon Sep 17 00:00:00 2001 From: Philipp Werner <22914157+philippwerner@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:41:21 +0100 Subject: [PATCH 17/17] Set initial tick for restart --- src/public_settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/public_settings.h b/src/public_settings.h index 352d3ca8..3ab69496 100644 --- a/src/public_settings.h +++ b/src/public_settings.h @@ -12,7 +12,7 @@ #define VERSION_C 0 #define EPOCH 96 -#define TICK 12499942 +#define TICK 12501000 // random seed is now obtained from spectrumDigests