Exemple #1
0
        private static void ImportBlocksAndSearchNEO(Stream stream, int specified_block_height)
        {
            long start_tick = DateTime.Now.Ticks;
            int  tx_count   = 0;
            //Dictionary<TransactionType, int> types = new Dictionary<TransactionType, int>();
            //Dictionary<TransactionType, int> typesWithOutput = new Dictionary<TransactionType, int>();
            //Dictionary<TransactionType, int> typesWithOutputNEO = new Dictionary<TransactionType, int>();
            //LevelDBBlockchain blockchain = (LevelDBBlockchain)Blockchain.Default;

            INeoAnalyst analyst = new NeoMemAnalyst();

            using (BinaryReader r = new BinaryReader(stream))
            {
                uint start = 0;
                uint count = r.ReadUInt32();
                uint end   = start + count - 1;

                if (specified_block_height > end)
                {
                    Console.WriteLine("Specified block height({0}) is larger than the height({1}) of chain.acc.", specified_block_height, end);
                    return;
                }

                Console.WriteLine("total blocks in chain.acc : {0}", count);

                for (uint height = start; height <= specified_block_height; height++)
                {
                    int    block_length = r.ReadInt32();
                    byte[] array        = r.ReadBytes(block_length);
                    Block  block        = array.AsSerializable <Block>();
                    tx_count += block.Transactions.Length;
                    int tx_order = 0;
                    foreach (Transaction tx in block.Transactions)
                    {
                        Fixed8 sumOfInput = Fixed8.Zero;
                        foreach (CoinReference input in tx.Inputs)
                        {
                            AddressPair value = analyst.Remove(input.PrevHash, input.PrevIndex);
                            //AddressPair value = analyst.Peek(input.PrevHash, input.PrevIndex);
                            if (value != null)
                            {
                                sumOfInput += value.value;
                            }
                        }

                        Fixed8 sumOfOutput = Fixed8.Zero;
                        for (ushort output_index = 0; output_index < (ushort)tx.Outputs.Length; output_index++)
                        {
                            TransactionOutput output = tx.Outputs[output_index];
                            if (output.AssetId.Equals(Blockchain.GoverningToken.Hash))
                            {
                                analyst.Add(tx.Hash, output_index, output.Value, output.ScriptHash);
                                sumOfOutput += output.Value;
                            }
                        }

                        if (sumOfInput != sumOfOutput && tx.Type != TransactionType.IssueTransaction)
                        {
                            Console.WriteLine("Unbalanced block height {0}, tx order {1} type {2}, input {3}, output {4},\n\ttx {5}", height, tx_order, tx.Type, sumOfInput, sumOfOutput, tx.Hash);
                            Console.WriteLine("-------- Inputs ----------");
                            foreach (CoinReference input in tx.Inputs)
                            {
                                Console.WriteLine("\t{0} : {1}", input.PrevHash, input.PrevIndex);
                                AddressPair value = analyst.Peek(input.PrevHash, input.PrevIndex);
                                if (value != null)
                                {
                                    Console.WriteLine("\t\t{0} : {1}", value.value, value.address);
                                }
                            }

                            Console.WriteLine("-------- Outputs ----------");

                            for (ushort output_index = 0; output_index < (ushort)tx.Outputs.Length; output_index++)
                            {
                                TransactionOutput output = tx.Outputs[output_index];
                                Console.WriteLine("\t{0} : {1} : {2}", output.Value, output.ScriptHash, output_index);
                            }
                            Console.WriteLine("------------------");
                        }

                        tx_order++;
                    }
                    if (height % 1000 == 0)
                    {
                        double progress = height * 100.0 / (specified_block_height + 1);
                        Console.WriteLine("{0:F2}% : block {1} size {2}", progress, height, block_length);
                    }
                }
            }

            Dictionary <UInt160, Fixed8> balanceDictionary = new Dictionary <UInt160, Fixed8>();

            foreach (AddressPair ap in analyst.AsEnumerable())
            {
                if (balanceDictionary.ContainsKey(ap.address))
                {
                    balanceDictionary[ap.address] = balanceDictionary[ap.address] + ap.value;
                }
                else
                {
                    balanceDictionary[ap.address] = ap.value;
                }
            }

            Export(balanceDictionary);

            long stop_tick = DateTime.Now.Ticks;
            long cost      = stop_tick - start_tick;
            long seconds   = cost / 10000000;

            Console.WriteLine("{0} seconds", seconds);
            Console.WriteLine("...");
        }
Exemple #2
0
        private static void ImportBlocksAndArrangeUTXO(Stream stream, int specified_block_height)
        {
            long start_tick = DateTime.Now.Ticks;
            int  tx_count   = 0;

            INeoAnalyst analyst = new NeoMemAnalyst();
            Dictionary <IndexPair, bool> utxoDictionary = new Dictionary <IndexPair, bool>();

            using (BinaryReader r = new BinaryReader(stream))
            {
                uint start = 0;
                uint count = r.ReadUInt32();
                uint end   = start + count - 1;

                if (specified_block_height > end)
                {
                    Console.WriteLine("Specified block height({0}) is larger than the height({1}) of chain.acc.", specified_block_height, end);
                    return;
                }
                else if (specified_block_height < 0)
                {
                    specified_block_height = (int)end;
                }

                Console.WriteLine("total blocks in chain.acc : {0}", count);

                for (uint height = start; height <= specified_block_height; height++)
                {
                    int    block_length = r.ReadInt32();
                    byte[] array        = r.ReadBytes(block_length);
                    Block  block        = array.AsSerializable <Block>();
                    tx_count += block.Transactions.Length;
                    int tx_order = 0;
                    foreach (Transaction tx in block.Transactions)
                    {
                        Fixed8 sumOfInput = Fixed8.Zero;
                        foreach (CoinReference input in tx.Inputs)
                        {
                            AddressPair value = analyst.Remove(input.PrevHash, input.PrevIndex);
                            //AddressPair value = analyst.Peek(input.PrevHash, input.PrevIndex);
                            if (value != null)
                            {
                                sumOfInput += value.value;
                                utxoDictionary[new IndexPair(input.PrevHash, input.PrevIndex)] = false;
                            }
                        }

                        Fixed8 sumOfOutput = Fixed8.Zero;
                        for (ushort output_index = 0; output_index < (ushort)tx.Outputs.Length; output_index++)
                        {
                            TransactionOutput output = tx.Outputs[output_index];
                            //if (output.AssetId.Equals(Blockchain.GoverningToken.Hash))
                            //{
                            analyst.Add(tx.Hash, output_index, output.Value, output.ScriptHash);
                            sumOfOutput += output.Value;
                            utxoDictionary.Add(new IndexPair(tx.Hash, output_index), true);
                            //}
                        }

                        //if (sumOfInput != sumOfOutput && tx.Type != TransactionType.IssueTransaction && tx.Type != TransactionType.ClaimTransaction && tx.Type != TransactionType.EnrollmentTransaction && tx.Type != TransactionType.RegisterTransaction && tx.Type != TransactionType.InvocationTransaction && tx.Type != TransactionType.MinerTransaction)
                        //{
                        //    Console.WriteLine("Unbalanced block height {0}, tx order {1} type {2}, input {3}, output {4},\n\ttx {5}", height, tx_order, tx.Type, sumOfInput, sumOfOutput, tx.Hash);
                        //    Console.WriteLine("-------- Inputs ----------");
                        //    foreach (CoinReference input in tx.Inputs)
                        //    {
                        //        Console.WriteLine("\t{0} : {1}", input.PrevHash, input.PrevIndex);
                        //        AddressPair value = analyst.Peek(input.PrevHash, input.PrevIndex);
                        //        if (value != null)
                        //        {
                        //            Console.WriteLine("\t\t{0} : {1}", value.value, value.address);
                        //        }
                        //    }

                        //    Console.WriteLine("-------- Outputs ----------");

                        //    for (ushort output_index = 0; output_index < (ushort)tx.Outputs.Length; output_index++)
                        //    {
                        //        TransactionOutput output = tx.Outputs[output_index];
                        //        Console.WriteLine("\t{0} : {1} : {2}", output.Value, output.ScriptHash, output_index);
                        //    }
                        //    Console.WriteLine("------------------");

                        //}

                        tx_order++;
                    }
                    if (height % 1000 == 0)
                    {
                        double progress = height * 100.0 / (specified_block_height + 1);
                        Console.WriteLine("{0:F2}% : block {1} size {2}", progress, height, block_length);
                    }
                }
            }

            Console.WriteLine("{0} UTXO entries.", utxoDictionary.Keys.Count);
            File.Delete("utxo_list.csv");
            StreamWriter sw = File.CreateText("utxo_list.csv");

            foreach (IndexPair key in utxoDictionary.Keys)
            {
                sw.WriteLine("{0},{1},{2}", key.hash, key.index, utxoDictionary[key]?"unspent":"spent");
            }
            sw.Close();

            File.Delete("utxo_sample_100k.csv");
            File.Delete("utxo_status_100k.csv");
            StreamWriter     sw1  = File.CreateText("utxo_sample_100k.csv");
            StreamWriter     sw2  = File.CreateText("utxo_status_100k.csv");
            List <IndexPair> keys = new List <IndexPair>();

            keys.AddRange(utxoDictionary.Keys);
            Random rnd = new Random();

            for (int i = 0; i < 100000; i++)
            {
                int index = rnd.Next(keys.Count);
                var key   = keys[index];
                sw1.WriteLine("{0},{1}", key.hash, key.index);
                sw2.WriteLine("{0}", utxoDictionary[key] ? "unspent" : "spent");
            }
            sw1.Close();
            sw2.Close();

            File.Delete("utxo_sample_1m.csv");
            File.Delete("utxo_status_1m.csv");
            StreamWriter sw3 = File.CreateText("utxo_sample_1m.csv");
            StreamWriter sw4 = File.CreateText("utxo_status_1m.csv");

            for (int i = 0; i < 1000000; i++)
            {
                int index = rnd.Next(keys.Count);
                var key   = keys[index];
                sw3.WriteLine("{0},{1}", key.hash, key.index);
                sw4.WriteLine("{0}", utxoDictionary[key] ? "unspent" : "spent");
            }
            sw3.Close();
            sw4.Close();

            long stop_tick = DateTime.Now.Ticks;
            long cost      = stop_tick - start_tick;
            long seconds   = cost / 10000000;

            Console.WriteLine("{0} seconds", seconds);
            Console.WriteLine("...");
        }