/// <exception cref="BlockStoreException"/> public StoredBlock Get(Sha256Hash hash) { lock (this) { StoredBlock block; _blockMap.TryGetValue(hash, out block); return block; } }
public static void Run(string[] args) { Console.WriteLine("Connecting to node"); var @params = NetworkParameters.ProdNet(); using (var blockStore = new MemoryBlockStore(@params)) { var chain = new BlockChain(@params, blockStore); var peer = new Peer(@params, new PeerAddress(IPAddress.Loopback), chain); peer.Connect(); new Thread(peer.Run).Start(); var blockHash = new Sha256Hash(args[0]); var future = peer.BeginGetBlock(blockHash, null, null); Console.WriteLine("Waiting for node to send us the requested block: " + blockHash); var block = peer.EndGetBlock(future); Console.WriteLine(block); peer.Disconnect(); } }
// All zeros. /// <exception cref="ProtocolException"/> protected override void Parse() { Hash = ReadHash(); Index = (int) ReadUint32(); }
public InventoryItem(ItemType type, Sha256Hash hash) { Type = type; Hash = hash; }
/// <exception cref="System.IO.IOException"/> /// <exception cref="BlockStoreException"/> private void Load(FileInfo file) { Log.InfoFormat("Reading block store from {0}", file); if (_channel != null) { _channel.Dispose(); } _channel = file.OpenRead(); try { // Read a version byte. var version = _channel.Read(); if (version == -1) { // No such file or the file was empty. throw new FileNotFoundException(file.Name + " does not exist or is empty"); } if (version != FileFormatVersion) { throw new BlockStoreException("Bad version number: " + version); } // Chain head pointer is the first thing in the file. var chainHeadHash = new byte[32]; if (_channel.Read(chainHeadHash) < chainHeadHash.Length) throw new BlockStoreException("Truncated store: could not read chain head hash."); _chainHead = new Sha256Hash(chainHeadHash); Log.InfoFormat("Read chain head from disk: {0}", _chainHead); _channel.Position = _channel.Length - Record.Size; } catch (IOException) { _channel.Close(); throw; } catch (BlockStoreException) { _channel.Close(); throw; } }
/// <exception cref="BlockStoreException"/> /// <exception cref="System.IO.IOException"/> /// <exception cref="BitcoinSharp.Core.Exceptions.ProtocolException"/> private Record GetRecord(Sha256Hash hash) { var startPos = _channel.Position; // Use our own file pointer within the tight loop as updating channel positions is really expensive. var position = startPos; var record = new Record(); do { if (!record.Read(_channel, position, _buf)) throw new IOException("Failed to read buffer"); if (record.GetHeader(_params).Hash.Equals(hash)) { // Found it. Update file position for next time. _channel.Position = position; return record; } // Did not find it. if (position == 1 + 32) { // At the start so wrap around to the end. position = _channel.Length - Record.Size; } else { // Move backwards. position = position - Record.Size; Debug.Assert(position >= 1 + 32, position.ToString(CultureInfo.InvariantCulture)); } } while (position != startPos); // Was never stored. _channel.Position = position; return null; }
/// <exception cref="BlockStoreException"/> private void CreateNewStore(NetworkParameters @params, FileInfo file) { // Create a new block store if the file wasn't found or anything went wrong whilst reading. _blockCache.Clear(); try { if (_channel != null) { _channel.Dispose(); _channel = null; } if (file.Exists) { try { file.Delete(); } catch (IOException) { throw new BlockStoreException("Could not delete old store in order to recreate it"); } } _channel = file.Create(); // Create fresh. _channel.Write(FileFormatVersion); } catch (IOException e1) { // We could not load a block store nor could we create a new one! throw new BlockStoreException(e1); } try { // Set up the genesis block. When we start out fresh, it is by definition the top of the chain. var genesis = @params.GenesisBlock.CloneAsHeader(); var storedGenesis = new StoredBlock(genesis, genesis.GetWork(), 0); _chainHead = storedGenesis.BlockHeader.Hash; _channel.Write(_chainHead.Bytes); Put(storedGenesis); } catch (IOException e) { throw new BlockStoreException(e); } }
/// <exception cref="BlockStoreException"/> public void SetChainHead(StoredBlock chainHead) { lock (this) { try { _chainHead = chainHead.BlockHeader.Hash; // Write out new hash to the first 32 bytes of the file past one (first byte is version number). var originalPos = _channel.Position; _channel.Position = 1; var bytes = _chainHead.Bytes; _channel.Write(bytes, 0, bytes.Length); _channel.Position = originalPos; } catch (IOException e) { throw new BlockStoreException(e); } } }
/// <exception cref="BlockStoreException"/> public StoredBlock Get(Sha256Hash hash) { lock (this) { if (_blockCache.Contains(hash)) { return _blockCache[hash] as StoredBlock; } if (_notFoundCache.Contains(hash) && Equals(_notFoundCache[hash] as StoredBlock, _notFoundMarker)) { return null; } try { var fromDisk = GetRecord(hash); StoredBlock block = null; if (fromDisk == null) { _notFoundCache[hash] = _notFoundMarker; while (_notFoundCache.Count > 2050) { _notFoundCache.RemoveAt(0); } } else { block = fromDisk.ToStoredBlock(_params); _blockCache[hash] = block; while (_blockCache.Count > 2050) { _blockCache.RemoveAt(0); } } return block; } catch (IOException e) { throw new BlockStoreException(e); } catch (ProtocolException e) { throw new BlockStoreException(e); } } }
public GetBlocksMessage(NetworkParameters networkParameters, IList<Sha256Hash> locator, Sha256Hash stopHash) : base(networkParameters) { _locator = locator; _stopHash = stopHash; }
/// <exception cref="ProtocolException" /> protected override void Parse() { _version = ReadUint32(); _previousBlockHash = ReadHash(); _merkleRoot = ReadHash(); _time = ReadUint32(); _targetDifficulty = ReadUint32(); _nonce = ReadUint32(); _hash = new Sha256Hash(Utils.ReverseBytes(Utils.DoubleDigest(Bytes, 0, Cursor))); if (Cursor == Bytes.Length) { // This message is just a header, it has no transactions. return; } var numTransactions = (int) ReadVarInt(); Transactions = new List<Transaction>(numTransactions); for (var i = 0; i < numTransactions; i++) { var transaction = new Transaction(NetworkParameters, Bytes, Cursor); Transactions.Add(transaction); Cursor += transaction.MessageSize; } }
/// <summary> /// Adds a transaction to this block. /// </summary> public void AddTransaction(Transaction transaction) { if (Transactions == null) { Transactions = new List<Transaction>(); } Transactions.Add(transaction); // Force a recalculation next time the values are needed. _merkleRoot = null; _hash = null; }
/// <summary> /// Special case constructor, used for the genesis node, cloneAsHeader and unit tests. /// </summary> internal Block(NetworkParameters networkParameters) : base(networkParameters) { // Set up a few basic things. We are not complete after this though. _version = 1; _targetDifficulty = 0x1d07fff8; _time = (uint) SystemTime.UnixNow(); _previousBlockHash = Sha256Hash.ZeroHash; }
/// <exception cref="System.IO.IOException"/> /// <exception cref="BlockStoreException"/> private void Load(FileInfo file) { _log.InfoFormat("Reading block store from {0}", file); using (var input = file.OpenRead()) { // Read a version byte. var version = input.Read(); if (version == -1) { // No such file or the file was empty. throw new FileNotFoundException(file.Name + " does not exist or is empty"); } if (version != 1) { throw new BlockStoreException("Bad version number: " + version); } // Chain head pointer is the first thing in the file. var chainHeadHash = new byte[32]; if (StreamExtensions.Read(input, chainHeadHash) < chainHeadHash.Length) throw new BlockStoreException("Truncated block store: cannot read chain head hash"); _chainHead = new Sha256Hash(chainHeadHash); _log.InfoFormat("Read chain head from disk: {0}", _chainHead); var now = Environment.TickCount; // Rest of file is raw block headers. var headerBytes = new byte[Block.HeaderSize]; try { while (true) { // Read a block from disk. if (StreamExtensions.Read(input, headerBytes) < 80) { // End of file. break; } // Parse it. var b = new Block(_params, headerBytes); // Look up the previous block it connects to. var prev = Get(b.PreviousBlockHash); StoredBlock s; if (prev == null) { // First block in the stored chain has to be treated specially. if (b.Equals(_params.GenesisBlock)) { s = new StoredBlock(_params.GenesisBlock.CloneAsHeader(), _params.GenesisBlock.GetWork(), 0); } else { throw new BlockStoreException("Could not connect " + b.Hash + " to " + b.PreviousBlockHash); } } else { // Don't try to verify the genesis block to avoid upsetting the unit tests. b.VerifyHeader(); // Calculate its height and total chain work. s = prev.Build(b); } // Save in memory. _blockMap[b.Hash] = s; } } catch (ProtocolException e) { // Corrupted file. throw new BlockStoreException(e); } catch (VerificationException e) { // Should not be able to happen unless the file contains bad blocks. throw new BlockStoreException(e); } var elapsed = Environment.TickCount - now; _log.InfoFormat("Block chain read complete in {0}ms", elapsed); } }
/// <exception cref="BlockStoreException"/> private void CreateNewStore(NetworkParameters @params, FileInfo file) { // Create a new block store if the file wasn't found or anything went wrong whilst reading. _blockMap.Clear(); try { if (_stream != null) { _stream.Dispose(); } _stream = file.OpenWrite(); // Do not append, create fresh. _stream.Write(1); // Version. } catch (IOException e1) { // We could not load a block store nor could we create a new one! throw new BlockStoreException(e1); } try { // Set up the genesis block. When we start out fresh, it is by definition the top of the chain. var genesis = @params.GenesisBlock.CloneAsHeader(); var storedGenesis = new StoredBlock(genesis, genesis.GetWork(), 0); _chainHead = storedGenesis.BlockHeader.Hash; _stream.Write(_chainHead.Bytes); Put(storedGenesis); } catch (IOException e) { throw new BlockStoreException(e); } }
/// <exception cref="BlockStoreException"/> public void SetChainHead(StoredBlock chainHead) { lock (this) { try { _chainHead = chainHead.BlockHeader.Hash; // Write out new hash to the first 32 bytes of the file past one (first byte is version number). _stream.Seek(1, SeekOrigin.Begin); var bytes = _chainHead.Bytes; _stream.Write(bytes, 0, bytes.Length); } catch (IOException e) { throw new BlockStoreException(e); } } }