From 805893741b0f8c379db252999616619246846cd9 Mon Sep 17 00:00:00 2001 From: quantumagi Date: Wed, 13 Jul 2022 00:05:16 +1000 Subject: [PATCH 1/4] Remove redundant CoinDb code --- .../CoinViews/CachedCoinView.cs | 2 +- .../CoinViews/Coindb/Coindb.cs | 65 +++++++++---------- .../CoinViews/Coindb/DBreezeCoindb.cs | 2 +- .../CoinViews/Coindb/ICoindb.cs | 3 +- .../CoinViews/InMemoryCoinView.cs | 2 +- .../CoinViewTests.cs | 2 +- .../NodeContext.cs | 6 +- 7 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/CachedCoinView.cs b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/CachedCoinView.cs index e77ad63bb0..86b5279c00 100644 --- a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/CachedCoinView.cs +++ b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/CachedCoinView.cs @@ -200,7 +200,7 @@ public void Sync(ChainIndexer chainIndexer) public void Initialize(ChainedHeader chainTip, ChainIndexer chainIndexer, IConsensusRuleEngine consensusRuleEngine) { - this.coindb.Initialize(chainTip); + this.coindb.Initialize(); Sync(chainIndexer); diff --git a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/Coindb.cs b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/Coindb.cs index be0cd8603a..3cc16ef3bd 100644 --- a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/Coindb.cs +++ b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/Coindb.cs @@ -41,7 +41,7 @@ namespace Stratis.Bitcoin.Features.Consensus.CoinViews private BackendPerformanceSnapshot latestPerformanceSnapShot; - /// Access to dBreeze database. + /// Access to database. private IDb coinDb; private readonly DBreezeSerializer dBreezeSerializer; @@ -70,12 +70,33 @@ public Coindb(Network network, string dataFolder, IDateTimeProvider dateTimeProv nodeStats.RegisterStats(this.AddBenchStats, StatsType.Benchmark, this.GetType().Name, 400); } - public void Initialize(ChainedHeader chainTip) + public void Initialize() { // Open a connection to a new DB and create if not found this.coinDb = new T(); this.coinDb.Open(this.dataFolder); + EndiannessFix(); + + EnsureCoinDatabaseIntegrity(); + + Block genesis = this.network.GetGenesis(); + + if (this.GetTipHash() == null) + { + using (var batch = this.coinDb.GetWriteBatch()) + { + this.SetBlockHash(batch, new HashHeightPair(genesis.GetHash(), 0)); + batch.Write(); + } + } + + this.logger.LogInformation("Coin database initialized with tip '{0}'.", this.persistedCoinviewTip); + } + + + private void EndiannessFix() + { // Check if key bytes are in the wrong endian order. HashHeightPair current = this.GetTipHash(); @@ -129,46 +150,18 @@ public void Initialize(ChainedHeader chainTip) } } } - - EnsureCoinDatabaseIntegrity(chainTip); - - Block genesis = this.network.GetGenesis(); - - if (this.GetTipHash() == null) - { - using (var batch = this.coinDb.GetWriteBatch()) - { - this.SetBlockHash(batch, new HashHeightPair(genesis.GetHash(), 0)); - batch.Write(); - } - } - - this.logger.LogInformation("Coinview initialized with tip '{0}'.", this.persistedCoinviewTip); } - private void EnsureCoinDatabaseIntegrity(ChainedHeader chainTip) + /// Just check the integrity. Coin view performs the sync with the chain tip. + private void EnsureCoinDatabaseIntegrity() { this.logger.LogInformation("Checking coin database integrity..."); - var heightToCheck = chainTip.Height; - - // Find the height up to where rewind data is stored above chain tip. - do - { - heightToCheck += 1; - - byte[] row = this.coinDb.Get(rewindTable, BitConverter.GetBytes(heightToCheck).Reverse().ToArray()); - if (row == null) - break; - - } while (true); - - for (int height = heightToCheck - 1; height > chainTip.Height;) + if (this.GetTipHash() == null) { - this.logger.LogInformation($"Fixing coin database, deleting rewind data at height {height} above tip '{chainTip}'."); - - // Do a batch of rewinding. - height = RewindInternal(height, new HashHeightPair(chainTip)).Height; + this.logger.LogInformation($"Rebuilding coin database that has no tip information."); + this.coinDb.Clear(); + return; } this.logger.LogInformation("Coin database integrity good."); diff --git a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/DBreezeCoindb.cs b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/DBreezeCoindb.cs index 638444e332..0864d972a0 100644 --- a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/DBreezeCoindb.cs +++ b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/DBreezeCoindb.cs @@ -65,7 +65,7 @@ public DBreezeCoindb(Network network, string folder, IDateTimeProvider dateTimeP nodeStats.RegisterStats(this.AddBenchStats, StatsType.Benchmark, this.GetType().Name, 300); } - public void Initialize(ChainedHeader chainTip) + public void Initialize() { Block genesis = this.network.GetGenesis(); diff --git a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/ICoindb.cs b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/ICoindb.cs index f8c664d6b6..076f696aed 100644 --- a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/ICoindb.cs +++ b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/ICoindb.cs @@ -10,8 +10,7 @@ namespace Stratis.Bitcoin.Features.Consensus.CoinViews public interface ICoindb { /// Initialize the coin database. - /// The current chain's tip. - void Initialize(ChainedHeader chainTip); + void Initialize(); /// /// Retrieves the block hash of the current tip of the coinview. diff --git a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/InMemoryCoinView.cs b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/InMemoryCoinView.cs index 9cb80e7129..7652b469a1 100644 --- a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/InMemoryCoinView.cs +++ b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/InMemoryCoinView.cs @@ -122,7 +122,7 @@ public RewindData GetRewindData(int height) throw new NotImplementedException(); } - public void Initialize(ChainedHeader chainTip = null) + public void Initialize() { } } diff --git a/src/Stratis.Bitcoin.IntegrationTests/CoinViewTests.cs b/src/Stratis.Bitcoin.IntegrationTests/CoinViewTests.cs index dc3ae155a1..2d0c628c82 100644 --- a/src/Stratis.Bitcoin.IntegrationTests/CoinViewTests.cs +++ b/src/Stratis.Bitcoin.IntegrationTests/CoinViewTests.cs @@ -55,7 +55,7 @@ public void TestDBreezeSerialization() chained = this.MakeNext(this.MakeNext(genesisChainedHeader, ctx.Network), ctx.Network); ctx.Coindb.SaveChanges(new List(), new HashHeightPair(previous), new HashHeightPair(chained)); Assert.Equal(chained.HashBlock, ctx.Coindb.GetTipHash().Hash); - ctx.ReloadPersistentCoinView(chained); + ctx.ReloadPersistentCoinView(); Assert.Equal(chained.HashBlock, ctx.Coindb.GetTipHash().Hash); Assert.NotNull(ctx.Coindb.FetchCoins(new[] { new OutPoint(genesis.Transactions[0], 0) }).UnspentOutputs.Values.FirstOrDefault().Coins); Assert.Null(ctx.Coindb.FetchCoins(new[] { new OutPoint() }).UnspentOutputs.Values.FirstOrDefault().Coins); diff --git a/src/Stratis.Bitcoin.IntegrationTests/NodeContext.cs b/src/Stratis.Bitcoin.IntegrationTests/NodeContext.cs index fb005f0b45..b503f3ea3d 100644 --- a/src/Stratis.Bitcoin.IntegrationTests/NodeContext.cs +++ b/src/Stratis.Bitcoin.IntegrationTests/NodeContext.cs @@ -29,7 +29,7 @@ public NodeContext(object caller, string name, Network network) var dateTimeProvider = new DateTimeProvider(); var serializer = new DBreezeSerializer(this.Network.Consensus.ConsensusFactory); this.Coindb = new Coindb(network, this.FolderName, dateTimeProvider, new NodeStats(dateTimeProvider, NodeSettings.Default(network), new Mock().Object), serializer); - this.Coindb.Initialize(new ChainedHeader(network.GetGenesis().Header, network.GenesisHash, 0)); + this.Coindb.Initialize(); this.cleanList = new List { (IDisposable)this.Coindb }; } @@ -60,7 +60,7 @@ public void Dispose() item.Dispose(); } - public void ReloadPersistentCoinView(ChainedHeader chainTip) + public void ReloadPersistentCoinView() { ((IDisposable)this.Coindb).Dispose(); this.cleanList.Remove((IDisposable)this.Coindb); @@ -68,7 +68,7 @@ public void ReloadPersistentCoinView(ChainedHeader chainTip) var serializer = new DBreezeSerializer(this.Network.Consensus.ConsensusFactory); this.Coindb = new Coindb(this.Network, this.FolderName, dateTimeProvider, new NodeStats(dateTimeProvider, NodeSettings.Default(this.Network), new Mock().Object), serializer); - this.Coindb.Initialize(chainTip); + this.Coindb.Initialize(); this.cleanList.Add((IDisposable)this.Coindb); } } From 1328a0750cd32a29e1a60221cfea2ea90363801f Mon Sep 17 00:00:00 2001 From: quantumagi Date: Wed, 13 Jul 2022 00:09:55 +1000 Subject: [PATCH 2/4] Fix RocksDb.IsValid --- src/Stratis.Bitcoin/Database/RocksDb.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stratis.Bitcoin/Database/RocksDb.cs b/src/Stratis.Bitcoin/Database/RocksDb.cs index f392c7e3b4..e2adcfd6eb 100644 --- a/src/Stratis.Bitcoin/Database/RocksDb.cs +++ b/src/Stratis.Bitcoin/Database/RocksDb.cs @@ -106,7 +106,7 @@ public void Prev() public bool IsValid() { - return this.iterator.Valid() && this.iterator.Value()[0] == this.table; + return this.iterator.Valid() && this.iterator.Key()[0] == this.table; } public byte[] Key() From b10352137197fb924fe2b7ce27ce3f1b1ba1ed7c Mon Sep 17 00:00:00 2001 From: quantumagi Date: Wed, 13 Jul 2022 00:16:20 +1000 Subject: [PATCH 3/4] Update test --- .../CoinViews/CoinviewTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stratis.Bitcoin.Features.Consensus.Tests/CoinViews/CoinviewTests.cs b/src/Stratis.Bitcoin.Features.Consensus.Tests/CoinViews/CoinviewTests.cs index 8f882403a4..4d71c6b4ff 100644 --- a/src/Stratis.Bitcoin.Features.Consensus.Tests/CoinViews/CoinviewTests.cs +++ b/src/Stratis.Bitcoin.Features.Consensus.Tests/CoinViews/CoinviewTests.cs @@ -43,7 +43,7 @@ public CoinviewTests() this.nodeStats = new NodeStats(this.dateTimeProvider, NodeSettings.Default(this.network), new Mock().Object); this.coindb = new DBreezeCoindb(this.network, this.dataFolder, this.dateTimeProvider, this.loggerFactory, this.nodeStats, new DBreezeSerializer(this.network.Consensus.ConsensusFactory)); - this.coindb.Initialize(new ChainedHeader(this.network.GetGenesis().Header, this.network.GenesisHash, 0)); + this.coindb.Initialize(); this.chainIndexer = new ChainIndexer(this.network); this.stakeChainStore = new StakeChainStore(this.network, this.chainIndexer, (IStakedb)this.coindb, this.loggerFactory); From 02a38ed67fd8094e614b80ee953038d0120fd08d Mon Sep 17 00:00:00 2001 From: quantumagi Date: Wed, 13 Jul 2022 00:42:30 +1000 Subject: [PATCH 4/4] Remove whitespace --- .../CoinViews/Coindb/Coindb.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/Coindb.cs b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/Coindb.cs index 3cc16ef3bd..64c27140be 100644 --- a/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/Coindb.cs +++ b/src/Stratis.Bitcoin.Features.Consensus/CoinViews/Coindb/Coindb.cs @@ -94,7 +94,6 @@ public void Initialize() this.logger.LogInformation("Coin database initialized with tip '{0}'.", this.persistedCoinviewTip); } - private void EndiannessFix() { // Check if key bytes are in the wrong endian order.