public async Task InconsistentImmatureIndexAsync()
    {
        var(dir, _, immatureFilters) = await GetIndexStorePathsAsync();

        var network      = Network.Main;
        var headersChain = new SmartHeaderChain();

        await using var indexStore = new IndexStore(dir, network, headersChain);

        var dummyFilter    = GolombRiceFilter.Parse("00");
        var startingFilter = StartingFilters.GetStartingFilter(network);

        var immatureIndexStoreContent = new[]
        {
            new FilterModel(new SmartHeader(new uint256(2), startingFilter.Header.BlockHash, startingFilter.Header.Height + 1, MinutesAgo(30)), dummyFilter),
            new FilterModel(new SmartHeader(new uint256(3), new uint256(2), startingFilter.Header.Height + 2, MinutesAgo(20)), dummyFilter),
            new FilterModel(new SmartHeader(new uint256(99), new uint256(98), startingFilter.Header.Height + 98, MinutesAgo(10)), dummyFilter)
        };
        await File.WriteAllLinesAsync(immatureFilters, immatureIndexStoreContent.Select(x => x.ToLine()));

        await Assert.ThrowsAsync <InvalidOperationException>(async() => await indexStore.InitializeAsync());

        Assert.Equal(new uint256(3), headersChain.TipHash);
        Assert.Equal(startingFilter.Header.Height + 2u, headersChain.TipHeight);

        // Check if the immatureIndex is deleted
        Assert.False(File.Exists(immatureFilters));
    }
        protected ClosedWalletViewModel(WalletManagerViewModel walletManagerViewModel, Wallet wallet)
            : base(wallet)
        {
            _smartHeaderChain = Services.BitcoinStore.SmartHeaderChain;

            OpenCommand = ReactiveCommand.Create(() => OnOpen(walletManagerViewModel));
        }
    public async Task GapInIndexAsync()
    {
        var(dir, matureFilters, immatureFilters) = await GetIndexStorePathsAsync();

        var network      = Network.Main;
        var headersChain = new SmartHeaderChain();

        await using var indexStore = new IndexStore(dir, network, headersChain);

        var dummyFilter = GolombRiceFilter.Parse("00");

        var matureIndexStoreContent = new[]
        {
            new FilterModel(new SmartHeader(new uint256(2), new uint256(1), 1, MinutesAgo(30)), dummyFilter),
            new FilterModel(new SmartHeader(new uint256(3), new uint256(2), 2, MinutesAgo(20)), dummyFilter),
        };
        await File.WriteAllLinesAsync(matureFilters, matureIndexStoreContent.Select(x => x.ToLine()));

        var immatureIndexStoreContent = new[]
        {
            new FilterModel(new SmartHeader(new uint256(5), new uint256(4), 4, MinutesAgo(30)), dummyFilter),
            new FilterModel(new SmartHeader(new uint256(6), new uint256(5), 5, MinutesAgo(20)), dummyFilter),
        };
        await File.WriteAllLinesAsync(immatureFilters, immatureIndexStoreContent.Select(x => x.ToLine()));

        await Assert.ThrowsAsync <InvalidOperationException>(async() => await indexStore.InitializeAsync());

        Assert.Equal(new uint256(3), headersChain.TipHash);
        Assert.Equal(2u, headersChain.TipHeight);

        Assert.True(File.Exists(matureFilters));            // mature filters are ok
        Assert.False(File.Exists(immatureFilters));         // immature filters are NOT ok
    }
        public async Task InitializeAsync(string workFolderPath, Network network)
        {
            using (BenchmarkLogger.Measure())
            {
                WorkFolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(workFolderPath), workFolderPath, trim: true);
                IoHelpers.EnsureDirectoryExists(WorkFolderPath);

                Network = Guard.NotNull(nameof(network), network);

                IndexStore       = new IndexStore();
                TransactionStore = new AllTransactionStore();
                var networkWorkFolderPath = Path.Combine(WorkFolderPath, Network.ToString());
                var indexStoreFolderPath  = Path.Combine(networkWorkFolderPath, "IndexStore");
                SmartHeaderChain = new SmartHeaderChain();
                MempoolService   = new MempoolService();

                var initTasks = new[]
                {
                    IndexStore.InitializeAsync(indexStoreFolderPath, Network, SmartHeaderChain),
                    TransactionStore.InitializeAsync(networkWorkFolderPath, Network)
                };

                await Task.WhenAll(initTasks).ConfigureAwait(false);

                IsInitialized = true;
            }
        }
Beispiel #5
0
 private static void AssertEverythingDefault(SmartHeaderChain hashChain)
 {
     Assert.Equal(0, hashChain.HashCount);
     Assert.Equal(0, hashChain.HashesLeft);
     Assert.Equal(0u, hashChain.ServerTipHeight);
     Assert.Null(hashChain.TipHash);
     Assert.Equal(0u, hashChain.TipHeight);
 }
        public IndexStore(string workFolderPath, Network network, SmartHeaderChain hashChain)
        {
            WorkFolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(workFolderPath), workFolderPath, trim: true);
            IoHelpers.EnsureDirectoryExists(WorkFolderPath);

            Network          = Guard.NotNull(nameof(network), network);
            SmartHeaderChain = Guard.NotNull(nameof(hashChain), hashChain);
        }
Beispiel #7
0
        public async Task InconsistentMatureIndexAsync()
        {
            var(dir, matureFilters, _) = await GetIndexStorePathsAsync();

            var network      = Network.Main;
            var headersChain = new SmartHeaderChain();

            var indexStore  = new IndexStore(dir, network, headersChain);
            var dummyFilter = GolombRiceFilter.Parse("00");
Beispiel #8
0
    public IndexStore(string workFolderPath, Network network, SmartHeaderChain smartHeaderChain)
    {
        WorkFolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(workFolderPath), workFolderPath, trim: true);
        IoHelpers.EnsureDirectoryExists(WorkFolderPath);
        var indexFilePath = Path.Combine(WorkFolderPath, "MatureIndex.dat");

        MatureIndexFileManager = new DigestableSafeIoManager(indexFilePath, useLastCharacterDigest: true);
        var immatureIndexFilePath = Path.Combine(WorkFolderPath, "ImmatureIndex.dat");

        ImmatureIndexFileManager = new DigestableSafeIoManager(immatureIndexFilePath, useLastCharacterDigest: true);

        Network          = network;
        StartingFilter   = StartingFilters.GetStartingFilter(Network);
        SmartHeaderChain = smartHeaderChain;
    }
        private volatile bool _disposedValue = false;         // To detect redundant calls

        public StatusBarViewModel(string dataDir, Network network, Config config, HostedServices hostedServices, SmartHeaderChain smartHeaderChain, WasabiSynchronizer synchronizer, LegalDocuments?legalDocuments)
        {
            DataDir          = dataDir;
            Network          = network;
            Config           = config;
            HostedServices   = hostedServices;
            SmartHeaderChain = smartHeaderChain;
            Synchronizer     = synchronizer;
            LegalDocuments   = legalDocuments;
            Backend          = BackendStatus.NotConnected;
            UseTor           = false;
            Tor            = TorStatus.NotRunning;
            Peers          = 0;
            BtcPrice       = "$0";
            ActiveStatuses = new StatusSet();
        }
        private volatile bool _disposedValue = false;         // To detect redundant calls

        public StatusBarViewModel(string dataDir, Network network, Config config, HostedServices hostedServices, SmartHeaderChain smartHeaderChain, WasabiSynchronizer synchronizer)
        {
            DataDir          = dataDir;
            Network          = network;
            Config           = config;
            HostedServices   = hostedServices;
            SmartHeaderChain = smartHeaderChain;
            Synchronizer     = synchronizer;
            Backend          = BackendStatus.NotConnected;
            UseTor           = false;
            Tor                     = TorStatus.NotRunning;
            Peers                   = 0;
            _exchangeRate           = "";
            IsExchangeRateAvailable = false;
            ActiveStatuses          = new StatusSet();
        }
Beispiel #11
0
    public IndexStore(string workFolderPath, Network network, SmartHeaderChain hashChain)
    {
        WorkFolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(workFolderPath), workFolderPath, trim: true);
        IoHelpers.EnsureDirectoryExists(WorkFolderPath);
        var indexFilePath = Path.Combine(WorkFolderPath, "MatureIndex.dat");

        MatureIndexFileManager = new DigestableSafeIoManager(indexFilePath, digestRandomIndex: -1);
        var immatureIndexFilePath = Path.Combine(WorkFolderPath, "ImmatureIndex.dat");

        ImmatureIndexFileManager = new DigestableSafeIoManager(immatureIndexFilePath, digestRandomIndex: -1);

        Network = Guard.NotNull(nameof(network), network);

        StartingFilter = StartingFilters.GetStartingFilter(Network);

        SmartHeaderChain = Guard.NotNull(nameof(hashChain), hashChain);
    }
Beispiel #12
0
        private bool TryProcessFilter(FilterModel filter, bool enqueue)
        {
            try
            {
                SmartHeaderChain.AddOrReplace(filter.Header);
                if (enqueue)
                {
                    ImmatureFilters.Add(filter);
                }

                return(true);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                return(false);
            }
        }
    public async Task ReceiveNonMatchingFilterAsync()
    {
        var(dir, matureFilters, immatureFilters) = await GetIndexStorePathsAsync();

        var network      = Network.Main;
        var headersChain = new SmartHeaderChain();

        await using var indexStore = new IndexStore(dir, network, headersChain);

        var dummyFilter = GolombRiceFilter.Parse("00");

        var matureIndexStoreContent = new[]
        {
            new FilterModel(new SmartHeader(new uint256(2), new uint256(1), 1, MinutesAgo(30)), dummyFilter),
            new FilterModel(new SmartHeader(new uint256(3), new uint256(2), 2, MinutesAgo(20)), dummyFilter),
        };
        await File.WriteAllLinesAsync(matureFilters, matureIndexStoreContent.Select(x => x.ToLine()));

        await indexStore.InitializeAsync();

        Assert.Equal(new uint256(3), headersChain.TipHash);
        Assert.Equal(2u, headersChain.TipHeight);

        Assert.True(File.Exists(matureFilters));         // mature filters are ok

        var nonMatchingBlockHashFilter = new FilterModel(new SmartHeader(new uint256(2), new uint256(1), 1, MinutesAgo(30)), dummyFilter);
        await indexStore.AddNewFiltersAsync(new[] { nonMatchingBlockHashFilter }, CancellationToken.None);

        Assert.Equal(new uint256(3), headersChain.TipHash);         // the filter is not added!
        Assert.Equal(2u, headersChain.TipHeight);

        var nonMatchingHeightFilter = new FilterModel(new SmartHeader(new uint256(4), new uint256(3), 37, MinutesAgo(1)), dummyFilter);
        await indexStore.AddNewFiltersAsync(new[] { nonMatchingHeightFilter }, CancellationToken.None);

        Assert.Equal(new uint256(3), headersChain.TipHash);         // the filter is not added!
        Assert.Equal(2u, headersChain.TipHeight);

        var correctFilter = new FilterModel(new SmartHeader(new uint256(4), new uint256(3), 3, MinutesAgo(1)), dummyFilter);
        await indexStore.AddNewFiltersAsync(new[] { correctFilter }, CancellationToken.None);

        Assert.Equal(new uint256(4), headersChain.TipHash);         // the filter is not added!
        Assert.Equal(3u, headersChain.TipHeight);
    }
Beispiel #14
0
        public async Task InitializeAsync(string workFolderPath, Network network, SmartHeaderChain hashChain)
        {
            using (BenchmarkLogger.Measure())
            {
                WorkFolderPath   = Guard.NotNullOrEmptyOrWhitespace(nameof(workFolderPath), workFolderPath, trim: true);
                Network          = Guard.NotNull(nameof(network), network);
                SmartHeaderChain = Guard.NotNull(nameof(hashChain), hashChain);
                var indexFilePath = Path.Combine(WorkFolderPath, "MatureIndex.dat");
                MatureIndexFileManager = new DigestableSafeMutexIoManager(indexFilePath, digestRandomIndex: -1);
                var immatureIndexFilePath = Path.Combine(WorkFolderPath, "ImmatureIndex.dat");
                ImmatureIndexFileManager = new DigestableSafeMutexIoManager(immatureIndexFilePath, digestRandomIndex: -1);

                StartingFilter = StartingFilters.GetStartingFilter(Network);
                StartingHeight = StartingFilter.Header.Height;

                ImmatureFilters = new List <FilterModel>(150);

                IndexLock = new AsyncLock();

                using (await IndexLock.LockAsync().ConfigureAwait(false))
                    using (await MatureIndexFileManager.Mutex.LockAsync().ConfigureAwait(false))
                        using (await ImmatureIndexFileManager.Mutex.LockAsync().ConfigureAwait(false))
                        {
                            IoHelpers.EnsureDirectoryExists(WorkFolderPath);

                            await EnsureBackwardsCompatibilityAsync().ConfigureAwait(false);

                            if (Network == Network.RegTest)
                            {
                                MatureIndexFileManager.DeleteMe();                 // RegTest is not a global ledger, better to delete it.
                                ImmatureIndexFileManager.DeleteMe();
                            }

                            if (!MatureIndexFileManager.Exists())
                            {
                                await MatureIndexFileManager.WriteAllLinesAsync(new[] { StartingFilter.ToLine() }).ConfigureAwait(false);
                            }

                            await InitializeFiltersAsync().ConfigureAwait(false);
                        }
            }
        }
Beispiel #15
0
    public async Task <FilterModel> RemoveLastFilterAsync(CancellationToken cancel)
    {
        FilterModel?filter = null;

        using (await IndexLock.LockAsync(cancel).ConfigureAwait(false))
        {
            filter = ImmatureFilters.Last();
            ImmatureFilters.RemoveLast();
            if (SmartHeaderChain.TipHeight != filter.Header.Height)
            {
                throw new InvalidOperationException($"{nameof(SmartHeaderChain)} and {nameof(ImmatureFilters)} are not in sync.");
            }
            SmartHeaderChain.RemoveTip();
        }

        Reorged?.Invoke(this, filter);

        AbandonedTasks.AddAndClearCompleted(TryCommitToFileAsync(TimeSpan.FromSeconds(3), cancel));

        return(filter);
    }
Beispiel #16
0
    private bool TryProcessFilter(FilterModel filter, bool enqueue)
    {
        try
        {
            if (IsWrongFilter(filter))
            {
                return(false);
            }

            SmartHeaderChain.AppendTip(filter.Header);
            if (enqueue)
            {
                ImmatureFilters.Add(filter);
            }

            return(true);
        }
        catch (Exception ex)
        {
            Logger.LogError(ex);
            return(false);
        }
    }
Beispiel #17
0
        public void GeneralHashChainTests()
        {
            var hashChain = new SmartHeaderChain();

            // ASSERT PROPERTIES

            // Assert everything is default value.
            AssertEverythingDefault(hashChain);

            // ASSERT EVENTS

            // Assert some functions do not raise any events when default.
            Assert.Throws <PropertyChangedException>(() =>
                                                     Assert.PropertyChanged(hashChain,
                                                                            nameof(hashChain.HashCount),
                                                                            () =>
            {
                // ASSERT FUNCTIONS
                // Assert RemoveLast does not modify nor throw anything when nothing is added.
                hashChain.RemoveLast();
                AssertEverythingDefault(hashChain);
            }));
            Assert.Throws <PropertyChangedException>(() =>
                                                     Assert.PropertyChanged(hashChain,
                                                                            nameof(hashChain.HashesLeft),
                                                                            () =>
            {
                // ASSERT FUNCTIONS
                // Assert RemoveLast does not modify nor throw anything when nothing is added.
                hashChain.RemoveLast();
                AssertEverythingDefault(hashChain);
            }));
            Assert.Throws <PropertyChangedException>(() =>
                                                     Assert.PropertyChanged(hashChain,
                                                                            nameof(hashChain.ServerTipHeight),
                                                                            () =>
            {
                // ASSERT FUNCTIONS
                // Assert RemoveLast does not modify nor throw anything when nothing is added.
                hashChain.RemoveLast();
                AssertEverythingDefault(hashChain);
            }));
            Assert.Throws <PropertyChangedException>(() =>
                                                     Assert.PropertyChanged(hashChain,
                                                                            nameof(hashChain.TipHash),
                                                                            () =>
            {
                // ASSERT FUNCTIONS
                // Assert RemoveLast does not modify nor throw anything when nothing is added.
                hashChain.RemoveLast();
                AssertEverythingDefault(hashChain);
            }));
            Assert.Throws <PropertyChangedException>(() =>
                                                     Assert.PropertyChanged(hashChain,
                                                                            nameof(hashChain.TipHeight),
                                                                            () =>
            {
                // ASSERT FUNCTIONS
                // Assert RemoveLast does not modify nor throw anything when nothing is added.
                hashChain.RemoveLast();
                AssertEverythingDefault(hashChain);
            }));

            // Assert the correct events are thrown and not thrown when applicable.
            var newServerHeight = hashChain.ServerTipHeight + 1;

            Assert.PropertyChanged(hashChain,
                                   nameof(hashChain.ServerTipHeight),
                                   // ASSERT FUNCTION
                                   // Assert update server height raises.
                                   () => hashChain.UpdateServerTipHeight(newServerHeight));
            newServerHeight++;
            Assert.PropertyChanged(hashChain,
                                   nameof(hashChain.HashesLeft),
                                   // ASSERT FUNCTION
                                   // Assert update server height raises.
                                   () => hashChain.UpdateServerTipHeight(newServerHeight));

            newServerHeight++;
            Assert.Throws <PropertyChangedException>(() =>
                                                     Assert.PropertyChanged(hashChain,
                                                                            nameof(hashChain.HashCount),
                                                                            // ASSERT FUNCTIONS
                                                                            // Assert update server height does not raise unnecessary events.
                                                                            () => hashChain.UpdateServerTipHeight(newServerHeight)));
            newServerHeight++;
            Assert.Throws <PropertyChangedException>(() =>
                                                     Assert.PropertyChanged(hashChain,
                                                                            nameof(hashChain.TipHash),
                                                                            // ASSERT FUNCTIONS
                                                                            // Assert update server height does not raise unnecessary events.
                                                                            () => hashChain.UpdateServerTipHeight(newServerHeight)));
            newServerHeight++;
            Assert.Throws <PropertyChangedException>(() =>
                                                     Assert.PropertyChanged(hashChain,
                                                                            nameof(hashChain.TipHeight),
                                                                            // ASSERT FUNCTIONS
                                                                            // Assert update server height does not raise unnecessary events.
                                                                            () => hashChain.UpdateServerTipHeight(newServerHeight)));
            var sameServerheight = newServerHeight;

            Assert.Throws <PropertyChangedException>(() =>
                                                     Assert.PropertyChanged(hashChain,
                                                                            nameof(hashChain.ServerTipHeight),
                                                                            // ASSERT FUNCTIONS
                                                                            // Assert update server height does not raise without actually changing.
                                                                            () => hashChain.UpdateServerTipHeight(sameServerheight)));
            Assert.Throws <PropertyChangedException>(() =>
                                                     Assert.PropertyChanged(hashChain,
                                                                            nameof(hashChain.HashesLeft),
                                                                            // ASSERT FUNCTIONS
                                                                            // Assert update server height does not raise without actually changing.
                                                                            () => hashChain.UpdateServerTipHeight(sameServerheight)));

            // ASSERT PROPERTIES
            Assert.Equal(0, hashChain.HashCount);
            var hashesLeft = sameServerheight;

            Assert.Equal((int)hashesLeft, hashChain.HashesLeft);
            Assert.Equal(hashesLeft, hashChain.ServerTipHeight);
            Assert.Null(hashChain.TipHash);
            Assert.Equal(0u, hashChain.TipHeight);
        }
Beispiel #18
0
 public IndexStore(Network network, SmartHeaderChain hashChain)
 {
     Network          = Guard.NotNull(nameof(network), network);
     SmartHeaderChain = Guard.NotNull(nameof(hashChain), hashChain);
 }