From fe1925c26b9e3cbd04c0a8f6f797df5d4988e42a Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Sat, 16 Sep 2023 14:25:02 +0100 Subject: [PATCH] ticket-1413 improved SNB discovery of connected S-chains --- agent/clpTools.mjs | 6 +- npms/skale-observer/observer.mjs | 102 ++++++++++++++++++++----- npms/skale-observer/observerWorker.mjs | 2 +- 3 files changed, 88 insertions(+), 22 deletions(-) diff --git a/agent/clpTools.mjs b/agent/clpTools.mjs index e153c8e5a..661fc2d52 100644 --- a/agent/clpTools.mjs +++ b/agent/clpTools.mjs @@ -1652,7 +1652,8 @@ export function commandLineTaskBrowseSkaleNetwork() { const opts = { imaState: imaState, "details": log, - "bStopNeeded": false + "bStopNeeded": false, + "isLoadConnectedOnly": false }; const arrSChains = await skaleObserver.loadSChains( opts ); const cnt = arrSChains.length; @@ -1685,7 +1686,8 @@ export function commandLineTaskBrowseConnectedSChains() { const opts = { "imaState": imaState, "details": log, - "bStopNeeded": false + "bStopNeeded": false, + "isLoadConnectedOnly": true }; const arrSChainsCached = await skaleObserver.loadSChainsConnectedOnly( imaState.chainProperties.sc.strChainName, opts ); diff --git a/npms/skale-observer/observer.mjs b/npms/skale-observer/observer.mjs index 6f70bb0e5..4afab418a 100644 --- a/npms/skale-observer/observer.mjs +++ b/npms/skale-observer/observer.mjs @@ -383,8 +383,8 @@ export async function loadSChain( idxSChain, hash, joData, cntSChains, opts ) { await loadSChainParts( joSChain, opts ); if( opts && opts.details ) { if( log.verboseGet() >= log.verboseReversed().trace ) { - opts.details.write( cc.debug( " Desc " ) + cc.j( joSChain.data ) + "\n" ); - opts.details.write( cc.success( "Done" ) + "\n" ); + opts.details.write( cc.debug( " SNB did loaded parts of S-chain " ) + + cc.j( joSChain.data ) + "\n" ); opts.details.write( cc.success( "Done" ) + "\n" ); } } joSChain.isConnected = false; @@ -411,10 +411,12 @@ export async function loadSChainsWithEMC( opts ) { if( opts && opts.details ) { if( log.verboseGet() >= log.verboseReversed().trace ) { opts.details.write( cc.debug( "Have " ) + cc.info( cntSChains ) + - cc.debug( " S-Chain(s) to load in " ) + + cc.debug( " S-Chain(s) to EMC-load in " ) + threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); } } + const isLoadConnectedOnly = ( "isLoadConnectedOnly" in opts ) + ? ( !!opts.isLoadConnectedOnly ) : true; const multicall = new EMC.Multicall( { ethersProvider: opts.imaState.chainProperties.mn.ethersProvider, tryAggregate: true @@ -548,6 +550,12 @@ export async function loadSChainsWithEMC( opts ) { if( opts && opts.bStopNeeded ) return null; } + const joMessageProxySChain = + new owaspUtils.ethersMod.ethers.Contract( + opts.imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_address, + opts.imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, + opts.imaState.chainProperties.sc.ethersProvider + ); const arrSChains = []; for( let idxSChain = 0; idxSChain < cntSChains; ++ idxSChain ) { if( opts && opts.bStopNeeded ) @@ -557,13 +565,22 @@ export async function loadSChainsWithEMC( opts ) { const joSChain = await loadSChain( // with hash + joData idxSChain, hash, joData, cntSChains, opts ); if( ! joSChain ) - break; + continue; + let isConnected = true; + if( isLoadConnectedOnly ) { + const strSChainName = joSChain.data.name; + isConnected = await checkWhetherSChainIsConnected( + strSChainName, joMessageProxySChain, opts ); + if( ! isConnected ) + continue; + } + joSChain.isConnected = isConnected; arrSChains.push( joSChain ); } if( opts && opts.details ) { if( log.verboseGet() >= log.verboseReversed().trace ) { opts.details.write( cc.success( "All " ) + cc.info( cntSChains ) + - cc.debug( " S-Chain(s) loaded:" ) + cc.j( arrSChains ) + "\n" ); + cc.debug( " S-Chain(s) EMC-loaded:" ) + cc.j( arrSChains ) + "\n" ); } } return arrSChains; @@ -572,30 +589,47 @@ export async function loadSChainsWithEMC( opts ) { export async function loadSChainsOptimal( opts ) { owaspUtils.ensureObserverOptionsInitialized( opts ); if( ! opts.imaState ) { - throw new Error( "Cannot load S-Chains in observer, no imaState is provided in " + - threadInfo.threadDescription( false ) ); + throw new Error( "Cannot un-filtered optimal-load S-Chains in observer, " + + "no imaState is provided in " + threadInfo.threadDescription( false ) ); } + const isLoadConnectedOnly = ( "isLoadConnectedOnly" in opts ) + ? ( !!opts.isLoadConnectedOnly ) : true; const cntSChains = await getSChainsCount( opts ); if( opts && opts.details ) { if( log.verboseGet() >= log.verboseReversed().trace ) { opts.details.write( cc.debug( "Have " ) + cc.info( cntSChains ) + - cc.debug( " S-Chain(s) to load in " ) + + cc.debug( " un-filtered S-Chain(s) to optimal-load in " ) + threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); } } + const joMessageProxySChain = + new owaspUtils.ethersMod.ethers.Contract( + opts.imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_address, + opts.imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, + opts.imaState.chainProperties.sc.ethersProvider + ); const arrSChains = []; for( let idxSChain = 0; idxSChain < cntSChains; ++ idxSChain ) { if( opts && opts.bStopNeeded ) break; const joSChain = await loadSChain( idxSChain, null, null, cntSChains, opts ); if( ! joSChain ) - break; + continue; + let isConnected = true; + if( isLoadConnectedOnly ) { + const strSChainName = joSChain.data.name; + isConnected = await checkWhetherSChainIsConnected( + strSChainName, joMessageProxySChain, opts ); + if( ! isConnected ) + continue; + } + joSChain.isConnected = isConnected; arrSChains.push( joSChain ); } if( opts && opts.details ) { if( log.verboseGet() >= log.verboseReversed().trace ) { opts.details.write( cc.success( "All " ) + cc.info( cntSChains ) + - cc.debug( " S-Chain(s) loaded in " ) + + cc.debug( " un-filtered S-Chain(s) optimal-loaded in " ) + threadInfo.threadDescription() + cc.success( ": " ) + cc.j( arrSChains ) + "\n" ); } @@ -605,8 +639,8 @@ export async function loadSChainsOptimal( opts ) { export async function loadCachedSChainsSimplified( addressFrom, opts ) { if( ! opts.imaState ) { - throw new Error( "Cannot load S-Chains in observer, no imaState is provided in " + - threadInfo.threadDescription( false ) ); + throw new Error( "Cannot simplified-load S-Chains in observer, " + + "no imaState is provided in " + threadInfo.threadDescription( false ) ); } if( opts && opts.details ) { if( log.verboseGet() >= log.verboseReversed().trace ) { @@ -614,6 +648,8 @@ export async function loadCachedSChainsSimplified( addressFrom, opts ) { threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); } } + const isLoadConnectedOnly = ( "isLoadConnectedOnly" in opts ) + ? ( !!opts.isLoadConnectedOnly ) : true; const arrSChainHashes = await opts.imaState.joSChainsInternal.callStatic.getSchains(); const cntSChains = arrSChainHashes.length; @@ -623,6 +659,12 @@ export async function loadCachedSChainsSimplified( addressFrom, opts ) { cc.debug( " S-Chain(s) hashes: " ) + cc.j( arrSChainHashes ) + "\n" ); } } + const joMessageProxySChain = + new owaspUtils.ethersMod.ethers.Contract( + opts.imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_address, + opts.imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, + opts.imaState.chainProperties.sc.ethersProvider + ); const arrSChains = []; for( let idxSChain = 0; idxSChain < cntSChains; ++ idxSChain ) { if( opts && opts.bStopNeeded ) @@ -640,11 +682,27 @@ export async function loadCachedSChainsSimplified( addressFrom, opts ) { } if( opts && opts.bStopNeeded ) break; + let isConnected = true; + if( isLoadConnectedOnly ) { + isConnected = await checkWhetherSChainIsConnected( + strSChainName, joMessageProxySChain, opts ); + if( ! isConnected ) + continue; + } const joSChain = await loadSChain( idxSChain, strSChainHash, null, cntSChains, opts ); if( ! joSChain ) - break; + continue; + joSChain.isConnected = isConnected; arrSChains.push( joSChain ); } + if( opts && opts.details ) { + if( log.verboseGet() >= log.verboseReversed().trace ) { + opts.details.write( cc.success( "All " ) + cc.info( cntSChains ) + + cc.debug( " S-Chain(s) simplified-loaded in " ) + + threadInfo.threadDescription() + cc.success( ": " ) + + cc.j( arrSChains ) + "\n" ); + } + } return arrSChains; } @@ -702,6 +760,9 @@ export async function loadSChainsConnectedOnly( strChainNameConnectedTo, opts ) threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); } } + // NOTICE: we are always check and filter connected status here, + // not depending on what is in opts + const isLoadConnectedOnly = true; const arrSChainHashes = await opts.imaState.joSChainsInternal.callStatic.getSchains(); const cntSChains = arrSChainHashes.length; if( opts && opts.details ) { @@ -752,14 +813,17 @@ export async function loadSChainsConnectedOnly( strChainNameConnectedTo, opts ) cc.info( strChainNameConnectedTo ) + cc.debug( "..." ) + "\n" ); } } - const isConnected = await checkWhetherSChainIsConnected( - strSChainName, joMessageProxySChain, opts ); - if( ! isConnected ) - continue; + let isConnected = false; + if( isLoadConnectedOnly ) { + isConnected = await checkWhetherSChainIsConnected( + strSChainName, joMessageProxySChain, opts ); + if( ! isConnected ) + continue; + } const joSChain = await loadSChain( idxSChain, strSChainHash, null, cntSChains, opts ); if( ! joSChain ) - break; - joSChain.isConnected = true; + continue; + joSChain.isConnected = isConnected; arrSChains.push( joSChain ); } catch ( err ) { if( opts && opts.details ) { diff --git a/npms/skale-observer/observerWorker.mjs b/npms/skale-observer/observerWorker.mjs index 832ab4009..ea576941b 100644 --- a/npms/skale-observer/observerWorker.mjs +++ b/npms/skale-observer/observerWorker.mjs @@ -345,7 +345,7 @@ class ObserverServer extends SocketServer { if( log.verboseGet() >= log.verboseReversed().debug ) { self.opts.details.write( cc.debug( "SKALE Observer in " ) + threadInfo.threadDescription() + - cc.debug( " will start periodic SNB refresh..." ) + "\n" ); + cc.debug( " did invoked periodic SNB refresh" ) + "\n" ); } self.intervalPeriodicSchainsCaching = setInterval( fnPeriodicCaching, secondsToReDiscoverSkaleNetwork * 1000 );