Skip to content

[Wallet] Fix transaction history#548

Merged
fassadlr merged 18 commits intostratisproject:masterfrom
fassadlr:fix-history
May 13, 2021
Merged

[Wallet] Fix transaction history#548
fassadlr merged 18 commits intostratisproject:masterfrom
fassadlr:fix-history

Conversation

@fassadlr
Copy link
Contributor

@fassadlr fassadlr commented May 5, 2021

Tests still need to be fixed.

/// <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);
Copy link
Contributor

@quantumagi quantumagi May 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Copy link
Contributor

@quantumagi quantumagi May 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

@fassadlr fassadlr May 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We get the wallet name from the account that is passed in's account root. This is called from:

https://github.com/stratisproject/StratisFullNode/pull/548/files#diff-481c41c671b79c78e1987b366a78efdd29721cb50dfff8bffe8881a830da91e3R847

Is this OK?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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));
Copy link
Contributor

@quantumagi quantumagi May 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah this was a mistake on my part. I will fix this.

GROUP BY
t.OutputTxId
ORDER BY
t.OutputTxTime DESC
Copy link
Contributor

@quantumagi quantumagi May 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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? 🤔

Copy link
Contributor

@quantumagi quantumagi May 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still busy fixing this.

}

[Fact]
public async Task GetHistoryWithoutAddressesReturnsEmptyModel()
Copy link
Contributor Author

@fassadlr fassadlr May 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused...

/// 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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused...

}
}
}
//[Fact]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still busy fixing...

@fassadlr
Copy link
Contributor Author

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?

@quantumagi
Copy link
Contributor

@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.

@fassadlr fassadlr changed the title [Wallet] Fix transaction history (WIP) [Wallet] Fix transaction history May 13, 2021
@fassadlr
Copy link
Contributor Author

@quantumagi as dicussed, if the CI passes we should merge this, so that I can then look at the address filtering.

@fassadlr fassadlr merged commit e16c8f0 into stratisproject:master May 13, 2021
@fassadlr fassadlr deleted the fix-history branch May 13, 2021 11:45
fassadlr added a commit that referenced this pull request May 14, 2021
* 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
zeptin pushed a commit to zeptin/StratisFullNode that referenced this pull request Jun 15, 2021
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants