Wrong time when importing transactions with rescanblockchain RPC command #20181

issue ben-kaufman openend this issue on October 18, 2020
  1. ben-kaufman commented at 6:02 pm on October 18, 2020: contributor

    When using the rescanblockchain wallet RPC command, it seems like sometimes (though not always, and I couldn’t find a specific pattern for when this does and doesn’t happen) the time field of all transactions found is being set to the time of the most recent transaction detected. Besides that field, all data (including block and blocktime) return correctly. What’s more, even in a node with txindex=1 this happens, despite that when calling the (non-wallet-specific) getrawtransaction command, it returns the correct time.

    Here’s an example of a testnet transaction where I experienced this behaviour, and the output of Core where the same txid has. 2 different times - a correct one using getrawtransaction and an incorrect one using gettransaction:

     0bitcoin-cli --testnet -rpcwallet=wallet getrawtransaction 8bacfc9c63d181e9d303f57f550fe72870afd640c961466829c6212bb23a72fe 1
     1{
     2  "txid": "8bacfc9c63d181e9d303f57f550fe72870afd640c961466829c6212bb23a72fe",
     3  "hash": "3de22064b8fec52fb183a8ad46fd011e6c6cab9906a008afa3d649d11bd250f1",
     4  "version": 2,
     5  "size": 222,
     6  "vsize": 141,
     7  "weight": 561,
     8  "locktime": 0,
     9  "vin": [
    10    {
    11      "txid": "685571776adce2ac3332faf6ed125235366cc3cb464604c9234bf371f1ab4e02",
    12      "vout": 0,
    13      "scriptSig": {
    14        "asm": "",
    15        "hex": ""
    16      },
    17      "txinwitness": [
    18        "30440220516d0b313aae44f639a111dac8f27bc1fac446345aaad51852a784620ac62c690220433cb7fdeb78cd84574ec0ddd08789a248fe19b71759e1b3b448ff9c3f980be401",
    19        "03eca8ceb44c4d930ab89fb5d721d02a745e4aeb0f75993fa535e98fb6c7f6e16e"
    20      ],
    21      "sequence": 4294967294
    22    }
    23  ],
    24  "vout": [
    25    {
    26      "value": 0.53891045,
    27      "n": 0,
    28      "scriptPubKey": {
    29        "asm": "0 f3020d45a9ccf870ddf4176fde4420931ffd9af6",
    30        "hex": "0014f3020d45a9ccf870ddf4176fde4420931ffd9af6",
    31        "reqSigs": 1,
    32        "type": "witness_v0_keyhash",
    33        "addresses": [
    34          "tb1q7vpq63dfenu8ph05zahau3pqjv0lmxhk73dsjm"
    35        ]
    36      }
    37    },
    38    {
    39      "value": 0.10000000,
    40      "n": 1,
    41      "scriptPubKey": {
    42        "asm": "0 bf702bf755da860153e7b1043fea160c6dcd9f1a",
    43        "hex": "0014bf702bf755da860153e7b1043fea160c6dcd9f1a",
    44        "reqSigs": 1,
    45        "type": "witness_v0_keyhash",
    46        "addresses": [
    47          "tb1qhaczha64m2rqz5l8kyzrl6skp3kum8c6m0c2h4"
    48        ]
    49      }
    50    }
    51  ],
    52  "hex": "02000000000101024eabf171f34b23c9044646cbc36c36355212edf6fa3233ace2dc6a777155680000000000feffffff02e54f360300000000160014f3020d45a9ccf870ddf4176fde4420931ffd9af68096980000000000160014bf702bf755da860153e7b1043fea160c6dcd9f1a024730440220516d0b313aae44f639a111dac8f27bc1fac446345aaad51852a784620ac62c690220433cb7fdeb78cd84574ec0ddd08789a248fe19b71759e1b3b448ff9c3f980be4012103eca8ceb44c4d930ab89fb5d721d02a745e4aeb0f75993fa535e98fb6c7f6e16e00000000",
    53  "blockhash": "00000000000000bc3b97cbe323c4695f39a65cc1d73060dca8ad084fb0ce61b5",
    54  "confirmations": 27528,
    55  "time": 1600623861,
    56  "blocktime": 1600623861
    57}
    
     0bitcoin-cli --testnet -rpcwallet=wallet gettransaction 8bacfc9c63d181e9d303f57f550fe72870afd640c961466829c6212bb23a72fe
     1{
     2  "amount": -0.10000000,
     3  "fee": -0.00000142,
     4  "confirmations": 27528,
     5  "blockhash": "00000000000000bc3b97cbe323c4695f39a65cc1d73060dca8ad084fb0ce61b5",
     6  "blockheight": 1835261,
     7  "blockindex": 24,
     8  "blocktime": 1600623861,
     9  "txid": "8bacfc9c63d181e9d303f57f550fe72870afd640c961466829c6212bb23a72fe",
    10  "walletconflicts": [
    11  ],
    12  "time": 1601486746,
    13  "timereceived": 1602570577,
    14  "bip125-replaceable": "no",
    15  "details": [
    16    {
    17      "involvesWatchonly": true,
    18      "address": "tb1q7vpq63dfenu8ph05zahau3pqjv0lmxhk73dsjm",
    19      "category": "send",
    20      "amount": -0.53891045,
    21      "label": "Change [#5](/bitcoin-bitcoin/5/)",
    22      "vout": 0,
    23      "fee": -0.00000142,
    24      "abandoned": false
    25    },
    26    {
    27      "involvesWatchonly": true,
    28      "address": "tb1qhaczha64m2rqz5l8kyzrl6skp3kum8c6m0c2h4",
    29      "category": "send",
    30      "amount": -0.10000000,
    31      "vout": 1,
    32      "fee": -0.00000142,
    33      "abandoned": false
    34    },
    35    {
    36      "involvesWatchonly": true,
    37      "address": "tb1q7vpq63dfenu8ph05zahau3pqjv0lmxhk73dsjm",
    38      "category": "receive",
    39      "amount": 0.53891045,
    40      "label": "Change [#5](/bitcoin-bitcoin/5/)",
    41      "vout": 0
    42    }
    43  ],
    44  "hex": "02000000000101024eabf171f34b23c9044646cbc36c36355212edf6fa3233ace2dc6a777155680000000000feffffff02e54f360300000000160014f3020d45a9ccf870ddf4176fde4420931ffd9af68096980000000000160014bf702bf755da860153e7b1043fea160c6dcd9f1a024730440220516d0b313aae44f639a111dac8f27bc1fac446345aaad51852a784620ac62c690220433cb7fdeb78cd84574ec0ddd08789a248fe19b71759e1b3b448ff9c3f980be4012103eca8ceb44c4d930ab89fb5d721d02a745e4aeb0f75993fa535e98fb6c7f6e16e00000000"
    45}
    
  2. ben-kaufman added the label Bug on Oct 18, 2020
  3. ghost commented at 10:21 pm on October 18, 2020: none

    time in getrawtransaction is same as block time

    “blocktime” : xxx, (numeric) The block time expressed in UNIX epoch time “time” : n (numeric) Same as “blocktime”

    There are 3 different variables for time in results of gettransaction

    “blocktime” : xxx, (numeric) The block time expressed in UNIX epoch time. “txid” : “hex”, (string) The transaction id. “walletconflicts” : [ (json array) Conflicting transaction ids. “hex”, (string) The transaction id. … ], “time” : xxx, (numeric) The transaction time expressed in UNIX epoch time. “timereceived” : xxx, (numeric) The time received expressed in UNIX epoch time.

  4. ben-kaufman commented at 3:38 pm on October 25, 2020: contributor
    Thanks, right, so I see this explains the getrawtransaction time. Still, this doesn’t explain the issue that all imported transactions after rescan have the time of the most recent transaction detected.
  5. BitcoinTsunami commented at 5:22 pm on December 2, 2020: none

    As a specter user, I had the same problem with multiple incorrect date across several wallet.

    I’ve look at the Bitcoin Core code and the function ComputeSmartTime in wallet.cpp attire my attention. The algorithm try to search for the best time between the received one, the block time one and a smart one wich is produced by a lot of time corrections. This ComputeSmartTime method is conceived with a real time approach in mind. The technique used to determine the smart version of the time is based on the hypothesis that you can’t discover transactions in the wrong order. And if you suppose that transcations can be discovered in the wrong order, the lastestEntry variable is going to be wrong for every transactions discovered after and be the exact same date. That’s exactly what I saw in my Bitcoin Core wallet, a lot of transactions with the exact same date, which is incorrect.

    I’ve not found yet a simple example where transactions could be dicovered in the wrong order, but I’m looking for a case where you start with a small rescan and after a larger one. To be more precise : if you rescan only the latest part of the history (2020 year only), and proceed to a larger rescan after (full rescan), every transaction before 2020 will be noted in 2020 du to the lastEntry constraint in nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));

    When you think about it, in a rescanning scenario, the blocktime is the only exploitable time. The received one means nothing and you can’t find a better value.

    That’s why I’ve patched the problem like this :

    add a rescanning_old_block boolean to ComputeSmartTime In case of rescanning_old_block don’t use anything else than blocktime. propagate this boolean in the methods hierarchy to differenciate realtime incoming transactions with rescanning case. I’m currently testing my patch. Tests cases stay all green. If everything is repaired in my wallets, I’ll submit this little patch in another comment to get feedback on it.

  6. BitcoinTsunami commented at 8:37 am on December 3, 2020: none

    I’ve test this approach on Bitcoin Core v0.21rc2. My transactions dates in my wallets are now correct with the attached patch. This won’t fix transactions with previously incorrect date determination, but it prevent bad datation in the first place during a rescanning process. This patch as no impact on ComputeTimeSmart usage outside rescanning process: realtime flow are not affected.

    I’ll now try to look at the way specter interract with Bitcoin Core API, because this bug is systematic in my wallet case with Specter v0.10.0 and Bitcoin Core (v0.20.1 or v0.21.0rc2).

    I’m pretty sure that the first rescan extecuted by specter is smaller that the next one. As I suggested in my first message, it may be a smaller timeframe first, then a bigger one. But it could also be a smaller address range first (100 first wallets adress), then a bigger range (1000 first). That way transactions may be discovered in wrong order too, because nothing impose to consume addresses in the naturel order of the HD wallet.

      0Date: Thu, 3 Dec 2020 08:39:33 +0100
      1Subject: [PATCH] fix incorrect transaction date during rescanning
      2
      3---
      4 src/wallet/wallet.cpp | 22 +++++++++++++---------
      5 src/wallet/wallet.h   |  8 ++++----
      6 2 files changed, 17 insertions(+), 13 deletions(-)
      7
      8diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
      9index ff8bfff87..1aa1b44df 100644
     10--- a/src/wallet/wallet.cpp
     11+++ b/src/wallet/wallet.cpp
     12@@ -842,7 +842,7 @@ bool CWallet::IsSpentKey(const uint256& hash, unsigned int n) const
     13     return false;
     14 }
     15 
     16-CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation& confirm, const UpdateWalletTxFn& update_wtx, bool fFlushOnClose)
     17+CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation& confirm, const UpdateWalletTxFn& update_wtx, bool fFlushOnClose, bool rescanning_old_block)
     18 {
     19     LOCK(cs_wallet);
     20 
     21@@ -872,7 +872,7 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmatio
     22         wtx.nTimeReceived = chain().getAdjustedTime();
     23         wtx.nOrderPos = IncOrderPosNext(&batch);
     24         wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
     25-        wtx.nTimeSmart = ComputeTimeSmart(wtx);
     26+        wtx.nTimeSmart = ComputeTimeSmart(wtx, rescanning_old_block);
     27         AddToSpends(hash);
     28     }
     29 
     30@@ -980,7 +980,7 @@ bool CWallet::LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx
     31     return true;
     32 }
     33 
     34-bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, CWalletTx::Confirmation confirm, bool fUpdate)
     35+bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, CWalletTx::Confirmation confirm, bool fUpdate, bool rescanning_old_block)
     36 {
     37     const CTransaction& tx = *ptx;
     38     {
     39@@ -1018,7 +1018,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, CWalletTx::Co
     40 
     41             // Block disconnection override an abandoned tx as unconfirmed
     42             // which means user may have to call abandontransaction again
     43-            return AddToWallet(MakeTransactionRef(tx), confirm, /* update_wtx= */ nullptr, /* fFlushOnClose= */ false);
     44+            return AddToWallet(MakeTransactionRef(tx), confirm, /* update_wtx= */ nullptr, /* fFlushOnClose= */ false, rescanning_old_block);
     45         }
     46     }
     47     return false;
     48@@ -1147,9 +1147,9 @@ void CWallet::MarkConflicted(const uint256& hashBlock, int conflicting_height, c
     49     }
     50 }
     51 
     52-void CWallet::SyncTransaction(const CTransactionRef& ptx, CWalletTx::Confirmation confirm, bool update_tx)
     53+void CWallet::SyncTransaction(const CTransactionRef& ptx, CWalletTx::Confirmation confirm, bool update_tx, bool rescanning_old_block)
     54 {
     55-    if (!AddToWalletIfInvolvingMe(ptx, confirm, update_tx))
     56+    if (!AddToWalletIfInvolvingMe(ptx, confirm, update_tx, rescanning_old_block))
     57         return; // Not one of ours
     58 
     59     // If a transaction changes 'conflicted' state, that changes the balance
     60@@ -1788,7 +1788,7 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
     61                 break;
     62             }
     63             for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) {
     64-                SyncTransaction(block.vtx[posInBlock], {CWalletTx::Status::CONFIRMED, block_height, block_hash, (int)posInBlock}, fUpdate);
     65+                SyncTransaction(block.vtx[posInBlock], {CWalletTx::Status::CONFIRMED, block_height, block_hash, (int)posInBlock}, fUpdate, true /* rescanning_old_block */);
     66             }
     67             // scan succeeded, record block as most recent successfully scanned
     68             result.last_scanned_block = block_hash;
     69@@ -3679,7 +3679,7 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t>& mapKeyBirth) const {
     70  * https://bitcointalk.org/?topic=54527, or
     71  * [#1393](/bitcoin-bitcoin/1393/).
     72  */
     73-unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const
     74+unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx, bool rescanning_old_block) const
     75 {
     76     unsigned int nTimeSmart = wtx.nTimeReceived;
     77     if (!wtx.isUnconfirmed() && !wtx.isAbandoned()) {
     78@@ -3710,7 +3710,11 @@ unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const
     79                 }
     80             }
     81 
     82-            nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
     83+            if(!rescanning_old_block) {
     84+                nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
     85+            } else {
     86+                nTimeSmart = blocktime;
     87+            }
     88         } else {
     89             WalletLogPrintf("%s: found %s in block %s not in index\n", __func__, wtx.GetHash().ToString(), wtx.m_confirm.hashBlock.ToString());
     90         }
     91diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
     92index 69cf6b66a..c1695e870 100644
     93--- a/src/wallet/wallet.h
     94+++ b/src/wallet/wallet.h
     95@@ -664,7 +664,7 @@ private:
     96      * Abandoned state should probably be more carefully tracked via different
     97      * posInBlock signals or by checking mempool presence when necessary.
     98      */
     99-    bool AddToWalletIfInvolvingMe(const CTransactionRef& tx, CWalletTx::Confirmation confirm, bool fUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
    100+    bool AddToWalletIfInvolvingMe(const CTransactionRef& tx, CWalletTx::Confirmation confirm, bool fUpdate, bool rescanning_old_block) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
    101 
    102     /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */
    103     void MarkConflicted(const uint256& hashBlock, int conflicting_height, const uint256& hashTx);
    104@@ -676,7 +676,7 @@ private:
    105 
    106     /* Used by TransactionAddedToMemorypool/BlockConnected/Disconnected/ScanForWalletTransactions.
    107      * Should be called with non-zero block_hash and posInBlock if this is for a transaction that is included in a block. */
    108-    void SyncTransaction(const CTransactionRef& tx, CWalletTx::Confirmation confirm, bool update_tx = true) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
    109+    void SyncTransaction(const CTransactionRef& tx, CWalletTx::Confirmation confirm, bool update_tx = true, bool rescanning_old_block = false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
    110 
    111     std::atomic<uint64_t> m_wallet_flags{0};
    112 
    113@@ -876,7 +876,7 @@ public:
    114     bool EncryptWallet(const SecureString& strWalletPassphrase);
    115 
    116     void GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
    117-    unsigned int ComputeTimeSmart(const CWalletTx& wtx) const;
    118+    unsigned int ComputeTimeSmart(const CWalletTx& wtx, bool rescanning_old_block) const;
    119 
    120     /**
    121      * Increment the next transaction order id
    122@@ -895,7 +895,7 @@ public:
    123     //! [@return](/bitcoin-bitcoin/contributor/return/) true if wtx is changed and needs to be saved to disk, otherwise false
    124     using UpdateWalletTxFn = std::function<bool(CWalletTx& wtx, bool new_tx)>;
    125 
    126-    CWalletTx* AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation& confirm, const UpdateWalletTxFn& update_wtx=nullptr, bool fFlushOnClose=true);
    127+    CWalletTx* AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation& confirm, const UpdateWalletTxFn& update_wtx=nullptr, bool fFlushOnClose=true, bool rescanning_old_block=false);
    128     bool LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
    129     void transactionAddedToMempool(const CTransactionRef& tx, uint64_t mempool_sequence) override;
    130     void blockConnected(const CBlock& block, int height) override;
    131-- 
    1322.24.3 (Apple Git-128)
    
  7. BitcoinTsunami commented at 0:14 am on December 5, 2020: none

    I’ve work on a functional test to show the problem. This test restore a watch only wallet with 3 pubkey and show the incorrect behavior of ComputeTimeSmart in case of a limited first rescan, and then a complete rescan. This test failed ont 0.21.0rc2 and pass after the patch I’ve posted previously.

      0#!/usr/bin/env python3
      1# Copyright (c) 2018-2019 The Bitcoin Core developers
      2# Distributed under the MIT software license, see the accompanying
      3# file COPYING or http://www.opensource.org/licenses/mit-license.php.
      4"""Test transaction time rescan.
      5"""
      6
      7from test_framework.test_framework import BitcoinTestFramework
      8from test_framework.util import (
      9    assert_equal,
     10    assert_raises_rpc_error
     11)
     12
     13
     14class TransactionTimeRescanTest(BitcoinTestFramework):
     15    def set_test_params(self):
     16        self.setup_clean_chain = False
     17        self.num_nodes = 3
     18
     19    def skip_test_if_missing_module(self):
     20        self.skip_if_no_wallet()
     21
     22    def run_test(self):
     23        self.log.info('Prepare nodes and wallet')
     24
     25        minernode = self.nodes[0] # node used to mine BTC and create transactions
     26        usernode = self.nodes[1] # reference node with correct time
     27        restorenode = self.nodes[2] # node used to restore reference wallet and demonstrate bug during time determination in ComputeSmartTime (wallet.cpp)
     28
     29        #time constant
     30        mocktime = 1525107225
     31        ten_days = 10 * 24 * 60 * 60
     32
     33        #synchronize nodes and time
     34        self.sync_all()
     35        minernode.setmocktime(mocktime)
     36        usernode.setmocktime(mocktime)
     37        restorenode.setmocktime(mocktime)
     38
     39        #prepare miner wallet
     40        minernode.createwallet(wallet_name='default')
     41        miner_wallet = minernode.get_wallet_rpc('default')
     42        m1 = miner_wallet.getnewaddress()
     43
     44        #prepare the reference wallet with 3 public key
     45        wo1 = 'bcrt1qqvs4h9g5kemwu8zdffv3c9tm3dm2qp9uzlxwzx'
     46        wo2 = 'bcrt1qnw7peeq89hwrg674zjf4phzzluld798p667q7q'
     47        wo3 = 'bcrt1qdr36v724uddf50jhnju3amzap2gmmt9tf4aac5'
     48
     49        usernode.createwallet(wallet_name='wo', disable_private_keys=True)
     50        wo_wallet = usernode.get_wallet_rpc('wo')
     51
     52        wo_wallet.importpubkey(pubkey='02f8802962c2ca756d8961c719f75bdfff2b6dbb775788ed54a68bcb182c0ea1ef')
     53        wo_wallet.importpubkey(pubkey='0330f4a96800a38fa0a49cde4b5f802e95a0c1044e5954389a8d00cecde01b842b')
     54        wo_wallet.importpubkey(pubkey='02f5ccbee49546e0b5bf2e76422ed959e983dafaa94c8abafc9c8f8b99ef23d16a')
     55
     56        self.log.info('Start transactions')
     57        assert_equal(minernode.getblockcount(), 200)
     58
     59        # generate some btc to create transactions and check blockcount
     60        minernode.generatetoaddress(300, m1)
     61        assert_equal(minernode.getblockcount(), 500)
     62
     63        #synchronize nodes and time
     64        self.sync_all()
     65        minernode.setmocktime(mocktime + ten_days)
     66        usernode.setmocktime(mocktime + ten_days)
     67        restorenode.setmocktime(mocktime + ten_days)
     68        # send 10 btc to user first watch-only address
     69        self.log.info('Send 10 btc to user')
     70        txid1 = miner_wallet.sendtoaddress(wo1, 10)
     71        
     72        # generate blocks and check blockcount
     73        minernode.generatetoaddress(100, m1)
     74        assert_equal(minernode.getblockcount(), 600)
     75
     76        #synchronize nodes and time
     77        self.sync_all()
     78        minernode.setmocktime(mocktime + ten_days + ten_days)
     79        usernode.setmocktime(mocktime + ten_days + ten_days)
     80        restorenode.setmocktime(mocktime + ten_days + ten_days)
     81        # send 5 btc to our second watch-only address
     82        self.log.info('Send 5 btc to user')
     83        txid2 = miner_wallet.sendtoaddress(wo2, 5)
     84        
     85        # generate blocks and check blockcount
     86        minernode.generatetoaddress(100, m1)
     87        assert_equal(minernode.getblockcount(), 700)
     88
     89        #synchronize nodes and time
     90        self.sync_all()
     91        minernode.setmocktime(mocktime + ten_days + ten_days + ten_days)
     92        usernode.setmocktime(mocktime + ten_days + ten_days + ten_days)
     93        restorenode.setmocktime(mocktime + ten_days + ten_days + ten_days)
     94        # send 1 btc to our third watch-only address
     95        self.log.info('Send 1 btc to user')
     96        txid3 = miner_wallet.sendtoaddress(wo3, 1)
     97        
     98        # generate more blocks and check blockcount
     99        minernode.generatetoaddress(100, m1)
    100        assert_equal(minernode.getblockcount(), 800)
    101
    102        # getbalance
    103        self.log.info('Check final user balance')
    104        assert_equal(wo_wallet.getbalance(), 16)
    105        assert_equal(len(wo_wallet.listtransactions()), 3)
    106
    107        for tx in wo_wallet.listtransactions():
    108            if tx['address'] == 'bcrt1qqvs4h9g5kemwu8zdffv3c9tm3dm2qp9uzlxwzx':
    109                assert_equal(tx['blocktime'], 1525971225)
    110                assert_equal(tx['time'], 1525971225)
    111            elif tx['address'] == 'bcrt1qnw7peeq89hwrg674zjf4phzzluld798p667q7q':
    112                assert_equal(tx['blocktime'], 1526835225)
    113                assert_equal(tx['time'], 1526835225)
    114            elif tx['address'] == 'bcrt1qdr36v724uddf50jhnju3amzap2gmmt9tf4aac5':
    115                assert_equal(tx['blocktime'], 1527699225)
    116                assert_equal(tx['time'], 1527699225)
    117
    118        self.log.info('Restore user wallet on another node without rescan')
    119        restorenode.createwallet(wallet_name='wo', disable_private_keys=True, )
    120        restorewo_wallet = restorenode.get_wallet_rpc('wo')
    121
    122        restorewo_wallet.importpubkey(pubkey='02f8802962c2ca756d8961c719f75bdfff2b6dbb775788ed54a68bcb182c0ea1ef', rescan=False)
    123        restorewo_wallet.importpubkey(pubkey='0330f4a96800a38fa0a49cde4b5f802e95a0c1044e5954389a8d00cecde01b842b', rescan=False)
    124        restorewo_wallet.importpubkey(pubkey='02f5ccbee49546e0b5bf2e76422ed959e983dafaa94c8abafc9c8f8b99ef23d16a', rescan=False)
    125
    126        assert_equal(restorewo_wallet.getbalance(), 0)
    127        assert_equal(len(restorewo_wallet.listtransactions()), 0)
    128
    129        self.log.info('Rescan last history part')
    130        restorewo_wallet.rescanblockchain(650)
    131        self.log.info('Rescan all history')
    132        restorewo_wallet.rescanblockchain()
    133
    134        self.log.info('Check final user balance after restoration')
    135        assert_equal(restorewo_wallet.getbalance(), 16)
    136        assert_equal(len(restorewo_wallet.listtransactions()), 3)
    137
    138        for tx in restorewo_wallet.listtransactions():
    139            if tx['address'] == 'bcrt1qqvs4h9g5kemwu8zdffv3c9tm3dm2qp9uzlxwzx':
    140                assert_equal(tx['blocktime'], 1525971225)
    141                assert_equal(tx['time'], 1525971225) #current version return incorrect 1527699225
    142            elif tx['address'] == 'bcrt1qnw7peeq89hwrg674zjf4phzzluld798p667q7q':
    143                assert_equal(tx['blocktime'], 1526835225)
    144                assert_equal(tx['time'], 1526835225) #current version return incorrect 1527699225
    145            elif tx['address'] == 'bcrt1qdr36v724uddf50jhnju3amzap2gmmt9tf4aac5':
    146                assert_equal(tx['blocktime'], 1527699225)
    147                assert_equal(tx['time'], 1527699225)
    148
    149
    150if __name__ == '__main__':
    151    TransactionTimeRescanTest().main()
    
  8. jonasschnelli commented at 8:34 am on December 7, 2020: contributor
    @BitcoinTsunami: thanks for the investigation! Would you mind opening a pull request?
  9. BitcoinTsunami referenced this in commit 6622746ea9 on Dec 7, 2020
  10. BitcoinTsunami referenced this in commit 3efe74bfba on Dec 7, 2020
  11. BitcoinTsunami referenced this in commit 9946ec9a29 on Dec 7, 2020
  12. BitcoinTsunami referenced this in commit c663adf52d on Dec 7, 2020
  13. BitcoinTsunami commented at 3:32 pm on December 7, 2020: none
    @jonasschnelli : I’m nearly ready to open a pull request. Can I open it against v0.21.0rc2 or should I rebase it against another target ?
  14. jonatack commented at 3:38 pm on December 7, 2020: member

    I’m nearly ready to open a pull request. Can I open it against v0.21.0rc2 or should I rebase it against another target ?

    Unless it fixes an issue specific to 0.21 only, open it against master. If merged it can be backported to 0.21, if needed.

  15. BitcoinTsunami commented at 3:40 pm on December 7, 2020: none
    Thanks I’ll do that.
  16. BitcoinTsunami referenced this in commit d5f05dab91 on Dec 7, 2020
  17. BitcoinTsunami referenced this in commit 4997a2ea5f on Dec 7, 2020
  18. meshcollider closed this on Sep 28, 2021

  19. sidhujag referenced this in commit 89faa29cfa on Sep 28, 2021
  20. DrahtBot locked this on Oct 30, 2022

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-07-05 19:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me