Beispiel #1
0
        public async Task <BlockBase> CreateBlock(HashSet <Transaction> transactions, DateTime enqueueTime,
                                                  BlockBase parentBlock = null, CancellationToken token = default(CancellationToken))
        {
            if (transactions == null)
            {
                return(null);
            }

            if (!transactions.Any())
            {
                return(null);
            }

            var tree = _merkleTreeProvider.GetMerkleTree(transactions);

            var header = new Header
            {
                ParentHash         = EncryptionService.GetSha256Hash(parentBlock?.BlockJson),
                MerkleTreeRootHash = tree.Hash,
                TimeStamp          = DateTime.UtcNow,
                Version            = null,
                Nonce  = null,
                Target = null
            };

            var body = new Body
            {
                MerkleTree   = tree,
                Transactions = transactions
            };

            BlockBase newBlock;

            if (parentBlock == null)
            {
                newBlock = new GenesisBlock
                {
                    Id        = Convert.ToString(0, 16),
                    UniqueId  = $"{Guid.NewGuid()}-{BlockchainNodeConfiguration.NodeId}",
                    QueueTime = DateTime.UtcNow - enqueueTime
                };
            }
            else
            {
                newBlock = new Block
                {
                    Id             = Convert.ToString(Convert.ToInt32(parentBlock.Id, 16) + 1, 16),
                    UniqueId       = $"{Guid.NewGuid()}-{BlockchainNodeConfiguration.NodeId}",
                    ParentUniqueId = parentBlock.UniqueId,
                    QueueTime      = DateTime.UtcNow - enqueueTime,
                    Depth          = parentBlock.Depth + 1,
                    Parent         = parentBlock
                };
            }

            newBlock.Header = header;
            newBlock.Body   = body;

            return(await FillBlock(newBlock, token));
        }
Beispiel #2
0
        public IBlock Mine()
        {
            Logger.Log("[MineService] Start mining.");
            // Generate a block template.
            IBlock block;
            var    currentHeight = _blockChainService.GetCurrentHeight();

            if (currentHeight == 0)
            {
                block = new GenesisBlock(new GenesisBlockHeader(), new GenesisBlockBody());
            }
            else
            {
                var latestBlockHash = _blockChainService.GetLatestBlockHash();
                block = new Block(new BlockHeader(currentHeight + 1, latestBlockHash), new BlockBody());
            }

            // Fetch Transactions from tx pool.
            var txs = _transactionPool.GetAllTransactions();

            // Execute txs and fill the block.
            var executedTxIds = _transactionExecutingService.FillBlock(ref block, txs);

            // Remove executed txs.
            _transactionPool.RemoveTransactions(executedTxIds);

            Logger.Log($"[MineService] Mined a block: \n{block}");

            Thread.Sleep(1000);
            return(block);
        }
Beispiel #3
0
        public Blockchain(ZoroSystem system, Store store, UInt160 chainHash)
        {
            this.ChainHash   = chainHash;
            this.system      = system;
            this.Store       = store;
            store.Blockchain = this;

            if (root == null)
            {
                root = this;
                StandbyValidators = Settings.Default.StandbyValidators.OfType <string>().Select(p => ECPoint.DecodePoint(p.HexToBytes(), ECCurve.Secp256r1)).ToArray();
            }
            else
            {
                if (chainHash.Size == 0)
                {
                    throw new ArgumentException();
                }

                RegisterAppChain(chainHash, this);
            }

            GenesisBlock.RebuildMerkleRoot();

            lock (GetType())
            {
                header_index.AddRange(store.GetHeaderHashList().Find().OrderBy(p => (uint)p.Key).SelectMany(p => p.Value.Hashes));
                stored_header_count += (uint)header_index.Count;
                if (stored_header_count == 0)
                {
                    header_index.AddRange(store.GetBlocks().Find().OrderBy(p => p.Value.TrimmedBlock.Index).Select(p => p.Key));
                }
                else
                {
                    HashIndexState hashIndex = store.GetHeaderHashIndex().Get();
                    if (hashIndex.Index >= stored_header_count)
                    {
                        DataCache <UInt256, BlockState> cache = store.GetBlocks();
                        for (UInt256 hash = hashIndex.Hash; hash != header_index[(int)stored_header_count - 1];)
                        {
                            header_index.Insert((int)stored_header_count, hash);
                            hash = cache[hash].TrimmedBlock.PrevHash;
                        }
                    }
                }

                if (header_index.Count == 0)
                {
                    Persist(GenesisBlock);
                }
                else
                {
                    UpdateCurrentSnapshot();
                }
            }
        }
Beispiel #4
0
        public void GenesisBlock_Verify_Test()
        {
            GenesisBlock gblock = new GenesisBlock();

            Assert.Equal(ulong.Parse("233890554552"), gblock.GetDifficulty());
            Assert.True(gblock.HasTransactions());
            Assert.True(gblock.HasRewardTransaction());
            Assert.Equal("0000003674f6a2b8ac9e577ae1795f34c1badf5d7ac017c8d087c0c3ac1b7289", gblock.ToHash());
            Assert.True(gblock.GetRewardTransaction().Verify());
        }
    private void CreateGenesisBlock()
    {
        if (this.Blocks.Count == 0)
        {
            GenesisBlock genesisBlock = new GenesisBlock();
            Transaction  iTx1         = new Transaction("0", this.Wallet.PublicKey, Node.InitCoins);

            genesisBlock.AddTransaction(iTx1);

            MineNewBlock(genesisBlock);
        }
    }
Beispiel #6
0
        public static GenesisBlock CreateBlock(Account genesisAccount, Block genesisBlock, string[] publicKeys)
        {
            var keys = publicKeys.Select(x => string.Format("+{0}", x)).ToList();
            var delegateTransaction = new Transaction
            {
                Type            = TransactionType.Multi,
                Amount          = 0,
                Fee             = 0,
                Timestamp       = 0,
                RecipientId     = null,
                SenderId        = genesisAccount.Address.IdString,
                SenderPublicKey = genesisAccount.Address.KeyPair.PublicKey.ToHex(),
                Asset           = new DelegatesAsset
                {
                    Delegates = new DelegatesAssetCollection(keys)
                }
            };

            var block = new GenesisBlock
            {
                PointId     = new BigInteger(genesisBlock.Id),
                PointHeight = 1,
                Height      = 1,
                Delegate    = genesisAccount.Address.KeyPair.PublicKey.ToHex(),
                Timestamp   = 0
            };

            block.Transactions.Add(delegateTransaction);
            block.Count = block.Transactions.Count;

            var bytes = delegateTransaction.GetBytes();

            delegateTransaction.Signature = CryptoHelper.Sign(bytes, genesisAccount.Address.KeyPair.PrivateKey).ToHex();
            //bytes = delegateTransaction.GetBytes();
            delegateTransaction.Id = CryptoHelper.GetId(bytes);

            block.PayloadLength = bytes.Length;
            block.PayloadHash   = CryptoHelper.Sha256(bytes).ToHex();

            var blockBytes = block.GetBytes();

            block.Signature = CryptoHelper.Sign(blockBytes, genesisAccount.Address.KeyPair.PrivateKey).ToHex();
            block.Id        = CryptoHelper.GetId(bytes);

            return(block);
        }
        private GenesisBlock CreateGenesisBlock()
        {
            var genesisBlock = new GenesisBlock
            {
                Id        = "0",
                UniqueId  = Guid.Empty.ToString(),
                QueueTime = TimeSpan.Zero,
                Depth     = 0,
                Header    = new Header
                {
                    Nonce              = Guid.Empty.ToString().Replace("-", ""),
                    Target             = Guid.Empty.ToString().Replace("-", ""),
                    Version            = BlockchainNodeConfiguration.Version,
                    TimeStamp          = DateTime.MinValue,
                    MerkleTreeRootHash = null,
                    ParentHash         = null
                },
                Body = new Body
                {
                    Transactions = StartupValidators.Select((v, index) => new Transaction
                    {
                        Id                 = $"{Guid.Empty}-{index}",
                        Sender             = v.Key,
                        Recipient          = Guid.Empty.ToString(),
                        Amount             = v.Value,
                        Fee                = 0,
                        RegistrationTime   = DateTime.MinValue,
                        TransactionMessage = new TransactionMessage {
                            MessageType = TransactionMessageTypes.Deposit
                        }
                    }).ToHashSet(),
                    MerkleTree = null
                }
            };

            return(genesisBlock);
        }
Beispiel #8
0
        public BlockContext CreateNextValidBlock()
        {
            currentBIndex++;

            if (currentBIndex == 0)
            {
                Block blk = new GenesisBlock();

                blks.Add(blk);

                Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>> unspentTxOutsDictClone2 = new Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>>();
                Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>> spentTxOutsDictClone2 = new Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>>();

                for (int i = 0; i < keyPairs.Length; i++)
                {
                    unspentTxOutsDictClone2.Add(addresses[i], new List<TransactionOutputContext>());
                    foreach (var toc in unspentTxOutsDict[addresses[i]])
                        unspentTxOutsDictClone2[addresses[i]].Add(toc);
                    spentTxOutsDictClone2.Add(addresses[i], new List<TransactionOutputContext>());
                    foreach (var toc in spentTxOutsDict[addresses[i]])
                        spentTxOutsDictClone2[addresses[i]].Add(toc);
                }

                return new BlockContext(blk, new TransactionOutput[][] { }, 0, unspentTxOutsDictClone2, spentTxOutsDictClone2);
            }

            int numOfSpendTxs = maxNumOfSpendTxs.RandomNum() + 1;
            int[] numOfSpendTxOutss = new int[numOfSpendTxs];
            for (int i = 0; i < numOfSpendTxOutss.Length; i++)
                numOfSpendTxOutss[i] = maxNumOfSpendTxOuts.RandomNum() + 1;

            TransactionOutputContext[][] spendTxOutss = new TransactionOutputContext[numOfSpendTxs][];
            for (int i = 0; i < spendTxOutss.Length; i++)
            {
                if (unspentTxOuts.Count == 0)
                    break;

                spendTxOutss[i] = new TransactionOutputContext[numOfSpendTxOutss[i]];

                for (int j = 0; j < spendTxOutss[i].Length; j++)
                {
                    int index = unspentTxOuts.Count.RandomNum();

                    spendTxOutss[i][j] = unspentTxOuts[index];

                    spentTxOutsDict[unspentTxOuts[index].address].Add(unspentTxOuts[index]);
                    unspentTxOutsDict[unspentTxOuts[index].address].Remove(unspentTxOuts[index]);

                    spentTxOuts.Add(unspentTxOuts[index]);
                    unspentTxOuts.RemoveAt(index);

                    if (unspentTxOuts.Count == 0)
                        break;
                }
            }

            long fee = 0;
            List<TransferTransaction> transferTxs = new List<TransferTransaction>();
            List<TransactionOutput[]> prevTxOutsList = new List<TransactionOutput[]>();
            for (int i = 0; i < spendTxOutss.Length; i++)
            {
                if (spendTxOutss[i] == null)
                    break;

                long sumRawAmount = 0;

                List<TransactionInput> txInputsList = new List<TransactionInput>();
                for (int j = 0; j < spendTxOutss[i].Length; j++)
                {
                    if (spendTxOutss[i][j] == null)
                        break;

                    txInputsList.Add(spendTxOutss[i][j].GenerateTransactionInput());

                    sumRawAmount += spendTxOutss[i][j].amount.rawAmount;
                }

                TransactionInput[] txIns = txInputsList.ToArray();

                int num = sumRawAmount > 1000000 ? (int)Math.Ceiling(((avgIORatio - 1) * 2) * 1.RandomDouble() * txIns.Length) : 1;

                TransactionOutputContext[] txOutsCon = new TransactionOutputContext[num];
                TransactionOutput[] txOuts = new TransactionOutput[num];
                for (int j = 0; j < txOutsCon.Length; j++)
                {
                    long outAmount = 0;
                    if (sumRawAmount > 1000000)
                    {
                        long sumRawAmountDivided = sumRawAmount / 1000000;

                        int subtract = ((int)sumRawAmountDivided / 2).RandomNum() + 1;

                        outAmount = (long)subtract * 1000000;
                    }
                    else
                        outAmount = sumRawAmount;

                    sumRawAmount -= outAmount;

                    int index = numOfKeyPairs.RandomNum();

                    txOutsCon[j] = new TransactionOutputContext(currentBIndex, i + 1, j, new CurrencyUnit(outAmount), addresses[index], keyPairs[index]);
                    txOuts[j] = txOutsCon[j].GenerateTrasactionOutput();
                }

                fee += sumRawAmount;

                for (int j = 0; j < txOutsCon.Length; j++)
                {
                    unspentTxOutsDict[txOutsCon[j].address].Add(txOutsCon[j]);

                    unspentTxOuts.Add(txOutsCon[j]);
                }

                TransactionOutput[] prevTxOuts = new TransactionOutput[txIns.Length];
                Ecdsa256PrivKey[] privKeys = new Ecdsa256PrivKey[txIns.Length];
                for (int j = 0; j < prevTxOuts.Length; j++)
                {
                    prevTxOuts[j] = spendTxOutss[i][j].GenerateTrasactionOutput();
                    privKeys[j] = spendTxOutss[i][j].keyPair.privKey;
                }

                TransferTransaction tTx = new TransferTransaction();
                tTx.LoadVersion0(txIns, txOuts);
                tTx.Sign(prevTxOuts, privKeys);

                transferTxs.Add(tTx);
                prevTxOutsList.Add(prevTxOuts);
            }

            long rewardAndFee = TransactionalBlock.GetRewardToMiner(currentBIndex, 0).rawAmount + fee;

            TransactionOutputContext[] coinbaseTxOutsCon = new TransactionOutputContext[numOfCoinbaseTxOuts];
            TransactionOutput[] coinbaseTxOuts = new TransactionOutput[numOfCoinbaseTxOuts];
            for (int i = 0; i < coinbaseTxOutsCon.Length; i++)
            {
                long outAmount2 = 0;
                if (i != coinbaseTxOutsCon.Length - 1)
                {
                    long rewardAndFeeDevided = rewardAndFee / 1000000;

                    int subtract2 = ((int)rewardAndFeeDevided / 2).RandomNum() + 1;

                    outAmount2 = (long)subtract2 * 1000000;

                    rewardAndFee -= outAmount2;
                }
                else
                    outAmount2 = rewardAndFee;

                int index = numOfKeyPairs.RandomNum();

                coinbaseTxOutsCon[i] = new TransactionOutputContext(currentBIndex, 0, i, new CurrencyUnit(outAmount2), addresses[index], keyPairs[index]);
                coinbaseTxOuts[i] = coinbaseTxOutsCon[i].GenerateTrasactionOutput();
            }

            CoinbaseTransaction coinbaseTx = new CoinbaseTransaction();
            coinbaseTx.LoadVersion0(coinbaseTxOuts);

            for (int i = 0; i < coinbaseTxOutsCon.Length; i++)
            {
                unspentTxOutsDict[coinbaseTxOutsCon[i].address].Add(coinbaseTxOutsCon[i]);

                unspentTxOuts.Add(coinbaseTxOutsCon[i]);
            }

            prevTxOutsList.Insert(0, new TransactionOutput[] { });

            Difficulty<Creahash> diff = new Difficulty<Creahash>(HASHBASE.FromHash<Creahash>(new byte[] { 0, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }));
            byte[] nonce = new byte[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            BlockHeader bh = new BlockHeader();
            bh.LoadVersion0(currentBIndex, blks[blks.Count - 1].Id, DateTime.Now, diff, nonce);

            NormalBlock nblk = new NormalBlock();
            nblk.LoadVersion0(bh, coinbaseTx, transferTxs.ToArray());
            nblk.UpdateMerkleRootHash();

            blks.Add(nblk);

            Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>> unspentTxOutsDictClone = new Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>>();
            Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>> spentTxOutsDictClone = new Dictionary<Sha256Ripemd160Hash, List<TransactionOutputContext>>();

            for (int i = 0; i < keyPairs.Length; i++)
            {
                unspentTxOutsDictClone.Add(addresses[i], new List<TransactionOutputContext>());
                foreach (var toc in unspentTxOutsDict[addresses[i]])
                    unspentTxOutsDictClone[addresses[i]].Add(toc);
                spentTxOutsDictClone.Add(addresses[i], new List<TransactionOutputContext>());
                foreach (var toc in spentTxOutsDict[addresses[i]])
                    spentTxOutsDictClone[addresses[i]].Add(toc);
            }

            BlockContext blkCon = new BlockContext(nblk, prevTxOutsList.ToArray(), fee, unspentTxOutsDictClone, spentTxOutsDictClone);

            return blkCon;
        }
Beispiel #9
0
        //Blockのテスト1
        public static void Test11()
        {
            GenesisBlock gblk = new GenesisBlock();

            if (gblk.Index != 0)
                throw new Exception("test11_1");
            if (gblk.PrevId != null)
                throw new Exception("test11_2");
            if (gblk.Difficulty.Diff != 0.00000011)
                throw new Exception("test11_3");
            if (gblk.Transactions.Length != 0)
                throw new Exception("test11_4");

            byte[] gblkBytes = gblk.ToBinary();

            if (gblkBytes.Length != 68)
                throw new Exception("test11_5");

            GenesisBlock gblkRestore = SHAREDDATA.FromBinary<GenesisBlock>(gblkBytes);

            if (!gblk.Id.Equals(gblkRestore.Id))
                throw new Exception("test11_6");

            byte[] gblkBytes2 = SHAREDDATA.ToBinary<Block>(gblk);

            if (gblkBytes2.Length != 88)
                throw new Exception("test11_7");

            GenesisBlock gblkRestore2 = SHAREDDATA.FromBinary<Block>(gblkBytes2) as GenesisBlock;

            if (!gblk.Id.Equals(gblkRestore2.Id))
                throw new Exception("test11_8");

            BlockHeader bh = new BlockHeader();

            bool flag = false;
            try
            {
                bh.LoadVersion0(0, null, DateTime.Now, null, new byte[10]);
            }
            catch (ArgumentOutOfRangeException)
            {
                flag = true;
            }
            if (!flag)
                throw new Exception("test11_9");

            bool flag2 = false;
            try
            {
                bh.LoadVersion0(1, null, DateTime.Now, null, new byte[9]);
            }
            catch (ArgumentOutOfRangeException)
            {
                flag2 = true;
            }
            if (!flag2)
                throw new Exception("test11_10");

            Difficulty<Creahash> diff = new Difficulty<Creahash>(HASHBASE.FromHash<Creahash>(new byte[] { 0, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }));
            Sha256Sha256Hash hash = new Sha256Sha256Hash(new byte[] { 1 });
            DateTime dt = DateTime.Now;
            byte[] nonce = new byte[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            bh.LoadVersion0(1, gblk.Id, DateTime.Now, diff, new byte[10]);

            bool flag3 = false;
            try
            {
                bh.UpdateNonce(new byte[11]);
            }
            catch (ArgumentOutOfRangeException)
            {
                flag3 = true;
            }
            if (!flag3)
                throw new Exception("test11_11");

            bh.UpdateMerkleRootHash(hash);
            bh.UpdateTimestamp(dt);
            bh.UpdateNonce(nonce);

            if (bh.index != 1)
                throw new Exception("test11_12");
            if (bh.prevBlockHash != gblk.Id)
                throw new Exception("test11_13");
            if (bh.merkleRootHash != hash)
                throw new Exception("test11_14");
            if (bh.timestamp != dt)
                throw new Exception("test11_15");
            if (bh.difficulty != diff)
                throw new Exception("test11_16");
            if (bh.nonce != nonce)
                throw new Exception("test11_17");

            byte[] bhBytes = bh.ToBinary();

            if (bhBytes.Length != 95)
                throw new Exception("test11_18");

            BlockHeader bhRestore = SHAREDDATA.FromBinary<BlockHeader>(bhBytes);

            if (bh.index != bhRestore.index)
                throw new Exception("test11_19");
            if (!bh.prevBlockHash.Equals(bhRestore.prevBlockHash))
                throw new Exception("test11_20");
            if (!bh.merkleRootHash.Equals(bhRestore.merkleRootHash))
                throw new Exception("test11_21");
            if (bh.timestamp != bhRestore.timestamp)
                throw new Exception("test11_22");
            if (bh.difficulty.Diff != bhRestore.difficulty.Diff)
                throw new Exception("test11_23");
            if (!bh.nonce.BytesEquals(bhRestore.nonce))
                throw new Exception("test11_24");

            bool flag4 = false;
            try
            {
                TransactionalBlock.GetBlockType(0, 0);
            }
            catch (ArgumentOutOfRangeException)
            {
                flag4 = true;
            }
            if (!flag4)
                throw new Exception("test11_25");

            Type type1 = TransactionalBlock.GetBlockType(60 * 24 - 1, 0);
            Type type2 = TransactionalBlock.GetBlockType(60 * 24, 0);
            Type type3 = TransactionalBlock.GetBlockType(60 * 24 + 1, 0);

            if (type1 != typeof(NormalBlock))
                throw new Exception("test11_26");
            if (type2 != typeof(FoundationalBlock))
                throw new Exception("test11_27");
            if (type3 != typeof(NormalBlock))
                throw new Exception("test11_28");

            bool flag5 = false;
            try
            {
                TransactionalBlock.GetRewardToAll(0, 0);
            }
            catch (ArgumentOutOfRangeException)
            {
                flag5 = true;
            }
            if (!flag5)
                throw new Exception("test11_29");

            bool flag6 = false;
            try
            {
                TransactionalBlock.GetRewardToMiner(0, 0);
            }
            catch (ArgumentOutOfRangeException)
            {
                flag6 = true;
            }
            if (!flag6)
                throw new Exception("test11_30");

            bool flag7 = false;
            try
            {
                TransactionalBlock.GetRewardToFoundation(0, 0);
            }
            catch (ArgumentOutOfRangeException)
            {
                flag7 = true;
            }
            if (!flag7)
                throw new Exception("test11_31");

            bool flag8 = false;
            try
            {
                TransactionalBlock.GetRewardToFoundationInterval(0, 0);
            }
            catch (ArgumentOutOfRangeException)
            {
                flag8 = true;
            }
            if (!flag8)
                throw new Exception("test11_32");

            bool flag9 = false;
            try
            {
                TransactionalBlock.GetRewardToFoundationInterval(1, 0);
            }
            catch (ArgumentException)
            {
                flag9 = true;
            }
            if (!flag9)
                throw new Exception("test11_33");

            CurrencyUnit initial = new Creacoin(60.0m);
            decimal rate = 1.25m;
            for (int i = 0; i < 8; i++)
            {
                CurrencyUnit reward1 = i != 0 ? TransactionalBlock.GetRewardToAll((60 * 24 * 365 * i) - 1, 0) : null;
                CurrencyUnit reward2 = i != 0 ? TransactionalBlock.GetRewardToAll(60 * 24 * 365 * i, 0) : null;
                CurrencyUnit reward3 = TransactionalBlock.GetRewardToAll((60 * 24 * 365 * i) + 1, 0);

                CurrencyUnit reward7 = i != 0 ? TransactionalBlock.GetRewardToMiner((60 * 24 * 365 * i) - 1, 0) : null;
                CurrencyUnit reward8 = i != 0 ? TransactionalBlock.GetRewardToMiner(60 * 24 * 365 * i, 0) : null;
                CurrencyUnit reward9 = TransactionalBlock.GetRewardToMiner((60 * 24 * 365 * i) + 1, 0);

                CurrencyUnit reward10 = i != 0 ? TransactionalBlock.GetRewardToFoundation((60 * 24 * 365 * i) - 1, 0) : null;
                CurrencyUnit reward11 = i != 0 ? TransactionalBlock.GetRewardToFoundation(60 * 24 * 365 * i, 0) : null;
                CurrencyUnit reward12 = TransactionalBlock.GetRewardToFoundation((60 * 24 * 365 * i) + 1, 0);

                CurrencyUnit reward19 = i != 0 ? TransactionalBlock.GetRewardToFoundationInterval(((365 * i) - 1) * 60 * 24, 0) : null;
                CurrencyUnit reward20 = i != 0 ? TransactionalBlock.GetRewardToFoundationInterval(60 * 24 * 365 * i, 0) : null;
                CurrencyUnit reward21 = TransactionalBlock.GetRewardToFoundationInterval(((365 * i) + 1) * 60 * 24, 0);

                if (i != 0 && reward1.rawAmount != initial.rawAmount * rate)
                    throw new Exception("test11_34");
                if (i != 0 && reward7.rawAmount != initial.rawAmount * rate * 0.9m)
                    throw new Exception("test11_35");
                if (i != 0 && reward10.rawAmount != initial.rawAmount * rate * 0.1m)
                    throw new Exception("test11_36");
                if (i != 0 && reward19.rawAmount != initial.rawAmount * rate * 0.1m * 60m * 24m)
                    throw new Exception("test11_37");

                rate *= 0.8m;

                if (i != 0 && reward2.rawAmount != initial.rawAmount * rate)
                    throw new Exception("test11_38");
                if (i != 0 && reward8.rawAmount != initial.rawAmount * rate * 0.9m)
                    throw new Exception("test11_39");
                if (i != 0 && reward11.rawAmount != initial.rawAmount * rate * 0.1m)
                    throw new Exception("test11_40");
                if (i != 0 && reward20.rawAmount != initial.rawAmount * rate * 0.1m * 60m * 24m)
                    throw new Exception("test11_41");

                if (reward3.rawAmount != initial.rawAmount * rate)
                    throw new Exception("test11_42");
                if (reward9.rawAmount != initial.rawAmount * rate * 0.9m)
                    throw new Exception("test11_43");
                if (reward12.rawAmount != initial.rawAmount * rate * 0.1m)
                    throw new Exception("test11_44");
                if (reward21.rawAmount != initial.rawAmount * rate * 0.1m * 60m * 24m)
                    throw new Exception("test11_45");
            }

            CurrencyUnit reward4 = TransactionalBlock.GetRewardToAll((60 * 24 * 365 * 8) - 1, 0);
            CurrencyUnit reward5 = TransactionalBlock.GetRewardToAll(60 * 24 * 365 * 8, 0);
            CurrencyUnit reward6 = TransactionalBlock.GetRewardToAll((60 * 24 * 365 * 8) + 1, 0);

            CurrencyUnit reward13 = TransactionalBlock.GetRewardToMiner((60 * 24 * 365 * 8) - 1, 0);
            CurrencyUnit reward14 = TransactionalBlock.GetRewardToMiner(60 * 24 * 365 * 8, 0);
            CurrencyUnit reward15 = TransactionalBlock.GetRewardToMiner((60 * 24 * 365 * 8) + 1, 0);

            CurrencyUnit reward16 = TransactionalBlock.GetRewardToFoundation((60 * 24 * 365 * 8) - 1, 0);
            CurrencyUnit reward17 = TransactionalBlock.GetRewardToFoundation(60 * 24 * 365 * 8, 0);
            CurrencyUnit reward18 = TransactionalBlock.GetRewardToFoundation((60 * 24 * 365 * 8) + 1, 0);

            CurrencyUnit reward22 = TransactionalBlock.GetRewardToFoundationInterval(((365 * 8) - 1) * 60 * 24, 0);
            CurrencyUnit reward23 = TransactionalBlock.GetRewardToFoundationInterval(60 * 24 * 365 * 8, 0);
            CurrencyUnit reward24 = TransactionalBlock.GetRewardToFoundationInterval(((365 * 8) + 1) * 60 * 24, 0);

            if (reward4.rawAmount != initial.rawAmount * rate)
                throw new Exception("test11_46");
            if (reward13.rawAmount != initial.rawAmount * rate * 0.9m)
                throw new Exception("test11_47");
            if (reward16.rawAmount != initial.rawAmount * rate * 0.1m)
                throw new Exception("test11_48");
            if (reward22.rawAmount != initial.rawAmount * rate * 0.1m * 60m * 24m)
                throw new Exception("test11_49");

            if (reward5.rawAmount != 0)
                throw new Exception("test11_50");
            if (reward14.rawAmount != 0)
                throw new Exception("test11_51");
            if (reward17.rawAmount != 0)
                throw new Exception("test11_52");
            if (reward23.rawAmount != 0)
                throw new Exception("test11_53");

            if (reward6.rawAmount != 0)
                throw new Exception("test11_54");
            if (reward15.rawAmount != 0)
                throw new Exception("test11_55");
            if (reward18.rawAmount != 0)
                throw new Exception("test11_56");
            if (reward24.rawAmount != 0)
                throw new Exception("test11_57");

            Console.WriteLine("test11_succeeded");
        }
Beispiel #10
0
        public async Task <bool> Start(string[] args, CancellationTokenSource quiteToken)
        {
            _quitToken = quiteToken;

            if (_quitToken.IsCancellationRequested)
            {
                return(false);
            }

            var dataPath = "heleusdata";

            var genesis        = false;
            var sync           = false;
            var run            = false;
            var init           = false;
            var newChainConfig = false;

            if (args.Length == 1)
            {
                dataPath = args[0];
                run      = true;
            }
            else if (args.Length == 2)
            {
                dataPath = args[0];
                var cmd = args[1];

                if (cmd == "init")
                {
                    init = true;
                }
                else if (cmd == "run")
                {
                    run = true;
                }
                else if (cmd == "sync")
                {
                    sync = true;
                }
                else if (cmd == "chainconfig")
                {
                    newChainConfig = true;
                }
                else if (cmd == "genesis")
                {
                    genesis = true;
                }
                else
                {
                    Usage();
                    return(false);
                }
            }
            else
            {
                Usage();
                return(false);
            }

            if ((run || sync) && !File.Exists(Path.Combine(dataPath, $"{nameof(NodeConfig).ToLower()}.txt")))
            {
                Usage();
                var dp = new DirectoryInfo(dataPath);
                Log.Error($"Data path {dp.FullName} not initalized.", this);
                return(false);
            }

            Storage = new Storage(dataPath);
            if (!Storage.IsWriteable)
            {
                Log.Fatal($"Data path {Storage.Root} is not writeable!", this);
                return(false);
            }

            if (genesis)
            {
                Storage.DeleteDirectory("cache");
                Storage.DeleteDirectory("chains");
            }

            PubSub = Log.PubSub = new PubSub();

            Log.Write($"Starting Heleus Node (Version {Program.Version}).");
            Log.Trace($"PID {System.Diagnostics.Process.GetCurrentProcess().Id}");

            Log.Write($"Data path is '{Storage.Root.FullName}'.");

            var config = Config.Load <NodeConfig>(Storage);

            Log.AddIgnoreList(config.LogIgnore);
            Log.LogLevel = config.LogLevel;

            if (Program.IsDebugging)
            {
                Log.LogLevel = LogLevels.Trace;
            }

            if (newChainConfig)
            {
                var chainConfig = Config.Load <ChainConfig>(Storage, true);
                //if (chainConfig.Chains.Count == 0)
                {
                    Log.Write("Chain config generated.");

                    chainConfig.Chains.Add(new ChainConfig.ChainInfo {
                        ChainKeys = new List <ChainConfig.ChainKeyInfo> {
                            new ChainConfig.ChainKeyInfo {
                                ChainKey = string.Empty, ChainKeyPassword = string.Empty, AttachementKey = -1
                            }
                        }
                    });
                    Config.Save(chainConfig);
                }

                return(false);
            }

            if (init)
            {
                Log.Write("Config file generated.");
                return(false);
            }

            if (!genesis)
            {
                if (config.NetworkPublicKey.IsNullOrEmpty())
                {
                    Log.Write("Network key not set. Querying beacon nodes.");
                    var beacons = config.BeaconNodes;
                    foreach (var beacon in beacons)
                    {
                        Log.Write($"Querying beacon node {beacon}.");
                        var client   = new NodeClient(new Uri(beacon));
                        var nodeInfo = (await client.DownloadNodeInfo()).Data;
                        if (nodeInfo != null)
                        {
                            config.NetworkPublicKey = nodeInfo.NetworkKey.HexString;
                            Config.Save(config);
                            Log.Write($"Network key set to {config.NetworkPublicKey}.");
                            break;
                        }
                    }
                }

                if (config.NetworkPublicKey.IsNullOrEmpty())
                {
                    Log.Write("No valid network key found or set.", this);
                    return(false);
                }
            }

            NodeConfiguration = new NodeConfiguration(config, Config.Load <CoreKeyConfig>(Storage, false), Config.Load <ChainConfig>(Storage, false));
            Host = new Host(config);
            AttachementManager = new AttachementManager(this);
            ChainManager       = new ChainManager(this);
            if (!await ChainManager.Initalize())
            {
                return(false);
            }

            if (genesis)
            {
                var result = GenesisBlock.Generate(Storage);

                var blockData = new BlockData <CoreBlock>(result.Block, result.Signature);
                await ChainManager.Start(false);

                await ChainManager.CoreChain.BlockStorage.StoreBlock(blockData);

                ChainManager.ConsumeBlockData(blockData);

                Log.Write($"Genesis block and keys generated. Network public key: {result.NetworkPublicKey.HexString}.");

                var coreKeyConfig = Config.Load <CoreKeyConfig>(Storage);
                coreKeyConfig.Key      = result.NetworkVoteKey.HexString;
                coreKeyConfig.Password = result.NetworkVotePassword;

                config.NetworkPublicKey = result.NetworkPublicKey.HexString;

                Config.Save(config);
                Config.Save(coreKeyConfig);

                await ChainManager.Stop();

                await ChainManager.Start(true);

                if (result.ServiceTransactions.Count > 0)
                {
                    foreach (var serviceTransactions in result.ServiceTransactions)
                    {
                        var chainId      = serviceTransactions.Key;
                        var transactions = serviceTransactions.Value;

                        var serviceChain  = ChainManager.GetServiceChain(chainId);
                        var maintainChain = ChainManager.GetMaintainChain(chainId);
                        if (serviceChain != null)
                        {
                            var generator = new ServiceBlockGenerator(ChainManager.CoreChain, serviceChain, maintainChain, null);
                            foreach (var transaction in transactions)
                            {
                                generator.ConsumeTransaction(transaction);
                            }

                            var serviceBlock     = generator.GenerateBlock(0, 0);
                            var serviceBlockData = new BlockData <ServiceBlock>(serviceBlock, new BlockSignatures(serviceBlock));
                            await serviceChain.BlockStorage.StoreBlock(serviceBlockData);

                            serviceChain.ConsumeBlockData(serviceBlockData);
                        }
                    }
                }

                await ChainManager.Stop();

                return(false);
            }

            SyncManager = new SyncManager(this);
            await SyncManager.Start();

            //if (!await SyncManager.Start())
            //    return false;

            if (sync)
            {
                Log.Write("Sync done.");
                return(false);
            }

            AttachementManager.Start();

            Kademlia           = new Kademlia(Storage, this);
            TransactionManager = new TransactionManager(this);
            CouncilManager     = new CouncilManager(this);

            NodeServer   = new NodeServer(this, config.MaxIncomingConnections, config.MaxOutgoingConnectoins);
            ClientServer = new ClientServer(this);

            if (Host.EnableRemoteServices)
            {
                ServiceServer = new ServiceServer();
            }

            await(Host as Host).Start(this);
            return(true);
        }