Skip to content

Commit fac7352

Browse files
SlowSlow
authored andcommitted
fix: keep node failover available
1 parent 819ef40 commit fac7352

2 files changed

Lines changed: 25 additions & 6 deletions

File tree

includes/class-wc-gateway-monero.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -615,18 +615,26 @@ private function nodes_match_network( $nodes, $network ) {
615615
return 'ok' === $health;
616616
}
617617
require_once __DIR__ . '/class-monero-scanner.php';
618-
$health = 'ok';
618+
$infos = array();
619619
foreach ( $nodes as $node ) {
620-
$info = ( new Monero_Scanner( $node, $network, 12 ) )->node_info();
621-
if ( empty( $info['ok'] ) || empty( $info['nettype'] ) || 'unknown' === $info['nettype'] || $network !== $info['nettype'] ) {
622-
$health = 'invalid';
623-
break;
624-
}
620+
$infos[] = ( new Monero_Scanner( $node, $network, 12 ) )->node_info();
625621
}
622+
$health = self::node_health_allows_payments( $infos, $network ) ? 'ok' : 'invalid';
626623
set_transient( $key, $health, 'ok' === $health ? 5 * MINUTE_IN_SECONDS : MINUTE_IN_SECONDS );
627624
return 'ok' === $health;
628625
}
629626

627+
public static function node_health_allows_payments( $infos, $network ) {
628+
$healthy = 0;
629+
foreach ( (array) $infos as $info ) {
630+
if ( empty( $info['ok'] ) ) { continue; }
631+
$nettype = isset( $info['nettype'] ) ? (string) $info['nettype'] : 'unknown';
632+
if ( 'unknown' !== $nettype && $network !== $nettype ) { return false; }
633+
$healthy++;
634+
}
635+
return $healthy > 0;
636+
}
637+
630638
private function live_rate_stale() {
631639
$source = $this->get_option( 'price_source', 'coingecko' );
632640
if ( 'fixed' === $source || (float) $this->get_option( 'fixed_rate' ) > 0 ) {

tests/node-auth.test.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ class WC_Payment_Gateway {}
3535
ok_auth( '401 diagnostic is specific', 'unauthorized' === $diagnostic['code'] && false !== strpos( $diagnostic['msg'], 'credentials' ) );
3636
$diagnostic = WC_Gateway_Monero::node_setup_diagnostic( array( 'code' => 'digest_unavailable' ) );
3737
ok_auth( 'Digest diagnostic requests cURL', 'digest_unavailable' === $diagnostic['code'] && false !== strpos( $diagnostic['msg'], 'cURL' ) );
38+
ok_auth( 'one healthy node tolerates an unreachable fallback', WC_Gateway_Monero::node_health_allows_payments( array(
39+
array( 'ok' => true, 'nettype' => 'stagenet' ),
40+
array( 'ok' => false, 'nettype' => 'unknown' ),
41+
), 'stagenet' ) );
42+
ok_auth( 'reachable wrong-network node is rejected', ! WC_Gateway_Monero::node_health_allows_payments( array(
43+
array( 'ok' => true, 'nettype' => 'stagenet' ),
44+
array( 'ok' => true, 'nettype' => 'mainnet' ),
45+
), 'stagenet' ) );
46+
ok_auth( 'no healthy node fails closed', ! WC_Gateway_Monero::node_health_allows_payments( array(
47+
array( 'ok' => false, 'nettype' => 'unknown' ),
48+
), 'stagenet' ) );
3849

3950
$responses[] = array( 'code' => 200, 'body' => json_encode( array( 'height' => 123, 'nettype' => 'mainnet' ) ) );
4051
$scanner = new Monero_Scanner( array( array( 'url' => 'https://node.test', 'auth' => 'basic', 'username' => 'u', 'password' => 'p' ) ) );

0 commit comments

Comments
 (0)