Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
f390f43
Adapt the score_bpp9000 with the ant colony.
cyber-pc Aug 2, 2026
01bb6ae
Change the score queue support a generic task base.
cyber-pc Aug 3, 2026
85b5db5
Replace ACQUIRE/RELEASE with LockGuard.
cyber-pc Aug 4, 2026
00af787
Improve the canonical nonce check
cyber-pc Aug 4, 2026
50e8c65
Add message and transaction for ant.
cyber-pc Aug 4, 2026
037670a
Move the code relate to update miner ranking to separate function.
cyber-pc Aug 4, 2026
28a3df6
Add the ant colony tree and validity rules
cyber-pc Aug 5, 2026
5ba7646
Add the ant colony lifecycle and per-tick anchor digests
cyber-pc Aug 7, 2026
693813c
Main score function for the ant colony.
cyber-pc Aug 7, 2026
7245389
Handle the solution transaction of ant colony.
cyber-pc Aug 7, 2026
fdb8fb9
Score ant solutions on the task queue and add a seen filter
cyber-pc Aug 7, 2026
80db1c5
Improve the ant colony test
cyber-pc Aug 7, 2026
223a378
Support save load snapshot for ant colony.
cyber-pc Aug 7, 2026
6f07fc0
Add the score cache for ant colony.
cyber-pc Aug 8, 2026
8fab23c
Handle the case ant colony tree is full.
cyber-pc Aug 8, 2026
8d49a2b
Collect best ANN at the end of epoch
cyber-pc Aug 8, 2026
f1524ff
Implement request responde for mineableParent and ant's stats in epoch.
cyber-pc Aug 8, 2026
5224c4a
Print stats of ant colony
cyber-pc Aug 8, 2026
4d41c3f
Add ant colony retries queue.
cyber-pc Aug 9, 2026
b8ce241
Queue and publish pool ant solutions.
cyber-pc Aug 9, 2026
5a69349
Enable logging for ant colony.
cyber-pc Aug 9, 2026
875f8a4
Pre-score ant solution transactions at arrival.
cyber-pc Aug 9, 2026
e5c1d33
Enable ant cache saving.
cyber-pc Aug 9, 2026
5013689
Rename the ant ANN state message pair to parent ANN.
cyber-pc Aug 9, 2026
d7db85e
Allow fetch the ANN state of a node.
cyber-pc Aug 9, 2026
833ce2a
Add debug log message for ant colony.
cyber-pc Aug 9, 2026
90f07a0
Bind the ant canonical-nonce rule to the scorer and dispatch by algor…
cyber-pc Aug 9, 2026
2b029f8
Gather the ant colony file names in public_settings.
cyber-pc Aug 9, 2026
0fca52f
Move ant colony related files to the same folder.
cyber-pc Aug 9, 2026
785e4c5
Reject ant solutions whose parent is in the current or a later tick.
cyber-pc Aug 9, 2026
639a087
Make the ant anchor-ring seqlock reader use atomic tick loads
cyber-pc Aug 9, 2026
3e064da
Validate the ant export-set order as a permutation on snapshot load
cyber-pc Aug 9, 2026
25d572a
Pin the bpp9000 score multiplier to 1 with a static assert.
cyber-pc Aug 9, 2026
9476c8b
Combine the ant snapshot meta, anchors and export into one header file.
cyber-pc Aug 10, 2026
8185203
Use a dedicated colony buffer for the snapshot header
cyber-pc Aug 10, 2026
53d3243
Fold the ant snapshot save/load into ant_colony.h
cyber-pc Aug 10, 2026
96cfa37
Gather the ant colony file-scope constants at the top of ant_colony.h
cyber-pc Aug 10, 2026
6e31a45
Replace the ant sibling floor with a per-parent child cap.
cyber-pc Aug 10, 2026
0c93194
Rename the request-respond for get mine nodes.
cyber-pc Aug 10, 2026
1a3fff1
Support request the max number of children per ant node.
cyber-pc Aug 11, 2026
65087fd
Update documentation for ant colony.
cyber-pc Aug 12, 2026
524ff25
Set the number of children to unbound.
cyber-pc Aug 14, 2026
20768f6
Update the antEpochContext with task file's digest.
cyber-pc Aug 13, 2026
88a6a37
Ant colony parent tick uses the absolute tick for consistency.
cyber-pc Aug 13, 2026
519147e
Update unit test for ant colony.
cyber-pc Aug 14, 2026
9bcb561
Disable standalone bpp9000
cyber-pc Aug 14, 2026
cfb81b7
Copy the computor list first before the epoch.
cyber-pc Aug 17, 2026
48e1162
Use asyncsave for collection best ann solution at the end of epoch.
cyber-pc Aug 17, 2026
5c9913d
Ant score cache replicate behavior of standalone score cache.
cyber-pc Aug 17, 2026
34ec3a8
Update ant colony parameters.
cyber-pc Aug 22, 2026
f7516a5
Update document for ant colony's files.
cyber-pc Aug 22, 2026
daa11fb
Update ant colony about ANN's LUT layout.
cyber-pc Aug 24, 2026
42ac52f
Feat/asset raffle (#968)
double-k-3033 Aug 24, 2026
a85db37
Add OLD_QRAFFLE toggle.
cyber-pc Aug 24, 2026
27cc942
Merge upstream PR qubic/core#978 (ant colony on bpp9000)
hackerby888 Aug 24, 2026
57b6ae7
Ant rollback fixes, local test drivers, CMake option
hackerby888 Aug 24, 2026
b8357de
Guard reprocess against empty ticks; make PORT overridable
hackerby888 Aug 24, 2026
08f5bd0
Testnet ant threshold 4100; injector seeds an anchor on an idle chain
hackerby888 Aug 24, 2026
a16dbfd
Ant injector mines on its own thread; forced reprocess only on soluti…
hackerby888 Aug 24, 2026
d597854
Ant injector reads the publish tick after mining, logs each publish
hackerby888 Aug 24, 2026
58e0545
Testnet ant threshold 6500; injector logs each walk and uses no explo…
hackerby888 Aug 24, 2026
5a6148e
Ant injector mines one identity so the tree deepens
hackerby888 Aug 24, 2026
c2293ad
Ant injector uses engine slot 0, off the tick processor's lock
hackerby888 Aug 24, 2026
4cacd2b
Add --ant-trust-claimed-score so an aux node can diverge under test
hackerby888 Aug 24, 2026
b2b989f
Cap the ant injector at a small solution budget
hackerby888 Aug 24, 2026
0d3c5ed
Ant colony on bpp9000 (#978)
cyber-pc Aug 24, 2026
a3e620c
Ant injector: mine seat 1 instead of seat 0
hackerby888 Aug 24, 2026
c8b33c7
Merge upstream/develop into ant-colony branch
hackerby888 Aug 25, 2026
3603679
Merge develop into ant-colony branch
hackerby888 Aug 25, 2026
0745bee
Drop duplicated ant pre-score block from the merge
hackerby888 Aug 25, 2026
acf506b
Ant colony: allow a record without its network, rebuilt on demand
hackerby888 Aug 25, 2026
0fa0ccf
Ant colony: AUX accepts a solution on its claimed score
hackerby888 Aug 25, 2026
d264c2d
Tests for trusted-score admission and records without a network
hackerby888 Aug 25, 2026
3b72dd9
Ant injector no longer requires --fbis to start
hackerby888 Aug 25, 2026
9a7bfda
Ant injector seeds the tree before aiming at the le-parent rule
hackerby888 Aug 25, 2026
3cf3234
Ant injector: warm-up publishes and a tick gap between them
hackerby888 Aug 25, 2026
d20cd5a
Trace ant accepts, over-accepts and network rebuilds behind --ant-debug
hackerby888 Aug 25, 2026
d3acf0a
Only trust a claimed score on builds that can roll a tick back
hackerby888 Aug 25, 2026
ab32736
Avoid std::max in CLI parsing; the legacy sln build has no NOMINMAX
hackerby888 Aug 25, 2026
896da41
Shorten comments added on this branch
hackerby888 Aug 25, 2026
887cdf1
fix over commit on shared memory page
hackerby888 Aug 26, 2026
7a370f3
remove the legacy padding bytes on old epoch data
hackerby888 Aug 26, 2026
cb76697
implement shadow and commit for snapshot
hackerby888 Aug 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
417 changes: 417 additions & 0 deletions doc/ant_colony_mining.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions doc/protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The following transaction types (`tx->inputType`) are defined:
- `ExecutionFeeReportTransactionPrefix`, type 9, defined in `src/network_messages/execution_fees.h`.
- `OracleUserQueryTransactionPrefix`, type 10, defined in `src/oracle_core/oracle_transactions.h`.
- `DogeMiningShareTransaction`, type 11, defined in `src/mining/mining.h`.
- `AntColonyMiningSolutionTransaction`, type 12, defined in `src/mining/mining.h`.


## Peer Sharing
Expand Down
5 changes: 5 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ if(NO_RPC)
target_compile_definitions(Qubic PRIVATE NO_RPC)
endif()

# Peer port override, so a second node can run where the default is taken.
if(DEFINED PORT)
target_compile_definitions(Qubic PRIVATE PORT=${PORT})
endif()

if(NO_ENABLE_QUBIC_LOGGING_EVENT)
target_compile_definitions(Qubic PRIVATE NO_ENABLE_QUBIC_LOGGING_EVENT)
endif()
Expand Down
6 changes: 6 additions & 0 deletions src/Qubic.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<ClInclude Include="contracts\QBAY.h" />
<ClInclude Include="contracts\Nostromo.h" />
<ClInclude Include="contracts\QRaffle.h" />
<ClInclude Include="contracts\QRaffle_old.h" />
<ClInclude Include="contracts\QBond.h" />
<ClInclude Include="contracts\QIP.h" />
<ClInclude Include="contracts\Qusino.h" />
Expand All @@ -69,16 +70,21 @@
<ClInclude Include="files\files.h" />
<ClInclude Include="logging\logging.h" />
<ClInclude Include="logging\net_msg_impl.h" />
<ClInclude Include="mining\ant_colony\ant_colony.h" />
<ClInclude Include="mining\ant_colony\ant_colony_bpp9000.h" />
<ClInclude Include="mining\ant_colony\ant_pending_solutions.h" />
<ClInclude Include="mining\custom_qubic_mining_storage.h" />
<ClInclude Include="mining\mining.h" />
<ClInclude Include="mining\bpp9000_task.generated.h" />
<ClInclude Include="mining\score_bpp9000.h" />
<ClInclude Include="mining\score_common.h" />
<ClInclude Include="mining\score_engine.h" />
<ClInclude Include="mining\task_file.h" />
<ClInclude Include="mining\trit_pack.h" />
<ClInclude Include="network_core\peers.h" />
<ClInclude Include="network_core\tcp4.h" />
<ClInclude Include="network_messages\all.h" />
<ClInclude Include="network_messages\ant_colony_message.h" />
<ClInclude Include="network_messages\network_message_type.h" />
<ClInclude Include="network_messages\assets.h" />
<ClInclude Include="network_messages\broadcast_message.h" />
Expand Down
21 changes: 21 additions & 0 deletions src/Qubic.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
<ClInclude Include="network_messages\all.h">
<Filter>network_messages</Filter>
</ClInclude>
<ClInclude Include="network_messages\ant_colony_message.h">
<Filter>network_messages</Filter>
</ClInclude>
<ClInclude Include="network_messages\header.h">
<Filter>network_messages</Filter>
</ClInclude>
Expand Down Expand Up @@ -123,6 +126,9 @@
<ClInclude Include="contracts\QRaffle.h">
<Filter>contracts</Filter>
</ClInclude>
<ClInclude Include="contracts\QRaffle_old.h">
<Filter>contracts</Filter>
</ClInclude>
<ClInclude Include="contracts\QBond.h">
<Filter>contracts</Filter>
</ClInclude>
Expand Down Expand Up @@ -185,6 +191,18 @@
<ClInclude Include="mining\mining.h">
<Filter>mining</Filter>
</ClInclude>
<ClInclude Include="mining\ant_colony\ant_colony.h">
<Filter>mining\ant_colony</Filter>
</ClInclude>
<ClInclude Include="mining\ant_colony\ant_pending_solutions.h">
<Filter>mining\ant_colony</Filter>
</ClInclude>
<ClInclude Include="mining\ant_colony\ant_colony_bpp9000.h">
<Filter>mining\ant_colony</Filter>
</ClInclude>
<ClInclude Include="mining\trit_pack.h">
<Filter>mining</Filter>
</ClInclude>
<ClInclude Include="logging\logging.h">
<Filter>logging</Filter>
</ClInclude>
Expand Down Expand Up @@ -459,6 +477,9 @@
<Filter Include="mining">
<UniqueIdentifier>{df525479-7504-470c-a25a-de4af8be0e5d}</UniqueIdentifier>
</Filter>
<Filter Include="mining\ant_colony">
<UniqueIdentifier>{7b1f3a52-9c4e-4d2a-b8e6-2a5c9d417f60}</UniqueIdentifier>
</Filter>
<Filter Include="logging">
<UniqueIdentifier>{d334594b-f24d-440e-949a-c791aa13f867}</UniqueIdentifier>
</Filter>
Expand Down
4 changes: 4 additions & 0 deletions src/contract_core/contract_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,11 @@
#define CONTRACT_INDEX QRAFFLE_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QRAFFLE
#define CONTRACT_STATE2_TYPE QRAFFLE2
#ifdef OLD_QRAFFLE
#include "contracts/QRaffle_old.h"
#else
#include "contracts/QRaffle.h"
#endif

#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
Expand Down
68 changes: 54 additions & 14 deletions src/contracts/QRaffle.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,20 @@ constexpr uint32 QRAFFLE_REGISTER_FEE = 5; // percent
constexpr uint32 QRAFFLE_FEE = 1; // percent
constexpr uint32 QRAFFLE_CHARITY_FEE = 1; // percent
constexpr uint32 QRAFFLE_SHAREHOLDER_FEE = 8; // percent
// Retained in the contract's own balance (never transferred out) to fund RANDOM
// entropy purchases in END_EPOCH; builds a self-sustaining reserve over time.
constexpr uint32 QRAFFLE_ENTROPY_FEE = 1; // percent

// RANDOM smart contract entropy purchase: mixed into the winner-selection seed
// once per END_EPOCH. Mirrors RL_RANDOM_* in RandomLottery.h.
constexpr uint16 QRAFFLE_RANDOM_ENTROPY_BITS = 256;
constexpr uint8 QRAFFLE_RANDOM_COLLATERAL_TIER = 0;
constexpr uint64 QRAFFLE_RANDOM_ENTROPY_FEE = RANDOM_BITFEE * QRAFFLE_RANDOM_ENTROPY_BITS;

constexpr uint32 QRAFFLE_MAX_EPOCH = 65536;
constexpr uint32 QRAFFLE_MAX_PROPOSAL_EPOCH = 128;
constexpr uint32 QRAFFLE_MAX_MEMBER = 65536;
constexpr uint32 QRAFFLE_DEFAULT_QRAFFLE_AMOUNT = 10000000ull;
constexpr uint32 QRAFFLE_DEFAULT_QRAFFLE_AMOUNT = 1000000ull;
constexpr uint32 QRAFFLE_MIN_QRAFFLE_AMOUNT = 1000000ull;
constexpr uint32 QRAFFLE_MAX_QRAFFLE_AMOUNT = 1000000000ull;
// Ended token-raffle ring: 16 384 slots × ~96 B ≈ 1.5 MB.
Expand Down Expand Up @@ -1409,16 +1419,7 @@ struct QRAFFLE : public ContractBase
LOG_INFO(locals.log);
return;
}
// QRAFFLE and QXMR are reserved for dividends/registration; disallow in bundles.
if ((locals.item.asset.assetName == QRAFFLE_ASSET_NAME && locals.item.asset.issuer == NULL_ID)
|| (locals.item.asset.assetName == QRAFFLE_QXMR_ASSET_NAME && locals.item.asset.issuer == state.get().QXMRIssuer))
{
qpi.transfer(qpi.invocator(), qpi.invocationReward());
output.returnCode = QRAFFLE_INVALID_BUNDLE;
locals.log = Logger{ QRAFFLE_CONTRACT_INDEX, QRAFFLE_invalidBundle, 0 };
LOG_INFO(locals.log);
return;
}

// Duplicate-asset check within the bundle; O(N²) acceptable for N ≤ 4.
locals.dupFound = 0;
for (locals.j = 0; locals.j < locals.i; locals.j++)
Expand Down Expand Up @@ -2218,6 +2219,16 @@ struct QRAFFLE : public ContractBase
sint64 transferResult;
uint64 sumOfEntryAmountSubmitted, r, winnerRevenue, burnAmount, charityRevenue, shareholderRevenue, registerRevenue, fee, oneShareholderRev;
uint64 tokenPool;
// RANDOM entropy purchase (winner-selection seed strengthening).
Entity entity;
RANDOM::BuyEntropy_input buyEntropyInput;
RANDOM::BuyEntropy_output buyEntropyOutput;
uint64 entropyReserveAmount; // per-block carve-out, recomputed fresh in each of the 3 fee blocks
struct EntropyMixData
{
id baseSeed;
bit_4096 entropy;
} entropyMixData;
uint64 shareholderPerShareUnit;
uint64 registerPerShareUnit;
uint64 actualShareholderTotal;
Expand Down Expand Up @@ -2281,6 +2292,28 @@ struct QRAFFLE : public ContractBase
locals.digest.u64._2 ^ locals.computerDigest.u64._2,
locals.digest.u64._3 ^ locals.computerDigest.u64._3));

// Strengthen the seed with entropy from the RANDOM smart contract's independent
// commit-reveal miner pool, on top of the digest-based value above. This is
// additive, not a replacement: if the purchase fails (insufficient reserve, or
// RANDOM's pool is empty this cycle) baseSeed simply stays digest-only and
// raffle settlement proceeds unchanged -- member funds are already committed,
// so degrading gracefully is safer than blocking settlement.
qpi.getEntity(SELF, locals.entity);
if (locals.entity.incomingAmount - locals.entity.outgoingAmount >= (sint64)QRAFFLE_RANDOM_ENTROPY_FEE)
{
locals.buyEntropyInput.collateralTier = QRAFFLE_RANDOM_COLLATERAL_TIER;
locals.buyEntropyInput.numberOfBits = QRAFFLE_RANDOM_ENTROPY_BITS;
locals.buyEntropyInput.trustee = id::zero();
INVOKE_OTHER_CONTRACT_PROCEDURE(RANDOM, BuyEntropy, locals.buyEntropyInput, locals.buyEntropyOutput, QRAFFLE_RANDOM_ENTROPY_FEE);

if (interContractCallError == NoCallError && !(locals.buyEntropyOutput.entropy == BIT4096_ZERO))
{
locals.entropyMixData.baseSeed = locals.baseSeed;
locals.entropyMixData.entropy = locals.buyEntropyOutput.entropy;
locals.baseSeed = qpi.K12(locals.entropyMixData);
}
}

// Asset descriptor reused by the QXMR distribution and per-token-raffle shareholder
// payout loops below; both iterate QRAFFLE_ASSET possessors directly via locals.iter.
locals.QraffleAsset.assetName = QRAFFLE_ASSET_NAME;
Expand All @@ -2301,12 +2334,15 @@ struct QRAFFLE : public ContractBase
locals.shareholderRevenue = div<uint64>(locals.tokenPool * QRAFFLE_SHAREHOLDER_FEE, 100);
locals.registerRevenue = div<uint64>(locals.tokenPool * QRAFFLE_REGISTER_FEE, 100);
locals.fee = div<uint64>(locals.tokenPool * QRAFFLE_FEE, 100);
// Entropy reserve: retained in the contract's own balance (never transferred),
// funding future RANDOM entropy purchases in END_EPOCH.
locals.entropyReserveAmount = div<uint64>(locals.tokenPool * QRAFFLE_ENTROPY_FEE, 100);
// Round down per-share amounts; winner gets the remainder.
locals.shareholderPerShareUnit = div<uint64>(locals.shareholderRevenue, NUMBER_OF_COMPUTORS);
locals.actualShareholderTotal = locals.shareholderPerShareUnit * NUMBER_OF_COMPUTORS;
locals.registerPerShareUnit = div<uint64>(locals.registerRevenue, state.get().numberOfRegisters);
locals.actualRegisterTotal = locals.registerPerShareUnit * state.get().numberOfRegisters;
locals.winnerRevenue = locals.tokenPool - locals.burnAmount - locals.charityRevenue - locals.actualShareholderTotal - locals.actualRegisterTotal - locals.fee;
locals.winnerRevenue = locals.tokenPool - locals.burnAmount - locals.charityRevenue - locals.actualShareholderTotal - locals.actualRegisterTotal - locals.fee - locals.entropyReserveAmount;

locals.revenueLog = RevenueLogger{
QRAFFLE_CONTRACT_INDEX,
Expand Down Expand Up @@ -2566,14 +2602,17 @@ struct QRAFFLE : public ContractBase
}
}

// Qu pool distribution: 80% to creator, 20% to fee buckets.
// Qu pool distribution: 79% to creator, 21% to fee buckets (incl. entropy reserve).
// Always executed when reserve is met, regardless of per-item delivery outcome.
// (Assets already delivered to winner; we cannot recall them from a user's wallet.)
locals.arBurn = div<uint64>(locals.arGross * (uint64)QRAFFLE_BURN_FEE, 100ull);
locals.arCharity = div<uint64>(locals.arGross * (uint64)QRAFFLE_CHARITY_FEE, 100ull);
locals.arShareholderRev = div<uint64>(locals.arGross * (uint64)QRAFFLE_SHAREHOLDER_FEE, 100ull);
locals.arRegisterRev = div<uint64>(locals.arGross * (uint64)QRAFFLE_REGISTER_FEE, 100ull);
locals.arFee = div<uint64>(locals.arGross * (uint64)QRAFFLE_FEE, 100ull);
// Entropy reserve: retained in the contract's own balance (never transferred),
// funding future RANDOM entropy purchases in END_EPOCH.
locals.entropyReserveAmount = div<uint64>(locals.arGross * (uint64)QRAFFLE_ENTROPY_FEE, 100ull);
// Round down per-share amounts; all rounding dust goes to creator.
locals.arShareholderPerShare = div<uint64>(locals.arShareholderRev, (uint64)NUMBER_OF_COMPUTORS);
locals.arRegisterPerShare = (state.get().numberOfRegisters > 0)
Expand All @@ -2586,7 +2625,8 @@ struct QRAFFLE : public ContractBase
- locals.arCharity
- (locals.arShareholderPerShare * (uint64)NUMBER_OF_COMPUTORS)
- locals.arRegisterPerShareActual
- locals.arFee;
- locals.arFee
- locals.entropyReserveAmount;

qpi.transfer(locals.arInfo.creator, locals.arCreatorPay);
qpi.burn(locals.arBurn);
Expand Down
Loading
Loading