Create SmartHeader
MODIFY
WalletWasabi.Tests/IntegrationTests/LiveServerTests.cs
WalletWasabi.Tests/IntegrationTests/LiveServerTests.cs
@@ -4,9 +4,9 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using WalletWasabi.Backend.Models.Responses;
+using WalletWasabi.Blockchain.BlockFilters;
using WalletWasabi.CoinJoin.Client.Clients;
using WalletWasabi.Services;
-using WalletWasabi.Stores;
using WalletWasabi.Tests.XunitConfiguration;
using WalletWasabi.TorSocks5;
using WalletWasabi.WebClients.Wasabi;

ADD
WalletWasabi.Tests/UnitTests/SmartHeaderTests.cs
+using NBitcoin;
+using NBitcoin.DataEncoders;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using WalletWasabi.Blockchain;
+using WalletWasabi.Blockchain.Blocks;
+using Xunit;
+
+namespace WalletWasabi.Tests.UnitTests
+{
+ public class SmartHeaderTests
+ {
+ // TODO
+ // equality
+ // comparision
+ // line serialization
+ // need mempool too
+ [Fact]
+ public void ConstructorTests()
+ {
+ var blockTime = DateTimeOffset.UtcNow;
+ new SmartHeader(uint256.Zero, uint256.One, 0, blockTime);
+ new SmartHeader(uint256.Zero, uint256.One, 1, blockTime);
+ new SmartHeader(uint256.Zero, uint256.One, 1, blockTime);
+
+ Assert.Throws<ArgumentNullException>(() => new SmartHeader(null, uint256.One, 1, blockTime));
+ Assert.Throws<ArgumentNullException>(() => new SmartHeader(uint256.Zero, null, 1, blockTime));
+ Assert.Throws<InvalidOperationException>(() => new SmartHeader(uint256.Zero, uint256.Zero, 1, blockTime));
+ }
+
+ [Fact]
+ public void StartingHeaderTests()
+ {
+ var startingMain = SmartHeader.GetStartingHeader(Network.Main);
+ var startingTest = SmartHeader.GetStartingHeader(Network.TestNet);
+ var startingReg = SmartHeader.GetStartingHeader(Network.RegTest);
+
+ var expectedHashMain = new uint256("0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893");
+ var expectedPrevHashMain = new uint256("000000000000000000cbeff0b533f8e1189cf09dfbebf57a8ebe349362811b80");
+ uint expectedHeightMain = 481824;
+ var expectedTimeMain = DateTimeOffset.FromUnixTimeSeconds(1503539857);
+
+ var expectedHashTest = new uint256("00000000000f0d5edcaeba823db17f366be49a80d91d15b77747c2e017b8c20a");
+ var expectedPrevHashTest = new uint256("0000000000211a4d54bceb763ea690a4171a734c48d36f7d8e30b51d6df6ea85");
+ uint expectedHeightTest = 828575;
+ var expectedTimeTest = DateTimeOffset.FromUnixTimeSeconds(1463079943);
+
+ var expectedHashReg = Network.RegTest.GenesisHash;
+ var expectedPrevHashReg = uint256.Zero;
+ uint expectedHeightReg = 0;
+ var expectedTimeReg = Network.RegTest.GetGenesis().Header.BlockTime;
+
+ Assert.Equal(expectedHashMain, startingMain.BlockHash);
+ Assert.Equal(expectedPrevHashMain, startingMain.PrevHash);
+ Assert.Equal(expectedHeightMain, startingMain.Height);
+ Assert.Equal(expectedTimeMain, startingMain.BlockTime);
+
+ Assert.Equal(expectedHashTest, startingTest.BlockHash);
+ Assert.Equal(expectedPrevHashTest, startingTest.PrevHash);
+ Assert.Equal(expectedHeightTest, startingTest.Height);
+ Assert.Equal(expectedTimeTest, startingTest.BlockTime);
+
+ Assert.Equal(expectedHashReg, startingReg.BlockHash);
+ Assert.Equal(expectedPrevHashReg, startingReg.PrevHash);
+ Assert.Equal(expectedHeightReg, startingReg.Height);
+ Assert.Equal(expectedTimeReg, startingReg.BlockTime);
+ }
+ }
+}

RENAME
WalletWasabi/Stores/StartingFilters.cs
WalletWasabi/Blockchain/BlockFilters/StartingFilters.cs
@@ -3,10 +3,11 @@ using System;
using System.Collections.Generic;
using System.Text;
using WalletWasabi.Backend.Models;
+using WalletWasabi.Blockchain.Blocks;
using WalletWasabi.Exceptions;
using WalletWasabi.Models;
-namespace WalletWasabi.Stores
+namespace WalletWasabi.Blockchain.BlockFilters
{
public static class StartingFilters
{
@@ -30,24 +31,7 @@ namespace WalletWasabi.Stores
}
}
- public static Height GetStartingHeight(Network network) // First possible bech32 transaction ever.
- {
- if (network == Network.Main)
- {
- return new Height(481824);
- }
- else if (network == Network.TestNet)
- {
- return new Height(828575);
- }
- else if (network == Network.RegTest)
- {
- return new Height(0);
- }
- else
- {
- throw new NotSupportedNetworkException(network);
- }
- }
+ public static Height GetStartingHeight(Network network)
+ => (int)SmartHeader.GetStartingHeader(network).Height;
}
}

ADD
WalletWasabi/Blockchain/Blocks/SmartHeader.cs
+using NBitcoin;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using WalletWasabi.Exceptions;
+using WalletWasabi.Helpers;
+
+namespace WalletWasabi.Blockchain.Blocks
+{
+ public class SmartHeader
+ {
+ public uint256 BlockHash { get; }
+ public uint256 PrevHash { get; }
+ public uint Height { get; }
+ public DateTimeOffset BlockTime { get; }
+
+ public SmartHeader(uint256 blockHash, uint256 prevHash, uint height, DateTimeOffset blockTime)
+ {
+ BlockHash = Guard.NotNull(nameof(blockHash), blockHash);
+ PrevHash = Guard.NotNull(nameof(prevHash), prevHash);
+ if (blockHash == prevHash)
+ {
+ throw new InvalidOperationException($"{nameof(blockHash)} cannot be equal to {nameof(prevHash)}. Value: {blockHash}.");
+ }
+
+ Height = height;
+ BlockTime = blockTime;
+ }
+
+ #region SpecialHeaders
+
+ private static SmartHeader StartingHeaderMain { get; } = new SmartHeader(
+ new uint256("0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893"),
+ new uint256("000000000000000000cbeff0b533f8e1189cf09dfbebf57a8ebe349362811b80"),
+ 481824,
+ DateTimeOffset.FromUnixTimeSeconds(1503539857));
+
+ private static SmartHeader StartingHeaderTestNet { get; } = new SmartHeader(
+ new uint256("00000000000f0d5edcaeba823db17f366be49a80d91d15b77747c2e017b8c20a"),
+ new uint256("0000000000211a4d54bceb763ea690a4171a734c48d36f7d8e30b51d6df6ea85"),
+ 828575,
+ DateTimeOffset.FromUnixTimeSeconds(1463079943));
+
+ private static SmartHeader StartingHeaderRegTest { get; } = new SmartHeader(
+ Network.RegTest.GenesisHash,
+ Network.RegTest.GetGenesis().Header.HashPrevBlock,
+ 0,
+ Network.RegTest.GetGenesis().Header.BlockTime);
+
+ /// <summary>
+ /// Where the first possible bech32 transaction ever can be found.
+ /// </summary>
+ public static SmartHeader GetStartingHeader(Network network)
+ => network.NetworkType switch
+ {
+ NetworkType.Mainnet => StartingHeaderMain,
+ NetworkType.Testnet => StartingHeaderTestNet,
+ NetworkType.Regtest => StartingHeaderRegTest,
+ _ => throw new NotSupportedNetworkException(network)
+ };
+
+ #endregion SpecialHeaders
+ }
+}

MODIFY
WalletWasabi/Stores/IndexStore.cs
WalletWasabi/Stores/IndexStore.cs
@@ -8,6 +8,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WalletWasabi.Backend.Models;
+using WalletWasabi.Blockchain.BlockFilters;
using WalletWasabi.Helpers;
using WalletWasabi.Io;
using WalletWasabi.Logging;

Create SmartHeader