diff options
| author | mtg0001 <106211915+mtg0001@users.noreply.github.com> | 2026-08-03 10:43:42 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-03 10:43:42 -0300 |
| commit | 57441faffb02f4f2eea37d31b29728de25f18bef (patch) | |
| tree | edade03dddf472790e8bc7e3bc52d3e8f8eac87b /src/main.cpp | |
| parent | 5e37647023463cec4331dc48dc360ba60b22c888 (diff) | |
Add wallet recovery balance audit (#117)
Co-authored-by: Gilcimar Duarte <ti@gpm.infra>
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp index 1b09a1a..75647ba 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -3660,6 +3660,93 @@ bool BitcoinMiner(int nThreadId) | |||
| 3660 | // | 3660 | // |
| 3661 | 3661 | ||
| 3662 | 3662 | ||
| 3663 | WalletRecoveryAudit GetWalletRecoveryAudit() | ||
| 3664 | { | ||
| 3665 | WalletRecoveryAudit audit; | ||
| 3666 | set<vector<unsigned char> > setDerivedPubKeys; | ||
| 3667 | |||
| 3668 | CRITICAL_BLOCK(cs_keyPool) | ||
| 3669 | { | ||
| 3670 | audit.fHaveSeed = HaveHDSeed(); | ||
| 3671 | audit.nDerivedKnown = nHDNext; | ||
| 3672 | if (audit.fHaveSeed) | ||
| 3673 | { | ||
| 3674 | string strError; | ||
| 3675 | for (unsigned int i = 0; i < nHDNext; i++) | ||
| 3676 | { | ||
| 3677 | CKey key; | ||
| 3678 | if (!DeriveHDKey(i, key, strError)) | ||
| 3679 | { | ||
| 3680 | audit.fDeriveComplete = false; | ||
| 3681 | audit.strDeriveError = strprintf("derivation failed at index %u: %s", | ||
| 3682 | i, strError.c_str()); | ||
| 3683 | break; | ||
| 3684 | } | ||
| 3685 | setDerivedPubKeys.insert(key.GetPubKey()); | ||
| 3686 | } | ||
| 3687 | } | ||
| 3688 | } | ||
| 3689 | |||
| 3690 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 3691 | { | ||
| 3692 | for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) | ||
| 3693 | { | ||
| 3694 | CWalletTx& wtx = (*it).second; | ||
| 3695 | if (!wtx.IsFinal() || wtx.fSpent) | ||
| 3696 | continue; | ||
| 3697 | bool fImmature = wtx.IsCoinBase() && wtx.GetBlocksToMaturity() > 0; | ||
| 3698 | |||
| 3699 | bool fTxRecoverable = false; | ||
| 3700 | bool fTxLegacy = false; | ||
| 3701 | for (int i = 0; i < (int)wtx.vout.size(); i++) | ||
| 3702 | { | ||
| 3703 | const CTxOut& txout = wtx.vout[i]; | ||
| 3704 | if (!txout.IsMine()) | ||
| 3705 | continue; | ||
| 3706 | |||
| 3707 | vector<unsigned char> vchPubKey; | ||
| 3708 | bool fRecoverable = false; | ||
| 3709 | if (audit.fHaveSeed && ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) | ||
| 3710 | fRecoverable = setDerivedPubKeys.count(vchPubKey) > 0; | ||
| 3711 | |||
| 3712 | if (fRecoverable) | ||
| 3713 | { | ||
| 3714 | if (fImmature) | ||
| 3715 | audit.nRecoverableImmatureCredit += txout.nValue; | ||
| 3716 | else | ||
| 3717 | audit.nRecoverableCredit += txout.nValue; | ||
| 3718 | fTxRecoverable = true; | ||
| 3719 | } | ||
| 3720 | else | ||
| 3721 | { | ||
| 3722 | if (fImmature) | ||
| 3723 | audit.nLegacyImmatureCredit += txout.nValue; | ||
| 3724 | else | ||
| 3725 | audit.nLegacyCredit += txout.nValue; | ||
| 3726 | fTxLegacy = true; | ||
| 3727 | } | ||
| 3728 | } | ||
| 3729 | |||
| 3730 | if (fTxRecoverable) | ||
| 3731 | { | ||
| 3732 | if (fImmature) | ||
| 3733 | audit.nRecoverableImmatureTx++; | ||
| 3734 | else | ||
| 3735 | audit.nRecoverableTx++; | ||
| 3736 | } | ||
| 3737 | if (fTxLegacy) | ||
| 3738 | { | ||
| 3739 | if (fImmature) | ||
| 3740 | audit.nLegacyImmatureTx++; | ||
| 3741 | else | ||
| 3742 | audit.nLegacyTx++; | ||
| 3743 | } | ||
| 3744 | } | ||
| 3745 | } | ||
| 3746 | |||
| 3747 | return audit; | ||
| 3748 | } | ||
| 3749 | |||
| 3663 | int64 GetBalance() | 3750 | int64 GetBalance() |
| 3664 | { | 3751 | { |
| 3665 | int64 nStart, nEnd; | 3752 | int64 nStart, nEnd; |