public ConsolidationBlock CreateConsolidationGenesisBlock(ServiceBlock svcGen, LyraTokenGenesisBlock lyraGen, PoolFactoryBlock pf) { var consBlock = new ConsolidationBlock { createdBy = ProtocolSettings.Default.StandbyValidators[0], blockHashes = new List <string>() { svcGen.Hash, lyraGen.Hash, pf.Hash }, totalBlockCount = 3 // not including self }; consBlock.TimeStamp = DateTime.UtcNow.AddSeconds(-18); var mt = new MerkleTree(); mt.AppendLeaf(MerkleHash.Create(svcGen.Hash)); mt.AppendLeaf(MerkleHash.Create(lyraGen.Hash)); mt.AppendLeaf(MerkleHash.Create(pf.Hash)); consBlock.MerkelTreeHash = mt.BuildTree().ToString(); consBlock.ServiceHash = svcGen.Hash; consBlock.totalFees = lyraGen.Fee.ToBalanceLong(); consBlock.InitializeBlock(null, _sys.PosWallet.PrivateKey, _sys.PosWallet.AccountId); return(consBlock); }
public void CreateUnbalancedTreeTest() { MerkleTree tree = new MerkleTree(); tree.AppendLeaf(MerkleHash.Create("abc")); tree.AppendLeaf(MerkleHash.Create("def")); tree.AppendLeaf(MerkleHash.Create("123")); tree.BuildTree(); Assert.NotNull(tree.RootNode); }
private async Task <bool> VerifyConsolidationBlock(ConsolidationBlock consBlock, long latestHeight = -1) { _log.LogInformation($"VerifyConsolidationBlock: {consBlock.Height}/{latestHeight}"); var myConsBlock = await FindBlockByHashAsync(consBlock.Hash) as ConsolidationBlock; if (myConsBlock == null) { return(false); } var mt = new MerkleTree(); foreach (var hash in myConsBlock.blockHashes) { var myBlock = await FindBlockByHashAsync(hash); if (myBlock == null) { return(false); } mt.AppendLeaf(MerkleHash.Create(hash)); } var merkelTreeHash = mt.BuildTree().ToString(); return(consBlock.MerkelTreeHash == merkelTreeHash); }
public void ConsistencyTest() { // Start with a tree with 2 leaves: MerkleTree tree = new MerkleTree(); var startingNodes = tree.AppendLeaves(new MerkleHash[] { MerkleHash.Create("1"), MerkleHash.Create("2"), }); // startingNodes.ForEachWithIndex((n, i) => n.Text = i.ToString()); MerkleHash firstRoot = tree.BuildTree(); List <MerkleHash> oldRoots = new List <MerkleHash>() { firstRoot }; // Add a new leaf and verify that each time we add a leaf, we can get a consistency check // for all the previous leaves. for (int i = 2; i < 100; i++) { tree.AppendLeaf(MerkleHash.Create(i.ToString())); //.Text=i.ToString(); tree.BuildTree(); // After adding a leaf, verify that all the old root hashes exist. oldRoots.ForEachWithIndex((oldRootHash, n) => { List <MerkleProofHash> proof = tree.ConsistencyProof(n + 2); MerkleHash hash, lhash, rhash; if (proof.Count > 1) { lhash = proof[proof.Count - 2].Hash; int hidx = proof.Count - 1; hash = rhash = MerkleTree.ComputeHash(lhash, proof[hidx].Hash); hidx -= 2; while (hidx >= 0) { lhash = proof[hidx].Hash; hash = rhash = MerkleTree.ComputeHash(lhash, rhash); --hidx; } } else { hash = proof[0].Hash; } Assert.True(hash == oldRootHash, "Old root hash not found for index " + i + " m = " + (n + 2).ToString()); }); // Then we add this root hash as the next old root hash to check. oldRoots.Add(tree.RootNode.Hash); } }
private void BuildMerkleTree() { merkleTree = new MerkleTree(); foreach (var txn in Transactions) { merkleTree.AppendLeaf(MerkleHash.Create(txn.CalculateTransactionHash())); } merkleTree.BuildTree(); }
private void BuildMerkleTree() { _merkleTree = new MerkleTree(); foreach (ITransaction transaction in Transactions) { _merkleTree.AppendLeaf(MerkleHash.Create(transaction.CalculateTransactionHash())); } _merkleTree.BuildTree(); }
public void BuildMerkleTree() { merkleTreeObj = new MerkleTree(); foreach (ITransaction transaction in Transaction) { merkleTreeObj.AppendLeaf(MerkleHash.Create(transaction.CalculateTransactionHash())); } merkleTreeObj.BuildTree(); }
public void CreateTree(MerkleTree tree, int numLeaves) { List <DemoMerkleNode> leaves = new List <DemoMerkleNode>(); for (int i = 0; i < numLeaves; i++) { tree.AppendLeaf(DemoMerkleNode.Create(i.ToString()).SetText(i.ToString("X"))); } tree.BuildTree(); }
public ConsolidationBlock GetConsolidationGenesisBlock(ServiceBlock svcGen, LyraTokenGenesisBlock lyraGen) { var consBlock = new ConsolidationBlock { blockHashes = new List <string>() { svcGen.Hash, lyraGen.Hash }, totalBlockCount = 2 // not including self }; var mt = new MerkleTree(); mt.AppendLeaf(MerkleHash.Create(svcGen.Hash)); mt.AppendLeaf(MerkleHash.Create(lyraGen.Hash)); consBlock.MerkelTreeHash = mt.BuildTree().ToString(); consBlock.ServiceHash = svcGen.Hash; consBlock.InitializeBlock(null, NodeService.Instance.PosWallet.PrivateKey, NodeService.Instance.PosWallet.AccountId); return(consBlock); }
public string GetUnConsolidatedHash(List <string> unCons) { if (unCons.Count() == 0) { return(null); } var mt = new MerkleTree(); foreach (var hash in unCons) { mt.AppendLeaf(MerkleHash.Create(hash)); } return(mt.BuildTree().ToString()); }
public void RootNodeTest() { var tree = new MerkleTree(); for (int i = 0; i <= 65; i++) { tree.AppendLeaf(new MerkleNode(MerkleHash.Create(i.ToString()))); Assert.Equal(tree.CurrentParent.Root.Hash, tree.RootNode.Hash); } tree = new MerkleTree(); for (int i = 0; i <= 65; i++) { tree.AppendLeaf(new MerkleNode(MerkleHash.Create(i.ToString()))); } Assert.Equal(tree.CurrentParent.Root.Hash, tree.RootNode.Hash); }
public async Task <MultiBlockAPIResult> GetBlocksByConsolidation(string AccountId, string Signature, string consolidationHash) { var result = new MultiBlockAPIResult(); if (!await VerifyClientAsync(AccountId, Signature)) { result.ResultCode = APIResultCodes.APISignatureValidationFailed; return(result); } var consBlock = (await BlockChain.Singleton.FindBlockByHashAsync(consolidationHash)) as ConsolidationBlock; if (consBlock == null) { result.ResultCode = APIResultCodes.BlockNotFound; return(result); } var mt = new MerkleTree(); var blocks = new Block[consBlock.blockHashes.Count]; for (int i = 0; i < blocks.Length; i++) { blocks[i] = await BlockChain.Singleton.FindBlockByHashAsync(consBlock.blockHashes[i]); mt.AppendLeaf(MerkleHash.Create(blocks[i].Hash)); } var merkelTreeHash = mt.BuildTree().ToString(); if (consBlock.MerkelTreeHash == merkelTreeHash) { result.SetBlocks(blocks); result.ResultCode = APIResultCodes.Success; return(result); } else { // never replicate error data result.ResultCode = APIResultCodes.BlockValidationFailed; return(result); } }
private async Task <bool> SyncAndVerifyConsolidationBlockAsync(ILyraAPI client, ConsolidationBlock consBlock) { _log.LogInformation($"Sync and verify consolidation block height {consBlock.Height}"); foreach (var hash in consBlock.blockHashes) { if (!await SyncOneBlockAsync(client, hash)) { return(false); } } if (null != await _sys.Storage.FindBlockByHashAsync(consBlock.Hash)) { await _sys.Storage.RemoveBlockAsync(consBlock.Hash); } var mt = new MerkleTree(); foreach (var hash1 in consBlock.blockHashes) { mt.AppendLeaf(MerkleHash.Create(hash1)); } var merkelTreeHash = mt.BuildTree().ToString(); if (consBlock.MerkelTreeHash != merkelTreeHash) { _log.LogWarning($"SyncAndVerifyConsolidationBlock: consMerkelTree: {consBlock.MerkelTreeHash} mine: {merkelTreeHash}"); return(false); } // make sure no extra blocks here if (consBlock.Height > 1) { var prevConsHash = consBlock.blockHashes.First(); var prevConsResult = await client.GetBlockByHashAsync(_sys.PosWallet.AccountId, prevConsHash, null); if (prevConsResult.ResultCode != APIResultCodes.Success) { _log.LogWarning($"SyncAndVerifyConsolidationBlock: prevConsResult.ResultCode: {prevConsResult.ResultCode}"); return(false); } var prevConsBlock = prevConsResult.GetBlock() as ConsolidationBlock; if (prevConsBlock == null) { _log.LogWarning($"SyncAndVerifyConsolidationBlock: prevConsBlock: null"); return(false); } var blocksInTimeRange = await _sys.Storage.GetBlockHashesByTimeRangeAsync(prevConsBlock.TimeStamp, consBlock.TimeStamp); var q = blocksInTimeRange.Where(a => !consBlock.blockHashes.Contains(a)); foreach (var extraBlock in q) { await _sys.Storage.RemoveBlockAsync(extraBlock); } } return(await _sys.Storage.AddBlockAsync(consBlock)); }
protected override async Task <APIResultCodes> AuthorizeImplAsync <T>(DagSystem sys, T tblock) { if (!(tblock is ConsolidationBlock)) { return(APIResultCodes.InvalidBlockType); } var block = tblock as ConsolidationBlock; //// 1. check if the block already exists //if (null != await DagSystem.Singleton.Storage.GetBlockByUIndexAsync(block.UIndex)) // return APIResultCodes.BlockWithThisUIndexAlreadyExists; var lastCons = await sys.Storage.GetLastConsolidationBlockAsync(); if (block.Height > 1) { if (lastCons == null) { return(APIResultCodes.CouldNotFindLatestBlock); } // make sure the first hash is ALWAYS the previous consblock (except the first one) if (block.blockHashes.First() != lastCons.Hash) { return(APIResultCodes.InvalidConsolidationBlockContinuty); } var allHashes = (await sys.Storage.GetBlockHashesByTimeRangeAsync(lastCons.TimeStamp, block.TimeStamp)).ToList(); if (block.blockHashes.Count != allHashes.Count) { Console.WriteLine($"real count: {allHashes.Count} but block has: {block.blockHashes.Count}"); return(APIResultCodes.InvalidConsolidationBlockCount); } var mineNotYours = allHashes.Except(block.blockHashes).ToList(); var yoursNotMine = block.blockHashes.Except(allHashes).ToList(); if (mineNotYours.Any() || yoursNotMine.Any()) { return(APIResultCodes.InvalidConsolidationBlockHashes); } } // recalculate merkeltree // use merkle tree to consolidate all previous blocks, from lastCons.UIndex to consBlock.UIndex -1 var mt = new MerkleTree(); decimal feeAggregated = 0; foreach (var hash in block.blockHashes) { mt.AppendLeaf(MerkleHash.Create(hash)); // verify block exists if (null == await sys.Storage.FindBlockByHashAsync(hash)) { return(APIResultCodes.BlockNotFound); } // aggregate fees var transBlock = (await sys.Storage.FindBlockByHashAsync(hash)) as TransactionBlock; if (transBlock != null) { feeAggregated += transBlock.Fee; } } var mkhash = mt.BuildTree().ToString(); if (block.MerkelTreeHash != mkhash) { return(APIResultCodes.InvalidConsolidationMerkleTreeHash); } if (block.totalFees != feeAggregated.ToBalanceLong()) { return(APIResultCodes.InvalidConsolidationTotalFees); } // consolidation must come from leader node // done in base authorizer already! return(await Lyra.Shared.StopWatcher.TrackAsync(() => base.AuthorizeImplAsync(sys, tblock), "ConsolidationBlockAuthorizer->BaseAuthorizer")); }
private void GenerateConsolidateBlock() { var authGenesis = BlockChain.Singleton.GetLastServiceBlock(); var lastCons = BlockChain.Singleton.GetSyncBlock(); var consBlock = new ConsolidationBlock { UIndex = _UIndexSeed++, NetworkId = authGenesis.NetworkId, ShardId = authGenesis.ShardId, ServiceHash = authGenesis.Hash, SvcAccountID = NodeService.Instance.PosWallet.AccountId }; // use merkle tree to consolidate all previous blocks, from lastCons.UIndex to consBlock.UIndex -1 var mt = new MerkleTree(); for (var ndx = lastCons.UIndex; ndx < consBlock.UIndex; ndx++) // TODO: handling "losing" block here { var block = BlockChain.Singleton.GetBlockByUIndex(ndx); if (block == null) { // block lost _log.LogError($"Block lost for No. {ndx}. Try to resync with other seeds..."); // triggering a resync Mode = ConsensusWorkingMode.OutofSyncWaiting; LyraSystem.Singleton.TheBlockchain.Tell(new BlockChain.NeedSync { ToUIndex = ndx }); return; } var mhash = MerkleHash.Create(block.UHash); mt.AppendLeaf(mhash); } consBlock.MerkelTreeHash = mt.BuildTree().ToString(); consBlock.InitializeBlock(lastCons, NodeService.Instance.PosWallet.PrivateKey, authGenesis.NetworkId, authGenesis.ShardId, NodeService.Instance.PosWallet.AccountId); //consBlock.UHash = SignableObject.CalculateHash($"{consBlock.UIndex}|{consBlock.Index}|{consBlock.Hash}"); //consBlock.Authorizations = new List<AuthorizationSignature>(); //consBlock.Authorizations.Add(new AuthorizationSignature //{ // Key = NodeService.Instance.PosWallet.AccountId, // Signature = Signatures.GetSignature(NodeService.Instance.PosWallet.PrivateKey, consBlock.Hash + consBlock.ServiceHash, NodeService.Instance.PosWallet.AccountId) //}); //BlockChain.Singleton.AddBlock(consBlock); //// broadcast to whole network //var msg = new ChatMsg(NodeService.Instance.PosWallet.AccountId, JsonConvert.SerializeObject(consBlock)); //msg.MsgType = ChatMessageType.BlockConsolidation; //Send2P2pNetwork(msg); // no, we do consensus AuthorizingMsg msg = new AuthorizingMsg { From = NodeService.Instance.PosWallet.AccountId, Block = consBlock, MsgType = ChatMessageType.AuthorizerPrePrepare }; var state = CreateAuthringState(msg); var localAuthResult = LocalAuthorizingAsync(msg); state.AddAuthResult(localAuthResult); if (!localAuthResult.IsSuccess) { _log.LogError("Fatal Error: Consolidate block local authorization failed."); } else { Send2P2pNetwork(msg); Send2P2pNetwork(localAuthResult); } }