/// <exception cref="BlockStoreException"/>
 public StoredBlock Get(Sha256Hash hash)
 {
     lock (this)
     {
         StoredBlock block;
         _blockMap.TryGetValue(hash, out block);
         return block;
     }
 }
Example #2
0
        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();
 }
Example #4
0
 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);
                }
            }
        }
Example #10
0
 public GetBlocksMessage(NetworkParameters networkParameters, IList<Sha256Hash> locator, Sha256Hash stopHash)
     : base(networkParameters)
 {
     _locator = locator;
     _stopHash = stopHash;
 }
Example #11
0
        /// <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;
            }
        }
Example #12
0
 /// <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;
 }
Example #13
0
 /// <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;
 }
Example #14
0
 /// <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);
     }
 }
Example #15
0
 /// <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);
     }
 }
Example #16
0
 /// <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);
         }
     }
 }