forked from stratisproject/StratisBitcoinFullNode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request stratisproject#34 from quantumagi/kvmigrate
Add Migrate method for KeyValueStore
- Loading branch information
Showing
23 changed files
with
177 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file modified
BIN
+44.2 KB
(190%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/RegTest100Listener.zip
Binary file not shown.
Binary file modified
BIN
+44.2 KB
(170%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/RegTest100Miner.zip
Binary file not shown.
Binary file modified
BIN
+44.2 KB
(200%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/RegTest100NoWallet.zip
Binary file not shown.
Binary file modified
BIN
+2.51 KB
(110%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/RegTest10Listener.zip
Binary file not shown.
Binary file modified
BIN
+2.49 KB
(110%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/RegTest10Miner.zip
Binary file not shown.
Binary file modified
BIN
+2.5 KB
(120%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/RegTest10NoWallet.zip
Binary file not shown.
Binary file modified
BIN
+69 KB
(200%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/RegTest150Listener.zip
Binary file not shown.
Binary file modified
BIN
+67.8 KB
(180%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/RegTest150Miner.zip
Binary file not shown.
Binary file modified
BIN
+67.8 KB
(210%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/RegTest150NoWallet.zip
Binary file not shown.
Binary file modified
BIN
+15.9 MB
(280%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/StratisMain9500.zip
Binary file not shown.
Binary file modified
BIN
+76.4 KB
(200%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/StratisRegTest100Listener.zip
Binary file not shown.
Binary file modified
BIN
+77 KB
(190%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/StratisRegTest100Miner.zip
Binary file not shown.
Binary file modified
BIN
+77 KB
(210%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/StratisRegTest100NoWallet.zip
Binary file not shown.
Binary file modified
BIN
+2.93 KB
(110%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/StratisRegTest10Listener.zip
Binary file not shown.
Binary file modified
BIN
+3.13 KB
(110%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/StratisRegTest10Miner.zip
Binary file not shown.
Binary file modified
BIN
+3.13 KB
(110%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/StratisRegTest10NoWallet.zip
Binary file not shown.
Binary file modified
BIN
+119 KB
(210%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/StratisRegTest150Listener.zip
Binary file not shown.
Binary file modified
BIN
+119 KB
(200%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/StratisRegTest150Miner.zip
Binary file not shown.
Binary file modified
BIN
+119 KB
(220%)
src/Stratis.Bitcoin.IntegrationTests.Common/ReadyData/StratisRegTest150NoWallet.zip
Binary file not shown.
64 changes: 64 additions & 0 deletions
64
src/Stratis.Bitcoin.IntegrationTests/ReadyBlockChainTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
using System.IO; | ||
using System.IO.Compression; | ||
using NBitcoin; | ||
using Stratis.Bitcoin.Configuration; | ||
using Stratis.Bitcoin.IntegrationTests.Common.ReadyData; | ||
using Stratis.Bitcoin.NodeStorage; | ||
using Stratis.Bitcoin.Tests.Common; | ||
using Stratis.Bitcoin.Utilities; | ||
using Xunit; | ||
|
||
namespace Stratis.Bitcoin.IntegrationTests | ||
{ | ||
internal static class NormalizeDirectorySeparatorExt | ||
{ | ||
/// <summary> | ||
/// Fixes incorrect directory separator characters in path (if any). | ||
/// </summary> | ||
public static string NormalizeDirectorySeparator(this string path) | ||
{ | ||
// Replace incorrect with correct | ||
return path.Replace((Path.DirectorySeparatorChar == '/') ? '\\' : '/', Path.DirectorySeparatorChar); | ||
} | ||
} | ||
|
||
public class ReadyBlockChainTest | ||
{ | ||
private void MigrateStores(Network network, string readyDataName) | ||
{ | ||
byte[] TxIndexKey = new byte[1]; | ||
|
||
string temp = Path.GetTempPath(); | ||
string dir = Path.Combine(temp, readyDataName.Substring(0, readyDataName.LastIndexOf('.'))); | ||
string workDir = dir.Replace("ReadyData", "ReadyDataLevelDB"); | ||
string zipTarget = Path.Combine(temp, readyDataName.Replace("ReadyData", "ReadyDataLevelDB")); | ||
string typeName = network.IsBitcoin() ? "bitcoin" : "stratis"; | ||
|
||
Directory.CreateDirectory("ReadyDataLevelDB"); | ||
|
||
ZipFile.ExtractToDirectory(Path.GetFullPath(readyDataName), dir, true); | ||
|
||
var dataFolderDBZ = new DataFolder(Path.Combine(dir, typeName, network.Name)); | ||
var dataFolderLDB = new DataFolder(Path.Combine(workDir, typeName, network.Name)); | ||
|
||
(new Migrate()).MigrateKeyValueStore<KeyValueStoreDBreeze.KeyValueStoreDBreeze, KeyValueStoreLevelDB.KeyValueStoreLevelDB>(network, dataFolderDBZ, dataFolderLDB); | ||
|
||
if (File.Exists(zipTarget)) | ||
File.Delete(zipTarget); | ||
|
||
ZipFile.CreateFromDirectory(workDir, zipTarget); | ||
} | ||
|
||
[Fact(Skip="Run this manually when needed")] | ||
public void MigrateFromDBreezeToLevelDb() | ||
{ | ||
foreach (string readyDataName in ReadyBlockchain.StratisRegTestAll) | ||
this.MigrateStores(KnownNetworks.StratisRegTest, readyDataName.NormalizeDirectorySeparator()); | ||
|
||
foreach (string readyDataName in ReadyBlockchain.BitcoinRegTestAll) | ||
this.MigrateStores(KnownNetworks.RegTest, readyDataName.NormalizeDirectorySeparator()); | ||
|
||
this.MigrateStores(KnownNetworks.StratisMain, ReadyBlockchain.StratisMainnet9500.NormalizeDirectorySeparator()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
using System; | ||
using System.IO; | ||
using Microsoft.Extensions.Logging; | ||
using NBitcoin; | ||
using Stratis.Bitcoin.Configuration; | ||
using Stratis.Bitcoin.Interfaces; | ||
using Stratis.Bitcoin.KeyValueStore; | ||
using Stratis.Bitcoin.Utilities; | ||
|
||
namespace Stratis.Bitcoin.NodeStorage | ||
{ | ||
public class Migrate | ||
{ | ||
public void MigrateKeyValueStore<TFrom, TTo>(Network network, DataFolder sourceDataFolder, DataFolder targetDataFolder) where TFrom : KeyValueStoreRepository where TTo : KeyValueStoreRepository | ||
{ | ||
// Copy Block Store. | ||
using (var blockStoreSource = new KeyValueStore<TFrom>(sourceDataFolder.BlockPath, new LoggerFactory(), DateTimeProvider.Default, new RepositorySerializer(network.Consensus.ConsensusFactory))) | ||
{ | ||
using (var blockStoreTarget = new KeyValueStore<TTo>(targetDataFolder.BlockPath, new LoggerFactory(), DateTimeProvider.Default, new RepositorySerializer(network.Consensus.ConsensusFactory))) | ||
{ | ||
CopyTable<byte[], byte[]>(blockStoreSource, blockStoreTarget, "Block"); | ||
CopyTable<byte[], byte[]>(blockStoreSource, blockStoreTarget, "Transaction"); | ||
CopyTable<byte[], byte[]>(blockStoreSource, blockStoreTarget, "Common", (tableName, from, to) => | ||
{ | ||
byte[] txIndexKey = new byte[1]; | ||
|
||
if (from.Select(tableName, txIndexKey, out bool txIndex)) | ||
to.Insert(tableName, txIndexKey, txIndex); | ||
}); | ||
} | ||
} | ||
|
||
// Copy Chain Repository. | ||
using (var chainRepoSource = new KeyValueStore<TFrom>(sourceDataFolder.ChainPath, new LoggerFactory(), DateTimeProvider.Default, new RepositorySerializer(network.Consensus.ConsensusFactory))) | ||
{ | ||
using (var chainRepoTarget = new KeyValueStore<TTo>(targetDataFolder.ChainPath, new LoggerFactory(), DateTimeProvider.Default, new RepositorySerializer(network.Consensus.ConsensusFactory))) | ||
{ | ||
// Primitive types must be used. | ||
CopyTable<int, byte[]>(chainRepoSource, chainRepoTarget, "Chain"); | ||
} | ||
} | ||
|
||
// Copy CoinView. | ||
using (var coinViewSource = new KeyValueStore<TFrom>(sourceDataFolder.CoinViewPath, new LoggerFactory(), DateTimeProvider.Default, new RepositorySerializer(network.Consensus.ConsensusFactory))) | ||
{ | ||
using (var coinViewTarget = new KeyValueStore<TTo>(targetDataFolder.CoinViewPath, new LoggerFactory(), DateTimeProvider.Default, new RepositorySerializer(network.Consensus.ConsensusFactory))) | ||
{ | ||
CopyTable<byte[], byte[]>(coinViewSource, coinViewTarget, "Coins"); | ||
// Primitive types must be used. | ||
CopyTable<int, byte[]>(coinViewSource, coinViewTarget, "Rewind"); | ||
CopyTable<byte[], byte[]>(coinViewSource, coinViewTarget, "Stake"); | ||
CopyTable<byte[], byte[]>(coinViewSource, coinViewTarget, "BlockHash"); | ||
} | ||
} | ||
|
||
// Copy ProvenBlockHeader. | ||
using (var provenSource = new KeyValueStore<TFrom>(sourceDataFolder.ProvenBlockHeaderPath, new LoggerFactory(), DateTimeProvider.Default, new RepositorySerializer(network.Consensus.ConsensusFactory))) | ||
{ | ||
using (var provenTarget = new KeyValueStore<TTo>(targetDataFolder.ProvenBlockHeaderPath, new LoggerFactory(), DateTimeProvider.Default, new RepositorySerializer(network.Consensus.ConsensusFactory))) | ||
{ | ||
// Primitive types must be used. | ||
CopyTable<int, byte[]>(provenSource, provenTarget, "ProvenBlockHeader"); | ||
CopyTable<byte[], byte[]>(provenSource, provenTarget, "BlockHashHeight"); | ||
} | ||
} | ||
|
||
if (Directory.Exists(Path.Combine(sourceDataFolder.RootPath, "finalizedBlock"))) | ||
{ | ||
string targetFolder = Path.Combine(targetDataFolder.RootPath, "finalizedBlock"); | ||
if (Directory.Exists(targetFolder)) | ||
Directory.Delete(targetFolder, true); | ||
Directory.CreateDirectory(targetFolder); | ||
foreach (string file in Directory.EnumerateFiles(Path.Combine(sourceDataFolder.RootPath, "finalizedBlock"), "*.*", SearchOption.TopDirectoryOnly)) | ||
File.Copy(file, file.Replace("ReadyData", "ReadyDataLevelDB")); | ||
} | ||
|
||
foreach (string file in Directory.EnumerateFiles(sourceDataFolder.RootPath, "*.*", SearchOption.TopDirectoryOnly)) | ||
{ | ||
string targetName = file.Replace("ReadyData", "ReadyDataLevelDB"); | ||
if (File.Exists(targetName)) | ||
File.Delete(targetName); | ||
File.Copy(file, targetName); | ||
} | ||
} | ||
|
||
private static void CopyTable<K, V>(IKeyValueStore keyValueStoreFrom, IKeyValueStore keyValueStoreTo, string tableName, | ||
Action<string, IKeyValueStoreTransaction, IKeyValueStoreTransaction> action = null) | ||
{ | ||
using (IKeyValueStoreTransaction tranFrom = keyValueStoreFrom.CreateTransaction(KeyValueStoreTransactionMode.Read)) | ||
{ | ||
using (IKeyValueStoreTransaction tranTo = keyValueStoreTo.CreateTransaction(KeyValueStoreTransactionMode.ReadWrite)) | ||
{ | ||
foreach ((K key, V value) in tranFrom.SelectForward<K, V>(tableName)) | ||
{ | ||
tranTo.Insert(tableName, key, value); | ||
} | ||
|
||
// Copy primitives explicitly using the correct types. | ||
action?.Invoke(tableName, tranFrom, tranTo); | ||
|
||
tranTo.Commit(); | ||
} | ||
} | ||
} | ||
} | ||
} |