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)); }
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); }
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(); } } }
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); } }
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); }
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; }
//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"); }
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); }