diff --git a/NBXplorer.Tests/UnitTest1.cs b/NBXplorer.Tests/UnitTest1.cs index ba0bec929..6457d721c 100644 --- a/NBXplorer.Tests/UnitTest1.cs +++ b/NBXplorer.Tests/UnitTest1.cs @@ -4488,7 +4488,7 @@ public async Task CanAssociateIndependentScripts(Backend backend) var parentWallet = Guid.NewGuid().ToString(); var parentWalletTS = new WalletTrackedSource(parentWallet); - +#if SUPPORT_DBTRIE //this should create both wallets if (backend == Backend.DBTrie) { @@ -4507,7 +4507,7 @@ await Assert.ThrowsAsync(async () =>await tester.Client.Gene await Assert.ThrowsAsync(async () =>await tester.Client.ImportUTXOs(parentWalletTS, Array.Empty())); return; } - +#endif await tester.Client.TrackAsync(wallet1TS, new TrackWalletRequest() { ParentWallet = parentWalletTS @@ -4580,6 +4580,32 @@ await Eventually(async () => scriptBagUtxos = await tester.Client.GetUTXOsAsync(wallet1TS); Assert.Equal(2, scriptBagUtxos.GetUnspentUTXOs().Length); }); + + //create wallet A + //create wallet b using generate and make it child of A + // create address using unused on B + // creat wallet C tracking address from B, make it child of A, B + var walletA = new WalletTrackedSource(Guid.NewGuid().ToString()); + await tester.Client.TrackAsync(walletA); + var generatResponse = await tester.Client.GenerateWalletAsync(new GenerateWalletRequest() + { + ParentWallet = walletA + }); + var walletB = TrackedSource.Create(generatResponse.DerivationScheme); + var addressA = await tester.Client.GetUnusedAsync(generatResponse.DerivationScheme, DerivationFeature.Deposit, 0, true); + var walletC = AddressTrackedSource.Create(addressA.Address); + await tester.Client.TrackAsync(walletC, new TrackWalletRequest() + { + ParentWallet = walletB + }); + await tester.Client.TrackAsync(walletC, new TrackWalletRequest() + { + ParentWallet = walletA + }); + + var kpi = await tester.Client.GetKeyInformationsAsync(addressA.ScriptPubKey, CancellationToken.None); + var tss = kpi.Select(information => information.TrackedSource); + Assert.True(tss.Distinct().Count() == tss.Count(), "The result should only distinct tracked source matches. While this endpoint is marked obsolete, the same logic is used to trigger events, which means there will be duplicated events when the script is matched against"); } } } diff --git a/NBXplorer/Controllers/MainController.cs b/NBXplorer/Controllers/MainController.cs index 1ee4cb363..717f792ae 100644 --- a/NBXplorer/Controllers/MainController.cs +++ b/NBXplorer/Controllers/MainController.cs @@ -518,6 +518,11 @@ public async Task TrackWallet( (trackedSourceContext.TrackedSource is WalletTrackedSource || request?.ParentWallet is not null)) { + if (request?.ParentWallet == trackedSourceContext.TrackedSource) + { + throw new NBXplorerException(new NBXplorerError(400, "parent-wallet-same-as-tracked-source", + "Parent wallets cannot be the same as the tracked source")); + } await postgresRepository.EnsureWalletCreated(trackedSourceContext.TrackedSource, request?.ParentWallet is null? null: new []{request?.ParentWallet }); } if (repo is not PostgresRepository && request.ParentWallet is not null)