Exemplo n.º 1
0
        /// <exception cref="ProtocolException"/>
        protected override void Parse()
        {
            _version          = ReadUint32();
            _prevBlockHash    = ReadHash();
            _merkleRoot       = ReadHash();
            _time             = ReadUint32();
            _difficultyTarget = 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 tx = new Transaction(Params, Bytes, Cursor);
                Transactions.Add(tx);
                Cursor += tx.MessageSize;
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Special case constructor, used for the genesis node, cloneAsHeader and unit tests.
 /// </summary>
 internal Block(NetworkParameters networkParams)
     : base(networkParams)
 {
     // Set up a few basic things. We are not complete after this though.
     _version          = 1;
     _difficultyTarget = 0x1d07fff8;
     _time             = (uint)UnixTime.ToUnixTime(DateTime.UtcNow);
     _prevBlockHash    = Sha256Hash.ZeroHash;
 }
Exemplo n.º 3
0
 /// <summary>
 /// Adds a transaction to this block.
 /// </summary>
 internal void AddTransaction(Transaction t)
 {
     if (Transactions == null)
     {
         Transactions = new List <Transaction>();
     }
     Transactions.Add(t);
     // Force a recalculation next time the values are needed.
     _merkleRoot = null;
     _hash       = null;
 }
Exemplo n.º 4
0
        /// <exception cref="IOException"/>
        private void BlockChainDownload(Sha256Hash toHash)
        {
            // This may run in ANY thread.

            // The block chain download process is a bit complicated. Basically, we start with zero or more blocks in a
            // chain that we have from a previous session. We want to catch up to the head of the chain BUT we don't know
            // where that chain is up to or even if the top block we have is even still in the chain - we
            // might have got ourselves onto a fork that was later resolved by the network.
            //
            // To solve this, we send the peer a block locator which is just a list of block hashes. It contains the
            // blocks we know about, but not all of them, just enough of them so the peer can figure out if we did end up
            // on a fork and if so, what the earliest still valid block we know about is likely to be.
            //
            // Once it has decided which blocks we need, it will send us an inv with up to 500 block messages. We may
            // have some of them already if we already have a block chain and just need to catch up. Once we request the
            // last block, if there are still more to come it sends us an "inv" containing only the hash of the head
            // block.
            //
            // That causes us to download the head block but then we find (in processBlock) that we can't connect
            // it to the chain yet because we don't have the intermediate blocks. So we rerun this function building a
            // new block locator describing where we're up to.
            //
            // The getblocks with the new locator gets us another inv with another bunch of blocks. We download them once
            // again. This time when the peer sends us an inv with the head block, we already have it so we won't download
            // it again - but we recognize this case as special and call back into blockChainDownload to continue the
            // process.
            //
            // So this is a complicated process but it has the advantage that we can download a chain of enormous length
            // in a relatively stateless manner and with constant/bounded memory usage.
            Log.InfoFormat("blockChainDownload({0})", toHash);

            // TODO: Block locators should be abstracted out rather than special cased here.
            var blockLocator = new LinkedList <Sha256Hash>();

            // We don't do the exponential thinning here, so if we get onto a fork of the chain we will end up
            // re-downloading the whole thing again.
            blockLocator.AddLast(_params.GenesisBlock.Hash);
            var topBlock = _blockChain.ChainHead.Header;

            if (!topBlock.Equals(_params.GenesisBlock))
            {
                blockLocator.AddFirst(topBlock.Hash);
            }
            var message = new GetBlocksMessage(_params, blockLocator.ToList(), toHash);

            _conn.WriteMessage(message);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Asks the connected peer for the block of the given hash, and returns a Future representing the answer.
        /// If you want the block right away and don't mind waiting for it, just call .get() on the result. Your thread
        /// will block until the peer answers. You can also use the Future object to wait with a timeout, or just check
        /// whether it's done later.
        /// </summary>
        /// <param name="blockHash">Hash of the block you were requesting.</param>
        /// <exception cref="IOException"/>
        public IAsyncResult BeginGetBlock(Sha256Hash blockHash, AsyncCallback callback, object state)
        {
            var getdata       = new GetDataMessage(_params);
            var inventoryItem = new InventoryItem(InventoryItem.ItemType.Block, blockHash);

            getdata.AddItem(inventoryItem);
            var future = new GetDataFuture <Block>(inventoryItem, callback, state);

            // Add to the list of things we're waiting for. It's important this come before the network send to avoid
            // race conditions.
            lock (_pendingGetBlockFutures)
            {
                _pendingGetBlockFutures.Add(future);
            }
            _conn.WriteMessage(getdata);
            return(future);
        }
Exemplo n.º 6
0
        /// <exception cref="IOException"/>
        private void BlockChainDownload(Sha256Hash toHash)
        {
            // This may run in ANY thread.

            // The block chain download process is a bit complicated. Basically, we start with zero or more blocks in a
            // chain that we have from a previous session. We want to catch up to the head of the chain BUT we don't know
            // where that chain is up to or even if the top block we have is even still in the chain - we
            // might have got ourselves onto a fork that was later resolved by the network.
            //
            // To solve this, we send the peer a block locator which is just a list of block hashes. It contains the
            // blocks we know about, but not all of them, just enough of them so the peer can figure out if we did end up
            // on a fork and if so, what the earliest still valid block we know about is likely to be.
            //
            // Once it has decided which blocks we need, it will send us an inv with up to 500 block messages. We may
            // have some of them already if we already have a block chain and just need to catch up. Once we request the
            // last block, if there are still more to come it sends us an "inv" containing only the hash of the head
            // block.
            //
            // That causes us to download the head block but then we find (in processBlock) that we can't connect
            // it to the chain yet because we don't have the intermediate blocks. So we rerun this function building a
            // new block locator describing where we're up to.
            //
            // The getblocks with the new locator gets us another inv with another bunch of blocks. We download them once
            // again. This time when the peer sends us an inv with the head block, we already have it so we won't download
            // it again - but we recognize this case as special and call back into blockChainDownload to continue the
            // process.
            //
            // So this is a complicated process but it has the advantage that we can download a chain of enormous length
            // in a relatively stateless manner and with constant/bounded memory usage.
            Log.InfoFormat("blockChainDownload({0})", toHash);

            // TODO: Block locators should be abstracted out rather than special cased here.
            var blockLocator = new LinkedList<Sha256Hash>();
            // We don't do the exponential thinning here, so if we get onto a fork of the chain we will end up
            // re-downloading the whole thing again.
            blockLocator.AddLast(_params.GenesisBlock.Hash);
            var topBlock = _blockChain.ChainHead.Header;
            if (!topBlock.Equals(_params.GenesisBlock))
                blockLocator.AddFirst(topBlock.Hash);
            var message = new GetBlocksMessage(_params, blockLocator.ToList(), toHash);
            _conn.WriteMessage(message);
        }
Exemplo n.º 7
0
 /// <summary>
 /// Asks the connected peer for the block of the given hash, and returns a Future representing the answer.
 /// If you want the block right away and don't mind waiting for it, just call .get() on the result. Your thread
 /// will block until the peer answers. You can also use the Future object to wait with a timeout, or just check
 /// whether it's done later.
 /// </summary>
 /// <param name="blockHash">Hash of the block you were requesting.</param>
 /// <exception cref="IOException"/>
 public IAsyncResult BeginGetBlock(Sha256Hash blockHash, AsyncCallback callback, object state)
 {
     var getdata = new GetDataMessage(_params);
     var inventoryItem = new InventoryItem(InventoryItem.ItemType.Block, blockHash);
     getdata.AddItem(inventoryItem);
     var future = new GetDataFuture<Block>(inventoryItem, callback, state);
     // Add to the list of things we're waiting for. It's important this come before the network send to avoid
     // race conditions.
     lock (_pendingGetBlockFutures)
     {
         _pendingGetBlockFutures.Add(future);
     }
     _conn.WriteMessage(getdata);
     return future;
 }
Exemplo n.º 8
0
 public GetBlocksMessage(NetworkParameters networkParams, IList<Sha256Hash> locator, Sha256Hash stopHash)
     : base(networkParams)
 {
     _locator = locator;
     _stopHash = stopHash;
 }
Exemplo n.º 9
0
        /// <exception cref="ProtocolException"/>
        protected override void Parse()
        {
            _version = ReadUint32();
            _prevBlockHash = ReadHash();
            _merkleRoot = ReadHash();
            _time = ReadUint32();
            _difficultyTarget = 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 tx = new Transaction(Params, Bytes, Cursor);
                Transactions.Add(tx);
                Cursor += tx.MessageSize;
            }
        }
Exemplo n.º 10
0
 /// <summary>
 /// Adds a transaction to this block.
 /// </summary>
 internal void AddTransaction(Transaction t)
 {
     if (Transactions == null)
     {
         Transactions = new List<Transaction>();
     }
     Transactions.Add(t);
     // Force a recalculation next time the values are needed.
     _merkleRoot = null;
     _hash = null;
 }
Exemplo n.º 11
0
 /// <summary>
 /// Special case constructor, used for the genesis node, cloneAsHeader and unit tests.
 /// </summary>
 internal Block(NetworkParameters networkParams)
     : base(networkParams)
 {
     // Set up a few basic things. We are not complete after this though.
     _version = 1;
     _difficultyTarget = 0x1d07fff8;
     _time = (uint) UnixTime.ToUnixTime(DateTime.UtcNow);
     _prevBlockHash = Sha256Hash.ZeroHash;
 }
Exemplo n.º 12
0
 public GetBlocksMessage(NetworkParameters networkParams, IList <Sha256Hash> locator, Sha256Hash stopHash)
     : base(networkParams)
 {
     _locator  = locator;
     _stopHash = stopHash;
 }