Skip to content

Commit

Permalink
Restore ForEachAccount. Calc owner reward on MN wallet addresses. (#1789
Browse files Browse the repository at this point in the history
)
  • Loading branch information
Bushstar authored Mar 3, 2023
1 parent b6914e8 commit ae87d05
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 40 deletions.
5 changes: 5 additions & 0 deletions src/masternodes/accounts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ Res CAccountsView::SubBalances(const CScript &owner, const CBalances &balances)
return Res::Ok();
}

void CAccountsView::ForEachAccount(std::function<bool(const CScript &)> callback, const CScript &start) {
ForEach<ByHeightKey, CScript, uint32_t>(
[&callback](const CScript &owner, CLazySerialize<uint32_t>) { return callback(owner); }, start);
}

Res CAccountsView::UpdateBalancesHeight(const CScript &owner, uint32_t height) {
WriteBy<ByHeightKey>(owner, height);
return Res::Ok();
Expand Down
1 change: 1 addition & 0 deletions src/masternodes/accounts.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct CFuturesUserValue {

class CAccountsView : public virtual CStorageView {
public:
void ForEachAccount(std::function<bool(const CScript &)> callback, const CScript &start = {});
void ForEachBalance(std::function<bool(const CScript &, const CTokenAmount &)> callback,
const BalanceKey &start = {});
CTokenAmount GetBalance(const CScript &owner, DCT_ID tokenID) const;
Expand Down
22 changes: 22 additions & 0 deletions src/masternodes/masternodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1324,3 +1324,25 @@ CAmount CCustomCSView::GetFeeBurnPctFromAttributes() const {

return attributes->GetValue(feeBurnPctKey, Params().GetConsensus().props.feeBurnPct);
}

void CalcMissingRewardTempFix(CCustomCSView &mnview, const uint32_t targetHeight, const CWallet &wallet) {
mnview.ForEachMasternode([&](const uint256 &id, const CMasternode &node) {
if (node.rewardAddressType) {
const CScript rewardAddress = GetScriptForDestination(node.rewardAddressType == PKHashType ?
CTxDestination(PKHash(node.rewardAddress)) :
CTxDestination(WitnessV0KeyHash(node.rewardAddress)));
if (IsMineCached(wallet, rewardAddress) == ISMINE_SPENDABLE) {
mnview.CalculateOwnerRewards(rewardAddress, targetHeight);
}
}

const CScript rewardAddress = GetScriptForDestination(node.ownerType == PKHashType ?
CTxDestination(PKHash(node.ownerAuthAddress)) :
CTxDestination(WitnessV0KeyHash(node.ownerAuthAddress)));
if (IsMineCached(wallet, rewardAddress) == ISMINE_SPENDABLE) {
mnview.CalculateOwnerRewards(rewardAddress, targetHeight);
}

return true;
});
}
4 changes: 4 additions & 0 deletions src/masternodes/masternodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ CAmount GetTokenCreationFee(int height);
CAmount GetMnCollateralAmount(int height);
CAmount GetProposalCreationFee(int height, const CCustomCSView &view, const CCreateProposalMessage &msg);

// Update owner rewards for MNs missing call to CalculateOwnerRewards after voter fee distributions.
// Missing call fixed in: https://github.com/DeFiCh/ain/pull/1766
void CalcMissingRewardTempFix(CCustomCSView &mnview, const uint32_t targetHeight, const CWallet &wallet);

enum class UpdateMasternodeType : uint8_t {
None = 0x00,
OwnerAddress = 0x01,
Expand Down
21 changes: 8 additions & 13 deletions src/masternodes/mn_rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,15 @@ CAccounts GetAllMineAccounts(CWallet * const pwallet) {
CCustomCSView mnview(*pcustomcsview);
auto targetHeight = ::ChainActive().Height() + 1;

// ForEachBalance is in account order, so we only need to check if the
// last record is the same as the current one to know whether we can skip
// CalculateOwnerRewards or if it needs to be called.
CScript lastCalculatedOwner;

mnview.ForEachBalance([&](const CScript &owner, const CTokenAmount &balance) {
if (IsMineCached(*pwallet, owner) == ISMINE_SPENDABLE) {
if (lastCalculatedOwner != owner) {
mnview.CalculateOwnerRewards(owner, targetHeight);
lastCalculatedOwner = owner;
}
walletAccounts[owner].Add(balance);
CalcMissingRewardTempFix(mnview, targetHeight, *pwallet);

mnview.ForEachAccount([&](CScript const & account) {
if (IsMineCached(*pwallet, account) == ISMINE_SPENDABLE) {
mnview.CalculateOwnerRewards(account, targetHeight);
mnview.ForEachBalance([&](CScript const & owner, CTokenAmount balance) {
return account == owner && walletAccounts[owner].Add(balance);
}, {account, DCT_ID{}});
}

return true;
});

Expand Down
49 changes: 22 additions & 27 deletions src/masternodes/rpc_accounts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,27 +365,28 @@ UniValue listaccounts(const JSONRPCRequest& request) {
CCustomCSView mnview(*pcustomcsview);
auto targetHeight = ::ChainActive().Height() + 1;

// ForEachBalance is in account order, so we only need to check if the
// last record is the same as the current one to know whether we can skip
// CalculateOwnerRewards or if it needs to be called.
CScript lastCalculatedOwner;
CalcMissingRewardTempFix(mnview, targetHeight, *pwallet);

mnview.ForEachBalance([&](const CScript &owner, const CTokenAmount &balance) {
if (isMineOnly && IsMineCached(*pwallet, owner) != ISMINE_SPENDABLE) {
mnview.ForEachAccount([&](CScript const & account) {

if (isMineOnly && IsMineCached(*pwallet, account) != ISMINE_SPENDABLE) {
return true;
}

if (lastCalculatedOwner != owner) {
mnview.CalculateOwnerRewards(owner, targetHeight);
lastCalculatedOwner = owner;
}
mnview.CalculateOwnerRewards(account, targetHeight);

ret.push_back(accountToJSON(owner, balance, verbose, indexed_amounts));
// output the relavant balances only for account
mnview.ForEachBalance([&](CScript const & owner, CTokenAmount balance) {
if (account != owner) {
return false;
}
ret.push_back(accountToJSON(owner, balance, verbose, indexed_amounts));
return --limit != 0;
}, {account, start.tokenID});

start.tokenID = DCT_ID{}; // reset to start id

return --limit != 0;
}, {start.owner, start.tokenID});
return limit != 0;
}, start.owner);

return GetRPCResultCache().Set(request, ret);
}
Expand Down Expand Up @@ -559,23 +560,17 @@ UniValue gettokenbalances(const JSONRPCRequest& request) {
CCustomCSView mnview(*pcustomcsview);
auto targetHeight = ::ChainActive().Height() + 1;

// ForEachBalance is in account order, so we only need to check if the
// last record is the same as the current one to know whether we can skip
// CalculateOwnerRewards or if it needs to be called.
CScript lastCalculatedOwner;
CalcMissingRewardTempFix(mnview, targetHeight, *pwallet);

mnview.ForEachBalance([&](const CScript &owner, CTokenAmount balance) {
if (IsMineCached(*pwallet, owner) == ISMINE_SPENDABLE) {
if (lastCalculatedOwner != owner) {
mnview.CalculateOwnerRewards(owner, targetHeight);
lastCalculatedOwner = owner;
}
totalBalances.Add(balance);
mnview.ForEachAccount([&](CScript const & account) {
if (IsMineCached(*pwallet, account) == ISMINE_SPENDABLE) {
mnview.CalculateOwnerRewards(account, targetHeight);
mnview.ForEachBalance([&](CScript const & owner, CTokenAmount balance) {
return account == owner && totalBalances.Add(balance);
}, {account, DCT_ID{}});
}

return true;
});

auto it = totalBalances.balances.lower_bound(start);
for (size_t i = 0; it != totalBalances.balances.end() && i < limit; it++, i++) {
auto bal = CTokenAmount{(*it).first, (*it).second};
Expand Down

0 comments on commit ae87d05

Please sign in to comment.