Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consensus, contract, mining, researcher, rpc, staking, gui: Implementation of MRC - baseline functionality #2425

Merged
merged 125 commits into from
Mar 21, 2022

Conversation

jamescowens
Copy link
Member

@jamescowens jamescowens commented Jan 15, 2022

This is the tracking PR for Manual Reward Claims (MRC). It is from the mrc_for_pr branch, which I will update at certain points in the mrc development, which is occurring on the mrc branch on my fork. This is a nice way for people to see the diff against the current development branch and understand what is going on. I will be adding documentation to the initial comment here to explain the design choices and implementation.

One point I will make first. I have been running at least one node on testnet with this code at various commit points to guard against regression problems against our current protocol (block v11). Commit c290fae I did full -reindex runs against both testnet and mainnet after the most essential parts of the core code is complete and both passed. I have not yet set up an isolated testnet environment to fork the chain and begin testing MRC. We are not quite ready for that. The rpc function to create an MRC transaction needs to be written (@div72 has graciously volunteered to do that) first, and I need to do a thorough static review of the block v12 consensus to ensure everything is going to work. Initial testing and troubleshooting on isolated testnet fork complete. Minor issues corrected and first and second successful MRCs conducted (see below).

This PR will only have an rpc function to create the MRC. We will do a separate PR for the GUI code as this PR is big enough as it is, although the transaction categories in the GUI have been extended to properly account for MRC.

Closes #2007. Also refer to gridcoin-community/Gridcoin-Tasks#218.

Also closes #1946 as an alternative approach.

See gridcoin-community/Gridcoin-Tasks#250 for the poll to decide the fee split between the staker and the foundation.

Design documentation:

  • Node initiates an MRC via the createmrcrequest rpc function and/or the GUI equivalent (which will be in a separate PR). Note that the createmrcrequest will prevent a node from creating an mrc that is in the zero payment interval, or causes the number of transactions in the memory pool to exceed the MRCOutputLimit (see below). For now this can be overridden for testing purposes, but this will not be allowed on mainnet later. An optional fee can be provided above the minimum (but less than the research subsidy) to change the "queue" position of the MRC request.
  • The node sends out a burn transaction (with a burn requirement of 0.01 GRC) with an attached signed MRC contract to the network (this uses the CreateMRC function).
  • This MRC contract contains much the same information as a CLAIM, which includes the accrued research rewards and CBR to be paid as of the last block (chain head) before the MRC transaction time. The MRC contract is signed by the researcher's beacon key and the hash bound into the signature includes the cpid of the reseacher requesting an MRC and the block hash of the last block before the MRC was created (i.e. the head of the chain). See GetMRCHash(), TrySignMRC(), and MRCSign().
  • The MRC contract transactions from all requesting nodes sit in the memory pool until a staking node binds them into a block.
  • A staking node, which can be a researcher or investor, will call CreateRestOfTheBlock. This will sweep up normal transactions in priority order, and will also include MRC transactions, up to the MRCOutputLimit of 5 or 4 10 or 9 if the Foundation MRC fee sidestake is active. MRC transactions bound to the block but whose number exceeds the MRCOutputLimit are expended (the burn goes through) without action. To minimize the possibility of this occurring, which causes the loss of the burn fee by the MRC requestor without payment, the createmrcrequest on the sending node checks the number of MRC transactions in the memory pool before creating a new one. CreateRestOfTheBlock will also check if an MRC payment has been initiated by the same CPID as the staker (which means the very node that has requested the MRC is now staking immediately after). In that situation, the MRC request will be ignored (and expended) as a normal transaction in favor of a normal research rewards stake by the researcher. This will not be very common for practical purposes. Anyone with a GRC balance high enough to stake often will NOT be using MRC as a matter of course, because it would not be rational in that instance to pay the extra fees for the MRC. People using MRC are very likely to have lower balances, which means the probability of them staking on the block right after the MRC is created by them is extremely low.
  • The CreateMRCRewards, run after CreateGridcoinReward (which computes the staker's reward) will act on the MRC contract transactions included in the block to be staked and create outputs on the coinstake corresponding to the MRC contracts. This information will be recorded in an extended CLAIM contract in the m_mrc_tx_map. This map is keyed by CPID and therefore ensures only one MRC payment can exist per unique CPID in a given block.
  • There is a ValidateMRC function which is wrapped by an MRC contract handler and implements the virtual Validate function to validate incoming MRC transactions. Invalid MRC transactions will cause the sending node to accumulate misbehavior (DoS) score and could lead to banning the sending node to protect against invalid MRCs. The ValidateMRC function (in unwrapped form) is also used in the GRC Validator class, which operates at the block level to validate incoming blocks as part of ConnectBlock.
  • The CreateMRC function calls ComputeMRCFee to compute the fee. This function has a fee curve that looks like the following:
    image
  • Looking at the dark blue line, which is the mrc fees charged as a % of the MRC requesters reward: this starts at 100% during the zero payout interval (consensus parameter MRCZeroPaymentInterval), which is 14 days for mainnet and 10 minutes for testnet. While the normal createmrcrequest will refuse to form an MRC during this interval, if someone modifies a node to try and get around it, and submits an MRC, if greater than 1/2 the interval has elapsed, this will be accepted, but the MRC requester will forfeit 100% of their rewards as fees to the staker and/or foundation. If less than 1/2 the interval has elapsed, the transaction will be rejected and banscore assigned.
  • After the zero payout interval has passed, the fees immediately drop to InitialMRCFeeFractionPostZeroInterval, which is 2/5 or 40%. The fees then decline as c/t where t is the interval since the last reward payment and the current MRC request. So for example at mainnet the end of the zero payment interval is 14 days, and the fees drop to 40%. At 28 days, they will be 20%, etc.
  • The ComputeMRCFee function is called both when the MRC contract is created to record the fees in the MRC, AND also again by the ValidateMRC function upon receipt of a transaction by a receiving node to check that the fees were not calculated improperly by a rogue sender. It is also called by the staking node during the CreateRestOfTheBlock function. Fees that do not agree or incorrect rewards on an incoming MRC transaction will fail validation and result in misbehavior points.
  • A portion of the MRC fee can be set aside by setting the Fraction FoundationSidestakeAllocation. Currently this is static in the early test stage at 1/20 (5%), but it is anticipated that this will be made a dynamic setting that can be changed by an administrative protocol setting. By poll ID 651a3d7cbb797ee06bd8c2b17c415223d77bb296434866ddf437a42b6d1e9d89, the foundation sidestake allocation was set to the permanent value of 4/5, i.e. 80%. A change to this value will require a poll and another mandatory.
  • Likewise if the above foundation fraction is greater than zero, another function, the FoundationSidestakeAddress, will return the foundation's address. This is currently overridable by a startup parameter for testing and testnet purposes , but it is anticipated that this will also be made a dynamic setting that can be changed by an administrative protocol setting.
  • If there is a non-zero allocation to the foundation from the fees, the first MRC output on the coinstake will be the fee payment to the foundation. Essentially this is a special sidestake.
  • The remainder of the fees will go back to the staker. This is why the splitting/regular sidestake stuff has to be done AFTER the MRC payments are created, because you need to know all of the fees first.
  • The accrual system has been extended to ensure it properly deals with the extended claim payments, which include MRC outputs.
  • Note that the MRC payment interval and associated rewards are recorded in the MRC contracts is computed from the last payment to the last block (head of the chain) when the MRC request was created. This last block is recorded in the MRC contract and is checked by the staking node to ensure that the last block is the same as the head of the chain underneath the new block being staked. If they don't match, the MRC transaction is ignored for MRC payout. Essentially this means, in correlation with coinstakes, the MRC transactions do not survive forks/reorgs. The ending interval for MRC payouts in the coinstake is always one block behind the research payout for the staker themselves (because the staker's interval is computed on the new block being staked). MRC transactions and payouts not surviving forks/reorgs can cause MRC payments to be rolled back but this has the advantage of reducing the potentiality of double spend/double reward problems and the alignment along the block times just like the coinstake itself for the main researcher payment greatly simplifies the accrual system modifications.

src/miner.cpp Outdated Show resolved Hide resolved
@jamescowens jamescowens removed the gui label Jan 16, 2022
Copy link
Contributor

@RoboticMind RoboticMind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at the RPC command and have a few comments

src/rpc/blockchain.cpp Outdated Show resolved Hide resolved
src/rpc/blockchain.cpp Outdated Show resolved Hide resolved
@jamescowens
Copy link
Member Author

The first successful MRC on an isolated two node testnet!
Gridcoin first successful MRC send on isolated testnet network 20220116
first successful MRC on isolated testnet.log

@jamescowens
Copy link
Member Author

Note that the characterization of the MRC fees going to the staker (in this case 100% because we are in the 14 day period), have to be recharacterized. They are showing up as PoS mined. We will have to create a separate category I think. otherwise it will be confusing.

@jamescowens
Copy link
Member Author

Ok. I have implemented InitialMRCFeeFractionPostZeroInterval and MRCZeroPaymentInterval chainparams. This is to formally support different params for the mainnet and testnet chains. Note that InitialMRCFeeFractionPostZeroInterval is set to 2/5 (40%) for both, but MRCZeroPaymentInterval is set to 14 days on mainnet, but 10 minutes on testnet to facilitate rapid testing of the zero interval and fee decay curve.

@jamescowens
Copy link
Member Author

Here is another test with the above parameters in force for testnet and where the MRC is beyond the zero payment interval...
Gridcoin second successful MRC send on isolated testnet network 20220117
second successful MRC on isolated testnet.log

@jamescowens
Copy link
Member Author

I will be thinking through how to change the GUI transaction display to be more clear what is going on.

@jamescowens jamescowens force-pushed the mrc_for_pr branch 2 times, most recently from cbf23ee to f476d85 Compare January 20, 2022 07:47
@jamescowens
Copy link
Member Author

jamescowens commented Jan 22, 2022

We need to decide how to extend

enum MinedType
{
UNKNOWN = 0,
POS = 1,
POR = 2,
ORPHANED = 3,
POS_SIDE_STAKE_RCV = 4,
POR_SIDE_STAKE_RCV = 5,
POS_SIDE_STAKE_SEND = 6,
POR_SIDE_STAKE_SEND = 7,
SUPERBLOCK = 8
};

for mrcs.

This is largely for display purposes as the underlying transaction structure is already good.

I think we need MRC_RCV and MRC_SEND. The lower part of the block should always be purple because the MRC is ALWAYS associated with a research reward. The upper part is green and red, respectively for receive and send as usual.

We also may need a separate one for the foundation fee sidstake.

Let's go through an example MRC request and payment.

image

The bottom transaction is the original request. This does not have a destination, because it is a burn transaction. The debited amount is correct and good and represents the burn fee + the normal transaction fee.

The top transaction is the payment back to node 1 from the block staked by node 2.
Notice that the amoutn of

The request was initiated from node 1 (on the left), which is a node with a valid beacon and accruing research rewards to be paid, while the staking node is an investor node and on the right.

The original mrc request was as follows on node 1:

15:48:56
createmrcrequest

15:48:57
{
"txid": "0dedfc8bc1527825077278ba5189038b44b49b1cd0df6cc6ceccecec8c7a4b37",
"reward": 139.71643518,
"fee": 11.97569444
}

So you can see the reward and the fee to be taken out. Here is how node 1 displays the original request and the result.
image

The bottom transaction is the original mrc request and shows the proper debit for the burn + transaction fee. There is no destination because it is a burn.

The top transaction is the payment to node 1 from the block staked by node 2. The amount is correct: 139.71643518 - 11.97569444 = 127.74074074, which is the net payment due after taking out the MRC fees. The misleading point is the golden color of the block body. This is because the MRC was paid from a staker that is a non-researcher. This is where we need to introduce the MRC_RCV to have the bottom colored purple, regardless of whether the node staking and paying the MRC is a researcher or non-researcher, because in this case the researcher context is from the requester.

@jamescowens
Copy link
Member Author

jamescowens commented Jan 22, 2022

The display for node 2 is the following:
image

The bottom entry is the entire value of the coinstake, following the rule established long ago when side-staking was implemented, to show the entire value of the coinstake as a positive, then show the payout as negatives.

The middle entry is the MRC "sidestake" of fees to the foundation address. This only appears here as a receive because I am temporarily using an address on node 2 as the "foundation address" for staking. So this entry would not be present on mainnet in any normal person's wallet.

The top entry is the actual payment to the MRC requester.

How does the math work? The outputs minus the input is equal to 139.71643518 (MRC rewards) + 0.001 (tx fees to staker) + 10 (CBR) = 149.71743518

The fees to the staker and the foundation are taken from the MRC rewards. The foundation fraction (5%) is sent to the foundation = 0.59878472. The staker simply keeps the remainder of the fees and the MRC rewards - total fees is sent to the MRC requester. Here is a small Excel grid to show how it all fits together...
image

@jamescowens
Copy link
Member Author

jamescowens commented Jan 23, 2022

Ok. With the "Correct UI display/categorization of MRC payments commit applied, node 1 (the MRC requester) shows:
image
image

Node 2 (the staker) shows:
image

This is correct.

@jamescowens jamescowens changed the title consensus, contract, mining, researcher, rpc, staking: Tracking PR for implementation of MRC consensus, contract, mining, researcher, rpc, staking, gui: Tracking PR for implementation of MRC Jan 23, 2022
@jamescowens jamescowens marked this pull request as ready for review January 23, 2022 16:56
@jamescowens
Copy link
Member Author

I marked this ready for review even though some things still need tidying up.

src/gridcoin/claim.h Show resolved Hide resolved
src/gridcoin/mrc.cpp Outdated Show resolved Hide resolved
src/gridcoin/mrc.cpp Outdated Show resolved Hide resolved
@jamescowens
Copy link
Member Author

jamescowens commented Jan 23, 2022

Ok. This is after creating a GUI category for the MRC request contract send... I created a file src/qt/res/icons/tx_contract_mrc.svg which is a copy of the send.svg in the light theme as a temporary stand in.
image

The tooltip shows "Manual Rewards Claim Request".

jamescowens and others added 15 commits March 12, 2022 18:01
This code was refactored and changed into an erasure.
This is moved to the generic ConnectBlock from the Gridcoin specific
ConnectBlock so that it can be executed after mempool remove for all
tx in block.
This adds a check to ensure v12 blocks are enabled at the start
of the createmrcrequest function to avoid a cryptic error message
that the mrc request queue is full if submitted while still on
v11 blocks. That error message is technically true, since the
MRC output limit is zero for v11, but the error message is
misleading.
This commit changes the behavior of processing mrc transactions
in CreateRestOfTheBlock to only add mrc transactions to the block
from the mempool that meet all conditions for binding into the
block and the claim. The other MRC transactions in the mempool
are ignored and will become stale.
Also modify FoundationSideStakeAddress()
@jamescowens jamescowens changed the title consensus, contract, mining, researcher, rpc, staking, gui: Tracking PR for implementation of MRC consensus, contract, mining, researcher, rpc, staking, gui: Implementation of MRC - baseline functionality Mar 21, 2022
@jamescowens
Copy link
Member Author

I am doing another sync from zero on my isolated testnet branch (fork #3) of one of the nodes to ensure that the transition to v12 goes well. If this passes I am merging this PR into the development branch. The MRC code will be inactive on testnet and is backwards compatible with earlier code for block versions v11 and below. The remaining items to actually activate MRC on testnet will be done in a subsequent PR.

@jamescowens
Copy link
Member Author

The sync from zero through v12 transition in the isolated fork went flawlessly. Merging this PR into development.

@jamescowens jamescowens merged commit 77d037d into gridcoin-community:development Mar 21, 2022
jamescowens added a commit to jamescowens/Gridcoin-Research that referenced this pull request Jul 31, 2022
Added
 - test: Add TrimString(...) tests gridcoin-community#2447 (@barton2526)
 - test: Add dead code detection gridcoin-community#2449 (@barton2526)
 - test: Add explicit references to related CVE's in comments gridcoin-community#2467 (@barton2526)
 - test: Add testing of ParseInt/ParseUInt edge cases with leading +/-/0:s gridcoin-community#2470 (@barton2526)
 - consensus, contract, mining, researcher, rpc, staking, gui: Implementation of MRC - baseline functionality gridcoin-community#2425 (@jamescowens)
 - consensus: MRC mandatory implementation code gridcoin-community#2471 (@jamescowens)
 - test: Add upstream sync_tests.cpp gridcoin-community#2481 (@barton2526)
 - net: Countermeasures against eclipse attacks gridcoin-community#2454 (@Pythonix)
 - lint: add script to check for https violations gridcoin-community#2491 (@div72)
 - util: Add flatpath BOINC data directory path resolution for Linux gridcoin-community#2499 (@jamescowens)
 - gui: Add beaconExpired() to researchermodel gridcoin-community#2498 (@jamescowens)
 - consensus: Add missing block nVersion check for v12 blocks in AcceptBlock gridcoin-community#2502 (@jamescowens)
 - gui, util: Add AccrualChangedFromStakeOrMRC core signal gridcoin-community#2503 (@jamescowens)
 - util: Change default -dbcache to 100 MB and also implement -txindexdbcache gridcoin-community#2507 (@jamescowens)
 - rpc, util, consensus: Implement exception handling framework for MRC and fix ValidateMRC to deal with testnet consensus issue gridcoin-community#2508 (@jamescowens)
 - gui: Initial implementation of GUI MRC submission form gridcoin-community#2513 (@jamescowens)
 - build: Port over Bitcoin's translation docs gridcoin-community#2439 (@jamescowens)
 - (2/3) build: integrate libsecp256k1 gridcoin-community#2492 (@div72)
 - gui: New MRC request icon gridcoin-community#2526 (@jamescowens)
 - mandatory, voting: Implement poll type validation in protocol gridcoin-community#2522 (@jamescowens)
 - gui, voting: Implement poll additional fields gui components gridcoin-community#2525 (@jamescowens)
 - gui, researcher: Add GDPR protection display gridcoin-community#2527 (@jamescowens)
 - consensus, rpc: Kermit's mom hardfork (2671700) gridcoin-community#2551 (@jamescowens)

Changed
 - net: Hard Coded Seed Node Cleanup gridcoin-community#2427 (@barton2526)
 - script: Add More Generated Files to Gitignore gridcoin-community#2435 (@RoboticMind)
 - gui: Update copyright year to 2022 for Gridcoin About dialog box gridcoin-community#2443 (@jamescowens)
 - rpc: Change type field in ListTransactions to lower case gridcoin-community#2441 (@jamescowens)
 - refactor: Replace memset calls with array initialization gridcoin-community#2452 (@barton2526)
 - refactor: Changed some parameters from pass by value to pass by reference gridcoin-community#2455 (@Pythonix)
 - ci, cd: improve caching gridcoin-community#2461 (@div72)
 - contrib: port recent macdeployqtplus changes gridcoin-community#2465 (@div72)
 - test: Test for expected return values when calling functions returning a success code gridcoin-community#2464 (@barton2526)
 - build: Improve error message when pkg-config is not installed gridcoin-community#2460 (@barton2526)
 - test: Bump shellcheck, mypy versions gridcoin-community#2463 (@barton2526)
 - build: Update depends packages (expat, fontconfig, freetype, libXau, libxcb, xcb_proto, xproto) gridcoin-community#2466 (@barton2526)
 - lint: run mypy over contrib/devtools gridcoin-community#2475 (@barton2526)
 - build, lint: Remove x-prefix's from comparisons, Fix some shell script issues the linter complains about, Re-enable boost include checks gridcoin-community#2478 (@barton2526)
 - test: Avoid copies of CTransaction gridcoin-community#2479 (@barton2526)
 - ci: change windows CI to Focal, modify wrap_wine to use wine64 for 64bit binaries gridcoin-community#2484 (@barton2526)
 - build: Qt 5.15.2 gridcoin-community#2486 (@barton2526)
 - net: No longer send local address in addrMe gridcoin-community#2459 (@Pythonix)
 - voting, gui, rpc: Enhance PollResult and AVW calculation to improve pool handling gridcoin-community#2489 (@jamescowens)
 - (1/3) refactor: port some misc changes from upstream gridcoin-community#2485 (@div72)
 - build: Try posix-specific CXX first for mingw32 host, Fix Windows cross-compiling with Qt 5.15 gridcoin-community#2494 (@barton2526)
 - Improve upon scanforunspent rpc gridcoin-community#2468 (@iFoggz)
 - rpc: Change tail_fee and head_fee to display in GRC rather than Halfords in createmrcrequest gridcoin-community#2501 (@jamescowens)
 - scripted-diff: change http to https in copyright text gridcoin-community#2504 (@div72)
 - qt, refactor: Use enum type as switch argument in *TableModel gridcoin-community#2496 (@barton2526)
 - build, qt: bump Qt5 version to 5.15.3 gridcoin-community#2510 (@barton2526)
 - utils: run commands using utf-8 string on Windows gridcoin-community#2514 (@barton2526)
 - prevector: enforce is_trivially_copyable_v gridcoin-community#2516 (@div72)
 - crypto: Unroll the ChaCha20 inner loop for performance gridcoin-community#2515 (@div72)
 - gui: Modify VerifyTCPPort to use the status of CheckOutboundConnectionCount gridcoin-community#2506 (@jamescowens)
 - gui: Fix transaction history table column size behavior gridcoin-community#2520 (@jamescowens)
 - log: Use consistent wording in random.cpp log gridcoin-community#2538 (@div72)
 - lint: Use newer versions of our lint packages, remove yq gridcoin-community#2541 (@barton2526)
 - (1/2) validation: move CBlock validation methods to validation.cpp gridcoin-community#2539 (@div72)
 - gui: Implement proportional column resizing for Addressbook with memory gridcoin-community#2543 (@jamescowens)
 - build: remove redundant warning flags gridcoin-community#2546 (@barton2526)
 - qt: Prefix makefile variables with QT_ gridcoin-community#2547 (@barton2526)
 - build: remove build stubs for external leveldb gridcoin-community#2550 (@barton2526)
 - build, refactor: Improve package version usage gridcoin-community#2549 (@barton2526)
 - build: minor boost tidyups gridcoin-community#2548 (@barton2526)

Removed
 - rpc, util: Remove caching from BlockFinder gridcoin-community#2490 (@jamescowens)
 - test: remove obsolete check sig test gridcoin-community#2552 (@div72)

Fixed
 - build: fix unoptimized libraries in depends gridcoin-community#2428 (@barton2526)
 - build: don't use deprecated brew package names gridcoin-community#2429 (@barton2526)
 - qt: fix shutdown on MacOS gridcoin-community#2440 (@div72)
 - net: Do not add random inbound peers to addrman gridcoin-community#2451 (@barton2526)
 - util: skip trying to set the locale on NetBSD gridcoin-community#2448 (@barton2526)
 - build: change bundle id gridcoin-community#2462 (@div72)
 - net: Do not propagate obviously poor addresses onto the network gridcoin-community#2453 (@Pythonix)
 - ci: Fix CI build title to reflect that we are building for bionic, not xenial gridcoin-community#2469 (@barton2526)
 - lint: Fix misc typos gridcoin-community#2472 (@barton2526)
 - util: Fix crash when parsing command line with -noincludeconf=0, Properly handle -noincludeconf on command line gridcoin-community#2473 (@barton2526)
 - build: Fix several minor linter errors gridcoin-community#2476 (@jamescowens)
 - tests: Don't access out of bounds array index: array[sizeof(array)] gridcoin-community#2480 (@barton2526)
 - script: Fix and Minify Icon SVG gridcoin-community#2488 (@RoboticMind)
 - gui: Add missing null pointer check for m_beacon gridcoin-community#2500 (@jamescowens)
 - util: Fix BN_zero macro in key.cpp for OpenSSL 3.0 gridcoin-community#2497 (@jamescowens)
 - rpc, contract: Adjust ValidateMRC, CreateMRC, and createmrcrequest to correct provided fee handling gridcoin-community#2505 (@jamescowens)
 - consensus: Move DoS into contract validators to allow variability of DoS based on context and further fixes to ValidateMRC gridcoin-community#2512 (@jamescowens)
 - lockedpool: When possible, use madvise to avoid including sensitive information in core dumps gridcoin-community#2509 (@barton2526)
 - refactor: Fix some minor linter complaints gridcoin-community#2517 (@jamescowens)
 - miner: Miner Logger bug fix gridcoin-community#2518 (@iFoggz)
 - key: properly parse short DER private keys gridcoin-community#2519 (@div72)
 - researcher: Fix ReadClientStateXml() crash on wrong BOINC directory permissions gridcoin-community#2524 (@jamescowens)
 - init: fix daemon forking gridcoin-community#2521 (@div72)
 - scraper: Change open mode from append to truncate for auth file gridcoin-community#2528 (@jamescowens)
 - gui: New mrc contract icon try #2 gridcoin-community#2529 (@jamescowens)
 - gui: Remove white outlines on MRC icon gridcoin-community#2530 (@a123b)
 - voting: Change m_additional_fields serialization gridcoin-community#2531 (@jamescowens)
 - build, qt: Fix `QMAKE_CXXFLAGS` expression for `mingw32` host gridcoin-community#2537 (@div72)
 - logging: fix logging empty thread name gridcoin-community#2535 (@div72)
 - trivial: fix comment in account header guard gridcoin-community#2542 (@div72)
 - build: Restrict check for CRC32C intrinsic to aarch64 gridcoin-community#2544 (@barton2526)
 - build: force CRCCheck in Windows installer gridcoin-community#2545 (@barton2526)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Manual Reward Claim (MRC) : BountyPot Add Balance Warning To Beacon Process
5 participants