Nullable providers
MODIFY
WalletWasabi.Fluent/Global.cs
WalletWasabi.Fluent/Global.cs
@@ -193,7 +193,7 @@ public class Global
var blockProvider = new SmartBlockProvider(
BitcoinStore.BlockRepository,
- new RpcBlockProvider(BitcoinCoreNode),
+ BitcoinCoreNode?.RpcClient is null ? null : new RpcBlockProvider(BitcoinCoreNode.RpcClient),
new SpecificNodeBlockProvider(Network, Config.ServiceConfiguration, HttpClientFactory),
new P2PBlockProvider(Network, HostedServices.Get<P2pNetwork>().Nodes, HttpClientFactory),
Cache);

MODIFY
WalletWasabi.Tests/IntegrationTests/P2pTests.cs
WalletWasabi.Tests/IntegrationTests/P2pTests.cs
@@ -111,7 +111,7 @@ public class P2pTests
IRepository<uint256, Block> blockRepository = bitcoinStore.BlockRepository;
IBlockProvider blockProvider = new SmartBlockProvider(
blockRepository,
- new RpcBlockProvider(null),
+ null,
new SpecificNodeBlockProvider(network, serviceConfig, httpClientFactory),
new P2PBlockProvider(network, nodes, httpClientFactory),
cache);

MODIFY
WalletWasabi.Tests/RegressionTests/BuildTests.cs
WalletWasabi.Tests/RegressionTests/BuildTests.cs
@@ -66,7 +66,7 @@ public class BuildTests
var blockProvider = new SmartBlockProvider(
bitcoinStore.BlockRepository,
- rpcBlockProvider: new RpcBlockProvider(null),
+ rpcBlockProvider: null,
specificNodeBlockProvider: new SpecificNodeBlockProvider(network, serviceConfiguration, httpClientFactory: httpClientFactory),
p2PBlockProvider: new P2PBlockProvider(network, nodes, httpClientFactory),
cache);
@@ -224,7 +224,7 @@ public class BuildTests
var blockProvider = new SmartBlockProvider(
bitcoinStore.BlockRepository,
- new RpcBlockProvider(null),
+ null,
new SpecificNodeBlockProvider(network, serviceConfiguration, httpClientFactory: httpClientFactory),
new P2PBlockProvider(network, nodes, httpClientFactory),
cache);

MODIFY
WalletWasabi.Tests/RegressionTests/SendTests.cs
WalletWasabi.Tests/RegressionTests/SendTests.cs
@@ -64,7 +64,7 @@ public class SendTests
var blockProvider = new SmartBlockProvider(
bitcoinStore.BlockRepository,
- rpcBlockProvider: new RpcBlockProvider(null),
+ rpcBlockProvider: null,
specificNodeBlockProvider: new SpecificNodeBlockProvider(network, serviceConfiguration, httpClientFactory: httpClientFactory),
new P2PBlockProvider(network, nodes, httpClientFactory),
cache);
@@ -547,7 +547,7 @@ public class SendTests
var blockProvider = new SmartBlockProvider(
bitcoinStore.BlockRepository,
- rpcBlockProvider: new RpcBlockProvider(null),
+ rpcBlockProvider: null,
specificNodeBlockProvider: new SpecificNodeBlockProvider(network, serviceConfiguration, httpClientFactory: httpClientFactory),
new P2PBlockProvider(network, nodes, httpClientFactory),
cache);
@@ -726,7 +726,7 @@ public class SendTests
var blockProvider = new SmartBlockProvider(
bitcoinStore.BlockRepository,
- new RpcBlockProvider(null),
+ null,
new SpecificNodeBlockProvider(network, serviceConfiguration, httpClientFactory: httpClientFactory),
new P2PBlockProvider(network, nodes, httpClientFactory),
cache);

MODIFY
WalletWasabi.Tests/RegressionTests/WalletTests.cs
WalletWasabi.Tests/RegressionTests/WalletTests.cs
@@ -258,7 +258,7 @@ public class WalletTests
SmartBlockProvider blockProvider = new SmartBlockProvider(
bitcoinStore.BlockRepository,
- new RpcBlockProvider(null),
+ null,
new SpecificNodeBlockProvider(network, serviceConfiguration, httpClientFactory: httpClientFactory),
new P2PBlockProvider(network, nodes, httpClientFactory),
cache);

MODIFY
WalletWasabi/Wallets/RpcBlockProvider.cs
WalletWasabi/Wallets/RpcBlockProvider.cs
using System.Threading;
using System.Threading.Tasks;
using NBitcoin;
-using WalletWasabi.BitcoinCore;
+using WalletWasabi.BitcoinCore.Rpc;
using WalletWasabi.Logging;
namespace WalletWasabi.Wallets;
public class RpcBlockProvider : IBlockProvider
{
- public RpcBlockProvider(CoreNode? coreNode)
+ public RpcBlockProvider(IRPCClient rpcClient)
{
- CoreNode = coreNode;
+ RpcClient = rpcClient;
}
- private CoreNode? CoreNode { get; }
+ private IRPCClient RpcClient { get; }
public async Task<Block?> TryGetBlockAsync(uint256 hash, CancellationToken cancellationToken)
{
- if (CoreNode?.RpcClient is null)
- {
- return null;
- }
-
try
{
- return await CoreNode!.RpcClient.GetBlockAsync(hash, cancellationToken).ConfigureAwait(false);
+ return await RpcClient.GetBlockAsync(hash, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{

MODIFY
WalletWasabi/Wallets/SmartBlockProvider.cs
WalletWasabi/Wallets/SmartBlockProvider.cs
@@ -19,12 +19,12 @@ public class SmartBlockProvider : IBlockProvider
};
[SuppressMessage("Style", "IDE0004:Remove Unnecessary Cast", Justification = "The cast is necessary to call the other constructor.")]
- public SmartBlockProvider(IRepository<uint256, Block> blockRepository, RpcBlockProvider rpcBlockProvider, SpecificNodeBlockProvider specificNodeBlockProvider, P2PBlockProvider p2PBlockProvider, IMemoryCache cache)
- : this(blockRepository, (IBlockProvider)rpcBlockProvider, (IBlockProvider)specificNodeBlockProvider, (IBlockProvider)p2PBlockProvider, cache)
+ public SmartBlockProvider(IRepository<uint256, Block> blockRepository, RpcBlockProvider? rpcBlockProvider, SpecificNodeBlockProvider? specificNodeBlockProvider, P2PBlockProvider? p2PBlockProvider, IMemoryCache cache)
+ : this(blockRepository, (IBlockProvider?)rpcBlockProvider, (IBlockProvider?)specificNodeBlockProvider, (IBlockProvider?)p2PBlockProvider, cache)
{
}
- internal SmartBlockProvider(IRepository<uint256, Block> blockRepository, IBlockProvider rpcBlockProvider, IBlockProvider specificNodeBlockProvider, IBlockProvider p2PBlockProvider, IMemoryCache cache)
+ internal SmartBlockProvider(IRepository<uint256, Block> blockRepository, IBlockProvider? rpcBlockProvider, IBlockProvider? specificNodeBlockProvider, IBlockProvider? p2PBlockProvider, IMemoryCache cache)
{
BlockRepository = blockRepository;
RpcProvider = rpcBlockProvider;
@@ -34,13 +34,13 @@ public class SmartBlockProvider : IBlockProvider
}
/// <seealso cref="RpcProvider"/>
- private IBlockProvider RpcProvider { get; }
+ private IBlockProvider? RpcProvider { get; }
/// <seealso cref="SpecificNodeProvider"/>
- private IBlockProvider SpecificNodeProvider { get; }
+ private IBlockProvider? SpecificNodeProvider { get; }
/// <seealso cref="P2PProvider"/>
- private IBlockProvider P2PProvider { get; }
+ private IBlockProvider? P2PProvider { get; }
private IdempotencyRequestCache Cache { get; }
private IRepository<uint256, Block> BlockRepository { get; }
@@ -82,9 +82,22 @@ public class SmartBlockProvider : IBlockProvider
/// <remarks>First ask the rpc, then the specific node block provider (both may or may not be set up) and use the P2P block provider as a fallback.</remarks>
private async Task<Block?> GetBlockNoCacheAsync(uint256 blockHash, CancellationToken cancellationToken)
{
- return await RpcProvider.TryGetBlockAsync(blockHash, cancellationToken).ConfigureAwait(false)
- ?? await SpecificNodeProvider.TryGetBlockAsync(blockHash, cancellationToken).ConfigureAwait(false)
- ?? await P2PProvider.TryGetBlockAsync(blockHash, cancellationToken).ConfigureAwait(false);
+ Block? result = null;
+
+ if (RpcProvider is not null)
+ {
+ result = await RpcProvider.TryGetBlockAsync(blockHash, cancellationToken).ConfigureAwait(false);
+ }
+ if (result is null && SpecificNodeProvider is not null)
+ {
+ result = await SpecificNodeProvider.TryGetBlockAsync(blockHash, cancellationToken).ConfigureAwait(false);
+ }
+ if (result is null && P2PProvider is not null)
+ {
+ result = await P2PProvider.TryGetBlockAsync(blockHash, cancellationToken).ConfigureAwait(false);
+ }
+
+ return result;
}
/// <summary>

Nullable providers