예제 #1
0
파일: Core.cs 프로젝트: pizyumi/CREA
        public void StartSystem()
        {
            if (isSystemStarted)
                throw new InvalidOperationException("core_started");

            ahdb = new AccountHoldersDatabase(databaseBasepath);
            thdb = new TransactionHistoriesDatabase(databaseBasepath);
            bcadb = new BlockchainAccessDB(databaseBasepath);
            bmdb = new BlockManagerDB(databaseBasepath);
            bdb = new BlockDB(databaseBasepath);
            bfpdb = new BlockFilePointersDB(databaseBasepath);
            ufadb = new UtxoFileAccessDB(databaseBasepath);
            ufpdb = new UtxoFilePointersDB(databaseBasepath);
            ufptempdb = new UtxoFilePointersTempDB(databaseBasepath);
            utxodb = new UtxoDB(databaseBasepath);

            accountHolders = new AccountHolders();
            accountHoldersFactory = new AccountHoldersFactory();

            byte[] ahDataBytes = ahdb.GetData();
            if (ahDataBytes.Length != 0)
                accountHolders.FromBinary(ahDataBytes);
            else
                accountHolders.LoadVersion0();

            transactionHistories = thdb.GetData().Pipe((data) => data.Length == 0 ? new TransactionHistories() : SHAREDDATA.FromBinary<TransactionHistories>(data));
            transactionHistories.UnconfirmedTransactionAdded += (sender, e) =>
            {
                foreach (var accountHolder in accountHolders.AllAccountHolders)
                    foreach (var account in accountHolder.Accounts)
                        foreach (var prevTxOut in e.senders)
                            if (account.Address.Equals(prevTxOut.Address))
                                account.accountStatus.unconfirmedAmount = new CurrencyUnit(account.accountStatus.unconfirmedAmount.rawAmount + prevTxOut.Amount.rawAmount);
            };
            transactionHistories.UnconfirmedTransactionRemoved += (sender, e) =>
            {
                foreach (var accountHolder in accountHolders.AllAccountHolders)
                    foreach (var account in accountHolder.Accounts)
                        foreach (var prevTxOut in e.receivers)
                            if (account.Address.Equals(prevTxOut.Address))
                                account.accountStatus.unconfirmedAmount = new CurrencyUnit(account.accountStatus.unconfirmedAmount.rawAmount - prevTxOut.Amount.rawAmount);
            };

            usableBalanceCache = new CachedData<CurrencyUnit>(() =>
            {
                long rawAmount = 0;
                foreach (var accountHolder in accountHolders.AllAccountHolders)
                    foreach (var account in accountHolder.Accounts)
                        rawAmount += account.accountStatus.usableAmount.rawAmount;
                return new CurrencyUnit(rawAmount);
            });
            unusableBalanceCache = new CachedData<CurrencyUnit>(() =>
            {
                long rawAmount = 0;
                foreach (var accountHolder in accountHolders.AllAccountHolders)
                    foreach (var account in accountHolder.Accounts)
                        rawAmount += account.accountStatus.unusableAmount.rawAmount;
                return new CurrencyUnit(rawAmount);
            });
            unconfirmedBalanceCache = new CachedData<CurrencyUnit>(() =>
            {
                long rawAmount = 0;
                foreach (var accountHolder in accountHolders.AllAccountHolders)
                    foreach (var account in accountHolder.Accounts)
                        rawAmount += account.accountStatus.unconfirmedAmount.rawAmount;
                return new CurrencyUnit(rawAmount);
            });
            usableBalanceWithUnconfirmedCache = new CachedData<CurrencyUnit>(() => new CurrencyUnit(usableBalanceCache.Data.rawAmount - unconfirmedBalanceCache.Data.rawAmount));
            unusableBalanceWithUnconformedCache = new CachedData<CurrencyUnit>(() => new CurrencyUnit(unusableBalanceCache.Data.rawAmount + unconfirmedBalanceCache.Data.rawAmount));

            blockChain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb);
            blockChain.LoadTransactionHistories(transactionHistories);

            //<未改良>暫定?
            if (blockChain.headBlockIndex == -1)
            {
                blockChain.UpdateChain(new GenesisBlock());

                this.RaiseNotification("genesis_block_generated", 5);
            }

            Dictionary<Account, EventHandler<Tuple<CurrencyUnit, CurrencyUnit>>> changeAmountDict = new Dictionary<Account, EventHandler<Tuple<CurrencyUnit, CurrencyUnit>>>();

            Action<bool> _UpdateBalance = (isOnlyUnconfirmed) =>
            {
                if (!isOnlyUnconfirmed)
                {
                    usableBalanceCache.IsModified = true;
                    unusableBalanceCache.IsModified = true;
                }
                unconfirmedBalanceCache.IsModified = true;
                usableBalanceWithUnconfirmedCache.IsModified = true;
                unusableBalanceWithUnconformedCache.IsModified = true;

                BalanceUpdated(this, EventArgs.Empty);
            };

            Action<Account, bool> _AddAddressEvent = (account, isUpdatebalance) =>
            {
                EventHandler<Tuple<CurrencyUnit, CurrencyUnit>> eh = (sender, e) =>
                {
                    account.accountStatus.usableAmount = e.Item1;
                    account.accountStatus.unusableAmount = e.Item2;
                };

                changeAmountDict.Add(account, eh);

                AddressEvent addressEvent = new AddressEvent(account.Address.Hash);
                addressEvent.BalanceUpdated += eh;

                blockChain.AddAddressEvent(addressEvent);

                long rawAmount = 0;
                foreach (var unconfirmedTh in transactionHistories.unconfirmedTransactionHistories.ToArray())
                    foreach (var prevTxOut in unconfirmedTh.senders)
                        if (prevTxOut.Address.Equals(account.Address))
                            rawAmount += prevTxOut.Amount.rawAmount;
                account.accountStatus.unconfirmedAmount = new CurrencyUnit(rawAmount);

                if (isUpdatebalance)
                    _UpdateBalance(false);
            };

            EventHandler<Account> _AccountAdded = (sender, e) =>
            {
                utxodb.Open();

                _AddAddressEvent(e, true);

                utxodb.Close();
            };
            EventHandler<Account> _AccountRemoved = (sender, e) =>
            {
                EventHandler<Tuple<CurrencyUnit, CurrencyUnit>> eh = changeAmountDict[e];

                changeAmountDict.Remove(e);

                AddressEvent addressEvent = blockChain.RemoveAddressEvent(e.Address.Hash);
                addressEvent.BalanceUpdated -= eh;

                _UpdateBalance(false);
            };

            utxodb.Open();

            foreach (var accountHolder in accountHolders.AllAccountHolders)
            {
                foreach (var account in accountHolder.Accounts)
                    _AddAddressEvent(account, false);

                accountHolder.AccountAdded += _AccountAdded;
                accountHolder.AccountRemoved += _AccountRemoved;
            }

            utxodb.Close();

            accountHolders.AccountHolderAdded += (sender, e) =>
            {
                e.AccountAdded += _AccountAdded;
                e.AccountRemoved += _AccountRemoved;
            };
            accountHolders.AccountHolderRemoved += (semder, e) =>
            {
                e.AccountAdded -= _AccountAdded;
                e.AccountRemoved -= _AccountRemoved;
            };

            blockChain.BalanceUpdated += (sender, e) => _UpdateBalance(false);

            _UpdateBalance(false);

            unconfirmedTtxs = new Dictionary<TransferTransaction, TransactionOutput[]>();
            mining = new Mining();
            mining.FoundNonce += (sender, e) => creaNodeTest.DiffuseNewBlock(e);

            blockChain.Updated += (sender, e) =>
            {
                foreach (var block in e)
                    foreach (var tx in block.Transactions)
                        foreach (var txIn in tx.TxInputs)
                        {
                            TransferTransaction contradiction = null;

                            foreach (var unconfirmedTx in unconfirmedTtxs)
                            {
                                foreach (var unconfirmedTxIn in unconfirmedTx.Key.TxInputs)
                                    if (txIn.PrevTxBlockIndex == unconfirmedTxIn.PrevTxBlockIndex && txIn.PrevTxIndex == unconfirmedTxIn.PrevTxIndex && txIn.PrevTxOutputIndex == unconfirmedTxIn.PrevTxOutputIndex)
                                    {
                                        contradiction = unconfirmedTx.Key;

                                        break;
                                    }

                                if (contradiction != null)
                                    break;
                            }

                            if (contradiction != null)
                                unconfirmedTtxs.Remove(contradiction);
                        }

                Mine();
            };

            Mine();

            //creaNodeTest = new CreaNode(ps.NodePort, creaVersion, appnameWithVersion, new FirstNodeInfosDatabase(p2pDirectory));
            creaNodeTest = new CreaNodeTest(blockChain, ps.NodePort, creaVersion, appnameWithVersion);
            creaNodeTest.ConnectionKeeped += (sender, e) => creaNodeTest.SyncronizeBlockchain();
            creaNodeTest.ReceivedNewTransaction += (sender, e) =>
            {
                TransferTransaction ttx = e as TransferTransaction;

                if (ttx == null)
                    return;

                TransactionOutput[] prevTxOuts = new TransactionOutput[ttx.TxInputs.Length];
                for (int i = 0; i < prevTxOuts.Length; i++)
                    prevTxOuts[i] = blockChain.GetMainBlock(ttx.TxInputs[i].PrevTxBlockIndex).Transactions[ttx.TxInputs[i].PrevTxIndex].TxOutputs[ttx.TxInputs[i].PrevTxOutputIndex];

                if (!ttx.Verify(prevTxOuts))
                    return;

                List<TransactionOutput> senders = new List<TransactionOutput>();
                List<TransactionOutput> receivers = new List<TransactionOutput>();

                long sentAmount = 0;
                long receivedAmount = 0;

                for (int i = 0; i < ttx.txInputs.Length; i++)
                    foreach (var accountHolder in accountHolders.AllAccountHolders)
                        foreach (var account in accountHolder.Accounts)
                            if (prevTxOuts[i].Address.Equals(account.Address.Hash))
                            {
                                sentAmount += prevTxOuts[i].Amount.rawAmount;

                                senders.Add(prevTxOuts[i]);
                            }

                for (int i = 0; i < ttx.TxOutputs.Length; i++)
                    foreach (var accountHolder in accountHolders.AllAccountHolders)
                        foreach (var account in accountHolder.Accounts)
                            if (ttx.TxOutputs[i].Address.Equals(account.Address.Hash))
                            {
                                receivedAmount += ttx.TxOutputs[i].Amount.rawAmount;

                                receivers.Add(ttx.TxOutputs[i]);
                            }

                if (senders.Count > 0 || receivers.Count > 0)
                {
                    TransactionHistoryType type = TransactionHistoryType.transfered;
                    if (receivers.Count < ttx.TxOutputs.Length)
                        type = TransactionHistoryType.sent;
                    else if (senders.Count < ttx.TxInputs.Length)
                        type = TransactionHistoryType.received;

                    transactionHistories.AddTransactionHistory(new TransactionHistory(true, false, type, DateTime.MinValue, 0, ttx.Id, senders.ToArray(), receivers.ToArray(), ttx, prevTxOuts, new CurrencyUnit(sentAmount), new CurrencyUnit(receivedAmount - sentAmount)));
                }

                utxodb.Open();

                for (int i = 0; i < ttx.TxInputs.Length; i++)
                    if (blockChain.FindUtxo(prevTxOuts[i].Address, ttx.TxInputs[i].PrevTxBlockIndex, ttx.TxInputs[i].PrevTxIndex, ttx.TxInputs[i].PrevTxOutputIndex) == null)
                        return;

                utxodb.Close();

                foreach (var txIn in ttx.TxInputs)
                    foreach (var unconfirmedTtx in unconfirmedTtxs)
                        foreach (var unconfirmedTxIn in unconfirmedTtx.Key.TxInputs)
                            if (txIn.PrevTxBlockIndex == unconfirmedTxIn.PrevTxBlockIndex && txIn.PrevTxIndex == unconfirmedTxIn.PrevTxIndex && txIn.PrevTxOutputIndex == unconfirmedTxIn.PrevTxOutputIndex)
                                return;

                unconfirmedTtxs.Add(ttx, prevTxOuts);

                Mine();
            };
            creaNodeTest.ReceivedNewBlock += (sender, e) => blockChain.UpdateChain(e).Pipe((ret) => this.RaiseResult("blockchain_update", 5, ret.ToString()));
            //creaNodeTest.Start();

            isSystemStarted = true;
        }
예제 #2
0
파일: CoreTest.cs 프로젝트: pizyumi/CREA
        //BlockChainのテスト(分岐がある場合・採掘・後ろが無効な場合)
        public static void Test24()
        {
            string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath);
            string bcadbPath = bcadb.GetPath();

            if (File.Exists(bcadbPath))
                File.Delete(bcadbPath);

            BlockManagerDB bmdb = new BlockManagerDB(basepath);
            string bmdbPath = bmdb.GetPath();

            if (File.Exists(bmdbPath))
                File.Delete(bmdbPath);

            BlockDB bdb = new BlockDB(basepath);
            string bdbPath = bdb.GetPath(0);

            if (File.Exists(bdbPath))
                File.Delete(bdbPath);

            BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath);
            string bfpPath = bfpdb.GetPath();

            if (File.Exists(bfpPath))
                File.Delete(bfpPath);

            UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath);
            string ufadbPath = ufadb.GetPath();

            if (File.Exists(ufadbPath))
                File.Delete(ufadbPath);

            UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath);
            string ufpdbPath = ufpdb.GetPath();

            if (File.Exists(ufpdbPath))
                File.Delete(ufpdbPath);

            UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath);
            string ufptempdbPath = ufptempdb.GetPath();

            if (File.Exists(ufptempdbPath))
                File.Delete(ufptempdbPath);

            UtxoDB utxodb = new UtxoDB(basepath);
            string utxodbPath = utxodb.GetPath();

            if (File.Exists(utxodbPath))
                File.Delete(utxodbPath);

            BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb, 100, 300, 1000, 1000);

            BlockGenerator bg = new BlockGenerator();

            Block[] blks = new Block[10];
            BlockContext[] blkCons = new BlockContext[blks.Length];
            for (int i = 0; i < blks.Length; i++)
            {
                blkCons[i] = bg.CreateNextValidBlock();
                blks[i] = blkCons[i].block;

                Console.WriteLine("block" + i.ToString() + " created.");
            }

            Block[] blks2 = new Block[blks.Length];
            double cumulativeDiff1 = 0.0;
            byte[] nonce = null;

            Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock;

            for (int i = 0; i < blks.Length; i++)
            {
                if (i == 0)
                {
                    blks2[i] = blks[i];
                    cumulativeDiff1 += blks2[i].Difficulty.Diff;

                    Console.WriteLine("block" + i.ToString() + "_1 " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString());

                    continue;
                }

                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk2.UpdateTimestamp(DateTime.Now);
                    tblk2.UpdateNonce(nonce);

                    if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0)
                    {
                        blks2[i] = tblk2;
                        cumulativeDiff1 += blks2[i].Difficulty.Diff;

                        Console.WriteLine("block" + i.ToString() + "_1 mined. " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString());

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            TransactionalBlock tblk2_1 = blks2[1] as TransactionalBlock;
            TransactionalBlock tblk2_2 = blks2[2] as TransactionalBlock;

            TransactionalBlock blk3_2 = TransactionalBlock.GetBlockTemplate(2, tblk2_2.coinbaseTxToMiner, tblk2_2.transferTxs, _indexToBlock, 0);

            while (true)
            {
                blk3_2.UpdateTimestamp(DateTime.Now);
                blk3_2.UpdateNonce(nonce);

                if (blk3_2.Id.CompareTo(blk3_2.header.difficulty.Target) <= 0)
                {
                    Console.WriteLine("block3_2 mined. " + blk3_2.Difficulty.Diff.ToString());

                    break;
                }

                int index = nonce.Length.RandomNum();
                int value = 256.RandomNum();

                nonce[index] = (byte)value;
            }

            BlockHeader bh3 = new BlockHeader();
            bh3.LoadVersion0(3, blk3_2.Id, DateTime.Now, blks2[1].Difficulty, new byte[10]);
            NormalBlock blk3_3 = new NormalBlock();
            blk3_3.LoadVersion0(bh3, tblk2_1.coinbaseTxToMiner, tblk2_1.transferTxs);
            blk3_3.UpdateMerkleRootHash();

            int forkLength = (int)Math.Floor(cumulativeDiff1 / blks2[1].Difficulty.Diff + 10);

            TransactionalBlock[] blks3 = new TransactionalBlock[forkLength];

            blks3[0] = blk3_3;

            for (int i = 1; i < blks3.Length; i++)
            {
                BlockHeader bh = new BlockHeader();
                bh.LoadVersion0(i + 3, blks3[i - 1].Id, DateTime.Now, blks2[1].Difficulty, new byte[10]);
                NormalBlock blk3 = new NormalBlock();
                blk3.LoadVersion0(bh, tblk2_1.coinbaseTxToMiner, tblk2_1.transferTxs);
                blk3.UpdateMerkleRootHash();

                blks3[i] = blk3;
            }

            BlockHeader bh4 = new BlockHeader();
            bh4.LoadVersion0(4, blk3_3.Id, DateTime.Now, blks2[1].Difficulty, new byte[10]);
            NormalBlock blk4 = new NormalBlock();
            blk4.LoadVersion0(bh4, tblk2_1.coinbaseTxToMiner, tblk2_1.transferTxs);
            blk4.UpdateMerkleRootHash();

            BlockHeader bh10 = new BlockHeader();
            bh10.LoadVersion0(10, blks2[9].Id, DateTime.Now, blks2[1].Difficulty, new byte[10]);
            NormalBlock blk5_10 = new NormalBlock();
            blk5_10.LoadVersion0(bh10, tblk2_1.coinbaseTxToMiner, tblk2_1.transferTxs);
            blk5_10.UpdateMerkleRootHash();

            TransactionalBlock[] blks5 = new TransactionalBlock[5];

            blks5[0] = blk5_10;

            for (int i = 1; i < blks5.Length; i++)
            {
                BlockHeader bh = new BlockHeader();
                bh.LoadVersion0(i + 10, blks5[i - 1].Id, DateTime.Now, blks2[1].Difficulty, new byte[10]);
                NormalBlock blk5 = new NormalBlock();
                blk5.LoadVersion0(bh, tblk2_1.coinbaseTxToMiner, tblk2_1.transferTxs);
                blk5.UpdateMerkleRootHash();

                blks5[i] = blk5;
            }

            BlockChain.UpdateChainReturnType type5 = blockchain.UpdateChain(blks2[0]);

            if (type5 != BlockChain.UpdateChainReturnType.updated)
                throw new Exception("test24_5");

            BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blk4);

            if (type != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test24_1");

            for (int i = 2; i < blks2.Length; i++)
            {
                BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blks2[i]);

                if (type2 != BlockChain.UpdateChainReturnType.pending)
                    throw new Exception("test24_2");
            }

            for (int i = 0; i < blks5.Length; i++)
            {
                BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blks5[i]);

                if (type2 != BlockChain.UpdateChainReturnType.pending)
                    throw new Exception("test24_3");
            }

            BlockChain.UpdateChainReturnType type3 = blockchain.UpdateChain(blk3_2);

            if (type3 != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test24_1");

            for (int i = 0; i < blks3.Length; i++)
            {
                BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blks3[i]);

                if (type2 != BlockChain.UpdateChainReturnType.pending)
                    throw new Exception("test24_4");
            }

            BlockChain.UpdateChainReturnType type4 = blockchain.UpdateChain(blks2[1]);

            if (type4 != BlockChain.UpdateChainReturnType.updatedAndRejected)
                throw new Exception("test24_6");
            if (blockchain.blocksCurrent.value != 10)
                throw new Exception("test19_2");

            Console.WriteLine("test24_succeeded");
        }
예제 #3
0
파일: CoreTest.cs 프로젝트: pizyumi/CREA
        //2014/12/17追加 BlockChainの試験(口座残高)
        public static void Test25()
        {
            string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath);
            string bcadbPath = bcadb.GetPath();

            if (File.Exists(bcadbPath))
                File.Delete(bcadbPath);

            BlockManagerDB bmdb = new BlockManagerDB(basepath);
            string bmdbPath = bmdb.GetPath();

            if (File.Exists(bmdbPath))
                File.Delete(bmdbPath);

            BlockDB bdb = new BlockDB(basepath);
            string bdbPath = bdb.GetPath(0);

            if (File.Exists(bdbPath))
                File.Delete(bdbPath);

            BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath);
            string bfpPath = bfpdb.GetPath();

            if (File.Exists(bfpPath))
                File.Delete(bfpPath);

            UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath);
            string ufadbPath = ufadb.GetPath();

            if (File.Exists(ufadbPath))
                File.Delete(ufadbPath);

            UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath);
            string ufpdbPath = ufpdb.GetPath();

            if (File.Exists(ufpdbPath))
                File.Delete(ufpdbPath);

            UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath);
            string ufptempdbPath = ufptempdb.GetPath();

            if (File.Exists(ufptempdbPath))
                File.Delete(ufptempdbPath);

            UtxoDB utxodb = new UtxoDB(basepath);
            string utxodbPath = utxodb.GetPath();

            if (File.Exists(utxodbPath))
                File.Delete(utxodbPath);

            BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb);

            BlockGenerator bg = new BlockGenerator();

            Block[] blks = new Block[10];
            BlockContext[] blkCons = new BlockContext[blks.Length];
            for (int i = 0; i < blks.Length; i++)
            {
                blkCons[i] = bg.CreateNextValidBlock();
                blks[i] = blkCons[i].block;

                Console.WriteLine("block" + i.ToString() + " created.");
            }

            Block[] blks2 = new Block[blks.Length];
            byte[] nonce = null;

            Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock;

            for (int i = 0; i < blks.Length; i++)
            {
                if (i == 0)
                {
                    blks2[i] = blks[i];

                    continue;
                }

                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk2.UpdateTimestamp(DateTime.Now);
                    tblk2.UpdateNonce(nonce);

                    if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0)
                    {
                        blks2[i] = tblk2;

                        Console.WriteLine("block" + i.ToString() + " mined.");

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            if (blockchain.registeredAddresses.Count != 0)
                throw new Exception("test25_1");

            AddressEvent ae = new AddressEvent(new Sha256Ripemd160Hash());

            blockchain.AddAddressEvent(ae);

            if (blockchain.registeredAddresses.Count != 1)
                throw new Exception("test25_2");
            if (!blockchain.registeredAddresses.Keys.Contains(ae))
                throw new Exception("test25_3");
            if (blockchain.registeredAddresses[ae].Count != 0)
                throw new Exception("test25_4");

            AddressEvent aeret = blockchain.RemoveAddressEvent(new Sha256Ripemd160Hash());

            if (ae != aeret)
                throw new Exception("test25_5");
            if (blockchain.registeredAddresses.Count != 0)
                throw new Exception("test25_6");

            blockchain.AddAddressEvent(ae);

            Dictionary<Sha256Ripemd160Hash, Tuple<CurrencyUnit, CurrencyUnit>> balances = new Dictionary<Sha256Ripemd160Hash, Tuple<CurrencyUnit, CurrencyUnit>>();

            foreach (var address in bg.addresses)
            {
                AddressEvent addressEvent = new AddressEvent(address);
                addressEvent.BalanceUpdated += (sender, e) =>
                {
                    balances[addressEvent.address] = e;
                };

                blockchain.AddAddressEvent(addressEvent);
            }

            int counter = 0;
            blockchain.BalanceUpdated += (sender, e) =>
            {
                counter++;
            };

            for (int i = 0; i < blks.Length; i++)
            {
                blockchain.UpdateChain(blks2[i]);

                if (counter != i)
                    throw new Exception("test25_7");

                foreach (var address in bg.addresses)
                {
                    long usable = 0;
                    long unusable = 0;

                    foreach (var txoutcon in blkCons[i].unspentTxOuts[address])
                        if (txoutcon.bIndex + 6 > i)
                            unusable += txoutcon.amount.rawAmount;
                        else
                            usable += txoutcon.amount.rawAmount;

                    if (balances[address].Item1.rawAmount != usable)
                        throw new Exception("test25_2");
                    if (balances[address].Item2.rawAmount != unusable)
                        throw new Exception("test25_2");
                }
            }

            Console.WriteLine("test25_succeeded");
        }
예제 #4
0
파일: CoreTest.cs 프로젝트: pizyumi/CREA
        //BlockChainのテスト(分岐がある場合・採掘・順番通りに追加されなかった場合)
        public static void Test22()
        {
            string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath);
            string bcadbPath = bcadb.GetPath();

            if (File.Exists(bcadbPath))
                File.Delete(bcadbPath);

            BlockManagerDB bmdb = new BlockManagerDB(basepath);
            string bmdbPath = bmdb.GetPath();

            if (File.Exists(bmdbPath))
                File.Delete(bmdbPath);

            BlockDB bdb = new BlockDB(basepath);
            string bdbPath = bdb.GetPath(0);

            if (File.Exists(bdbPath))
                File.Delete(bdbPath);

            BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath);
            string bfpPath = bfpdb.GetPath();

            if (File.Exists(bfpPath))
                File.Delete(bfpPath);

            UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath);
            string ufadbPath = ufadb.GetPath();

            if (File.Exists(ufadbPath))
                File.Delete(ufadbPath);

            UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath);
            string ufpdbPath = ufpdb.GetPath();

            if (File.Exists(ufpdbPath))
                File.Delete(ufpdbPath);

            UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath);
            string ufptempdbPath = ufptempdb.GetPath();

            if (File.Exists(ufptempdbPath))
                File.Delete(ufptempdbPath);

            UtxoDB utxodb = new UtxoDB(basepath);
            string utxodbPath = utxodb.GetPath();

            if (File.Exists(utxodbPath))
                File.Delete(utxodbPath);

            BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb);

            BlockGenerator bg = new BlockGenerator();

            Block[] blks = new Block[10];
            double[] cumulativeDiffs0 = new double[blks.Length];
            BlockContext[] blkCons = new BlockContext[blks.Length];
            for (int i = 0; i < blks.Length; i++)
            {
                blkCons[i] = bg.CreateNextValidBlock();
                blks[i] = blkCons[i].block;
                cumulativeDiffs0[i] = i == 0 ? blks[i].Difficulty.Diff : cumulativeDiffs0[i - 1] + blks[i].Difficulty.Diff;

                Console.WriteLine("block" + i.ToString() + " created.");
            }

            Block[] blks2 = new Block[blks.Length];
            double[] cumulativeDiffs1 = new double[blks.Length];
            byte[] nonce = null;

            Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock;

            for (int i = 0; i < blks.Length; i++)
            {
                if (i == 0)
                {
                    blks2[i] = blks[i];
                    cumulativeDiffs1[i] = blks2[i].Difficulty.Diff;

                    Console.WriteLine("block" + i.ToString() + "_1 " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiffs1[i].ToString());

                    continue;
                }

                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk2.UpdateTimestamp(DateTime.Now);
                    tblk2.UpdateNonce(nonce);

                    if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0)
                    {
                        blks2[i] = tblk2;
                        cumulativeDiffs1[i] = cumulativeDiffs1[i - 1] + blks2[i].Difficulty.Diff;

                        Console.WriteLine("block" + i.ToString() + "_1 mined. " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiffs1[i].ToString());

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            int forkIndex1 = 0;
            int forkIndex2 = 0;

            int[] forkIndexes = (blks.Length - 1).RandomNums();
            if (forkIndexes[0] < forkIndexes[1])
            {
                forkIndex1 = forkIndexes[0] + 1;
                forkIndex2 = forkIndexes[1] + 1;
            }
            else
            {
                forkIndex1 = forkIndexes[1] + 1;
                forkIndex2 = forkIndexes[0] + 1;
            }

            Block[] blks3 = new Block[blks.Length];
            double[] cumulativeDiffs2 = new double[blks.Length];

            Func<long, TransactionalBlock> _indexToBlock2 = (index) => index >= forkIndex1 ? blks3[index] as TransactionalBlock : blks2[index] as TransactionalBlock;

            for (int i = forkIndex1; i < blks.Length; i++)
            {
                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk3 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock2, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk3.UpdateTimestamp(DateTime.Now);
                    tblk3.UpdateNonce(nonce);

                    if (tblk3.Id.CompareTo(tblk3.header.difficulty.Target) <= 0)
                    {
                        blks3[i] = tblk3;
                        if (i == forkIndex1)
                            cumulativeDiffs2[i] = cumulativeDiffs1[i - 1] + blks3[i].Difficulty.Diff;
                        else
                            cumulativeDiffs2[i] = cumulativeDiffs2[i - 1] + blks3[i].Difficulty.Diff;

                        Console.WriteLine("block" + i.ToString() + "_2 mined. " + blks3[i].Difficulty.Diff.ToString() + " " + cumulativeDiffs2[i].ToString());

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            Block[] blks4 = new Block[blks.Length];
            double[] cumulativeDiffs3 = new double[blks.Length];

            Func<long, TransactionalBlock> _indexToBlock3 = (index) => index >= forkIndex2 ? blks4[index] as TransactionalBlock : blks2[index] as TransactionalBlock;

            for (int i = forkIndex2; i < blks.Length; i++)
            {
                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk3 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock3, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk3.UpdateTimestamp(DateTime.Now);
                    tblk3.UpdateNonce(nonce);

                    if (tblk3.Id.CompareTo(tblk3.header.difficulty.Target) <= 0)
                    {
                        blks4[i] = tblk3;
                        if (i == forkIndex2)
                            cumulativeDiffs3[i] = cumulativeDiffs1[i - 1] + blks4[i].Difficulty.Diff;
                        else
                            cumulativeDiffs3[i] = cumulativeDiffs3[i - 1] + blks4[i].Difficulty.Diff;

                        Console.WriteLine("block" + i.ToString() + "_3 mined. " + blks4[i].Difficulty.Diff.ToString() + " " + cumulativeDiffs3[i].ToString());

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            bool?[] map1 = new bool?[blks.Length];
            bool?[] map2 = new bool?[blks.Length];
            bool?[] map3 = new bool?[blks.Length];
            bool?[] map4 = new bool?[blks.Length];

            for (int i = 0; i < blks.Length; i++)
            {
                map1[i] = i == 0 ? (bool?)null : false;
                map2[i] = i == 0 ? (bool?)null : false;
                map3[i] = i < forkIndex1 ? (bool?)null : false;
                map4[i] = i < forkIndex2 ? (bool?)null : false;
            }

            blockchain.UpdateChain(blks[0]);

            int[] randomnums = (4 * blks.Length).RandomNums();

            double cumulativeDiff = 0.0;
            int main = 0;
            int rejectedIndex = 0;

            for (int i = 0; i < randomnums.Length; i++)
            {
                int keiretsu = randomnums[i] / blks.Length;
                int index = randomnums[i] % blks.Length;

                if ((keiretsu == 0 && map1[index] == null) || (keiretsu == 1 && map2[index] == null) || (keiretsu == 2 && map3[index] == null) || (keiretsu == 3 && map4[index] == null))
                    continue;

                if (keiretsu == 0)
                {
                    BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks[index]);

                    bool flag = false;

                    for (int j = index - 1; j > 0; j--)
                        if (!map1[j].Value)
                        {
                            flag = true;

                            break;
                        }

                    if (!flag && index != 1)
                    {
                        if (type != BlockChain.UpdateChainReturnType.rejected)
                            throw new Exception("test22_1");
                    }
                    else
                    {
                        if (!flag)
                        {
                            int headIndex = index;
                            for (int j = index + 1; j < blks.Length; j++)
                                if (map1[j].Value)
                                    headIndex = j;
                                else
                                    break;

                            if (cumulativeDiff >= cumulativeDiffs0[headIndex])
                                flag = true;
                            else
                                rejectedIndex = headIndex;
                        }

                        if (flag && type != BlockChain.UpdateChainReturnType.pending)
                            throw new Exception("test22_2");
                        if (!flag && type != BlockChain.UpdateChainReturnType.updatedAndRejected)
                            throw new Exception("test22_3");
                    }

                    map1[index] = true;
                }
                else if (keiretsu == 1)
                {
                    BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks2[index]);

                    bool flag = false;

                    for (int j = index - 1; j > 0; j--)
                        if (!map2[j].Value)
                        {
                            flag = true;

                            break;
                        }

                    if (!flag)
                    {
                        int headIndex1 = index;
                        for (int j = index + 1; j < blks.Length; j++)
                            if (map2[j].Value)
                                headIndex1 = j;
                            else
                                break;

                        double cdiff = cumulativeDiffs1[headIndex1];
                        int m = 1;

                        if (headIndex1 + 1 >= forkIndex1 && map3[forkIndex1].Value)
                        {
                            int headIndex2 = forkIndex1;
                            for (int j = forkIndex1 + 1; j < blks.Length; j++)
                                if (map3[j].Value)
                                    headIndex2 = j;
                                else
                                    break;

                            //<未実装>等しい場合の対処
                            if (cumulativeDiffs2[headIndex2] > cdiff)
                            {
                                cdiff = cumulativeDiffs2[headIndex2];
                                m = 2;
                            }
                            else if (cumulativeDiffs2[headIndex2] == cdiff)
                            {
                                Console.WriteLine("not_implemented_test_case");

                                return;
                            }
                        }

                        if (headIndex1 + 1 >= forkIndex2 && map4[forkIndex2].Value)
                        {
                            int headIndex3 = forkIndex2;
                            for (int j = forkIndex2 + 1; j < blks.Length; j++)
                                if (map4[j].Value)
                                    headIndex3 = j;
                                else
                                    break;

                            //<未実装>等しい場合の対処
                            if (cumulativeDiffs3[headIndex3] > cdiff)
                            {
                                cdiff = cumulativeDiffs3[headIndex3];
                                m = 3;
                            }
                            else if (cumulativeDiffs3[headIndex3] == cdiff)
                            {
                                Console.WriteLine("not_implemented_test_case");

                                return;
                            }
                        }

                        if (cumulativeDiff >= cdiff)
                            flag = true;
                        else
                        {
                            cumulativeDiff = cdiff;
                            main = m;
                        }
                    }

                    if (flag && type != BlockChain.UpdateChainReturnType.pending)
                        throw new Exception("test22_4");
                    if (!flag && type != BlockChain.UpdateChainReturnType.updated)
                        throw new Exception("test22_5");

                    map2[index] = true;
                }
                else if (keiretsu == 2)
                {
                    BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks3[index]);

                    bool flag = false;

                    for (int j = index - 1; j >= forkIndex1; j--)
                        if (!map3[j].Value)
                        {
                            flag = true;

                            break;
                        }
                    if (!flag)
                        for (int j = forkIndex1 - 1; j > 0; j--)
                            if (!map2[j].Value)
                            {
                                flag = true;

                                break;
                            }

                    if (!flag)
                    {
                        int headIndex = index;
                        for (int j = index + 1; j < blks.Length; j++)
                            if (map3[j].Value)
                                headIndex = j;
                            else
                                break;

                        if (cumulativeDiff >= cumulativeDiffs2[headIndex])
                            flag = true;
                        else
                        {
                            cumulativeDiff = cumulativeDiffs2[headIndex];
                            main = 2;
                        }
                    }

                    if (flag && type != BlockChain.UpdateChainReturnType.pending)
                        throw new Exception("test22_6");
                    if (!flag && type != BlockChain.UpdateChainReturnType.updated)
                        throw new Exception("test22_7");

                    map3[index] = true;
                }
                else if (keiretsu == 3)
                {
                    BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks4[index]);

                    bool flag = false;

                    for (int j = index - 1; j >= forkIndex2; j--)
                        if (!map4[j].Value)
                        {
                            flag = true;

                            break;
                        }
                    if (!flag)
                        for (int j = forkIndex2 - 1; j > 0; j--)
                            if (!map2[j].Value)
                            {
                                flag = true;

                                break;
                            }

                    if (!flag)
                    {
                        int headIndex = index;
                        for (int j = index + 1; j < blks.Length; j++)
                            if (map4[j].Value)
                                headIndex = j;
                            else
                                break;

                        if (cumulativeDiff >= cumulativeDiffs3[headIndex])
                            flag = true;
                        else
                        {
                            cumulativeDiff = cumulativeDiffs3[headIndex];
                            main = 3;
                        }
                    }

                    if (flag && type != BlockChain.UpdateChainReturnType.pending)
                        throw new Exception("test22_8");
                    if (!flag && type != BlockChain.UpdateChainReturnType.updated)
                        throw new Exception("test22_9");

                    map4[index] = true;
                }

                bool flag2 = true;
                for (int j = 1; j < blks.Length; j++)
                {
                    if (map1[j].Value)
                    {
                        if (flag2 && j <= rejectedIndex)
                        {
                            if (blockchain.rejectedBlocks[j + 1] == null || !blockchain.rejectedBlocks[j + 1].Keys.Contains(blks[j].Id))
                                throw new Exception("test22_10");
                            if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks[j].Id))
                                throw new Exception("test22_11");
                        }
                        else
                        {
                            if (blockchain.rejectedBlocks[j + 1] != null && blockchain.rejectedBlocks[j + 1].Keys.Contains(blks[j].Id))
                                throw new Exception("test22_12");
                            if (blockchain.pendingBlocks[j + 1] == null || !blockchain.pendingBlocks[j + 1].Keys.Contains(blks[j].Id))
                                throw new Exception("test22_13");
                        }
                    }
                    else
                    {
                        flag2 = false;

                        if (blockchain.rejectedBlocks[j + 1] != null && blockchain.rejectedBlocks[j + 1].Keys.Contains(blks[j].Id))
                            throw new Exception("test22_14");
                        if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks[j].Id))
                            throw new Exception("test22_15");
                    }
                }

                bool flag3 = true;
                for (int j = 1; j < blks.Length; j++)
                {
                    if (blockchain.rejectedBlocks[j + 1] != null && blockchain.rejectedBlocks[j + 1].Keys.Contains(blks2[j].Id))
                        throw new Exception("test22_16");

                    if (map2[j].Value)
                    {
                        if (flag3 && (main == 1 || (main == 2 && j < forkIndex1) || (main == 3 && j < forkIndex2)))
                        {
                            if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks2[j].Id))
                                throw new Exception("test22_17");
                        }
                        else
                        {
                            if (blockchain.pendingBlocks[j + 1] == null || !blockchain.pendingBlocks[j + 1].Keys.Contains(blks2[j].Id))
                                throw new Exception("test22_18");
                        }
                    }
                    else
                    {
                        flag3 = false;

                        if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks2[j].Id))
                            throw new Exception("test22_19");
                    }
                }

                bool flag4 = true;
                for (int j = forkIndex1; j < blks.Length; j++)
                {
                    if (blockchain.rejectedBlocks[j + 1] != null && blockchain.rejectedBlocks[j + 1].Keys.Contains(blks3[j].Id))
                        throw new Exception("test22_20");

                    if (map3[j].Value)
                    {
                        if (flag4 && main == 2)
                        {
                            if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks3[j].Id))
                                throw new Exception("test22_21");
                        }
                        else
                        {
                            if (blockchain.pendingBlocks[j + 1] == null || !blockchain.pendingBlocks[j + 1].Keys.Contains(blks3[j].Id))
                                throw new Exception("test22_22");
                        }
                    }
                    else
                    {
                        flag4 = false;

                        if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks3[j].Id))
                            throw new Exception("test22_23");
                    }
                }

                bool flag5 = true;
                for (int j = forkIndex2; j < blks.Length; j++)
                {
                    if (blockchain.rejectedBlocks[j + 1] != null && blockchain.rejectedBlocks[j + 1].Keys.Contains(blks4[j].Id))
                        throw new Exception("test22_24");

                    if (map4[j].Value)
                    {
                        if (flag5 && main == 3)
                        {
                            if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks4[j].Id))
                                throw new Exception("test22_25");
                        }
                        else
                        {
                            if (blockchain.pendingBlocks[j + 1] == null || !blockchain.pendingBlocks[j + 1].Keys.Contains(blks4[j].Id))
                                throw new Exception("test22_26");
                        }
                    }
                    else
                    {
                        flag5 = false;

                        if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks4[j].Id))
                            throw new Exception("test22_27");
                    }
                }
            }

            Block headBlock = blockchain.GetHeadBlock();

            if (main == 1)
            {
                if (!headBlock.Id.Equals(blks2[9].Id))
                    throw new Exception("test22_28");
            }
            else if (main == 2)
            {
                if (!headBlock.Id.Equals(blks3[9].Id))
                    throw new Exception("test22_29");
            }
            else if (main == 3)
            {
                if (!headBlock.Id.Equals(blks4[9].Id))
                    throw new Exception("test22_30");
            }
            else
                throw new InvalidOperationException();

            utxodb.Open();

            foreach (var address in blkCons[9].unspentTxOuts.Keys)
                foreach (var toc in blkCons[9].unspentTxOuts[address])
                    if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) == null)
                        throw new Exception("test22_31");

            foreach (var address in blkCons[9].spentTxOuts.Keys)
                foreach (var toc in blkCons[9].spentTxOuts[address])
                    if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) != null)
                        throw new Exception("test22_32");

            utxodb.Close();

            Console.WriteLine("test22_succeeded");
        }
예제 #5
0
파일: CoreTest.cs 프로젝트: pizyumi/CREA
        //BlockChainのテスト(分岐がある場合・採掘・長過ぎる場合)
        public static void Test23()
        {
            string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath);
            string bcadbPath = bcadb.GetPath();

            if (File.Exists(bcadbPath))
                File.Delete(bcadbPath);

            BlockManagerDB bmdb = new BlockManagerDB(basepath);
            string bmdbPath = bmdb.GetPath();

            if (File.Exists(bmdbPath))
                File.Delete(bmdbPath);

            BlockDB bdb = new BlockDB(basepath);
            string bdbPath = bdb.GetPath(0);

            if (File.Exists(bdbPath))
                File.Delete(bdbPath);

            BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath);
            string bfpPath = bfpdb.GetPath();

            if (File.Exists(bfpPath))
                File.Delete(bfpPath);

            UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath);
            string ufadbPath = ufadb.GetPath();

            if (File.Exists(ufadbPath))
                File.Delete(ufadbPath);

            UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath);
            string ufpdbPath = ufpdb.GetPath();

            if (File.Exists(ufpdbPath))
                File.Delete(ufpdbPath);

            UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath);
            string ufptempdbPath = ufptempdb.GetPath();

            if (File.Exists(ufptempdbPath))
                File.Delete(ufptempdbPath);

            UtxoDB utxodb = new UtxoDB(basepath);
            string utxodbPath = utxodb.GetPath();

            if (File.Exists(utxodbPath))
                File.Delete(utxodbPath);

            BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb, 100, 3, 1000, 1000);

            BlockGenerator bg = new BlockGenerator();

            Block[] blks = new Block[10];
            BlockContext[] blkCons = new BlockContext[blks.Length];
            for (int i = 0; i < blks.Length; i++)
            {
                blkCons[i] = bg.CreateNextValidBlock();
                blks[i] = blkCons[i].block;

                Console.WriteLine("block" + i.ToString() + " created.");
            }

            Block[] blks2 = new Block[blks.Length];
            double cumulativeDiff1 = 0.0;
            byte[] nonce = null;

            Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock;

            for (int i = 0; i < blks.Length; i++)
            {
                if (i == 0)
                {
                    blks2[i] = blks[i];
                    cumulativeDiff1 += blks2[i].Difficulty.Diff;

                    Console.WriteLine("block" + i.ToString() + "_1 " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString());

                    continue;
                }

                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk2.UpdateTimestamp(DateTime.Now);
                    tblk2.UpdateNonce(nonce);

                    if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0)
                    {
                        blks2[i] = tblk2;
                        cumulativeDiff1 += blks2[i].Difficulty.Diff;

                        Console.WriteLine("block" + i.ToString() + "_1 mined. " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString());

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            Console.WriteLine();

            Block[] blks3 = new Block[blks.Length];
            double cumulativeDiff2 = 0.0;

            Func<long, TransactionalBlock> _indexToBlock2 = (index) => blks3[index] as TransactionalBlock;

            for (int i = 0; i < blks.Length; i++)
            {
                if (i == 0)
                {
                    blks3[i] = blks[i];
                    cumulativeDiff2 += blks3[i].Difficulty.Diff;

                    Console.WriteLine("block" + i.ToString() + "_2 " + blks3[i].Difficulty.Diff.ToString() + " " + cumulativeDiff2.ToString());

                    continue;
                }

                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk3 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock2, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk3.UpdateTimestamp(DateTime.Now);
                    tblk3.UpdateNonce(nonce);

                    if (tblk3.Id.CompareTo(tblk3.header.difficulty.Target) <= 0)
                    {
                        blks3[i] = tblk3;
                        cumulativeDiff2 += blks3[i].Difficulty.Diff;

                        Console.WriteLine("block" + i.ToString() + "_2 mined. " + blks3[i].Difficulty.Diff.ToString() + " " + cumulativeDiff2.ToString());

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            for (int i = 0; i < blks.Length; i++)
                blockchain.UpdateChain(blks2[i]);

            for (int i = blks.Length - 1; i >= blks.Length - 3; i--)
            {
                BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks3[i]);

                if (i == blks.Length - 3)
                {
                    if (type != BlockChain.UpdateChainReturnType.rejected)
                        throw new Exception("test23_1");

                    for (int j = 0; j < blks.Length - 3; j++)
                        if (blockchain.rejectedBlocks[j + 1] != null)
                            throw new Exception("test23_2");
                    for (int j = blks.Length - 3; j < blks.Length; j++)
                        if (blockchain.rejectedBlocks[j + 1] == null || !blockchain.rejectedBlocks[j + 1].Keys.Contains(blks3[j].Id))
                            throw new Exception("test23_3");

                    for (int j = 0; j <= blks.Length - 3; j++)
                        if (blockchain.pendingBlocks[j + 1] != null)
                            throw new Exception("test23_4");
                    for (int j = blks.Length - 3 + 1; j < blks.Length; j++)
                        if (blockchain.pendingBlocks[j + 1] == null || blockchain.pendingBlocks[j + 1].Keys.Count != 0)
                            throw new Exception("test23_5");
                }
                else
                {
                    if (type != BlockChain.UpdateChainReturnType.pending)
                        throw new Exception("test23_6");
                }
            }

            Console.WriteLine("test23_succeeded");
        }
예제 #6
0
파일: CoreTest.cs 프로젝트: pizyumi/CREA
        //BlockChainのテスト(分岐がある場合・採掘・交互に追加していく場合)
        public static void Test21()
        {
            string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath);
            string bcadbPath = bcadb.GetPath();

            if (File.Exists(bcadbPath))
                File.Delete(bcadbPath);

            BlockManagerDB bmdb = new BlockManagerDB(basepath);
            string bmdbPath = bmdb.GetPath();

            if (File.Exists(bmdbPath))
                File.Delete(bmdbPath);

            BlockDB bdb = new BlockDB(basepath);
            string bdbPath = bdb.GetPath(0);

            if (File.Exists(bdbPath))
                File.Delete(bdbPath);

            BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath);
            string bfpPath = bfpdb.GetPath();

            if (File.Exists(bfpPath))
                File.Delete(bfpPath);

            UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath);
            string ufadbPath = ufadb.GetPath();

            if (File.Exists(ufadbPath))
                File.Delete(ufadbPath);

            UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath);
            string ufpdbPath = ufpdb.GetPath();

            if (File.Exists(ufpdbPath))
                File.Delete(ufpdbPath);

            UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath);
            string ufptempdbPath = ufptempdb.GetPath();

            if (File.Exists(ufptempdbPath))
                File.Delete(ufptempdbPath);

            UtxoDB utxodb = new UtxoDB(basepath);
            string utxodbPath = utxodb.GetPath();

            if (File.Exists(utxodbPath))
                File.Delete(utxodbPath);

            BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb);

            BlockGenerator bg = new BlockGenerator();

            Block[] blks = new Block[10];
            BlockContext[] blkCons = new BlockContext[blks.Length];
            for (int i = 0; i < blks.Length; i++)
            {
                blkCons[i] = bg.CreateNextValidBlock();
                blks[i] = blkCons[i].block;

                Console.WriteLine("block" + i.ToString() + " created.");
            }

            Block[] blks2 = new Block[blks.Length];
            double cumulativeDiff1 = 0.0;
            byte[] nonce = null;

            Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock;

            for (int i = 0; i < blks.Length; i++)
            {
                if (i == 0)
                {
                    blks2[i] = blks[i];
                    cumulativeDiff1 += blks2[i].Difficulty.Diff;

                    Console.WriteLine("block" + i.ToString() + "_1 " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString());

                    continue;
                }

                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk2.UpdateTimestamp(DateTime.Now);
                    tblk2.UpdateNonce(nonce);

                    if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0)
                    {
                        blks2[i] = tblk2;
                        cumulativeDiff1 += blks2[i].Difficulty.Diff;

                        Console.WriteLine("block" + i.ToString() + "_1 mined. " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString());

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            Console.WriteLine();

            Block[] blks3 = new Block[blks.Length];
            double cumulativeDiff2 = 0.0;

            Func<long, TransactionalBlock> _indexToBlock2 = (index) => blks3[index] as TransactionalBlock;

            for (int i = 0; i < blks.Length; i++)
            {
                if (i == 0)
                {
                    blks3[i] = blks[i];
                    cumulativeDiff2 += blks3[i].Difficulty.Diff;

                    Console.WriteLine("block" + i.ToString() + "_2 " + blks3[i].Difficulty.Diff.ToString() + " " + cumulativeDiff2.ToString());

                    continue;
                }

                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk3 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock2, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk3.UpdateTimestamp(DateTime.Now);
                    tblk3.UpdateNonce(nonce);

                    if (tblk3.Id.CompareTo(tblk3.header.difficulty.Target) <= 0)
                    {
                        blks3[i] = tblk3;
                        cumulativeDiff2 += blks3[i].Difficulty.Diff;

                        Console.WriteLine("block" + i.ToString() + "_2 mined. " + blks3[i].Difficulty.Diff.ToString() + " " + cumulativeDiff2.ToString());

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            cumulativeDiff1 = 0.0;
            cumulativeDiff2 = 0.0;

            blockchain.UpdateChain(blks2[0]);

            for (int i = 1; i < blks.Length; i++)
            {
                cumulativeDiff1 += blks2[i].Difficulty.Diff;

                BlockChain.UpdateChainReturnType type1 = blockchain.UpdateChain(blks2[i]);

                if (cumulativeDiff1 > cumulativeDiff2)
                {
                    if (type1 != BlockChain.UpdateChainReturnType.updated)
                        throw new Exception("test21_1");
                }
                else
                {
                    if (type1 != BlockChain.UpdateChainReturnType.pending)
                        throw new Exception("test21_3");
                }

                cumulativeDiff2 += blks3[i].Difficulty.Diff;

                BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blks3[i]);

                if (cumulativeDiff2 > cumulativeDiff1)
                {
                    if (type2 != BlockChain.UpdateChainReturnType.updated)
                        throw new Exception("test21_2");
                }
                else
                {
                    if (type2 != BlockChain.UpdateChainReturnType.pending)
                        throw new Exception("test21_4");
                }
            }

            utxodb.Open();

            foreach (var address in blkCons[9].unspentTxOuts.Keys)
                foreach (var toc in blkCons[9].unspentTxOuts[address])
                    if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) == null)
                        throw new Exception("test21_5");

            foreach (var address in blkCons[9].spentTxOuts.Keys)
                foreach (var toc in blkCons[9].spentTxOuts[address])
                    if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) != null)
                        throw new Exception("test21_6");

            utxodb.Close();

            Console.WriteLine("test21_succeeded");
        }
예제 #7
0
파일: CoreTest.cs 프로젝트: pizyumi/CREA
        //BlockChainのテスト(分岐がない場合・採掘・順番通りに追加されなかった場合)
        public static void Test19()
        {
            string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath);
            string bcadbPath = bcadb.GetPath();

            if (File.Exists(bcadbPath))
                File.Delete(bcadbPath);

            BlockManagerDB bmdb = new BlockManagerDB(basepath);
            string bmdbPath = bmdb.GetPath();

            if (File.Exists(bmdbPath))
                File.Delete(bmdbPath);

            BlockDB bdb = new BlockDB(basepath);
            string bdbPath = bdb.GetPath(0);

            if (File.Exists(bdbPath))
                File.Delete(bdbPath);

            BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath);
            string bfpPath = bfpdb.GetPath();

            if (File.Exists(bfpPath))
                File.Delete(bfpPath);

            UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath);
            string ufadbPath = ufadb.GetPath();

            if (File.Exists(ufadbPath))
                File.Delete(ufadbPath);

            UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath);
            string ufpdbPath = ufpdb.GetPath();

            if (File.Exists(ufpdbPath))
                File.Delete(ufpdbPath);

            UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath);
            string ufptempdbPath = ufptempdb.GetPath();

            if (File.Exists(ufptempdbPath))
                File.Delete(ufptempdbPath);

            UtxoDB utxodb = new UtxoDB(basepath);
            string utxodbPath = utxodb.GetPath();

            if (File.Exists(utxodbPath))
                File.Delete(utxodbPath);

            BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb);

            BlockGenerator bg = new BlockGenerator();

            Block[] blks = new Block[8];
            BlockContext[] blkCons = new BlockContext[blks.Length];
            for (int i = 0; i < blks.Length; i++)
            {
                blkCons[i] = bg.CreateNextValidBlock();
                blks[i] = blkCons[i].block;

                Console.WriteLine("block" + i.ToString() + " created.");
            }

            Block[] blks2 = new Block[blks.Length];
            byte[] nonce = null;

            Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock;

            for (int i = 0; i < blks.Length; i++)
            {
                if (i == 0)
                {
                    blks2[i] = blks[i];

                    continue;
                }

                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk2.UpdateTimestamp(DateTime.Now);
                    tblk2.UpdateNonce(nonce);

                    if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0)
                    {
                        blks2[i] = tblk2;

                        Console.WriteLine("block" + i.ToString() + " mined.");

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks2[2]);

            if (type != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test19_1");

            if (blockchain.blocksCurrent.value != 0)
                throw new Exception("test19_2");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (i == 3)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test19_3");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test19_4");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blks2[2].Id))
                        throw new Exception("test19_5");
                }
                else
                {
                    if (blockchain.pendingBlocks[i] != null)
                        throw new Exception("test19_6");
                }

                if (blockchain.rejectedBlocks[i] != null)
                    throw new Exception("test19_7");
            }

            BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blks2[1]);

            if (type2 != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test19_8");

            if (blockchain.blocksCurrent.value != 0)
                throw new Exception("test19_9");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (i == 2)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test19_10");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test19_11");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blks2[1].Id))
                        throw new Exception("test19_12");
                }
                else if (i == 3)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test19_13");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test19_14");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blks2[2].Id))
                        throw new Exception("test19_15");
                }
                else
                {
                    if (blockchain.pendingBlocks[i] != null)
                        throw new Exception("test19_16");
                }

                if (blockchain.rejectedBlocks[i] != null)
                    throw new Exception("test19_17");
            }

            BlockChain.UpdateChainReturnType type3 = blockchain.UpdateChain(blks2[0]);

            if (type3 != BlockChain.UpdateChainReturnType.updated)
                throw new Exception("test19_18");
            if (blockchain.headBlockIndex != 2)
                throw new Exception("test19_19");

            if (blockchain.blocksCurrent.value != 3)
                throw new Exception("test19_20");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (i == 2 || i == 3)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test19_21");
                    if (blockchain.pendingBlocks[i].Count != 0)
                        throw new Exception("test19_22");
                }
                else
                {
                    if (blockchain.pendingBlocks[i] != null)
                        throw new Exception("test19_23");
                }

                if (blockchain.rejectedBlocks[i] != null)
                    throw new Exception("test19_24");
            }

            BlockChain.UpdateChainReturnType type4 = blockchain.UpdateChain(blks2[6]);
            BlockChain.UpdateChainReturnType type5 = blockchain.UpdateChain(blks2[7]);
            BlockChain.UpdateChainReturnType type6 = blockchain.UpdateChain(blks2[4]);
            BlockChain.UpdateChainReturnType type7 = blockchain.UpdateChain(blks2[5]);
            BlockChain.UpdateChainReturnType type8 = blockchain.UpdateChain(blks2[3]);

            if (type4 != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test19_25");
            if (type5 != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test19_26");
            if (type6 != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test19_27");
            if (type7 != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test19_28");
            if (type8 != BlockChain.UpdateChainReturnType.updated)
                throw new Exception("test19_29");
            if (blockchain.headBlockIndex != 7)
                throw new Exception("test19_30");

            utxodb.Open();

            foreach (var address in blkCons[7].unspentTxOuts.Keys)
                foreach (var toc in blkCons[7].unspentTxOuts[address])
                    if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) == null)
                        throw new Exception("test19_31");

            foreach (var address in blkCons[7].spentTxOuts.Keys)
                foreach (var toc in blkCons[7].spentTxOuts[address])
                    if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) != null)
                        throw new Exception("test19_32");

            utxodb.Close();

            Console.WriteLine("test19_succeeded");
        }
예제 #8
0
파일: CoreTest.cs 프로젝트: pizyumi/CREA
        //BlockChainのテスト(分岐がない場合・無効ブロックなどを追加しようとした場合)
        public static void Test18()
        {
            string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath);
            string bcadbPath = bcadb.GetPath();

            if (File.Exists(bcadbPath))
                File.Delete(bcadbPath);

            BlockManagerDB bmdb = new BlockManagerDB(basepath);
            string bmdbPath = bmdb.GetPath();

            if (File.Exists(bmdbPath))
                File.Delete(bmdbPath);

            BlockDB bdb = new BlockDB(basepath);
            string bdbPath = bdb.GetPath(0);

            if (File.Exists(bdbPath))
                File.Delete(bdbPath);

            BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath);
            string bfpPath = bfpdb.GetPath();

            if (File.Exists(bfpPath))
                File.Delete(bfpPath);

            UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath);
            string ufadbPath = ufadb.GetPath();

            if (File.Exists(ufadbPath))
                File.Delete(ufadbPath);

            UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath);
            string ufpdbPath = ufpdb.GetPath();

            if (File.Exists(ufpdbPath))
                File.Delete(ufpdbPath);

            UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath);
            string ufptempdbPath = ufptempdb.GetPath();

            if (File.Exists(ufptempdbPath))
                File.Delete(ufptempdbPath);

            UtxoDB utxodb = new UtxoDB(basepath);
            string utxodbPath = utxodb.GetPath();

            if (File.Exists(utxodbPath))
                File.Delete(utxodbPath);

            BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb);

            BlockGenerator bg = new BlockGenerator();

            Block[] blks = new Block[10];
            BlockContext[] blkCons = new BlockContext[blks.Length];
            for (int i = 0; i < blks.Length; i++)
            {
                blkCons[i] = bg.CreateNextValidBlock();
                blks[i] = blkCons[i].block;

                Console.WriteLine("block" + i.ToString() + " created.");
            }

            Block[] blks2 = new Block[blks.Length];
            byte[] nonce = null;

            Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock;

            for (int i = 0; i < blks.Length; i++)
            {
                if (i == 0)
                {
                    blks2[i] = blks[i];

                    continue;
                }

                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk2.UpdateTimestamp(DateTime.Now);
                    tblk2.UpdateNonce(nonce);

                    if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0)
                    {
                        blks2[i] = tblk2;

                        Console.WriteLine("block" + i.ToString() + " mined.");

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            if (blockchain.blocksCurrent.value != 0)
                throw new Exception("test18_1");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (blockchain.pendingBlocks[i] != null)
                    throw new Exception("test18_2");
                if (blockchain.rejectedBlocks[i] != null)
                    throw new Exception("test18_3");
            }

            TransactionalBlock blk1 = blks2[1] as TransactionalBlock;
            TransactionalBlock blk2 = blks2[2] as TransactionalBlock;

            Creahash hashzero = new Creahash();

            BlockHeader bh5 = new BlockHeader();
            bh5.LoadVersion0(100, hashzero, DateTime.Now, blk1.Difficulty, new byte[10]);

            BlockHeader bh6 = new BlockHeader();
            bh6.LoadVersion0(101, hashzero, DateTime.Now, blk1.Difficulty, new byte[10]);

            TransactionalBlock blk100 = new NormalBlock();
            blk100.LoadVersion0(bh5, blk1.coinbaseTxToMiner, blk1.transferTxs);
            blk100.UpdateMerkleRootHash();

            TransactionalBlock blk101 = new NormalBlock();
            blk101.LoadVersion0(bh6, blk1.coinbaseTxToMiner, blk1.transferTxs);
            blk101.UpdateMerkleRootHash();

            blockchain.pendingBlocks[101] = new Dictionary<Creahash, Block>();
            blockchain.rejectedBlocks[101] = new Dictionary<Creahash, Block>();

            BlockChain.UpdateChainReturnType type1 = blockchain.UpdateChain(blks[0]);

            if (type1 != BlockChain.UpdateChainReturnType.updated)
                throw new Exception("test18_5");

            if (blockchain.blocksCurrent.value != 1)
                throw new Exception("test18_6");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (blockchain.pendingBlocks[i] != null)
                    throw new Exception("test18_7");
                if (blockchain.rejectedBlocks[i] != null)
                    throw new Exception("test18_8");
            }

            bool flag2 = false;
            try
            {
                blockchain.UpdateChain(blk101);
            }
            catch (InvalidOperationException)
            {
                flag2 = true;
            }
            if (!flag2)
                throw new Exception("test18_9");

            BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blk100);

            if (type2 != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test18_10");

            if (blockchain.blocksCurrent.value != 1)
                throw new Exception("test18_11");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (i == 101)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_12");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_13");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id))
                        throw new Exception("test18_14");
                }
                else
                {
                    if (blockchain.pendingBlocks[i] != null)
                        throw new Exception("test18_15");
                }

                if (blockchain.rejectedBlocks[i] != null)
                    throw new Exception("test18_16");
            }

            BlockHeader bh1 = new BlockHeader();
            bh1.LoadVersion0(1, hashzero, DateTime.Now, blk1.Difficulty, new byte[10]);

            TransactionalBlock blk1_2 = new NormalBlock();
            blk1_2.LoadVersion0(bh1, blk1.coinbaseTxToMiner, blk1.transferTxs);
            blk1_2.UpdateMerkleRootHash();

            BlockChain.UpdateChainReturnType type3 = blockchain.UpdateChain(blk1_2);

            if (type3 != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test18_17");

            if (blockchain.blocksCurrent.value != 1)
                throw new Exception("test18_18");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (i == 2)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_19");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_20");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk1_2.Id))
                        throw new Exception("test18_21");
                }
                else if (i == 101)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_22");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_23");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id))
                        throw new Exception("test18_24");
                }
                else
                {
                    if (blockchain.pendingBlocks[i] != null)
                        throw new Exception("test18_25");
                }

                if (blockchain.rejectedBlocks[i] != null)
                    throw new Exception("test18_26");
            }

            BlockHeader bh2 = new BlockHeader();
            bh2.LoadVersion0(1, blks[0].Id, DateTime.Now, blk1.Difficulty, new byte[10]);

            TransactionalBlock blk1_3 = new NormalBlock();
            blk1_3.LoadVersion0(bh2, blk1.coinbaseTxToMiner, blk1.transferTxs);
            blk1_3.UpdateMerkleRootHash();

            BlockChain.UpdateChainReturnType type4 = blockchain.UpdateChain(blk1_3);

            if (type4 != BlockChain.UpdateChainReturnType.rejected)
                throw new Exception("test18_27");

            if (blockchain.blocksCurrent.value != 1)
                throw new Exception("test18_28");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (i == 2)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_29");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_30");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk1_2.Id))
                        throw new Exception("test18_31");

                    if (blockchain.rejectedBlocks[i] == null)
                        throw new Exception("test18_32");
                    if (blockchain.rejectedBlocks[i].Count != 1)
                        throw new Exception("test18_33");
                    if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_3.Id))
                        throw new Exception("test18_34");
                }
                else if (i == 101)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_35");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_36");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id))
                        throw new Exception("test18_37");

                    if (blockchain.rejectedBlocks[i] != null)
                        throw new Exception("test18_38");
                }
                else
                {
                    if (blockchain.pendingBlocks[i] != null)
                        throw new Exception("test18_39");

                    if (blockchain.rejectedBlocks[i] != null)
                        throw new Exception("test18_40");
                }
            }

            TransactionalBlock blk1_4 = TransactionalBlock.GetBlockTemplate(1, blk1.coinbaseTxToMiner, blk2.transferTxs, _indexToBlock, 0);

            while (true)
            {
                blk1_4.UpdateTimestamp(DateTime.Now);
                blk1_4.UpdateNonce(nonce);

                if (blk1_4.Id.CompareTo(blk1_4.header.difficulty.Target) <= 0)
                {
                    Console.WriteLine("block1_4 mined.");

                    break;
                }

                int index = nonce.Length.RandomNum();
                int value = 256.RandomNum();

                nonce[index] = (byte)value;
            }

            BlockChain.UpdateChainReturnType type5 = blockchain.UpdateChain(blk1_4);

            if (type5 != BlockChain.UpdateChainReturnType.rejected)
                throw new Exception("test18_41");

            if (blockchain.blocksCurrent.value != 1)
                throw new Exception("test18_42");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (i == 2)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_43");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_44");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk1_2.Id))
                        throw new Exception("test18_45");

                    if (blockchain.rejectedBlocks[i] == null)
                        throw new Exception("test18_46");
                    if (blockchain.rejectedBlocks[i].Count != 2)
                        throw new Exception("test18_47");
                    if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_3.Id))
                        throw new Exception("test18_48");
                    if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_4.Id))
                        throw new Exception("test18_49");
                }
                else if (i == 101)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_50");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_51");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id))
                        throw new Exception("test18_52");

                    if (blockchain.rejectedBlocks[i] != null)
                        throw new Exception("test18_53");
                }
                else
                {
                    if (blockchain.pendingBlocks[i] != null)
                        throw new Exception("test18_54");

                    if (blockchain.rejectedBlocks[i] != null)
                        throw new Exception("test18_55");
                }
            }

            BlockChain.UpdateChainReturnType type8 = blockchain.UpdateChain(blk1_3);

            if (type8 != BlockChain.UpdateChainReturnType.invariable)
                throw new Exception("test18_56");

            if (blockchain.blocksCurrent.value != 1)
                throw new Exception("test18_57");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (i == 2)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_58");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_59");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk1_2.Id))
                        throw new Exception("test18_60");

                    if (blockchain.rejectedBlocks[i] == null)
                        throw new Exception("test18_61");
                    if (blockchain.rejectedBlocks[i].Count != 2)
                        throw new Exception("test18_62");
                    if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_3.Id))
                        throw new Exception("test18_63");
                    if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_4.Id))
                        throw new Exception("test18_64");
                }
                else if (i == 101)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_65");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_66");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id))
                        throw new Exception("test18_67");

                    if (blockchain.rejectedBlocks[i] != null)
                        throw new Exception("test18_68");
                }
                else
                {
                    if (blockchain.pendingBlocks[i] != null)
                        throw new Exception("test18_69");

                    if (blockchain.rejectedBlocks[i] != null)
                        throw new Exception("test18_70");
                }
            }

            BlockChain.UpdateChainReturnType type6 = blockchain.UpdateChain(blk1);

            if (type6 != BlockChain.UpdateChainReturnType.updated)
                throw new Exception("test18_71");

            BlockChain.UpdateChainReturnType type7 = blockchain.UpdateChain(blk1_3);

            if (type7 != BlockChain.UpdateChainReturnType.invariable)
                throw new Exception("test18_72");

            if (blockchain.blocksCurrent.value != 2)
                throw new Exception("test18_73");
            for (int i = 0; i < blockchain.pendingBlocks.Length; i++)
            {
                if (i == 2)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_74");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_75");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk1_2.Id))
                        throw new Exception("test18_76");

                    if (blockchain.rejectedBlocks[i] == null)
                        throw new Exception("test18_77");
                    if (blockchain.rejectedBlocks[i].Count != 2)
                        throw new Exception("test18_78");
                    if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_3.Id))
                        throw new Exception("test18_79");
                    if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_4.Id))
                        throw new Exception("test18_80");
                }
                else if (i == 101)
                {
                    if (blockchain.pendingBlocks[i] == null)
                        throw new Exception("test18_81");
                    if (blockchain.pendingBlocks[i].Count != 1)
                        throw new Exception("test18_82");
                    if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id))
                        throw new Exception("test18_83");

                    if (blockchain.rejectedBlocks[i] != null)
                        throw new Exception("test18_84");
                }
                else
                {
                    if (blockchain.pendingBlocks[i] != null)
                        throw new Exception("test18_85");

                    if (blockchain.rejectedBlocks[i] != null)
                        throw new Exception("test18_86");
                }
            }

            BlockHeader bh3 = new BlockHeader();
            bh3.LoadVersion0(2, hashzero, DateTime.Now, blk2.Difficulty, new byte[10]);

            TransactionalBlock blk2_2 = new NormalBlock();
            blk2_2.LoadVersion0(bh3, blk2.coinbaseTxToMiner, blk2.transferTxs);
            blk2_2.UpdateMerkleRootHash();

            BlockChain.UpdateChainReturnType type9 = blockchain.UpdateChain(blk2_2);

            if (type9 != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test18_87");

            BlockHeader bh4 = new BlockHeader();
            bh4.LoadVersion0(2, blk1_2.Id, DateTime.Now, blk2.Difficulty, new byte[10]);

            TransactionalBlock blk2_3 = new NormalBlock();
            blk2_3.LoadVersion0(bh4, blk2.coinbaseTxToMiner, blk2.transferTxs);
            blk2_3.UpdateMerkleRootHash();

            BlockChain.UpdateChainReturnType type10 = blockchain.UpdateChain(blk2_3);

            if (type10 != BlockChain.UpdateChainReturnType.pending)
                throw new Exception("test18_88");

            BlockHeader bh7 = new BlockHeader();
            bh7.LoadVersion0(2, blk1_3.Id, DateTime.Now, blk2.Difficulty, new byte[10]);

            TransactionalBlock blk2_4 = new NormalBlock();
            blk2_4.LoadVersion0(bh7, blk2.coinbaseTxToMiner, blk2.transferTxs);
            blk2_4.UpdateMerkleRootHash();

            BlockChain.UpdateChainReturnType type13 = blockchain.UpdateChain(blk2_4);

            if (type13 != BlockChain.UpdateChainReturnType.rejected)
                throw new Exception("test18_91");

            for (int i = 2; i < blks2.Length; i++)
            {
                BlockChain.UpdateChainReturnType type11 = blockchain.UpdateChain(blks2[i]);

                if (type11 != BlockChain.UpdateChainReturnType.updated)
                    throw new Exception("test18_89");
            }

            TransactionalBlock blk10 = TransactionalBlock.GetBlockTemplate(10, blk2.coinbaseTxToMiner, blk2.transferTxs, _indexToBlock, 0);

            while (true)
            {
                blk10.UpdateTimestamp(DateTime.Now);
                blk10.UpdateNonce(nonce);

                if (blk10.Id.CompareTo(blk10.header.difficulty.Target) <= 0)
                {
                    Console.WriteLine("block10 mined.");

                    break;
                }

                int index = nonce.Length.RandomNum();
                int value = 256.RandomNum();

                nonce[index] = (byte)value;
            }

            BlockChain.UpdateChainReturnType type12 = blockchain.UpdateChain(blk10);

            if (type12 != BlockChain.UpdateChainReturnType.rejected)
                throw new Exception("test18_90");

            Console.WriteLine("test18_succeeded");
        }
예제 #9
0
파일: CoreTest.cs 프로젝트: pizyumi/CREA
        //BlockChainのテスト(分岐がない場合・採掘)
        public static void Test17()
        {
            string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath);
            string bcadbPath = bcadb.GetPath();

            if (File.Exists(bcadbPath))
                File.Delete(bcadbPath);

            BlockManagerDB bmdb = new BlockManagerDB(basepath);
            string bmdbPath = bmdb.GetPath();

            if (File.Exists(bmdbPath))
                File.Delete(bmdbPath);

            BlockDB bdb = new BlockDB(basepath);
            string bdbPath = bdb.GetPath(0);

            if (File.Exists(bdbPath))
                File.Delete(bdbPath);

            BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath);
            string bfpPath = bfpdb.GetPath();

            if (File.Exists(bfpPath))
                File.Delete(bfpPath);

            UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath);
            string ufadbPath = ufadb.GetPath();

            if (File.Exists(ufadbPath))
                File.Delete(ufadbPath);

            UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath);
            string ufpdbPath = ufpdb.GetPath();

            if (File.Exists(ufpdbPath))
                File.Delete(ufpdbPath);

            UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath);
            string ufptempdbPath = ufptempdb.GetPath();

            if (File.Exists(ufptempdbPath))
                File.Delete(ufptempdbPath);

            UtxoDB utxodb = new UtxoDB(basepath);
            string utxodbPath = utxodb.GetPath();

            if (File.Exists(utxodbPath))
                File.Delete(utxodbPath);

            BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb);

            BlockGenerator bg = new BlockGenerator();

            Block[] blks = new Block[100];
            BlockContext[] blkCons = new BlockContext[blks.Length];
            for (int i = 0; i < blks.Length; i++)
            {
                blkCons[i] = bg.CreateNextValidBlock();
                blks[i] = blkCons[i].block;

                Console.WriteLine("block" + i.ToString() + " created.");
            }

            Block[] blks2 = new Block[blks.Length];
            byte[] nonce = null;

            Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock;

            for (int i = 0; i < blks.Length; i++)
            {
                if (i == 0)
                {
                    blks2[i] = blks[i];

                    continue;
                }

                TransactionalBlock tblk = blks[i] as TransactionalBlock;

                TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0);

                nonce = new byte[10];

                while (true)
                {
                    tblk2.UpdateTimestamp(DateTime.Now);
                    tblk2.UpdateNonce(nonce);

                    if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0)
                    {
                        blks2[i] = tblk2;

                        Console.WriteLine("block" + i.ToString() + " mined.");

                        break;
                    }

                    int index = nonce.Length.RandomNum();
                    int value = 256.RandomNum();

                    nonce[index] = (byte)value;
                }
            }

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            for (int i = 0; i < blks.Length; i++)
                blockchain.UpdateChain(blks2[i]);

            stopwatch.Stop();

            Console.WriteLine(string.Join(":", "test17_1", stopwatch.ElapsedMilliseconds.ToString() + "ms"));

            Console.WriteLine("test17_succeeded");
        }
예제 #10
0
        public void StartSystem()
        {
            if (isSystemStarted)
            {
                throw new InvalidOperationException("core_started");
            }

            ahdb      = new AccountHoldersDatabase(databaseBasepath);
            thdb      = new TransactionHistoriesDatabase(databaseBasepath);
            bcadb     = new BlockchainAccessDB(databaseBasepath);
            bmdb      = new BlockManagerDB(databaseBasepath);
            bdb       = new BlockDB(databaseBasepath);
            bfpdb     = new BlockFilePointersDB(databaseBasepath);
            ufadb     = new UtxoFileAccessDB(databaseBasepath);
            ufpdb     = new UtxoFilePointersDB(databaseBasepath);
            ufptempdb = new UtxoFilePointersTempDB(databaseBasepath);
            utxodb    = new UtxoDB(databaseBasepath);

            accountHolders        = new AccountHolders();
            accountHoldersFactory = new AccountHoldersFactory();

            byte[] ahDataBytes = ahdb.GetData();
            if (ahDataBytes.Length != 0)
            {
                accountHolders.FromBinary(ahDataBytes);
            }
            else
            {
                accountHolders.LoadVersion0();
            }

            transactionHistories = thdb.GetData().Pipe((data) => data.Length == 0 ? new TransactionHistories() : SHAREDDATA.FromBinary <TransactionHistories>(data));
            transactionHistories.UnconfirmedTransactionAdded += (sender, e) =>
            {
                foreach (var accountHolder in accountHolders.AllAccountHolders)
                {
                    foreach (var account in accountHolder.Accounts)
                    {
                        foreach (var prevTxOut in e.senders)
                        {
                            if (account.Address.Equals(prevTxOut.Address))
                            {
                                account.accountStatus.unconfirmedAmount = new CurrencyUnit(account.accountStatus.unconfirmedAmount.rawAmount + prevTxOut.Amount.rawAmount);
                            }
                        }
                    }
                }
            };
            transactionHistories.UnconfirmedTransactionRemoved += (sender, e) =>
            {
                foreach (var accountHolder in accountHolders.AllAccountHolders)
                {
                    foreach (var account in accountHolder.Accounts)
                    {
                        foreach (var prevTxOut in e.receivers)
                        {
                            if (account.Address.Equals(prevTxOut.Address))
                            {
                                account.accountStatus.unconfirmedAmount = new CurrencyUnit(account.accountStatus.unconfirmedAmount.rawAmount - prevTxOut.Amount.rawAmount);
                            }
                        }
                    }
                }
            };

            usableBalanceCache = new CachedData <CurrencyUnit>(() =>
            {
                long rawAmount = 0;
                foreach (var accountHolder in accountHolders.AllAccountHolders)
                {
                    foreach (var account in accountHolder.Accounts)
                    {
                        rawAmount += account.accountStatus.usableAmount.rawAmount;
                    }
                }
                return(new CurrencyUnit(rawAmount));
            });
            unusableBalanceCache = new CachedData <CurrencyUnit>(() =>
            {
                long rawAmount = 0;
                foreach (var accountHolder in accountHolders.AllAccountHolders)
                {
                    foreach (var account in accountHolder.Accounts)
                    {
                        rawAmount += account.accountStatus.unusableAmount.rawAmount;
                    }
                }
                return(new CurrencyUnit(rawAmount));
            });
            unconfirmedBalanceCache = new CachedData <CurrencyUnit>(() =>
            {
                long rawAmount = 0;
                foreach (var accountHolder in accountHolders.AllAccountHolders)
                {
                    foreach (var account in accountHolder.Accounts)
                    {
                        rawAmount += account.accountStatus.unconfirmedAmount.rawAmount;
                    }
                }
                return(new CurrencyUnit(rawAmount));
            });
            usableBalanceWithUnconfirmedCache   = new CachedData <CurrencyUnit>(() => new CurrencyUnit(usableBalanceCache.Data.rawAmount - unconfirmedBalanceCache.Data.rawAmount));
            unusableBalanceWithUnconformedCache = new CachedData <CurrencyUnit>(() => new CurrencyUnit(unusableBalanceCache.Data.rawAmount + unconfirmedBalanceCache.Data.rawAmount));

            blockChain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb);
            blockChain.LoadTransactionHistories(transactionHistories);

            //<未改良>暫定?
            if (blockChain.headBlockIndex == -1)
            {
                blockChain.UpdateChain(new GenesisBlock());

                this.RaiseNotification("genesis_block_generated", 5);
            }

            Dictionary <Account, EventHandler <Tuple <CurrencyUnit, CurrencyUnit> > > changeAmountDict = new Dictionary <Account, EventHandler <Tuple <CurrencyUnit, CurrencyUnit> > >();

            Action <bool> _UpdateBalance = (isOnlyUnconfirmed) =>
            {
                if (!isOnlyUnconfirmed)
                {
                    usableBalanceCache.IsModified   = true;
                    unusableBalanceCache.IsModified = true;
                }
                unconfirmedBalanceCache.IsModified             = true;
                usableBalanceWithUnconfirmedCache.IsModified   = true;
                unusableBalanceWithUnconformedCache.IsModified = true;

                BalanceUpdated(this, EventArgs.Empty);
            };

            Action <Account, bool> _AddAddressEvent = (account, isUpdatebalance) =>
            {
                EventHandler <Tuple <CurrencyUnit, CurrencyUnit> > eh = (sender, e) =>
                {
                    account.accountStatus.usableAmount   = e.Item1;
                    account.accountStatus.unusableAmount = e.Item2;
                };

                changeAmountDict.Add(account, eh);

                AddressEvent addressEvent = new AddressEvent(account.Address.Hash);
                addressEvent.BalanceUpdated += eh;

                blockChain.AddAddressEvent(addressEvent);

                long rawAmount = 0;
                foreach (var unconfirmedTh in transactionHistories.unconfirmedTransactionHistories.ToArray())
                {
                    foreach (var prevTxOut in unconfirmedTh.senders)
                    {
                        if (prevTxOut.Address.Equals(account.Address))
                        {
                            rawAmount += prevTxOut.Amount.rawAmount;
                        }
                    }
                }
                account.accountStatus.unconfirmedAmount = new CurrencyUnit(rawAmount);

                if (isUpdatebalance)
                {
                    _UpdateBalance(false);
                }
            };

            EventHandler <Account> _AccountAdded = (sender, e) =>
            {
                utxodb.Open();

                _AddAddressEvent(e, true);

                utxodb.Close();
            };
            EventHandler <Account> _AccountRemoved = (sender, e) =>
            {
                EventHandler <Tuple <CurrencyUnit, CurrencyUnit> > eh = changeAmountDict[e];

                changeAmountDict.Remove(e);

                AddressEvent addressEvent = blockChain.RemoveAddressEvent(e.Address.Hash);
                addressEvent.BalanceUpdated -= eh;

                _UpdateBalance(false);
            };

            utxodb.Open();

            foreach (var accountHolder in accountHolders.AllAccountHolders)
            {
                foreach (var account in accountHolder.Accounts)
                {
                    _AddAddressEvent(account, false);
                }

                accountHolder.AccountAdded   += _AccountAdded;
                accountHolder.AccountRemoved += _AccountRemoved;
            }

            utxodb.Close();

            accountHolders.AccountHolderAdded += (sender, e) =>
            {
                e.AccountAdded   += _AccountAdded;
                e.AccountRemoved += _AccountRemoved;
            };
            accountHolders.AccountHolderRemoved += (semder, e) =>
            {
                e.AccountAdded   -= _AccountAdded;
                e.AccountRemoved -= _AccountRemoved;
            };

            blockChain.BalanceUpdated += (sender, e) => _UpdateBalance(false);

            _UpdateBalance(false);

            unconfirmedTtxs    = new Dictionary <TransferTransaction, TransactionOutput[]>();
            mining             = new Mining();
            mining.FoundNonce += (sender, e) => creaNodeTest.DiffuseNewBlock(e);

            blockChain.Updated += (sender, e) =>
            {
                foreach (var block in e)
                {
                    foreach (var tx in block.Transactions)
                    {
                        foreach (var txIn in tx.TxInputs)
                        {
                            TransferTransaction contradiction = null;

                            foreach (var unconfirmedTx in unconfirmedTtxs)
                            {
                                foreach (var unconfirmedTxIn in unconfirmedTx.Key.TxInputs)
                                {
                                    if (txIn.PrevTxBlockIndex == unconfirmedTxIn.PrevTxBlockIndex && txIn.PrevTxIndex == unconfirmedTxIn.PrevTxIndex && txIn.PrevTxOutputIndex == unconfirmedTxIn.PrevTxOutputIndex)
                                    {
                                        contradiction = unconfirmedTx.Key;

                                        break;
                                    }
                                }

                                if (contradiction != null)
                                {
                                    break;
                                }
                            }

                            if (contradiction != null)
                            {
                                unconfirmedTtxs.Remove(contradiction);
                            }
                        }
                    }
                }

                Mine();
            };

            Mine();

            //creaNodeTest = new CreaNode(ps.NodePort, creaVersion, appnameWithVersion, new FirstNodeInfosDatabase(p2pDirectory));
            creaNodeTest = new CreaNodeTest(blockChain, ps.NodePort, creaVersion, appnameWithVersion);
            creaNodeTest.ConnectionKeeped       += (sender, e) => creaNodeTest.SyncronizeBlockchain();
            creaNodeTest.ReceivedNewTransaction += (sender, e) =>
            {
                TransferTransaction ttx = e as TransferTransaction;

                if (ttx == null)
                {
                    return;
                }

                TransactionOutput[] prevTxOuts = new TransactionOutput[ttx.TxInputs.Length];
                for (int i = 0; i < prevTxOuts.Length; i++)
                {
                    prevTxOuts[i] = blockChain.GetMainBlock(ttx.TxInputs[i].PrevTxBlockIndex).Transactions[ttx.TxInputs[i].PrevTxIndex].TxOutputs[ttx.TxInputs[i].PrevTxOutputIndex];
                }

                if (!ttx.Verify(prevTxOuts))
                {
                    return;
                }

                List <TransactionOutput> senders   = new List <TransactionOutput>();
                List <TransactionOutput> receivers = new List <TransactionOutput>();

                long sentAmount     = 0;
                long receivedAmount = 0;

                for (int i = 0; i < ttx.txInputs.Length; i++)
                {
                    foreach (var accountHolder in accountHolders.AllAccountHolders)
                    {
                        foreach (var account in accountHolder.Accounts)
                        {
                            if (prevTxOuts[i].Address.Equals(account.Address.Hash))
                            {
                                sentAmount += prevTxOuts[i].Amount.rawAmount;

                                senders.Add(prevTxOuts[i]);
                            }
                        }
                    }
                }

                for (int i = 0; i < ttx.TxOutputs.Length; i++)
                {
                    foreach (var accountHolder in accountHolders.AllAccountHolders)
                    {
                        foreach (var account in accountHolder.Accounts)
                        {
                            if (ttx.TxOutputs[i].Address.Equals(account.Address.Hash))
                            {
                                receivedAmount += ttx.TxOutputs[i].Amount.rawAmount;

                                receivers.Add(ttx.TxOutputs[i]);
                            }
                        }
                    }
                }

                if (senders.Count > 0 || receivers.Count > 0)
                {
                    TransactionHistoryType type = TransactionHistoryType.transfered;
                    if (receivers.Count < ttx.TxOutputs.Length)
                    {
                        type = TransactionHistoryType.sent;
                    }
                    else if (senders.Count < ttx.TxInputs.Length)
                    {
                        type = TransactionHistoryType.received;
                    }

                    transactionHistories.AddTransactionHistory(new TransactionHistory(true, false, type, DateTime.MinValue, 0, ttx.Id, senders.ToArray(), receivers.ToArray(), ttx, prevTxOuts, new CurrencyUnit(sentAmount), new CurrencyUnit(receivedAmount - sentAmount)));
                }

                utxodb.Open();

                for (int i = 0; i < ttx.TxInputs.Length; i++)
                {
                    if (blockChain.FindUtxo(prevTxOuts[i].Address, ttx.TxInputs[i].PrevTxBlockIndex, ttx.TxInputs[i].PrevTxIndex, ttx.TxInputs[i].PrevTxOutputIndex) == null)
                    {
                        return;
                    }
                }

                utxodb.Close();

                foreach (var txIn in ttx.TxInputs)
                {
                    foreach (var unconfirmedTtx in unconfirmedTtxs)
                    {
                        foreach (var unconfirmedTxIn in unconfirmedTtx.Key.TxInputs)
                        {
                            if (txIn.PrevTxBlockIndex == unconfirmedTxIn.PrevTxBlockIndex && txIn.PrevTxIndex == unconfirmedTxIn.PrevTxIndex && txIn.PrevTxOutputIndex == unconfirmedTxIn.PrevTxOutputIndex)
                            {
                                return;
                            }
                        }
                    }
                }

                unconfirmedTtxs.Add(ttx, prevTxOuts);

                Mine();
            };
            creaNodeTest.ReceivedNewBlock += (sender, e) => blockChain.UpdateChain(e).Pipe((ret) => this.RaiseResult("blockchain_update", 5, ret.ToString()));
            //creaNodeTest.Start();

            isSystemStarted = true;
        }