Skip to content
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

Filter Transaction History by Transaction Id #393

Merged
merged 4 commits into from
Jan 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ public void GetHistoryWithValidModelWithoutTransactionSpendingDetailsReturnsWall
List<FlatHistory> flat = addresses.SelectMany(s => s.Transactions.Select(t => new FlatHistory { Address = s, Transaction = t })).ToList();

var accountsHistory = new List<AccountHistory> { new AccountHistory { History = flat, Account = account } };
this.walletManager.Setup(w => w.GetHistory(walletName, It.IsAny<string>())).Returns(accountsHistory);
this.walletManager.Setup(w => w.GetHistory(walletName, It.IsAny<string>(), null)).Returns(accountsHistory);
this.walletManager.Setup(w => w.GetWallet(walletName)).Returns(wallet);
this.walletManager.Setup(w => w.GetAccounts(walletName)).Returns(new List<HdAccount> { account });

var receipt = new Receipt(null, 12345, new Log[0], null, null, null, uint160.Zero, true, null, null, 2, 100000);
this.receiptRepository.Setup(x => x.RetrieveMany(It.IsAny<IList<uint256>>()))
.Returns(new List<Receipt> {receipt});
.Returns(new List<Receipt> { receipt });
this.callDataSerializer.Setup(x => x.Deserialize(It.IsAny<byte[]>()))
.Returns(Result.Ok(new ContractTxData(0, 0, (Stratis.SmartContracts.RuntimeObserver.Gas)0, new uint160(0), null, null)));

Expand Down Expand Up @@ -151,12 +151,12 @@ public void GetHistoryWithValidModelWithSkipAndTakeReturnsWalletHistoryModel()

for (int i = 0; i < totalHistoryLength; i++)
{
TransactionData createTransaction = WalletTestsHelpers.CreateTransaction(new uint256((ulong) i), new Money(500000), 100 + i);
TransactionData createTransaction = WalletTestsHelpers.CreateTransaction(new uint256((ulong)i), new Money(500000), 100 + i);
createTransaction.SpendingDetails = new SpendingDetails
{
BlockHeight = 100 + i,
CreationTime = DateTimeOffset.Now,
TransactionId = new uint256((ulong) i),
TransactionId = new uint256((ulong)i),
Payments = new List<PaymentDetails>
{
new PaymentDetails
Expand All @@ -180,7 +180,7 @@ public void GetHistoryWithValidModelWithSkipAndTakeReturnsWalletHistoryModel()
List<FlatHistory> flat = addresses.SelectMany(s => s.Transactions.Select(t => new FlatHistory { Address = s, Transaction = t })).ToList();

var accountsHistory = new List<AccountHistory> { new AccountHistory { History = flat, Account = account } };
this.walletManager.Setup(w => w.GetHistory(walletName, It.IsAny<string>())).Returns(accountsHistory);
this.walletManager.Setup(w => w.GetHistory(walletName, It.IsAny<string>(), null)).Returns(accountsHistory);
this.walletManager.Setup(w => w.GetWallet(walletName)).Returns(wallet);
this.walletManager.Setup(w => w.GetAccounts(walletName)).Returns(new List<HdAccount> { account });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public IActionResult GetHistory(GetHistoryRequest request)
HdAccount account = this.walletManager.GetAccounts(request.WalletName).First();

// Get a list of all the transactions found in an account (or in a wallet if no account is specified), with the addresses associated with them.
IEnumerable<AccountHistory> accountsHistory = this.walletManager.GetHistory(request.WalletName, account.Name);
IEnumerable<AccountHistory> accountsHistory = this.walletManager.GetHistory(request.WalletName, account.Name, null);

// Wallet manager returns only 1 when an account name is specified.
AccountHistory accountHistory = accountsHistory.First();
Expand Down
20 changes: 10 additions & 10 deletions src/Stratis.Bitcoin.Features.Wallet.Tests/WalletControllerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,8 @@ public async Task RecoverWalletWithFileNotFoundExceptionReturnsNotFound()
[Fact]
public async Task RecoverWalletWithExceptionReturnsBadRequest()
{
var mockWalletManager = this.ConfigureMock<IWalletManager>(mock => {
var mockWalletManager = this.ConfigureMock<IWalletManager>(mock =>
{
mock.Setup(w => w.RecoverWallet(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<DateTime>(), null, null))
.Throws(new FormatException("Formatting failed."));
Expand Down Expand Up @@ -768,7 +769,7 @@ public async Task GetHistoryWithoutAddressesReturnsEmptyModel()
{
string walletName = "myWallet";
var mockWalletManager = this.ConfigureMock<IWalletManager>(mock =>
mock.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount)).Returns(
mock.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount, null)).Returns(
new List<AccountHistory>
{
new AccountHistory
Expand Down Expand Up @@ -815,7 +816,7 @@ public async Task GetHistoryWithValidModelWithoutTransactionSpendingDetailsRetur

var accountsHistory = new List<AccountHistory> { new AccountHistory { History = flat, Account = account } };
var mockWalletManager = this.ConfigureMock<IWalletManager>(mock =>
mock.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount))
mock.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount, null))
.Returns(accountsHistory));
mockWalletManager.Setup(w => w.GetWallet(walletName)).Returns(wallet);

Expand Down Expand Up @@ -891,7 +892,7 @@ public async Task GetHistoryWithCoinStakeWithMultipleInputs()
var accountsHistory = new List<AccountHistory> { new AccountHistory { History = flat, Account = account } };
var mockWalletManager = this.ConfigureMock<IWalletManager>();

mockWalletManager.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount))
mockWalletManager.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount, null))
.Returns(accountsHistory);
mockWalletManager.Setup(w => w.GetWallet(walletName)).Returns(wallet);

Expand Down Expand Up @@ -957,7 +958,7 @@ public async Task GetHistoryWithValidModelWithTransactionSpendingDetailsReturnsW
var accountsHistory = new List<AccountHistory> { new AccountHistory { History = flat, Account = account } };

var mockWalletManager = this.ConfigureMock<IWalletManager>(mock =>
mock.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount))
mock.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount, null))
.Returns(accountsHistory));
mockWalletManager.Setup(w => w.GetWallet(walletName)).Returns(wallet);

Expand Down Expand Up @@ -1037,7 +1038,7 @@ public async Task GetHistoryWithValidModelWithFeeBelowZeroSetsFeeToZero()
var accountsHistory = new List<AccountHistory> { new AccountHistory { History = flat, Account = account } };

var mockWalletManager = this.ConfigureMock<IWalletManager>(mock =>
mock.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount))
mock.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount, null))
.Returns(accountsHistory));
mockWalletManager.Setup(w => w.GetWallet(walletName)).Returns(wallet);

Expand Down Expand Up @@ -1140,7 +1141,7 @@ public async Task GetHistoryWithDuplicateSpentTransactionsSelectsDistinctsSpentT

var mockWalletManager = this.ConfigureMock<IWalletManager>(mock =>
mock.Setup(w => w.GetWallet(walletName)).Returns(wallet));
mockWalletManager.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount))
mockWalletManager.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount, null))
.Returns(accountsHistory);

var controller = this.GetWalletController();
Expand Down Expand Up @@ -1177,7 +1178,7 @@ public async Task GetHistoryWithExceptionReturnsBadRequest()
{
string walletName = "myWallet";
var mockWalletManager = this.ConfigureMock<IWalletManager>(mock =>
mock.Setup(w => w.GetHistory("myWallet", WalletManager.DefaultAccount))
mock.Setup(w => w.GetHistory("myWallet", WalletManager.DefaultAccount, null))
.Throws(new InvalidOperationException("Issue retrieving wallets.")));
mockWalletManager.Setup(w => w.GetWallet(walletName)).Returns(new Wallet());

Expand Down Expand Up @@ -1254,8 +1255,7 @@ public async Task GetHistoryWithChangeAddressesShouldIncludeSpentChangeAddesses(
var mockWalletManager = this.ConfigureMock<IWalletManager>();

var accountsHistory = new List<AccountHistory> { new AccountHistory { History = flat, Account = account } };
mockWalletManager.Setup(w =>
w.GetHistory(walletName, WalletManager.DefaultAccount)).Returns(accountsHistory);
mockWalletManager.Setup(w => w.GetHistory(walletName, WalletManager.DefaultAccount, null)).Returns(accountsHistory);
mockWalletManager.Setup(w => w.GetWallet(walletName)).Returns(wallet);

var controller = this.GetWalletController();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public interface IWalletManager
/// <param name="extPubKey">The extended public key.</param>
/// <param name="accountIndex">The account number.</param>
/// <param name="creationTime">The date and time this wallet was created.</param>
/// <returns></returns>
/// <returns>The recovered wallet.</returns>
Wallet RecoverWallet(string name, ExtPubKey extPubKey, int accountIndex, DateTime creationTime, ChainedHeader lastBlockSynced = null);

/// <summary>
Expand Down Expand Up @@ -244,8 +244,9 @@ public interface IWalletManager
/// </summary>
/// <param name="walletName">The wallet name.</param>
/// <param name="accountName">The account name.</param>
/// <param name="searchQuery">For now this can only be a transaction Id.</param>
/// <returns>Collection of address history and transaction pairs.</returns>
IEnumerable<AccountHistory> GetHistory(string walletName, string accountName = null);
IEnumerable<AccountHistory> GetHistory(string walletName, string accountName = null, string searchQuery = null);

/// <summary>
/// Gets the history of transactions contained in an account.
Expand All @@ -256,8 +257,9 @@ public interface IWalletManager
/// <param name="prevOutputTxTime">Previous OutputTxTime, used for pagination</param>
/// <param name="prevOutputIndex">Previous prevOutputIndex, used for pagination</param>
/// <param name="take">Number of records to Take</param>
/// <param name="searchQuery">For now this can only be a transaction Id.</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);
IEnumerable<AccountHistory> GetHistory(string walletName, string accountName = null, long? prevOutputTxTime = null, int? prevOutputIndex = null, int? take = int.MaxValue, string searchQuery = null);

/// <summary>
/// Gets the history of the transactions in addresses contained in this account.
Expand Down
11 changes: 4 additions & 7 deletions src/Stratis.Bitcoin.Features.Wallet/Services/WalletService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,18 +186,16 @@ public async Task<WalletBalanceModel> GetBalance(
}, cancellationToken);
}

public async Task<WalletHistoryModel> GetHistory(WalletHistoryRequest request,
CancellationToken cancellationToken)
public async Task<WalletHistoryModel> GetHistory(WalletHistoryRequest request, CancellationToken cancellationToken)
{
return await Task.Run(() =>
{
var model = new WalletHistoryModel();

// Get a list of all the transactions found in an account (or in a wallet if no account is specified), with the addresses associated with them.
IEnumerable<AccountHistory> accountsHistory = request.Take == null
? this.walletManager.GetHistory(request.WalletName, request.AccountName)
: this.walletManager.GetHistory(request.WalletName, request.AccountName, request.PrevOutputTxTime,
request.PrevOutputIndex, request.Take);
? this.walletManager.GetHistory(request.WalletName, request.AccountName, request.SearchQuery)
: this.walletManager.GetHistory(request.WalletName, request.AccountName, request.PrevOutputTxTime, request.PrevOutputIndex, request.Take);

foreach (AccountHistory accountHistory in accountsHistory)
{
Expand Down Expand Up @@ -230,8 +228,7 @@ public async Task<WalletHistoryModel> GetHistory(WalletHistoryRequest request,

// Represents a sublist of transactions associated with receive addresses + a sublist of already spent transactions associated with change addresses.
// In effect, we filter out 'change' transactions that are not spent, as we don't want to show these in the history.
foreach (FlatHistory item in items.Where(t =>
!t.Address.IsChangeAddress() || (t.Address.IsChangeAddress() && t.Transaction.IsSpent())))
foreach (FlatHistory item in items.Where(t => !t.Address.IsChangeAddress() || (t.Address.IsChangeAddress() && t.Transaction.IsSpent())))
{
// Count only unique transactions and limit it to MaxHistoryItemsPerAccount.
int processedTransactions = uniqueProcessedTxIds.Count;
Expand Down
23 changes: 13 additions & 10 deletions src/Stratis.Bitcoin.Features.Wallet/WalletManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -870,13 +870,13 @@ public IEnumerable<HdAddress> GetNewAddresses(WalletAccountReference accountRefe
return this.WalletRepository.GetUsedAddresses(accountReference, isChange);
}

public IEnumerable<AccountHistory> GetHistory(string walletName, string accountName = null)
public IEnumerable<AccountHistory> GetHistory(string walletName, string accountName = null, string searchQuery = null)
{
return this.GetHistory(walletName, accountName, null, null, int.MaxValue);
return this.GetHistory(walletName, accountName, null, null, int.MaxValue, searchQuery);
}

/// <inheritdoc />
public IEnumerable<AccountHistory> GetHistory(string walletName, string accountName, long? prevOutputTxTime, int? prevOutputIndex, int? take = int.MaxValue)
public IEnumerable<AccountHistory> GetHistory(string walletName, string accountName, long? prevOutputTxTime, int? prevOutputIndex, int? take = int.MaxValue, string searchQuery = null)
{
Guard.NotEmpty(walletName, nameof(walletName));

Expand All @@ -903,7 +903,7 @@ public IEnumerable<AccountHistory> GetHistory(string walletName, string accountN

foreach (HdAccount account in accounts)
{
accountsHistory.Add(this.GetHistoryForAccount(account, prevOutputTxTime, prevOutputIndex, take.GetValueOrDefault()));
accountsHistory.Add(this.GetHistoryForAccount(account, prevOutputTxTime, prevOutputIndex, take.GetValueOrDefault(), searchQuery));
}
}

Expand All @@ -915,8 +915,8 @@ public AccountHistory GetHistory(HdAccount account)
{
return this.GetHistoryForAccount(account, null, null, int.MaxValue);
}
protected AccountHistory GetHistoryForAccount(HdAccount account, long? prevOutputTxTime = null, int? prevOutputIndex = null, int take = int.MaxValue)

protected AccountHistory GetHistoryForAccount(HdAccount account, long? prevOutputTxTime = null, int? prevOutputIndex = null, int take = int.MaxValue, string searchQuery = null)
{
Guard.NotNull(account, nameof(account));
FlatHistory[] items;
Expand All @@ -926,10 +926,13 @@ protected AccountHistory GetHistoryForAccount(HdAccount account, long? prevOutpu
// Get transactions contained in the account.
var query = account.GetCombinedAddresses().Where(a => a.Transactions.Any());

// When the account is a normal one, we want to filter out all cold stake UTXOs.
if (account.IsNormalAccount())
{
// When the account is a normal one, we want to filter out all cold stake UTXOs.
items = query.SelectMany(s => s.Transactions.Where(t => t.IsColdCoinStake == null || t.IsColdCoinStake == false).Select(t => new FlatHistory { Address = s, Transaction = t })).ToArray();
if (searchQuery != null && uint256.TryParse(searchQuery, out uint256 parsedTxId))
items = query.SelectMany(s => s.Transactions.Where(t => (t.IsColdCoinStake == null || t.IsColdCoinStake == false) && t.Id == parsedTxId).Select(t => new FlatHistory { Address = s, Transaction = t })).ToArray();
else
items = query.SelectMany(s => s.Transactions.Where(t => t.IsColdCoinStake == null || t.IsColdCoinStake == false).Select(t => new FlatHistory { Address = s, Transaction = t })).ToArray();
}
else
{
Expand Down Expand Up @@ -1207,7 +1210,7 @@ public void ProcessBlocks(Func<ChainedHeader, IEnumerable<(ChainedHeader, Block)

if (this.WalletRepository.RewindWallet(walletName, fork).RewindExecuted)
this.logger.LogDebug("Rewound wallet, {0}='{1}', {2}='{3}'", nameof(fork), fork, nameof(this.ChainIndexer.Tip), this.ChainIndexer.Tip?.HashBlock);

// Update the lowest common tip.
walletTip = (fork == null) ? null : walletTip?.FindFork(fork);
}
Expand Down