[Wallet] Fix transaction history#548
Conversation
| /// <param name="offset">Skip (offset) the result set by this amount (primarily used for pagination).</param> | ||
| /// <returns>Collection of address history and transaction pairs.</returns> | ||
| IEnumerable<AccountHistory> GetHistory(string walletName, string accountName = null, long? prevOutputTxTime = null, int? prevOutputIndex = null, int? take = int.MaxValue, string searchQuery = null); | ||
| IEnumerable<AccountHistory> GetHistory(string walletName, string accountName = null, string searchQuery = null, int? limit = int.MaxValue, int? offset = 0); |
There was a problem hiding this comment.
Offsets, although often used, are generally not 100% reliable due to the fact that the database can change between subsequent queries. In this case, with chronologically ordered data (only the receipts, not the spends), its probably ok and should still work 99.99% of the time assuming rewinds/forks are not occurring all that frequently. Issues, if they occur, will be in the form of omitted or duplicated rows at paging boundaries.
There was a problem hiding this comment.
Yeah, I'm not too concerned this. We have to remember that the history call is currently only used by the UI for the user's benefit. Unless this logic someday gets used for business critical results, I wouldn't worry about it too much.
| /// </summary> | ||
| /// <param name="walletName">The name of the wallet to return the transactions of.</param> | ||
| /// <param name="accountName">An optional account name to limit the results to a particular account.</param> | ||
| /// <param name="account">An optional account name to limit the results to a particular account.</param> |
There was a problem hiding this comment.
How are the results limited to a specific wallet? The database contains the data for multiple wallets so it must be possible to specify a wallet in the absence of a specific wallet account being specified. This could be why the walletName was a separate parameter in the legacy implementation.
There was a problem hiding this comment.
We get the wallet name from the account that is passed in's account root. This is called from:
Is this OK?
There was a problem hiding this comment.
We won't have the wallet name if the account is passed as null here.
| foreach (HdAccount account in accounts) | ||
| { | ||
| accountsHistory.Add(this.GetHistoryForAccount(account, prevOutputTxTime, prevOutputIndex, take.GetValueOrDefault(), searchQuery)); | ||
| accountsHistory.Add(this.GetHistoryForAccount(account, limit.GetValueOrDefault(), 0, searchQuery)); |
There was a problem hiding this comment.
The offset is not passed. Can the offset be used in this way - i.e. across accounts? I suppose the alternative is to use a single query (instead of multiple calls to retrieve each account's info individually)?
There was a problem hiding this comment.
Ah this was a mistake on my part. I will fix this.
| GROUP BY | ||
| t.OutputTxId | ||
| ORDER BY | ||
| t.OutputTxTime DESC |
There was a problem hiding this comment.
Ordering is happening by the "receiving time" of the UTXO even when its being spent/sent at a different time. Should the data be merged with a query getting all the "sends" ordered separately - i.e. using SpendTxTime?
There was a problem hiding this comment.
@quantumagi this is very strange as the SQL i get back is perfectly ordered... I.e receives/sends/stakes/mines all in perfect date order? 🤔
There was a problem hiding this comment.
It seems we will only be displaying the receive date - so that alone would be an issue, and then secondly we only order by the original receive date rather than using the spent date when applicable to the transaction type.
| Assert.Equal(new uint256(toSkip), model.ElementAt(toTake - 1).Hash); | ||
| Assert.Equal(new uint256(toSkip + toTake - 1), model.ElementAt(0).Hash); | ||
| } | ||
| //[Fact] |
There was a problem hiding this comment.
I'm still busy fixing/porting these.
| AccountHistory accountHistory = accountsHistory.First(); | ||
|
|
||
| List<FlatHistory> items = accountHistory.History.Where(x => x.Address.Address == request.Address).ToList(); | ||
| List<FlatHistory> items = new List<FlatHistory>();// accountHistory.History.ToList();//.Where(x => x.Address.Address == request.Address).ToList(); |
There was a problem hiding this comment.
I'm still busy fixing this.
| } | ||
|
|
||
| [Fact] | ||
| public async Task GetHistoryWithoutAddressesReturnsEmptyModel() |
There was a problem hiding this comment.
All these tests I'm moving to one encompassing integration test as we can't mock results any longer due to us query the DB directly with SQL.
| async (req, token) => this.Json(await this.walletService.Consolidate(req, token))); | ||
| } | ||
|
|
||
| private TransactionItemModel FindSimilarReceivedTransactionOutput(List<TransactionItemModel> items, |
| /// Copies the test wallet into data folder for node if it isn't already present. | ||
| /// </summary> | ||
| /// <param name="path">The path of the folder to move the wallet to.</param> | ||
| private void InitializeTestWallet(string path) |
| } | ||
| } | ||
| } | ||
| //[Fact] |
There was a problem hiding this comment.
Still busy fixing...
|
Hi @quantumagi, I'm keen for this PR to go in as is 😎 as I don't want to bloat it more due to the amount of changes already in it. Do you have any more comments on my replies? I'm pretty confident that the integration test I wrote covers a lot of bases There are still tests commented out but they relate to queries where we search/filter by address, especially in smart contracts. The smart contracts controller's get history method and related tests relies on the address "filter", so after this PR is merged I want to get on to fixing/reimplementing those. What are your thoughts? |
|
@fassadlr , the main issue i can see is spends/receives not ordered correctly by also utilising the spend date. I think if that is fixed and there are no other bigger issues we should be good. |
|
@quantumagi as dicussed, if the CI passes we should merge this, so that I can then look at the address filtering. |
* WIP * Single SQL query * Refactor * WIP * Tests still need to be fixed * Self review * Self review * Fixing tests and review changes * Fix Test * Fix Test * busy with test * WIP * SQL changes based on review * Update WalletHistoryIntegrationTests.cs * Fix test * Fix Tests * Review fixes
* WIP * Single SQL query * Refactor * WIP * Tests still need to be fixed * Self review * Self review * Fixing tests and review changes * Fix Test * Fix Test * busy with test * WIP * SQL changes based on review * Update WalletHistoryIntegrationTests.cs * Fix test * Fix Tests * Review fixes
Tests still need to be fixed.