-
Notifications
You must be signed in to change notification settings - Fork 92
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
Added new attributes to the getstakinginfo
and getstakereport
commands
#485
Conversation
// Check if we need to add the average | ||
if (nDays > 0) { | ||
// Add the Average | ||
result.push_back(Pair(vIt->Name + " Avg", FormatMoney(vIt->Total / nDays).c_str())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the average be calculated only over the amount for days where a stake happened? If my wallet is 60 days old, it'll need 305 days to show an accurate number in "365 Avg", for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you mean calculate the average stake for the last X days where X Days is the number of days past since your first stake that is no older than 365 days?
Well, that would not really be a 365 day average, that would be more an average since staking.
The current formula would be 100% accurate if your wallet is 1 year old, but as you say it would be completely off if your wallet has only been staking for like 45 days.
I'll see what I can come up with for making the average more accurate.
I think I can calculate the wallet age based on first stake date and use it to adjust nDays value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would define “X Avg” as the daily average received as rewards over the last X days of active staking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be clearly documented somewhere so people don't accidentally assume the averages are simple averages over the entire X timeframe regardless of initial staking activity.
Ahh, so just add a new attribute to the response?
…On Thu, May 16, 2019, 17:19 alex v. ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/wallet/rpcwallet.cpp
<#485 (comment)>:
> result.push_back(Pair(vIt->Name, FormatMoney(vIt->Total).c_str()));
+
+ // Get the nDays value
+ nDays = 0;
+ if (vIt->Name == "Last 7 Days")
+ nDays = 7;
+ else if (vIt->Name == "Last 30 Days")
+ nDays = 30;
+ else if (vIt->Name == "Last 365 Days")
+ nDays = 365;
+
+ // Check if we need to add the average
+ if (nDays > 0) {
+ // Add the Average
+ result.push_back(Pair(vIt->Name + " Avg", FormatMoney(vIt->Total / nDays).c_str()));
I would define “X Avg” as the daily average received as rewards over the
last X days of active staking.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#485?email_source=notifications&email_token=AAIDAKMQO4DNOXU5SEPXNEDPVURKDA5CNFSM4HNIOYXKYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOBYZ4DAY#discussion_r284614385>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAIDAKOTGBHMRNSWNVWWU63PVURKDANCNFSM4HNIOYXA>
.
|
what I mean is, as a general definition, “X Avg” should show Sum(stakes[today-X:today])/min(X,n) for a wallet which is n days old |
You mean like this: {
"Last 24H": "2.00",
"Last 7 Days": "22.0001",
"Last 7 Days Avg": "3.14287142",
"Last 30 Days": "98.0001",
"Last 30 Days Avg": "3.26667",
"Last 365 Days": "425.2213209",
"Last 365 Days Avg": "1.16498992",
"Last X Avg": "3.14287142",
"Last All": "438.03126175"
} |
Let X be 7, 30 or 365. |
else if (tx->vout[1].scriptPubKey.IsColdStaking()) | ||
return tx->GetCredit(pwalletMain->IsMine(tx->vout[1])) - tx->GetDebit(pwalletMain->IsMine(tx->vout[1])); | ||
|
||
return tx->GetCredit(ISMINE_SPENDABLE) + tx->GetCredit(ISMINE_STAKABLE) - tx->GetDebit(ISMINE_SPENDABLE) - tx->GetDebit(ISMINE_STAKABLE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ignoring ISMINE_SPENDABLE_STAKABLE would make this to fail for wallets holding both the spending and staking key (not an ideal scenario from a security perspective but its technically possible)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll see if I can add more scenarios to the test case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this scenario was already covered by the test cases
Please check this code in the test and let me know what you think:
# Import the 2 keys into a third wallet
self.nodes[0].importprivkey(spending_address_private_key)
self.nodes[0].importprivkey(staking_address_private_key)
Basically in the test cases, there are 3 modes, node 1 has spending key, node 2 has staking key and node 0 has both keys imported
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes you are right, my bad as ISMINE_SPENDABLE_STAKABLE = ISMINE_SPENDABLE | ISMINE_STAKABLE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forget why, but in the 4.6.0 fix that I created for this
This would not get the correct amounts:
tx->GetCredit(ISMINE_SPENDABLE_STAKABLE) - tx->GetDebit(ISMINE_SPENDABLE_STAKABLE);
Bu this would:
tx->GetCredit(ISMINE_SPENDABLE) + tx->GetCredit(ISMINE_STAKABLE) - tx->GetDebit(ISMINE_SPENDABLE) - tx->GetDebit(ISMINE_STAKABLE);
While in theory they should be the same, but I don't remember exactly why.
I think there was code in GetCredit
and GetDebit
that was causing an issue when passing ISMINE_SPENDABLE_STAKABLE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ISMINE_SPENDABLE_STAKABLE
is both Spendable+Stakable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyways, I think the scenarios are covered in the test case
And I also added the time travel stuff that we discussed with @craigmacgregor during the 4.6.0 release which we skipped due to time constraints.
src/wallet/rpcwallet.cpp
Outdated
const CWalletTx* tx; | ||
|
||
// scan the entire wallet transactions | ||
for (auto it = pwalletMain->mapWallet.end(); it != pwalletMain->mapWallet.begin(); --it) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maps are ordered per key so theres no assurance the first stake you will hit is the oldest stake, i'd say the easiest would be to iterate over wtxOrdered
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK, I will replace this with wtxOrdered, thanks for the heads up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed a commit which addresses this.
Rebased the branch from master |
Just to confirm, all the |
Builds on Ubuntu 18.04. Tests pass. Tests make sense. |
src/wallet/rpcwallet.cpp
Outdated
const CWalletTx* tx; | ||
|
||
// scan the entire wallet transactions | ||
for (auto it = pwalletMain->wtxOrdered.begin(); it != pwalletMain->wtxOrdered.end(); ++it) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If wtxOrdered is not changing length during this loop, you could cache the end iterator to save it being calculated each time the loop iterates. I'm not sure on the exact syntax here, in javascript you can do it directly into the loop declaration like this;
for(let i=0, l=my_array.length(); i<l; i++) {
console.log(my_array[i]);
}
I don't think there's an inline way to do it in C++, so you'd just cache the iterator before you start the loop something like this;
std::vector<uint32_t>::const_iterator end = pwalletMain->wtxOrdered.end();
for (auto it = pwalletMain->wtxOrdered.begin(); it != end; ++it)
{
//do stuff
}
It's probably not hugely relevant here since we're hoping the first item is the one we're looking for, but its a neat trick that can optimise loops especially when you're iterating through thousands of items like we can be doing when dealing with wallet transactions and especially long lived staking addresses. Keep it in mind if it's useful somewhere else!
:)
// Check if we need to add the average | ||
if (nDays > 0) { | ||
// Add the Average | ||
result.push_back(Pair(vIt->Name + " Avg", FormatMoney(vIt->Total / nDays).c_str())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be clearly documented somewhere so people don't accidentally assume the averages are simple averages over the entire X timeframe regardless of initial staking activity.
@proletesseract Rebased on master and added cache for the wallet first stake value (Just in memory, so when the report is run more than once it will use the cached timestamp) But this report will be slower for wallets with TX data but no stakes (Since it will have to loop all the TX every time in case it has staked since the last check) |
code looks good. need to resolve travis issues though. |
Travis-CI Passed, merging |
Added new attributes to the
getstakinginfo
andgetstakereport
commandsgetstakinginfo
now hasexpecteddailyreward
getstakereport
now hasLast 7 Days Avg
,Last 30 Days Avg
andLast 365 Days Avg
reports looks like these: