async Task RetrieveBlocks(IBlocksRetrieverHandler handler) { var cancellationToken = this.retrieveBlocksCancelSource.Token; var height = await handler.GetBlockHintAsync(cancellationToken); while (true) { // Get block. Block block; using (var rpc = await this.rpc.CreateChainInformationRpcAsync(cancellationToken)) { try { block = await rpc.GetBlockAsync(height, cancellationToken); } catch (RPCException ex) when(ex.RPCCode == RPCErrorCode.RPC_INVALID_PARAMETER) { // Invalid block height. await WaitNewBlockAsync(cancellationToken); continue; } } // Execute handler. height = await handler.ProcessBlockAsync(block, height, cancellationToken); } }
async Task RetrieveBlocks(IBlocksRetrieverHandler handler) { var cancellationToken = this.retrieveBlocksCancelSource.Token; var height = await handler.GetStartBlockAsync(cancellationToken); while (true) { // Get block. Block block; using (var rpc = await this.rpc.CreateChainInformationRpcAsync(cancellationToken)) { try { block = await rpc.GetBlockAsync(height, cancellationToken); } catch (RPCException ex) when(ex.RPCCode == RPCErrorCode.RPC_INVALID_PARAMETER) // Invalid height. { var info = await rpc.GetChainInfoAsync(cancellationToken); var blocks = (int)info.Blocks; if (blocks >= height) { // There is a new block already. continue; } if (blocks == height - 1) { // A block of the target height is not available right now. await WaitNewBlockAsync(cancellationToken); continue; } // There is a re-org happened. await handler.DiscardBlocksAsync(blocks, cancellationToken); height = blocks; continue; } } // Execute handler. height = await handler.ProcessBlockAsync(block, height, cancellationToken); } }