Skip to content

Commit 089329a

Browse files
committed
Implement dynamic sidestaking entries
This commit introduces two new settings for sidestaking, -sidestakeaddresses=address1,address2,..., addressN -sidestakeallocations=alloc1,alloc2,...,allocN These may be used in both the config file and with changesettings as an alternative to the original sidestake=address,allocation entries. If the new entries are present, are not empty, and are correctly filled out then they will take precedence over the older entries. The reason this is necessary is that the read-write settings file does not support multiple instances of the same setting, so a restructure was required to support the r-w override.
1 parent 1988cfa commit 089329a

File tree

8 files changed

+120
-82
lines changed

8 files changed

+120
-82
lines changed

src/gridcoin/staking/status.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace {
1818
//!
1919
constexpr const char* STAKING_ERROR_STRINGS[] {
2020
"None",
21-
"Commanded disabled",
21+
"Disabled by configuration",
2222
"No Mature Coins",
2323
"No coins",
2424
"Entire balance reserved",

src/gridcoin/staking/status.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class MinerStatus
2020
enum ReasonNotStakingCategory
2121
{
2222
NONE,
23-
COMMANDED_DISABLED,
23+
DISABLED_BY_CONFIGURATION,
2424
NO_MATURE_COINS,
2525
NO_COINS,
2626
ENTIRE_BALANCE_RESERVED,

src/init.cpp

+15-2
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,21 @@ void SetupServerArgs()
363363
argsman.AddArg("-sidestake=<address,percent>", "Sidestake destination and allocation entry. There can be as many "
364364
"specified as desired. Only six per stake can be sent. If more than "
365365
"six are specified. Six are randomly chosen for each stake. Only active "
366-
"if -enablesidestaking is set.",
367-
ArgsManager::ALLOW_ANY, OptionsCategory::STAKING);
366+
"if -enablesidestaking is set. These settings are overridden if "
367+
"-sidestakeaddresses and -stakestakeallocations are set.",
368+
ArgsManager::ALLOW_ANY | ArgsManager::IMMEDIATE_EFFECT, OptionsCategory::STAKING);
369+
argsman.AddArg("-sidestakeaddresses=<address1,address2,...,addressN>", "Sidestake destination entry. There can be as many "
370+
"specified as desired. Only six per stake can be sent. If more than "
371+
"six are specified. Six are randomly chosen for each stake. Only active "
372+
"if -enablesidestaking is set. If set along with -sidestakeallocations "
373+
"overrides the -sidestake entries.",
374+
ArgsManager::ALLOW_ANY | ArgsManager::IMMEDIATE_EFFECT, OptionsCategory::STAKING);
375+
argsman.AddArg("-sidestakeallocations=percent1,percent2,...,percentN>", "Sidestake allocation entry. There can be as many "
376+
"specified as desired. Only six per stake can be sent. If more than "
377+
"six are specified. Six are randomly chosen for each stake. Only active "
378+
"if -enablesidestaking is set. If set along with -sidestakeaddresses "
379+
"overrides the -sidestake entries.",
380+
ArgsManager::ALLOW_ANY | ArgsManager::IMMEDIATE_EFFECT, OptionsCategory::STAKING);
368381
argsman.AddArg("-enablestakesplit", "Enable unspent output spitting when staking to optimize staking efficiency "
369382
"(default: 0",
370383
ArgsManager::ALLOW_ANY | ArgsManager::IMMEDIATE_EFFECT, OptionsCategory::STAKING);

src/miner.cpp

+97-72
Original file line numberDiff line numberDiff line change
@@ -1189,87 +1189,108 @@ bool IsMiningAllowed(CWallet *pwallet)
11891189

11901190
// This function parses the config file for the directives for side staking. It is used
11911191
// in StakeMiner for the miner loop and also called by rpc getmininginfo.
1192-
bool GetSideStakingStatusAndAlloc(SideStakeAlloc& vSideStakeAlloc)
1192+
SideStakeAlloc GetSideStakingStatusAndAlloc()
11931193
{
1194-
vector<string> vSubParam;
1195-
std::string sAddress;
1196-
double dAllocation = 0.0;
1194+
SideStakeAlloc vSideStakeAlloc;
1195+
std::vector<std::pair<std::string, std::string>> raw_vSideStakeAlloc;
11971196
double dSumAllocation = 0.0;
11981197

1199-
bool fEnableSideStaking = gArgs.GetBoolArg("-enablesidestaking");
1200-
LogPrint(BCLog::LogFlags::MINER, "StakeMiner: fEnableSideStaking = %u", fEnableSideStaking);
1198+
// Parse destinations and allocations. We don't need to worry about any that are rejected other than a warning
1199+
// message, because any unallocated rewards will go back into the coinstake output(s).
12011200

1202-
// If side staking is enabled, parse destinations and allocations. We don't need to worry about any that are rejected
1203-
// other than a warning message, because any unallocated rewards will go back into the coinstake output(s).
1204-
if (fEnableSideStaking)
1201+
// If -sidestakeaddresses and -sidestakeallocations is set in either the config file or the r-w settings file
1202+
// and the settings are not empty and they are the same size, this will take precedence over the multiple entry
1203+
// -sidestake format.
1204+
std::vector<std::string> addresses;
1205+
std::vector<std::string> allocations;
1206+
1207+
ParseString(gArgs.GetArg("-sidestakeaddresses", ""), ',', addresses);
1208+
ParseString(gArgs.GetArg("-sidestakeallocations", ""), ',', allocations);
1209+
1210+
if (addresses.size() != allocations.size())
1211+
{
1212+
LogPrintf("WARN: %s: Malformed new style sidestaking configuration entries. Reverting to original format.",
1213+
__func__);
1214+
}
1215+
1216+
if (addresses.size() && addresses.size() == allocations.size())
1217+
{
1218+
for (unsigned int i = 0; i < addresses.size(); ++i)
1219+
{
1220+
raw_vSideStakeAlloc.push_back(std::make_pair(addresses[i], allocations[i]));
1221+
}
1222+
}
1223+
else if (gArgs.GetArgs("-sidestake").size())
12051224
{
1206-
if (gArgs.GetArgs("-sidestake").size())
1225+
for (auto const& sSubParam : gArgs.GetArgs("-sidestake"))
12071226
{
1208-
for (auto const& sSubParam : gArgs.GetArgs("-sidestake"))
1227+
std::vector<std::string> vSubParam;
1228+
1229+
ParseString(sSubParam, ',', vSubParam);
1230+
if (vSubParam.size() != 2)
12091231
{
1210-
ParseString(sSubParam, ',', vSubParam);
1211-
if (vSubParam.size() != 2)
1212-
{
1213-
LogPrintf("WARN: StakeMiner: Incompletely SideStake Allocation specified. Skipping SideStake entry.");
1214-
vSubParam.clear();
1215-
continue;
1216-
}
1232+
LogPrintf("WARN: %s: Incomplete SideStake Allocation specified. Skipping SideStake entry.", __func__);
1233+
continue;
1234+
}
12171235

1218-
sAddress = vSubParam[0];
1236+
raw_vSideStakeAlloc.push_back(std::make_pair(vSubParam[0], vSubParam[1]));
1237+
}
1238+
}
12191239

1220-
CBitcoinAddress address(sAddress);
1221-
if (!address.IsValid())
1222-
{
1223-
LogPrintf("WARN: StakeMiner: ignoring sidestake invalid address %s.", sAddress.c_str());
1224-
vSubParam.clear();
1225-
continue;
1226-
}
1240+
for (auto const& entry : raw_vSideStakeAlloc)
1241+
{
1242+
std::string sAddress;
1243+
double dAllocation = 0.0;
12271244

1228-
try
1229-
{
1230-
dAllocation = stof(vSubParam[1]) / 100.0;
1231-
}
1232-
catch(...)
1233-
{
1234-
LogPrintf("WARN: StakeMiner: Invalid allocation provided. Skipping allocation.");
1235-
vSubParam.clear();
1236-
continue;
1237-
}
1245+
sAddress = entry.first;
12381246

1239-
if (dAllocation <= 0)
1240-
{
1241-
LogPrintf("WARN: StakeMiner: Negative or zero allocation provided. Skipping allocation.");
1242-
vSubParam.clear();
1243-
continue;
1244-
}
1247+
CBitcoinAddress address(sAddress);
1248+
if (!address.IsValid())
1249+
{
1250+
LogPrintf("WARN: %s: ignoring sidestake invalid address %s.", __func__, sAddress);
1251+
continue;
1252+
}
12451253

1246-
// The below will stop allocations if someone has made a mistake and the total adds up to more than 100%.
1247-
// Note this same check is also done in SplitCoinStakeOutput, but it needs to be done here for two reasons:
1248-
// 1. Early alertment in the debug log, rather than when the first kernel is found, and 2. When the UI is
1249-
// hooked up, the SideStakeAlloc vector will be filled in by other than reading the config file and will
1250-
// skip the above code.
1251-
dSumAllocation += dAllocation;
1252-
if (dSumAllocation > 1.0)
1253-
{
1254-
LogPrintf("WARN: StakeMiner: allocation percentage over 100\%, ending sidestake allocations.");
1255-
break;
1256-
}
1254+
try
1255+
{
1256+
dAllocation = stof(entry.second) / 100.0;
1257+
}
1258+
catch (...)
1259+
{
1260+
LogPrintf("WARN: %s: Invalid allocation provided. Skipping allocation.", __func__);
1261+
continue;
1262+
}
12571263

1258-
vSideStakeAlloc.push_back(std::pair<std::string, double>(sAddress, dAllocation));
1259-
LogPrint(BCLog::LogFlags::MINER, "StakeMiner: SideStakeAlloc Address %s, Allocation %f",
1260-
sAddress.c_str(), dAllocation);
1264+
if (dAllocation <= 0)
1265+
{
1266+
LogPrintf("WARN: %s: Negative or zero allocation provided. Skipping allocation.", __func__);
1267+
continue;
1268+
}
12611269

1262-
vSubParam.clear();
1263-
}
1270+
// The below will stop allocations if someone has made a mistake and the total adds up to more than 100%.
1271+
// Note this same check is also done in SplitCoinStakeOutput, but it needs to be done here for two reasons:
1272+
// 1. Early alertment in the debug log, rather than when the first kernel is found, and 2. When the UI is
1273+
// hooked up, the SideStakeAlloc vector will be filled in by other than reading the config file and will
1274+
// skip the above code.
1275+
dSumAllocation += dAllocation;
1276+
if (dSumAllocation > 1.0)
1277+
{
1278+
LogPrintf("WARN: %s: allocation percentage over 100\%, ending sidestake allocations.", __func__);
1279+
break;
12641280
}
1265-
// If we get here and dSumAllocation is zero then the enablesidestaking flag was set, but no VALID distribution
1266-
// was provided in the config file, so warn in the debug log.
1267-
if (!dSumAllocation)
1268-
LogPrintf("WARN: StakeMiner: enablesidestaking was set in config but nothing has been allocated for"
1269-
" distribution!");
1281+
1282+
vSideStakeAlloc.push_back(std::pair<std::string, double>(sAddress, dAllocation));
1283+
LogPrint(BCLog::LogFlags::MINER, "INFO: %s: SideStakeAlloc Address %s, Allocation %f",
1284+
__func__, sAddress, dAllocation);
12701285
}
12711286

1272-
return fEnableSideStaking;
1287+
// If we get here and dSumAllocation is zero then the enablesidestaking flag was set, but no VALID distribution
1288+
// was provided in the config file, so warn in the debug log.
1289+
if (!dSumAllocation)
1290+
LogPrintf("WARN: %s: enablesidestaking was set in config but nothing has been allocated for"
1291+
" distribution!");
1292+
1293+
return vSideStakeAlloc;
12731294
}
12741295

12751296
// This function parses the config file for the directives for stake splitting. It is used
@@ -1325,17 +1346,21 @@ void StakeMiner(CWallet *pwallet)
13251346
int64_t nMinStakeSplitValue = 0;
13261347
double dEfficiency = 0;
13271348
int64_t nDesiredStakeOutputValue = 0;
1328-
SideStakeAlloc vSideStakeAlloc = {};
1329-
1330-
// nMinStakeSplitValue and dEfficiency are out parameters.
1331-
bool fEnableStakeSplit = GetStakeSplitStatusAndParams(nMinStakeSplitValue, dEfficiency, nDesiredStakeOutputValue);
1332-
1333-
// vSideStakeAlloc is an out parameter.
1334-
bool fEnableSideStaking = GetSideStakingStatusAndAlloc(vSideStakeAlloc);
1349+
SideStakeAlloc vSideStakeAlloc;
13351350

13361351
while (!fShutdown)
13371352
{
1338-
//wait for next round
1353+
// nMinStakeSplitValue and dEfficiency are out parameters.
1354+
bool fEnableStakeSplit = GetStakeSplitStatusAndParams(nMinStakeSplitValue, dEfficiency, nDesiredStakeOutputValue);
1355+
1356+
bool fEnableSideStaking = gArgs.GetBoolArg("-enablesidestaking");
1357+
1358+
LogPrint(BCLog::LogFlags::MINER, "StakeMiner: fEnableSideStaking = %u", fEnableSideStaking);
1359+
1360+
// vSideStakeAlloc is an out parameter.
1361+
if (fEnableSideStaking) vSideStakeAlloc = GetSideStakingStatusAndAlloc();
1362+
1363+
// wait for next round
13391364
MilliSleep(nMinerSleep);
13401365

13411366
g_timer.InitTimer("miner", LogInstance().WillLogCategory(BCLog::LogFlags::MISC));

src/miner.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ std::optional<CWalletTx> GetLastStake(CWallet& wallet);
2525

2626
void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStakeSplit, bool &fEnableSideStaking, SideStakeAlloc &vSideStakeAlloc, double &dEfficiency);
2727
unsigned int GetNumberOfStakeOutputs(int64_t &nValue, int64_t &nMinStakeSplitValue, double &dEfficiency);
28-
bool GetSideStakingStatusAndAlloc(SideStakeAlloc& vSideStakeAlloc);
28+
SideStakeAlloc GetSideStakingStatusAndAlloc();
2929
bool GetStakeSplitStatusAndParams(int64_t& nMinStakeSplitValue, double& dEfficiency, int64_t& nDesiredStakeOutputValue);
3030

3131
#endif // NOVACOIN_MINER_H

src/qt/bitcoingui.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ void BitcoinGUI::createToolBars()
705705
}
706706
else
707707
{
708-
labelStakingIcon->setToolTip(tr("Not staking: Commanded disabled."));
708+
labelStakingIcon->setToolTip(tr("Not staking: Disabled by configuration."));
709709
}
710710

711711
statusBar()->addPermanentWidget(frameBlocks);

src/rpc/mining.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,9 @@ UniValue getmininginfo(const UniValue& params, bool fHelp)
111111
// nMinStakeSplitValue, dEfficiency, and nDesiredStakeSplitValue are out parameters.
112112
bool fEnableStakeSplit = GetStakeSplitStatusAndParams(nMinStakeSplitValue, dEfficiency, nDesiredStakeSplitValue);
113113

114-
// vSideStakeAlloc is an out parameter.
115-
bool fEnableSideStaking = GetSideStakingStatusAndAlloc(vSideStakeAlloc);
114+
bool fEnableSideStaking = gArgs.GetBoolArg("-enablesidestaking");
115+
116+
vSideStakeAlloc = GetSideStakingStatusAndAlloc();
116117

117118
stakesplitting.pushKV("stake-splitting-enabled", fEnableStakeSplit);
118119
if (fEnableStakeSplit)

src/rpc/misc.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ UniValue changesettings(const UniValue& params, bool fHelp)
166166
{
167167
current_value = gArgs.GetArg(name, "never_used_default");
168168
}
169-
catch (std::exception& e)
169+
catch (...)
170170
{
171171
// If it is a number convert back to a string.
172172
current_value = ToString(gArgs.GetArg(name, 1));
@@ -232,4 +232,3 @@ UniValue changesettings(const UniValue& params, bool fHelp)
232232

233233
return result;
234234
}
235-

0 commit comments

Comments
 (0)