private void verifyMinimumTreeM(int sizeFrom, int sizeTo, int included_percent = 2, int max_tx = 5, byte numLevels = 4)
        {
            PrefixInclusionTree pit   = new PrefixInclusionTree(44, numLevels);
            HashSet <string>    txids = new HashSet <string>();

            for (int i = 0; i < RNG.Next(sizeTo - sizeFrom) + sizeFrom; i++)
            {
                string tx = generateRandomTXID();
                txids.Add(tx);
                pit.add(tx);
            }
            Trace.WriteLine(String.Format("Generated {0} transactions...", txids.Count));
            byte[]    original_tree_hash = pit.calculateTreeHash();
            Stopwatch sw = new Stopwatch();
            // chose some transactions for which to make a minimum tree
            List <string> chosenTransactions = new List <string>();

            foreach (string tx in txids)
            {
                // 10% of transactions, or at least one
                if (chosenTransactions.Count == 0 || RNG.Next(100) < included_percent)
                {
                    chosenTransactions.Add(tx);
                }
                if (chosenTransactions.Count >= max_tx)
                {
                    break;
                }
            }
            Trace.WriteLine(String.Format("Chosen {0} transactions from the list.", chosenTransactions.Count));
            sw.Start();
            byte[] minimal_tree = pit.getMinimumTreeTXList(chosenTransactions);
            sw.Stop();
            Trace.WriteLine(String.Format("Retrieving matcher-based minimum TX tree took {0} ms and yielded {1} bytes.", sw.ElapsedMilliseconds, minimal_tree.Length));
            sw.Reset();
            Assert.IsNotNull(minimal_tree, "PIT returns null minimal tree!");

            PrefixInclusionTree pit2 = new PrefixInclusionTree();

            sw.Start();
            pit2.reconstructMinimumTree(minimal_tree);
            sw.Stop();
            Trace.WriteLine(String.Format("Reconstructing minimum TX tree took {0} ms.", sw.ElapsedMilliseconds));
            sw.Reset();

            sw.Start();
            foreach (string tx in chosenTransactions)
            {
                Assert.IsTrue(pit2.contains(tx), "Reconstructed PIT should contain the selected transactions!");
            }
            Assert.IsTrue(original_tree_hash.SequenceEqual(pit2.calculateTreeHash()), "Minimum PIT tree does not verify successfully!");
            sw.Stop();
            Trace.WriteLine(String.Format("Verifying minimum TX tree took {0} ms.", sw.ElapsedMilliseconds));
        }
        private void verifyMinimumTreeA(int sizeFrom, int sizeTo, bool all_tx, byte numLevels = 4)
        {
            PrefixInclusionTree pit   = new PrefixInclusionTree(44, numLevels);
            HashSet <string>    txids = new HashSet <string>();

            for (int i = 0; i < RNG.Next(sizeTo - sizeFrom) + sizeFrom; i++)
            {
                string tx = generateRandomTXID();
                txids.Add(tx);
                pit.add(tx);
            }
            Trace.WriteLine(String.Format("Generated {0} transactions...", txids.Count));
            byte[]    original_tree_hash = pit.calculateTreeHash();
            Stopwatch sw = new Stopwatch();

            sw.Start();
            byte[] minimal_tree = pit.getMinimumTreeAnonymized();
            sw.Stop();
            Trace.WriteLine(String.Format("Retrieving anonymized minimum TX tree took {0} ms and yielded {1} bytes.", sw.ElapsedMilliseconds, minimal_tree.Length));
            sw.Reset();
            Assert.IsNotNull(minimal_tree, "PIT returns null minimal tree!");

            PrefixInclusionTree pit2 = new PrefixInclusionTree();

            sw.Start();
            pit2.reconstructMinimumTree(minimal_tree);
            sw.Stop();
            Trace.WriteLine(String.Format("Reconstructing minimum TX tree took {0} ms.", sw.ElapsedMilliseconds));
            sw.Reset();
            sw.Start();
            if (all_tx)
            {
                foreach (string tx in txids)
                {
                    // "pretend" to add the transactions we're interested in verifying - this should not change the resulting tree hash
                    pit2.add(tx);
                }
            }
            else
            {
                // only verify some tx (10%)
                int num_to_verify = RNG.Next(sizeFrom) / 10;
                for (int i = 0; i < num_to_verify; i++)
                {
                    string rand_tx = txids.ElementAt(RNG.Next(txids.Count));
                    pit2.add(rand_tx);
                }
            }
            Assert.IsTrue(original_tree_hash.SequenceEqual(pit2.calculateTreeHash()), "Minimum PIT tree does not verify successfully!");
            sw.Stop();
            Trace.WriteLine(String.Format("Verifying minimum TX tree took {0} ms.", sw.ElapsedMilliseconds));
        }
        private void verifyMinimumTree(int sizeFrom, int sizeTo, byte numLevels = 4)
        {
            PrefixInclusionTree pit   = new PrefixInclusionTree(44, numLevels);
            HashSet <string>    txids = new HashSet <string>();

            for (int i = 0; i < RNG.Next(sizeTo - sizeFrom) + sizeFrom; i++)
            {
                string tx = generateRandomTXID();
                txids.Add(tx);
                pit.add(tx);
            }
            byte[] original_tree_hash = pit.calculateTreeHash();
            Trace.WriteLine(String.Format("Generated {0} transactions...", txids.Count));
            // pick a random tx
            string    rtx = txids.ElementAt(RNG.Next(txids.Count));
            Stopwatch sw  = new Stopwatch();

            sw.Start();
            byte[] minimal_tree = pit.getMinimumTree(rtx);
            sw.Stop();
            Trace.WriteLine(String.Format("Retrieving minimum TX tree took {0} ms and yielded {1} bytes.", sw.ElapsedMilliseconds, minimal_tree.Length));
            sw.Reset();
            Assert.IsNotNull(minimal_tree, "PIT returns null minimal tree!");

            PrefixInclusionTree pit2 = new PrefixInclusionTree();

            sw.Start();
            pit2.reconstructMinimumTree(minimal_tree);
            sw.Stop();
            Trace.WriteLine(String.Format("Reconstructing minimum TX tree took {0} ms.", sw.ElapsedMilliseconds));
            sw.Reset();
            sw.Start();
            Assert.IsTrue(pit2.contains(rtx), "Reconstructed PIT should contain the minimal transaction!");
            Assert.IsTrue(original_tree_hash.SequenceEqual(pit2.calculateTreeHash()), "Minimum PIT tree does not verify successfully!");
            sw.Stop();
            Trace.WriteLine(String.Format("Verifying minimum TX tree took {0} ms.", sw.ElapsedMilliseconds));
        }