コード例 #1
0
        public void ProcessTransactions()
        {
            Program.CheckFolderStructure();
            Program.Settings = new Settings("settings.json");

            if (File.Exists("balance"))
            {
                File.Delete("balance");
            }
            if (File.Exists("nonces"))
            {
                File.Delete("nonces");
            }

            foreach (var file in Directory.GetFiles("chains"))
            {
                File.Delete(file);
            }

            foreach (var file in Directory.GetFiles("tables"))
            {
                File.Delete(file);
            }

            var walletA = new Wallet();
            var walletB = new Wallet();
            var walletC = new Wallet();
            var walletD = new Wallet();
            var walletE = new Wallet();
            var walletF = new Wallet();

            var walletM = new Wallet(); //miner

            var balanceLedger = new BalanceLedger();
            var manager       = new ChainManager(balanceLedger);
            var contacts      = new ContactLedger(new HttpProvider());

            //generate first blocks

            var minedBlocks = new List <Block>();

            minedBlocks.Add(CreateNextBlock(Block.Genesis, null, walletA.PublicKey));
            minedBlocks.Add(CreateNextBlock(minedBlocks[0], null, walletA.PublicKey));
            minedBlocks.Add(CreateNextBlock(minedBlocks[1], null, walletA.PublicKey));

            minedBlocks.Add(CreateNextBlock(minedBlocks[2], null, walletB.PublicKey));
            minedBlocks.Add(CreateNextBlock(minedBlocks[3], null, walletB.PublicKey));
            minedBlocks.Add(CreateNextBlock(minedBlocks[4], null, walletB.PublicKey));
            minedBlocks.Add(CreateNextBlock(minedBlocks[5], null, walletB.PublicKey));

            manager.ProcessBlocks(minedBlocks);

            var transactions = new List <Transaction>()
            {
                CreateTransaction(walletA, walletD, 100, 0),
                CreateTransaction(walletB, walletF, 200, 0),
                CreateTransaction(walletA, walletB, 400, 1),
                CreateTransaction(walletB, walletD, 800, 1),
                CreateTransaction(walletA, walletD, 1600, 2)
            };

            var txBlock = CreateNextBlock(minedBlocks[minedBlocks.Count - 1], transactions);

            manager.ProcessBlocks(new List <Block>()
            {
                txBlock
            });

            Assert.IsTrue(manager.GetBalance(walletA.PublicKey) == (Program.MinerReward * 3 - 100 - 400 - 1600 - 60));
            Assert.IsTrue(manager.GetBalance(walletB.PublicKey) == (Program.MinerReward * 4 - 200 - 800 - 40 + 400));

            Assert.IsTrue(manager.GetTransactionCount(walletA.PublicKey) == 3);
            Assert.IsTrue(manager.GetTransactionCount(walletB.PublicKey) == 2);

            var paddingBlocks = new List <Block>();

            paddingBlocks.Add(CreateNextBlock(txBlock, new List <Transaction>()
            {
                CreateTransaction(walletB, walletF, 3200, 2)
            }, walletA.PublicKey));

            paddingBlocks.Add(CreateNextBlock(paddingBlocks[0], new List <Transaction>()
            {
                CreateTransaction(walletA, walletE, 6400, 3)
            }, walletA.PublicKey));

            paddingBlocks.Add(CreateNextBlock(paddingBlocks[1], new List <Transaction>()
            {
                CreateTransaction(walletA, walletB, 12800, 4),
                CreateTransaction(walletD, walletC, 2400, 0)
            }, walletA.PublicKey));

            manager.ProcessBlocks(paddingBlocks);

            Assert.IsTrue(manager.GetBalance(walletA.PublicKey) == (Program.MinerReward * 6 - 100 - 400 - 1600 - 6400 - 12800 - 100));
            Assert.IsTrue(manager.GetBalance(walletB.PublicKey) == (Program.MinerReward * 4 - 200 - 800 - 3200 - 60 + 400 + 12800));
            Assert.IsTrue(manager.GetBalance(walletC.PublicKey) == 2400);
            Assert.IsTrue(manager.GetBalance(walletD.PublicKey) == 100 + 800 + 1600 - 2400 - 20);
            Assert.IsTrue(manager.GetBalance(walletE.PublicKey) == 6400);
            Assert.IsTrue(manager.GetBalance(walletF.PublicKey) == 200 + 3200);

            var forkBlocks = new List <Block>();

            forkBlocks.Add(CreateNextBlock(paddingBlocks[0], new List <Transaction>()
            {
                CreateTransaction(walletA, walletB, 2400, 3),
                CreateTransaction(walletD, walletC, 1200, 0)
            }, walletE.PublicKey));

            forkBlocks.Add(CreateNextBlock(forkBlocks[0], new List <Transaction>(), walletE.PublicKey));
            forkBlocks.Add(CreateNextBlock(forkBlocks[1], new List <Transaction>(), walletE.PublicKey));
            forkBlocks.Add(CreateNextBlock(forkBlocks[2], new List <Transaction>(), walletE.PublicKey));

            manager.ProcessBlocks(forkBlocks);

            Assert.IsTrue(manager.GetBalance(walletA.PublicKey) == (Program.MinerReward * 4 - 100 - 400 - 1600 - 2400 - 80));
            Assert.IsTrue(manager.GetBalance(walletB.PublicKey) == (Program.MinerReward * 4 - 200 - 800 - 3200 - 60 + 400 + 2400));
            Assert.IsTrue(manager.GetBalance(walletC.PublicKey) == 1200);
            Assert.IsTrue(manager.GetBalance(walletD.PublicKey) == 100 + 800 + 1600 - 20 - 1200);
            Assert.IsTrue(manager.GetBalance(walletE.PublicKey) == Program.MinerReward * 4);
            Assert.IsTrue(manager.GetBalance(walletF.PublicKey) == 3400);

            var lowerNonceBlock = CreateNextBlock(forkBlocks.Last(), new List <Transaction>()
            {
                CreateTransaction(walletA, walletB, 2000, 2)
            });

            manager.ProcessBlocks(new List <Block>()
            {
                lowerNonceBlock
            });

            Assert.IsTrue(manager.Height == 13);

            var higherNonceBlock = CreateNextBlock(forkBlocks.Last(), new List <Transaction>()
            {
                CreateTransaction(walletA, walletB, 2000, 5)
            });

            manager.ProcessBlocks(new List <Block>()
            {
                higherNonceBlock
            });

            Assert.IsTrue(manager.Height == 13);

            var overBalanceBlock = CreateNextBlock(forkBlocks.Last(), new List <Transaction>()
            {
                CreateTransaction(walletF, walletB, 10000, 0)
            });

            manager.ProcessBlocks(new List <Block>()
            {
                overBalanceBlock
            });

            Assert.IsTrue(manager.Height == 13);

            var noBalanceBlock = CreateNextBlock(forkBlocks.Last(), new List <Transaction>()
            {
                CreateTransaction(new Wallet(), walletB, 10000, 0)
            });

            manager.ProcessBlocks(new List <Block>()
            {
                noBalanceBlock
            });

            Assert.IsTrue(manager.Height == 13);

            //persistency check
            manager.Dispose();

            balanceLedger = new BalanceLedger();
            manager       = new ChainManager(balanceLedger);

            Assert.IsTrue(manager.GetBalance(walletA.PublicKey) == (Program.MinerReward * 4 - 100 - 400 - 1600 - 2400 - 80));
            Assert.IsTrue(manager.GetBalance(walletB.PublicKey) == (Program.MinerReward * 4 - 200 - 800 - 3200 - 60 + 400 + 2400));
            Assert.IsTrue(manager.GetBalance(walletC.PublicKey) == 1200);
            Assert.IsTrue(manager.GetBalance(walletD.PublicKey) == 100 + 800 + 1600 - 20 - 1200);
            Assert.IsTrue(manager.GetBalance(walletE.PublicKey) == Program.MinerReward * 4);
            Assert.IsTrue(manager.GetBalance(walletF.PublicKey) == 3400);

            //miner test
            var txPool = new TransactionPool(balanceLedger);

            Program.Settings.minerAddr = HexConverter.ToPrefixString(walletM.PublicKey);
            var miner = new Miner(balanceLedger, txPool, manager);

            for (int i = 0; i < 187; i++)
            {
                miner.UpdateParameters();
                while (miner.MineRound().Result == null)
                {
                    ;
                }
            }

            miner.UpdateParameters();
            var ret = miner.MineRound().Result;

            Assert.IsTrue(manager.Height == 201);

            //tx pool test

            txPool.AddTransactions(new List <Transaction>()
            {
                CreateTransaction(walletA, walletF, 5000, manager.GetTransactionCount(walletA.PublicKey)),
                CreateTransaction(walletA, walletB, 5000, 5),
                CreateTransaction(walletA, walletB, 5000, 8)
            });

            var mineableTxs = txPool.GetMineableTransactions();
        }