From 4dbd056146bab9a556c63ca47213bf70263a625d Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 26 Oct 2023 09:55:43 +0100 Subject: [PATCH 01/29] ticket-1621 fixed IMA Agent crash during imaBLS verify writes error message to log output --- agent/bls.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/bls.mjs b/agent/bls.mjs index 45c1a1212..c5588d155 100644 --- a/agent/bls.mjs +++ b/agent/bls.mjs @@ -1271,7 +1271,7 @@ async function gatherSigningStartImpl( optsSignOperation ) { "\n"; if( log.verboseGet() >= log.verboseReversed().error ) { optsSignOperation.details.write( strErrorMessage ); - if( log.id != details.id ) + if( log.id != optsSignOperation.details.id ) log.write( strErrorMessage ); } } From 6b51c37a074ab406492d54789ea29fcf30025d1a Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 26 Oct 2023 14:51:19 +0100 Subject: [PATCH 02/29] ticket-1620 IMA event log scanner moved into external module --- agent/clpTools.mjs | 5 ++ agent/loop.mjs | 11 +-- agent/test/agentUnitTests.js | 8 ++ npms/skale-ima/imaEventLogScan.mjs | 50 ++++++++++- npms/skale-ima/imaExternalLogScan.mjs | 88 ++++++++++++++++++++ npms/skale-ima/imaSgxExternalSigner.mjs | 2 +- npms/skale-ima/index.mjs | 106 ++++++++++++------------ npms/skale-observer/observer.mjs | 2 +- 8 files changed, 210 insertions(+), 62 deletions(-) create mode 100644 npms/skale-ima/imaExternalLogScan.mjs diff --git a/agent/clpTools.mjs b/agent/clpTools.mjs index 811d02cfb..d32803bb9 100644 --- a/agent/clpTools.mjs +++ b/agent/clpTools.mjs @@ -1319,9 +1319,11 @@ export function commandLineTaskTransferM2S() { joRuntimeOpts, imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, + imaState.chainProperties.mn.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, + imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.strChainName, imaState.chainProperties.sc.strChainName, @@ -1359,9 +1361,11 @@ export function commandLineTaskTransferS2M() { joRuntimeOpts, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, + imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, + imaState.chainProperties.sc.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.mn.strChainName, @@ -1403,6 +1407,7 @@ export function commandLineTaskTransferS2S() { skaleObserver, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, + imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.sc.chainId, diff --git a/agent/loop.mjs b/agent/loop.mjs index 71a1170a6..1c1402d22 100644 --- a/agent/loop.mjs +++ b/agent/loop.mjs @@ -223,13 +223,13 @@ async function singleTransferLoopPartM2S( optsLoop, strLogPrefix ) { b1 = await IMA.doTransfer( // main-net --> s-chain "M2S", optsLoop.joRuntimeOpts, - imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, + imaState.chainProperties.sc.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - + imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.strChainName, imaState.chainProperties.sc.strChainName, @@ -303,13 +303,13 @@ async function singleTransferLoopPartS2M( optsLoop, strLogPrefix ) { b2 = await IMA.doTransfer( // s-chain --> main-net "S2M", optsLoop.joRuntimeOpts, - imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, + imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, - + imaState.chainProperties.sc.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.mn.strChainName, @@ -373,6 +373,7 @@ async function singleTransferLoopPartS2S( optsLoop, strLogPrefix ) { skaleObserver, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, + imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.sc.chainId, @@ -836,7 +837,7 @@ export async function ensureHaveWorkers( opts ) { }; while( ! aClient.logicalInitComplete ) { if( log.verboseGet() >= log.verboseReversed().info ) - log.write( "LOOP server is not inited yet...\n" ); + log.write( "LOOP server is not initialized yet...\n" ); await threadInfo.sleep( 1000 ); aClient.send( jo ); } diff --git a/agent/test/agentUnitTests.js b/agent/test/agentUnitTests.js index 00158e3bd..d142e5487 100644 --- a/agent/test/agentUnitTests.js +++ b/agent/test/agentUnitTests.js @@ -490,6 +490,8 @@ describe( "tests for `npms/skale-ima` 3", function() { it( "should return `false` invoke `doTransfer`", async function() { let joMessageProxySrc; // for `false` output + const joMessageProxySrcABI = null; + const joMessageProxyDstABI = null; const chainNameSrc = "test"; const chainNameDst = "test"; const nTransactionsCountInBlock = 4; @@ -508,9 +510,11 @@ describe( "tests for `npms/skale-ima` 3", function() { joRuntimeOpts, ethersProviderSrc, joMessageProxySrc, + joMessageProxySrcABI, joAccountSrc, ethersProviderDst, joMessageProxyDst, + joMessageProxyDstABI, joAccountDst, chainNameSrc, chainNameDst, @@ -542,15 +546,19 @@ describe( "tests for `npms/skale-ima` 3", function() { idxChainKnownForS2S: 0, cntChainsKnownForS2S: 0 }; + const joMessageProxySrcABI = null; + const joMessageProxyDstABI = null; // eslint-disable-next-line no-unused-expressions expect( await IMA.doTransfer( "M2S", joRuntimeOpts, ethersProviderSrc, joMessageProxySrc, + joMessageProxySrcABI, joAccountSrc, ethersProviderDst, joMessageProxyDst, + joMessageProxyDstABI, joAccountDst, chainNameSrc, chainNameDst, diff --git a/npms/skale-ima/imaEventLogScan.mjs b/npms/skale-ima/imaEventLogScan.mjs index 5b22f155d..e0e4d69fd 100644 --- a/npms/skale-ima/imaEventLogScan.mjs +++ b/npms/skale-ima/imaEventLogScan.mjs @@ -31,6 +31,12 @@ import * as rpcCall from "../../agent/rpcCall.mjs"; import * as imaHelperAPIs from "./imaHelperAPIs.mjs"; import * as imaTransferErrorHandling from "./imaTransferErrorHandling.mjs"; +import * as childProcessModule from "child_process"; +import * as path from "path"; +import * as url from "url"; + +const __dirname = path.dirname( url.fileURLToPath( import.meta.url ) ); + export function createProgressiveEventsScanPlan( details, nLatestBlockNumber ) { // assume Main Net mines 6 blocks per minute const blocksInOneMinute = 6; @@ -86,9 +92,49 @@ export function createProgressiveEventsScanPlan( details, nLatestBlockNumber ) { return arrProgressiveEventsScanPlan; } +export function extractEventArg( arg ) { + if( arg && typeof arg == "object" && "type" in arg && typeof arg.type == "string" && + arg.type == "BigNumber" && "hex" in arg && typeof arg.hex == "string" ) + return owaspUtils.toBN( arg.hex ); + return arg; +} + +export async function safeGetPastEventsProgressiveExternal( + details, strLogPrefix, ethersProvider, attempts, + joContract, joABI, strEventName, + nBlockFrom, nBlockTo, joFilter +) { + if( joABI && typeof joABI == "object" ) { + const escapeShell = function( cmd ) { + return "\"" + cmd.replace( /(["'$`\\])/g,"\\$1" ) + "\""; + }; + const joArg = { + "url": owaspUtils.ethersProviderToUrl( ethersProvider ), + "attempts": attempts, + "strEventName": strEventName, + "nBlockFrom": nBlockFrom, + "nBlockTo": nBlockTo, + "joFilter": joFilter, + "address": joContract.address, + "abi": joABI + }; + const cmd = "node " + path.join( __dirname, "imaExternalLogScan.mjs" ) + " " + + escapeShell( JSON.stringify( joArg ) ); + const res = childProcessModule.execSync( cmd ); + if( "error" in res && res.error ) + throw new Error( res.error ); + + return JSON.parse( res ).result; + } + return await safeGetPastEventsProgressive( + details, strLogPrefix, ethersProvider, attempts, + joContract, strEventName, + nBlockFrom, nBlockTo, joFilter ); +} + export async function safeGetPastEventsProgressive( - details, strLogPrefix, - ethersProvider, attempts, joContract, strEventName, + details, strLogPrefix, ethersProvider, attempts, + joContract, strEventName, nBlockFrom, nBlockTo, joFilter ) { if( ! imaTransferErrorHandling.getEnabledProgressiveEventsScan() ) { diff --git a/npms/skale-ima/imaExternalLogScan.mjs b/npms/skale-ima/imaExternalLogScan.mjs new file mode 100644 index 000000000..6c740d497 --- /dev/null +++ b/npms/skale-ima/imaExternalLogScan.mjs @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +/** + * @license + * SKALE IMA + * + * SKALE IMA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SKALE IMA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with SKALE IMA. If not, see . + */ + +/** + * @file imaExternalLogScan.mjs + * @copyright SKALE Labs 2019-Present + */ + +import * as cc from "../skale-cc/cc.mjs"; +import * as log from "../skale-log/log.mjs"; +import * as owaspUtils from "../skale-owasp/owaspUtils.mjs"; +import * as imaEventLogScan from "./imaEventLogScan.mjs"; + +const gIsDebugLogging = false; // development option only, must be always false +cc.enable( false ); +log.addStdout(); + +// allow self-signed wss and https +process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; + +function finalizeOutput( jo ) { + if( ! jo ) + return; + cc.enable( false ); + process.stdout.write( cc.j( jo ) ); +} + +async function run() { + const details = log.createMemoryStream(); + try { + if( gIsDebugLogging ) { + log.write( cc.debug( "Process startup arguments array is " ) + + cc.j( process.argv ) + "\n" ); + } + if( process.argv.length != 3 ) + throw new Error( "Wrong number of command line arguments" ); + + if( gIsDebugLogging ) { + log.write( cc.debug( "Main argument text is " ) + + cc.j( process.argv[2] ) + "\n" ); + } + const joArg = JSON.parse( process.argv[2] ); + if( gIsDebugLogging ) { + log.write( cc.debug( "Main argument JSON is " ) + + cc.j( joArg ) + "\n" ); + } + + const ethersProvider = owaspUtils.getEthersProviderFromURL( joArg.url ); + const joContract = new owaspUtils.ethersMod.ethers.Contract( + joArg.address, joArg.abi, ethersProvider ); + + const arrLogRecordReferencesWalk = await imaEventLogScan.safeGetPastEventsProgressive( + details, "", ethersProvider, joArg.attempts, + joContract, joArg.strEventName, + joArg.nBlockFrom, joArg.nBlockTo, joArg.joFilter ); + + finalizeOutput( { "result": arrLogRecordReferencesWalk, "error": null } ); + process.exit( 0 ); + } catch ( err ) { + if( gIsDebugLogging ) { + log.write( cc.error( "Failed to create RPC call: " ) + + cc.j( err ) + "\n" ); + } + finalizeOutput( { + "error": owaspUtils.extractErrorMessage( err ), + "output": details.toString() + } ); + process.exit( 1 ); + } +} +run(); diff --git a/npms/skale-ima/imaSgxExternalSigner.mjs b/npms/skale-ima/imaSgxExternalSigner.mjs index 87715dcc4..60fe93b9b 100644 --- a/npms/skale-ima/imaSgxExternalSigner.mjs +++ b/npms/skale-ima/imaSgxExternalSigner.mjs @@ -6,7 +6,7 @@ import * as rpcCall from "../../agent/rpcCall.mjs"; const gIsDebugLogging = false; // development option only, must be always false const isColors = owaspUtils.toBoolean( process.argv[2] ); -cc.enable( true ); +cc.enable( false ); log.addStdout(); // allow self-signed wss and https diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index 6666a1cbf..16ba0146e 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -44,15 +44,13 @@ const perMessageGasForTransfer = 1000000; const additionalS2MTransferOverhead = 200000; async function findOutReferenceLogRecord( - details, strLogPrefix, - ethersProvider, joMessageProxy, + details, strLogPrefix, ethersProvider, joMessageProxy, joABI, bnBlockId, nMessageNumberToFind, isVerbose ) { const bnMessageNumberToFind = owaspUtils.toBN( nMessageNumberToFind.toString() ); const strEventName = "PreviousMessageReference"; - const arrLogRecords = await imaEventLogScan.safeGetPastEventsProgressive( - details, strLogPrefix, - ethersProvider, 10, joMessageProxy, strEventName, + const arrLogRecords = await imaEventLogScan.safeGetPastEventsProgressiveExternal( + details, strLogPrefix, ethersProvider, 10, joMessageProxy, joABI, strEventName, bnBlockId, bnBlockId, joMessageProxy.filters[strEventName]() ); const cntLogRecord = arrLogRecords.length; @@ -66,8 +64,8 @@ async function findOutReferenceLogRecord( for( let idxLogRecord = 0; idxLogRecord < cntLogRecord; ++ idxLogRecord ) { const joEvent = arrLogRecords[idxLogRecord]; const eventValuesByName = { - "currentMessage": joEvent.args[0], - "previousOutgoingMessageBlockId": joEvent.args[1] + "currentMessage": imaEventLogScan.extractEventArg( joEvent.args[0] ), + "previousOutgoingMessageBlockId": imaEventLogScan.extractEventArg( joEvent.args[1] ) }; const joReferenceLogRecord = { "currentMessage": eventValuesByName.currentMessage, @@ -98,8 +96,7 @@ async function findOutReferenceLogRecord( } async function findOutAllReferenceLogRecords( - details, strLogPrefix, - ethersProvider, joMessageProxy, + details, strLogPrefix, ethersProvider, joMessageProxy, joABI, bnBlockId, nIncMsgCnt, nOutMsgCnt, isVerbose ) { if( isVerbose ) { @@ -130,8 +127,7 @@ async function findOutAllReferenceLogRecords( for( ; nWalkMsgNumber >= nIncMsgCnt; -- nWalkMsgNumber ) { const joReferenceLogRecord = await findOutReferenceLogRecord( - details, strLogPrefix, - ethersProvider, joMessageProxy, + details, strLogPrefix, ethersProvider, joMessageProxy, joABI, nWalkBlockId, nWalkMsgNumber, isVerbose ); if( joReferenceLogRecord == null ) @@ -287,9 +283,9 @@ async function doQueryOutgoingMessageCounter( optsTransfer ) { optsTransfer.strActionName = "in-getOutgoingMessagesCounter()--findOutAllReferenceLogRecords()"; optsTransfer.arrLogRecordReferences = - await findOutAllReferenceLogRecords( - optsTransfer.details, optsTransfer.strLogPrefixShort, - optsTransfer.ethersProviderSrc, optsTransfer.joMessageProxySrc, + await findOutAllReferenceLogRecords( optsTransfer.details, + optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, + optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, bnBlockId, optsTransfer.nIncMsgCnt, optsTransfer.nOutMsgCnt, true ); return true; // success, finish at this point @@ -326,15 +322,14 @@ async function doQueryOutgoingMessageCounter( optsTransfer ) { ++ nWalkMsgNumber ) { const joFilter = optsTransfer.joMessageProxySrc.filters[strEventName]( - owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainIdDst ), // dstChainHash + owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainIdDst ), owaspUtils.toBN( nWalkMsgNumber ) ); - const arrLogRecordReferencesWalk = await imaEventLogScan.safeGetPastEventsProgressive( - optsTransfer.details, optsTransfer.strLogPrefixShort, - optsTransfer.ethersProviderSrc, attempts, optsTransfer.joMessageProxySrc, - strEventName, - nBlockFrom, nBlockTo, joFilter - ); + const arrLogRecordReferencesWalk = await imaEventLogScan + .safeGetPastEventsProgressiveExternal( optsTransfer.details, + optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, attempts, + optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, strEventName, + nBlockFrom, nBlockTo, joFilter ); optsTransfer.arrLogRecordReferences = optsTransfer.arrLogRecordReferences.concat( arrLogRecordReferencesWalk ); } @@ -361,11 +356,11 @@ async function analyzeGatheredRecords( optsTransfer, r ) { cc.debug( " with data " ) + cc.j( joEvent ) + "\n" ); } const eventValuesByName = { - "dstChainHash": joEvent.args[0], - "msgCounter": joEvent.args[1], - "srcContract": joEvent.args[2], - "dstContract": joEvent.args[3], - "data": joEvent.args[4] + "dstChainHash": imaEventLogScan.extractEventArg( joEvent.args[0] ), + "msgCounter": imaEventLogScan.extractEventArg( joEvent.args[1] ), + "srcContract": imaEventLogScan.extractEventArg( joEvent.args[2] ), + "dstContract": imaEventLogScan.extractEventArg( joEvent.args[3] ), + "data": imaEventLogScan.extractEventArg( joEvent.args[4] ) }; if( eventValuesByName.dstChainHash == strChainHashWeAreLookingFor ) { joValues = eventValuesByName; @@ -432,11 +427,11 @@ async function gatherMessages( optsTransfer ) { cc.notice( optsTransfer.strActionName ) + cc.debug( " for " ) + cc.info( strEventName ) + cc.debug( " event..." ) + "\n" ); } - r = await imaEventLogScan.safeGetPastEventsProgressive( - optsTransfer.details, optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, - 10, optsTransfer.joMessageProxySrc, strEventName, nBlockFrom, nBlockTo, - optsTransfer.joMessageProxySrc.filters[strEventName]( - owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), // dstChainHash + r = await imaEventLogScan.safeGetPastEventsProgressiveExternal( optsTransfer.details, + optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, 10, + optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, strEventName, + nBlockFrom, nBlockTo, optsTransfer.joMessageProxySrc.filters[strEventName]( + owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), owaspUtils.toBN( optsTransfer.nIdxCurrentMsg ) ) ); const joValues = await analyzeGatheredRecords( optsTransfer, r ); @@ -450,8 +445,8 @@ async function gatherMessages( optsTransfer ) { const transactionHash = r[0].transactionHash; if( log.verboseGet() >= log.verboseReversed().debug ) { optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.debug( "Event transactionHash is " ) + cc.info( transactionHash ) + - "\n" ); + cc.debug( "Event transactionHash is " ) + + cc.info( transactionHash ) + "\n" ); } const blockNumber = r[0].blockNumber; optsTransfer.details.write( optsTransfer.strLogPrefix + @@ -477,10 +472,10 @@ async function gatherMessages( optsTransfer ) { if( log.verboseGet() >= log.verboseReversed().critical ) { const strError = owaspUtils.extractErrorMessage( err ); const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " Exception(evaluate block depth) while " + - "getting transaction hash and block number during " + - optsTransfer.strActionName + ": " ) + cc.error( strError ) + - cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + "\n"; + cc.error( " Exception(evaluate block depth) while getting transaction " + + "hash and block number during " + optsTransfer.strActionName + ": " ) + + cc.error( strError ) + cc.error( ", stack is: " ) + "\n" + + cc.stack( err.stack ) + "\n"; optsTransfer.details.write( s ); if( log.id != optsTransfer.details.id ) log.write( s ); @@ -585,9 +580,7 @@ async function gatherMessages( optsTransfer ) { cc.info( optsTransfer.nIdxCurrentMsg ) + cc.success( " and " ) + cc.notice( "dstChain" ) + cc.success( " set to " ) + cc.info( optsTransfer.chainNameDst ) + cc.success( ", event description: " ) + - cc.j( joValues ) + - // + cc.j(evs) + - "\n" ); + cc.j( joValues ) + "\n" ); optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Will process message counter value " ) + cc.info( optsTransfer.nIdxCurrentMsg ) + "\n" ); @@ -938,17 +931,17 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { .joAbiIMA.message_proxy_chain_abi, ethersProviderNode ); + const joMessageProxyNodeABI = + optsTransfer.imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi; const strEventName = "OutgoingMessage"; - const node_r = await imaEventLogScan.safeGetPastEventsProgressive( - optsTransfer.details, optsTransfer.strLogPrefixShort, - ethersProviderNode, 10, joMessageProxyNode, strEventName, + const node_r = await imaEventLogScan.safeGetPastEventsProgressiveExternal( + optsTransfer.details, optsTransfer.strLogPrefixShort, ethersProviderNode, + 10, joMessageProxyNode, joMessageProxyNodeABI, strEventName, joMessage.savedBlockNumberForOptimizations, joMessage.savedBlockNumberForOptimizations, joMessageProxyNode.filters[strEventName]( owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), - owaspUtils.toBN( idxImaMessage ) - ) - ); + owaspUtils.toBN( idxImaMessage ) ) ); const cntEvents = node_r.length; if( log.verboseGet() >= log.verboseReversed().trace ) { optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Got " ) + @@ -960,11 +953,11 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { for( let idxEvent = 0; idxEvent < cntEvents; ++ idxEvent ) { const joEvent = node_r[idxEvent]; const eventValuesByName = { - "dstChainHash": joEvent.args[0], - "msgCounter": joEvent.args[1], - "srcContract": joEvent.args[2], - "dstContract": joEvent.args[3], - "data": joEvent.args[4] + "dstChainHash": imaEventLogScan.extractEventArg( joEvent.args[0] ), + "msgCounter": imaEventLogScan.extractEventArg( joEvent.args[1] ), + "srcContract": imaEventLogScan.extractEventArg( joEvent.args[2] ), + "dstContract": imaEventLogScan.extractEventArg( joEvent.args[3] ), + "data": imaEventLogScan.extractEventArg( joEvent.args[4] ) }; if( owaspUtils.ensureStartsWith0x( joMessage.sender ).toLowerCase() == @@ -1276,8 +1269,8 @@ let gIsOneTransferInProgressInThisThread = false; export async function doTransfer( strDirection, joRuntimeOpts, - ethersProviderSrc, joMessageProxySrc, joAccountSrc, - ethersProviderDst, joMessageProxyDst, joAccountDst, + ethersProviderSrc, joMessageProxySrc, joMessageProxySrcABI, joAccountSrc, + ethersProviderDst, joMessageProxyDst, joMessageProxyDstABI, joAccountDst, chainNameSrc, chainNameDst, chainIdSrc, chainIdDst, joDepositBoxMainNet, // for logs validation on mainnet joTokenManagerSChain, // for logs validation on s-chain @@ -1290,9 +1283,11 @@ export async function doTransfer( joRuntimeOpts: joRuntimeOpts, ethersProviderSrc: ethersProviderSrc, joMessageProxySrc: joMessageProxySrc, + joMessageProxySrcABI: joMessageProxySrcABI, joAccountSrc: joAccountSrc, ethersProviderDst: ethersProviderDst, joMessageProxyDst: joMessageProxyDst, + joMessageProxyDstABI: joMessageProxyDstABI, joAccountDst: joAccountDst, chainNameSrc: chainNameSrc, chainNameDst: chainNameDst, @@ -1471,6 +1466,7 @@ export async function doAllS2S( // s-chain --> s-chain skaleObserver, ethersProviderDst, joMessageProxyDst, + joMessageProxyDstABI, joAccountDst, chainNameDst, chainIdDst, @@ -1524,6 +1520,8 @@ export async function doAllS2S( // s-chain --> s-chain imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, ethersProviderSrc ); + const joMessageProxySrcABI = + imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi; const joDepositBoxSrc = new owaspUtils.ethersMod.ethers.Contract( imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_address, @@ -1554,9 +1552,11 @@ export async function doAllS2S( // s-chain --> s-chain joRuntimeOpts, ethersProviderSrc, joMessageProxySrc, + joMessageProxySrcABI, joAccountSrc, ethersProviderDst, joMessageProxyDst, + joMessageProxyDstABI, joAccountDst, chainNameSrc, chainNameDst, diff --git a/npms/skale-observer/observer.mjs b/npms/skale-observer/observer.mjs index 47364448e..7b24553bc 100644 --- a/npms/skale-observer/observer.mjs +++ b/npms/skale-observer/observer.mjs @@ -1333,7 +1333,7 @@ export async function ensureHaveWorker( opts ) { }; while( ! gClient.logicalInitComplete ) { if( log.verboseGet() >= log.verboseReversed().info ) - log.write( "SNB server is not inited yet...\n" ); + log.write( "SNB server is not initialized yet...\n" ); await threadInfo.sleep( 1000 ); gClient.send( jo ); From 9b82784151e6673f8fb5dbcf65927cab19d21c65 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 26 Oct 2023 18:24:22 +0100 Subject: [PATCH 03/29] ticket-1620 IMA event log scanner moved into external module --- VERSION | 2 +- npms/skale-ima/imaEventLogScan.mjs | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 227cea215..38f77a65b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.0 +2.0.1 diff --git a/npms/skale-ima/imaEventLogScan.mjs b/npms/skale-ima/imaEventLogScan.mjs index e0e4d69fd..3a6c6ec9e 100644 --- a/npms/skale-ima/imaEventLogScan.mjs +++ b/npms/skale-ima/imaEventLogScan.mjs @@ -120,10 +120,26 @@ export async function safeGetPastEventsProgressiveExternal( }; const cmd = "node " + path.join( __dirname, "imaExternalLogScan.mjs" ) + " " + escapeShell( JSON.stringify( joArg ) ); + if( log.verboseGet() >= log.verboseReversed().trace ) { + details.write( strLogPrefix + + cc.debug( "Will run external command to search logs for event" ) + + cc.j( strEventName ) + cc.debug( "..." ) + "\n" ); + } const res = childProcessModule.execSync( cmd ); - if( "error" in res && res.error ) + if( "error" in res && res.error ) { + if( log.verboseGet() >= log.verboseReversed().error ) { + details.write( strLogPrefix + + cc.error( "Got error from external command to search logs for event" ) + + cc.j( strEventName ) + cc.error( ":" ) + + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n" ); + } throw new Error( res.error ); - + } + if( log.verboseGet() >= log.verboseReversed().trace ) { + details.write( strLogPrefix + + cc.debug( "Done running external command to search logs for event" ) + + cc.j( strEventName ) + cc.debug( "." ) + "\n" ); + } return JSON.parse( res ).result; } return await safeGetPastEventsProgressive( From 140f0398a175a77391c082974d4bb5136a4a4588 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 26 Oct 2023 22:26:41 +0100 Subject: [PATCH 04/29] ticket-1620 IMA event log scanner moved into external module --- agent/clpTools.mjs | 16 +++++++- agent/loop.mjs | 16 +++++++- npms/skale-ima/imaEventLogScan.mjs | 32 ++++++++++++--- npms/skale-ima/index.mjs | 64 +++++++++++++++++------------- npms/skale-observer/observer.mjs | 13 ++++++ 5 files changed, 104 insertions(+), 37 deletions(-) diff --git a/agent/clpTools.mjs b/agent/clpTools.mjs index d32803bb9..8bb30473c 100644 --- a/agent/clpTools.mjs +++ b/agent/clpTools.mjs @@ -1314,6 +1314,11 @@ export function commandLineTaskTransferM2S() { idxChainKnownForS2S: 0, cntChainsKnownForS2S: 0 }; + const optsChainPair = { + "strDirection": "M2S", + "chainSrc": imaState.chainProperties.mn, + "chainDst": imaState.chainProperties.sc + }; return await IMA.doTransfer( // main-net --> s-chain "M2S", joRuntimeOpts, @@ -1338,7 +1343,8 @@ export function commandLineTaskTransferM2S() { imaState.nBlockAgeM2S, imaBLS.doSignMessagesM2S, null, - imaState.chainProperties.sc.transactionCustomizer + imaState.chainProperties.sc.transactionCustomizer, + optsChainPair ); } } ); @@ -1356,6 +1362,11 @@ export function commandLineTaskTransferS2M() { idxChainKnownForS2S: 0, cntChainsKnownForS2S: 0 }; + const optsChainPair = { + "strDirection": "S2M", + "chainSrc": imaState.chainProperties.sc, + "chainDst": imaState.chainProperties.mn + }; return await IMA.doTransfer( // s-chain --> main-net "S2M", joRuntimeOpts, @@ -1380,7 +1391,8 @@ export function commandLineTaskTransferS2M() { imaState.nBlockAgeS2M, imaBLS.doSignMessagesS2M, null, - imaState.chainProperties.mn.transactionCustomizer + imaState.chainProperties.mn.transactionCustomizer, + optsChainPair ); } } ); diff --git a/agent/loop.mjs b/agent/loop.mjs index 1c1402d22..ae8a64cc2 100644 --- a/agent/loop.mjs +++ b/agent/loop.mjs @@ -220,6 +220,11 @@ async function singleTransferLoopPartM2S( optsLoop, strLogPrefix ) { if( checkTimeFraming( null, "m2s", optsLoop.joRuntimeOpts ) ) { imaState.loopState.m2s.isInProgress = true; await pwa.notifyOnLoopStart( imaState, "m2s" ); + const optsChainPair = { + "strDirection": "M2S", + "chainSrc": imaState.chainProperties.mn, + "chainDst": imaState.chainProperties.sc + }; b1 = await IMA.doTransfer( // main-net --> s-chain "M2S", optsLoop.joRuntimeOpts, @@ -244,7 +249,8 @@ async function singleTransferLoopPartM2S( optsLoop, strLogPrefix ) { imaState.nBlockAgeM2S, imaBLS.doSignMessagesM2S, null, - imaState.chainProperties.sc.transactionCustomizer + imaState.chainProperties.sc.transactionCustomizer, + optsChainPair ); imaState.loopState.m2s.isInProgress = false; await pwa.notifyOnLoopEnd( imaState, "m2s" ); @@ -300,6 +306,11 @@ async function singleTransferLoopPartS2M( optsLoop, strLogPrefix ) { if( checkTimeFraming( null, "s2m", optsLoop.joRuntimeOpts ) ) { imaState.loopState.s2m.isInProgress = true; await pwa.notifyOnLoopStart( imaState, "s2m" ); + const optsChainPair = { + "strDirection": "S2M", + "chainSrc": imaState.chainProperties.sc, + "chainDst": imaState.chainProperties.mn + }; b2 = await IMA.doTransfer( // s-chain --> main-net "S2M", optsLoop.joRuntimeOpts, @@ -324,7 +335,8 @@ async function singleTransferLoopPartS2M( optsLoop, strLogPrefix ) { imaState.nBlockAgeS2M, imaBLS.doSignMessagesS2M, null, - imaState.chainProperties.mn.transactionCustomizer + imaState.chainProperties.mn.transactionCustomizer, + optsChainPair ); imaState.loopState.s2m.isInProgress = false; await pwa.notifyOnLoopEnd( imaState, "s2m" ); diff --git a/npms/skale-ima/imaEventLogScan.mjs b/npms/skale-ima/imaEventLogScan.mjs index 3a6c6ec9e..f1b77cfb5 100644 --- a/npms/skale-ima/imaEventLogScan.mjs +++ b/npms/skale-ima/imaEventLogScan.mjs @@ -99,10 +99,27 @@ export function extractEventArg( arg ) { return arg; } +function generateWhileTransferringLogMessageSuffix( optsChainPair ) { + if( ! optsChainPair ) + return ""; + if( ! optsChainPair.strDirection ) + return ""; + if( optsChainPair.strDirection == "S2S" ) { + return cc.debug( " (while performing " ) + cc.attention( optsChainPair.strDirection ) + + cc.debug( " transfer with external S-Chain " ) + + cc.info( optsChainPair.optsSpecificS2S.joSChain.data.name ) + cc.debug( " / " ) + + cc.notice( optsChainPair.optsSpecificS2S.joSChain.data.computed.chainId ) + + cc.debug( " node " ) + cc.info( optsChainPair.optsSpecificS2S.idxNode ) + + cc.debug( ")" ); + } + return cc.debug( " (while performing " ) + optsChainPair.strDirection + + cc.debug( " transfer)" ); +} + export async function safeGetPastEventsProgressiveExternal( details, strLogPrefix, ethersProvider, attempts, joContract, joABI, strEventName, - nBlockFrom, nBlockTo, joFilter + nBlockFrom, nBlockTo, joFilter, optsChainPair ) { if( joABI && typeof joABI == "object" ) { const escapeShell = function( cmd ) { @@ -123,22 +140,27 @@ export async function safeGetPastEventsProgressiveExternal( if( log.verboseGet() >= log.verboseReversed().trace ) { details.write( strLogPrefix + cc.debug( "Will run external command to search logs for event" ) + - cc.j( strEventName ) + cc.debug( "..." ) + "\n" ); + cc.j( strEventName ) + cc.debug( "via URL " ) + cc.u( joArg ) + + generateWhileTransferringLogMessageSuffix( optsChainPair ) + + cc.debug( "..." ) + "\n" ); } const res = childProcessModule.execSync( cmd ); if( "error" in res && res.error ) { if( log.verboseGet() >= log.verboseReversed().error ) { details.write( strLogPrefix + cc.error( "Got error from external command to search logs for event" ) + - cc.j( strEventName ) + cc.error( ":" ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n" ); + cc.j( strEventName ) + cc.error( "via URL " ) + cc.u( joArg ) + + generateWhileTransferringLogMessageSuffix( optsChainPair ) + + cc.error( ":" ) + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n" ); } throw new Error( res.error ); } if( log.verboseGet() >= log.verboseReversed().trace ) { details.write( strLogPrefix + cc.debug( "Done running external command to search logs for event" ) + - cc.j( strEventName ) + cc.debug( "." ) + "\n" ); + cc.j( strEventName ) + cc.debug( "via URL " ) + cc.u( joArg ) + + generateWhileTransferringLogMessageSuffix( optsChainPair ) + + cc.debug( "." ) + "\n" ); } return JSON.parse( res ).result; } diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index 16ba0146e..ac575bc2b 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -45,13 +45,13 @@ const additionalS2MTransferOverhead = 200000; async function findOutReferenceLogRecord( details, strLogPrefix, ethersProvider, joMessageProxy, joABI, - bnBlockId, nMessageNumberToFind, isVerbose + bnBlockId, nMessageNumberToFind, isVerbose, optsChainPair ) { const bnMessageNumberToFind = owaspUtils.toBN( nMessageNumberToFind.toString() ); const strEventName = "PreviousMessageReference"; const arrLogRecords = await imaEventLogScan.safeGetPastEventsProgressiveExternal( details, strLogPrefix, ethersProvider, 10, joMessageProxy, joABI, strEventName, - bnBlockId, bnBlockId, joMessageProxy.filters[strEventName]() + bnBlockId, bnBlockId, joMessageProxy.filters[strEventName](), optsChainPair ); const cntLogRecord = arrLogRecords.length; if( isVerbose ) { @@ -97,7 +97,7 @@ async function findOutReferenceLogRecord( async function findOutAllReferenceLogRecords( details, strLogPrefix, ethersProvider, joMessageProxy, joABI, - bnBlockId, nIncMsgCnt, nOutMsgCnt, isVerbose + bnBlockId, nIncMsgCnt, nOutMsgCnt, isVerbose, optsChainPair ) { if( isVerbose ) { if( log.verboseGet() >= log.verboseReversed().debug ) { @@ -125,11 +125,9 @@ async function findOutAllReferenceLogRecords( let nWalkMsgNumber = nOutMsgCnt - 1; let nWalkBlockId = bnBlockId; for( ; nWalkMsgNumber >= nIncMsgCnt; -- nWalkMsgNumber ) { - const joReferenceLogRecord = - await findOutReferenceLogRecord( - details, strLogPrefix, ethersProvider, joMessageProxy, joABI, - nWalkBlockId, nWalkMsgNumber, isVerbose - ); + const joReferenceLogRecord = await findOutReferenceLogRecord( + details, strLogPrefix, ethersProvider, joMessageProxy, joABI, + nWalkBlockId, nWalkMsgNumber, isVerbose, optsChainPair ); if( joReferenceLogRecord == null ) break; nWalkBlockId = owaspUtils.toBN( joReferenceLogRecord.previousOutgoingMessageBlockId ); @@ -286,8 +284,8 @@ async function doQueryOutgoingMessageCounter( optsTransfer ) { await findOutAllReferenceLogRecords( optsTransfer.details, optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, - bnBlockId, optsTransfer.nIncMsgCnt, optsTransfer.nOutMsgCnt, true - ); + bnBlockId, optsTransfer.nIncMsgCnt, optsTransfer.nOutMsgCnt, true, + optsTransfer.optsChainPair ); return true; // success, finish at this point } catch ( err ) { optsTransfer.arrLogRecordReferences = []; @@ -329,7 +327,7 @@ async function doQueryOutgoingMessageCounter( optsTransfer ) { .safeGetPastEventsProgressiveExternal( optsTransfer.details, optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, attempts, optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, strEventName, - nBlockFrom, nBlockTo, joFilter ); + nBlockFrom, nBlockTo, joFilter, optsTransfer.optsChainPair ); optsTransfer.arrLogRecordReferences = optsTransfer.arrLogRecordReferences.concat( arrLogRecordReferencesWalk ); } @@ -433,7 +431,7 @@ async function gatherMessages( optsTransfer ) { nBlockFrom, nBlockTo, optsTransfer.joMessageProxySrc.filters[strEventName]( owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), owaspUtils.toBN( optsTransfer.nIdxCurrentMsg ) - ) ); + ), optsTransfer.optsChainPair ); const joValues = await analyzeGatheredRecords( optsTransfer, r ); if( joValues == null ) return false; @@ -891,6 +889,7 @@ async function handleAllMessagesSigning( optsTransfer ) { } async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { + const sc = optsTransfer.imaState.chainProperties.sc; const cntNodes = joSChain.data.computed.nodes.length; const cntMessages = optsTransfer.jarrMessages.length; for( let idxMessage = 0; idxMessage < cntMessages; ++ idxMessage ) { @@ -923,16 +922,11 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { // eslint-disable-next-line dot-notation const ethersProviderNode = owaspUtils.getEthersProviderFromURL( strUrlHttp ); - const joMessageProxyNode = - new owaspUtils.ethersMod.ethers.Contract( - optsTransfer.imaState.chainProperties.sc - .joAbiIMA.message_proxy_chain_address, - optsTransfer.imaState.chainProperties.sc - .joAbiIMA.message_proxy_chain_abi, - ethersProviderNode - ); - const joMessageProxyNodeABI = - optsTransfer.imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi; + const joMessageProxyNode = new owaspUtils.ethersMod.ethers.Contract( + sc.joAbiIMA.message_proxy_chain_address, + sc.joAbiIMA.message_proxy_chain_abi, + ethersProviderNode ); + const joMessageProxyNodeABI = sc.joAbiIMA.message_proxy_chain_abi; const strEventName = "OutgoingMessage"; const node_r = await imaEventLogScan.safeGetPastEventsProgressiveExternal( optsTransfer.details, optsTransfer.strLogPrefixShort, ethersProviderNode, @@ -941,7 +935,7 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { joMessage.savedBlockNumberForOptimizations, joMessageProxyNode.filters[strEventName]( owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), - owaspUtils.toBN( idxImaMessage ) ) ); + owaspUtils.toBN( idxImaMessage ) ), optsTransfer.optsChainPair ); const cntEvents = node_r.length; if( log.verboseGet() >= log.verboseReversed().trace ) { optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Got " ) + @@ -1276,11 +1270,12 @@ export async function doTransfer( joTokenManagerSChain, // for logs validation on s-chain nTransactionsCountInBlock, nTransferSteps, nMaxTransactionsCount, nBlockAwaitDepth, nBlockAge, - fnSignMessages, joExtraSignOpts, transactionCustomizerDst + fnSignMessages, joExtraSignOpts, transactionCustomizerDst, optsChainPair ) { const optsTransfer = { strDirection: strDirection, joRuntimeOpts: joRuntimeOpts, + optsChainPair: optsChainPair, ethersProviderSrc: ethersProviderSrc, joMessageProxySrc: joMessageProxySrc, joMessageProxySrcABI: joMessageProxySrcABI, @@ -1491,7 +1486,8 @@ export async function doAllS2S( // s-chain --> s-chain } for( let idxSChain = 0; idxSChain < cntSChains; ++ idxSChain ) { const joSChain = arrSChainsCached[idxSChain]; - const urlSrc = skaleObserver.pickRandomSChainUrl( joSChain ); + const joPickResult = pickRandomSChainIndexAndNodeAndUrl( joSChain ); + const urlSrc = joPickResult.strURL; const ethersProviderSrc = owaspUtils.getEthersProviderFromURL( urlSrc ); const joAccountSrc = joAccountDst; // ??? const chainNameSrc = "" + joSChain.data.name; @@ -1546,8 +1542,19 @@ export async function doAllS2S( // s-chain --> s-chain imaState.loopState.s2s.isInProgress = true; await pwa.notifyOnLoopStart( imaState, "s2s", nIndexS2S ); - bOK = - await doTransfer( + const optsChainPair = { + "strDirection": strDirection, + "chainSrc": null, + "chainDst": imaState.chainProperties.sc, + "optsSpecificS2S": { + "joSChain": joSChain, + "idxSChain": idxSChain, + "urlSrc": urlSrc, + "idxNode": joPickResult.idxNode, + "joNode": joPickResult.joNode + } + }; + bOK = await doTransfer( strDirection, joRuntimeOpts, ethersProviderSrc, @@ -1571,7 +1578,8 @@ export async function doAllS2S( // s-chain --> s-chain nBlockAge, fnSignMessages, joExtraSignOpts, - transactionCustomizerDst + transactionCustomizerDst, + optsChainPair ); imaState.loopState.s2s.isInProgress = false; await pwa.notifyOnLoopEnd( imaState, "s2s", nIndexS2S ); diff --git a/npms/skale-observer/observer.mjs b/npms/skale-observer/observer.mjs index 7b24553bc..c9146cf9c 100644 --- a/npms/skale-observer/observer.mjs +++ b/npms/skale-observer/observer.mjs @@ -1513,6 +1513,19 @@ export function pickRandomSChainUrl( joSChain ) { return "" + joNode["http_endpoint_ip"]; } +export function pickRandomSChainIndexAndNodeAndUrl( joSChain ) { + const idxNode = pickRandomSChainNodeIndex( joSChain ); + const joNode = joSChain.data.computed.nodes[idxNode]; + // eslint-disable-next-line dot-notation + const strURL = "" + joNode["http_endpoint_ip"]; + const joPickResult = { + "strURL": strURL, + "joNode": joNode, + "idxNode": idxNode + }; + return joPickResult; +} + export async function discoverChainId( strURL ) { let ret = null; const rpcCallOpts = null; From 08162ea188ab3a339d847e62650a555db88fe1c3 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 26 Oct 2023 22:40:59 +0100 Subject: [PATCH 05/29] ticket-1620 IMA event log scanner moved into external module --- npms/skale-ima/index.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index ac575bc2b..93b9ff712 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -1486,7 +1486,7 @@ export async function doAllS2S( // s-chain --> s-chain } for( let idxSChain = 0; idxSChain < cntSChains; ++ idxSChain ) { const joSChain = arrSChainsCached[idxSChain]; - const joPickResult = pickRandomSChainIndexAndNodeAndUrl( joSChain ); + const joPickResult = skaleObserver.pickRandomSChainIndexAndNodeAndUrl( joSChain ); const urlSrc = joPickResult.strURL; const ethersProviderSrc = owaspUtils.getEthersProviderFromURL( urlSrc ); const joAccountSrc = joAccountDst; // ??? From 95fd54219efc53eb8ab6260a35035c85e01d919b Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 26 Oct 2023 22:56:50 +0100 Subject: [PATCH 06/29] ticket-1620 IMA event log scanner moved into external module --- npms/skale-ima/imaEventLogScan.mjs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/npms/skale-ima/imaEventLogScan.mjs b/npms/skale-ima/imaEventLogScan.mjs index f1b77cfb5..f8d8b16bc 100644 --- a/npms/skale-ima/imaEventLogScan.mjs +++ b/npms/skale-ima/imaEventLogScan.mjs @@ -112,7 +112,7 @@ function generateWhileTransferringLogMessageSuffix( optsChainPair ) { cc.debug( " node " ) + cc.info( optsChainPair.optsSpecificS2S.idxNode ) + cc.debug( ")" ); } - return cc.debug( " (while performing " ) + optsChainPair.strDirection + + return cc.debug( " (while performing " ) + cc.attention( optsChainPair.strDirection ) + cc.debug( " transfer)" ); } @@ -139,8 +139,8 @@ export async function safeGetPastEventsProgressiveExternal( escapeShell( JSON.stringify( joArg ) ); if( log.verboseGet() >= log.verboseReversed().trace ) { details.write( strLogPrefix + - cc.debug( "Will run external command to search logs for event" ) + - cc.j( strEventName ) + cc.debug( "via URL " ) + cc.u( joArg ) + + cc.debug( "Will run external command to search logs for event " ) + + cc.j( strEventName ) + cc.debug( " via URL " ) + cc.u( joArg ) + generateWhileTransferringLogMessageSuffix( optsChainPair ) + cc.debug( "..." ) + "\n" ); } @@ -148,8 +148,8 @@ export async function safeGetPastEventsProgressiveExternal( if( "error" in res && res.error ) { if( log.verboseGet() >= log.verboseReversed().error ) { details.write( strLogPrefix + - cc.error( "Got error from external command to search logs for event" ) + - cc.j( strEventName ) + cc.error( "via URL " ) + cc.u( joArg ) + + cc.error( "Got error from external command to search logs for event " ) + + cc.j( strEventName ) + cc.error( " via URL " ) + cc.u( joArg ) + generateWhileTransferringLogMessageSuffix( optsChainPair ) + cc.error( ":" ) + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n" ); } @@ -157,8 +157,8 @@ export async function safeGetPastEventsProgressiveExternal( } if( log.verboseGet() >= log.verboseReversed().trace ) { details.write( strLogPrefix + - cc.debug( "Done running external command to search logs for event" ) + - cc.j( strEventName ) + cc.debug( "via URL " ) + cc.u( joArg ) + + cc.debug( "Done running external command to search logs for event " ) + + cc.j( strEventName ) + cc.debug( " via URL " ) + cc.u( joArg ) + generateWhileTransferringLogMessageSuffix( optsChainPair ) + cc.debug( "." ) + "\n" ); } From 0003adfc48940a50c90f787868e61d96fad65d80 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 26 Oct 2023 23:31:07 +0100 Subject: [PATCH 07/29] ticket-1620 IMA event log scanner moved into external module --- npms/skale-ima/imaEventLogScan.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/npms/skale-ima/imaEventLogScan.mjs b/npms/skale-ima/imaEventLogScan.mjs index f8d8b16bc..bf7da1fc9 100644 --- a/npms/skale-ima/imaEventLogScan.mjs +++ b/npms/skale-ima/imaEventLogScan.mjs @@ -140,7 +140,7 @@ export async function safeGetPastEventsProgressiveExternal( if( log.verboseGet() >= log.verboseReversed().trace ) { details.write( strLogPrefix + cc.debug( "Will run external command to search logs for event " ) + - cc.j( strEventName ) + cc.debug( " via URL " ) + cc.u( joArg ) + + cc.j( strEventName ) + cc.debug( " via URL " ) + cc.u( joArg.url ) + generateWhileTransferringLogMessageSuffix( optsChainPair ) + cc.debug( "..." ) + "\n" ); } @@ -149,7 +149,7 @@ export async function safeGetPastEventsProgressiveExternal( if( log.verboseGet() >= log.verboseReversed().error ) { details.write( strLogPrefix + cc.error( "Got error from external command to search logs for event " ) + - cc.j( strEventName ) + cc.error( " via URL " ) + cc.u( joArg ) + + cc.j( strEventName ) + cc.error( " via URL " ) + cc.u( joArg.url ) + generateWhileTransferringLogMessageSuffix( optsChainPair ) + cc.error( ":" ) + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n" ); } @@ -158,7 +158,7 @@ export async function safeGetPastEventsProgressiveExternal( if( log.verboseGet() >= log.verboseReversed().trace ) { details.write( strLogPrefix + cc.debug( "Done running external command to search logs for event " ) + - cc.j( strEventName ) + cc.debug( " via URL " ) + cc.u( joArg ) + + cc.j( strEventName ) + cc.debug( " via URL " ) + cc.u( joArg.url ) + generateWhileTransferringLogMessageSuffix( optsChainPair ) + cc.debug( "." ) + "\n" ); } From 3e7d620e8e5fbeb969bc3c924c843fc4168cdeab Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Sat, 28 Oct 2023 10:58:50 +0100 Subject: [PATCH 08/29] ticket-1620 fixed misprint in event log scanner code --- npms/skale-ima/index.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index 93b9ff712..18f5b8378 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -320,7 +320,7 @@ async function doQueryOutgoingMessageCounter( optsTransfer ) { ++ nWalkMsgNumber ) { const joFilter = optsTransfer.joMessageProxySrc.filters[strEventName]( - owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainIdDst ), + owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), owaspUtils.toBN( nWalkMsgNumber ) ); const arrLogRecordReferencesWalk = await imaEventLogScan From 71b12c361ddfb5eee52463f0c463c6aac98a779f Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Sat, 28 Oct 2023 11:29:20 +0100 Subject: [PATCH 09/29] ticket-1620 IMA event log scanner is now in-place code, external module was removed --- npms/skale-ima/imaEventLogScan.mjs | 73 +++------------------- npms/skale-ima/imaExternalLogScan.mjs | 88 --------------------------- npms/skale-ima/index.mjs | 31 +++++----- 3 files changed, 24 insertions(+), 168 deletions(-) delete mode 100644 npms/skale-ima/imaExternalLogScan.mjs diff --git a/npms/skale-ima/imaEventLogScan.mjs b/npms/skale-ima/imaEventLogScan.mjs index bf7da1fc9..bcc0a37b7 100644 --- a/npms/skale-ima/imaEventLogScan.mjs +++ b/npms/skale-ima/imaEventLogScan.mjs @@ -31,12 +31,6 @@ import * as rpcCall from "../../agent/rpcCall.mjs"; import * as imaHelperAPIs from "./imaHelperAPIs.mjs"; import * as imaTransferErrorHandling from "./imaTransferErrorHandling.mjs"; -import * as childProcessModule from "child_process"; -import * as path from "path"; -import * as url from "url"; - -const __dirname = path.dirname( url.fileURLToPath( import.meta.url ) ); - export function createProgressiveEventsScanPlan( details, nLatestBlockNumber ) { // assume Main Net mines 6 blocks per minute const blocksInOneMinute = 6; @@ -116,64 +110,9 @@ function generateWhileTransferringLogMessageSuffix( optsChainPair ) { cc.debug( " transfer)" ); } -export async function safeGetPastEventsProgressiveExternal( - details, strLogPrefix, ethersProvider, attempts, - joContract, joABI, strEventName, - nBlockFrom, nBlockTo, joFilter, optsChainPair -) { - if( joABI && typeof joABI == "object" ) { - const escapeShell = function( cmd ) { - return "\"" + cmd.replace( /(["'$`\\])/g,"\\$1" ) + "\""; - }; - const joArg = { - "url": owaspUtils.ethersProviderToUrl( ethersProvider ), - "attempts": attempts, - "strEventName": strEventName, - "nBlockFrom": nBlockFrom, - "nBlockTo": nBlockTo, - "joFilter": joFilter, - "address": joContract.address, - "abi": joABI - }; - const cmd = "node " + path.join( __dirname, "imaExternalLogScan.mjs" ) + " " + - escapeShell( JSON.stringify( joArg ) ); - if( log.verboseGet() >= log.verboseReversed().trace ) { - details.write( strLogPrefix + - cc.debug( "Will run external command to search logs for event " ) + - cc.j( strEventName ) + cc.debug( " via URL " ) + cc.u( joArg.url ) + - generateWhileTransferringLogMessageSuffix( optsChainPair ) + - cc.debug( "..." ) + "\n" ); - } - const res = childProcessModule.execSync( cmd ); - if( "error" in res && res.error ) { - if( log.verboseGet() >= log.verboseReversed().error ) { - details.write( strLogPrefix + - cc.error( "Got error from external command to search logs for event " ) + - cc.j( strEventName ) + cc.error( " via URL " ) + cc.u( joArg.url ) + - generateWhileTransferringLogMessageSuffix( optsChainPair ) + - cc.error( ":" ) + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n" ); - } - throw new Error( res.error ); - } - if( log.verboseGet() >= log.verboseReversed().trace ) { - details.write( strLogPrefix + - cc.debug( "Done running external command to search logs for event " ) + - cc.j( strEventName ) + cc.debug( " via URL " ) + cc.u( joArg.url ) + - generateWhileTransferringLogMessageSuffix( optsChainPair ) + - cc.debug( "." ) + "\n" ); - } - return JSON.parse( res ).result; - } - return await safeGetPastEventsProgressive( - details, strLogPrefix, ethersProvider, attempts, - joContract, strEventName, - nBlockFrom, nBlockTo, joFilter ); -} - export async function safeGetPastEventsProgressive( - details, strLogPrefix, ethersProvider, attempts, - joContract, strEventName, - nBlockFrom, nBlockTo, joFilter + details, strLogPrefix, ethersProvider, attempts, joContract, strEventName, + nBlockFrom, nBlockTo, joFilter, optsChainPair ) { if( ! imaTransferErrorHandling.getEnabledProgressiveEventsScan() ) { details.write( strLogPrefix + @@ -188,6 +127,14 @@ export async function safeGetPastEventsProgressive( nBlockFrom, nBlockTo, joFilter ); } + if( log.verboseGet() >= log.verboseReversed().information ) { + details.write( strLogPrefix + + cc.info( "Will run progressive event log search for event " ) + + cc.j( strEventName ) + cc.info( " via URL " ) + + cc.u( owaspUtils.ethersProviderToUrl( ethersProvider ) ) + + generateWhileTransferringLogMessageSuffix( optsChainPair ) + + cc.info( "..." ) ); + } const nLatestBlockNumber = owaspUtils.toBN( await imaHelperAPIs.safeGetBlockNumber( details, 10, ethersProvider ) ); const nLatestBlockNumberPlus1 = nLatestBlockNumber.add( owaspUtils.toBN( 1 ) ); diff --git a/npms/skale-ima/imaExternalLogScan.mjs b/npms/skale-ima/imaExternalLogScan.mjs deleted file mode 100644 index 6c740d497..000000000 --- a/npms/skale-ima/imaExternalLogScan.mjs +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only - -/** - * @license - * SKALE IMA - * - * SKALE IMA is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SKALE IMA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with SKALE IMA. If not, see . - */ - -/** - * @file imaExternalLogScan.mjs - * @copyright SKALE Labs 2019-Present - */ - -import * as cc from "../skale-cc/cc.mjs"; -import * as log from "../skale-log/log.mjs"; -import * as owaspUtils from "../skale-owasp/owaspUtils.mjs"; -import * as imaEventLogScan from "./imaEventLogScan.mjs"; - -const gIsDebugLogging = false; // development option only, must be always false -cc.enable( false ); -log.addStdout(); - -// allow self-signed wss and https -process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; - -function finalizeOutput( jo ) { - if( ! jo ) - return; - cc.enable( false ); - process.stdout.write( cc.j( jo ) ); -} - -async function run() { - const details = log.createMemoryStream(); - try { - if( gIsDebugLogging ) { - log.write( cc.debug( "Process startup arguments array is " ) + - cc.j( process.argv ) + "\n" ); - } - if( process.argv.length != 3 ) - throw new Error( "Wrong number of command line arguments" ); - - if( gIsDebugLogging ) { - log.write( cc.debug( "Main argument text is " ) + - cc.j( process.argv[2] ) + "\n" ); - } - const joArg = JSON.parse( process.argv[2] ); - if( gIsDebugLogging ) { - log.write( cc.debug( "Main argument JSON is " ) + - cc.j( joArg ) + "\n" ); - } - - const ethersProvider = owaspUtils.getEthersProviderFromURL( joArg.url ); - const joContract = new owaspUtils.ethersMod.ethers.Contract( - joArg.address, joArg.abi, ethersProvider ); - - const arrLogRecordReferencesWalk = await imaEventLogScan.safeGetPastEventsProgressive( - details, "", ethersProvider, joArg.attempts, - joContract, joArg.strEventName, - joArg.nBlockFrom, joArg.nBlockTo, joArg.joFilter ); - - finalizeOutput( { "result": arrLogRecordReferencesWalk, "error": null } ); - process.exit( 0 ); - } catch ( err ) { - if( gIsDebugLogging ) { - log.write( cc.error( "Failed to create RPC call: " ) + - cc.j( err ) + "\n" ); - } - finalizeOutput( { - "error": owaspUtils.extractErrorMessage( err ), - "output": details.toString() - } ); - process.exit( 1 ); - } -} -run(); diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index 93b9ff712..93b2a6a4f 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -49,8 +49,8 @@ async function findOutReferenceLogRecord( ) { const bnMessageNumberToFind = owaspUtils.toBN( nMessageNumberToFind.toString() ); const strEventName = "PreviousMessageReference"; - const arrLogRecords = await imaEventLogScan.safeGetPastEventsProgressiveExternal( - details, strLogPrefix, ethersProvider, 10, joMessageProxy, joABI, strEventName, + const arrLogRecords = await imaEventLogScan.safeGetPastEventsProgressive( + details, strLogPrefix, ethersProvider, 10, joMessageProxy, strEventName, bnBlockId, bnBlockId, joMessageProxy.filters[strEventName](), optsChainPair ); const cntLogRecord = arrLogRecords.length; @@ -96,7 +96,7 @@ async function findOutReferenceLogRecord( } async function findOutAllReferenceLogRecords( - details, strLogPrefix, ethersProvider, joMessageProxy, joABI, + details, strLogPrefix, ethersProvider, joMessageProxy, bnBlockId, nIncMsgCnt, nOutMsgCnt, isVerbose, optsChainPair ) { if( isVerbose ) { @@ -126,7 +126,7 @@ async function findOutAllReferenceLogRecords( let nWalkBlockId = bnBlockId; for( ; nWalkMsgNumber >= nIncMsgCnt; -- nWalkMsgNumber ) { const joReferenceLogRecord = await findOutReferenceLogRecord( - details, strLogPrefix, ethersProvider, joMessageProxy, joABI, + details, strLogPrefix, ethersProvider, joMessageProxy, nWalkBlockId, nWalkMsgNumber, isVerbose, optsChainPair ); if( joReferenceLogRecord == null ) break; @@ -283,9 +283,8 @@ async function doQueryOutgoingMessageCounter( optsTransfer ) { optsTransfer.arrLogRecordReferences = await findOutAllReferenceLogRecords( optsTransfer.details, optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, - optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, - bnBlockId, optsTransfer.nIncMsgCnt, optsTransfer.nOutMsgCnt, true, - optsTransfer.optsChainPair ); + optsTransfer.joMessageProxySrc, bnBlockId, optsTransfer.nIncMsgCnt, + optsTransfer.nOutMsgCnt, true, optsTransfer.optsChainPair ); return true; // success, finish at this point } catch ( err ) { optsTransfer.arrLogRecordReferences = []; @@ -323,11 +322,10 @@ async function doQueryOutgoingMessageCounter( optsTransfer ) { owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainIdDst ), owaspUtils.toBN( nWalkMsgNumber ) ); - const arrLogRecordReferencesWalk = await imaEventLogScan - .safeGetPastEventsProgressiveExternal( optsTransfer.details, - optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, attempts, - optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, strEventName, - nBlockFrom, nBlockTo, joFilter, optsTransfer.optsChainPair ); + const arrLogRecordReferencesWalk = await imaEventLogScan.safeGetPastEventsProgressive( + optsTransfer.details, optsTransfer.strLogPrefixShort, + optsTransfer.ethersProviderSrc, attempts, optsTransfer.joMessageProxySrc, + strEventName, nBlockFrom, nBlockTo, joFilter, optsTransfer.optsChainPair ); optsTransfer.arrLogRecordReferences = optsTransfer.arrLogRecordReferences.concat( arrLogRecordReferencesWalk ); } @@ -425,9 +423,9 @@ async function gatherMessages( optsTransfer ) { cc.notice( optsTransfer.strActionName ) + cc.debug( " for " ) + cc.info( strEventName ) + cc.debug( " event..." ) + "\n" ); } - r = await imaEventLogScan.safeGetPastEventsProgressiveExternal( optsTransfer.details, + r = await imaEventLogScan.safeGetPastEventsProgressive( optsTransfer.details, optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, 10, - optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, strEventName, + optsTransfer.joMessageProxySrc, strEventName, nBlockFrom, nBlockTo, optsTransfer.joMessageProxySrc.filters[strEventName]( owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), owaspUtils.toBN( optsTransfer.nIdxCurrentMsg ) @@ -926,11 +924,10 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { sc.joAbiIMA.message_proxy_chain_address, sc.joAbiIMA.message_proxy_chain_abi, ethersProviderNode ); - const joMessageProxyNodeABI = sc.joAbiIMA.message_proxy_chain_abi; const strEventName = "OutgoingMessage"; - const node_r = await imaEventLogScan.safeGetPastEventsProgressiveExternal( + const node_r = await imaEventLogScan.safeGetPastEventsProgressive( optsTransfer.details, optsTransfer.strLogPrefixShort, ethersProviderNode, - 10, joMessageProxyNode, joMessageProxyNodeABI, strEventName, + 10, joMessageProxyNode, strEventName, joMessage.savedBlockNumberForOptimizations, joMessage.savedBlockNumberForOptimizations, joMessageProxyNode.filters[strEventName]( From a1a89f32c9f3f46485dd08862f931dd43adb62df Mon Sep 17 00:00:00 2001 From: Dmytro Nazarenko Date: Mon, 30 Oct 2023 11:26:24 +0000 Subject: [PATCH 10/29] Revert "Ticket 1620/resolve speed issues of ima event scanner" --- VERSION | 2 +- agent/clpTools.mjs | 21 +--- agent/loop.mjs | 27 ++-- agent/test/agentUnitTests.js | 8 -- npms/skale-ima/imaEventLogScan.mjs | 88 +------------ npms/skale-ima/imaExternalLogScan.mjs | 88 ------------- npms/skale-ima/imaSgxExternalSigner.mjs | 2 +- npms/skale-ima/index.mjs | 160 +++++++++++------------- npms/skale-observer/observer.mjs | 15 +-- 9 files changed, 90 insertions(+), 321 deletions(-) delete mode 100644 npms/skale-ima/imaExternalLogScan.mjs diff --git a/VERSION b/VERSION index 38f77a65b..227cea215 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.1 +2.0.0 diff --git a/agent/clpTools.mjs b/agent/clpTools.mjs index 8bb30473c..811d02cfb 100644 --- a/agent/clpTools.mjs +++ b/agent/clpTools.mjs @@ -1314,21 +1314,14 @@ export function commandLineTaskTransferM2S() { idxChainKnownForS2S: 0, cntChainsKnownForS2S: 0 }; - const optsChainPair = { - "strDirection": "M2S", - "chainSrc": imaState.chainProperties.mn, - "chainDst": imaState.chainProperties.sc - }; return await IMA.doTransfer( // main-net --> s-chain "M2S", joRuntimeOpts, imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, - imaState.chainProperties.mn.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.strChainName, imaState.chainProperties.sc.strChainName, @@ -1343,8 +1336,7 @@ export function commandLineTaskTransferM2S() { imaState.nBlockAgeM2S, imaBLS.doSignMessagesM2S, null, - imaState.chainProperties.sc.transactionCustomizer, - optsChainPair + imaState.chainProperties.sc.transactionCustomizer ); } } ); @@ -1362,21 +1354,14 @@ export function commandLineTaskTransferS2M() { idxChainKnownForS2S: 0, cntChainsKnownForS2S: 0 }; - const optsChainPair = { - "strDirection": "S2M", - "chainSrc": imaState.chainProperties.sc, - "chainDst": imaState.chainProperties.mn - }; return await IMA.doTransfer( // s-chain --> main-net "S2M", joRuntimeOpts, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, - imaState.chainProperties.sc.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.mn.strChainName, @@ -1391,8 +1376,7 @@ export function commandLineTaskTransferS2M() { imaState.nBlockAgeS2M, imaBLS.doSignMessagesS2M, null, - imaState.chainProperties.mn.transactionCustomizer, - optsChainPair + imaState.chainProperties.mn.transactionCustomizer ); } } ); @@ -1419,7 +1403,6 @@ export function commandLineTaskTransferS2S() { skaleObserver, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.sc.chainId, diff --git a/agent/loop.mjs b/agent/loop.mjs index ae8a64cc2..71a1170a6 100644 --- a/agent/loop.mjs +++ b/agent/loop.mjs @@ -220,21 +220,16 @@ async function singleTransferLoopPartM2S( optsLoop, strLogPrefix ) { if( checkTimeFraming( null, "m2s", optsLoop.joRuntimeOpts ) ) { imaState.loopState.m2s.isInProgress = true; await pwa.notifyOnLoopStart( imaState, "m2s" ); - const optsChainPair = { - "strDirection": "M2S", - "chainSrc": imaState.chainProperties.mn, - "chainDst": imaState.chainProperties.sc - }; b1 = await IMA.doTransfer( // main-net --> s-chain "M2S", optsLoop.joRuntimeOpts, + imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, - imaState.chainProperties.sc.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, + imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.strChainName, imaState.chainProperties.sc.strChainName, @@ -249,8 +244,7 @@ async function singleTransferLoopPartM2S( optsLoop, strLogPrefix ) { imaState.nBlockAgeM2S, imaBLS.doSignMessagesM2S, null, - imaState.chainProperties.sc.transactionCustomizer, - optsChainPair + imaState.chainProperties.sc.transactionCustomizer ); imaState.loopState.m2s.isInProgress = false; await pwa.notifyOnLoopEnd( imaState, "m2s" ); @@ -306,21 +300,16 @@ async function singleTransferLoopPartS2M( optsLoop, strLogPrefix ) { if( checkTimeFraming( null, "s2m", optsLoop.joRuntimeOpts ) ) { imaState.loopState.s2m.isInProgress = true; await pwa.notifyOnLoopStart( imaState, "s2m" ); - const optsChainPair = { - "strDirection": "S2M", - "chainSrc": imaState.chainProperties.sc, - "chainDst": imaState.chainProperties.mn - }; b2 = await IMA.doTransfer( // s-chain --> main-net "S2M", optsLoop.joRuntimeOpts, + imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, - imaState.chainProperties.sc.joAbiIMA.message_proxy_mainnet_abi, + imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.mn.strChainName, @@ -335,8 +324,7 @@ async function singleTransferLoopPartS2M( optsLoop, strLogPrefix ) { imaState.nBlockAgeS2M, imaBLS.doSignMessagesS2M, null, - imaState.chainProperties.mn.transactionCustomizer, - optsChainPair + imaState.chainProperties.mn.transactionCustomizer ); imaState.loopState.s2m.isInProgress = false; await pwa.notifyOnLoopEnd( imaState, "s2m" ); @@ -385,7 +373,6 @@ async function singleTransferLoopPartS2S( optsLoop, strLogPrefix ) { skaleObserver, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.sc.chainId, @@ -849,7 +836,7 @@ export async function ensureHaveWorkers( opts ) { }; while( ! aClient.logicalInitComplete ) { if( log.verboseGet() >= log.verboseReversed().info ) - log.write( "LOOP server is not initialized yet...\n" ); + log.write( "LOOP server is not inited yet...\n" ); await threadInfo.sleep( 1000 ); aClient.send( jo ); } diff --git a/agent/test/agentUnitTests.js b/agent/test/agentUnitTests.js index d142e5487..00158e3bd 100644 --- a/agent/test/agentUnitTests.js +++ b/agent/test/agentUnitTests.js @@ -490,8 +490,6 @@ describe( "tests for `npms/skale-ima` 3", function() { it( "should return `false` invoke `doTransfer`", async function() { let joMessageProxySrc; // for `false` output - const joMessageProxySrcABI = null; - const joMessageProxyDstABI = null; const chainNameSrc = "test"; const chainNameDst = "test"; const nTransactionsCountInBlock = 4; @@ -510,11 +508,9 @@ describe( "tests for `npms/skale-ima` 3", function() { joRuntimeOpts, ethersProviderSrc, joMessageProxySrc, - joMessageProxySrcABI, joAccountSrc, ethersProviderDst, joMessageProxyDst, - joMessageProxyDstABI, joAccountDst, chainNameSrc, chainNameDst, @@ -546,19 +542,15 @@ describe( "tests for `npms/skale-ima` 3", function() { idxChainKnownForS2S: 0, cntChainsKnownForS2S: 0 }; - const joMessageProxySrcABI = null; - const joMessageProxyDstABI = null; // eslint-disable-next-line no-unused-expressions expect( await IMA.doTransfer( "M2S", joRuntimeOpts, ethersProviderSrc, joMessageProxySrc, - joMessageProxySrcABI, joAccountSrc, ethersProviderDst, joMessageProxyDst, - joMessageProxyDstABI, joAccountDst, chainNameSrc, chainNameDst, diff --git a/npms/skale-ima/imaEventLogScan.mjs b/npms/skale-ima/imaEventLogScan.mjs index bf7da1fc9..5b22f155d 100644 --- a/npms/skale-ima/imaEventLogScan.mjs +++ b/npms/skale-ima/imaEventLogScan.mjs @@ -31,12 +31,6 @@ import * as rpcCall from "../../agent/rpcCall.mjs"; import * as imaHelperAPIs from "./imaHelperAPIs.mjs"; import * as imaTransferErrorHandling from "./imaTransferErrorHandling.mjs"; -import * as childProcessModule from "child_process"; -import * as path from "path"; -import * as url from "url"; - -const __dirname = path.dirname( url.fileURLToPath( import.meta.url ) ); - export function createProgressiveEventsScanPlan( details, nLatestBlockNumber ) { // assume Main Net mines 6 blocks per minute const blocksInOneMinute = 6; @@ -92,87 +86,9 @@ export function createProgressiveEventsScanPlan( details, nLatestBlockNumber ) { return arrProgressiveEventsScanPlan; } -export function extractEventArg( arg ) { - if( arg && typeof arg == "object" && "type" in arg && typeof arg.type == "string" && - arg.type == "BigNumber" && "hex" in arg && typeof arg.hex == "string" ) - return owaspUtils.toBN( arg.hex ); - return arg; -} - -function generateWhileTransferringLogMessageSuffix( optsChainPair ) { - if( ! optsChainPair ) - return ""; - if( ! optsChainPair.strDirection ) - return ""; - if( optsChainPair.strDirection == "S2S" ) { - return cc.debug( " (while performing " ) + cc.attention( optsChainPair.strDirection ) + - cc.debug( " transfer with external S-Chain " ) + - cc.info( optsChainPair.optsSpecificS2S.joSChain.data.name ) + cc.debug( " / " ) + - cc.notice( optsChainPair.optsSpecificS2S.joSChain.data.computed.chainId ) + - cc.debug( " node " ) + cc.info( optsChainPair.optsSpecificS2S.idxNode ) + - cc.debug( ")" ); - } - return cc.debug( " (while performing " ) + cc.attention( optsChainPair.strDirection ) + - cc.debug( " transfer)" ); -} - -export async function safeGetPastEventsProgressiveExternal( - details, strLogPrefix, ethersProvider, attempts, - joContract, joABI, strEventName, - nBlockFrom, nBlockTo, joFilter, optsChainPair -) { - if( joABI && typeof joABI == "object" ) { - const escapeShell = function( cmd ) { - return "\"" + cmd.replace( /(["'$`\\])/g,"\\$1" ) + "\""; - }; - const joArg = { - "url": owaspUtils.ethersProviderToUrl( ethersProvider ), - "attempts": attempts, - "strEventName": strEventName, - "nBlockFrom": nBlockFrom, - "nBlockTo": nBlockTo, - "joFilter": joFilter, - "address": joContract.address, - "abi": joABI - }; - const cmd = "node " + path.join( __dirname, "imaExternalLogScan.mjs" ) + " " + - escapeShell( JSON.stringify( joArg ) ); - if( log.verboseGet() >= log.verboseReversed().trace ) { - details.write( strLogPrefix + - cc.debug( "Will run external command to search logs for event " ) + - cc.j( strEventName ) + cc.debug( " via URL " ) + cc.u( joArg.url ) + - generateWhileTransferringLogMessageSuffix( optsChainPair ) + - cc.debug( "..." ) + "\n" ); - } - const res = childProcessModule.execSync( cmd ); - if( "error" in res && res.error ) { - if( log.verboseGet() >= log.verboseReversed().error ) { - details.write( strLogPrefix + - cc.error( "Got error from external command to search logs for event " ) + - cc.j( strEventName ) + cc.error( " via URL " ) + cc.u( joArg.url ) + - generateWhileTransferringLogMessageSuffix( optsChainPair ) + - cc.error( ":" ) + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n" ); - } - throw new Error( res.error ); - } - if( log.verboseGet() >= log.verboseReversed().trace ) { - details.write( strLogPrefix + - cc.debug( "Done running external command to search logs for event " ) + - cc.j( strEventName ) + cc.debug( " via URL " ) + cc.u( joArg.url ) + - generateWhileTransferringLogMessageSuffix( optsChainPair ) + - cc.debug( "." ) + "\n" ); - } - return JSON.parse( res ).result; - } - return await safeGetPastEventsProgressive( - details, strLogPrefix, ethersProvider, attempts, - joContract, strEventName, - nBlockFrom, nBlockTo, joFilter ); -} - export async function safeGetPastEventsProgressive( - details, strLogPrefix, ethersProvider, attempts, - joContract, strEventName, + details, strLogPrefix, + ethersProvider, attempts, joContract, strEventName, nBlockFrom, nBlockTo, joFilter ) { if( ! imaTransferErrorHandling.getEnabledProgressiveEventsScan() ) { diff --git a/npms/skale-ima/imaExternalLogScan.mjs b/npms/skale-ima/imaExternalLogScan.mjs deleted file mode 100644 index 6c740d497..000000000 --- a/npms/skale-ima/imaExternalLogScan.mjs +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only - -/** - * @license - * SKALE IMA - * - * SKALE IMA is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SKALE IMA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with SKALE IMA. If not, see . - */ - -/** - * @file imaExternalLogScan.mjs - * @copyright SKALE Labs 2019-Present - */ - -import * as cc from "../skale-cc/cc.mjs"; -import * as log from "../skale-log/log.mjs"; -import * as owaspUtils from "../skale-owasp/owaspUtils.mjs"; -import * as imaEventLogScan from "./imaEventLogScan.mjs"; - -const gIsDebugLogging = false; // development option only, must be always false -cc.enable( false ); -log.addStdout(); - -// allow self-signed wss and https -process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; - -function finalizeOutput( jo ) { - if( ! jo ) - return; - cc.enable( false ); - process.stdout.write( cc.j( jo ) ); -} - -async function run() { - const details = log.createMemoryStream(); - try { - if( gIsDebugLogging ) { - log.write( cc.debug( "Process startup arguments array is " ) + - cc.j( process.argv ) + "\n" ); - } - if( process.argv.length != 3 ) - throw new Error( "Wrong number of command line arguments" ); - - if( gIsDebugLogging ) { - log.write( cc.debug( "Main argument text is " ) + - cc.j( process.argv[2] ) + "\n" ); - } - const joArg = JSON.parse( process.argv[2] ); - if( gIsDebugLogging ) { - log.write( cc.debug( "Main argument JSON is " ) + - cc.j( joArg ) + "\n" ); - } - - const ethersProvider = owaspUtils.getEthersProviderFromURL( joArg.url ); - const joContract = new owaspUtils.ethersMod.ethers.Contract( - joArg.address, joArg.abi, ethersProvider ); - - const arrLogRecordReferencesWalk = await imaEventLogScan.safeGetPastEventsProgressive( - details, "", ethersProvider, joArg.attempts, - joContract, joArg.strEventName, - joArg.nBlockFrom, joArg.nBlockTo, joArg.joFilter ); - - finalizeOutput( { "result": arrLogRecordReferencesWalk, "error": null } ); - process.exit( 0 ); - } catch ( err ) { - if( gIsDebugLogging ) { - log.write( cc.error( "Failed to create RPC call: " ) + - cc.j( err ) + "\n" ); - } - finalizeOutput( { - "error": owaspUtils.extractErrorMessage( err ), - "output": details.toString() - } ); - process.exit( 1 ); - } -} -run(); diff --git a/npms/skale-ima/imaSgxExternalSigner.mjs b/npms/skale-ima/imaSgxExternalSigner.mjs index 60fe93b9b..87715dcc4 100644 --- a/npms/skale-ima/imaSgxExternalSigner.mjs +++ b/npms/skale-ima/imaSgxExternalSigner.mjs @@ -6,7 +6,7 @@ import * as rpcCall from "../../agent/rpcCall.mjs"; const gIsDebugLogging = false; // development option only, must be always false const isColors = owaspUtils.toBoolean( process.argv[2] ); -cc.enable( false ); +cc.enable( true ); log.addStdout(); // allow self-signed wss and https diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index 93b9ff712..6666a1cbf 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -44,14 +44,16 @@ const perMessageGasForTransfer = 1000000; const additionalS2MTransferOverhead = 200000; async function findOutReferenceLogRecord( - details, strLogPrefix, ethersProvider, joMessageProxy, joABI, - bnBlockId, nMessageNumberToFind, isVerbose, optsChainPair + details, strLogPrefix, + ethersProvider, joMessageProxy, + bnBlockId, nMessageNumberToFind, isVerbose ) { const bnMessageNumberToFind = owaspUtils.toBN( nMessageNumberToFind.toString() ); const strEventName = "PreviousMessageReference"; - const arrLogRecords = await imaEventLogScan.safeGetPastEventsProgressiveExternal( - details, strLogPrefix, ethersProvider, 10, joMessageProxy, joABI, strEventName, - bnBlockId, bnBlockId, joMessageProxy.filters[strEventName](), optsChainPair + const arrLogRecords = await imaEventLogScan.safeGetPastEventsProgressive( + details, strLogPrefix, + ethersProvider, 10, joMessageProxy, strEventName, + bnBlockId, bnBlockId, joMessageProxy.filters[strEventName]() ); const cntLogRecord = arrLogRecords.length; if( isVerbose ) { @@ -64,8 +66,8 @@ async function findOutReferenceLogRecord( for( let idxLogRecord = 0; idxLogRecord < cntLogRecord; ++ idxLogRecord ) { const joEvent = arrLogRecords[idxLogRecord]; const eventValuesByName = { - "currentMessage": imaEventLogScan.extractEventArg( joEvent.args[0] ), - "previousOutgoingMessageBlockId": imaEventLogScan.extractEventArg( joEvent.args[1] ) + "currentMessage": joEvent.args[0], + "previousOutgoingMessageBlockId": joEvent.args[1] }; const joReferenceLogRecord = { "currentMessage": eventValuesByName.currentMessage, @@ -96,8 +98,9 @@ async function findOutReferenceLogRecord( } async function findOutAllReferenceLogRecords( - details, strLogPrefix, ethersProvider, joMessageProxy, joABI, - bnBlockId, nIncMsgCnt, nOutMsgCnt, isVerbose, optsChainPair + details, strLogPrefix, + ethersProvider, joMessageProxy, + bnBlockId, nIncMsgCnt, nOutMsgCnt, isVerbose ) { if( isVerbose ) { if( log.verboseGet() >= log.verboseReversed().debug ) { @@ -125,9 +128,12 @@ async function findOutAllReferenceLogRecords( let nWalkMsgNumber = nOutMsgCnt - 1; let nWalkBlockId = bnBlockId; for( ; nWalkMsgNumber >= nIncMsgCnt; -- nWalkMsgNumber ) { - const joReferenceLogRecord = await findOutReferenceLogRecord( - details, strLogPrefix, ethersProvider, joMessageProxy, joABI, - nWalkBlockId, nWalkMsgNumber, isVerbose, optsChainPair ); + const joReferenceLogRecord = + await findOutReferenceLogRecord( + details, strLogPrefix, + ethersProvider, joMessageProxy, + nWalkBlockId, nWalkMsgNumber, isVerbose + ); if( joReferenceLogRecord == null ) break; nWalkBlockId = owaspUtils.toBN( joReferenceLogRecord.previousOutgoingMessageBlockId ); @@ -281,11 +287,11 @@ async function doQueryOutgoingMessageCounter( optsTransfer ) { optsTransfer.strActionName = "in-getOutgoingMessagesCounter()--findOutAllReferenceLogRecords()"; optsTransfer.arrLogRecordReferences = - await findOutAllReferenceLogRecords( optsTransfer.details, - optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, - optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, - bnBlockId, optsTransfer.nIncMsgCnt, optsTransfer.nOutMsgCnt, true, - optsTransfer.optsChainPair ); + await findOutAllReferenceLogRecords( + optsTransfer.details, optsTransfer.strLogPrefixShort, + optsTransfer.ethersProviderSrc, optsTransfer.joMessageProxySrc, + bnBlockId, optsTransfer.nIncMsgCnt, optsTransfer.nOutMsgCnt, true + ); return true; // success, finish at this point } catch ( err ) { optsTransfer.arrLogRecordReferences = []; @@ -320,14 +326,15 @@ async function doQueryOutgoingMessageCounter( optsTransfer ) { ++ nWalkMsgNumber ) { const joFilter = optsTransfer.joMessageProxySrc.filters[strEventName]( - owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainIdDst ), + owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainIdDst ), // dstChainHash owaspUtils.toBN( nWalkMsgNumber ) ); - const arrLogRecordReferencesWalk = await imaEventLogScan - .safeGetPastEventsProgressiveExternal( optsTransfer.details, - optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, attempts, - optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, strEventName, - nBlockFrom, nBlockTo, joFilter, optsTransfer.optsChainPair ); + const arrLogRecordReferencesWalk = await imaEventLogScan.safeGetPastEventsProgressive( + optsTransfer.details, optsTransfer.strLogPrefixShort, + optsTransfer.ethersProviderSrc, attempts, optsTransfer.joMessageProxySrc, + strEventName, + nBlockFrom, nBlockTo, joFilter + ); optsTransfer.arrLogRecordReferences = optsTransfer.arrLogRecordReferences.concat( arrLogRecordReferencesWalk ); } @@ -354,11 +361,11 @@ async function analyzeGatheredRecords( optsTransfer, r ) { cc.debug( " with data " ) + cc.j( joEvent ) + "\n" ); } const eventValuesByName = { - "dstChainHash": imaEventLogScan.extractEventArg( joEvent.args[0] ), - "msgCounter": imaEventLogScan.extractEventArg( joEvent.args[1] ), - "srcContract": imaEventLogScan.extractEventArg( joEvent.args[2] ), - "dstContract": imaEventLogScan.extractEventArg( joEvent.args[3] ), - "data": imaEventLogScan.extractEventArg( joEvent.args[4] ) + "dstChainHash": joEvent.args[0], + "msgCounter": joEvent.args[1], + "srcContract": joEvent.args[2], + "dstContract": joEvent.args[3], + "data": joEvent.args[4] }; if( eventValuesByName.dstChainHash == strChainHashWeAreLookingFor ) { joValues = eventValuesByName; @@ -425,13 +432,13 @@ async function gatherMessages( optsTransfer ) { cc.notice( optsTransfer.strActionName ) + cc.debug( " for " ) + cc.info( strEventName ) + cc.debug( " event..." ) + "\n" ); } - r = await imaEventLogScan.safeGetPastEventsProgressiveExternal( optsTransfer.details, - optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, 10, - optsTransfer.joMessageProxySrc, optsTransfer.joMessageProxySrcABI, strEventName, - nBlockFrom, nBlockTo, optsTransfer.joMessageProxySrc.filters[strEventName]( - owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), + r = await imaEventLogScan.safeGetPastEventsProgressive( + optsTransfer.details, optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, + 10, optsTransfer.joMessageProxySrc, strEventName, nBlockFrom, nBlockTo, + optsTransfer.joMessageProxySrc.filters[strEventName]( + owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), // dstChainHash owaspUtils.toBN( optsTransfer.nIdxCurrentMsg ) - ), optsTransfer.optsChainPair ); + ) ); const joValues = await analyzeGatheredRecords( optsTransfer, r ); if( joValues == null ) return false; @@ -443,8 +450,8 @@ async function gatherMessages( optsTransfer ) { const transactionHash = r[0].transactionHash; if( log.verboseGet() >= log.verboseReversed().debug ) { optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.debug( "Event transactionHash is " ) + - cc.info( transactionHash ) + "\n" ); + cc.debug( "Event transactionHash is " ) + cc.info( transactionHash ) + + "\n" ); } const blockNumber = r[0].blockNumber; optsTransfer.details.write( optsTransfer.strLogPrefix + @@ -470,10 +477,10 @@ async function gatherMessages( optsTransfer ) { if( log.verboseGet() >= log.verboseReversed().critical ) { const strError = owaspUtils.extractErrorMessage( err ); const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " Exception(evaluate block depth) while getting transaction " + - "hash and block number during " + optsTransfer.strActionName + ": " ) + - cc.error( strError ) + cc.error( ", stack is: " ) + "\n" + - cc.stack( err.stack ) + "\n"; + cc.error( " Exception(evaluate block depth) while " + + "getting transaction hash and block number during " + + optsTransfer.strActionName + ": " ) + cc.error( strError ) + + cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + "\n"; optsTransfer.details.write( s ); if( log.id != optsTransfer.details.id ) log.write( s ); @@ -578,7 +585,9 @@ async function gatherMessages( optsTransfer ) { cc.info( optsTransfer.nIdxCurrentMsg ) + cc.success( " and " ) + cc.notice( "dstChain" ) + cc.success( " set to " ) + cc.info( optsTransfer.chainNameDst ) + cc.success( ", event description: " ) + - cc.j( joValues ) + "\n" ); + cc.j( joValues ) + + // + cc.j(evs) + + "\n" ); optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Will process message counter value " ) + cc.info( optsTransfer.nIdxCurrentMsg ) + "\n" ); @@ -889,7 +898,6 @@ async function handleAllMessagesSigning( optsTransfer ) { } async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { - const sc = optsTransfer.imaState.chainProperties.sc; const cntNodes = joSChain.data.computed.nodes.length; const cntMessages = optsTransfer.jarrMessages.length; for( let idxMessage = 0; idxMessage < cntMessages; ++ idxMessage ) { @@ -922,20 +930,25 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { // eslint-disable-next-line dot-notation const ethersProviderNode = owaspUtils.getEthersProviderFromURL( strUrlHttp ); - const joMessageProxyNode = new owaspUtils.ethersMod.ethers.Contract( - sc.joAbiIMA.message_proxy_chain_address, - sc.joAbiIMA.message_proxy_chain_abi, - ethersProviderNode ); - const joMessageProxyNodeABI = sc.joAbiIMA.message_proxy_chain_abi; + const joMessageProxyNode = + new owaspUtils.ethersMod.ethers.Contract( + optsTransfer.imaState.chainProperties.sc + .joAbiIMA.message_proxy_chain_address, + optsTransfer.imaState.chainProperties.sc + .joAbiIMA.message_proxy_chain_abi, + ethersProviderNode + ); const strEventName = "OutgoingMessage"; - const node_r = await imaEventLogScan.safeGetPastEventsProgressiveExternal( - optsTransfer.details, optsTransfer.strLogPrefixShort, ethersProviderNode, - 10, joMessageProxyNode, joMessageProxyNodeABI, strEventName, + const node_r = await imaEventLogScan.safeGetPastEventsProgressive( + optsTransfer.details, optsTransfer.strLogPrefixShort, + ethersProviderNode, 10, joMessageProxyNode, strEventName, joMessage.savedBlockNumberForOptimizations, joMessage.savedBlockNumberForOptimizations, joMessageProxyNode.filters[strEventName]( owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), - owaspUtils.toBN( idxImaMessage ) ), optsTransfer.optsChainPair ); + owaspUtils.toBN( idxImaMessage ) + ) + ); const cntEvents = node_r.length; if( log.verboseGet() >= log.verboseReversed().trace ) { optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Got " ) + @@ -947,11 +960,11 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { for( let idxEvent = 0; idxEvent < cntEvents; ++ idxEvent ) { const joEvent = node_r[idxEvent]; const eventValuesByName = { - "dstChainHash": imaEventLogScan.extractEventArg( joEvent.args[0] ), - "msgCounter": imaEventLogScan.extractEventArg( joEvent.args[1] ), - "srcContract": imaEventLogScan.extractEventArg( joEvent.args[2] ), - "dstContract": imaEventLogScan.extractEventArg( joEvent.args[3] ), - "data": imaEventLogScan.extractEventArg( joEvent.args[4] ) + "dstChainHash": joEvent.args[0], + "msgCounter": joEvent.args[1], + "srcContract": joEvent.args[2], + "dstContract": joEvent.args[3], + "data": joEvent.args[4] }; if( owaspUtils.ensureStartsWith0x( joMessage.sender ).toLowerCase() == @@ -1263,26 +1276,23 @@ let gIsOneTransferInProgressInThisThread = false; export async function doTransfer( strDirection, joRuntimeOpts, - ethersProviderSrc, joMessageProxySrc, joMessageProxySrcABI, joAccountSrc, - ethersProviderDst, joMessageProxyDst, joMessageProxyDstABI, joAccountDst, + ethersProviderSrc, joMessageProxySrc, joAccountSrc, + ethersProviderDst, joMessageProxyDst, joAccountDst, chainNameSrc, chainNameDst, chainIdSrc, chainIdDst, joDepositBoxMainNet, // for logs validation on mainnet joTokenManagerSChain, // for logs validation on s-chain nTransactionsCountInBlock, nTransferSteps, nMaxTransactionsCount, nBlockAwaitDepth, nBlockAge, - fnSignMessages, joExtraSignOpts, transactionCustomizerDst, optsChainPair + fnSignMessages, joExtraSignOpts, transactionCustomizerDst ) { const optsTransfer = { strDirection: strDirection, joRuntimeOpts: joRuntimeOpts, - optsChainPair: optsChainPair, ethersProviderSrc: ethersProviderSrc, joMessageProxySrc: joMessageProxySrc, - joMessageProxySrcABI: joMessageProxySrcABI, joAccountSrc: joAccountSrc, ethersProviderDst: ethersProviderDst, joMessageProxyDst: joMessageProxyDst, - joMessageProxyDstABI: joMessageProxyDstABI, joAccountDst: joAccountDst, chainNameSrc: chainNameSrc, chainNameDst: chainNameDst, @@ -1461,7 +1471,6 @@ export async function doAllS2S( // s-chain --> s-chain skaleObserver, ethersProviderDst, joMessageProxyDst, - joMessageProxyDstABI, joAccountDst, chainNameDst, chainIdDst, @@ -1486,8 +1495,7 @@ export async function doAllS2S( // s-chain --> s-chain } for( let idxSChain = 0; idxSChain < cntSChains; ++ idxSChain ) { const joSChain = arrSChainsCached[idxSChain]; - const joPickResult = skaleObserver.pickRandomSChainIndexAndNodeAndUrl( joSChain ); - const urlSrc = joPickResult.strURL; + const urlSrc = skaleObserver.pickRandomSChainUrl( joSChain ); const ethersProviderSrc = owaspUtils.getEthersProviderFromURL( urlSrc ); const joAccountSrc = joAccountDst; // ??? const chainNameSrc = "" + joSChain.data.name; @@ -1516,8 +1524,6 @@ export async function doAllS2S( // s-chain --> s-chain imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, ethersProviderSrc ); - const joMessageProxySrcABI = - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi; const joDepositBoxSrc = new owaspUtils.ethersMod.ethers.Contract( imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_address, @@ -1542,28 +1548,15 @@ export async function doAllS2S( // s-chain --> s-chain imaState.loopState.s2s.isInProgress = true; await pwa.notifyOnLoopStart( imaState, "s2s", nIndexS2S ); - const optsChainPair = { - "strDirection": strDirection, - "chainSrc": null, - "chainDst": imaState.chainProperties.sc, - "optsSpecificS2S": { - "joSChain": joSChain, - "idxSChain": idxSChain, - "urlSrc": urlSrc, - "idxNode": joPickResult.idxNode, - "joNode": joPickResult.joNode - } - }; - bOK = await doTransfer( + bOK = + await doTransfer( strDirection, joRuntimeOpts, ethersProviderSrc, joMessageProxySrc, - joMessageProxySrcABI, joAccountSrc, ethersProviderDst, joMessageProxyDst, - joMessageProxyDstABI, joAccountDst, chainNameSrc, chainNameDst, @@ -1578,8 +1571,7 @@ export async function doAllS2S( // s-chain --> s-chain nBlockAge, fnSignMessages, joExtraSignOpts, - transactionCustomizerDst, - optsChainPair + transactionCustomizerDst ); imaState.loopState.s2s.isInProgress = false; await pwa.notifyOnLoopEnd( imaState, "s2s", nIndexS2S ); diff --git a/npms/skale-observer/observer.mjs b/npms/skale-observer/observer.mjs index c9146cf9c..47364448e 100644 --- a/npms/skale-observer/observer.mjs +++ b/npms/skale-observer/observer.mjs @@ -1333,7 +1333,7 @@ export async function ensureHaveWorker( opts ) { }; while( ! gClient.logicalInitComplete ) { if( log.verboseGet() >= log.verboseReversed().info ) - log.write( "SNB server is not initialized yet...\n" ); + log.write( "SNB server is not inited yet...\n" ); await threadInfo.sleep( 1000 ); gClient.send( jo ); @@ -1513,19 +1513,6 @@ export function pickRandomSChainUrl( joSChain ) { return "" + joNode["http_endpoint_ip"]; } -export function pickRandomSChainIndexAndNodeAndUrl( joSChain ) { - const idxNode = pickRandomSChainNodeIndex( joSChain ); - const joNode = joSChain.data.computed.nodes[idxNode]; - // eslint-disable-next-line dot-notation - const strURL = "" + joNode["http_endpoint_ip"]; - const joPickResult = { - "strURL": strURL, - "joNode": joNode, - "idxNode": idxNode - }; - return joPickResult; -} - export async function discoverChainId( strURL ) { let ret = null; const rpcCallOpts = null; From 32cde11421df0d1c03d169737330e6bc29083332 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Mon, 30 Oct 2023 16:11:06 +0000 Subject: [PATCH 11/29] revert redundant code changes --- agent/clpTools.mjs | 5 ----- agent/loop.mjs | 5 ----- agent/test/agentUnitTests.js | 8 ------- npms/skale-ima/imaEventLogScan.mjs | 7 ------ npms/skale-ima/index.mjs | 35 ++++++++++++------------------ 5 files changed, 14 insertions(+), 46 deletions(-) diff --git a/agent/clpTools.mjs b/agent/clpTools.mjs index 8bb30473c..d1673c5df 100644 --- a/agent/clpTools.mjs +++ b/agent/clpTools.mjs @@ -1324,11 +1324,9 @@ export function commandLineTaskTransferM2S() { joRuntimeOpts, imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, - imaState.chainProperties.mn.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.strChainName, imaState.chainProperties.sc.strChainName, @@ -1372,11 +1370,9 @@ export function commandLineTaskTransferS2M() { joRuntimeOpts, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, - imaState.chainProperties.sc.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.mn.strChainName, @@ -1419,7 +1415,6 @@ export function commandLineTaskTransferS2S() { skaleObserver, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.sc.chainId, diff --git a/agent/loop.mjs b/agent/loop.mjs index ae8a64cc2..3b408e4e7 100644 --- a/agent/loop.mjs +++ b/agent/loop.mjs @@ -230,11 +230,9 @@ async function singleTransferLoopPartM2S( optsLoop, strLogPrefix ) { optsLoop.joRuntimeOpts, imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, - imaState.chainProperties.sc.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.strChainName, imaState.chainProperties.sc.strChainName, @@ -316,11 +314,9 @@ async function singleTransferLoopPartS2M( optsLoop, strLogPrefix ) { optsLoop.joRuntimeOpts, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.mn.ethersProvider, imaState.joMessageProxyMainNet, - imaState.chainProperties.sc.joAbiIMA.message_proxy_mainnet_abi, imaState.chainProperties.mn.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.mn.strChainName, @@ -385,7 +381,6 @@ async function singleTransferLoopPartS2S( optsLoop, strLogPrefix ) { skaleObserver, imaState.chainProperties.sc.ethersProvider, imaState.joMessageProxySChain, - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, imaState.chainProperties.sc.joAccount, imaState.chainProperties.sc.strChainName, imaState.chainProperties.sc.chainId, diff --git a/agent/test/agentUnitTests.js b/agent/test/agentUnitTests.js index d142e5487..00158e3bd 100644 --- a/agent/test/agentUnitTests.js +++ b/agent/test/agentUnitTests.js @@ -490,8 +490,6 @@ describe( "tests for `npms/skale-ima` 3", function() { it( "should return `false` invoke `doTransfer`", async function() { let joMessageProxySrc; // for `false` output - const joMessageProxySrcABI = null; - const joMessageProxyDstABI = null; const chainNameSrc = "test"; const chainNameDst = "test"; const nTransactionsCountInBlock = 4; @@ -510,11 +508,9 @@ describe( "tests for `npms/skale-ima` 3", function() { joRuntimeOpts, ethersProviderSrc, joMessageProxySrc, - joMessageProxySrcABI, joAccountSrc, ethersProviderDst, joMessageProxyDst, - joMessageProxyDstABI, joAccountDst, chainNameSrc, chainNameDst, @@ -546,19 +542,15 @@ describe( "tests for `npms/skale-ima` 3", function() { idxChainKnownForS2S: 0, cntChainsKnownForS2S: 0 }; - const joMessageProxySrcABI = null; - const joMessageProxyDstABI = null; // eslint-disable-next-line no-unused-expressions expect( await IMA.doTransfer( "M2S", joRuntimeOpts, ethersProviderSrc, joMessageProxySrc, - joMessageProxySrcABI, joAccountSrc, ethersProviderDst, joMessageProxyDst, - joMessageProxyDstABI, joAccountDst, chainNameSrc, chainNameDst, diff --git a/npms/skale-ima/imaEventLogScan.mjs b/npms/skale-ima/imaEventLogScan.mjs index bcc0a37b7..85fab34e1 100644 --- a/npms/skale-ima/imaEventLogScan.mjs +++ b/npms/skale-ima/imaEventLogScan.mjs @@ -86,13 +86,6 @@ export function createProgressiveEventsScanPlan( details, nLatestBlockNumber ) { return arrProgressiveEventsScanPlan; } -export function extractEventArg( arg ) { - if( arg && typeof arg == "object" && "type" in arg && typeof arg.type == "string" && - arg.type == "BigNumber" && "hex" in arg && typeof arg.hex == "string" ) - return owaspUtils.toBN( arg.hex ); - return arg; -} - function generateWhileTransferringLogMessageSuffix( optsChainPair ) { if( ! optsChainPair ) return ""; diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index 93b2a6a4f..f3b825299 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -64,8 +64,8 @@ async function findOutReferenceLogRecord( for( let idxLogRecord = 0; idxLogRecord < cntLogRecord; ++ idxLogRecord ) { const joEvent = arrLogRecords[idxLogRecord]; const eventValuesByName = { - "currentMessage": imaEventLogScan.extractEventArg( joEvent.args[0] ), - "previousOutgoingMessageBlockId": imaEventLogScan.extractEventArg( joEvent.args[1] ) + "currentMessage": joEvent.args[0], + "previousOutgoingMessageBlockId": joEvent.args[1] }; const joReferenceLogRecord = { "currentMessage": eventValuesByName.currentMessage, @@ -352,11 +352,11 @@ async function analyzeGatheredRecords( optsTransfer, r ) { cc.debug( " with data " ) + cc.j( joEvent ) + "\n" ); } const eventValuesByName = { - "dstChainHash": imaEventLogScan.extractEventArg( joEvent.args[0] ), - "msgCounter": imaEventLogScan.extractEventArg( joEvent.args[1] ), - "srcContract": imaEventLogScan.extractEventArg( joEvent.args[2] ), - "dstContract": imaEventLogScan.extractEventArg( joEvent.args[3] ), - "data": imaEventLogScan.extractEventArg( joEvent.args[4] ) + "dstChainHash": joEvent.args[0], + "msgCounter": joEvent.args[1], + "srcContract": joEvent.args[2], + "dstContract": joEvent.args[3], + "data": joEvent.args[4] }; if( eventValuesByName.dstChainHash == strChainHashWeAreLookingFor ) { joValues = eventValuesByName; @@ -944,11 +944,11 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { for( let idxEvent = 0; idxEvent < cntEvents; ++ idxEvent ) { const joEvent = node_r[idxEvent]; const eventValuesByName = { - "dstChainHash": imaEventLogScan.extractEventArg( joEvent.args[0] ), - "msgCounter": imaEventLogScan.extractEventArg( joEvent.args[1] ), - "srcContract": imaEventLogScan.extractEventArg( joEvent.args[2] ), - "dstContract": imaEventLogScan.extractEventArg( joEvent.args[3] ), - "data": imaEventLogScan.extractEventArg( joEvent.args[4] ) + "dstChainHash": joEvent.args[0], + "msgCounter": joEvent.args[1], + "srcContract": joEvent.args[2], + "dstContract": joEvent.args[3], + "data": joEvent.args[4] }; if( owaspUtils.ensureStartsWith0x( joMessage.sender ).toLowerCase() == @@ -1260,8 +1260,8 @@ let gIsOneTransferInProgressInThisThread = false; export async function doTransfer( strDirection, joRuntimeOpts, - ethersProviderSrc, joMessageProxySrc, joMessageProxySrcABI, joAccountSrc, - ethersProviderDst, joMessageProxyDst, joMessageProxyDstABI, joAccountDst, + ethersProviderSrc, joMessageProxySrc, joAccountSrc, + ethersProviderDst, joMessageProxyDst, joAccountDst, chainNameSrc, chainNameDst, chainIdSrc, chainIdDst, joDepositBoxMainNet, // for logs validation on mainnet joTokenManagerSChain, // for logs validation on s-chain @@ -1275,11 +1275,9 @@ export async function doTransfer( optsChainPair: optsChainPair, ethersProviderSrc: ethersProviderSrc, joMessageProxySrc: joMessageProxySrc, - joMessageProxySrcABI: joMessageProxySrcABI, joAccountSrc: joAccountSrc, ethersProviderDst: ethersProviderDst, joMessageProxyDst: joMessageProxyDst, - joMessageProxyDstABI: joMessageProxyDstABI, joAccountDst: joAccountDst, chainNameSrc: chainNameSrc, chainNameDst: chainNameDst, @@ -1458,7 +1456,6 @@ export async function doAllS2S( // s-chain --> s-chain skaleObserver, ethersProviderDst, joMessageProxyDst, - joMessageProxyDstABI, joAccountDst, chainNameDst, chainIdDst, @@ -1513,8 +1510,6 @@ export async function doAllS2S( // s-chain --> s-chain imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi, ethersProviderSrc ); - const joMessageProxySrcABI = - imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_abi; const joDepositBoxSrc = new owaspUtils.ethersMod.ethers.Contract( imaState.chainProperties.sc.joAbiIMA.message_proxy_chain_address, @@ -1556,11 +1551,9 @@ export async function doAllS2S( // s-chain --> s-chain joRuntimeOpts, ethersProviderSrc, joMessageProxySrc, - joMessageProxySrcABI, joAccountSrc, ethersProviderDst, joMessageProxyDst, - joMessageProxyDstABI, joAccountDst, chainNameSrc, chainNameDst, From 43355c2f7683820f0420cb105f5dc0718ab6d8a4 Mon Sep 17 00:00:00 2001 From: Dmytro Nazarenko Date: Tue, 31 Oct 2023 15:35:37 +0000 Subject: [PATCH 12/29] Update VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 227cea215..38f77a65b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.0 +2.0.1 From 0d63e3eccc01063328fad551e1542055dbdac761 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 31 Oct 2023 16:19:06 +0000 Subject: [PATCH 13/29] requested PR changes --- npms/skale-ima/index.mjs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index 560367e2e..8671a5d97 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -44,15 +44,14 @@ const perMessageGasForTransfer = 1000000; const additionalS2MTransferOverhead = 200000; async function findOutReferenceLogRecord( - details, strLogPrefix, - ethersProvider, joMessageProxy, + details, strLogPrefix, ethersProvider, joMessageProxy, bnBlockId, nMessageNumberToFind, isVerbose ) { const bnMessageNumberToFind = owaspUtils.toBN( nMessageNumberToFind.toString() ); const strEventName = "PreviousMessageReference"; const arrLogRecords = await imaEventLogScan.safeGetPastEventsProgressive( details, strLogPrefix, ethersProvider, 10, joMessageProxy, strEventName, - bnBlockId, bnBlockId, joMessageProxy.filters[strEventName](), optsChainPair + bnBlockId, bnBlockId, joMessageProxy.filters[strEventName]() ); const cntLogRecord = arrLogRecords.length; if( isVerbose ) { @@ -426,11 +425,11 @@ async function gatherMessages( optsTransfer ) { } r = await imaEventLogScan.safeGetPastEventsProgressive( optsTransfer.details, optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, 10, - optsTransfer.joMessageProxySrc, strEventName, - nBlockFrom, nBlockTo, optsTransfer.joMessageProxySrc.filters[strEventName]( + optsTransfer.joMessageProxySrc, strEventName, nBlockFrom, nBlockTo, + optsTransfer.joMessageProxySrc.filters[strEventName]( owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), owaspUtils.toBN( optsTransfer.nIdxCurrentMsg ) - ) ); + ), optsTransfer.optsChainPair ); const joValues = await analyzeGatheredRecords( optsTransfer, r ); if( joValues == null ) return false; @@ -920,11 +919,12 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { let bEventIsFound = false; try { // eslint-disable-next-line dot-notation - const ethersProviderNode = - owaspUtils.getEthersProviderFromURL( strUrlHttp ); + const ethersProviderNode = owaspUtils.getEthersProviderFromURL( strUrlHttp ); const joMessageProxyNode = new owaspUtils.ethersMod.ethers.Contract( - sc.joAbiIMA.message_proxy_chain_address, - sc.joAbiIMA.message_proxy_chain_abi, + optsTransfer.imaState.chainProperties.sc + .joAbiIMA.message_proxy_chain_address, + optsTransfer.imaState.chainProperties + .sc.joAbiIMA.message_proxy_chain_abi, ethersProviderNode ); const strEventName = "OutgoingMessage"; const node_r = await imaEventLogScan.safeGetPastEventsProgressive( @@ -935,7 +935,8 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { joMessageProxyNode.filters[strEventName]( owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), owaspUtils.toBN( idxImaMessage ) - ) + ), + optsTransfer.optsChainPair ); const cntEvents = node_r.length; if( log.verboseGet() >= log.verboseReversed().trace ) { From 0fc5d13c4a2d0e67421a8dc197efc03b71c5cb1a Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 2 Nov 2023 19:12:20 +0000 Subject: [PATCH 14/29] added details about iterative event search --- npms/skale-ima/imaEventLogScan.mjs | 4 +- npms/skale-ima/index.mjs | 84 ++++++++++++++---------------- 2 files changed, 42 insertions(+), 46 deletions(-) diff --git a/npms/skale-ima/imaEventLogScan.mjs b/npms/skale-ima/imaEventLogScan.mjs index 85fab34e1..a757c1fcd 100644 --- a/npms/skale-ima/imaEventLogScan.mjs +++ b/npms/skale-ima/imaEventLogScan.mjs @@ -126,7 +126,9 @@ export async function safeGetPastEventsProgressive( cc.j( strEventName ) + cc.info( " via URL " ) + cc.u( owaspUtils.ethersProviderToUrl( ethersProvider ) ) + generateWhileTransferringLogMessageSuffix( optsChainPair ) + - cc.info( "..." ) ); + cc.info( ", from block " ) + cc.notice( nBlockFrom ) + + cc.info( ", to block " ) + cc.notice( nBlockTo ) + + cc.info( "..." ) + "\n" ); } const nLatestBlockNumber = owaspUtils.toBN( await imaHelperAPIs.safeGetBlockNumber( details, 10, ethersProvider ) ); diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index 8671a5d97..2b3ccd659 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -278,14 +278,16 @@ async function doQueryOutgoingMessageCounter( optsTransfer ) { optsTransfer.chainNameDst, { from: optsTransfer.joAccountSrc.address() } ) ); try { - optsTransfer.strActionName = - "in-getOutgoingMessagesCounter()--findOutAllReferenceLogRecords()"; - optsTransfer.arrLogRecordReferences = - await findOutAllReferenceLogRecords( optsTransfer.details, - optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, - optsTransfer.joMessageProxySrc, bnBlockId, optsTransfer.nIncMsgCnt, - optsTransfer.nOutMsgCnt, true, optsTransfer.optsChainPair ); - return true; // success, finish at this point + if( bnBlockId ) { + optsTransfer.strActionName = + "in-getOutgoingMessagesCounter()--findOutAllReferenceLogRecords()"; + optsTransfer.arrLogRecordReferences = + await findOutAllReferenceLogRecords( optsTransfer.details, + optsTransfer.strLogPrefixShort, optsTransfer.ethersProviderSrc, + optsTransfer.joMessageProxySrc, bnBlockId, optsTransfer.nIncMsgCnt, + optsTransfer.nOutMsgCnt, true, optsTransfer.optsChainPair ); + return true; // success, finish at this point + } } catch ( err ) { optsTransfer.arrLogRecordReferences = []; if( log.verboseGet() >= log.verboseReversed().error ) { @@ -405,16 +407,18 @@ async function gatherMessages( optsTransfer ) { for( let idxInBlock = 0; // inner loop wil create block of transactions optsTransfer.nIdxCurrentMsg < optsTransfer.nOutMsgCnt && idxInBlock < optsTransfer.nTransactionsCountInBlock; - ++optsTransfer.nIdxCurrentMsg, ++idxInBlock, ++optsTransfer.cntAccumulatedForBlock - ) { + ++optsTransfer.nIdxCurrentMsg, ++idxInBlock, ++optsTransfer.cntAccumulatedForBlock ) { const idxProcessing = optsTransfer.cntProcessed + idxInBlock; if( idxProcessing > optsTransfer.nMaxTransactionsCount ) break; let nBlockFrom = 0, nBlockTo = "latest"; if( optsTransfer.arrLogRecordReferences.length > 0 ) { const joReferenceLogRecord = optsTransfer.arrLogRecordReferences.shift(); - nBlockFrom = joReferenceLogRecord.currentBlockId; - nBlockTo = joReferenceLogRecord.currentBlockId; + if( joReferenceLogRecord && "currentBlockId" in joReferenceLogRecord && + joReferenceLogRecord.currentBlockId ) { + nBlockFrom = joReferenceLogRecord.currentBlockId; + nBlockTo = joReferenceLogRecord.currentBlockId; + } } optsTransfer.strActionName = "src-chain->MessageProxy->scan-past-events()"; const strEventName = "OutgoingMessage"; @@ -440,9 +444,8 @@ async function gatherMessages( optsTransfer ) { try { const transactionHash = r[0].transactionHash; if( log.verboseGet() >= log.verboseReversed().debug ) { - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.debug( "Event transactionHash is " ) + cc.info( transactionHash ) + - "\n" ); + optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Event " + + "transactionHash is " ) + cc.info( transactionHash ) + "\n" ); } const blockNumber = r[0].blockNumber; optsTransfer.details.write( optsTransfer.strLogPrefix + @@ -450,28 +453,27 @@ async function gatherMessages( optsTransfer ) { const nLatestBlockNumber = await imaHelperAPIs.safeGetBlockNumber( optsTransfer.details, 10, optsTransfer.ethersProviderSrc ); if( log.verboseGet() >= log.verboseReversed().debug ) { - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.debug( "Latest blockNumber is " ) + cc.info( nLatestBlockNumber ) + - "\n" ); + optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Latest " + + "blockNumber is " ) + cc.info( nLatestBlockNumber ) + "\n" ); } const nDist = nLatestBlockNumber - blockNumber; if( nDist < optsTransfer.nBlockAwaitDepth ) bSecurityCheckPassed = false; if( log.verboseGet() >= log.verboseReversed().debug ) { - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.debug( "Distance by blockNumber is " ) + cc.info( nDist ) + - cc.debug( ", await check is " ) + ( bSecurityCheckPassed - ? cc.success( "PASSED" ) : cc.error( "FAILED" ) ) + "\n" ); + const cp = bSecurityCheckPassed ? cc.success( "PASSED" ) : cc.error( "FAILED" ); + optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Distance " + + "by blockNumber is " ) + cc.info( nDist ) + cc.debug( ", await check " + + "is " ) + cp + "\n" ); } } catch ( err ) { bSecurityCheckPassed = false; if( log.verboseGet() >= log.verboseReversed().critical ) { const strError = owaspUtils.extractErrorMessage( err ); const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " Exception(evaluate block depth) while " + - "getting transaction hash and block number during " + - optsTransfer.strActionName + ": " ) + cc.error( strError ) + - cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + "\n"; + cc.error( " Exception(evaluate block depth) while getting transaction " + + "hash and block number during " + optsTransfer.strActionName + ": " ) + + cc.error( strError ) + cc.error( ", stack is: " ) + + "\n" + cc.stack( err.stack ) + "\n"; optsTransfer.details.write( s ); if( log.id != optsTransfer.details.id ) log.write( s ); @@ -502,9 +504,8 @@ async function gatherMessages( optsTransfer ) { try { const transactionHash = r[0].transactionHash; if( log.verboseGet() >= log.verboseReversed().debug ) { - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.debug( "Event transactionHash is " ) + cc.info( transactionHash ) + - "\n" ); + optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Event " + + "transactionHash is " ) + cc.info( transactionHash ) + "\n" ); } const blockNumber = r[0].blockNumber; if( log.verboseGet() >= log.verboseReversed().debug ) { @@ -561,27 +562,21 @@ async function gatherMessages( optsTransfer ) { optsTransfer.strActionName = "" + strActionNameOld; if( !bSecurityCheckPassed ) { if( log.verboseGet() >= log.verboseReversed().warning ) { - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.warning( "Block age check was not passed, " + - "canceling search for transfer events" ) + "\n" ); + optsTransfer.details.write( optsTransfer.strLogPrefix + cc.warning( "Block " + + "age check was not passed, canceling search for transfer events" ) + "\n" ); } break; } } if( log.verboseGet() >= log.verboseReversed().debug ) { optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.success( "Got event optsTransfer.details from " ) + - cc.notice( "getPastEvents()" ) + cc.success( " event invoked with " ) + - cc.notice( "msgCounter" ) + cc.success( " set to " ) + - cc.info( optsTransfer.nIdxCurrentMsg ) + cc.success( " and " ) + - cc.notice( "dstChain" ) + cc.success( " set to " ) + + cc.success( "Got event optsTransfer.details from getPastEvents() event invoked " + + "with msgCounter set to " ) + cc.info( optsTransfer.nIdxCurrentMsg ) + + cc.success( " and " ) + cc.notice( "dstChain" ) + cc.success( " set to " ) + cc.info( optsTransfer.chainNameDst ) + cc.success( ", event description: " ) + - cc.j( joValues ) + - // + cc.j(evs) + - "\n" ); - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.debug( "Will process message counter value " ) + - cc.info( optsTransfer.nIdxCurrentMsg ) + "\n" ); + cc.j( joValues ) + "\n" ); + optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Will process " + + "message counter value " ) + cc.info( optsTransfer.nIdxCurrentMsg ) + "\n" ); } optsTransfer.arrMessageCounters.push( optsTransfer.nIdxCurrentMsg ); const joMessage = { @@ -590,8 +585,7 @@ async function gatherMessages( optsTransfer ) { "to": joValues.to, "amount": joValues.amount, "data": joValues.data, - "savedBlockNumberForOptimizations": - joValues.savedBlockNumberForOptimizations + "savedBlockNumberForOptimizations": joValues.savedBlockNumberForOptimizations }; optsTransfer.jarrMessages.push( joMessage ); } From dbd9c57b273889aa07f322c5614352abf4889ef5 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 9 Nov 2023 12:14:42 +0000 Subject: [PATCH 15/29] ticket-883 Fixed problem related to empty SNB cache rewriting data --- agent/loop.mjs | 81 ++++++++++++++++++-------------- agent/loopWorker.mjs | 36 ++++++++++---- agent/threadInfo.mjs | 5 ++ npms/skale-observer/observer.mjs | 61 +++++++++++++++--------- 4 files changed, 118 insertions(+), 65 deletions(-) diff --git a/agent/loop.mjs b/agent/loop.mjs index ab90ece44..564079c8e 100644 --- a/agent/loop.mjs +++ b/agent/loop.mjs @@ -510,17 +510,21 @@ const gArrClients = []; export function notifyCacheChangedSNB( arrSChainsCached ) { const cntWorkers = gArrWorkers.length; if( cntWorkers == 0 ) { - if( log.verboseGet() >= log.verboseReversed().debug ) { - log.write( cc.warning( "Will skip chainsCacheChanged dispatch event with " ) + - cc.warning( "no chains arrived in " ) + threadInfo.threadDescription() + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().debug ) { + log.write( cc.warning( "Will skip chainsCacheChanged dispatch event with " ) + + cc.warning( "no chains arrived in " ) + threadInfo.threadDescription() + "\n" ); + } } return; } - if( log.verboseGet() >= log.verboseReversed().debug ) { - log.write( - cc.debug( "Loop module will broadcast arrSChainsCached event to its " ) + - cc.info( cntWorkers ) + cc.debug( " worker(s) in " ) + - threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().debug ) { + log.write( + cc.debug( "Loop module will broadcast arrSChainsCached event to its " ) + + cc.info( cntWorkers ) + cc.debug( " worker(s) in " ) + + threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); + } } for( let idxWorker = 0; idxWorker < cntWorkers; ++ idxWorker ) { const jo = { @@ -529,34 +533,44 @@ export function notifyCacheChangedSNB( arrSChainsCached ) { "arrSChainsCached": arrSChainsCached } }; - if( log.verboseGet() >= log.verboseReversed().debug ) { - log.write( cc.debug( "S-Chains cache will be sent to " ) + - cc.notice( gArrClients[idxWorker].url ) + cc.debug( " loop worker..." ) + - "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().debug ) { + log.write( cc.debug( "S-Chains cache will be sent to " ) + + cc.notice( gArrClients[idxWorker].url ) + cc.debug( " loop worker..." ) + + "\n" ); + } } gArrClients[idxWorker].send( jo ); - if( log.verboseGet() >= log.verboseReversed().debug ) { - log.write( cc.debug( "S-Chains cache did sent to " ) + - cc.notice( gArrClients[idxWorker].url ) + cc.debug( " loop worker" ) + - "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().debug ) { + log.write( cc.debug( "S-Chains cache did sent to " ) + + cc.notice( gArrClients[idxWorker].url ) + cc.debug( " loop worker" ) + + "\n" ); + } } } - if( log.verboseGet() >= log.verboseReversed().debug ) { - log.write( - cc.debug( "Loop module did finished broadcasting arrSChainsCached event to its " ) + - cc.info( cntWorkers ) + cc.debug( " worker(s) in " ) + - threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().debug ) { + log.write( + cc.debug( "Loop module did finished broadcasting arrSChainsCached event to its " ) + + cc.info( cntWorkers ) + cc.debug( " worker(s) in " ) + + threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); + } } } if( log.verboseGet() >= log.verboseReversed().trace ) { - log.write( cc.debug( "Subscribe to chainsCacheChanged event in " ) + - threadInfo.threadDescription() + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + log.write( cc.debug( "Subscribe to chainsCacheChanged event in " ) + + threadInfo.threadDescription() + "\n" ); + } } skaleObserver.events.on( "chainsCacheChanged", function( eventData ) { - if( log.verboseGet() >= log.verboseReversed().trace ) { - log.write( cc.debug( "Did arrived chainsCacheChanged event in " ) + - threadInfo.threadDescription() + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().trace ) { + log.write( cc.debug( "Did arrived chainsCacheChanged event in " ) + + threadInfo.threadDescription() + "\n" ); + } } notifyCacheChangedSNB( eventData.detail.arrSChainsCached ); } ); @@ -755,14 +769,12 @@ export async function ensureHaveWorkers( opts ) { "nMaxTransactionsM2S": opts.imaState.nMaxTransactionsM2S, "nMaxTransactionsS2M": opts.imaState.nMaxTransactionsS2M, "nMaxTransactionsS2S": opts.imaState.nMaxTransactionsS2S, - "nBlockAwaitDepthM2S": opts.imaState.nBlockAwaitDepthM2S, "nBlockAwaitDepthS2M": opts.imaState.nBlockAwaitDepthS2M, "nBlockAwaitDepthS2S": opts.imaState.nBlockAwaitDepthS2S, "nBlockAgeM2S": opts.imaState.nBlockAgeM2S, "nBlockAgeS2M": opts.imaState.nBlockAgeS2M, "nBlockAgeS2S": opts.imaState.nBlockAgeS2S, - "nLoopPeriodSeconds": opts.imaState.nLoopPeriodSeconds, "nNodeNumber": opts.imaState.nNodeNumber, "nNodesCount": opts.imaState.nNodesCount, @@ -834,7 +846,7 @@ export async function ensureHaveWorkers( opts ) { }; while( ! aClient.logicalInitComplete ) { if( log.verboseGet() >= log.verboseReversed().info ) - log.write( "LOOP server is not inited yet...\n" ); + log.write( "LOOP server is not initialized yet...\n" ); await threadInfo.sleep( 1000 ); aClient.send( jo ); } @@ -844,12 +856,14 @@ export async function ensureHaveWorkers( opts ) { cc.info( gArrWorkers.length ) + cc.debug( " worker(s) in " ) + threadInfo.threadDescription() + cc.debug( "" ) + "\n" ); } - if( log.verboseGet() >= log.verboseReversed().trace ) { + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded && + log.verboseGet() >= log.verboseReversed().trace ) { log.write( cc.debug( "Subscribe to inThread-arrSChainsCached event in " ) + threadInfo.threadDescription() + "\n" ); } skaleObserver.events.on( "inThread-arrSChainsCached", function( eventData ) { - if( log.verboseGet() >= log.verboseReversed().trace ) { + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded && + log.verboseGet() >= log.verboseReversed().trace ) { log.write( cc.debug( "Did arrived inThread-arrSChainsCached event in " ) + threadInfo.threadDescription() + "\n" ); } @@ -859,9 +873,8 @@ export async function ensureHaveWorkers( opts ) { // Force broadcast what we have in SNB right now because works above can start later than SNB // is finished download connected chains quickly if( log.verboseGet() >= log.verboseReversed().debug ) { - log.write( - cc.debug( "Loop module will do first initial broadcast of arrSChainsCached to its " ) + - cc.info( cntWorkers ) + cc.debug( " worker(s) in " ) + + log.write( cc.debug( "Loop module will do first initial broadcast of arrSChainsCached " + + "to its " ) + cc.info( cntWorkers ) + cc.debug( " worker(s) in " ) + threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); } notifyCacheChangedSNB( skaleObserver.getLastCachedSChains() ); diff --git a/agent/loopWorker.mjs b/agent/loopWorker.mjs index 09111c278..242857437 100644 --- a/agent/loopWorker.mjs +++ b/agent/loopWorker.mjs @@ -108,9 +108,17 @@ class ObserverServer extends SocketServer { const isFlush = true; socket.send( jo, isFlush ); } ); - if( log.verboseGet() >= log.verboseReversed().debug ) { - log.write( - cc.debug( "Loop worker " ) + cc.notice( workerData.url ) + + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().debug ) { + log.write( + cc.debug( "Loop worker " ) + cc.notice( workerData.url ) + + cc.debug( " will save cached S-Chains..." ) + "\n" ); + } + } + if( ! self.opts.imaState.optsLoop.enableStepS2S ) + threadInfo.joCustomThreadProperties.isSChainsCacheNeeded = false; + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + log.write( cc.debug( "Loop worker " ) + cc.notice( workerData.url ) + cc.debug( " will save cached S-Chains..." ) + "\n" ); } skaleObserver.setLastCachedSChains( self.opts.imaState.arrSChainsCached ); @@ -200,11 +208,23 @@ class ObserverServer extends SocketServer { imaState.joSChainNetworkInfo = joMessage.joSChainNetworkInfo; }; self.mapApiHandlers.schainsCached = function( joMessage, joAnswer, eventData, socket ) { - if( log.verboseGet() >= log.verboseReversed().debug ) { - self.log( cc.debug( "S-Chains cache did arrived to " ) + - cc.notice( workerData.url ) + cc.debug( " loop worker in " ) + - threadInfo.threadDescription() + cc.debug( ": " ) + - cc.j( joMessage.message.arrSChainsCached ) + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().debug ) { + self.log( cc.debug( "S-Chains cache did arrived to " ) + + cc.notice( workerData.url ) + cc.debug( " loop worker in " ) + + threadInfo.threadDescription() + cc.debug( ": " ) + + cc.j( joMessage.message.arrSChainsCached ) + "\n" ); + } + } + if( ( !joMessage.message.arrSChainsCached ) || + joMessage.message.arrSChainsCached.length == 0 + ) { + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + self.log( cc.debug( "Empty S-Chains cache arrived to " ) + + cc.notice( workerData.url ) + cc.debug( " will not be renewed in " ) + + threadInfo.threadDescription() + "\n" ); + } + return; } skaleObserver.setLastCachedSChains( joMessage.message.arrSChainsCached ); }; diff --git a/agent/threadInfo.mjs b/agent/threadInfo.mjs index 1e9c6767d..dc7f03451 100644 --- a/agent/threadInfo.mjs +++ b/agent/threadInfo.mjs @@ -29,6 +29,11 @@ import * as cc from "../npms/skale-cc/cc.mjs"; const Worker = worker_threads.Worker; export { Worker }; +const joCustomThreadProperties = { + "isSChainsCacheNeeded": true // by default is set to true +}; +export { joCustomThreadProperties }; + export const sleep = ( milliseconds ) => { return new Promise( resolve => setTimeout( resolve, milliseconds ) ); }; diff --git a/npms/skale-observer/observer.mjs b/npms/skale-observer/observer.mjs index 47364448e..c82bd3a09 100644 --- a/npms/skale-observer/observer.mjs +++ b/npms/skale-observer/observer.mjs @@ -1084,10 +1084,12 @@ export async function cacheSChains( strChainNameConnectedTo, opts ) { } } if( opts && opts.details ) { - if( log.verboseGet() >= log.verboseReversed().trace ) { - opts.details.write( - cc.debug( "Will dispatch inThread-arrSChainsCached event in " ) + - threadInfo.threadDescription() + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().trace ) { + opts.details.write( + cc.debug( "Will dispatch inThread-arrSChainsCached event in " ) + + threadInfo.threadDescription() + "\n" ); + } } } events.dispatchEvent( @@ -1095,10 +1097,12 @@ export async function cacheSChains( strChainNameConnectedTo, opts ) { "inThread-arrSChainsCached", { "detail": { "arrSChainsCached": arrSChains } } ) ); if( opts && opts.details ) { - if( log.verboseGet() >= log.verboseReversed().trace ) { - opts.details.write( - cc.debug( "Did dispatched inThread-arrSChainsCached event in " ) + - threadInfo.threadDescription() + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().trace ) { + opts.details.write( + cc.debug( "Did dispatched inThread-arrSChainsCached event in " ) + + threadInfo.threadDescription() + "\n" ); + } } } if( opts.fnCacheChanged ) @@ -1127,12 +1131,19 @@ export function getLastCachedSChains() { } export function setLastCachedSChains( arrSChainsCached ) { - if( log.verboseGet() >= log.verboseReversed().debug ) { - log.write( cc.debug( "Will set arrSChainsCached in " ) + - threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); - log.write( cc.debug( "Value of arrSChainsCached in " ) + - threadInfo.threadDescription() + cc.debug( " is: " ) + - cc.j( arrSChainsCached ) + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().debug ) { + log.write( cc.debug( "Value of arrSChainsCached in " ) + + threadInfo.threadDescription() + cc.debug( " is: " ) + + cc.j( arrSChainsCached ) + "\n" ); + } + } + if( ( !arrSChainsCached ) || arrSChainsCached.length == 0 ) { + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + log.write( cc.debug( "Empty S-Chains cache arrived to SkaleObserver " ) + + "will not be renewed in " + threadInfo.threadDescription() + "\n" ); + } + return; } if( arrSChainsCached && typeof arrSChainsCached == "object" ) { gArrSChainsCached = JSON.parse( JSON.stringify( arrSChainsCached ) ); @@ -1143,20 +1154,24 @@ export function setLastCachedSChains( arrSChainsCached ) { const nMaxSize = getLastCachedHistoryMaxSize(); while( gArrCacheHistory.length > nMaxSize ) gArrCacheHistory.shift(); - if( log.verboseGet() >= log.verboseReversed().debug ) { - log.write( cc.debug( "Will dispatch arrSChainsCached event in " ) + - threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().debug ) { + log.write( cc.debug( "Will dispatch arrSChainsCached event in " ) + + threadInfo.threadDescription() + cc.debug( "..." ) + "\n" ); + } } events.dispatchEvent( new UniversalDispatcherEvent( "chainsCacheChanged", { "detail": { "arrSChainsCached": getLastCachedSChains() } } ) ); } else { - if( log.verboseGet() >= log.verboseReversed().error ) { - log.write( cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " Cannot dispatch arrSChainsCached event with bad object " ) + - cc.j( arrSChainsCached ) + cc.error( " in " ) + - threadInfo.threadDescription() + "\n" ); + if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { + if( log.verboseGet() >= log.verboseReversed().error ) { + log.write( cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " Cannot dispatch arrSChainsCached event with bad object " ) + + cc.j( arrSChainsCached ) + cc.error( " in " ) + + threadInfo.threadDescription() + "\n" ); + } } } } @@ -1333,7 +1348,7 @@ export async function ensureHaveWorker( opts ) { }; while( ! gClient.logicalInitComplete ) { if( log.verboseGet() >= log.verboseReversed().info ) - log.write( "SNB server is not inited yet...\n" ); + log.write( "SNB server is not initialized yet...\n" ); await threadInfo.sleep( 1000 ); gClient.send( jo ); From 57006a62f76d3497e13532de658e3f1ff2619adc Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 9 Nov 2023 20:07:11 +0000 Subject: [PATCH 16/29] ticket-883 Fixed problem related to empty SNB cache rewriting data --- agent/loopWorker.mjs | 10 -- npms/skale-observer/observer.mjs | 151 +++++++++---------------- npms/skale-observer/observerWorker.mjs | 6 +- 3 files changed, 55 insertions(+), 112 deletions(-) diff --git a/agent/loopWorker.mjs b/agent/loopWorker.mjs index 242857437..f9664ad07 100644 --- a/agent/loopWorker.mjs +++ b/agent/loopWorker.mjs @@ -216,16 +216,6 @@ class ObserverServer extends SocketServer { cc.j( joMessage.message.arrSChainsCached ) + "\n" ); } } - if( ( !joMessage.message.arrSChainsCached ) || - joMessage.message.arrSChainsCached.length == 0 - ) { - if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { - self.log( cc.debug( "Empty S-Chains cache arrived to " ) + - cc.notice( workerData.url ) + cc.debug( " will not be renewed in " ) + - threadInfo.threadDescription() + "\n" ); - } - return; - } skaleObserver.setLastCachedSChains( joMessage.message.arrSChainsCached ); }; // eslint-disable-next-line dot-notation diff --git a/npms/skale-observer/observer.mjs b/npms/skale-observer/observer.mjs index c82bd3a09..7ce7f8abe 100644 --- a/npms/skale-observer/observer.mjs +++ b/npms/skale-observer/observer.mjs @@ -779,12 +779,10 @@ async function checkWhetherSChainIsConnected( strSChainName, joMessageProxySChai ? opts.cntAttemptsCheckConnectedState : 3; for( let idxAttempt = 0; idxAttempt < cntAttempts; ++ idxAttempt ) { try { - isConnected = - await joMessageProxySChain.callStatic.isConnectedChain( strSChainName ); + isConnected = await joMessageProxySChain.callStatic.isConnectedChain( strSChainName ); isQueryPassed = true; break; } catch ( err ) { - isConnected = false; if( opts && opts.details ) { if( log.verboseGet() >= log.verboseReversed().error ) { opts.details.write( cc.error( "Failed attempt " ) + @@ -798,17 +796,14 @@ async function checkWhetherSChainIsConnected( strSChainName, joMessageProxySChai } } } - if( opts && opts.details ) { - if( ! isQueryPassed ) { - if( log.verboseGet() >= log.verboseReversed().warning ) { - opts.details.write( cc.debug( "Will assume S-Chain " ) + - cc.info( strSChainName ) + cc.debug( " connected status: " ) + - cc.yn( isConnected ) + "\n" ); - } - } else if( log.verboseGet() >= log.verboseReversed().trace ) { - opts.details.write( cc.debug( "Got S-Chain " ) + cc.info( strSChainName ) + - cc.debug( " connected status: " ) + cc.yn( isConnected ) + "\n" ); + if( ! isQueryPassed ) { + if( opts && opts.details ) { + opts.details.write( cc.error( "Failed all " ) + cc.info( cntAttempts ) + + cc.error( " attempt(s) to query connected state of " ) + cc.info( strSChainName ) + + cc.error( " S-Chain" ) + "\n" ); } + throw new Error( "Failed all " + cntAttempts + " attempt(s) to query connected state of " + + strSChainName + " S-Chain" ); } return isConnected; } @@ -843,50 +838,40 @@ export async function loadSChainsConnectedOnly( strChainNameConnectedTo, opts ) ); const arrSChains = [], arrSChainNames = await getAllSchainNames( arrSChainHashes, opts ); for( let idxSChain = 0; idxSChain < cntSChains; ++ idxSChain ) { - try { - if( opts && opts.bStopNeeded ) - break; - const strSChainHash = arrSChainHashes[idxSChain]; - const strSChainName = arrSChainNames[idxSChain]; - if( strChainNameConnectedTo == strSChainName ) { - if( opts && opts.details ) { - if( log.verboseGet() >= log.verboseReversed().trace ) { - opts.details.write( cc.debug( "Skip this S-Chain " ) + - cc.info( strSChainName ) + cc.debug( " connected status check" ) + - "\n" ); - } - } - continue; - } + if( opts && opts.bStopNeeded ) + break; + const strSChainHash = arrSChainHashes[idxSChain]; + const strSChainName = arrSChainNames[idxSChain]; + if( strChainNameConnectedTo == strSChainName ) { if( opts && opts.details ) { if( log.verboseGet() >= log.verboseReversed().trace ) { - opts.details.write( - cc.debug( "Querying(1) connected status between S-Chain " ) + - cc.info( strSChainName ) + cc.debug( " and S-Chain " ) + - cc.info( strChainNameConnectedTo ) + cc.debug( "..." ) + "\n" ); + opts.details.write( cc.debug( "Skip this S-Chain " ) + + cc.info( strSChainName ) + cc.debug( " connected status check" ) + + "\n" ); } } - let isConnected = false; - if( isLoadConnectedOnly ) { - isConnected = await checkWhetherSChainIsConnected( - strSChainName, joMessageProxySChain, opts ); - if( ! isConnected ) - continue; + continue; + } + if( opts && opts.details ) { + if( log.verboseGet() >= log.verboseReversed().trace ) { + opts.details.write( + cc.debug( "Querying(1) connected status between S-Chain " ) + + cc.info( strSChainName ) + cc.debug( " and S-Chain " ) + + cc.info( strChainNameConnectedTo ) + cc.debug( "..." ) + "\n" ); } - const joSChain = await loadSChain( idxSChain, strSChainHash, null, cntSChains, opts ); - if( ! joSChain ) + } + let isConnected = false; + if( isLoadConnectedOnly ) { + isConnected = await checkWhetherSChainIsConnected( + strSChainName, joMessageProxySChain, opts ); + if( ! isConnected ) continue; - joSChain.isConnected = isConnected; - arrSChains.push( joSChain ); - } catch ( err ) { - if( opts && opts.details ) { - if( log.verboseGet() >= log.verboseReversed().error ) { - opts.details.write( cc.error( "Got error: " ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + - cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + "\n" ); - } - } } + const joSChain = await loadSChain( idxSChain, strSChainHash, null, cntSChains, opts ); + if( ! joSChain ) + continue; + joSChain.isConnected = isConnected; + arrSChains.push( joSChain ); } return arrSChains; } @@ -905,34 +890,22 @@ export async function checkConnectedSChains( strChainNameConnectedTo, arrSChains joSChain.isConnected = false; if( joSChain.data.name == strChainNameConnectedTo ) continue; - try { - const url = pickRandomSChainUrl( joSChain ); - if( opts && opts.details ) { - if( log.verboseGet() >= log.verboseReversed().trace ) { - opts.details.write( cc.debug( "Querying(2) via URL " ) + cc.u( url ) + - cc.debug( " to S-Chain " ) + cc.info( joSChain.data.name ) + - cc.debug( " whether it's connected to S-Chain " ) + - cc.info( strChainNameConnectedTo ) + cc.debug( "..." ) + "\n" ); - } - } - const ethersProvider = owaspUtils.getEthersProviderFromURL( url ); - 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, - ethersProvider - ); - joSChain.isConnected = await checkWhetherSChainIsConnected( - strChainNameConnectedTo, joMessageProxySChain, opts ); - } catch ( err ) { - if( opts && opts.details ) { - if( log.verboseGet() >= log.verboseReversed().error ) { - opts.details.write( cc.error( "Got error: " ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + - cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + "\n" ); - } + const url = pickRandomSChainUrl( joSChain ); + if( opts && opts.details ) { + if( log.verboseGet() >= log.verboseReversed().trace ) { + opts.details.write( cc.debug( "Querying(2) via URL " ) + cc.u( url ) + + cc.debug( " to S-Chain " ) + cc.info( joSChain.data.name ) + + cc.debug( " whether it's connected to S-Chain " ) + + cc.info( strChainNameConnectedTo ) + cc.debug( "..." ) + "\n" ); } } + const ethersProvider = owaspUtils.getEthersProviderFromURL( url ); + 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, + ethersProvider ); + joSChain.isConnected = await checkWhetherSChainIsConnected( + strChainNameConnectedTo, joMessageProxySChain, opts ); } return arrSChains; } @@ -1065,15 +1038,8 @@ export async function cacheSChains( strChainNameConnectedTo, opts ) { ( typeof strChainNameConnectedTo == "string" ) && strChainNameConnectedTo.length > 0 ) { - await checkConnectedSChains( - strChainNameConnectedTo, - arrSChains, - opts - ); - gArrSChainsCached = await filterSChainsMarkedAsConnected( - arrSChains, - opts - ); + await checkConnectedSChains( strChainNameConnectedTo, arrSChains, opts ); + gArrSChainsCached = await filterSChainsMarkedAsConnected( arrSChains, opts ); } else gArrSChainsCached = arrSChains; if( opts && opts.details ) { @@ -1092,10 +1058,8 @@ export async function cacheSChains( strChainNameConnectedTo, opts ) { } } } - events.dispatchEvent( - new UniversalDispatcherEvent( - "inThread-arrSChainsCached", - { "detail": { "arrSChainsCached": arrSChains } } ) ); + events.dispatchEvent( new UniversalDispatcherEvent( + "inThread-arrSChainsCached", { "detail": { "arrSChainsCached": arrSChains } } ) ); if( opts && opts.details ) { if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { if( log.verboseGet() >= log.verboseReversed().trace ) { @@ -1133,18 +1097,11 @@ export function getLastCachedSChains() { export function setLastCachedSChains( arrSChainsCached ) { if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { if( log.verboseGet() >= log.verboseReversed().debug ) { - log.write( cc.debug( "Value of arrSChainsCached in " ) + + log.write( cc.debug( "Will save value of arrSChainsCached in " ) + threadInfo.threadDescription() + cc.debug( " is: " ) + cc.j( arrSChainsCached ) + "\n" ); } } - if( ( !arrSChainsCached ) || arrSChainsCached.length == 0 ) { - if( threadInfo.joCustomThreadProperties.isSChainsCacheNeeded ) { - log.write( cc.debug( "Empty S-Chains cache arrived to SkaleObserver " ) + - "will not be renewed in " + threadInfo.threadDescription() + "\n" ); - } - return; - } if( arrSChainsCached && typeof arrSChainsCached == "object" ) { gArrSChainsCached = JSON.parse( JSON.stringify( arrSChainsCached ) ); gArrCacheHistory.push( { diff --git a/npms/skale-observer/observerWorker.mjs b/npms/skale-observer/observerWorker.mjs index 01ea4fd90..49c62da43 100644 --- a/npms/skale-observer/observerWorker.mjs +++ b/npms/skale-observer/observerWorker.mjs @@ -232,11 +232,7 @@ class ObserverServer extends SocketServer { cc.debug( " thread will invoke S-Chains caching(attempt + " ) + cc.info( idxAttempt ) + cc.debug( ")..." ) + "\n" ); } - strError = - await skaleObserver.cacheSChains( - strChainNameConnectedTo, - self.opts - ); + strError = await skaleObserver.cacheSChains( strChainNameConnectedTo, self.opts ); if( ! strError ) break; } catch ( err ) { From 1128a15bd0f6fd153fdfdbdafabdd07297190069 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Fri, 10 Nov 2023 15:15:31 +0000 Subject: [PATCH 17/29] ticket-884 Async walk through S-Chain nodes to check OutgoingMessage event on each of 16 --- npms/skale-ima/index.mjs | 375 ++++++++++++++++++++++----------------- 1 file changed, 209 insertions(+), 166 deletions(-) diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index 2b3ccd659..fa4567224 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -882,6 +882,48 @@ async function handleAllMessagesSigning( optsTransfer ) { } } +async function checkOutgoingMessageEventResult( + optsTransfer, joSChain, idxMessage, cntPassedNodes, cntFailedNodes +) { + if( cntFailedNodes > optsTransfer.cntNodesMayFail ) { + if( log.verboseGet() >= log.verboseReversed().critical ) { + const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " Error validating " ) + cc.sunny( optsTransfer.strDirection ) + + cc.error( " messages, failed node count " ) + cc.info( cntFailedNodes ) + + cc.error( " is greater then allowed to fail " ) + + cc.info( optsTransfer.cntNodesMayFail ) + "\n"; + optsTransfer.details.write( s ); + if( log.id != optsTransfer.details.id ) + log.write( s ); + } + optsTransfer.details.exposeDetailsTo( + log, optsTransfer.strGatheredDetailsName, false ); + imaTransferErrorHandling.saveTransferError( + optsTransfer.strTransferErrorCategoryName, + optsTransfer.details.toString() ); + optsTransfer.details.close(); + return false; + } + if( ! ( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) ) { + if( log.verboseGet() >= log.verboseReversed().critical ) { + const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " Error validating " ) + cc.sunny( optsTransfer.strDirection ) + + cc.error( " messages, passed node count " ) + cc.info( cntPassedNodes ) + + cc.error( " is less then needed count " ) + + cc.info( optsTransfer.cntNodesShouldPass ) + "\n"; + optsTransfer.details.write( s ); + if( log.id != optsTransfer.details.id ) + log.write( s ); + } + optsTransfer.details.exposeDetailsTo( + log, optsTransfer.strGatheredDetailsName, false ); + imaTransferErrorHandling.saveTransferError( + optsTransfer.strTransferErrorCategoryName, optsTransfer.details.toString() ); + optsTransfer.details.close(); + return false; + } +} + async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { const cntNodes = joSChain.data.computed.nodes.length; const cntMessages = optsTransfer.jarrMessages.length; @@ -897,185 +939,186 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { cc.debug( " and message envelope data:" ) + cc.j( joMessage ) + "\n" ); } let cntPassedNodes = 0, cntFailedNodes = 0, joNode = null; - try { - for( let idxNode = 0; idxNode < cntNodes; ++ idxNode ) { - joNode = joSChain.data.computed.nodes[idxNode]; - // eslint-disable-next-line dot-notation - const strUrlHttp = joNode["http_endpoint_ip"]; - if( log.verboseGet() >= log.verboseReversed().trace ) { - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.debug( "Validating " ) + cc.sunny( optsTransfer.strDirection ) + - cc.debug( " message " ) + cc.info( idxMessage + 1 ) + - cc.debug( " on node " ) + cc.info( joNode.name ) + - cc.debug( " using URL " ) + cc.info( strUrlHttp ) + cc.debug( "..." ) + - "\n" ); + const promiseComplete = new Promise( function( resolve, reject ) { + const iv = setInterval( function() { + if( cntFailedNodes > optsTransfer.cntNodesMayFail ) { + clearInterval( iv ); + reject( new Error( "Error validating " + optsTransfer.strDirection + + " messages, failed node count " + cntFailedNodes + + " is greater then allowed to fail " + optsTransfer.cntNodesMayFail ) ); + return; } - let bEventIsFound = false; - try { + if( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) { + resolve( true ); + return; + } + }, 500 ); + try { + for( let idxNode = 0; idxNode < cntNodes; ++ idxNode ) { + joNode = joSChain.data.computed.nodes[idxNode]; // eslint-disable-next-line dot-notation - const ethersProviderNode = owaspUtils.getEthersProviderFromURL( strUrlHttp ); - const joMessageProxyNode = new owaspUtils.ethersMod.ethers.Contract( - optsTransfer.imaState.chainProperties.sc - .joAbiIMA.message_proxy_chain_address, - optsTransfer.imaState.chainProperties - .sc.joAbiIMA.message_proxy_chain_abi, - ethersProviderNode ); - const strEventName = "OutgoingMessage"; - const node_r = await imaEventLogScan.safeGetPastEventsProgressive( - optsTransfer.details, optsTransfer.strLogPrefixShort, ethersProviderNode, - 10, joMessageProxyNode, strEventName, - joMessage.savedBlockNumberForOptimizations, - joMessage.savedBlockNumberForOptimizations, - joMessageProxyNode.filters[strEventName]( - owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), - owaspUtils.toBN( idxImaMessage ) - ), - optsTransfer.optsChainPair - ); - const cntEvents = node_r.length; + const strUrlHttp = joNode["http_endpoint_ip"]; if( log.verboseGet() >= log.verboseReversed().trace ) { - optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Got " ) + - cc.info( cntEvents ) + cc.debug( " event(s) (" ) + - cc.info( strEventName ) + cc.debug( ") on node " ) + - cc.info( joNode.name ) + cc.debug( " with data: " ) + - cc.j( node_r ) + "\n" ); - } - for( let idxEvent = 0; idxEvent < cntEvents; ++ idxEvent ) { - const joEvent = node_r[idxEvent]; - const eventValuesByName = { - "dstChainHash": joEvent.args[0], - "msgCounter": joEvent.args[1], - "srcContract": joEvent.args[2], - "dstContract": joEvent.args[3], - "data": joEvent.args[4] - }; - if( owaspUtils.ensureStartsWith0x( - joMessage.sender ).toLowerCase() == - owaspUtils.ensureStartsWith0x( - eventValuesByName.srcContract ).toLowerCase() && - owaspUtils.ensureStartsWith0x( - joMessage.destinationContract ).toLowerCase() == - owaspUtils.ensureStartsWith0x( - eventValuesByName.dstContract ).toLowerCase() - ) { - bEventIsFound = true; - break; - } - } - } catch ( err ) { - ++ cntFailedNodes; - if( log.verboseGet() >= log.verboseReversed().error ) { - const strError = optsTransfer.strLogPrefix + - cc.fatal( optsTransfer.strDirection + - " message analysis error:" ) + " " + - cc.error( "Failed to scan events on node " ) + cc.info( joNode.name ) + - cc.error( ", error is: " ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + - cc.error( ", detailed node description is: " ) + cc.j( joNode ) + - cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + "\n"; - optsTransfer.details.write( strError ); - if( log.id != optsTransfer.details.id ) - log.write( strError ); - } - continue; - } - if( bEventIsFound ) { - ++ cntPassedNodes; - if( log.verboseGet() >= log.verboseReversed().information ) { optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.sunny( optsTransfer.strDirection ) + cc.success( " message " ) + - cc.info( idxMessage + 1 ) + cc.success( " validation on node " ) + - cc.info( joNode.name ) + cc.success( " using URL " ) + - cc.info( strUrlHttp ) + cc.success( " is passed" ) + "\n" ); + cc.debug( "Validating " ) + cc.sunny( optsTransfer.strDirection ) + + cc.debug( " message " ) + cc.info( idxMessage + 1 ) + + cc.debug( " on node " ) + cc.info( joNode.name ) + + cc.debug( " using URL " ) + cc.info( strUrlHttp ) + cc.debug( "..." ) + + "\n" ); } - } else { - ++ cntFailedNodes; - if( log.verboseGet() >= log.verboseReversed().error ) { + try { + const sc = optsTransfer.imaState.chainProperties.sc; // eslint-disable-next-line dot-notation - const strError = optsTransfer.strLogPrefix + - cc.sunny( optsTransfer.strDirection ) + cc.error( " message " ) + - cc.info( idxMessage + 1 ) + cc.error( " validation on node " ) + - cc.info( joNode.name ) + cc.success( " using URL " ) + - cc.info( strUrlHttp ) + cc.error( " is failed" ) + "\n"; - optsTransfer.details.write( strError ); - if( log.id != optsTransfer.details.id ) - log.write( strError ); + const ethersProviderNode = + owaspUtils.getEthersProviderFromURL( strUrlHttp ); + const joMessageProxyNode = new owaspUtils.ethersMod.ethers.Contract( + sc.joAbiIMA.message_proxy_chain_address, + sc.joAbiIMA.message_proxy_chain_abi, ethersProviderNode ); + const strEventName = "OutgoingMessage"; + imaEventLogScan.safeGetPastEventsProgressive( + optsTransfer.details, optsTransfer.strLogPrefixShort, + ethersProviderNode, 10, joMessageProxyNode, strEventName, + joMessage.savedBlockNumberForOptimizations, + joMessage.savedBlockNumberForOptimizations, + joMessageProxyNode.filters[strEventName]( + owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), + owaspUtils.toBN( idxImaMessage ) + ), + optsTransfer.optsChainPair + ).then( node_r => { + const cntEvents = node_r.length; + if( log.verboseGet() >= log.verboseReversed().trace ) { + optsTransfer.details.write( optsTransfer.strLogPrefix + + cc.debug( "Got " ) + cc.info( cntEvents ) + + cc.debug( " event(s) (" ) + cc.info( strEventName ) + + cc.debug( ") on node " ) + cc.info( joNode.name ) + + cc.debug( " with data: " ) + cc.j( node_r ) + "\n" ); + } + let bEventIsFound = false; + for( let idxEvent = 0; idxEvent < cntEvents; ++ idxEvent ) { + const joEvent = node_r[idxEvent]; + const eventValuesByName = { + "dstChainHash": joEvent.args[0], + "msgCounter": joEvent.args[1], + "srcContract": joEvent.args[2], + "dstContract": joEvent.args[3], + "data": joEvent.args[4] + }; + if( owaspUtils.ensureStartsWith0x( + joMessage.sender ).toLowerCase() == + owaspUtils.ensureStartsWith0x( + eventValuesByName.srcContract ).toLowerCase() && + owaspUtils.ensureStartsWith0x( + joMessage.destinationContract ).toLowerCase() == + owaspUtils.ensureStartsWith0x( + eventValuesByName.dstContract ).toLowerCase() + ) { + bEventIsFound = true; + break; + } + } + if( bEventIsFound ) { + ++ cntPassedNodes; + if( log.verboseGet() >= log.verboseReversed().information ) { + optsTransfer.details.write( optsTransfer.strLogPrefix + + cc.sunny( optsTransfer.strDirection ) + + cc.success( " message " ) + cc.info( idxMessage + 1 ) + + cc.success( " validation on node " ) + + cc.info( joNode.name ) + cc.success( " using URL " ) + + cc.info( strUrlHttp ) + cc.success( " is passed" ) + "\n" ); + } + } else { + ++ cntFailedNodes; + if( log.verboseGet() >= log.verboseReversed().error ) { + // eslint-disable-next-line dot-notation + const strError = optsTransfer.strLogPrefix + + cc.sunny( optsTransfer.strDirection ) + + cc.error( " message " ) + cc.info( idxMessage + 1 ) + + cc.error( " validation on node " ) + + cc.info( joNode.name ) + cc.success( " using URL " ) + + cc.info( strUrlHttp ) + cc.error( " is failed" ) + "\n"; + optsTransfer.details.write( strError ); + if( log.id != optsTransfer.details.id ) + log.write( strError ); + } + } + } ).catch( err => { + ++ cntFailedNodes; + if( log.verboseGet() >= log.verboseReversed().error ) { + const strError = optsTransfer.strLogPrefix + + cc.fatal( optsTransfer.strDirection + + " message analysis error:" ) + " " + + cc.error( "Failed to scan events on node " ) + + cc.info( joNode.name ) + cc.error( ", error is: " ) + + cc.warning( owaspUtils.extractErrorMessage( err ) ) + + cc.error( ", detailed node description is: " ) + + cc.j( joNode ) + cc.error( ", stack is: " ) + "\n" + + cc.stack( err.stack ) + "\n"; + optsTransfer.details.write( strError ); + if( log.id != optsTransfer.details.id ) + log.write( strError ); + } + } ); + } catch ( err ) { + ++ cntFailedNodes; + if( log.verboseGet() >= log.verboseReversed().error ) { + const strError = optsTransfer.strLogPrefix + + cc.fatal( optsTransfer.strDirection + + " message analysis error:" ) + " " + + cc.error( "Failed to scan events on node " ) + + cc.info( joNode.name ) + cc.error( ", error is: " ) + + cc.warning( owaspUtils.extractErrorMessage( err ) ) + + cc.error( ", detailed node description is: " ) + cc.j( joNode ) + + cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + "\n"; + optsTransfer.details.write( strError ); + if( log.id != optsTransfer.details.id ) + log.write( strError ); + } + continue; } - } - if( cntFailedNodes > optsTransfer.cntNodesMayFail ) - break; - if( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) { - if( log.verboseGet() >= log.verboseReversed().information ) { - // eslint-disable-next-line dot-notation - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.sunny( optsTransfer.strDirection ) + cc.success( " message " ) + - cc.info( idxMessage + 1 ) + cc.success( " validation on node " ) + - cc.info( joNode.name ) + cc.success( " using URL " ) + - cc.info( strUrlHttp ) + cc.success( " is passed" ) + "\n" ); + if( cntFailedNodes > optsTransfer.cntNodesMayFail ) + break; + if( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) { + if( log.verboseGet() >= log.verboseReversed().information ) { + // eslint-disable-next-line dot-notation + optsTransfer.details.write( optsTransfer.strLogPrefix + + cc.sunny( optsTransfer.strDirection ) + cc.success( " message " ) + + cc.info( idxMessage + 1 ) + cc.success( " validation on node " ) + + cc.info( joNode.name ) + cc.success( " using URL " ) + + cc.info( strUrlHttp ) + cc.success( " is passed" ) + "\n" ); + } + break; } - break; + } + } catch ( err ) { + if( log.verboseGet() >= log.verboseReversed().critical ) { + // eslint-disable-next-line dot-notation + const strUrlHttp = joNode ? joNode["http_endpoint_ip"] : ""; + const strError = optsTransfer.strLogPrefix + + cc.fatal( optsTransfer.strDirection + " message analysis error:" ) + + " " + cc.error( "Failed to process events for " ) + + cc.sunny( optsTransfer.strDirection ) + cc.error( " message " ) + + cc.info( idxMessage + 1 ) + cc.error( " on node " ) + + ( joNode ? cc.info( joNode.name ) : cc.error( "<>" ) ) + + cc.error( " using URL " ) + ( joNode + ? cc.info( strUrlHttp ) : cc.error( "<>" ) ) + + cc.error( ", error is: " ) + + cc.warning( owaspUtils.extractErrorMessage( err ) ) + + cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + + "\n"; + optsTransfer.details.write( strError ); + if( log.id != optsTransfer.details.id ) + log.write( strError ); } } + } ); + try { + await promiseComplete; } catch ( err ) { - if( log.verboseGet() >= log.verboseReversed().critical ) { - // eslint-disable-next-line dot-notation - const strUrlHttp = joNode ? joNode["http_endpoint_ip"] : ""; - const strError = optsTransfer.strLogPrefix + - cc.fatal( optsTransfer.strDirection + " message analysis error:" ) + - " " + cc.error( "Failed to process events for " ) + - cc.sunny( optsTransfer.strDirection ) + cc.error( " message " ) + - cc.info( idxMessage + 1 ) + cc.error( " on node " ) + - ( joNode - ? cc.info( joNode.name ) - : cc.error( "<>" ) ) + - cc.error( " using URL " ) + - ( joNode ? cc.info( strUrlHttp ) : cc.error( "<>" ) ) + - cc.error( ", error is: " ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + - cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + - "\n"; - optsTransfer.details.write( strError ); - if( log.id != optsTransfer.details.id ) - log.write( strError ); - } - } - if( cntFailedNodes > optsTransfer.cntNodesMayFail ) { - if( log.verboseGet() >= log.verboseReversed().critical ) { - const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " Error validating " ) + cc.sunny( optsTransfer.strDirection ) + - cc.error( " messages, failed node count " ) + cc.info( cntFailedNodes ) + - cc.error( " is greater then allowed to fail " ) + - cc.info( optsTransfer.cntNodesMayFail ) + "\n"; - optsTransfer.details.write( s ); - if( log.id != optsTransfer.details.id ) - log.write( s ); - } - optsTransfer.details.exposeDetailsTo( - log, optsTransfer.strGatheredDetailsName, false ); - imaTransferErrorHandling.saveTransferError( - optsTransfer.strTransferErrorCategoryName, - optsTransfer.details.toString() ); - optsTransfer.details.close(); - return false; } - if( ! ( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) ) { - if( log.verboseGet() >= log.verboseReversed().critical ) { - const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " Error validating " ) + cc.sunny( optsTransfer.strDirection ) + - cc.error( " messages, passed node count " ) + cc.info( cntFailedNodes ) + - cc.error( " is less then needed count " ) + - cc.info( optsTransfer.cntNodesShouldPass ) + "\n"; - optsTransfer.details.write( s ); - if( log.id != optsTransfer.details.id ) - log.write( s ); - } - optsTransfer.details.exposeDetailsTo( - log, optsTransfer.strGatheredDetailsName, false ); - imaTransferErrorHandling.saveTransferError( - optsTransfer.strTransferErrorCategoryName, optsTransfer.details.toString() ); - optsTransfer.details.close(); + if( ! checkOutgoingMessageEventResult( + optsTransfer, joSChain, idxMessage, cntPassedNodes, cntFailedNodes ) ) return false; - } } return true; } From 27b5902c84dd00bb1de4d424a77c33f9ec145edf Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Fri, 10 Nov 2023 15:47:38 +0000 Subject: [PATCH 18/29] ticket-884 Async walk through S-Chain nodes to check OutgoingMessage event on each of 16 --- npms/skale-ima/index.mjs | 34 +++++++++++++++++---------------- npms/skale-owasp/owaspUtils.mjs | 4 ++++ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index fa4567224..4161582eb 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -938,21 +938,29 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { cc.debug( " with IMA message index " ) + cc.j( idxImaMessage ) + cc.debug( " and message envelope data:" ) + cc.j( joMessage ) + "\n" ); } - let cntPassedNodes = 0, cntFailedNodes = 0, joNode = null; + let cntPassedNodes = 0, cntFailedNodes = 0, joNode = null, cntWaitStepsDone = 0; const promiseComplete = new Promise( function( resolve, reject ) { const iv = setInterval( function() { + ++ cntWaitStepsDone; if( cntFailedNodes > optsTransfer.cntNodesMayFail ) { clearInterval( iv ); - reject( new Error( "Error validating " + optsTransfer.strDirection + + reject( new Error( "Critical error validating " + optsTransfer.strDirection + " messages, failed node count " + cntFailedNodes + " is greater then allowed to fail " + optsTransfer.cntNodesMayFail ) ); return; } if( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) { + clearInterval( iv ); resolve( true ); return; } - }, 500 ); + if( cntWaitStepsDone > 300 ) { + clearInterval( iv ); + reject( new Error( "Timeout error validating " + optsTransfer.strDirection + + " messages" ) ); + return; + } + }, 1000 ); try { for( let idxNode = 0; idxNode < cntNodes; ++ idxNode ) { joNode = joSChain.data.computed.nodes[idxNode]; @@ -997,21 +1005,18 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { let bEventIsFound = false; for( let idxEvent = 0; idxEvent < cntEvents; ++ idxEvent ) { const joEvent = node_r[idxEvent]; - const eventValuesByName = { + const ev = { "dstChainHash": joEvent.args[0], "msgCounter": joEvent.args[1], "srcContract": joEvent.args[2], "dstContract": joEvent.args[3], "data": joEvent.args[4] }; - if( owaspUtils.ensureStartsWith0x( - joMessage.sender ).toLowerCase() == - owaspUtils.ensureStartsWith0x( - eventValuesByName.srcContract ).toLowerCase() && - owaspUtils.ensureStartsWith0x( - joMessage.destinationContract ).toLowerCase() == - owaspUtils.ensureStartsWith0x( - eventValuesByName.dstContract ).toLowerCase() + if( owaspUtils.ensureStartsWith0xLC( joMessage.sender ) == + owaspUtils.ensureStartsWith0xLC( ev.srcContract ) && + owaspUtils.ensureStartsWith0xLC( + joMessage.destinationContract ) == + owaspUtils.ensureStartsWith0xLC( ev.dstContract ) ) { bEventIsFound = true; break; @@ -1112,10 +1117,7 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { } } } ); - try { - await promiseComplete; - } catch ( err ) { - } + try { await promiseComplete; } catch ( err ) { } if( ! checkOutgoingMessageEventResult( optsTransfer, joSChain, idxMessage, cntPassedNodes, cntFailedNodes ) ) return false; diff --git a/npms/skale-owasp/owaspUtils.mjs b/npms/skale-owasp/owaspUtils.mjs index 406f3ae07..530de56ce 100644 --- a/npms/skale-owasp/owaspUtils.mjs +++ b/npms/skale-owasp/owaspUtils.mjs @@ -487,6 +487,10 @@ export function ensureStartsWith0x( s ) { return "0x" + s; } +export function ensureStartsWith0xLC( s ) { + return ensureStartsWith0x( s ).toLowerCase(); +} + export function removeStarting0x( s ) { if( s == null || s == undefined || typeof s !== "string" ) return s; From 4e871477cf2d951d1bc3133038aca82921aa6c12 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Fri, 10 Nov 2023 16:31:03 +0000 Subject: [PATCH 19/29] ticket-883 Fixed problem related to empty SNB cache rewriting data --- npms/skale-ima/index.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index 4161582eb..aa9767417 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -922,6 +922,7 @@ async function checkOutgoingMessageEventResult( optsTransfer.details.close(); return false; } + return true; } async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { From 47bfc7237dba26f534551d74bce0d63be568174d Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Mon, 13 Nov 2023 15:41:03 +0000 Subject: [PATCH 20/29] ticket-885 added strong BLS parts validation before BLS glue; re-designed success counter for BLS parts --- agent/bls.mjs | 214 +++++++++++++++++++++++++------------------------- 1 file changed, 109 insertions(+), 105 deletions(-) diff --git a/agent/bls.mjs b/agent/bls.mjs index c5588d155..74edb690f 100644 --- a/agent/bls.mjs +++ b/agent/bls.mjs @@ -280,6 +280,8 @@ export function keccak256ForPendingWorkAnalysis( nNodeNumber, strLoopWorkType, i function splitSignatureShare( signatureShare ) { const jarr = signatureShare.split( ":" ); + if( jarr.length < 2 ) + throw new Error( "Failed to split signatureShare=" + signatureShare.toString() ); return { X: jarr[0], Y: jarr[1] @@ -301,10 +303,7 @@ function allocBlsTmpActionDir() { } function performBlsGlue( - details, - strDirection, - jarrMessages, nIdxCurrentMsgBlockStart, strFromChainName, - arrSignResults + details, strDirection, jarrMessages, nIdxCurrentMsgBlockStart, strFromChainName, arrSignResults ) { const imaState = state.get(); const strLogPrefix = @@ -345,6 +344,8 @@ function performBlsGlue( const cnt = arrSignResults.length; for( let i = 0; i < cnt; ++i ) { const jo = arrSignResults[i]; + if( ( !jo ) || typeof jo != "object" ) + throw new Error( "Failed to save BLS part " + i + "because it's not JSON object" ); const strPath = strActionDir + "/sign-result" + jo.index + ".json"; if( log.verboseGet() >= log.verboseReversed().trace ) { details.write( strLogPrefix + cc.debug( "Saving " ) + cc.notice( strPath ) + @@ -483,6 +484,8 @@ function performBlsGlueU256( details, u256, arrSignResults ) { const cnt = arrSignResults.length; for( let i = 0; i < cnt; ++i ) { const jo = arrSignResults[i]; + if( ( !jo ) || typeof jo != "object" ) + throw new Error( "Failed to save BLS part " + i + "because it's not JSON object" ); const strPath = strActionDir + "/sign-result" + jo.index + ".json"; if( log.verboseGet() >= log.verboseReversed().trace ) { details.write( strLogPrefix + cc.debug( "Saving " ) + cc.notice( strPath ) + @@ -1191,6 +1194,7 @@ async function gatherSigningStartImpl( optsSignOperation ) { optsSignOperation.errGathering = null; optsSignOperation.promiseCompleteGathering = new Promise( ( resolve, reject ) => { const iv = setInterval( function() { + const cntSuccess = 0 + optsSignOperation.arrSignResults.length; if( optsSignOperation.joGatheringTracker.nCountReceivedPrevious != optsSignOperation.joGatheringTracker.nCountReceived ) { if( log.verboseGet() >= log.verboseReversed().debug ) { @@ -1199,9 +1203,9 @@ async function gatherSigningStartImpl( optsSignOperation ) { cc.attention( "#" ) + cc.sunny( optsSignOperation.nTransferLoopCounter ) + cc.debug( " BLS signature gathering progress updated, now have " ) + cc.info( optsSignOperation.joGatheringTracker.nCountReceived ) + - cc.debug( " BLS parts of " ) + + cc.debug( " BLS parts of needed " ) + cc.info( optsSignOperation.nCountOfBlsPartsToCollect ) + - cc.debug( " arrived, have " ) + cc.info( optsSignOperation.cntSuccess ) + + cc.debug( " arrived, have " ) + cc.info( cntSuccess ) + cc.debug( " success(es) and " ) + cc.info( optsSignOperation.joGatheringTracker.nCountErrors ) + cc.debug( " error(s)" ) + "\n" ); @@ -1210,10 +1214,7 @@ async function gatherSigningStartImpl( optsSignOperation ) { 0 + optsSignOperation.joGatheringTracker.nCountReceived; } ++ optsSignOperation.joGatheringTracker.nWaitIntervalStepsDone; - optsSignOperation.cntSuccess = - optsSignOperation.joGatheringTracker.nCountReceived - - optsSignOperation.joGatheringTracker.nCountErrors; - if( optsSignOperation.cntSuccess >= optsSignOperation.nCountOfBlsPartsToCollect ) { + if( cntSuccess >= optsSignOperation.nCountOfBlsPartsToCollect ) { optsSignOperation.strLogPrefixB = cc.bright( optsSignOperation.strDirection ) + cc.debug( "/" ) + cc.attention( "#" ) + cc.sunny( optsSignOperation.nTransferLoopCounter ) + @@ -1221,13 +1222,10 @@ async function gatherSigningStartImpl( optsSignOperation ) { cc.debug( "/" ) + cc.sunny( "Summary" ) + cc.debug( ":" ) + " "; clearInterval( iv ); let strError = null, strSuccessfulResultDescription = null; - const joGlueResult = performBlsGlue( - optsSignOperation.details, optsSignOperation.strDirection, - optsSignOperation.jarrMessages, - optsSignOperation.nIdxCurrentMsgBlockStart, - optsSignOperation.strFromChainName, - optsSignOperation.arrSignResults - ); + const joGlueResult = performBlsGlue( optsSignOperation.details, + optsSignOperation.strDirection, optsSignOperation.jarrMessages, + optsSignOperation.nIdxCurrentMsgBlockStart, optsSignOperation.strFromChainName, + optsSignOperation.arrSignResults ); if( joGlueResult ) { if( log.verboseGet() >= log.verboseReversed().debug ) { optsSignOperation.details.write( optsSignOperation.strLogPrefixB + @@ -1318,15 +1316,14 @@ async function gatherSigningStartImpl( optsSignOperation ) { " node(s)", optsSignOperation.jarrMessages, null ).catch( ( err ) => { + const cntSuccess = 0 + optsSignOperation.arrSignResults.length; if( log.verboseGet() >= log.verboseReversed().critical ) { const strErrorMessage = cc.error( "Problem(3) in BLS sign result handler, " + "not enough successful BLS signature parts(" ) + - cc.info( optsSignOperation.cntSuccess ) + - cc.error( " when all attempts done, " + + cc.info( cntSuccess ) + cc.error( " when all attempts done, " + "error optsSignOperation.details: " ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + - "\n"; + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n"; optsSignOperation.details.write( strErrorMessage ); if( log.id != optsSignOperation.details.id ) log.write( strErrorMessage ); @@ -1334,7 +1331,7 @@ async function gatherSigningStartImpl( optsSignOperation ) { optsSignOperation.errGathering = "Problem(3) in BLS sign result handler," + " not enough successful BLS signature parts(" + - optsSignOperation.cntSuccess + + cntSuccess + " when all attempts done, error optsSignOperation.details: " + owaspUtils.extractErrorMessage( err ); reject( new Error( optsSignOperation.errGathering ) ); @@ -1353,13 +1350,13 @@ async function gatherSigningStartImpl( optsSignOperation ) { optsSignOperation.jarrMessages, null ).catch( ( err ) => { + const cntSuccess = 0 + optsSignOperation.arrSignResults.length; if( log.verboseGet() >= log.verboseReversed().critical ) { const strErrorMessage = cc.error( "Problem(4) in BLS sign result handler, " + "not enough successful BLS signature parts(" ) + - cc.info( optsSignOperation.cntSuccess ) + - cc.error( ") and timeout reached, " + + cc.info( cntSuccess ) + cc.error( ") and timeout reached, " + "error optsSignOperation.details: " ) + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n"; @@ -1369,8 +1366,7 @@ async function gatherSigningStartImpl( optsSignOperation ) { } optsSignOperation.errGathering = "Problem(4) in BLS sign result handler, " + - "not enough successful BLS signature parts(" + - optsSignOperation.cntSuccess + + "not enough successful BLS signature parts(" + cntSuccess + ") and timeout reached, error optsSignOperation.details: " + owaspUtils.extractErrorMessage( err ); reject( new Error( optsSignOperation.errGathering ) ); @@ -1429,14 +1425,13 @@ async function gatherSigningFinishImpl( optsSignOperation ) { optsSignOperation.jarrMessages, null ).catch( ( err ) => { + const cntSuccess = 0 + optsSignOperation.arrSignResults.length; if( log.verboseGet() >= log.verboseReversed().critical ) { const strErrorMessage = cc.error( "Problem(5) in BLS sign result handler, " + - "not enough successful BLS signature parts(" ) + - cc.info( optsSignOperation.cntSuccess ) + + "not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error optsSignOperation.details: " ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + - "\n"; + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n"; if( log.verboseGet() >= log.verboseReversed().error ) { if( log.id != optsSignOperation.details.id ) log.write( strErrorMessage ); @@ -1467,11 +1462,11 @@ async function gatherSigningFinishImpl( optsSignOperation ) { JSON.stringify( optsSignOperation.joGatheringTracker ), optsSignOperation.jarrMessages, null ).catch( ( err ) => { + const cntSuccess = 0 + optsSignOperation.arrSignResults.length; if( log.verboseGet() >= log.verboseReversed().critical ) { const strErrorMessage = cc.error( "Problem(6) in BLS sign result handler, " + - "not enough successful BLS signature parts(" ) + - cc.info( optsSignOperation.cntSuccess ) + + "not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error optsSignOperation.details: " ) + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n"; if( log.id != optsSignOperation.details.id ) @@ -1605,11 +1600,8 @@ async function doSignProcessHandleCall( cc.notice( "#" ) + cc.bright( nZeroBasedNodeIndex ) + cc.debug( ":" ) + " "; try { - optsSignOperation.cntSuccess = - optsSignOperation.joGatheringTracker.nCountReceived - - optsSignOperation.joGatheringTracker.nCountErrors; - if( optsSignOperation.cntSuccess > - optsSignOperation.nCountOfBlsPartsToCollect ) { + const cntSuccess = 0 + optsSignOperation.arrSignResults.length; + if( cntSuccess > optsSignOperation.nCountOfBlsPartsToCollect ) { ++optsSignOperation.joGatheringTracker.nCountSkipped; if( log.verboseGet() >= log.verboseReversed().notice ) { optsSignOperation.details.write( @@ -1810,7 +1802,6 @@ async function doSignMessagesImpl( strLogPrefixB: "", joGatheringTracker: {}, arrSignResults: [], - cntSuccess: 0, details: log, strGatheredDetailsName: "", sequenceId: "", @@ -1851,10 +1842,8 @@ async function doSignMessagesImpl( if( ! ( await prepareSignMessagesImpl( optsSignOperation ) ) ) return; for( let i = 0; i < optsSignOperation.jarrNodes.length; ++i ) { - optsSignOperation.cntSuccess = - optsSignOperation.joGatheringTracker.nCountReceived - - optsSignOperation.joGatheringTracker.nCountErrors; - if( optsSignOperation.cntSuccess >= optsSignOperation.nCountOfBlsPartsToCollect ) { + const cntSuccess = 0 + optsSignOperation.arrSignResults.length; + if( cntSuccess >= optsSignOperation.nCountOfBlsPartsToCollect ) { if( log.verboseGet() >= log.verboseReversed().trace ) { optsSignOperation.details.write( optsSignOperation.strLogPrefix + log.generateTimestampString( null, true ) + " " + @@ -1862,7 +1851,7 @@ async function doSignMessagesImpl( cc.debug( " for transfer from chain " ) + cc.info( fromChainName ) + cc.debug( " at #" ) + cc.info( i ) + cc.debug( " because successfully gathered count is reached " ) + - cc.j( optsSignOperation.cntSuccess ) + "\n" ); + cc.j( cntSuccess ) + "\n" ); } break; } @@ -2077,9 +2066,9 @@ async function doSignU256OneImpl( i, optsSignU256 ) { cc.info( optsSignU256.u256.toString() ) + cc.debug( ", answer is: " ) + cc.j( joOut ) + "\n" ); } - if( joOut.result == null || - joOut.result == undefined || - ( !typeof joOut.result == "object" ) + if( ( !joOut ) || typeof joOut != "object" || ( !( "result" in joOut ) ) || + ( !joOut.result ) || typeof joOut.result != "object" || + ( !( "signature" in joOut.result ) ) || joOut.result.signature != "object" ) { ++optsSignU256.joGatheringTracker.nCountErrors; const strErrorMessage = @@ -2110,8 +2099,7 @@ async function doSignU256OneImpl( i, optsSignU256 ) { const strLogPrefixA = cc.info( "BLS" ) + cc.debug( "/" ) + cc.notice( "#" ) + cc.bright( nZeroBasedNodeIndex ) + cc.debug( ":" ) + " "; try { - const cntSuccess = optsSignU256.joGatheringTracker.nCountReceived - - optsSignU256.joGatheringTracker.nCountErrors; + const cntSuccess = 0 + optsSignU256.arrSignResults.length; if( cntSuccess > optsSignU256.nCountOfBlsPartsToCollect ) { ++optsSignU256.joGatheringTracker.nCountSkipped; if( log.verboseGet() >= log.verboseReversed().notice ) { @@ -2214,14 +2202,15 @@ async function doSignU256Gathering( optsSignU256 ) { const iv = setInterval( function() { if( optsSignU256.joGatheringTracker.nCountReceivedPrevious != optsSignU256.joGatheringTracker.nCountReceived ) { + const cntSuccess = 0 + optsSignU256.arrSignResults.length; if( log.verboseGet() >= log.verboseReversed().debug ) { optsSignU256.details.write( cc.info( "BLS u256" ) + cc.debug( " BLS signature gathering progress updated, now have " ) + cc.info( optsSignU256.joGatheringTracker.nCountReceived ) + - cc.debug( " BLS parts of " ) + + cc.debug( " BLS parts of needed " ) + cc.info( optsSignU256.nCountOfBlsPartsToCollect ) + - cc.debug( " arrived, have " ) + cc.info( optsSignU256.cntSuccess ) + + cc.debug( " arrived, have " ) + cc.info( cntSuccess ) + cc.debug( " success(es) and " ) + cc.info( optsSignU256.joGatheringTracker.nCountErrors ) + cc.debug( " error(s)" ) + "\n" ); @@ -2230,9 +2219,7 @@ async function doSignU256Gathering( optsSignU256 ) { 0 + optsSignU256.joGatheringTracker.nCountReceived; } ++ optsSignU256.joGatheringTracker.nWaitIntervalStepsDone; - const cntSuccess = - optsSignU256.joGatheringTracker.nCountReceived - - optsSignU256.joGatheringTracker.nCountErrors; + const cntSuccess = 0 + optsSignU256.arrSignResults.length; if( cntSuccess >= optsSignU256.nCountOfBlsPartsToCollect ) { const strLogPrefixB = cc.info( "BLS u256" ) + cc.debug( "/" ) + cc.sunny( "Summary" ) + cc.debug( ":" ) + " "; @@ -2696,16 +2683,28 @@ export async function doSignReadyHash( strMessageHash, isExposeOutput ) { if( joOut.signResult != null && joOut.signResult != undefined && typeof joOut.signResult == "object" ) joSignResult = joOut.signResult; + if( !joSignResult ) { + const strError = "No signature arrived"; + joRetVal.error = strError; + if( log.id != details.id ) { + log.write( strLogPrefix + cc.error( "BLS-sign(1) finished with error: }" ) + + cc.warning( strError ) + "\n" ); + } + details.write( strLogPrefix + cc.error( "BLS-sign(1) finished with error: }" ) + + cc.warning( strError ) + "\n" ); + await joCall.disconnect(); + throw new Error( strError ); + } if( "errorMessage" in joSignResult && typeof joSignResult.errorMessage == "string" && joSignResult.errorMessage.length > 0 ) { const strError = - "BLS signing finished with error: " + joSignResult.errorMessage; + "BLS-sign(2) finished with error: " + joSignResult.errorMessage; joRetVal.error = strError; const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " BLS signing(1) finished with error: " ) + + cc.error( " BLS-sign(2) finished with error: " ) + cc.warning( joSignResult.errorMessage ) + "\n"; if( log.verboseGet() >= log.verboseReversed().error ) { @@ -2766,9 +2765,9 @@ async function prepareHandlingOfSkaleImaVerifyAndSign( optsHandleVerifyAndSign ) optsHandleVerifyAndSign.joCallData.params.direction; optsHandleVerifyAndSign.jarrMessages = optsHandleVerifyAndSign.joCallData.params.messages; + const strDir = cc.bright( optsHandleVerifyAndSign.strDirection ); if( log.verboseGet() >= log.verboseReversed().trace ) { - optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + - cc.bright( optsHandleVerifyAndSign.strDirection ) + + optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + strDir + cc.debug( " verification algorithm will work for transfer from chain " ) + cc.info( optsHandleVerifyAndSign.strFromChainName ) + cc.debug( "/" ) + cc.notice( optsHandleVerifyAndSign.strFromChainID ) + cc.debug( " to chain" ) + @@ -2782,12 +2781,10 @@ async function prepareHandlingOfSkaleImaVerifyAndSign( optsHandleVerifyAndSign ) optsHandleVerifyAndSign.nParticipants = discoverBlsParticipants( optsHandleVerifyAndSign.imaState.joSChainNetworkInfo ); if( log.verboseGet() >= log.verboseReversed().debug ) { - optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + - cc.bright( optsHandleVerifyAndSign.strDirection ) + + optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + strDir + cc.debug( " verification algorithm discovered BLS threshold is " ) + cc.info( optsHandleVerifyAndSign.nThreshold ) + cc.debug( "." ) + "\n" ); - optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + - cc.bright( optsHandleVerifyAndSign.strDirection ) + + optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + strDir + cc.debug( " verification algorithm discovered number of BLS participants is " ) + cc.info( optsHandleVerifyAndSign.nParticipants ) + cc.debug( "." ) + "\n" ); } @@ -2806,11 +2803,9 @@ async function prepareHandlingOfSkaleImaVerifyAndSign( optsHandleVerifyAndSign ) ) ); if( log.verboseGet() >= log.verboseReversed().debug ) { - optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + - cc.bright( optsHandleVerifyAndSign.strDirection ) + + optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + strDir + cc.debug( " verification algorithm message hash to sign is " ) + - cc.info( optsHandleVerifyAndSign.strMessageHash ) + - "\n" ); + cc.info( optsHandleVerifyAndSign.strMessageHash ) + "\n" ); } return true; } @@ -2819,8 +2814,7 @@ async function prepareS2sOfSkaleImaVerifyAndSign( optsHandleVerifyAndSign ) { const strSChainNameSrc = optsHandleVerifyAndSign.joCallData.params.srcChainName; const strSChainNameDst = optsHandleVerifyAndSign.joCallData.params.dstChainName; if( log.verboseGet() >= log.verboseReversed().trace ) { - optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + - cc.bright( optsHandleVerifyAndSign.strDirection ) + + optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + strDir + cc.debug( " verification algorithm will use for source chain name " ) + cc.info( strSChainNameSrc ) + cc.debug( " and destination chain name " ) + cc.info( strSChainNameDst ) + "\n" ); @@ -2887,19 +2881,18 @@ export async function handleSkaleImaVerifyAndSign( joCallData ) { nThreshold: 1, nParticipants: 1 }; + const strDir = cc.bright( optsHandleVerifyAndSign.strDirection ); try { if( ! ( await prepareHandlingOfSkaleImaVerifyAndSign( optsHandleVerifyAndSign ) ) ) return null; optsHandleVerifyAndSign.joExtraSignOpts = null; if( optsHandleVerifyAndSign.strDirection == "S2S" ) await prepareS2sOfSkaleImaVerifyAndSign( optsHandleVerifyAndSign ); - await checkCorrectnessOfMessagesToSign( optsHandleVerifyAndSign.details, optsHandleVerifyAndSign.strLogPrefix, optsHandleVerifyAndSign.strDirection, optsHandleVerifyAndSign.jarrMessages, optsHandleVerifyAndSign.nIdxCurrentMsgBlockStart, - optsHandleVerifyAndSign.joExtraSignOpts - ); + optsHandleVerifyAndSign.joExtraSignOpts ); if( log.verboseGet() >= log.verboseReversed().debug ) { optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + cc.debug( "Will BLS-sign verified messages." ) + "\n" ); @@ -2930,12 +2923,10 @@ export async function handleSkaleImaVerifyAndSign( joCallData ) { const signerIndex = optsHandleVerifyAndSign.imaState.nNodeNumber; await rpcCall.create( joAccount.strSgxURL, rpcCallOpts, async function( joCall, err ) { if( err ) { - const strErrorMessage = optsHandleVerifyAndSign.strLogPrefix + - cc.bright( optsHandleVerifyAndSign.strDirection ) + " " + - cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call(handleSkaleImaVerifyAndSign) to SGX failed, " + - "RPC call was not created, error is: " ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n"; + const strErrorMessage = optsHandleVerifyAndSign.strLogPrefix + strDir + " " + + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call" + + "(handleSkaleImaVerifyAndSign) to SGX failed, RPC call was not created, " + + "error is: " ) + cc.warning( owaspUtils.extractErrorMessage( err ) ) + "\n"; if( log.verboseGet() >= log.verboseReversed().error ) { if( log.id != optsHandleVerifyAndSign.details.id ) log.write( strErrorMessage ); @@ -2944,10 +2935,8 @@ export async function handleSkaleImaVerifyAndSign( joCallData ) { if( joCall ) await joCall.disconnect(); throw new Error( - "JSON RPC call(handleSkaleImaVerifyAndSign) to SGX failed, " + - "RPC call was not created, error is: " + - owaspUtils.extractErrorMessage( err ) - ); + "JSON RPC call(handleSkaleImaVerifyAndSign) to SGX failed, RPC call was " + + "not created, error is: " + owaspUtils.extractErrorMessage( err ) ); } const joCallSGX = { "jsonrpc": "2.0", @@ -2963,22 +2952,19 @@ export async function handleSkaleImaVerifyAndSign( joCallData ) { }; if( log.verboseGet() >= log.verboseReversed().trace ) { optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + - cc.bright( optsHandleVerifyAndSign.strDirection ) + - cc.debug( " verification algorithm will invoke " ) + cc.info( "SGX" ) + " " + - cc.debug( "with call data" ) + " " + cc.j( joCallSGX ) + "\n" ); + strDir + cc.debug( " verification algorithm will invoke " ) + cc.info( "SGX" ) + + " " + cc.debug( "with call data" ) + " " + cc.j( joCallSGX ) + "\n" ); } await joCall.call( joCallSGX, async function( joIn, joOut, err ) { if( err ) { const strError = - "JSON RPC call(handleSkaleImaVerifyAndSign) " + - "to SGX failed, RPC call reported error: " + - owaspUtils.extractErrorMessage( err ); + "JSON RPC call(handleSkaleImaVerifyAndSign) to SGX failed, RPC call " + + "reported error: " + owaspUtils.extractErrorMessage( err ); optsHandleVerifyAndSign.joRetVal.error = strError; const jsErrorObject = new Error( strError ); const strErrorMessage = optsHandleVerifyAndSign.strLogPrefix + - cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call(handleSkaleImaVerifyAndSign) to SGX failed, " + - "RPC call reported error: " ) + + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call" + + "(handleSkaleImaVerifyAndSign) to SGX failed, RPC call reported error: " ) + cc.warning( owaspUtils.extractErrorMessage( err ) ) + cc.error( ", stack is:" ) + "\n" + cc.stack( jsErrorObject.stack ) + "\n"; if( log.verboseGet() >= log.verboseReversed().error ) { @@ -2991,8 +2977,7 @@ export async function handleSkaleImaVerifyAndSign( joCallData ) { } if( log.verboseGet() >= log.verboseReversed().trace ) { optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + - cc.bright( optsHandleVerifyAndSign.strDirection ) + - cc.debug( " Call to " ) + cc.info( "SGX" ) + + strDir + cc.debug( " Call to " ) + cc.info( "SGX" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); } let joSignResult = joOut; @@ -3004,18 +2989,29 @@ export async function handleSkaleImaVerifyAndSign( joCallData ) { joSignResult = joOut.signResult; if( "qa" in optsHandleVerifyAndSign.joCallData ) optsHandleVerifyAndSign.joRetVal.qa = optsHandleVerifyAndSign.joCallData.qa; + if( !joSignResult ) { + const strError = "No signature arrived"; + joRetVal.error = strError; + if( log.id != details.id ) { + log.write( strLogPrefix + cc.error( "BLS-sign(1) finished with error: }" ) + + cc.warning( strError ) + "\n" ); + } + details.write( strLogPrefix + cc.error( "BLS-sign(1) finished with error: }" ) + + cc.warning( strError ) + "\n" ); + await joCall.disconnect(); + throw new Error( strError ); + } if( "errorMessage" in joSignResult && typeof joSignResult.errorMessage == "string" && joSignResult.errorMessage.length > 0 ) { optsHandleVerifyAndSign.isSuccess = false; const strError = - "BLS signing finished with error: " + joSignResult.errorMessage; + "BLS-sign(2) finished with error: " + joSignResult.errorMessage; optsHandleVerifyAndSign.joRetVal.error = strError; const strErrorMessage = optsHandleVerifyAndSign.strLogPrefix + - cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " BLS signing(2) finished with error: " ) + - cc.warning( joSignResult.errorMessage ) + "\n"; + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " BLS-sign(2) finished with " + + "error: " ) + cc.warning( joSignResult.errorMessage ) + "\n"; if( log.verboseGet() >= log.verboseReversed().error ) { if( log.id != optsHandleVerifyAndSign.details.id ) log.write( strErrorMessage ); @@ -3039,8 +3035,7 @@ export async function handleSkaleImaVerifyAndSign( joCallData ) { const strErrorMessage = optsHandleVerifyAndSign.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + cc.error( "IMA messages verifier/signer error: " ) + cc.warning( strError ) + - cc.error( ", stack is:" ) + "\n" + cc.stack( err.stack ) + - "\n"; + cc.error( ", stack is:" ) + "\n" + cc.stack( err.stack ) + "\n"; if( log.id != optsHandleVerifyAndSign.details.id ) log.write( strErrorMessage ); optsHandleVerifyAndSign.details.write( strErrorMessage ); @@ -3204,17 +3199,28 @@ export async function handleSkaleImaBSU256( joCallData ) { if( joOut.signResult != null && joOut.signResult != undefined && typeof joOut.signResult == "object" ) joSignResult = joOut.signResult; + if( !joSignResult ) { + const strError = "No signature arrived"; + joRetVal.error = strError; + if( log.id != details.id ) { + log.write( strLogPrefix + cc.error( "U256/BLS-sign(1) finished " + + "with error: " ) + cc.warning( strError ) + "\n" ); + } + details.write( strLogPrefix + cc.error( "U256/BLS-sign(1) finished " + + "with error: " ) + cc.warning( strError ) + "\n" ); + await joCall.disconnect(); + throw new Error( strError ); + } if( "errorMessage" in joSignResult && typeof joSignResult.errorMessage == "string" && joSignResult.errorMessage.length > 0 ) { optsBSU256.isSuccess = false; const strError = - "BLS signing finished with error: " + joSignResult.errorMessage; + "U256/BLS-sign(2) finished with error: " + joSignResult.errorMessage; optsBSU256.joRetVal.error = strError; const strErrorMessage = optsBSU256.strLogPrefix + - cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " BLS signing(3) finished with error: " ) + - cc.warning( joSignResult.errorMessage ) + "\n"; + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " U256/BLS-sign(2) finished" + + " with error: " ) + cc.warning( joSignResult.errorMessage ) + "\n"; if( log.verboseGet() >= log.verboseReversed().error ) { if( log.id != optsBSU256.details.id ) log.write( strErrorMessage ); @@ -3235,11 +3241,9 @@ export async function handleSkaleImaBSU256( joCallData ) { const strError = owaspUtils.extractErrorMessage( err ); optsBSU256.joRetVal.error = strError; if( log.verboseGet() >= log.verboseReversed().critical ) { - const strErrorMessage = - optsBSU256.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + + const strErrorMessage = optsBSU256.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + cc.error( "U256-BLS-signer error: " ) + cc.warning( strError ) + - cc.error( ", stack is:" ) + "\n" + cc.stack( err.stack ) + - "\n"; + cc.error( ", stack is:" ) + "\n" + cc.stack( err.stack ) + "\n"; if( log.id != optsBSU256.details.id ) log.write( strErrorMessage ); optsBSU256.details.write( strErrorMessage ); From 940771f29bfde4111eae658154b790feabaaadc3 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Mon, 13 Nov 2023 17:06:54 +0000 Subject: [PATCH 21/29] ticket-885 added error check in skale_imaVerifyAndSign JSON RPC API --- agent/bls.mjs | 6 ++---- agent/main.mjs | 7 ++++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/agent/bls.mjs b/agent/bls.mjs index 74edb690f..d81622758 100644 --- a/agent/bls.mjs +++ b/agent/bls.mjs @@ -1559,10 +1559,8 @@ async function doSignProcessHandleCall( cc.j( joOut ) + cc.debug( ", " ) + cc.notice( "sequence ID" ) + cc.debug( " is " ) + cc.attention( optsSignOperation.sequenceId ) + "\n" ); } - if( joOut.result == null || - joOut.result == undefined || - ( !typeof joOut.result == "object" ) - ) { + if( ( !joOut ) || typeof joOut != "object" || ( !( "result" in joOut ) ) || ( !joOut.result ) || + typeof joOut.result != "object" ) { ++optsSignOperation.joGatheringTracker.nCountErrors; const strErrorMessage = optsSignOperation.strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + diff --git a/agent/main.mjs b/agent/main.mjs index 5d0edc449..165b228d5 100644 --- a/agent/main.mjs +++ b/agent/main.mjs @@ -392,8 +392,13 @@ function initJsonRpcServer() { } break; default: - throw new Error( "Unknown method name \"" + joMessage.method + "\" was specified" ); + joAnswer.error = `Unknown method name ${joMessage.method} was specified`; + break; } // switch( joMessage.method ) + if( ( !joAnswer ) || typeof joAnswer != "object" ) { + joAnswer = {}; + joAnswer.error = "internal error, null data returned"; + } } catch ( err ) { if( log.verboseGet() >= log.verboseReversed().error ) { const strError = owaspUtils.extractErrorMessage( err ); From c88275c08cf17415f87c22821c4c5c3c9e774012 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Mon, 13 Nov 2023 20:10:34 +0000 Subject: [PATCH 22/29] Fixed logging typo with missing endline --- npms/skale-observer/observer.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npms/skale-observer/observer.mjs b/npms/skale-observer/observer.mjs index 7ce7f8abe..44956c704 100644 --- a/npms/skale-observer/observer.mjs +++ b/npms/skale-observer/observer.mjs @@ -1082,7 +1082,7 @@ export async function cacheSChains( strChainNameConnectedTo, opts ) { if( opts && opts.details ) { if( log.verboseGet() >= log.verboseReversed().error ) { opts.details.write( cc.fatal( "ERROR:" ) + - cc.error( " Failed to cache: " ) + cc.error( err ) ); + cc.error( " Failed to cache: " ) + cc.error( err ) + "\n" ); opts.details.write( cc.stack( err.stack ) ); } } From 53bbaef3f621fb3504a5b8737db12fabbaa40b0b Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 14 Nov 2023 13:11:17 +0000 Subject: [PATCH 23/29] ticket-885 added error check in skale_imaVerifyAndSign JSON RPC API --- agent/bls.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/agent/bls.mjs b/agent/bls.mjs index d81622758..707abd880 100644 --- a/agent/bls.mjs +++ b/agent/bls.mjs @@ -2811,6 +2811,7 @@ async function prepareHandlingOfSkaleImaVerifyAndSign( optsHandleVerifyAndSign ) async function prepareS2sOfSkaleImaVerifyAndSign( optsHandleVerifyAndSign ) { const strSChainNameSrc = optsHandleVerifyAndSign.joCallData.params.srcChainName; const strSChainNameDst = optsHandleVerifyAndSign.joCallData.params.dstChainName; + const strDir = cc.bright( optsHandleVerifyAndSign.strDirection ); if( log.verboseGet() >= log.verboseReversed().trace ) { optsHandleVerifyAndSign.details.write( optsHandleVerifyAndSign.strLogPrefix + strDir + cc.debug( " verification algorithm will use for source chain name " ) + From b241992881994c1c8f9a18fb3c51f2065efb6c98 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 14 Nov 2023 16:40:36 +0000 Subject: [PATCH 24/29] ticket-884 rolled back --- npms/skale-ima/index.mjs | 384 ++++++++++++++------------------ npms/skale-owasp/owaspUtils.mjs | 4 - 2 files changed, 169 insertions(+), 219 deletions(-) diff --git a/npms/skale-ima/index.mjs b/npms/skale-ima/index.mjs index aa9767417..2b3ccd659 100644 --- a/npms/skale-ima/index.mjs +++ b/npms/skale-ima/index.mjs @@ -882,49 +882,6 @@ async function handleAllMessagesSigning( optsTransfer ) { } } -async function checkOutgoingMessageEventResult( - optsTransfer, joSChain, idxMessage, cntPassedNodes, cntFailedNodes -) { - if( cntFailedNodes > optsTransfer.cntNodesMayFail ) { - if( log.verboseGet() >= log.verboseReversed().critical ) { - const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " Error validating " ) + cc.sunny( optsTransfer.strDirection ) + - cc.error( " messages, failed node count " ) + cc.info( cntFailedNodes ) + - cc.error( " is greater then allowed to fail " ) + - cc.info( optsTransfer.cntNodesMayFail ) + "\n"; - optsTransfer.details.write( s ); - if( log.id != optsTransfer.details.id ) - log.write( s ); - } - optsTransfer.details.exposeDetailsTo( - log, optsTransfer.strGatheredDetailsName, false ); - imaTransferErrorHandling.saveTransferError( - optsTransfer.strTransferErrorCategoryName, - optsTransfer.details.toString() ); - optsTransfer.details.close(); - return false; - } - if( ! ( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) ) { - if( log.verboseGet() >= log.verboseReversed().critical ) { - const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " Error validating " ) + cc.sunny( optsTransfer.strDirection ) + - cc.error( " messages, passed node count " ) + cc.info( cntPassedNodes ) + - cc.error( " is less then needed count " ) + - cc.info( optsTransfer.cntNodesShouldPass ) + "\n"; - optsTransfer.details.write( s ); - if( log.id != optsTransfer.details.id ) - log.write( s ); - } - optsTransfer.details.exposeDetailsTo( - log, optsTransfer.strGatheredDetailsName, false ); - imaTransferErrorHandling.saveTransferError( - optsTransfer.strTransferErrorCategoryName, optsTransfer.details.toString() ); - optsTransfer.details.close(); - return false; - } - return true; -} - async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { const cntNodes = joSChain.data.computed.nodes.length; const cntMessages = optsTransfer.jarrMessages.length; @@ -939,189 +896,186 @@ async function checkOutgoingMessageEvent( optsTransfer, joSChain ) { cc.debug( " with IMA message index " ) + cc.j( idxImaMessage ) + cc.debug( " and message envelope data:" ) + cc.j( joMessage ) + "\n" ); } - let cntPassedNodes = 0, cntFailedNodes = 0, joNode = null, cntWaitStepsDone = 0; - const promiseComplete = new Promise( function( resolve, reject ) { - const iv = setInterval( function() { - ++ cntWaitStepsDone; - if( cntFailedNodes > optsTransfer.cntNodesMayFail ) { - clearInterval( iv ); - reject( new Error( "Critical error validating " + optsTransfer.strDirection + - " messages, failed node count " + cntFailedNodes + - " is greater then allowed to fail " + optsTransfer.cntNodesMayFail ) ); - return; - } - if( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) { - clearInterval( iv ); - resolve( true ); - return; - } - if( cntWaitStepsDone > 300 ) { - clearInterval( iv ); - reject( new Error( "Timeout error validating " + optsTransfer.strDirection + - " messages" ) ); - return; + let cntPassedNodes = 0, cntFailedNodes = 0, joNode = null; + try { + for( let idxNode = 0; idxNode < cntNodes; ++ idxNode ) { + joNode = joSChain.data.computed.nodes[idxNode]; + // eslint-disable-next-line dot-notation + const strUrlHttp = joNode["http_endpoint_ip"]; + if( log.verboseGet() >= log.verboseReversed().trace ) { + optsTransfer.details.write( optsTransfer.strLogPrefix + + cc.debug( "Validating " ) + cc.sunny( optsTransfer.strDirection ) + + cc.debug( " message " ) + cc.info( idxMessage + 1 ) + + cc.debug( " on node " ) + cc.info( joNode.name ) + + cc.debug( " using URL " ) + cc.info( strUrlHttp ) + cc.debug( "..." ) + + "\n" ); } - }, 1000 ); - try { - for( let idxNode = 0; idxNode < cntNodes; ++ idxNode ) { - joNode = joSChain.data.computed.nodes[idxNode]; + let bEventIsFound = false; + try { // eslint-disable-next-line dot-notation - const strUrlHttp = joNode["http_endpoint_ip"]; + const ethersProviderNode = owaspUtils.getEthersProviderFromURL( strUrlHttp ); + const joMessageProxyNode = new owaspUtils.ethersMod.ethers.Contract( + optsTransfer.imaState.chainProperties.sc + .joAbiIMA.message_proxy_chain_address, + optsTransfer.imaState.chainProperties + .sc.joAbiIMA.message_proxy_chain_abi, + ethersProviderNode ); + const strEventName = "OutgoingMessage"; + const node_r = await imaEventLogScan.safeGetPastEventsProgressive( + optsTransfer.details, optsTransfer.strLogPrefixShort, ethersProviderNode, + 10, joMessageProxyNode, strEventName, + joMessage.savedBlockNumberForOptimizations, + joMessage.savedBlockNumberForOptimizations, + joMessageProxyNode.filters[strEventName]( + owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), + owaspUtils.toBN( idxImaMessage ) + ), + optsTransfer.optsChainPair + ); + const cntEvents = node_r.length; if( log.verboseGet() >= log.verboseReversed().trace ) { - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.debug( "Validating " ) + cc.sunny( optsTransfer.strDirection ) + - cc.debug( " message " ) + cc.info( idxMessage + 1 ) + - cc.debug( " on node " ) + cc.info( joNode.name ) + - cc.debug( " using URL " ) + cc.info( strUrlHttp ) + cc.debug( "..." ) + - "\n" ); + optsTransfer.details.write( optsTransfer.strLogPrefix + cc.debug( "Got " ) + + cc.info( cntEvents ) + cc.debug( " event(s) (" ) + + cc.info( strEventName ) + cc.debug( ") on node " ) + + cc.info( joNode.name ) + cc.debug( " with data: " ) + + cc.j( node_r ) + "\n" ); } - try { - const sc = optsTransfer.imaState.chainProperties.sc; - // eslint-disable-next-line dot-notation - const ethersProviderNode = - owaspUtils.getEthersProviderFromURL( strUrlHttp ); - const joMessageProxyNode = new owaspUtils.ethersMod.ethers.Contract( - sc.joAbiIMA.message_proxy_chain_address, - sc.joAbiIMA.message_proxy_chain_abi, ethersProviderNode ); - const strEventName = "OutgoingMessage"; - imaEventLogScan.safeGetPastEventsProgressive( - optsTransfer.details, optsTransfer.strLogPrefixShort, - ethersProviderNode, 10, joMessageProxyNode, strEventName, - joMessage.savedBlockNumberForOptimizations, - joMessage.savedBlockNumberForOptimizations, - joMessageProxyNode.filters[strEventName]( - owaspUtils.ethersMod.ethers.utils.id( optsTransfer.chainNameDst ), - owaspUtils.toBN( idxImaMessage ) - ), - optsTransfer.optsChainPair - ).then( node_r => { - const cntEvents = node_r.length; - if( log.verboseGet() >= log.verboseReversed().trace ) { - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.debug( "Got " ) + cc.info( cntEvents ) + - cc.debug( " event(s) (" ) + cc.info( strEventName ) + - cc.debug( ") on node " ) + cc.info( joNode.name ) + - cc.debug( " with data: " ) + cc.j( node_r ) + "\n" ); - } - let bEventIsFound = false; - for( let idxEvent = 0; idxEvent < cntEvents; ++ idxEvent ) { - const joEvent = node_r[idxEvent]; - const ev = { - "dstChainHash": joEvent.args[0], - "msgCounter": joEvent.args[1], - "srcContract": joEvent.args[2], - "dstContract": joEvent.args[3], - "data": joEvent.args[4] - }; - if( owaspUtils.ensureStartsWith0xLC( joMessage.sender ) == - owaspUtils.ensureStartsWith0xLC( ev.srcContract ) && - owaspUtils.ensureStartsWith0xLC( - joMessage.destinationContract ) == - owaspUtils.ensureStartsWith0xLC( ev.dstContract ) - ) { - bEventIsFound = true; - break; - } - } - if( bEventIsFound ) { - ++ cntPassedNodes; - if( log.verboseGet() >= log.verboseReversed().information ) { - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.sunny( optsTransfer.strDirection ) + - cc.success( " message " ) + cc.info( idxMessage + 1 ) + - cc.success( " validation on node " ) + - cc.info( joNode.name ) + cc.success( " using URL " ) + - cc.info( strUrlHttp ) + cc.success( " is passed" ) + "\n" ); - } - } else { - ++ cntFailedNodes; - if( log.verboseGet() >= log.verboseReversed().error ) { - // eslint-disable-next-line dot-notation - const strError = optsTransfer.strLogPrefix + - cc.sunny( optsTransfer.strDirection ) + - cc.error( " message " ) + cc.info( idxMessage + 1 ) + - cc.error( " validation on node " ) + - cc.info( joNode.name ) + cc.success( " using URL " ) + - cc.info( strUrlHttp ) + cc.error( " is failed" ) + "\n"; - optsTransfer.details.write( strError ); - if( log.id != optsTransfer.details.id ) - log.write( strError ); - } - } - } ).catch( err => { - ++ cntFailedNodes; - if( log.verboseGet() >= log.verboseReversed().error ) { - const strError = optsTransfer.strLogPrefix + - cc.fatal( optsTransfer.strDirection + - " message analysis error:" ) + " " + - cc.error( "Failed to scan events on node " ) + - cc.info( joNode.name ) + cc.error( ", error is: " ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + - cc.error( ", detailed node description is: " ) + - cc.j( joNode ) + cc.error( ", stack is: " ) + "\n" + - cc.stack( err.stack ) + "\n"; - optsTransfer.details.write( strError ); - if( log.id != optsTransfer.details.id ) - log.write( strError ); - } - } ); - } catch ( err ) { - ++ cntFailedNodes; - if( log.verboseGet() >= log.verboseReversed().error ) { - const strError = optsTransfer.strLogPrefix + - cc.fatal( optsTransfer.strDirection + - " message analysis error:" ) + " " + - cc.error( "Failed to scan events on node " ) + - cc.info( joNode.name ) + cc.error( ", error is: " ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + - cc.error( ", detailed node description is: " ) + cc.j( joNode ) + - cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + "\n"; - optsTransfer.details.write( strError ); - if( log.id != optsTransfer.details.id ) - log.write( strError ); + for( let idxEvent = 0; idxEvent < cntEvents; ++ idxEvent ) { + const joEvent = node_r[idxEvent]; + const eventValuesByName = { + "dstChainHash": joEvent.args[0], + "msgCounter": joEvent.args[1], + "srcContract": joEvent.args[2], + "dstContract": joEvent.args[3], + "data": joEvent.args[4] + }; + if( owaspUtils.ensureStartsWith0x( + joMessage.sender ).toLowerCase() == + owaspUtils.ensureStartsWith0x( + eventValuesByName.srcContract ).toLowerCase() && + owaspUtils.ensureStartsWith0x( + joMessage.destinationContract ).toLowerCase() == + owaspUtils.ensureStartsWith0x( + eventValuesByName.dstContract ).toLowerCase() + ) { + bEventIsFound = true; + break; } - continue; } - if( cntFailedNodes > optsTransfer.cntNodesMayFail ) - break; - if( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) { - if( log.verboseGet() >= log.verboseReversed().information ) { - // eslint-disable-next-line dot-notation - optsTransfer.details.write( optsTransfer.strLogPrefix + - cc.sunny( optsTransfer.strDirection ) + cc.success( " message " ) + - cc.info( idxMessage + 1 ) + cc.success( " validation on node " ) + - cc.info( joNode.name ) + cc.success( " using URL " ) + - cc.info( strUrlHttp ) + cc.success( " is passed" ) + "\n" ); - } - break; + } catch ( err ) { + ++ cntFailedNodes; + if( log.verboseGet() >= log.verboseReversed().error ) { + const strError = optsTransfer.strLogPrefix + + cc.fatal( optsTransfer.strDirection + + " message analysis error:" ) + " " + + cc.error( "Failed to scan events on node " ) + cc.info( joNode.name ) + + cc.error( ", error is: " ) + + cc.warning( owaspUtils.extractErrorMessage( err ) ) + + cc.error( ", detailed node description is: " ) + cc.j( joNode ) + + cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + "\n"; + optsTransfer.details.write( strError ); + if( log.id != optsTransfer.details.id ) + log.write( strError ); } + continue; } - } catch ( err ) { - if( log.verboseGet() >= log.verboseReversed().critical ) { - // eslint-disable-next-line dot-notation - const strUrlHttp = joNode ? joNode["http_endpoint_ip"] : ""; - const strError = optsTransfer.strLogPrefix + - cc.fatal( optsTransfer.strDirection + " message analysis error:" ) + - " " + cc.error( "Failed to process events for " ) + - cc.sunny( optsTransfer.strDirection ) + cc.error( " message " ) + - cc.info( idxMessage + 1 ) + cc.error( " on node " ) + - ( joNode ? cc.info( joNode.name ) : cc.error( "<>" ) ) + - cc.error( " using URL " ) + ( joNode - ? cc.info( strUrlHttp ) : cc.error( "<>" ) ) + - cc.error( ", error is: " ) + - cc.warning( owaspUtils.extractErrorMessage( err ) ) + - cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + - "\n"; - optsTransfer.details.write( strError ); - if( log.id != optsTransfer.details.id ) - log.write( strError ); + if( bEventIsFound ) { + ++ cntPassedNodes; + if( log.verboseGet() >= log.verboseReversed().information ) { + optsTransfer.details.write( optsTransfer.strLogPrefix + + cc.sunny( optsTransfer.strDirection ) + cc.success( " message " ) + + cc.info( idxMessage + 1 ) + cc.success( " validation on node " ) + + cc.info( joNode.name ) + cc.success( " using URL " ) + + cc.info( strUrlHttp ) + cc.success( " is passed" ) + "\n" ); + } + } else { + ++ cntFailedNodes; + if( log.verboseGet() >= log.verboseReversed().error ) { + // eslint-disable-next-line dot-notation + const strError = optsTransfer.strLogPrefix + + cc.sunny( optsTransfer.strDirection ) + cc.error( " message " ) + + cc.info( idxMessage + 1 ) + cc.error( " validation on node " ) + + cc.info( joNode.name ) + cc.success( " using URL " ) + + cc.info( strUrlHttp ) + cc.error( " is failed" ) + "\n"; + optsTransfer.details.write( strError ); + if( log.id != optsTransfer.details.id ) + log.write( strError ); + } + } + if( cntFailedNodes > optsTransfer.cntNodesMayFail ) + break; + if( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) { + if( log.verboseGet() >= log.verboseReversed().information ) { + // eslint-disable-next-line dot-notation + optsTransfer.details.write( optsTransfer.strLogPrefix + + cc.sunny( optsTransfer.strDirection ) + cc.success( " message " ) + + cc.info( idxMessage + 1 ) + cc.success( " validation on node " ) + + cc.info( joNode.name ) + cc.success( " using URL " ) + + cc.info( strUrlHttp ) + cc.success( " is passed" ) + "\n" ); + } + break; } } - } ); - try { await promiseComplete; } catch ( err ) { } - if( ! checkOutgoingMessageEventResult( - optsTransfer, joSChain, idxMessage, cntPassedNodes, cntFailedNodes ) ) + } catch ( err ) { + if( log.verboseGet() >= log.verboseReversed().critical ) { + // eslint-disable-next-line dot-notation + const strUrlHttp = joNode ? joNode["http_endpoint_ip"] : ""; + const strError = optsTransfer.strLogPrefix + + cc.fatal( optsTransfer.strDirection + " message analysis error:" ) + + " " + cc.error( "Failed to process events for " ) + + cc.sunny( optsTransfer.strDirection ) + cc.error( " message " ) + + cc.info( idxMessage + 1 ) + cc.error( " on node " ) + + ( joNode + ? cc.info( joNode.name ) + : cc.error( "<>" ) ) + + cc.error( " using URL " ) + + ( joNode ? cc.info( strUrlHttp ) : cc.error( "<>" ) ) + + cc.error( ", error is: " ) + + cc.warning( owaspUtils.extractErrorMessage( err ) ) + + cc.error( ", stack is: " ) + "\n" + cc.stack( err.stack ) + + "\n"; + optsTransfer.details.write( strError ); + if( log.id != optsTransfer.details.id ) + log.write( strError ); + } + } + if( cntFailedNodes > optsTransfer.cntNodesMayFail ) { + if( log.verboseGet() >= log.verboseReversed().critical ) { + const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " Error validating " ) + cc.sunny( optsTransfer.strDirection ) + + cc.error( " messages, failed node count " ) + cc.info( cntFailedNodes ) + + cc.error( " is greater then allowed to fail " ) + + cc.info( optsTransfer.cntNodesMayFail ) + "\n"; + optsTransfer.details.write( s ); + if( log.id != optsTransfer.details.id ) + log.write( s ); + } + optsTransfer.details.exposeDetailsTo( + log, optsTransfer.strGatheredDetailsName, false ); + imaTransferErrorHandling.saveTransferError( + optsTransfer.strTransferErrorCategoryName, + optsTransfer.details.toString() ); + optsTransfer.details.close(); return false; + } + if( ! ( cntPassedNodes >= optsTransfer.cntNodesShouldPass ) ) { + if( log.verboseGet() >= log.verboseReversed().critical ) { + const s = optsTransfer.strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " Error validating " ) + cc.sunny( optsTransfer.strDirection ) + + cc.error( " messages, passed node count " ) + cc.info( cntFailedNodes ) + + cc.error( " is less then needed count " ) + + cc.info( optsTransfer.cntNodesShouldPass ) + "\n"; + optsTransfer.details.write( s ); + if( log.id != optsTransfer.details.id ) + log.write( s ); + } + optsTransfer.details.exposeDetailsTo( + log, optsTransfer.strGatheredDetailsName, false ); + imaTransferErrorHandling.saveTransferError( + optsTransfer.strTransferErrorCategoryName, optsTransfer.details.toString() ); + optsTransfer.details.close(); + return false; + } } return true; } diff --git a/npms/skale-owasp/owaspUtils.mjs b/npms/skale-owasp/owaspUtils.mjs index 530de56ce..406f3ae07 100644 --- a/npms/skale-owasp/owaspUtils.mjs +++ b/npms/skale-owasp/owaspUtils.mjs @@ -487,10 +487,6 @@ export function ensureStartsWith0x( s ) { return "0x" + s; } -export function ensureStartsWith0xLC( s ) { - return ensureStartsWith0x( s ).toLowerCase(); -} - export function removeStarting0x( s ) { if( s == null || s == undefined || typeof s !== "string" ) return s; From 2dca8561beaf450ae4ba204207d364bd42c884cb Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 14 Nov 2023 17:19:01 +0000 Subject: [PATCH 25/29] ticket-884 rolled back --- agent/bls.mjs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/agent/bls.mjs b/agent/bls.mjs index 707abd880..feb21591f 100644 --- a/agent/bls.mjs +++ b/agent/bls.mjs @@ -1194,7 +1194,7 @@ async function gatherSigningStartImpl( optsSignOperation ) { optsSignOperation.errGathering = null; optsSignOperation.promiseCompleteGathering = new Promise( ( resolve, reject ) => { const iv = setInterval( function() { - const cntSuccess = 0 + optsSignOperation.arrSignResults.length; + const cntSuccess = optsSignOperation.arrSignResults.length; if( optsSignOperation.joGatheringTracker.nCountReceivedPrevious != optsSignOperation.joGatheringTracker.nCountReceived ) { if( log.verboseGet() >= log.verboseReversed().debug ) { @@ -1316,7 +1316,7 @@ async function gatherSigningStartImpl( optsSignOperation ) { " node(s)", optsSignOperation.jarrMessages, null ).catch( ( err ) => { - const cntSuccess = 0 + optsSignOperation.arrSignResults.length; + const cntSuccess = optsSignOperation.arrSignResults.length; if( log.verboseGet() >= log.verboseReversed().critical ) { const strErrorMessage = cc.error( "Problem(3) in BLS sign result handler, " + @@ -1350,7 +1350,7 @@ async function gatherSigningStartImpl( optsSignOperation ) { optsSignOperation.jarrMessages, null ).catch( ( err ) => { - const cntSuccess = 0 + optsSignOperation.arrSignResults.length; + const cntSuccess = optsSignOperation.arrSignResults.length; if( log.verboseGet() >= log.verboseReversed().critical ) { const strErrorMessage = cc.error( @@ -1425,7 +1425,7 @@ async function gatherSigningFinishImpl( optsSignOperation ) { optsSignOperation.jarrMessages, null ).catch( ( err ) => { - const cntSuccess = 0 + optsSignOperation.arrSignResults.length; + const cntSuccess = optsSignOperation.arrSignResults.length; if( log.verboseGet() >= log.verboseReversed().critical ) { const strErrorMessage = cc.error( "Problem(5) in BLS sign result handler, " + @@ -1462,7 +1462,7 @@ async function gatherSigningFinishImpl( optsSignOperation ) { JSON.stringify( optsSignOperation.joGatheringTracker ), optsSignOperation.jarrMessages, null ).catch( ( err ) => { - const cntSuccess = 0 + optsSignOperation.arrSignResults.length; + const cntSuccess = optsSignOperation.arrSignResults.length; if( log.verboseGet() >= log.verboseReversed().critical ) { const strErrorMessage = cc.error( "Problem(6) in BLS sign result handler, " + @@ -1598,7 +1598,7 @@ async function doSignProcessHandleCall( cc.notice( "#" ) + cc.bright( nZeroBasedNodeIndex ) + cc.debug( ":" ) + " "; try { - const cntSuccess = 0 + optsSignOperation.arrSignResults.length; + const cntSuccess = optsSignOperation.arrSignResults.length; if( cntSuccess > optsSignOperation.nCountOfBlsPartsToCollect ) { ++optsSignOperation.joGatheringTracker.nCountSkipped; if( log.verboseGet() >= log.verboseReversed().notice ) { @@ -1840,7 +1840,7 @@ async function doSignMessagesImpl( if( ! ( await prepareSignMessagesImpl( optsSignOperation ) ) ) return; for( let i = 0; i < optsSignOperation.jarrNodes.length; ++i ) { - const cntSuccess = 0 + optsSignOperation.arrSignResults.length; + const cntSuccess = optsSignOperation.arrSignResults.length; if( cntSuccess >= optsSignOperation.nCountOfBlsPartsToCollect ) { if( log.verboseGet() >= log.verboseReversed().trace ) { optsSignOperation.details.write( optsSignOperation.strLogPrefix + @@ -2097,7 +2097,7 @@ async function doSignU256OneImpl( i, optsSignU256 ) { const strLogPrefixA = cc.info( "BLS" ) + cc.debug( "/" ) + cc.notice( "#" ) + cc.bright( nZeroBasedNodeIndex ) + cc.debug( ":" ) + " "; try { - const cntSuccess = 0 + optsSignU256.arrSignResults.length; + const cntSuccess = optsSignU256.arrSignResults.length; if( cntSuccess > optsSignU256.nCountOfBlsPartsToCollect ) { ++optsSignU256.joGatheringTracker.nCountSkipped; if( log.verboseGet() >= log.verboseReversed().notice ) { @@ -2200,7 +2200,7 @@ async function doSignU256Gathering( optsSignU256 ) { const iv = setInterval( function() { if( optsSignU256.joGatheringTracker.nCountReceivedPrevious != optsSignU256.joGatheringTracker.nCountReceived ) { - const cntSuccess = 0 + optsSignU256.arrSignResults.length; + const cntSuccess = optsSignU256.arrSignResults.length; if( log.verboseGet() >= log.verboseReversed().debug ) { optsSignU256.details.write( cc.info( "BLS u256" ) + @@ -2217,7 +2217,7 @@ async function doSignU256Gathering( optsSignU256 ) { 0 + optsSignU256.joGatheringTracker.nCountReceived; } ++ optsSignU256.joGatheringTracker.nWaitIntervalStepsDone; - const cntSuccess = 0 + optsSignU256.arrSignResults.length; + const cntSuccess = optsSignU256.arrSignResults.length; if( cntSuccess >= optsSignU256.nCountOfBlsPartsToCollect ) { const strLogPrefixB = cc.info( "BLS u256" ) + cc.debug( "/" ) + cc.sunny( "Summary" ) + cc.debug( ":" ) + " "; From 0d8c958f7efdab7cfa74d99858bffc871e74ecc8 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 14 Nov 2023 18:00:19 +0000 Subject: [PATCH 26/29] ticket-885 error check added for skale_imaVerifyAndSign call result --- agent/bls.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/agent/bls.mjs b/agent/bls.mjs index feb21591f..f863b3593 100644 --- a/agent/bls.mjs +++ b/agent/bls.mjs @@ -1560,7 +1560,7 @@ async function doSignProcessHandleCall( cc.attention( optsSignOperation.sequenceId ) + "\n" ); } if( ( !joOut ) || typeof joOut != "object" || ( !( "result" in joOut ) ) || ( !joOut.result ) || - typeof joOut.result != "object" ) { + typeof joOut.result != "object" || "error" in joOut || joOut.error ) { ++optsSignOperation.joGatheringTracker.nCountErrors; const strErrorMessage = optsSignOperation.strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + @@ -2065,6 +2065,7 @@ async function doSignU256OneImpl( i, optsSignU256 ) { cc.j( joOut ) + "\n" ); } if( ( !joOut ) || typeof joOut != "object" || ( !( "result" in joOut ) ) || + "error" in joOut || joOut.error || ( !joOut.result ) || typeof joOut.result != "object" || ( !( "signature" in joOut.result ) ) || joOut.result.signature != "object" ) { From 006962c98bc99954ace2989b78bc1b459ad33234 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 14 Nov 2023 18:21:25 +0000 Subject: [PATCH 27/29] ticket-885 error check added for skale_imaVerifyAndSign call result --- agent/bls.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/bls.mjs b/agent/bls.mjs index f863b3593..d6a09f1b7 100644 --- a/agent/bls.mjs +++ b/agent/bls.mjs @@ -1560,7 +1560,7 @@ async function doSignProcessHandleCall( cc.attention( optsSignOperation.sequenceId ) + "\n" ); } if( ( !joOut ) || typeof joOut != "object" || ( !( "result" in joOut ) ) || ( !joOut.result ) || - typeof joOut.result != "object" || "error" in joOut || joOut.error ) { + typeof joOut.result != "object" || ( "error" in joOut && joOut.error ) ) { ++optsSignOperation.joGatheringTracker.nCountErrors; const strErrorMessage = optsSignOperation.strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + From 402be2a3d2ce731dcb83661d7e3475ee135dfa77 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Fri, 17 Nov 2023 11:41:34 +0000 Subject: [PATCH 28/29] Cbanged IMA refresh and SNB intervals --- agent/run.sh | 2 +- agent/state.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/run.sh b/agent/run.sh index e71c6a06f..cacf2dab7 100644 --- a/agent/run.sh +++ b/agent/run.sh @@ -112,7 +112,7 @@ BASE_OPTIONS="--gas-price-multiplier=$GAS_PRICE_MULTIPLIER \ --monitoring-port=$MONITORING_PORT \ --pwa \ --no-expose-pwa \ ---auto-exit=86400" +--auto-exit=3600" echo "Running loop cmd..." node "$DIR/main.mjs" --loop $BASE_OPTIONS diff --git a/agent/state.mjs b/agent/state.mjs index 49676cdec..e63dd1760 100644 --- a/agent/state.mjs +++ b/agent/state.mjs @@ -277,7 +277,7 @@ export function get() { "isEnabled": true, "bParallelModeRefreshSNB": true, // seconds to re-discover SKALE network, 0 to disable - "secondsToReDiscoverSkaleNetwork": 1 * 60 * 60, + "secondsToReDiscoverSkaleNetwork": 90 * 60, // 90 minutes "secondsToWaitForSkaleNetworkDiscovered": 5 * 60 }, From 631b5c8d1cd0755dc4428b6a60ca7305a3848227 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Fri, 17 Nov 2023 18:08:32 +0000 Subject: [PATCH 29/29] 1h SNB interval --- agent/state.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/state.mjs b/agent/state.mjs index e63dd1760..49676cdec 100644 --- a/agent/state.mjs +++ b/agent/state.mjs @@ -277,7 +277,7 @@ export function get() { "isEnabled": true, "bParallelModeRefreshSNB": true, // seconds to re-discover SKALE network, 0 to disable - "secondsToReDiscoverSkaleNetwork": 90 * 60, // 90 minutes + "secondsToReDiscoverSkaleNetwork": 1 * 60 * 60, "secondsToWaitForSkaleNetworkDiscovered": 5 * 60 },