diff --git a/CHANGES.md b/CHANGES.md index 3b8078aeb5d..4313bcd4d06 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,8 @@ To be released. - Changed `IMessageCodec.Encode(MessageContent, PrivateKey, AppProtocolVersion, BoundPeer, DateTimeOffset, byte[]?)` to `IMessageCodec.Encode(Message, PrivateKey)`. [[#3997]] + - Removed `IStore.ForkBlockIndexes()` and `IStore.ForkTxNonces()` + interface methods. [[#4001]] ### Backward-incompatible network protocol changes @@ -29,6 +31,7 @@ To be released. ### CLI tools [#3997]: https://github.com/planetarium/libplanet/pull/3997 +[#4001]: https://github.com/planetarium/libplanet/pull/3997 Version 5.4.0 diff --git a/src/Libplanet.RocksDBStore/RocksDBStore.Fork.cs b/src/Libplanet.RocksDBStore/RocksDBStore.Fork.cs new file mode 100644 index 00000000000..7d429a2b273 --- /dev/null +++ b/src/Libplanet.RocksDBStore/RocksDBStore.Fork.cs @@ -0,0 +1,112 @@ +using System; +using System.Linq; +using Libplanet.Crypto; +using Libplanet.Types.Blocks; +using RocksDbSharp; + +namespace Libplanet.RocksDBStore +{ + public partial class RocksDBStore + { + /// + /// Forks block indexes from to + /// . + /// + /// The chain ID of block indexes to fork. + /// The chain ID of destination block indexes. + /// The branchpoint to fork. + /// + /// + public void ForkBlockIndexes( + Guid sourceChainId, + Guid destinationChainId, + BlockHash branchpoint + ) + { + BlockHash[] bottoms = IterateIndexes(sourceChainId, 0, 1, true).ToArray(); + BlockHash? genesisHash = bottoms.Any() ? bottoms[0] : (BlockHash?)null; + + if (genesisHash is null || branchpoint.Equals(genesisHash)) + { + return; + } + + using var batch = new WriteBatch(); + foreach (Iterator k in IterateDb(_chainDb, IndexKey(destinationChainId))) + { + batch.Delete(k.Key()); + } + + if (!(GetBlockIndex(branchpoint) is { } bpIndex)) + { + return; + } + + _chainDb.Write(batch); + + // Do fork from previous chain instead current if it's available and same as current. + if (GetPreviousChainInfo(sourceChainId) is { } chainInfo && + chainInfo.Item2 == bpIndex) + { + ForkBlockIndexes(chainInfo.Item1, destinationChainId, branchpoint); + return; + } + + _chainDb.Put(PreviousChainIdKey(destinationChainId), sourceChainId.ToByteArray()); + _chainDb.Put( + PreviousChainIndexKey(destinationChainId), + RocksDBStoreBitConverter.GetBytes(bpIndex) + ); + _chainDb.Put( + IndexCountKey(destinationChainId), + RocksDBStoreBitConverter.GetBytes(bpIndex + 1) + ); + + _chainDb.Put(ChainIdKey(destinationChainId), destinationChainId.ToByteArray()); + AddFork(sourceChainId, destinationChainId); + } + + /// + /// Forks s from + /// to . + /// + /// The chain of + /// s to fork. + /// The chain of destination + /// s. + public void ForkTxNonces(Guid sourceChainId, Guid destinationChainId) + { + var writeBatch = new WriteBatch(); + bool exist = false; + try + { + byte[] prefix = TxNonceKey(sourceChainId); + foreach (Iterator it in IterateDb(_chainDb, prefix)) + { + exist = true; + Address address = new Address(it.Key().Skip(prefix.Length).ToArray()); + writeBatch.Put(TxNonceKey(destinationChainId, address), it.Value()); + if (writeBatch.Count() >= ForkWriteBatchSize) + { + _chainDb.Write(writeBatch); + writeBatch.Dispose(); + writeBatch = new WriteBatch(); + } + } + } + catch (Exception e) + { + LogUnexpectedException(nameof(ForkTxNonces), e); + throw; + } + finally + { + if (exist) + { + _chainDb.Write(writeBatch); + writeBatch.Dispose(); + } + } + } + } +} diff --git a/src/Libplanet.RocksDBStore/RocksDBStore.cs b/src/Libplanet.RocksDBStore/RocksDBStore.cs index 117182a2211..c15abda7c17 100644 --- a/src/Libplanet.RocksDBStore/RocksDBStore.cs +++ b/src/Libplanet.RocksDBStore/RocksDBStore.cs @@ -84,7 +84,7 @@ namespace Libplanet.RocksDBStore /// /// /// - public class RocksDBStore : BaseStore + public partial class RocksDBStore : BaseStore { private const string BlockDbRootPathName = "block"; private const string BlockIndexDbName = "blockindex"; @@ -648,56 +648,6 @@ public override long AppendIndex(Guid chainId, BlockHash hash) return index; } - /// - public override void ForkBlockIndexes( - Guid sourceChainId, - Guid destinationChainId, - BlockHash branchpoint - ) - { - BlockHash[] bottoms = IterateIndexes(sourceChainId, 0, 1, true).ToArray(); - BlockHash? genesisHash = bottoms.Any() ? bottoms[0] : (BlockHash?)null; - - if (genesisHash is null || branchpoint.Equals(genesisHash)) - { - return; - } - - using var batch = new WriteBatch(); - foreach (Iterator k in IterateDb(_chainDb, IndexKey(destinationChainId))) - { - batch.Delete(k.Key()); - } - - if (!(GetBlockIndex(branchpoint) is { } bpIndex)) - { - return; - } - - _chainDb.Write(batch); - - // Do fork from previous chain instead current if it's available and same as current. - if (GetPreviousChainInfo(sourceChainId) is { } chainInfo && - chainInfo.Item2 == bpIndex) - { - ForkBlockIndexes(chainInfo.Item1, destinationChainId, branchpoint); - return; - } - - _chainDb.Put(PreviousChainIdKey(destinationChainId), sourceChainId.ToByteArray()); - _chainDb.Put( - PreviousChainIndexKey(destinationChainId), - RocksDBStoreBitConverter.GetBytes(bpIndex) - ); - _chainDb.Put( - IndexCountKey(destinationChainId), - RocksDBStoreBitConverter.GetBytes(bpIndex + 1) - ); - - _chainDb.Put(ChainIdKey(destinationChainId), destinationChainId.ToByteArray()); - AddFork(sourceChainId, destinationChainId); - } - /// public override Transaction? GetTransaction(TxId txid) { @@ -1137,42 +1087,6 @@ public override void Dispose() } } - /// - public override void ForkTxNonces(Guid sourceChainId, Guid destinationChainId) - { - var writeBatch = new WriteBatch(); - bool exist = false; - try - { - byte[] prefix = TxNonceKey(sourceChainId); - foreach (Iterator it in IterateDb(_chainDb, prefix)) - { - exist = true; - Address address = new Address(it.Key().Skip(prefix.Length).ToArray()); - writeBatch.Put(TxNonceKey(destinationChainId, address), it.Value()); - if (writeBatch.Count() >= ForkWriteBatchSize) - { - _chainDb.Write(writeBatch); - writeBatch.Dispose(); - writeBatch = new WriteBatch(); - } - } - } - catch (Exception e) - { - LogUnexpectedException(nameof(ForkTxNonces), e); - throw; - } - finally - { - if (exist) - { - _chainDb.Write(writeBatch); - writeBatch.Dispose(); - } - } - } - /// public override void PruneOutdatedChains(bool noopWithoutCanon = false) { diff --git a/src/Libplanet.Store/BaseStore.cs b/src/Libplanet.Store/BaseStore.cs index 265007014ee..d5198efe69c 100644 --- a/src/Libplanet.Store/BaseStore.cs +++ b/src/Libplanet.Store/BaseStore.cs @@ -41,13 +41,6 @@ public abstract class BaseStore : IStore /// public abstract long AppendIndex(Guid chainId, BlockHash hash); - /// - public abstract void ForkBlockIndexes( - Guid sourceChainId, - Guid destinationChainId, - BlockHash branchpoint - ); - public abstract Transaction? GetTransaction(TxId txid); public abstract void PutTransaction(Transaction tx); @@ -171,9 +164,6 @@ public virtual long CountBlocks() /// public abstract void Dispose(); - /// - public abstract void ForkTxNonces(Guid sourceChainId, Guid destinationChainId); - /// public abstract void PruneOutdatedChains(bool noopWithoutCanon = false); diff --git a/src/Libplanet.Store/DefaultStore.cs b/src/Libplanet.Store/DefaultStore.cs index 83460ad1f29..d6e2daffd86 100644 --- a/src/Libplanet.Store/DefaultStore.cs +++ b/src/Libplanet.Store/DefaultStore.cs @@ -317,30 +317,6 @@ public override long AppendIndex(Guid chainId, BlockHash hash) return IndexCollection(chainId).Insert(new HashDoc { Hash = hash }) - 1; } - /// - public override void ForkBlockIndexes( - Guid sourceChainId, - Guid destinationChainId, - BlockHash branchpoint) - { - LiteCollection srcColl = IndexCollection(sourceChainId); - LiteCollection destColl = IndexCollection(destinationChainId); - - BlockHash? genesisHash = IterateIndexes(sourceChainId, 0, 1) - .Cast() - .FirstOrDefault(); - - if (genesisHash is null || branchpoint.Equals(genesisHash)) - { - return; - } - - destColl.Delete(Query.All()); - destColl.InsertBulk(srcColl.FindAll().TakeWhile(i => !i.Hash.Equals(branchpoint))); - - AppendIndex(destinationChainId, branchpoint); - } - /// public override Transaction? GetTransaction(TxId txid) { @@ -624,14 +600,6 @@ public override void IncreaseTxNonce(Guid chainId, Address signer, long delta = collection.Upsert(docId, new BsonDocument() { ["v"] = new BsonValue(nextNonce) }); } - /// - public override void ForkTxNonces(Guid sourceChainId, Guid destinationChainId) - { - LiteCollection srcColl = TxNonceCollection(sourceChainId); - LiteCollection destColl = TxNonceCollection(destinationChainId); - destColl.InsertBulk(srcColl.FindAll()); - } - /// public override void PruneOutdatedChains(bool noopWithoutCanon = false) { diff --git a/src/Libplanet.Store/IStore.cs b/src/Libplanet.Store/IStore.cs index 62944075dfa..cef9d19300d 100644 --- a/src/Libplanet.Store/IStore.cs +++ b/src/Libplanet.Store/IStore.cs @@ -75,20 +75,6 @@ public interface IStore : IDisposable /// The index of the appended block. long AppendIndex(Guid chainId, BlockHash hash); - /// - /// Forks block indexes from - /// to - /// . - /// - /// The chain ID of block indexes to - /// fork. - /// The chain ID of destination - /// block indexes. - /// The branchpoint to fork. - /// - /// - void ForkBlockIndexes(Guid sourceChainId, Guid destinationChainId, BlockHash branchpoint); - Transaction? GetTransaction(TxId txid); /// @@ -271,17 +257,6 @@ public interface IStore : IDisposable long CountBlocks(); - /// - /// Forks s from - /// to - /// . - /// - /// The chain of - /// s to fork. - /// The chain of destination - /// s. - void ForkTxNonces(Guid sourceChainId, Guid destinationChainId); - /// /// Delete all non-canonical chains. /// diff --git a/src/Libplanet.Store/MemoryStore.cs b/src/Libplanet.Store/MemoryStore.cs index a8d926e8bc0..1a68b15d60e 100644 --- a/src/Libplanet.Store/MemoryStore.cs +++ b/src/Libplanet.Store/MemoryStore.cs @@ -133,19 +133,6 @@ long IStore.AppendIndex(Guid chainId, BlockHash hash) return list.Count - 1; } - public void ForkBlockIndexes( - Guid sourceChainId, - Guid destinationChainId, - BlockHash branchpoint - ) - { - if (_indices.TryGetValue(sourceChainId, out ImmutableTrieList? source)) - { - int bpIndex = source.FindIndex(branchpoint.Equals); - _indices[destinationChainId] = source.GetRange(0, bpIndex + 1); - } - } - Transaction? IStore.GetTransaction(TxId txid) => _txs.TryGetValue(txid, out Transaction? untyped) && untyped is Transaction tx ? tx @@ -267,14 +254,6 @@ bool IStore.ContainsTransaction(TxId txId) => long IStore.CountBlocks() => _blocks.Count; - void IStore.ForkTxNonces(Guid sourceChainId, Guid destinationChainId) - { - if (_txNonces.TryGetValue(sourceChainId, out ConcurrentDictionary? dict)) - { - _txNonces[destinationChainId] = new ConcurrentDictionary(dict); - } - } - void IStore.PruneOutdatedChains(bool noopWithoutCanon) { if (!(_canonicalChainId is { } ccid)) diff --git a/test/Libplanet.RocksDBStore.Tests/RocksDBStoreTest.cs b/test/Libplanet.RocksDBStore.Tests/RocksDBStoreTest.cs index 39c0c031eaf..a53e9be246a 100644 --- a/test/Libplanet.RocksDBStore.Tests/RocksDBStoreTest.cs +++ b/test/Libplanet.RocksDBStore.Tests/RocksDBStoreTest.cs @@ -278,5 +278,73 @@ int KeysWithChainId(RocksDb db, Guid cid) Directory.Delete(path, true); } } + + [SkippableFact] + public void PruneOutdatedChains() + { + var path = Path.Combine(Path.GetTempPath(), $"rocksdb_test_{Guid.NewGuid()}"); + var store = new RocksDBStore(path); + store.PutBlock(Fx.GenesisBlock); + store.PutBlock(Fx.Block1); + store.PutBlock(Fx.Block2); + store.PutBlock(Fx.Block3); + + Guid cid1 = Guid.NewGuid(); + store.AppendIndex(cid1, Fx.GenesisBlock.Hash); + store.AppendIndex(cid1, Fx.Block1.Hash); + store.AppendIndex(cid1, Fx.Block2.Hash); + Assert.Single(store.ListChainIds()); + Assert.Equal( + new[] { Fx.GenesisBlock.Hash, Fx.Block1.Hash, Fx.Block2.Hash }, + store.IterateIndexes(cid1, 0, null)); + + Guid cid2 = Guid.NewGuid(); + store.ForkBlockIndexes(cid1, cid2, Fx.Block1.Hash); + store.AppendIndex(cid2, Fx.Block2.Hash); + store.AppendIndex(cid2, Fx.Block3.Hash); + Assert.Equal(2, store.ListChainIds().Count()); + Assert.Equal( + new[] { Fx.GenesisBlock.Hash, Fx.Block1.Hash, Fx.Block2.Hash, Fx.Block3.Hash }, + store.IterateIndexes(cid2, 0, null)); + + Guid cid3 = Guid.NewGuid(); + store.ForkBlockIndexes(cid1, cid3, Fx.Block2.Hash); + Assert.Equal(3, store.ListChainIds().Count()); + Assert.Equal( + new[] { Fx.GenesisBlock.Hash, Fx.Block1.Hash, Fx.Block2.Hash }, + store.IterateIndexes(cid3, 0, null)); + + Assert.Throws(() => store.PruneOutdatedChains()); + store.PruneOutdatedChains(true); + store.SetCanonicalChainId(cid3); + store.PruneOutdatedChains(); + Assert.Single(store.ListChainIds()); + Assert.Equal( + new[] { Fx.GenesisBlock.Hash, Fx.Block1.Hash, Fx.Block2.Hash }, + store.IterateIndexes(cid3, 0, null)); + Assert.Equal(3, store.CountIndex(cid3)); + } + + [SkippableFact] + public void ForkTxNonces() + { + var path = Path.Combine(Path.GetTempPath(), $"rocksdb_test_{Guid.NewGuid()}"); + var store = new RocksDBStore(path); + Guid sourceChainId = Guid.NewGuid(); + Guid destinationChainId = Guid.NewGuid(); + store.IncreaseTxNonce(sourceChainId, Fx.Address1, 1); + store.IncreaseTxNonce(sourceChainId, Fx.Address2, 2); + store.IncreaseTxNonce(sourceChainId, Fx.Address3, 3); + + store.ForkTxNonces(sourceChainId, destinationChainId); + + Assert.Equal(1, store.GetTxNonce(destinationChainId, Fx.Address1)); + Assert.Equal(2, store.GetTxNonce(destinationChainId, Fx.Address2)); + Assert.Equal(3, store.GetTxNonce(destinationChainId, Fx.Address3)); + + store.IncreaseTxNonce(sourceChainId, Fx.Address1, 1); + Assert.Equal(2, store.GetTxNonce(sourceChainId, Fx.Address1)); + Assert.Equal(1, store.GetTxNonce(destinationChainId, Fx.Address1)); + } } } diff --git a/test/Libplanet.Tests/Store/ProxyStore.cs b/test/Libplanet.Tests/Store/ProxyStore.cs index b73c61eb1f2..7fc27711c98 100644 --- a/test/Libplanet.Tests/Store/ProxyStore.cs +++ b/test/Libplanet.Tests/Store/ProxyStore.cs @@ -71,14 +71,6 @@ public virtual IEnumerable IterateIndexes( public virtual long AppendIndex(Guid chainId, BlockHash hash) => Store.AppendIndex(chainId, hash); - /// - public virtual void ForkBlockIndexes( - Guid sourceChainId, - Guid destinationChainId, - BlockHash branchpoint - ) => - Store.ForkBlockIndexes(sourceChainId, destinationChainId, branchpoint); - /// public virtual Transaction GetTransaction(TxId txid) => Store.GetTransaction(txid); @@ -159,10 +151,6 @@ public virtual bool ContainsTransaction(TxId txId) => public virtual long CountBlocks() => Store.CountBlocks(); - /// - public virtual void ForkTxNonces(Guid sourceChainId, Guid destinationChainId) => - Store.ForkTxNonces(sourceChainId, destinationChainId); - /// public void PruneOutdatedChains(bool noopWithoutCanon = false) => Store.PruneOutdatedChains(noopWithoutCanon); diff --git a/test/Libplanet.Tests/Store/StoreTest.cs b/test/Libplanet.Tests/Store/StoreTest.cs index 5a25950f8b6..947c0bcb704 100644 --- a/test/Libplanet.Tests/Store/StoreTest.cs +++ b/test/Libplanet.Tests/Store/StoreTest.cs @@ -64,29 +64,6 @@ public void ListChainId() ); } - [SkippableFact] - public void ListChainIdAfterForkAndDelete() - { - var chainA = Guid.NewGuid(); - var chainB = Guid.NewGuid(); - - Fx.Store.PutBlock(Fx.GenesisBlock); - Fx.Store.PutBlock(Fx.Block1); - Fx.Store.PutBlock(Fx.Block2); - - Fx.Store.AppendIndex(chainA, Fx.GenesisBlock.Hash); - Fx.Store.AppendIndex(chainA, Fx.Block1.Hash); - Fx.Store.ForkBlockIndexes(chainA, chainB, Fx.Block1.Hash); - Fx.Store.AppendIndex(chainB, Fx.Block2.Hash); - - Fx.Store.DeleteChainId(chainA); - - Assert.Equal( - new[] { chainB }.ToImmutableHashSet(), - Fx.Store.ListChainIds().ToImmutableHashSet() - ); - } - [SkippableFact] public void DeleteChainId() { @@ -116,201 +93,6 @@ public void DeleteChainIdIsIdempotent() Assert.Empty(Fx.Store.ListChainIds()); } - [SkippableFact] - public void DeleteChainIdWithForks() - { - Skip.IfNot( - Environment.GetEnvironmentVariable("XUNIT_UNITY_RUNNER") is null, - "Flaky test : Libplanet.Blocks.InvalidBlockSignatureException" - ); - - IStore store = Fx.Store; - Guid chainA = Guid.NewGuid(); - Guid chainB = Guid.NewGuid(); - Guid chainC = Guid.NewGuid(); - - // We need `Block`s because `IStore` can't retrieve index(long) by block hash without - // actual block... - store.PutBlock(Fx.GenesisBlock); - store.PutBlock(Fx.Block1); - store.PutBlock(Fx.Block2); - store.PutBlock(Fx.Block3); - - store.AppendIndex(chainA, Fx.GenesisBlock.Hash); - store.AppendIndex(chainB, Fx.GenesisBlock.Hash); - store.AppendIndex(chainC, Fx.GenesisBlock.Hash); - - store.AppendIndex(chainA, Fx.Block1.Hash); - store.ForkBlockIndexes(chainA, chainB, Fx.Block1.Hash); - store.AppendIndex(chainB, Fx.Block2.Hash); - store.ForkBlockIndexes(chainB, chainC, Fx.Block2.Hash); - store.AppendIndex(chainC, Fx.Block3.Hash); - - // Deleting chainA doesn't effect chainB, chainC - store.DeleteChainId(chainA); - - Assert.Empty(store.IterateIndexes(chainA)); - Assert.Null(store.IndexBlockHash(chainA, 0)); - Assert.Null(store.IndexBlockHash(chainA, 1)); - - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - Fx.Block2.Hash, - }, - store.IterateIndexes(chainB) - ); - Assert.Equal(Fx.GenesisBlock.Hash, store.IndexBlockHash(chainB, 0)); - Assert.Equal(Fx.Block1.Hash, store.IndexBlockHash(chainB, 1)); - Assert.Equal(Fx.Block2.Hash, store.IndexBlockHash(chainB, 2)); - - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - Fx.Block2.Hash, - Fx.Block3.Hash, - }, - store.IterateIndexes(chainC) - ); - Assert.Equal(Fx.GenesisBlock.Hash, store.IndexBlockHash(chainC, 0)); - Assert.Equal(Fx.Block1.Hash, store.IndexBlockHash(chainC, 1)); - Assert.Equal(Fx.Block2.Hash, store.IndexBlockHash(chainC, 2)); - Assert.Equal(Fx.Block3.Hash, store.IndexBlockHash(chainC, 3)); - - // Deleting chainB doesn't effect chainC - store.DeleteChainId(chainB); - - Assert.Empty(store.IterateIndexes(chainA)); - Assert.Null(store.IndexBlockHash(chainA, 0)); - Assert.Null(store.IndexBlockHash(chainA, 1)); - - Assert.Empty(store.IterateIndexes(chainB)); - Assert.Null(store.IndexBlockHash(chainB, 0)); - Assert.Null(store.IndexBlockHash(chainB, 1)); - Assert.Null(store.IndexBlockHash(chainB, 2)); - - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - Fx.Block2.Hash, - Fx.Block3.Hash, - }, - store.IterateIndexes(chainC) - ); - Assert.Equal(Fx.GenesisBlock.Hash, store.IndexBlockHash(chainC, 0)); - Assert.Equal(Fx.Block1.Hash, store.IndexBlockHash(chainC, 1)); - Assert.Equal(Fx.Block2.Hash, store.IndexBlockHash(chainC, 2)); - Assert.Equal(Fx.Block3.Hash, store.IndexBlockHash(chainC, 3)); - - store.DeleteChainId(chainC); - - Assert.Empty(store.IterateIndexes(chainA)); - Assert.Empty(store.IterateIndexes(chainB)); - Assert.Empty(store.IterateIndexes(chainC)); - Assert.Null(store.IndexBlockHash(chainC, 0)); - Assert.Null(store.IndexBlockHash(chainC, 1)); - Assert.Null(store.IndexBlockHash(chainC, 2)); - Assert.Null(store.IndexBlockHash(chainC, 3)); - } - - [SkippableFact] - public void DeleteChainIdWithForksReverse() - { - IStore store = Fx.Store; - Guid chainA = Guid.NewGuid(); - Guid chainB = Guid.NewGuid(); - Guid chainC = Guid.NewGuid(); - - // We need `Block`s because `IStore` can't retrieve index(long) by block hash without - // actual block... - store.PutBlock(Fx.GenesisBlock); - store.PutBlock(Fx.Block1); - store.PutBlock(Fx.Block2); - store.PutBlock(Fx.Block3); - - store.AppendIndex(chainA, Fx.GenesisBlock.Hash); - store.AppendIndex(chainB, Fx.GenesisBlock.Hash); - store.AppendIndex(chainC, Fx.GenesisBlock.Hash); - - store.AppendIndex(chainA, Fx.Block1.Hash); - store.ForkBlockIndexes(chainA, chainB, Fx.Block1.Hash); - store.AppendIndex(chainB, Fx.Block2.Hash); - store.ForkBlockIndexes(chainB, chainC, Fx.Block2.Hash); - store.AppendIndex(chainC, Fx.Block3.Hash); - - store.DeleteChainId(chainC); - - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - }, - store.IterateIndexes(chainA) - ); - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - Fx.Block2.Hash, - }, - store.IterateIndexes(chainB) - ); - Assert.Empty(store.IterateIndexes(chainC)); - - store.DeleteChainId(chainB); - - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - }, - store.IterateIndexes(chainA) - ); - Assert.Empty(store.IterateIndexes(chainB)); - Assert.Empty(store.IterateIndexes(chainC)); - - store.DeleteChainId(chainA); - Assert.Empty(store.IterateIndexes(chainA)); - Assert.Empty(store.IterateIndexes(chainB)); - Assert.Empty(store.IterateIndexes(chainC)); - } - - [SkippableFact] - public void ForkFromChainWithDeletion() - { - IStore store = Fx.Store; - Guid chainA = Guid.NewGuid(); - Guid chainB = Guid.NewGuid(); - Guid chainC = Guid.NewGuid(); - - // We need `Block`s because `IStore` can't retrieve index(long) by block hash without - // actual block... - store.PutBlock(Fx.GenesisBlock); - store.PutBlock(Fx.Block1); - store.PutBlock(Fx.Block2); - store.PutBlock(Fx.Block3); - - store.AppendIndex(chainA, Fx.GenesisBlock.Hash); - store.AppendIndex(chainA, Fx.Block1.Hash); - store.ForkBlockIndexes(chainA, chainB, Fx.Block1.Hash); - store.DeleteChainId(chainA); - - store.ForkBlockIndexes(chainB, chainC, Fx.Block1.Hash); - Assert.Equal( - Fx.Block1.Hash, - store.IndexBlockHash(chainC, Fx.Block1.Index) - ); - } - [SkippableFact] public void CanonicalChainId() { @@ -795,211 +577,6 @@ int txNonce } } - [SkippableFact] - public void ForkBlockIndex() - { - IStore store = Fx.Store; - Guid chainA = Guid.NewGuid(); - Guid chainB = Guid.NewGuid(); - Guid chainC = Guid.NewGuid(); - - // We need `Block`s because `IStore` can't retrieve index(long) by block hash without - // actual block... - store.PutBlock(Fx.GenesisBlock); - store.PutBlock(Fx.Block1); - store.PutBlock(Fx.Block2); - store.PutBlock(Fx.Block3); - - store.AppendIndex(chainA, Fx.GenesisBlock.Hash); - store.AppendIndex(chainB, Fx.GenesisBlock.Hash); - store.AppendIndex(chainC, Fx.GenesisBlock.Hash); - - store.AppendIndex(chainA, Fx.Block1.Hash); - store.ForkBlockIndexes(chainA, chainB, Fx.Block1.Hash); - store.AppendIndex(chainB, Fx.Block2.Hash); - store.AppendIndex(chainB, Fx.Block3.Hash); - - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - }, - store.IterateIndexes(chainA) - ); - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - Fx.Block2.Hash, - Fx.Block3.Hash, - }, - store.IterateIndexes(chainB) - ); - - store.ForkBlockIndexes(chainB, chainC, Fx.Block3.Hash); - store.AppendIndex(chainC, Fx.Block4.Hash); - store.AppendIndex(chainC, Fx.Block5.Hash); - - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - }, - store.IterateIndexes(chainA) - ); - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - Fx.Block2.Hash, - Fx.Block3.Hash, - }, - store.IterateIndexes(chainB) - ); - Assert.Equal( - new[] - { - Fx.GenesisBlock.Hash, - Fx.Block1.Hash, - Fx.Block2.Hash, - Fx.Block3.Hash, - Fx.Block4.Hash, - Fx.Block5.Hash, - }, - store.IterateIndexes(chainC) - ); - - Assert.Equal( - new[] - { - Fx.Block1.Hash, - Fx.Block2.Hash, - Fx.Block3.Hash, - Fx.Block4.Hash, - Fx.Block5.Hash, - }, - store.IterateIndexes(chainC, offset: 1) - ); - - Assert.Equal( - new[] - { - Fx.Block2.Hash, - Fx.Block3.Hash, - Fx.Block4.Hash, - Fx.Block5.Hash, - }, - store.IterateIndexes(chainC, offset: 2) - ); - - Assert.Equal( - new[] - { - Fx.Block3.Hash, - Fx.Block4.Hash, - Fx.Block5.Hash, - }, - store.IterateIndexes(chainC, offset: 3) - ); - - Assert.Equal( - new[] - { - Fx.Block4.Hash, - Fx.Block5.Hash, - }, - store.IterateIndexes(chainC, offset: 4) - ); - - Assert.Equal( - new[] - { - Fx.Block5.Hash, - }, - store.IterateIndexes(chainC, offset: 5) - ); - - Assert.Equal( - Array.Empty(), - store.IterateIndexes(chainC, offset: 6) - ); - - Assert.Equal(Fx.Block1.Hash, store.IndexBlockHash(chainA, 1)); - Assert.Equal(Fx.Block1.Hash, store.IndexBlockHash(chainB, 1)); - Assert.Equal(Fx.Block1.Hash, store.IndexBlockHash(chainC, 1)); - Assert.Equal(Fx.Block2.Hash, store.IndexBlockHash(chainB, 2)); - Assert.Equal(Fx.Block2.Hash, store.IndexBlockHash(chainC, 2)); - Assert.Equal(Fx.Block3.Hash, store.IndexBlockHash(chainB, 3)); - Assert.Equal(Fx.Block3.Hash, store.IndexBlockHash(chainC, 3)); - Assert.Equal(Fx.Block4.Hash, store.IndexBlockHash(chainC, 4)); - Assert.Equal(Fx.Block5.Hash, store.IndexBlockHash(chainC, 5)); - } - - [SkippableFact] - public void ForkWithBranch() - { - IStore store = Fx.Store; - Guid chainA = Guid.NewGuid(); - Guid chainB = Guid.NewGuid(); - - // We need `Block`s because `IStore` can't retrieve index(long) by block hash without - // actual block... - Block anotherBlock3 = ProposeNextBlock( - Fx.Block2, - Fx.Proposer, - lastCommit: CreateBlockCommit(Fx.Block2.Hash, 2, 0)); - store.PutBlock(Fx.GenesisBlock); - store.PutBlock(Fx.Block1); - store.PutBlock(Fx.Block2); - store.PutBlock(Fx.Block3); - store.PutBlock(anotherBlock3); - - store.AppendIndex(chainA, Fx.GenesisBlock.Hash); - store.AppendIndex(chainA, Fx.Block1.Hash); - store.AppendIndex(chainA, Fx.Block2.Hash); - store.AppendIndex(chainA, Fx.Block3.Hash); - - store.ForkBlockIndexes(chainA, chainB, Fx.Block2.Hash); - store.AppendIndex(chainB, anotherBlock3.Hash); - - Assert.Equal( - new[] - { - Fx.Block2.Hash, - anotherBlock3.Hash, - }, - store.IterateIndexes(chainB, 2, 2) - ); - Assert.Equal( - new[] - { - Fx.Block2.Hash, - anotherBlock3.Hash, - }, - store.IterateIndexes(chainB, 2) - ); - - Assert.Equal( - new[] - { - anotherBlock3.Hash, - }, - store.IterateIndexes(chainB, 3, 1) - ); - - Assert.Equal( - new[] - { - anotherBlock3.Hash, - }, - store.IterateIndexes(chainB, 3) - ); - } - [SkippableFact] public void Copy() { @@ -1324,72 +901,6 @@ public void ManipulateCommittedEvidence() } } - [SkippableFact] - public void ForkTxNonces() - { - IStore store = Fx.Store; - Guid sourceChainId = Guid.NewGuid(); - Guid destinationChainId = Guid.NewGuid(); - store.IncreaseTxNonce(sourceChainId, Fx.Address1, 1); - store.IncreaseTxNonce(sourceChainId, Fx.Address2, 2); - store.IncreaseTxNonce(sourceChainId, Fx.Address3, 3); - - store.ForkTxNonces(sourceChainId, destinationChainId); - - Assert.Equal(1, store.GetTxNonce(destinationChainId, Fx.Address1)); - Assert.Equal(2, store.GetTxNonce(destinationChainId, Fx.Address2)); - Assert.Equal(3, store.GetTxNonce(destinationChainId, Fx.Address3)); - - store.IncreaseTxNonce(sourceChainId, Fx.Address1, 1); - Assert.Equal(2, store.GetTxNonce(sourceChainId, Fx.Address1)); - Assert.Equal(1, store.GetTxNonce(destinationChainId, Fx.Address1)); - } - - [SkippableFact] - public void PruneOutdatedChains() - { - IStore store = Fx.Store; - store.PutBlock(Fx.GenesisBlock); - store.PutBlock(Fx.Block1); - store.PutBlock(Fx.Block2); - store.PutBlock(Fx.Block3); - - Guid cid1 = Guid.NewGuid(); - store.AppendIndex(cid1, Fx.GenesisBlock.Hash); - store.AppendIndex(cid1, Fx.Block1.Hash); - store.AppendIndex(cid1, Fx.Block2.Hash); - Assert.Single(store.ListChainIds()); - Assert.Equal( - new[] { Fx.GenesisBlock.Hash, Fx.Block1.Hash, Fx.Block2.Hash }, - store.IterateIndexes(cid1, 0, null)); - - Guid cid2 = Guid.NewGuid(); - store.ForkBlockIndexes(cid1, cid2, Fx.Block1.Hash); - store.AppendIndex(cid2, Fx.Block2.Hash); - store.AppendIndex(cid2, Fx.Block3.Hash); - Assert.Equal(2, store.ListChainIds().Count()); - Assert.Equal( - new[] { Fx.GenesisBlock.Hash, Fx.Block1.Hash, Fx.Block2.Hash, Fx.Block3.Hash }, - store.IterateIndexes(cid2, 0, null)); - - Guid cid3 = Guid.NewGuid(); - store.ForkBlockIndexes(cid1, cid3, Fx.Block2.Hash); - Assert.Equal(3, store.ListChainIds().Count()); - Assert.Equal( - new[] { Fx.GenesisBlock.Hash, Fx.Block1.Hash, Fx.Block2.Hash }, - store.IterateIndexes(cid3, 0, null)); - - Assert.Throws(() => store.PruneOutdatedChains()); - store.PruneOutdatedChains(true); - store.SetCanonicalChainId(cid3); - store.PruneOutdatedChains(); - Assert.Single(store.ListChainIds()); - Assert.Equal( - new[] { Fx.GenesisBlock.Hash, Fx.Block1.Hash, Fx.Block2.Hash }, - store.IterateIndexes(cid3, 0, null)); - Assert.Equal(3, store.CountIndex(cid3)); - } - [SkippableFact] public void IdempotentDispose() { diff --git a/test/Libplanet.Tests/Store/StoreTracker.cs b/test/Libplanet.Tests/Store/StoreTracker.cs index ca8485820c2..427c76875f7 100644 --- a/test/Libplanet.Tests/Store/StoreTracker.cs +++ b/test/Libplanet.Tests/Store/StoreTracker.cs @@ -156,15 +156,6 @@ public bool ContainsTransaction(TxId txId) return _store.ContainsTransaction(txId); } - public void ForkBlockIndexes( - Guid sourceChainId, - Guid destinationChainId, - BlockHash branchPoint) - { - Log(nameof(ForkBlockIndexes), sourceChainId, destinationChainId, branchPoint); - _store.ForkBlockIndexes(sourceChainId, destinationChainId, branchPoint); - } - public IEnumerable> ListTxNonces(Guid chainId) { Log(nameof(ListTxNonces), chainId); @@ -183,12 +174,6 @@ public void IncreaseTxNonce(Guid chainId, Address address, long delta = 1) _store.IncreaseTxNonce(chainId, address, delta); } - public void ForkTxNonces(Guid sourceChainId, Guid destinationChainId) - { - Log(nameof(ForkTxNonces), sourceChainId, destinationChainId); - _store.ForkTxNonces(sourceChainId, destinationChainId); - } - public void PruneOutdatedChains(bool noopWithoutCanon = false) { Log(nameof(PruneOutdatedChains));