MetacoSA / NBitcoin

Comprehensive Bitcoin library for the .NET framework.
MIT License
1.85k stars 839 forks source link

Getting Block, Block Height, Block Hash #1196

Open tunerji opened 6 months ago

tunerji commented 6 months ago

Dear Nicolas and NBitcoin Dev Community,

I have been practicing, I haven`t found so far working examples of getting blocks from the nodes.

I have successfully connected nodes and can be anle to gather full list, But when I wanted to get latest hash or specific block height hash, it is giving inccorect results

forexample : This one suppose to download from the nodeaddress the latest block hash/ But it is keep finding the hash from 2009!

public static async Task<uint256> GetLatestBlockHashAsync(NetworkAddress nodeAddress)
        {
            try
            {
                using (var node = await Node.ConnectAsync(Network.Main, nodeAddress.Endpoint))
                {
                    node.VersionHandshake(); // Negotiate the protocol version

                    // Create a new GetHeadersPayload message with a dummy BlockLocator
                    var getHeadersPayload = new GetHeadersPayload()
                    {
                        BlockLocators = new BlockLocator() { Blocks = { uint256.Zero } }
                    };

                    await node.SendMessageAsync(getHeadersPayload);
                    var headersPayload = node.ReceiveMessage<HeadersPayload>(TimeSpan.FromSeconds(30));

                    // Assuming the last header is the most recent
                    var latestHeader = headersPayload.Headers.LastOrDefault();
                    if (latestHeader != null)
                    {
                        return latestHeader.GetHash();
                    }
                    else
                    {
                        throw new Exception("No headers received.");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error retrieving latest block hash: {ex.Message}");
                return null;
            }
        }

those are other examples to get block hash from height and get block methods: somehow it works but bringing wrong values.

public static async Task<Block> GetBlock(NetworkAddress nodeAddress, uint256 blockHash)
        {
            try
            {
                using (var node = await Node.ConnectAsync(Network.Main, nodeAddress.Endpoint))
                {
                    node.VersionHandshake(); // Negotiate the protocol version

                    // Asynchronously request blocks
                    await node.SendMessageAsync(new GetDataPayload(new InventoryVector(InventoryType.MSG_BLOCK, blockHash)));
                    var blockPayload = node.ReceiveMessage<BlockPayload>();
                    return blockPayload.Object;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
                return null;
            }
        }

        public static async Task<uint256> GetBlockHashByHeightAsync(NetworkAddress nodeAddress, int blockHeight)
        {
            try
            {
                using (var node = await Node.ConnectAsync(Network.Main, nodeAddress.Endpoint))
                {
                    node.VersionHandshake(); // Negotiate the protocol version

                    // Create a block locator object
                    var blockLocator = new BlockLocator { Blocks = { new uint256() } }; // You might need to adjust this for your specific needs

                    // Request blocks starting from the specified height
                    node.SendMessageAsync(new GetBlocksPayload(blockLocator));
                    var invPayload = node.ReceiveMessage<InvPayload>(TimeSpan.FromMinutes(1));
                    var blockHash = invPayload.Inventory.Where(inv => inv.Type == InventoryType.MSG_BLOCK)
                        .Select(inv => inv.Hash)
                        .FirstOrDefault();

                    return blockHash;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
                return null;
            }
        }