public Block TryLoadBlock(ByteString id, byte[] data) { // Data should not exceed the maximum size. if (data.Length > MaximumBlockSize) { throw new ArgumentException(nameof(data)); } // Integrity check. var computedId = BlockchainUtil.ComputeBlockId(data); if (!ByteString.CopyFrom(computedId).Equals(id)) { throw new ArgumentException(nameof(id)); } // Try to deserialize the data for format validity check. var block = BlockchainUtil.DeserializeBlock(data); lock (Blocks) { if (Blocks.ContainsKey(id)) { return(null); } Blocks.Add(id, data); } // Schedule the block for execution. Executor.ProcessBlock(block); return(block); }
public IEnumerable <(ByteString, byte[])> LoadAll() { foreach (var file in Directory.GetFiles(storagePath)) { var bytes = File.ReadAllBytes(file); var block = BlockchainUtil.DeserializeBlock(bytes); yield return(block.Id, bytes); } }
//初期化 bool LoadConfiguration(string[] args) { if (args.Length == 0) { Console.WriteLine("Should provide configuration file path."); return(false); } // config読み込み try { config = JsonConvert.DeserializeObject <Configuration>( File.ReadAllText(Path.GetFullPath(args[0]))); } catch (Exception exp) { logger.LogError( "Failed to load configuration file. Run 'config' command.", exp); return(false); } // config内の鍵情報を読み込み try { myKeys = KeyPair.LoadFrom(config.KeyPairPath); } catch (Exception exp) { logger.LogError( $"Failed to load key from {config.KeyPairPath}.", exp); return(false); } // genesis.binの読み込み try { var bytes = File.ReadAllBytes(config.GenesisPath); genesis = BlockchainUtil.DeserializeBlock(bytes); } catch (Exception exp) { logger.LogError( $"Failed to load the genesis from {config.GenesisPath}.", exp); return(false); } return(true); }
bool LoadConfiguration(string[] args) { if (args.Length == 0) { Console.WriteLine("Should provide configuration file path."); return(false); } try { config = JsonConvert.DeserializeObject <Configuration>( File.ReadAllText(Path.GetFullPath(args[0]))); } catch (Exception exp) { logger.LogError( "Failed to load configuration file. Run 'config' command.", exp); return(false); } try { KeyPair seedKeyPair = KeyPair.LoadFrom(config.KeyPairPath); hwallet = new Wallet.HierachicalWallet(seedKeyPair); hwallet.init(10); hwallet.dumpAll(); System.Threading.Thread.Sleep(3000); } catch (Exception exp) { logger.LogError( $"Failed to load key from {config.KeyPairPath}.", exp); return(false); } try { var bytes = File.ReadAllBytes(config.GenesisPath); genesis = BlockchainUtil.DeserializeBlock(bytes); } catch (Exception exp) { logger.LogError( $"Failed to load the genesis from {config.GenesisPath}.", exp); return(false); } return(true); }
void CheckFloatingBlocks(ByteString waitingBlockId) { List <ByteString> pendingBlocks; if (floatingBlocks.TryGetValue(waitingBlockId, out pendingBlocks)) { foreach (var floatBlockId in pendingBlocks) { byte[] data = null; try { lock (InventoryManager.Blocks) data = InventoryManager.Blocks[floatBlockId]; } catch { } if (data.IsNull()) { continue; } ProcessBlockLocked(BlockchainUtil.DeserializeBlock(data)); } } }
async Task HandleBody(InventoryMessage message, int peerId) { // Data should not exceed the maximum size. var data = message.Data; if (data.Length > MaximumBlockSize) { throw new ArgumentException(); } // ハッシュ値正しい? var id = message.IsBlock ? BlockchainUtil.ComputeBlockId(data) : Hash.ComputeDoubleSHA256(data); if (!ByteString.CopyFrom(id).Equals(message.ObjectId)) { return; } if (message.IsBlock) { // ミューテックス lock (Blocks) { if (Blocks.ContainsKey(message.ObjectId)) { return; } // ハッシュテーブルに追加 Blocks.Add(message.ObjectId, data); } var block = BlockchainUtil.DeserializeBlock(data); // 前のブロックも知らなかったら前のももらう var prevId = block.PreviousHash; if (!Blocks.ContainsKey(prevId)) { await ConnectionManager.SendAsync(new InventoryMessage { Type = Request, IsBlock = true, ObjectId = prevId, }, peerId); } Executor.ProcessBlock(block); } else { if (MemoryPool.ContainsKey(message.ObjectId)) { return; } var tx = BlockchainUtil.DeserializeTransaction(data); // Ignore the coinbase transactions. if (tx.InEntries.Count == 0) { return; } lock (MemoryPool) { if (MemoryPool.ContainsKey(message.ObjectId)) { return; } MemoryPool.Add(message.ObjectId, tx); } } message.Type = Advertise; message.Data = null; // 他の人に教えてあげる await ConnectionManager.BroadcastAsync(message, peerId); }
bool LoadConfiguration(string[] args) { if (args.Length == 0) { Console.WriteLine("Should provide configuration file path."); return false; } try { config = JsonConvert.DeserializeObject<Configuration>( File.ReadAllText(Path.GetFullPath(args[0]))); } catch (Exception exp) { logger.LogError( "Failed to load configuration file. Run 'config' command.", exp); return false; } try { myKeys = KeyPair.LoadFrom(config.KeyPairPath); } catch (Exception exp) { logger.LogError( $"Failed to load key from {config.KeyPairPath}.", exp); return false; } try { var bytes = File.ReadAllBytes(config.GenesisPath); genesis = BlockchainUtil.DeserializeBlock(bytes); } catch (Exception exp) { logger.LogError( $"Failed to load the genesis from {config.GenesisPath}.", exp); return false; } try { if (!string.IsNullOrEmpty(config.StoragePath)) storage = new Storage(config.StoragePath); } catch (Exception exp) { logger.LogError( $@"Failed to set up blockchain storage at { config.StoragePath}.", exp); return false; } return true; }
void ProcessBlockLocked(byte[] data, ByteString prevId) { Block prev; if (!Blocks.TryGetValue(prevId, out prev)) { // If the previous block is not under the block tree, mark the // block as floating. List <ByteString> blocks; if (!floatingBlocks.TryGetValue(prevId, out blocks)) { floatingBlocks[prevId] = blocks = new List <ByteString>(); } blocks.Add(prevId); return; } // Mark the block as the connected block. var block = BlockchainUtil.DeserializeBlock(data); block.Height = prev.Height + 1; block.TotalDifficulty = prev.TotalDifficulty + block.Difficulty; Blocks.Add(block.Id, block); // If the block difficulty does not surpass the current latest, // skip the execution. Once the descendant block comes later, // evaluate the difficulty then again. if (Latest.TotalDifficulty >= block.TotalDifficulty) { CheckFloatingBlocks(block.Id); return; } // Otherwise, try to execute the block. Considering the block folk, // first revert all the applied blocks prior to the fork point in // past blocks, if exists. Then apply blocks after the fork. var fork = BlockchainUtil.LowestCommonAncestor( Latest, block, Blocks); var revertingChain = Latest.Ancestors(Blocks) .TakeWhile(x => !x.Id.Equals(fork.Id)) .ToList(); var applyingChain = block.Ancestors(Blocks) .TakeWhile(x => !x.Id.Equals(fork.Id)) .Reverse() .ToList(); revertingChain.ForEach(Revert); int?failureIndex = null; for (var i = 0; i < applyingChain.Count; i++) { var applyBlock = applyingChain[i]; try { Run(applyBlock); } catch { // The block was invalid. Revert. PurgeBlock(applyBlock.Id); failureIndex = i; break; } Apply(applyBlock); } if (failureIndex.HasValue) { // Failure occurred during the block execution. Perform // opposite to revert to the state before the execution. applyingChain.Take(failureIndex.Value) .Reverse().ToList().ForEach(Revert); revertingChain.Reverse(); revertingChain.ForEach(Apply); return; } CheckFloatingBlocks(block.Id); }