Skip to content
Snippets Groups Projects
Commit 3490e96f authored by vjrj's avatar vjrj
Browse files

Take into account node current blocks

parent 5f00ed70
No related branches found
No related tags found
No related merge requests found
......@@ -8,33 +8,31 @@ part 'node.g.dart';
@JsonSerializable()
class Node extends Equatable implements IsJsonSerializable<Node> {
const Node({
required this.url,
this.latency = 99999,
this.errors = 0,
});
const Node(
{required this.url,
this.latency = 99999,
this.errors = 0,
this.currentBlock = 0});
factory Node.fromJson(Map<String, dynamic> json) => _$NodeFromJson(json);
final String url;
final int latency;
final int errors;
final int currentBlock;
Node copyWith({
String? url,
int? latency,
int? errors,
}) {
Node copyWith({String? url, int? latency, int? errors, int? currentBlock}) {
return Node(
url: url ?? this.url,
latency: latency ?? this.latency,
errors: errors ?? this.errors,
currentBlock: currentBlock ?? this.currentBlock,
);
}
@override
String toString() {
return 'node url: $url latency: $latency errors: $errors';
return 'node url: $url latency: $latency errors: $errors currentBlock: $currentBlock';
}
@override
......@@ -44,7 +42,7 @@ class Node extends Equatable implements IsJsonSerializable<Node> {
Node fromJson(Map<String, dynamic> json) => Node.fromJson(json);
@override
List<Object?> get props => <dynamic>[url, latency, errors];
List<Object?> get props => <dynamic>[url, latency, errors, currentBlock];
}
List<Node> readDotNodeConfig(String entry) =>
......
......@@ -253,11 +253,14 @@ Future<List<Node>> _fetchDuniterNodesFromPeers(NodeType type) async {
!endpoint.contains('test') &&
!endpoint.contains('localhost')) {
try {
final Duration latency = await _pingNode(endpoint, type);
final NodeCheck nodeCheck = await _pingNode(endpoint, type);
final Duration latency = nodeCheck.latency;
logger(
'Evaluating node: $endpoint, latency ${latency.inMicroseconds}');
final Node node =
Node(url: endpoint, latency: latency.inMicroseconds);
'Evaluating node: $endpoint, latency ${latency.inMicroseconds} currentBlock: ${nodeCheck.currentBlock}');
final Node node = Node(
url: endpoint,
latency: latency.inMicroseconds,
currentBlock: nodeCheck.currentBlock);
if (fastestNode == null || latency < fastestLatency) {
fastestNode = endpoint;
fastestLatency = latency;
......@@ -308,9 +311,13 @@ Future<List<Node>> _fetchNodes(NodeType type) async {
final String endpoint = node.url;
try {
final Duration latency = await _pingNode(endpoint, type);
final NodeCheck nodeCheck = await _pingNode(endpoint, type);
final Duration latency = nodeCheck.latency;
logger('Evaluating node: $endpoint, latency ${latency.inMicroseconds}');
final Node node = Node(url: endpoint, latency: latency.inMicroseconds);
final Node node = Node(
url: endpoint,
latency: latency.inMicroseconds,
currentBlock: nodeCheck.currentBlock);
if (fastestNode == null || latency < fastestLatency) {
fastestNode = endpoint;
fastestLatency = latency;
......@@ -341,8 +348,9 @@ Future<List<Node>> _fetchNodes(NodeType type) async {
return lNodes;
}
Future<Duration> _pingNode(String node, NodeType type) async {
Future<NodeCheck> _pingNode(String node, NodeType type) async {
const Duration timeout = Duration(seconds: 10);
int currentBlock = 0;
try {
final Stopwatch stopwatch = Stopwatch()..start();
if (type == NodeType.duniter || type == NodeType.cesiumPlus) {
......@@ -360,16 +368,15 @@ Future<Duration> _pingNode(String node, NodeType type) async {
} else {
// Test GVA with a query
final Gva gva = Gva(node: proxyfyNode(node));
await gva
.balance('EdWkzNABz7dPancFqW6JVLqv1wpGaQSxgWmMf1pmY7KG')
.timeout(timeout);
currentBlock = await gva.getCurrentBlock().timeout(timeout);
// NodeManager().updateNode(type, node.copyWith(latency: newLatency));
}
stopwatch.stop();
return stopwatch.elapsed;
return NodeCheck(latency: stopwatch.elapsed, currentBlock: currentBlock);
} catch (e) {
// Handle exception when node is unavailable etc
logger('Node $node does not respond to ping $e');
return const Duration(days: 2);
return NodeCheck(latency: const Duration(days: 2), currentBlock: 0);
}
}
......@@ -528,10 +535,17 @@ Future<String?> gvaNick(String pubKey) async {
Future<T?> gvaFunctionWrapper<T>(
String pubKey, Future<T?> Function(Gva) specificFunction) async {
final List<Node> nodes = NodeManager()
final List<Node> fnodes = NodeManager()
.nodeList(NodeType.gva)
.where((Node node) => node.errors <= NodeManager.maxNodeErrors)
.toList();
final int maxCurrentBlock = fnodes.fold(
0,
(int max, Node node) =>
node.currentBlock > max ? node.currentBlock : max);
final List<Node> nodes = fnodes
.where((Node node) => node.currentBlock == maxCurrentBlock)
.toList();
if (nodes.isEmpty) {
nodes.addAll(defaultGvaNodes);
}
......@@ -556,6 +570,12 @@ Future<T?> gvaFunctionWrapper<T>(
continue;
}
}
throw Exception(
'Sorry: I cannot find a working node to get your transactions');
throw Exception('Sorry: I cannot find a working gva node');
}
class NodeCheck {
NodeCheck({required this.latency, required this.currentBlock});
final Duration latency;
final int currentBlock;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment