//private async Task SyncManyBlocksAsync(LyraClientForNode client, ConsolidationBlock consBlock) //{ // _log.LogInformation($"Syncing Consolidations {consBlock.Height} / {consBlock.Hash.Shorten()} "); // var blocksResult = await client.GetBlocksByConsolidation(consBlock.Hash); // if (blocksResult.ResultCode == APIResultCodes.Success) // { // foreach (var block in blocksResult.GetBlocks()) // { // var localBlock = await _sys.Storage.FindBlockByHashAsync(block.Hash); // if (localBlock != null) // await _sys.Storage.RemoveBlockAsync(block.Hash); // await _sys.Storage.AddBlockAsync(block); // } // // save cons block itself // var localCons = await _sys.Storage.FindBlockByHashAsync(consBlock.Hash); // if (localCons != null) // await _sys.Storage.RemoveBlockAsync(consBlock.Hash); // await _sys.Storage.AddBlockAsync(consBlock); // } //} //private async Task SyncManyBlocksAsync(LyraClientForNode client, List<string> hashes) //{ // _log.LogInformation($"Syncing {hashes.Count()} blocks..."); // foreach (var hash in hashes) // { // var blockResult = await client.GetBlockByHash(hash); // if (blockResult.ResultCode == APIResultCodes.Success) // { // var localBlock = await _sys.Storage.FindBlockByHashAsync(hash); // if (localBlock != null) // await _sys.Storage.RemoveBlockAsync(hash); // await _sys.Storage.AddBlockAsync(blockResult.GetBlock()); // } // } //} private async Task <bool> SyncOneBlockAsync(ILyraAPI client, string hash) { if (null != await _sys.Storage.FindBlockByHashAsync(hash)) { await _sys.Storage.RemoveBlockAsync(hash); } var remoteBlock = await client.GetBlockByHashAsync(_sys.PosWallet.AccountId, hash, null); if (remoteBlock.ResultCode == APIResultCodes.Success) { var block = remoteBlock.GetBlock(); // when block stored into database, they lost their order. so it's hard to do verification style of authorizer. // and mixed with code change/logic upgrade, so just use hash verify to keep database integraty. //if(block is TransactionBlock tb) //{ // var authorizer = factory.Create(tb.BlockType); // var authResult = await authorizer.AuthorizeAsync(GetDagSystem(), tb); // if (authResult.Item1 != APIResultCodes.Success) // { // _log.LogWarning($"SyncOneBlockAsync: TX block {tb.Hash.Shorten()} failed to verify for {authResult.Item1}"); // } //} // non tx block just verify hash if (block != null && block.VerifyHash()) { return(await _sys.Storage.AddBlockAsync(block)); } else { _log.LogWarning($"Error SyncOneBlockAsync: block null? {block is null}"); if (!(block is null)) { _log.LogWarning($"Error SyncOneBlockAsync: block VerifyHash? {block.VerifyHash()}"); } return(false); } } else { _log.LogWarning($"Error SyncOneBlockAsync: remote return: {remoteBlock.ResultCode}"); return(false); } }
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)); }