コード例 #1
0
        public async Task ReorgSameBlockAgainAsync()
        {
            int    blocks = 300;
            int    transactionsPerBlock = 3;
            string dir = PrepareWorkDir();

            var network = Network.Main;

            await using var txStore = new AllTransactionStore(dir, network);
            await txStore.InitializeAsync(ensureBackwardsCompatibility : false);

            foreach (var height in Enumerable.Range(1, blocks))
            {
                var blockHash = RandomUtils.GetUInt256();
                foreach (var n in Enumerable.Range(0, transactionsPerBlock))
                {
                    txStore.AddOrUpdate(CreateTransaction(height, blockHash));
                }
            }
            var storedTxs = txStore.GetTransactions();

            Assert.Equal(blocks * transactionsPerBlock, storedTxs.Count());
            var newestConfirmedTx = storedTxs.Last();
            var tipHeight         = blocks;
            var tipHash           = newestConfirmedTx.BlockHash;

            Assert.Equal(tipHeight, newestConfirmedTx.Height.Value);

            // reorgs non-existing block
            var reorgedTxs = txStore.ReleaseToMempoolFromBlock(RandomUtils.GetUInt256());

            Assert.Empty(reorgedTxs);

            // reorgs most recent block
            reorgedTxs = txStore.ReleaseToMempoolFromBlock(newestConfirmedTx.BlockHash);
            Assert.Equal(3, reorgedTxs.Count());
            Assert.All(reorgedTxs, tx => Assert.False(tx.Confirmed));
            Assert.All(reorgedTxs, tx => Assert.True(txStore.TryGetTransaction(tx.GetHash(), out _)));

            Assert.False(txStore.TryGetTransaction(tipHash, out _));
            Assert.DoesNotContain(tipHash, txStore.GetTransactionHashes());

            // reorgs the same block again
            reorgedTxs = txStore.ReleaseToMempoolFromBlock(newestConfirmedTx.BlockHash);
            Assert.Empty(reorgedTxs);
            Assert.False(txStore.TryGetTransaction(tipHash, out _));
            Assert.DoesNotContain(tipHash, txStore.GetTransactionHashes());

            // reorgs deep block
            var oldestConfirmedTx = storedTxs.First();
            var firstBlockHash    = oldestConfirmedTx.BlockHash;

            // What to do here
            reorgedTxs = txStore.ReleaseToMempoolFromBlock(firstBlockHash);
            Assert.NotEmpty(reorgedTxs);
        }
コード例 #2
0
        public async Task ReorgAsync()
        {
            PrepareTestEnv(
                out string dir,
                out Network network,
                out string mempoolFile,
                out string txFile,
                out SmartTransaction uTx1,
                out SmartTransaction uTx2,
                out SmartTransaction uTx3,
                out SmartTransaction _,
                out SmartTransaction cTx2,
                out SmartTransaction cTx3);

            // Duplication is resolved with labels merged.
            var mempoolFileContent = new[]
            {
                uTx1.ToLine(),
                uTx2.ToLine(),
                uTx3.ToLine(),
            };
            var txFileContent = new[]
            {
                cTx2.ToLine(),
                cTx3.ToLine()
            };
            await File.WriteAllLinesAsync(mempoolFile, mempoolFileContent);

            await File.WriteAllLinesAsync(txFile, txFileContent);

            await using var txStore = new AllTransactionStore(dir, network);
            await txStore.InitializeAsync(ensureBackwardsCompatibility : false);

            // Two transactions are in the mempool store and unconfirmed.
            Assert.True(txStore.MempoolStore.TryGetTransaction(uTx1.GetHash(), out SmartTransaction myUnconfirmedTx1));
            Assert.False(myUnconfirmedTx1.Confirmed);
            Assert.True(txStore.MempoolStore.TryGetTransaction(uTx2.GetHash(), out SmartTransaction myUnconfirmedTx2));
            Assert.False(myUnconfirmedTx2.Confirmed);

            // Create the same transaction but now with a Height to make it confirmed.
            const int ReorgedBlockHeight = 34532;
            uint256   reorgedBlockHash   = new uint256(5);

            var tx1Confirmed = new SmartTransaction(uTx1.Transaction, new Height(ReorgedBlockHeight), blockHash: reorgedBlockHash, label: "buz, qux");
            var tx2Confirmed = new SmartTransaction(uTx2.Transaction, new Height(ReorgedBlockHeight), blockHash: reorgedBlockHash, label: "buz, qux");

            Assert.True(txStore.TryUpdate(tx1Confirmed));
            Assert.True(txStore.TryUpdate(tx2Confirmed));

            // Two transactions are in the ConfirmedStore store and confirmed.
            Assert.True(txStore.ConfirmedStore.TryGetTransaction(uTx1.GetHash(), out SmartTransaction mytx1));
            Assert.False(txStore.MempoolStore.TryGetTransaction(uTx1.GetHash(), out _));
            Assert.True(mytx1.Confirmed);
            Assert.True(txStore.ConfirmedStore.TryGetTransaction(uTx2.GetHash(), out SmartTransaction mytx2));
            Assert.False(txStore.MempoolStore.TryGetTransaction(uTx2.GetHash(), out _));
            Assert.True(mytx2.Confirmed);

            // Now reorg.
            txStore.ReleaseToMempoolFromBlock(reorgedBlockHash);

            // Two transactions are in the mempool store and unconfirmed.
            Assert.True(txStore.MempoolStore.TryGetTransaction(uTx1.GetHash(), out SmartTransaction myReorgedTx1));
            Assert.False(txStore.ConfirmedStore.TryGetTransaction(uTx1.GetHash(), out _));
            Assert.False(myReorgedTx1.Confirmed);
            Assert.True(txStore.MempoolStore.TryGetTransaction(uTx2.GetHash(), out SmartTransaction myReorgedTx2));
            Assert.False(txStore.ConfirmedStore.TryGetTransaction(uTx2.GetHash(), out _));
            Assert.False(myReorgedTx2.Confirmed);
        }