From f9adb821f0799474d97c35a5de465457d9f13082 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Mon, 26 Sep 2022 18:02:32 +0100 Subject: [PATCH 01/23] JS-only IMA agent, early alpha version --- agent/cli.js | 24 ++++++++++- agent/main.js | 74 +++++++++++++++++++++++++++++++++ agent/utils.js | 31 +++++++++++++- npms/skale-observer/observer.js | 7 +++- npms/skale-owasp/owasp-util.js | 4 +- test/agent-test.js | 7 ++++ 6 files changed, 140 insertions(+), 7 deletions(-) diff --git a/agent/cli.js b/agent/cli.js index 91aab5b44..2f38fd9d4 100644 --- a/agent/cli.js +++ b/agent/cli.js @@ -387,7 +387,7 @@ function parse( joExternalHandlers, argv ) { console.log( soi + cc.debug( "--" ) + cc.bright( "bls-verify" ) + cc.sunny( "=" ) + cc.note( "path" ) + cc.debug( "..............." ) + cc.debug( "Optional parameter, specifies path to " ) + cc.note( "verify_bls" ) + cc.debug( " application." ) ); // console.log( cc.sunny( "MONITORING" ) + cc.info( " options:" ) ); - console.log( soi + cc.debug( "--" ) + cc.bright( "monitoring-port" ) + cc.sunny( "=" ) + cc.note( "number" ) + cc.debug( "........" ) + cc.notice( "Run " ) + cc.note( "monitoring web socket RPC server" ) + cc.notice( " on specified port. " ) + cc.debug( "By default monitoring server is " ) + cc.error( "disabled" ) + cc.notice( "." ) ); + console.log( soi + cc.debug( "--" ) + cc.bright( "monitoring-port" ) + cc.sunny( "=" ) + cc.note( "number" ) + cc.debug( "........" ) + cc.notice( "Run " ) + cc.note( "monitoring web socket RPC server" ) + cc.notice( " on specified port. " ) + cc.debug( "Specify " ) + cc.sunny( "0" ) + cc.debug( " to " ) + cc.error( "disable" ) + cc.notice( "." ) + cc.debug( " By default monitoring server is " ) + cc.error( "disabled" ) + cc.notice( "." ) ); // console.log( cc.sunny( "GAS REIMBURSEMENT" ) + cc.info( " options:" ) ); console.log( soi + cc.debug( "--" ) + cc.bright( "reimbursement-chain" ) + cc.sunny( "=" ) + cc.note( "name" ) + cc.debug( "......" ) + cc.notice( "Specifies chain name." ) ); @@ -406,6 +406,11 @@ function parse( joExternalHandlers, argv ) { console.log( soi + cc.debug( "--" ) + cc.bright( "enable-oracle" ) + cc.debug( "................." ) + cc.success( "Enable" ) + cc.notice( " call to " ) + cc.note( "Oracle" ) + cc.notice( " to compute " ) + cc.note( "gas price" ) + cc.notice( " for " ) + cc.attention( "gas reimbursement" ) + cc.notice( ". " ) + cc.debug( "Default mode" ) + cc.notice( "." ) ); console.log( soi + cc.debug( "--" ) + cc.bright( "disable-oracle" ) + cc.debug( "................" ) + cc.error( "Disable" ) + cc.notice( " call to " ) + cc.note( "Oracle" ) + cc.notice( " to compute " ) + cc.note( "gas price" ) + cc.notice( " for " ) + cc.attention( "gas reimbursement" ) + cc.notice( "." ) ); // + console.log( cc.sunny( "IMA JSON RPC SERVER" ) + cc.info( " options:" ) ); + console.log( soi + cc.debug( "--" ) + cc.bright( "json-rpc-port" ) + cc.sunny( "=" ) + cc.note( "number" ) + cc.debug( ".........." ) + cc.notice( "Run " ) + cc.note( "IMA JSON RPC server" ) + cc.notice( " on specified " ) + cc.note( "port" ) + cc.notice( "." ) + cc.debug( " Specify " ) + cc.sunny( "0" ) + cc.debug( " to " ) + cc.error( "disable" ) + cc.notice( "." ) + cc.debug( " Defaut is " ) + cc.sunny( "14999" ) + cc.notice( "." ) ); + console.log( soi + cc.debug( "--" ) + cc.bright( "cross-ima" ) + cc.debug( "....................." ) + cc.success( "Enable" ) + cc.notice( " calls to " ) + cc.note( "IMA JSON RPC servers" ) + cc.notice( " to compute " ) + cc.note( "BLS signature parts" ) + cc.notice( " and operation state inside time frames. " ) + cc.debug( "Default mode" ) + cc.notice( "." ) ); + console.log( soi + cc.debug( "--" ) + cc.bright( "no-cross-ima" ) + cc.debug( ".................." ) + cc.error( "Disable" ) + cc.notice( " calls to " ) + cc.note( "IMA JSON RPC servers" ) + cc.notice( " to compute " ) + cc.note( "BLS signature parts" ) + cc.notice( " and operation state inside time frames. " ) + cc.debug( "Use calls to " ) + cc.attention( "skaled" ) + cc.debug( " instead" ) + cc.notice( "." ) ); + // console.log( cc.sunny( "TEST" ) + cc.info( " options:" ) ); console.log( soi + cc.debug( "--" ) + cc.bright( "browse-s-chain" ) + cc.debug( "................" ) + cc.notice( "Download own " ) + cc.note( "S-Chain" ) + cc.notice( " network information." ) ); console.log( soi + cc.debug( "--" ) + cc.bright( "browse-skale-network" ) + cc.debug( ".........." ) + cc.notice( "Download entire " ) + cc.note( "SKALE network" ) + cc.notice( " description." ) ); @@ -1128,7 +1133,7 @@ function parse( joExternalHandlers, argv ) { continue; } if( joArg.name == "monitoring-port" ) { - owaspUtils.verifyArgumentIsIntegerIpPortNumber( joArg ); + owaspUtils.verifyArgumentIsIntegerIpPortNumber( joArg, true ); imaState.nMonitoringPort = owaspUtils.toInteger( joArg.value ); continue; } @@ -1186,6 +1191,19 @@ function parse( joExternalHandlers, argv ) { IMA.setEnabledOracle( false ); continue; } + if( joArg.name == "json-rpc-port" ) { + owaspUtils.verifyArgumentIsIntegerIpPortNumber( joArg, true ); + imaState.nJsonRpcPort = owaspUtils.toInteger( joArg.value ); + continue; + } + if( joArg.name == "cross-ima" ) { + imaState.isCrossImaBlsMode = true; + continue; + } + if( joArg.name == "no-cross-ima" ) { + imaState.isCrossImaBlsMode = false; + continue; + } if( joArg.name == "s2s-forward" ) { IMA.setForwardS2S(); continue; @@ -2248,6 +2266,8 @@ function ima_common_init() { log.write( cc.info( "SKALE network re-discovery interval is" ) + cc.debug( "..............." ) + ( imaState.s2s_opts.secondsToReDiscoverSkaleNetwork ? cc.info( imaState.s2s_opts.secondsToReDiscoverSkaleNetwork.toString() ) : cc.error( "disabled" ) ) + "\n" ); log.write( cc.info( "S<->S transfer mode is" ) + cc.debug( "..............................." ) + IMA.get_S2S_transfer_mode_description_colorized() + "\n" ); } // if( isPrintGathered ) + log.write( cc.info( "IMA JSON RPC server port is" ) + cc.debug( "...,,,,,,,,,,,............" ) + ( ( imaState.nJsonRpcPort > 0 ) ? cc.info( imaState.nJsonRpcPort ) : cc.error( "disabled" ) ) + "\n" ); + log.write( cc.info( "Cross-IMA mode is" ) + cc.debug( "...................................." ) + ( imaState.isCrossImaBlsMode ? cc.success( "enabled" ) : cc.error( "disabled" ) ) + "\n" ); } // // diff --git a/agent/main.js b/agent/main.js index 3c89d7563..3dcbcc324 100644 --- a/agent/main.js +++ b/agent/main.js @@ -281,6 +281,9 @@ global.imaState = { "secondsToReDiscoverSkaleNetwork": 1 * 60 * 60 // seconts to re-discover SKALE network, 0 to disable }, + "nJsonRpcPort": 14999, // 0 to disable + "isCrossImaBlsMode": true, + "arrActions": [] // array of actions to run }; @@ -2217,6 +2220,77 @@ if( imaState.nMonitoringPort > 0 ) { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +let g_ws_server_ima = null; + +if( imaState.nJsonRpcPort > 0 ) { + const strLogPrefix = cc.attention( "JSON RPC" ) + " " + cc.sunny( ">>" ) + " "; + if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) + log.write( strLogPrefix + cc.normal( "Will start JSON RPC WS server on port " ) + cc.info( imaState.nJsonRpcPort ) + "\n" ); + g_ws_server_ima = new ws.Server( { port: 0 + imaState.nJsonRpcPort } ); + g_ws_server_ima.on( "connection", function( ws_peer, req ) { + const ip = req.socket.remoteAddress; + if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) + log.write( strLogPrefix + cc.normal( "New connection from " ) + cc.info( ip ) + "\n" ); + ws_peer.on( "message", function( message ) { + const joAnswer = { + method: null, + id: null, + error: null + }; + try { + const joMessage = JSON.parse( message ); + if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) + log.write( strLogPrefix + cc.normal( "Message from " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joMessage ) + "\n" ); + if( ! ( "method" in joMessage ) ) + throw new Error( "\"method\" field was not specified" ); + joAnswer.method = joMessage.method; + if( ! ( "id" in joMessage ) ) + throw new Error( "\"id\" field was not specified" ); + joAnswer.id = joMessage.id; + switch ( joMessage.method ) { + case "echo": + case "ping": + // call: { "id": 1, "method": "echo" } + // answer: { "id": 1, "method": "echo", "error": null } + // call: { "id": 1, "method": "ping" } + // answer: { "id": 1, "method": "ping", "error": null } + break; + case "get_schain_network_info": + // call: { "id": 1, "method": "get_schain_network_info" } + // answer: { "id": 1, "method": "get_schain_network_info", "error": null, "schain_network_info": ... } + joAnswer.schain_network_info = imaState.joSChainNetworkInfo; + break; + default: + throw new Error( "Unknown method name \"" + joMessage.method + "\" was specified" ); + } // switch( joMessage.method ) + } catch ( err ) { + if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { + log.write( strLogPrefix + + cc.error( "Bad message from " ) + cc.info( ip ) + cc.error( ": " ) + cc.warning( message ) + + cc.error( ", error is: " ) + cc.warning( err ) + "\n" + ); + } + } + try { + if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) + log.write( strLogPrefix + cc.normal( "Answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); + ws_peer.send( JSON.stringify( joAnswer ) ); + } catch ( err ) { + if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { + log.write( strLogPrefix + + cc.error( "Failed to sent answer to " ) + cc.info( ip ) + + cc.error( ", error is: " ) + cc.warning( err ) + "\n" + ); + } + } + } ); + // ws_peer.send( "something" ); + } ); +} // if( imaState.nJsonRpcPort > 0 ) + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + async function do_the_job() { const strLogPrefix = cc.info( "Job 1:" ) + " "; let idxAction = 0; diff --git a/agent/utils.js b/agent/utils.js index e9e7201e5..4c34b11a3 100644 --- a/agent/utils.js +++ b/agent/utils.js @@ -397,6 +397,34 @@ function compose_schain_node_url( joNode ) { return ""; } +function compose_ima_agent_node_url( joNode ) { + let nPort = -1; + if( "imaAgentRpcPort" in joNode && typeof joNode.imaAgentRpcPort === "number" && joNode.imaAgentRpcPort > 0 ) + nPort = joNode.imaAgentRpcPort; + // PROPOSAL = 0 + // CATCHUP = 1 + // WS_JSON = 2 + // HTTP_JSON = 3 + // BINARY_CONSENSUS = 4 + // ZMQ_BROADCAST = 5 + // IMA_MONITORING = 6 + // WSS_JSON = 7 + // HTTPS_JSON = 8 + // INFO_HTTP_JSON = 9 + // IMA_AGENT_JSON = 10 + if( nPort < 0 && "httpRpcPort" in joNode && typeof joNode.httpRpcPort === "number" && joNode.httpRpcPort > 0 ) + nPort = joNode.httpRpcPort - 3 + 10; + if( nPort < 0 && "wsRpcPort" in joNode && typeof joNode.wsRpcPort === "number" && joNode.wsRpcPort > 0 ) + nPort = joNode.wsRpcPort - 2 + 10; + if( nPort < 0 && "httpsRpcPort" in joNode && typeof joNode.httpsRpcPort === "number" && joNode.httpsRpcPort > 0 ) + nPort = joNode.httpsRpcPort - 8 + 10; + if( nPort < 0 && "wssRpcPort" in joNode && typeof joNode.wssRpcPort === "number" && joNode.wssRpcPort > 0 ) + nPort = joNode.wssRpcPort - 7 + 10; + if( nPort > 0 ) + return "ws://" + joNode.ip + ":" + joNode.imaAgentRpcPort; + return ""; +} + //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// @@ -433,5 +461,6 @@ module.exports = { check_key_exist_in_abi: check_key_exist_in_abi, check_keys_exist_in_abi: check_keys_exist_in_abi, // - compose_schain_node_url: compose_schain_node_url + compose_schain_node_url: compose_schain_node_url, + compose_ima_agent_node_url: compose_ima_agent_node_url }; // module.exports diff --git a/npms/skale-observer/observer.js b/npms/skale-observer/observer.js index 21b702d86..62fb0faf0 100644 --- a/npms/skale-observer/observer.js +++ b/npms/skale-observer/observer.js @@ -101,6 +101,7 @@ function compose_endpoints( jo_schain, node_dict, endpoint_type ) { node_dict["ws_endpoint_" + endpoint_type] = "ws://" + node_dict[endpoint_type] + ":" + jo_schain.data.computed.ports.wsRpcPort; node_dict["wss_endpoint_" + endpoint_type] = "wss://" + node_dict[endpoint_type] + ":" + jo_schain.data.computed.ports.wssRpcPort; node_dict["info_http_endpoint_" + endpoint_type] = "http://" + node_dict[endpoint_type] + ":" + jo_schain.data.computed.ports.infoHttpRpcPort; + node_dict["ima_agent_endpoint_" + endpoint_type] = "http://" + node_dict[endpoint_type] + ":" + jo_schain.data.computed.ports.imaAgentRpcPort; } const SkaledPorts = { @@ -113,7 +114,8 @@ const SkaledPorts = { IMA_MONITORING: 6, WSS_JSON: 7, HTTPS_JSON: 8, - INFO_HTTP_JSON: 9 + INFO_HTTP_JSON: 9, + IMA_AGENT_JSON: 10 }; function calc_ports( jo_schain, schain_base_port ) { @@ -123,7 +125,8 @@ function calc_ports( jo_schain, schain_base_port ) { httpsRpcPort: schain_base_port + SkaledPorts.HTTPS_JSON, wsRpcPort: schain_base_port + SkaledPorts.WS_JSON, wssRpcPort: schain_base_port + SkaledPorts.WSS_JSON, - infoHttpRpcPort: schain_base_port + SkaledPorts.INFO_HTTP_JSON + infoHttpRpcPort: schain_base_port + SkaledPorts.INFO_HTTP_JSON, + imaAgentRpcPort: schain_base_port + SkaledPorts.IMA_AGENT_JSON }; } diff --git a/npms/skale-owasp/owasp-util.js b/npms/skale-owasp/owasp-util.js index c7e51d941..6e2e7cd92 100644 --- a/npms/skale-owasp/owasp-util.js +++ b/npms/skale-owasp/owasp-util.js @@ -285,12 +285,12 @@ function verifyArgumentIsInteger( joArg ) { } } -function verifyArgumentIsIntegerIpPortNumber( joArg ) { +function verifyArgumentIsIntegerIpPortNumber( joArg, isEnableZero ) { try { verifyArgumentIsInteger( joArg ); if( joArg.value < 0 ) throw new Error( "Port number " + joArg.value + " cannot be negative" ); - if( joArg.value < 1 ) + if( ( !isEnableZero ) && joArg.value < 1 ) throw new Error( "Port number " + joArg.value + " too small" ); if( joArg.value > 65535 ) throw new Error( "Port number " + joArg.value + " too big" ); diff --git a/test/agent-test.js b/test/agent-test.js index 2ff55e927..810635e92 100644 --- a/test/agent-test.js +++ b/test/agent-test.js @@ -226,6 +226,9 @@ global.imaState = { "secondsToReDiscoverSkaleNetwork": 10 * 60 // seconts to re-discover SKALE network, 0 to disable }, + "nJsonRpcPort": 14999, // 0 to disable + "isCrossImaBlsMode": true, + "arrActions": [] // array of actions to run }; @@ -748,6 +751,10 @@ describe( "Agent Utils Module", function() { assert.equal( imaUtils.compose_schain_node_url( { ip6: "::1", wssRpcPort6: 3456 } ), "wss://[::1]:3456" ); } ); + it( "Compose IMA Agent URL", function() { + assert.equal( imaUtils.compose_ima_agent_node_url( { ip: "127.0.0.1", httpRpcPort: 14999 } ), "http://127.0.0.1:14999" ); + } ); + } ); describe( "Byte array manipulation helpers", function() { From da465524f4fc4f196e4e5d108e68f3951eb9c615 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 27 Sep 2022 19:52:27 +0100 Subject: [PATCH 02/23] transient commit, working on JS only IMA agent --- agent/bls.js | 98 +++++++++++++++++++++++++++++++++++++++++++++----- agent/cli.js | 6 ++-- agent/main.js | 22 +++++++----- agent/utils.js | 2 +- 4 files changed, 107 insertions(+), 21 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 187138a33..497775ba5 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -30,6 +30,7 @@ const child_process = require( "child_process" ); const shell = require( "shelljs" ); const { Keccak } = require( "sha3" ); +const { cc } = require( "./utils" ); function init() { owaspUtils.owaspAddUsageRef(); @@ -811,7 +812,10 @@ async function do_sign_messages_impl( fn ) { let bHaveResultReportCalled = false; - const strLogPrefix = cc.bright( strDirection ) + " " + cc.info( "Sign msgs:" ) + " "; + const strLogPrefix = + cc.bright( strDirection ) + " " + cc.info( "Sign msgs via " ) + + cc.attention( imaState.isCrossImaBlsMode ? "IMA agent" : "skaled" ) + + cc.info( ":" ) + " "; const joGatheringTracker = { nCountReceived: 0, // including errors nCountErrors: 0, @@ -913,7 +917,9 @@ async function do_sign_messages_impl( break; } const joNode = jarrNodes[i]; - const strNodeURL = imaUtils.compose_schain_node_url( joNode ); + const strNodeURL = imaState.isCrossImaBlsMode + ? imaUtils.compose_ima_agent_node_url( joNode ) + : imaUtils.compose_schain_node_url( joNode ); const strNodeDescColorized = cc.u( strNodeURL ) + " " + cc.normal( "(" ) + cc.bright( i ) + cc.normal( "/" ) + cc.bright( jarrNodes.length ) + cc.normal( ", ID " ) + cc.info( joNode.nodeID ) + cc.normal( ")" ) + cc.normal( ", " ) + cc.notice( "sequence ID" ) + cc.normal( " is " ) + cc.attention( sequence_id ); @@ -925,7 +931,7 @@ async function do_sign_messages_impl( const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call was not created, error: " ) + cc.warning( err ) + + cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( err.toString() ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -986,7 +992,7 @@ async function do_sign_messages_impl( const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call reported error: " ) + cc.warning( err ) + + cc.error( " failed, RPC call reported error: " ) + cc.warning( err.toString() ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -1229,7 +1235,7 @@ async function do_sign_messages_impl( bHaveResultReportCalled = true; await fn( "Failed to gather BLS signatures in " + jarrNodes.length + " node(s), trakcer data is: " + - JSON.stringify( joGatheringTracker ) + ", error: " + errGathering.toString(), + JSON.stringify( joGatheringTracker ) + ", error is: " + errGathering.toString(), jarrMessages, null ).catch( ( err ) => { @@ -1255,7 +1261,7 @@ async function do_sign_messages_impl( const strErrorMessage = cc.error( "Problem(6) in BLS sign result handler, not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error details: " ) + - cc.warning( err ) + "\n"; + cc.warning( err.toString() ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); details.exposeDetailsTo( log, strGatheredDetailsName, false ); @@ -1397,7 +1403,7 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call was not created, error: " ) + cc.warning( err ) + "\n"; + cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( err.toString() ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); return; @@ -1418,7 +1424,7 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call reported error: " ) + cc.warning( err ) + "\n"; + cc.error( " failed, RPC call reported error: " ) + cc.warning( err.toString() ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); return; @@ -1627,10 +1633,84 @@ async function do_sign_u256( u256, details, fn ) { details.write( strLogPrefix + cc.debug( "Completed signing u256 procedure " ) + "\n" ); } +async function handle_skale_call_via_redirect( joCallData ) { + const sequence_id = owaspUtils.remove_starting_0x( get_w3().utils.soliditySha3( log.generate_timestamp_string( null, false ) ) ); + const strLogPrefix = ""; + const strNodeURL = imaState.strURL_s_chain; + const rpcCallOpts = null; + let joRetVal = { }; + const details = log.createMemoryStream( true ); + let isSuccess = false; + try { + await rpcCall.create( strNodeURL, rpcCallOpts, async function( joCall, err ) { + if( err ) { + const strErrorMessage = + strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " JSON RPC call to S-Chain failed, RPC call was not created, error is: " ) + cc.warning( err.toString() ) + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + throw new Error( "JSON RPC call to S-Chain failed, RPC call was not created, error is: " + err.toString() ); + } + details.write( strLogPrefix + cc.debug( "Will invoke " ) + cc.info( "S-Chain" ) + cc.debug( " with call data " ) + cc.j( joCallData ) + "\n" ); + await joCall.call( joCallData, async function( joIn, joOut, err ) { + if( err ) { + const strErrorMessage = + strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " JSON RPC call to S-Chain failed, RPC call reported error: " ) + cc.warning( err.toString() ) + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + throw new Error( "JSON RPC call to S-Chain failed, RPC call reported error: " + err.toString() ); + } + details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "S-Chain" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); + if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { + let strThrowMessage = ""; + if( "error" in joOut && "message" in joOut.error ) { + const strErrorMessage = + strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + + cc.error( "S-Chain reported wallet error: " ) + cc.warning( joOut.error.message ) + + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + strThrowMessage = "S-Chain reported wallet error: " + joOut.error.message + ", sequence ID is " + sequence_id; + } else { + const strErrorMessage = + strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + + cc.error( "JSON RPC call to S-Chain failed with " ) + cc.warning( "unknown wallet error" ) + + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + strThrowMessage = "JSON RPC call to S-Chain failed with \"unknown wallet error\", sequence ID is " + sequence_id; + } + throw new Error( strThrowMessage ); + } + isSuccess = true; + joRetVal = joOut; // joOut.result + } ); // joCall.call ... + } ); // rpcCall.create ... + } catch ( err ) { + isSuccess = false; + const strError = err.toString(); + joRetVal.error = strError; + const strErrorMessage = + strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + + cc.error( "JSON RPC call finished with error: " ) + cc.warning( strError ) + + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + } + details.exposeDetailsTo( log, "handle_skale_call_via_redirect()", isSuccess ); + details.close(); + return joRetVal; +} + module.exports = { init: init, do_sign_messages_m2s: do_sign_messages_m2s, do_sign_messages_s2m: do_sign_messages_s2m, do_sign_messages_s2s: do_sign_messages_s2s, - do_sign_u256: do_sign_u256 + do_sign_u256: do_sign_u256, + handle_skale_imaVerifyAndSign: handle_skale_call_via_redirect, + handle_skale_imaBSU256: handle_skale_call_via_redirect }; // module.exports diff --git a/agent/cli.js b/agent/cli.js index 9b2776da3..2fa41a80b 100644 --- a/agent/cli.js +++ b/agent/cli.js @@ -407,9 +407,9 @@ function parse( joExternalHandlers, argv ) { console.log( soi + cc.debug( "--" ) + cc.bright( "disable-oracle" ) + cc.debug( "................" ) + cc.error( "Disable" ) + cc.notice( " call to " ) + cc.note( "Oracle" ) + cc.notice( " to compute " ) + cc.note( "gas price" ) + cc.notice( " for " ) + cc.attention( "gas reimbursement" ) + cc.notice( "." ) ); // console.log( cc.sunny( "IMA JSON RPC SERVER" ) + cc.info( " options:" ) ); - console.log( soi + cc.debug( "--" ) + cc.bright( "json-rpc-port" ) + cc.sunny( "=" ) + cc.note( "number" ) + cc.debug( ".........." ) + cc.notice( "Run " ) + cc.note( "IMA JSON RPC server" ) + cc.notice( " on specified " ) + cc.note( "port" ) + cc.notice( "." ) + cc.debug( " Specify " ) + cc.sunny( "0" ) + cc.debug( " to " ) + cc.error( "disable" ) + cc.notice( "." ) + cc.debug( " Defaut is " ) + cc.sunny( "14999" ) + cc.notice( "." ) ); - console.log( soi + cc.debug( "--" ) + cc.bright( "cross-ima" ) + cc.debug( "....................." ) + cc.success( "Enable" ) + cc.notice( " calls to " ) + cc.note( "IMA JSON RPC servers" ) + cc.notice( " to compute " ) + cc.note( "BLS signature parts" ) + cc.notice( " and operation state inside time frames. " ) + cc.debug( "Default mode" ) + cc.notice( "." ) ); - console.log( soi + cc.debug( "--" ) + cc.bright( "no-cross-ima" ) + cc.debug( ".................." ) + cc.error( "Disable" ) + cc.notice( " calls to " ) + cc.note( "IMA JSON RPC servers" ) + cc.notice( " to compute " ) + cc.note( "BLS signature parts" ) + cc.notice( " and operation state inside time frames. " ) + cc.debug( "Use calls to " ) + cc.attention( "skaled" ) + cc.debug( " instead" ) + cc.notice( "." ) ); + console.log( soi + cc.debug( "--" ) + cc.bright( "json-rpc-port" ) + cc.sunny( "=" ) + cc.note( "number" ) + cc.debug( ".........." ) + cc.notice( "Run " ) + cc.note( "IMA JSON RPC server" ) + cc.notice( " on specified " ) + cc.note( "port" ) + cc.notice( "." ) + cc.debug( " Specify " ) + cc.sunny( "0" ) + cc.debug( " to " ) + cc.error( "disable" ) + cc.notice( "." ) + cc.debug( " Defaut is " ) + cc.sunny( "0" ) + cc.notice( "." ) ); + console.log( soi + cc.debug( "--" ) + cc.bright( "cross-ima" ) + cc.debug( "....................." ) + cc.success( "Enable" ) + cc.notice( " calls to " ) + cc.note( "IMA JSON RPC servers" ) + cc.notice( " to compute " ) + cc.note( "BLS signature parts" ) + cc.notice( " and operation state inside time frames." ) + cc.debug( "Use calls to " ) + cc.attention( "IMA Agent" ) + cc.notice( "." ) ); + console.log( soi + cc.debug( "--" ) + cc.bright( "no-cross-ima" ) + cc.debug( ".................." ) + cc.error( "Disable" ) + cc.notice( " calls to " ) + cc.note( "IMA JSON RPC servers" ) + cc.notice( " to compute " ) + cc.note( "BLS signature parts" ) + cc.notice( " and operation state inside time frames. " ) + cc.debug( "Use calls to " ) + cc.attention( "skaled" ) + cc.notice( "." ) + cc.debug( " Default mode" ) + cc.notice( "." ) ); // console.log( cc.sunny( "TEST" ) + cc.info( " options:" ) ); console.log( soi + cc.debug( "--" ) + cc.bright( "browse-s-chain" ) + cc.debug( "................" ) + cc.notice( "Download own " ) + cc.note( "S-Chain" ) + cc.notice( " network information." ) ); diff --git a/agent/main.js b/agent/main.js index 9ece66fd7..4941f1183 100644 --- a/agent/main.js +++ b/agent/main.js @@ -281,8 +281,8 @@ global.imaState = { "secondsToReDiscoverSkaleNetwork": 1 * 60 * 60 // seconts to re-discover SKALE network, 0 to disable }, - "nJsonRpcPort": 14999, // 0 to disable - "isCrossImaBlsMode": true, + "nJsonRpcPort": 0, // 0 to disable + "isCrossImaBlsMode": false, "arrActions": [] // array of actions to run }; @@ -2231,8 +2231,8 @@ if( imaState.nJsonRpcPort > 0 ) { const ip = req.socket.remoteAddress; if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) log.write( strLogPrefix + cc.normal( "New connection from " ) + cc.info( ip ) + "\n" ); - ws_peer.on( "message", function( message ) { - const joAnswer = { + ws_peer.on( "message", async function( message ) { + let joAnswer = { method: null, id: null, error: null @@ -2255,10 +2255,16 @@ if( imaState.nJsonRpcPort > 0 ) { // call: { "id": 1, "method": "ping" } // answer: { "id": 1, "method": "ping", "error": null } break; - case "get_schain_network_info": - // call: { "id": 1, "method": "get_schain_network_info" } - // answer: { "id": 1, "method": "get_schain_network_info", "error": null, "schain_network_info": ... } - joAnswer.schain_network_info = imaState.joSChainNetworkInfo; + // case "get_schain_network_info": + // // call: { "id": 1, "method": "get_schain_network_info" } + // // answer: { "id": 1, "method": "get_schain_network_info", "error": null, "schain_network_info": ... } + // joAnswer.schain_network_info = imaState.joSChainNetworkInfo; + // break; + case "skale_imaVerifyAndSign": + joAnswer = await imaBLS.handle_skale_imaVerifyAndSign( joMessage ); + break; + case "skale_imaBSU256": + joAnswer = await imaBLS.handle_skale_imaBSU256( joMessage ); break; default: throw new Error( "Unknown method name \"" + joMessage.method + "\" was specified" ); diff --git a/agent/utils.js b/agent/utils.js index 4c34b11a3..aba3ab8dd 100644 --- a/agent/utils.js +++ b/agent/utils.js @@ -421,7 +421,7 @@ function compose_ima_agent_node_url( joNode ) { if( nPort < 0 && "wssRpcPort" in joNode && typeof joNode.wssRpcPort === "number" && joNode.wssRpcPort > 0 ) nPort = joNode.wssRpcPort - 7 + 10; if( nPort > 0 ) - return "ws://" + joNode.ip + ":" + joNode.imaAgentRpcPort; + return "ws://" + joNode.ip + ":" + nPort; return ""; } From 8c8e25fac06be3db8cc428b47d7f03a729bd49f0 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Wed, 28 Sep 2022 19:38:34 +0100 Subject: [PATCH 03/23] transient commit, working on JS only IMA agent --- agent/bls.js | 159 ++++++++++++++++++++++++++++++++++++++++++++++---- agent/main.js | 12 ++-- 2 files changed, 154 insertions(+), 17 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 497775ba5..d3dc9aad4 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -1010,7 +1010,7 @@ async function do_sign_messages_impl( "\n" ); if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { ++joGatheringTracker.nCountErrors; - if( "error" in joOut && "message" in joOut.error ) { + if( ( "error" in joOut ) && ( typeof joOut.error == "object" ) && ( "message" in joOut.error ) ) { const strErrorMessage = strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + cc.error( "S-Chain node " ) + strNodeDescColorized + @@ -1436,7 +1436,7 @@ async function do_sign_u256( u256, details, fn ) { "\n" ); if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { ++joGatheringTracker.nCountErrors; - if( "error" in joOut && "message" in joOut.error ) { + if( ( "error" in joOut ) && ( typeof joOut.error == "object" ) && ( "message" in joOut.error ) ) { const strErrorMessage = strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + cc.error( "S-Chain node " ) + strNodeDescColorized + @@ -1664,7 +1664,7 @@ async function handle_skale_call_via_redirect( joCallData ) { details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "S-Chain" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { let strThrowMessage = ""; - if( "error" in joOut && "message" in joOut.error ) { + if( ( "error" in joOut ) && ( typeof joOut.error == "object" ) && ( "message" in joOut.error ) ) { const strErrorMessage = strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + cc.error( "S-Chain reported wallet error: " ) + cc.warning( joOut.error.message ) + @@ -1672,21 +1672,101 @@ async function handle_skale_call_via_redirect( joCallData ) { "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - strThrowMessage = "S-Chain reported wallet error: " + joOut.error.message + ", sequence ID is " + sequence_id; - } else { + details.write( strErrorMessage ); + strThrowMessage = "JSON RPC call to S-Chain failed with \"unknown wallet error\", sequence ID is " + sequence_id; + } + throw new Error( strThrowMessage ); + } + isSuccess = true; + joRetVal = joOut; // joOut.result + } ); // joCall.call ... + } ); // rpcCall.create ... + } catch ( err ) { + isSuccess = false; + const strError = err.toString(); + joRetVal.error = strError; + const strErrorMessage = + strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + + cc.error( "JSON RPC call finished with error: " ) + cc.warning( strError ) + + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + } + details.exposeDetailsTo( log, "handle_skale_call_via_redirect()", isSuccess ); + details.close(); + return joRetVal; +} + +async function handle_skale_imaVerifyAndSign( joCallData ) { + const strLogPrefix = ""; + const details = log.createMemoryStream( true ); + let isSuccess = false; + try { + // + const nIdxCurrentMsgBlockStart = joCallData.params.startMessageIdx; + const strFromChainName = jojoRetVal.CallData.params.srcChainName; + const jarrMessages = joCallData.params.messages; + const nThreshold = discover_bls_threshold( imaState.joSChainNetworkInfo ); + const nParticipants = discover_bls_participants( imaState.joSChainNetworkInfo ); + details.write( strLogPrefix + cc.debug( "Discovered BLS threshold is " ) + cc.info( nThreshold ) + cc.debug( "." ) + "\n" ); + details.write( strLogPrefix + cc.debug( "Discovered number of BLS participants is " ) + cc.info( nParticipants ) + cc.debug( "." ) + "\n" ); + const strMessageHash = owaspUtils.remove_starting_0x( keccak256_message( jarrMessages, nIdxCurrentMsgBlockStart, strFromChainName ) ); + details.write( strLogPrefix + cc.debug( "Message hash to sign is " ) + cc.info( strMessageHash ) + "\n" ); + // + const strURL = imaState.joAccount_s_chain.strSgxURL; // TO-FIX: verify we have SGX connection parameters + const keyShareName = imaState.joAccount_s_chain.strSgxKeyName; // TO-FIX: verify we have SGX connection parameters + const signerIndex = imaState.joAccount_s_chain.nNodeNumber; + await rpcCall.create( strURL, rpcCallOpts, async function( joCall, err ) { + if( err ) { + const strErrorMessage = + strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " JSON RPC call to SGX failed, RPC call was not created, error is: " ) + cc.warning( err.toString() ) + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + throw new Error( "JSON RPC call to SGX failed, RPC call was not created, error is: " + err.toString() ); + } + const joCallSGX = { + method: "blsSignMessageHash", + // type: "BLSSignReq", + params: { + keyShareName: keyShareName, + messageHash: strMessageHash, + n: nParticipants, + t: nThreshold, + signerIndex: signerIndex + 1 // 1-based + } + }; + details.write( strLogPrefix + cc.debug( "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 strErrorMessage = + strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " JSON RPC call to SGX failed, RPC call reported error: " ) + cc.warning( err.toString() ) + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + throw new Error( "JSON RPC call to SGX failed, RPC call reported error: " + err.toString() ); + } + details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "SGX" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); + if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { + let strThrowMessage = ""; + if( ( "error" in joOut ) && ( typeof joOut.error == "object" ) && ( "message" in joOut.error ) ) { const strErrorMessage = strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + - cc.error( "JSON RPC call to S-Chain failed with " ) + cc.warning( "unknown wallet error" ) + + cc.error( "SGX reported wallet error: " ) + cc.warning( joOut.error.message ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - strThrowMessage = "JSON RPC call to S-Chain failed with \"unknown wallet error\", sequence ID is " + sequence_id; + details.write( strErrorMessage ); + strThrowMessage = "JSON RPC call to SGX failed with \"unknown wallet error\", sequence ID is " + sequence_id; } throw new Error( strThrowMessage ); } isSuccess = true; - joRetVal = joOut; // joOut.result + const joSignResult = ( "result" in joOut ) ? joOut.result : joOut; + joRetVal.signResult = joSignResult; + if( "qa" in joCallData ) + joRetVal.qa = joCallData.qa; } ); // joCall.call ... } ); // rpcCall.create ... } catch ( err ) { @@ -1695,22 +1775,79 @@ async function handle_skale_call_via_redirect( joCallData ) { joRetVal.error = strError; const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + - cc.error( "JSON RPC call finished with error: " ) + cc.warning( strError ) + + cc.error( "IMA messages verifier/signer error: " ) + cc.warning( strError ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); } - details.exposeDetailsTo( log, "handle_skale_call_via_redirect()", isSuccess ); + details.exposeDetailsTo( log, "IMA messages verifier/signer", isSuccess ); details.close(); return joRetVal; } +/* + +2022-09-28 12:46:22.936: JSON RPC: <<< message from ::ffff:127.0.0.1: +{ + "method":"skale_imaVerifyAndSign", + "params":{ + "direction":"S2S", + "startMessageIdx":11, + "dstChainName":"Bob1000", + "srcChainName":"Bob1001", + "messages":[ + { + "sender":"0xD2aaA00900000000000000000000000000000000", + "destinationContract":"0xD2aaA00900000000000000000000000000000000", + "data":"0x0000000000000000000000000000000000000000000000000000000000000009000000000000000000000000dedd5a997604ade31542e8a3d6aaa280e348aef10000000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003e8", + "savedBlockNumberForOptimizations":448 + } + ], + "qa":{ + "skaled_no":0, + "sequence_id":"9cef78ef82228cce2e4ed4bee0c485acca0f368c1d7ae94aa235d26c0b778db3", + "ts":"2022-09-28 12:46:22.934" + } + }, + "jsonrpc":"2.0", + "id":3937967578497932 +} + +--- --- --- --- --- GATHERED SUCCESS DETAILS FOR LATEST( (handle_skale_call_via_redirect()) action (BEGIN) --- --- ------ --- + +2022-09-28 12:46:22.938: Will invoke S-Chain with call data { method: "skale_imaVerifyAndSign", params: { direction: "S2S", startMessageIdx: 11, dstChainName: "Bob1000", srcChainName: "Bob1001", messages: [{ sender: "0xD2aaA00900000000000000000000000000000000", destinationContract: "0xD2aaA00900000000000000000000000000000000", data: "0x0000000000000000000000000000000000000000000000000000000000000009000000000000000000000000dedd5a997604ade31542e8a3d6aaa280e348aef10000000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003e8", savedBlockNumberForOptimizations: 448}], qa: { skaled_no: 0, sequence_id: "9cef78ef82228cce2e4ed4bee0c485acca0f368c1d7ae94aa235d26c0b778db3", ts: "2022-09-28 12:46:22.934"}}, jsonrpc: "2.0", id: 3937967578497932} +2022-09-28 12:46:23.052: Call to S-Chain done, answer is: { id: 3937967578497932, jsonrpc: "2.0", result: { qa: { sequence_id: "9cef78ef82228cce2e4ed4bee0c485acca0f368c1d7ae94aa235d26c0b778db3", skaled_no: 0, ts: "2022-09-28 12:46:22.934"}, signResult: { errorMessage: "", signatureShare: "17478565975047244907103895167228083798921988971796902124088684491074746004285:15031994568930252855707831149520060050211430984917981813828217031708710584295:16774908233857298972544743177670408960120003931859857609581436687829921077359:0", status: 0, type: "BLSSignRsp"}}} + +--- --- --- --- --- GATHERED SUCCESS DETAILS FOR LATEST( (handle_skale_call_via_redirect()) action (END) --- --- --- --- --- + +2022-09-28 12:46:23.053: JSON RPC: >>> answer to ::ffff:127.0.0.1: +{ + "id":3937967578497932, + "jsonrpc":"2.0", + "result":{ + "qa":{ + "sequence_id":"9cef78ef82228cce2e4ed4bee0c485acca0f368c1d7ae94aa235d26c0b778db3", + "skaled_no":0, + "ts":"2022-09-28 12:46:22.934" + }, + "signResult":{ + "errorMessage":"", + "signatureShare":"17478565975047244907103895167228083798921988971796902124088684491074746004285:15031994568930252855707831149520060050211430984917981813828217031708710584295:16774908233857298972544743177670408960120003931859857609581436687829921077359:0", + "status":0, + "type":"BLSSignRsp" + } + } +} + + */ + module.exports = { init: init, do_sign_messages_m2s: do_sign_messages_m2s, do_sign_messages_s2m: do_sign_messages_s2m, do_sign_messages_s2s: do_sign_messages_s2s, do_sign_u256: do_sign_u256, - handle_skale_imaVerifyAndSign: handle_skale_call_via_redirect, + // handle_skale_imaVerifyAndSign: handle_skale_call_via_redirect, + handle_skale_imaVerifyAndSign: handle_skale_imaVerifyAndSign, handle_skale_imaBSU256: handle_skale_call_via_redirect }; // module.exports diff --git a/agent/main.js b/agent/main.js index 4941f1183..7a81f5456 100644 --- a/agent/main.js +++ b/agent/main.js @@ -2094,7 +2094,7 @@ async function discover_s_chain_network( fnAfter, isSilent, joPrevSChainNetworkI let g_ws_server_monitoring = null; if( imaState.nMonitoringPort > 0 ) { - const strLogPrefix = cc.attention( "Monitoring" ) + " " + cc.sunny( ">>" ) + " "; + const strLogPrefix = cc.attention( "Monitoring:" ) + " "; if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) log.write( strLogPrefix + cc.normal( "Will start monitoring WS server on port " ) + cc.info( imaState.nMonitoringPort ) + "\n" ); g_ws_server_monitoring = new ws.Server( { port: 0 + imaState.nMonitoringPort } ); @@ -2111,7 +2111,7 @@ if( imaState.nMonitoringPort > 0 ) { try { const joMessage = JSON.parse( message ); if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) - log.write( strLogPrefix + cc.normal( "Message from " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joMessage ) + "\n" ); + log.write( strLogPrefix + cc.sunny( "<<<" ) + " " + cc.normal( "message from " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joMessage ) + "\n" ); if( ! ( "method" in joMessage ) ) throw new Error( "\"method\" field was not specified" ); joAnswer.method = joMessage.method; @@ -2202,7 +2202,7 @@ if( imaState.nMonitoringPort > 0 ) { } try { if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) - log.write( strLogPrefix + cc.normal( "Answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); + log.write( strLogPrefix + cc.sunny( ">>>" ) + " " + cc.normal( "answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); ws_peer.send( JSON.stringify( joAnswer ) ); } catch ( err ) { if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { @@ -2223,7 +2223,7 @@ if( imaState.nMonitoringPort > 0 ) { let g_ws_server_ima = null; if( imaState.nJsonRpcPort > 0 ) { - const strLogPrefix = cc.attention( "JSON RPC" ) + " " + cc.sunny( ">>" ) + " "; + const strLogPrefix = cc.attention( "JSON RPC:" ) + " "; if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) log.write( strLogPrefix + cc.normal( "Will start JSON RPC WS server on port " ) + cc.info( imaState.nJsonRpcPort ) + "\n" ); g_ws_server_ima = new ws.Server( { port: 0 + imaState.nJsonRpcPort } ); @@ -2240,7 +2240,7 @@ if( imaState.nJsonRpcPort > 0 ) { try { const joMessage = JSON.parse( message ); if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) - log.write( strLogPrefix + cc.normal( "Message from " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joMessage ) + "\n" ); + log.write( strLogPrefix + cc.sunny( "<<<" ) + " " + cc.normal( "message from " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joMessage ) + "\n" ); if( ! ( "method" in joMessage ) ) throw new Error( "\"method\" field was not specified" ); joAnswer.method = joMessage.method; @@ -2279,7 +2279,7 @@ if( imaState.nJsonRpcPort > 0 ) { } try { if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) - log.write( strLogPrefix + cc.normal( "Answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); + log.write( strLogPrefix + cc.sunny( ">>>" ) + " " + cc.normal( "answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); ws_peer.send( JSON.stringify( joAnswer ) ); } catch ( err ) { if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { From 180e24001f1c65df2edb79ea817b184346962d9e Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Fri, 30 Sep 2022 13:01:12 +0100 Subject: [PATCH 04/23] transient commit, working on JS only IMA agent --- agent/bls.js | 205 +++++++++++++++----------------- agent/cli.js | 4 +- agent/main.js | 2 +- agent/oracle.js | 18 +-- npms/skale-ima/index.js | 36 +++--- npms/skale-observer/observer.js | 12 +- npms/skale-owasp/owasp-util.js | 30 ++++- 7 files changed, 161 insertions(+), 146 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index d3dc9aad4..7d185a77d 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -31,6 +31,7 @@ const child_process = require( "child_process" ); const shell = require( "shelljs" ); const { Keccak } = require( "sha3" ); const { cc } = require( "./utils" ); +const owaspUtil = require( "../npms/skale-owasp/owasp-util" ); function init() { owaspUtils.owaspAddUsageRef(); @@ -45,7 +46,7 @@ async function with_timeout( strDescription, promise, seconds ) { let result_err = null, isComplete = false; promise.catch( function( err ) { isComplete = true; - result_err = new Error( strDescription + "error: " + err.toString() ); + result_err = new Error( strDescription + "error: " + owaspUtil.extract_error_message( err ) ); } ).finally( function() { isComplete = true; } ); @@ -362,7 +363,7 @@ function perform_bls_glue( // fnShellRestore(); } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "BLS glue CRITICAL ERROR:" ) + cc.error( " error description is: " ) + cc.warning( err.toString() ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "BLS glue CRITICAL ERROR:" ) + cc.error( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "BLS glue output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -461,7 +462,7 @@ function perform_bls_glue_u256( details, u256, arrSignResults ) { // fnShellRestore(); } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "BLS glue CRITICAL ERROR:" ) + cc.error( " error description is: " ) + cc.warning( err.toString() ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "BLS glue CRITICAL ERROR:" ) + cc.error( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "BLS glue output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -525,7 +526,7 @@ function perform_bls_verify_i( fnShellRestore(); return true; } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " BLS node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify error:" ) + cc.normal( " error description is: " ) + cc.warning( err.toString() ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " BLS node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify error:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "CRITICAL ERROR:" ) + cc.error( " BLS node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -574,7 +575,7 @@ function perform_bls_verify_i_u256( details, nZeroBasedNodeIndex, joResultFromNo fnShellRestore(); return true; } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " BLS u256 node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify error:" ) + cc.normal( " error description is: " ) + cc.warning( err.toString() ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " BLS u256 node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify error:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "CRITICAL ERROR:" ) + cc.error( " BLS u256 node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -643,7 +644,7 @@ function perform_bls_verify( fnShellRestore(); return true; } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "BLS/summary verify CRITICAL ERROR:" ) + cc.normal( " error description is: " ) + cc.warning( err.toString() ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "BLS/summary verify CRITICAL ERROR:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "BLS/summary verify output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -701,7 +702,7 @@ function perform_bls_verify_u256( details, joGlueResult, u256, joCommonPublicKey fnShellRestore(); return true; } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "BLS u256/summary verify CRITICAL ERROR:" ) + cc.normal( " error description is: " ) + cc.warning( err.toString() ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "BLS u256/summary verify CRITICAL ERROR:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "BLS u256/summary verify output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -785,7 +786,7 @@ async function check_correctness_of_messages_to_sign( details, strLogPrefix, str cc.error( " Correctness validation failed for message " ) + cc.info( idxMessage ) + cc.error( " sent to " ) + cc.info( joChainName ) + cc.error( ", message is: " ) + cc.j( joMessage ) + - cc.error( ", error information: " ) + cc.warning( err.toString() ) + + cc.error( ", error information: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( s ); details.write( s ); @@ -931,7 +932,7 @@ async function do_sign_messages_impl( const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( err.toString() ) + + cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -992,7 +993,7 @@ async function do_sign_messages_impl( const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call reported error: " ) + cc.warning( err.toString() ) + + cc.error( " failed, RPC call reported error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -1010,25 +1011,15 @@ async function do_sign_messages_impl( "\n" ); if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { ++joGatheringTracker.nCountErrors; - if( ( "error" in joOut ) && ( typeof joOut.error == "object" ) && ( "message" in joOut.error ) ) { - const strErrorMessage = - strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + - cc.error( "S-Chain node " ) + strNodeDescColorized + - cc.error( " reported wallet error: " ) + cc.warning( joOut.error.message ) + - cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + - "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - } else { - const strErrorMessage = - strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + - cc.error( "JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed with " ) + cc.warning( "unknown wallet error" ) + - cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + - "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - } + const strErrorMessage = + strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + + cc.error( "S-Chain node " ) + strNodeDescColorized + + cc.error( " reported wallet error: " ) + + cc.warning( owaspUtil.extract_error_message( joOut, "unknown wallet error(1)" ) ) + + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); return; } details.write( strLogPrefix + cc.normal( "Node " ) + cc.info( joNode.nodeID ) + cc.normal( " sign result: " ) + cc.j( joOut.result ? joOut.result : null ) + "\n" ); @@ -1079,7 +1070,7 @@ async function do_sign_messages_impl( const strErrorMessage = strLogPrefixA + cc.error( "S-Chain node " ) + strNodeDescColorized + cc.error( " sign " ) + cc.error( " CRITICAL ERROR:" ) + cc.error( " partial signature fail from with index " ) + cc.info( nZeroBasedNodeIndex ) + - cc.error( ", error is " ) + cc.warning( err.toString() ) + + cc.error( ", error is " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -1110,7 +1101,7 @@ async function do_sign_messages_impl( const strErrorMessage = strLogPrefix + cc.error( "S-Chain node " ) + strNodeDescColorized + " " + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " signature fail from node " ) + cc.info( joNode.nodeID ) + - cc.error( ", error is " ) + cc.warning( err.toString() ) + + cc.error( ", error is " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -1167,10 +1158,10 @@ async function do_sign_messages_impl( log.write( cc.debug( "Will call sending function (fn)" ) + "\n" ); details.write( cc.debug( "Will call sending function (fn) for " ) + "\n" ); /*await*/ fn( strError, jarrMessages, joGlueResult ).catch( ( err ) => { - const strErrorMessage = cc.error( "Problem(2) in BLS sign result handler: " ) + cc.warning( err.toString() ) + "\n"; + const strErrorMessage = cc.error( "Problem(2) in BLS sign result handler: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - errGathering = "Problem(2) in BLS sign result handler: " + err.toString(); + errGathering = "Problem(2) in BLS sign result handler: " + owaspUtil.extract_error_message( err ); return; } ); bHaveResultReportCalled = true; @@ -1186,13 +1177,13 @@ async function do_sign_messages_impl( /*await*/ fn( "signature error(2), got " + joGatheringTracker.nCountErrors + " errors(s) for " + jarrNodes.length + " node(s)", jarrMessages, null ).catch( ( err ) => { const strErrorMessage = cc.error( "Problem(3) in BLS sign result handler, not enough successful BLS signature parts(" ) + - cc.info( cntSuccess ) + cc.error( " when all attempts done, error details: " ) + cc.warning( err.toString() ) + + cc.info( cntSuccess ) + cc.error( " when all attempts done, error details: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); errGathering = "Problem(3) in BLS sign result handler, not enough successful BLS signature parts(" + - cntSuccess + " when all attempts done, error details: " + err.toString(); + cntSuccess + " when all attempts done, error details: " + owaspUtil.extract_error_message( err ); reject( new Error( errGathering ) ); } ); bHaveResultReportCalled = true; @@ -1204,12 +1195,12 @@ async function do_sign_messages_impl( const strErrorMessage = cc.error( "Problem(4) in BLS sign result handler, not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error details: " ) + - cc.warning( err.toString() ) + "\n"; + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); errGathering = "Problem(4) in BLS sign result handler, not enough successful BLS signature parts(" + - cntSuccess + ") and timeout reached, error details: " + err.toString(); + cntSuccess + ") and timeout reached, error details: " + owaspUtil.extract_error_message( err ); reject( new Error( errGathering ) ); } ); bHaveResultReportCalled = true; @@ -1223,7 +1214,7 @@ async function do_sign_messages_impl( details.write( cc.success( "BLS verification and sending promise awaited." ) + "\n" ); log.write( cc.success( "BLS verification and sending promise awaited." ) + "\n" ); } ).catch( err => { - const strErrorMessage = cc.error( "Failed to verify BLS and send message : " ) + cc.warning( err.toString() ) + "\n"; + const strErrorMessage = cc.error( "Failed to verify BLS and send message : " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); } ); @@ -1242,7 +1233,7 @@ async function do_sign_messages_impl( const strErrorMessage = cc.error( "Problem(5) in BLS sign result handler, not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error details: " ) + - cc.warning( err.toString() ) + "\n"; + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); details.exposeDetailsTo( log, strGatheredDetailsName, false ); @@ -1253,7 +1244,7 @@ async function do_sign_messages_impl( return; } if( ! bHaveResultReportCalled ) { - const strErrorMessage = cc.error( "Failed BLS sign result awaiting(2): " ) + cc.warning( err.toString() ) + "\n"; + const strErrorMessage = cc.error( "Failed BLS sign result awaiting(2): " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); bHaveResultReportCalled = true; @@ -1261,7 +1252,7 @@ async function do_sign_messages_impl( const strErrorMessage = cc.error( "Problem(6) in BLS sign result handler, not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error details: " ) + - cc.warning( err.toString() ) + "\n"; + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); details.exposeDetailsTo( log, strGatheredDetailsName, false ); @@ -1270,14 +1261,14 @@ async function do_sign_messages_impl( } ); } } catch ( err ) { - const strErrorMessage = cc.error( "Failed BLS sign due to generic flow exception: " ) + cc.warning( err.toString() ) + "\n"; + const strErrorMessage = cc.error( "Failed BLS sign due to generic flow exception: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); if( details ) details.write( strErrorMessage ); if( ! bHaveResultReportCalled ) { bHaveResultReportCalled = true; - await fn( "Failed BLS sign due to exception: " + err.toString(), jarrMessages, null ).catch( ( err ) => { - const strErrorMessage = cc.error( "Failed BLS sign due to error-erporting callback exception: " ) + cc.warning( err.toString() ) + "\n"; + await fn( "Failed BLS sign due to exception: " + owaspUtil.extract_error_message( err ), jarrMessages, null ).catch( ( err ) => { + const strErrorMessage = cc.error( "Failed BLS sign due to error-erporting callback exception: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); if( details ) { details.write( strErrorMessage ); @@ -1403,7 +1394,7 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( err.toString() ) + "\n"; + cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); return; @@ -1424,7 +1415,7 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call reported error: " ) + cc.warning( err.toString() ) + "\n"; + cc.error( " failed, RPC call reported error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); return; @@ -1436,21 +1427,14 @@ async function do_sign_u256( u256, details, fn ) { "\n" ); if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { ++joGatheringTracker.nCountErrors; - if( ( "error" in joOut ) && ( typeof joOut.error == "object" ) && ( "message" in joOut.error ) ) { - const strErrorMessage = - strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + - cc.error( "S-Chain node " ) + strNodeDescColorized + - cc.error( " reported wallet error: " ) + cc.warning( joOut.error.message ) + "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - } else { - const strErrorMessage = - strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + - cc.error( "JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed with " ) + cc.warning( "unknown wallet error" ) + "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - } + const strErrorMessage = + strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + + cc.error( "S-Chain node " ) + strNodeDescColorized + + cc.error( " reported wallet error: " ) + + cc.warning( owaspUtil.extract_error_message( joOut, "unknown wallet error(2)" ) ) + + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); return; } details.write( strLogPrefix + cc.normal( "Node " ) + cc.info( joNode.nodeID ) + cc.normal( " sign result: " ) + cc.j( joOut.result ? joOut.result : null ) + "\n" ); @@ -1494,7 +1478,7 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = strLogPrefixA + cc.error( "S-Chain node " ) + strNodeDescColorized + cc.error( " sign " ) + cc.error( " CRITICAL ERROR:" ) + cc.error( " partial signature fail from with index " ) + cc.info( nZeroBasedNodeIndex ) + - cc.error( ", error is " ) + cc.warning( err.toString() ) + "\n"; + cc.error( ", error is " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); } @@ -1523,7 +1507,7 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = strLogPrefix + cc.error( "S-Chain node " ) + strNodeDescColorized + " " + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " signature fail from node " ) + cc.info( joNode.nodeID ) + - cc.error( ", error is " ) + cc.warning( err.toString() ) + "\n"; + cc.error( ", error is " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); } @@ -1567,10 +1551,10 @@ async function do_sign_u256( u256, details, fn ) { log.write( cc.debug( "Will call sending function (fn)" ) + "\n" ); details.write( cc.debug( "Will call sending function (fn) for " ) + "\n" ); /*await*/ fn( strError, u256, joGlueResult ).catch( ( err ) => { - const strErrorMessage = cc.error( "Problem(2) in BLS u256 sign result handler: " ) + cc.warning( err.toString() ) + "\n"; + const strErrorMessage = cc.error( "Problem(2) in BLS u256 sign result handler: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - errGathering = "Problem(2) in BLS u256 sign result handler: " + err.toString(); + errGathering = "Problem(2) in BLS u256 sign result handler: " + owaspUtil.extract_error_message( err ); } ); if( strError ) { errGathering = strError; @@ -1584,13 +1568,13 @@ async function do_sign_u256( u256, details, fn ) { /*await*/ fn( "signature error(2, u256), got " + joGatheringTracker.nCountErrors + " errors(s) for " + jarrNodes.length + " node(s)", u256, null ).catch( ( err ) => { const strErrorMessage = cc.error( "Problem(3) in BLS u256 sign result handler, not enough successful BLS signature parts(" ) + - cc.info( cntSuccess ) + cc.error( " when all attempts done, error details: " ) + cc.warning( err.toString() ) + + cc.info( cntSuccess ) + cc.error( " when all attempts done, error details: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); errGathering = "Problem(3) in BLS u256 sign result handler, not enough successful BLS signature parts(" + - cntSuccess + " when all attempts done, error details: " + err.toString(); + cntSuccess + " when all attempts done, error details: " + owaspUtil.extract_error_message( err ); reject( new Error( errGathering ) ); } ); return; @@ -1601,12 +1585,12 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = cc.error( "Problem(4) in BLS u256 sign result handler, not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error details: " ) + - cc.warning( err.toString() ) + "\n"; + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); errGathering = "Problem(4) in BLS u256 sign result handler, not enough successful BLS signature parts(" + - cntSuccess + ") and timeout reached, error details: " + err.toString(); + cntSuccess + ") and timeout reached, error details: " + owaspUtil.extract_error_message( err ); reject( new Error( errGathering ) ); } ); return; @@ -1619,7 +1603,7 @@ async function do_sign_u256( u256, details, fn ) { details.write( cc.info( "BLS u256 sign promise awaited." ) + "\n" ); log.write( cc.info( "BLS u256 sign promise awaited." ) + "\n" ); } ).catch( err => { - const strErrorMessage = cc.error( "Failed to verify BLS and send message : " ) + cc.warning( err.toString() ) + "\n"; + const strErrorMessage = cc.error( "Failed to verify BLS and send message : " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); } ); @@ -1646,36 +1630,33 @@ async function handle_skale_call_via_redirect( joCallData ) { if( err ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call to S-Chain failed, RPC call was not created, error is: " ) + cc.warning( err.toString() ) + "\n"; + cc.error( " JSON RPC call to S-Chain failed, RPC call was not created, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - throw new Error( "JSON RPC call to S-Chain failed, RPC call was not created, error is: " + err.toString() ); + throw new Error( "JSON RPC call to S-Chain failed, RPC call was not created, error is: " + owaspUtil.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Will invoke " ) + cc.info( "S-Chain" ) + cc.debug( " with call data " ) + cc.j( joCallData ) + "\n" ); await joCall.call( joCallData, async function( joIn, joOut, err ) { if( err ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call to S-Chain failed, RPC call reported error: " ) + cc.warning( err.toString() ) + "\n"; + cc.error( " JSON RPC call to S-Chain failed, RPC call reported error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - throw new Error( "JSON RPC call to S-Chain failed, RPC call reported error: " + err.toString() ); + throw new Error( "JSON RPC call to S-Chain failed, RPC call reported error: " + owaspUtil.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "S-Chain" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { - let strThrowMessage = ""; - if( ( "error" in joOut ) && ( typeof joOut.error == "object" ) && ( "message" in joOut.error ) ) { - const strErrorMessage = - strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + - cc.error( "S-Chain reported wallet error: " ) + cc.warning( joOut.error.message ) + - cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + - "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - details.write( strErrorMessage ); - strThrowMessage = "JSON RPC call to S-Chain failed with \"unknown wallet error\", sequence ID is " + sequence_id; - } - throw new Error( strThrowMessage ); + const strErrorMessage = + strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + + cc.error( "S-Chain reported wallet error: " ) + + cc.warning( owaspUtil.extract_error_message( joOut, "unknown wallet error(3)" ) ) + + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + details.write( strErrorMessage ); + throw new Error( "JSON RPC call to S-Chain failed with \"unknown wallet error(3)\", sequence ID is " + sequence_id ); } isSuccess = true; joRetVal = joOut; // joOut.result @@ -1683,7 +1664,7 @@ async function handle_skale_call_via_redirect( joCallData ) { } ); // rpcCall.create ... } catch ( err ) { isSuccess = false; - const strError = err.toString(); + const strError = owaspUtil.extract_error_message( err ); joRetVal.error = strError; const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + @@ -1700,11 +1681,13 @@ async function handle_skale_call_via_redirect( joCallData ) { async function handle_skale_imaVerifyAndSign( joCallData ) { const strLogPrefix = ""; const details = log.createMemoryStream( true ); + let joRetVal = { }; let isSuccess = false; try { // + details.write( strLogPrefix + cc.debug( "Will verify and sign " ) + cc.j( joCallData ) + "\n" ); const nIdxCurrentMsgBlockStart = joCallData.params.startMessageIdx; - const strFromChainName = jojoRetVal.CallData.params.srcChainName; + const strFromChainName = joCallData.params.srcChainName; const jarrMessages = joCallData.params.messages; const nThreshold = discover_bls_threshold( imaState.joSChainNetworkInfo ); const nParticipants = discover_bls_participants( imaState.joSChainNetworkInfo ); @@ -1713,17 +1696,24 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { const strMessageHash = owaspUtils.remove_starting_0x( keccak256_message( jarrMessages, nIdxCurrentMsgBlockStart, strFromChainName ) ); details.write( strLogPrefix + cc.debug( "Message hash to sign is " ) + cc.info( strMessageHash ) + "\n" ); // - const strURL = imaState.joAccount_s_chain.strSgxURL; // TO-FIX: verify we have SGX connection parameters - const keyShareName = imaState.joAccount_s_chain.strSgxKeyName; // TO-FIX: verify we have SGX connection parameters + const strURL = imaState.joAccount_s_chain.strSgxURL + ? imaState.joAccount_s_chain.strSgxURL + : imaState.joAccount_main_net.strSgxURL; + if( ! strURL ) + throw new Error( "SGX URL is unknown, cannot verify IMA message(s)" ); + const keyShareName = imaState.joAccount_s_chain.strSgxKeyName; + if( ! strURL ) + throw new Error( "SGX keyshare name is unknown, cannot verify IMA message(s)" ); const signerIndex = imaState.joAccount_s_chain.nNodeNumber; + const rpcCallOpts = null; await rpcCall.create( strURL, rpcCallOpts, async function( joCall, err ) { if( err ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call to SGX failed, RPC call was not created, error is: " ) + cc.warning( err.toString() ) + "\n"; + cc.error( " JSON RPC call to SGX failed, RPC call was not created, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - throw new Error( "JSON RPC call to SGX failed, RPC call was not created, error is: " + err.toString() ); + throw new Error( "JSON RPC call to SGX failed, RPC call was not created, error is: " + owaspUtil.extract_error_message( err ) ); } const joCallSGX = { method: "blsSignMessageHash", @@ -1741,26 +1731,23 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { if( err ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call to SGX failed, RPC call reported error: " ) + cc.warning( err.toString() ) + "\n"; + cc.error( " JSON RPC call to SGX failed, RPC call reported error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - throw new Error( "JSON RPC call to SGX failed, RPC call reported error: " + err.toString() ); + throw new Error( "JSON RPC call to SGX failed, RPC call reported error: " + owaspUtil.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "SGX" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { - let strThrowMessage = ""; - if( ( "error" in joOut ) && ( typeof joOut.error == "object" ) && ( "message" in joOut.error ) ) { - const strErrorMessage = - strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + - cc.error( "SGX reported wallet error: " ) + cc.warning( joOut.error.message ) + - cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + - "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - details.write( strErrorMessage ); - strThrowMessage = "JSON RPC call to SGX failed with \"unknown wallet error\", sequence ID is " + sequence_id; - } - throw new Error( strThrowMessage ); + const strErrorMessage = + strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + + cc.error( "SGX reported wallet error: " ) + + cc.warning( owaspUtil.extract_error_message( joOut, "unknown wallet error(4)" ) ) + + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + details.write( strErrorMessage ); + throw new Error( "JSON RPC call to SGX failed with \"unknown wallet error(4)\", sequence ID is " + sequence_id ); } isSuccess = true; const joSignResult = ( "result" in joOut ) ? joOut.result : joOut; @@ -1771,7 +1758,7 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { } ); // rpcCall.create ... } catch ( err ) { isSuccess = false; - const strError = err.toString(); + const strError = owaspUtil.extract_error_message( err ); joRetVal.error = strError; const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + diff --git a/agent/cli.js b/agent/cli.js index 2fa41a80b..b721a48c6 100644 --- a/agent/cli.js +++ b/agent/cli.js @@ -1281,7 +1281,7 @@ function getWeb3FromURL( strURL, log ) { } catch ( err ) { log.write( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " Failed to create " ) + cc.attention( "Web3" ) + cc.error( " connection to " ) + cc.info( strURL ) + - cc.error( ": " ) + cc.warning( err.toString() ) + "\n" ); + cc.error( ": " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); w3 = null; } return w3; @@ -1302,7 +1302,7 @@ async function async_check_url_at_startup( u, name ) { } catch ( err ) { details.write( cc.fatal( "ERROR:" ) + cc.error( " Failed to check URL " ) + - cc.u( u ) + cc.error( " connectivity for " ) + cc.info( name ) + cc.error( " at start-up, error is: " ) + cc.warning( err.toString() ) + + cc.u( u ) + cc.error( " connectivity for " ) + cc.info( name ) + cc.error( " at start-up, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); } // details.exposeDetailsTo( log, "async_check_url_at_startup( \"" + u + "\", \"" + name + "\" )", true ); diff --git a/agent/main.js b/agent/main.js index 7a81f5456..cd1cd70fa 100644 --- a/agent/main.js +++ b/agent/main.js @@ -2643,7 +2643,7 @@ async function single_transfer_loop() { log.write( strLogPrefix + cc.debug( "Completed: " ) + cc.tf( bResult ) + "\n" ); return bResult; } catch ( err ) { - log.write( strLogPrefix + cc.fatal( "Exception:" ) + + cc.error( err.toString() ) + "\n" ); + log.write( strLogPrefix + cc.fatal( "Exception:" ) + + cc.error( owaspUtil.extract_error_message( err ) ) + "\n" ); } g_is_single_transfer_loop = false; return false; diff --git a/agent/oracle.js b/agent/oracle.js index a1fd223af..385e3ed8a 100644 --- a/agent/oracle.js +++ b/agent/oracle.js @@ -90,9 +90,9 @@ function oracle_get_gas_price( oracleOpts, details ) { cntAttempts = 1; rpcCall.create( url, callOpts || { }, async function( joCall, err ) { if( err ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC connection problem for url " ) + cc.u( url ) + cc.error( ", error description: " ) + cc.warning( err.toString() ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC connection problem for url " ) + cc.u( url ) + cc.error( ", error description: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); - reject( new Error( "CRITICAL ORACLE CALL ERROR: RPC connection problem for url \"" + url + "\", error description: " + err.toString() ) ); + reject( new Error( "CRITICAL ORACLE CALL ERROR: RPC connection problem for url \"" + url + "\", error description: " + owaspUtil.extract_error_message( err ) ) ); return; } try { @@ -110,10 +110,10 @@ function oracle_get_gas_price( oracleOpts, details ) { await joCall.call( joIn, async function( joIn, joOut, err ) { if( err ) { if( isVerboseTraceDetails ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " JSON RPC call" ) + cc.debug( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + cc.error( " failed, error: " ) + cc.warning( err.toString() ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " JSON RPC call" ) + cc.debug( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + cc.error( " failed, error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); } - reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_submitRequest) failed, error: " + err.toString() ) ); + reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_submitRequest) failed, error: " + owaspUtil.extract_error_message( err ) ) ); return; } if( isVerboseTraceDetails ) @@ -140,10 +140,10 @@ function oracle_get_gas_price( oracleOpts, details ) { await joCall.call( joIn, async function( joIn, joOut, err ) { if( err ) { if( isVerboseTraceDetails ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " JSON RPC call" ) + cc.debug( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " failed, error: " ) + cc.warning( err.toString() ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " JSON RPC call" ) + cc.debug( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " failed, error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); } - //reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_checkResult) failed, error: " + err.toString() ) ); + //reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_checkResult) failed, error: " + owaspUtil.extract_error_message( err ) ) ); return; } if( isVerboseTraceDetails ) @@ -166,7 +166,7 @@ function oracle_get_gas_price( oracleOpts, details ) { return; } ); } catch ( err ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " exception is: " ) + cc.warning( err.toString() ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " exception is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); reject( err ); return; @@ -177,14 +177,14 @@ function oracle_get_gas_price( oracleOpts, details ) { return; } ); } catch ( err ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + cc.error( " exception is: " ) + cc.warning( err.toString() ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + cc.error( " exception is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); reject( err ); return; } } ); } catch ( err ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call object creation failed, error is: " ) + cc.warning( err.toString() ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call object creation failed, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); reject( err ); return; diff --git a/npms/skale-ima/index.js b/npms/skale-ima/index.js index d8b3755be..aa759c4f1 100644 --- a/npms/skale-ima/index.js +++ b/npms/skale-ima/index.js @@ -192,7 +192,7 @@ async function get_web3_blockNumber( details, cntAttempts, w3, retValOnFail, thr cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( err.toString() ) + + cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -222,7 +222,7 @@ async function get_web3_blockNumber( details, cntAttempts, w3, retValOnFail, thr cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( err.toString() ) + + cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -257,7 +257,7 @@ async function get_web3_transactionCount( details, cntAttempts, w3, address, par cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( err.toString() ) + + cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -287,7 +287,7 @@ async function get_web3_transactionCount( details, cntAttempts, w3, address, par cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( err.toString() ) + + cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -322,7 +322,7 @@ async function get_web3_transactionReceipt( details, cntAttempts, w3, txHash, re cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( err.toString() ) + + cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -352,7 +352,7 @@ async function get_web3_transactionReceipt( details, cntAttempts, w3, txHash, re cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( err.toString() ) + + cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -393,9 +393,9 @@ async function get_web3_pastEvents( details, w3, cntAttempts, joContract, strEve cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + cc.error( ", from block " ) + cc.warning( nBlockFrom ) + cc.error( ", to block " ) + cc.warning( nBlockTo ) + - cc.error( ", error is: " ) + cc.warning( err.toString() ) + + cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); - if( err.toString().indexOf( strErrorTextAboutNotExistingEvent ) >= 0 ) { + if( owaspUtil.extract_error_message( err ).indexOf( strErrorTextAboutNotExistingEvent ) >= 0 ) { details.write( cc.error( "Did stopped calls to " ) + cc.note( strFnName + "()" ) + cc.error( " because event " ) + cc.notice( strEventName ) + @@ -439,9 +439,9 @@ async function get_web3_pastEvents( details, w3, cntAttempts, joContract, strEve cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + cc.error( ", from block " ) + cc.warning( nBlockFrom ) + cc.error( ", to block " ) + cc.warning( nBlockTo ) + - cc.error( ", error is: " ) + cc.warning( err.toString() ) + + cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); - if( err.toString().indexOf( strErrorTextAboutNotExistingEvent ) >= 0 ) { + if( owaspUtil.extract_error_message( err ).indexOf( strErrorTextAboutNotExistingEvent ) >= 0 ) { details.write( cc.error( "Did stopped calls to " ) + cc.note( strFnName + "()" ) + cc.error( " because event " ) + cc.notice( strEventName ) + @@ -552,7 +552,7 @@ async function get_web3_pastEventsIterative( details, w3, attempts, joContract, cc.error( "Got scan error during interative scan of " ) + cc.info( idxBlockSubRangeFrom ) + cc.error( "/" ) + cc.info( idxBlockSubRangeTo ) + cc.error( " block sub-range in " ) + cc.info( nBlockFrom ) + cc.error( "/" ) + cc.info( nBlockTo ) + - cc.error( " block range, error is: " ) + cc.warning( err.toString() ) + "\n" + cc.error( " block range, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); } idxBlockSubRangeFrom = idxBlockSubRangeTo; @@ -721,7 +721,7 @@ async function do_oracle_gas_price_setup( details.write( cc.error( "Failed to fetch " ) + cc.info( "Main Net gas price" ) + cc.error( " via call to " ) + cc.info( "Oracle" ) + - cc.error( ", error is: " ) + cc.warning( err.toString() ) + "\n" ); + cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); } } if( gasPriceOnMainNet === null ) { @@ -1141,8 +1141,8 @@ async function dry_run_call( details, w3, methodWithArguments, joAccount, strDRC details.write( strLogPrefix + cc.fatal( "CRITICAL DRY RUN FAIL" ) + " " + cc.error( " invoking the " ) + cc.info( strMethodName ) + cc.error( " method: " ) + - cc.warning( err.toString() ) + "\n" ); - return "CRITICAL DRY RUN FAIL invoking the \"" + strMethodName + "\" method: " + err.toString(); + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + return "CRITICAL DRY RUN FAIL invoking the \"" + strMethodName + "\" method: " + owaspUtil.extract_error_message( err ); } } return null; @@ -1418,7 +1418,7 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc strMsg = cc.fatal( "BAD ERROR:" ) + " " + cc.error( "TM - transaction was not sent, underlying error is: " ) + - cc.warning( err.toString() ); + cc.warning( owaspUtil.extract_error_message( err ) ); details.write( strPrefixDetails + strMsg + "\n" ); log.write( strPrefixLog + strMsg + "\n" ); // throw err; @@ -5673,7 +5673,7 @@ async function do_transfer( ++ cntFailedNodes; const strError = strLogPrefix + cc.fatal( strDirection + " message analysis error:" ) + " " + cc.error( "Failed to scan events on node " ) + cc.info( jo_node.name ) + - cc.error( ", error is: " ) + cc.warning( err.toString() ) + + cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + cc.error( ", detailed node description is: " ) + cc.j( jo_node ) + "\n"; details.write( strError ); @@ -5716,7 +5716,7 @@ async function do_transfer( cc.error( "Failed to process events for " ) + cc.sunny( strDirection ) + cc.error( " message " ) + cc.info( idxMessage + 1 ) + cc.error( " on node " ) + cc.info( jo_node.name ) + cc.success( " using URL " ) + cc.info( jo_node.http_endpoint_ip ) + - cc.debug( ", error is: " ) + cc.warning( err.toString() ) + "\n"; + cc.debug( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; details.write( strError ); if( verbose_get() >= RV_VERBOSE.fatal ) log.write( strError ); @@ -5970,7 +5970,7 @@ async function do_transfer( } ); // fn_sign_messages } catch ( err ) { const strError = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " Exception from sigining messages function: " ) + cc.error( err.toString() ); + cc.error( " Exception from sigining messages function: " ) + cc.error( owaspUtil.extract_error_message( err ) ); log.write( strError + "\n" ); details.write( strError + "\n" ); if( detailsB ) diff --git a/npms/skale-observer/observer.js b/npms/skale-observer/observer.js index 62fb0faf0..516e2e2ca 100644 --- a/npms/skale-observer/observer.js +++ b/npms/skale-observer/observer.js @@ -70,7 +70,7 @@ function getWeb3FromURL( strURL, log ) { } catch ( err ) { log.write( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " Failed to create " ) + cc.attention( "Web3" ) + cc.error( " connection to " ) + cc.info( strURL ) + - cc.error( ": " ) + cc.warning( err.toString() ) ); + cc.error( ": " ) + cc.warning( owaspUtil.extract_error_message( err ) ) ); w3 = null; } return w3; @@ -310,7 +310,7 @@ async function load_schains_connected_only( w3_main_net, w3_s_chain, strChainNam arr_schains.push( jo_schain ); } catch ( err ) { if( opts && opts.details ) { - opts.details.write( cc.error( "Got error: " ) + cc.warning( err.toString() ) + "\n" ); + opts.details.write( cc.error( "Got error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); opts.details.write( err.stack ); } } @@ -346,7 +346,7 @@ async function check_connected_schains( strChainNameConnectedTo, arr_schains, ad } } catch ( err ) { if( opts && opts.details ) { - opts.details.write( cc.error( "Got error: " ) + cc.warning( err.toString() ) + "\n" ); + opts.details.write( cc.error( "Got error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); opts.details.write( err.stack ); } } @@ -458,7 +458,7 @@ async function cache_schains( strChainNameConnectedTo, w3_main_net, w3_s_chain, if( opts.fn_chache_changed ) opts.fn_chache_changed( g_arr_schains_cached, null ); // null - no error } catch ( err ) { - strError = err.toString(); + strError = owaspUtil.extract_error_message( err ); if( ! strError ) strError = "unknown exception during S-Chains download"; if( opts.fn_chache_changed ) @@ -614,7 +614,7 @@ async function discover_chain_id( strURL ) { const rpcCallOpts = null; await rpcCall.create( strURL, rpcCallOpts, async function( joCall, err ) { if( err ) { - //ret = "Failed to create RPC (" + strURL + ") call: " + err.toString(); + //ret = "Failed to create RPC (" + strURL + ") call: " + owaspUtil.extract_error_message( err ); return; } await joCall.call( { @@ -622,7 +622,7 @@ async function discover_chain_id( strURL ) { "params": [] }, async function( joIn, joOut, err ) { if( err ) { - //ret = "Failed to query RPC (" + strURL + ") for chain ID: " + err.toString(); + //ret = "Failed to query RPC (" + strURL + ") for chain ID: " + owaspUtil.extract_error_message( err ); return; } if( ! ( "result" in joOut && joOut.result ) ) { diff --git a/npms/skale-owasp/owasp-util.js b/npms/skale-owasp/owasp-util.js index 6e2e7cd92..39963c7d2 100644 --- a/npms/skale-owasp/owasp-util.js +++ b/npms/skale-owasp/owasp-util.js @@ -625,6 +625,33 @@ function w3_2_url( w3 ) { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function extract_error_message( jo, strDefaultErrorText ) { + strDefaultErrorText = strDefaultErrorText || "unknown error or error without a description"; + try { + if( ! jo ) + return strDefaultErrorText; + if( typeof jo != "object" ) + return strDefaultErrorText; + if( "error" in jo ) { + jo = jo.error; + if( typeof jo == "string" ) + return jo; + if( typeof jo != "object" ) + return strDefaultErrorText + "(" + jo.toString() + ")"; + } + if( "message" in jo ) { + jo = jo.message; + if( typeof jo == "string" ) + return jo; + } + strDefaultErrorText += "(" + jo.toString() + ")"; + } catch ( err ) { + } + return strDefaultErrorText; +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// module.exports = { cc: cc, w3mod: w3mod, @@ -667,5 +694,6 @@ module.exports = { fn_address_impl_: fn_address_impl_, compute_chain_id_from_schain_name: compute_chain_id_from_schain_name, w3provider_2_url: w3provider_2_url, - w3_2_url: w3_2_url + w3_2_url: w3_2_url, + extract_error_message: extract_error_message }; // module.exports From 6c616cf01d85b4a3313d02e966c0745cee1ae2c1 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Fri, 30 Sep 2022 13:01:45 +0100 Subject: [PATCH 05/23] transient commit, working on JS only IMA agent --- agent/bls.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 7d185a77d..3b8d607b0 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -1681,7 +1681,7 @@ async function handle_skale_call_via_redirect( joCallData ) { async function handle_skale_imaVerifyAndSign( joCallData ) { const strLogPrefix = ""; const details = log.createMemoryStream( true ); - let joRetVal = { }; + const joRetVal = { }; let isSuccess = false; try { // @@ -1697,7 +1697,7 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { details.write( strLogPrefix + cc.debug( "Message hash to sign is " ) + cc.info( strMessageHash ) + "\n" ); // const strURL = imaState.joAccount_s_chain.strSgxURL - ? imaState.joAccount_s_chain.strSgxURL + ? imaState.joAccount_s_chain.strSgxURL : imaState.joAccount_main_net.strSgxURL; if( ! strURL ) throw new Error( "SGX URL is unknown, cannot verify IMA message(s)" ); From 50fa39b5dece2a6b3b33f1ca56edb43c83450b0f Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Mon, 3 Oct 2022 18:58:40 +0100 Subject: [PATCH 06/23] transient commit, working on JS only IMA agent --- agent/bls.js | 39 +++++++++++------- agent/cli.js | 35 ++++++++++++++++ agent/main.js | 72 ++++++++++++++++++++++++--------- npms/skale-observer/observer.js | 6 ++- test/agent-test.js | 9 +++-- 5 files changed, 124 insertions(+), 37 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 3b8d607b0..c2c5fa614 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -23,7 +23,7 @@ * @copyright SKALE Labs 2019-Present */ -// const fs = require( "fs" ); +const fs = require( "fs" ); // const path = require( "path" ); // const url = require( "url" ); // const os = require( "os" ); @@ -1261,7 +1261,9 @@ async function do_sign_messages_impl( } ); } } catch ( err ) { - const strErrorMessage = cc.error( "Failed BLS sign due to generic flow exception: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const strErrorMessage = + cc.error( "Failed BLS sign due to generic flow exception: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", call stack is: " ) + "\n" + err.stack() + "\n"; log.write( strErrorMessage ); if( details ) details.write( strErrorMessage ); @@ -1696,17 +1698,26 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { const strMessageHash = owaspUtils.remove_starting_0x( keccak256_message( jarrMessages, nIdxCurrentMsgBlockStart, strFromChainName ) ); details.write( strLogPrefix + cc.debug( "Message hash to sign is " ) + cc.info( strMessageHash ) + "\n" ); // - const strURL = imaState.joAccount_s_chain.strSgxURL - ? imaState.joAccount_s_chain.strSgxURL - : imaState.joAccount_main_net.strSgxURL; - if( ! strURL ) - throw new Error( "SGX URL is unknown, cannot verify IMA message(s)" ); - const keyShareName = imaState.joAccount_s_chain.strSgxKeyName; - if( ! strURL ) - throw new Error( "SGX keyshare name is unknown, cannot verify IMA message(s)" ); + let joAccount = imaState.joAccount_s_chain; + if( ! joAccount.strURL ) { + joAccount = imaState.joAccount_main_net; + if( ! joAccount.strSgxURL ) + throw new Error( "SGX URL is unknown, cannot verify IMA message(s)" ); + if( ! joAccount.strBlsKeyName ) + throw new Error( "BLS keys name is unknown, cannot sign IMA message(s)" ); + } + let rpcCallOpts = null; + if( "strPathSslKey" in joAccount && typeof joAccount.strPathSslKey == "string" && joAccount.strPathSslKey.length > 0 && + "strPathSslCert" in joAccount && typeof joAccount.strPathSslCert == "string" && joAccount.strPathSslCert.length > 0 + ) { + rpcCallOpts = { + "cert": fs.readFileSync( joAccount.strPathSslCert, "utf8" ), + "key": fs.readFileSync( joAccount.strPathSslKey, "utf8" ) + }; + // details.write( cc.debug( "Will sign via SGX with SSL options " ) + cc.j( rpcCallOpts ) + "\n" ); + } const signerIndex = imaState.joAccount_s_chain.nNodeNumber; - const rpcCallOpts = null; - await rpcCall.create( strURL, rpcCallOpts, async function( joCall, err ) { + await rpcCall.create( joAccount.strSgxURL, rpcCallOpts, async function( joCall, err ) { if( err ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + @@ -1719,11 +1730,11 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { method: "blsSignMessageHash", // type: "BLSSignReq", params: { - keyShareName: keyShareName, + keyShareName: joAccount.strBlsKeyName, messageHash: strMessageHash, n: nParticipants, t: nThreshold, - signerIndex: signerIndex + 1 // 1-based + signerIndex: signerIndex + 0 // 1-based } }; details.write( strLogPrefix + cc.debug( "Will invoke " ) + cc.info( "SGX" ) + cc.debug( " with call data " ) + cc.j( joCallSGX ) + "\n" ); diff --git a/agent/cli.js b/agent/cli.js index b721a48c6..60d6e4f65 100644 --- a/agent/cli.js +++ b/agent/cli.js @@ -241,6 +241,9 @@ function parse( joExternalHandlers, argv ) { console.log( soi + cc.debug( "--" ) + cc.bright( "sgx-ecdsa-key-main-net" ) + cc.sunny( "=" ) + cc.error( "name" ) + cc.debug( "..." ) + cc.attention( "SGX/ECDSA key name" ) + cc.notice( " for " ) + cc.note( "Main-net" ) + cc.notice( ". Value is automatically loaded from the " ) + cc.warning( "SGX_KEY_ETHEREUM" ) + cc.notice( " environment variable if not specified." ) ); console.log( soi + cc.debug( "--" ) + cc.bright( "sgx-ecdsa-key-s-chain" ) + cc.sunny( "=" ) + cc.error( "name" ) + cc.debug( "...." ) + cc.attention( "SGX/ECDSA key name" ) + cc.notice( " for " ) + cc.note( "S-chain" ) + cc.notice( ". Value is automatically loaded from the " ) + cc.warning( "SGX_KEY_S_CHAIN" ) + cc.notice( " environment variable if not specified." ) ); console.log( soi + cc.debug( "--" ) + cc.bright( "sgx-ecdsa-key-t-chain" ) + cc.sunny( "=" ) + cc.error( "name" ) + cc.debug( "...." ) + cc.attention( "SGX/ECDSA key name" ) + cc.notice( " for " ) + cc.note( "S<->S Target S-chain" ) + cc.notice( ". Value is automatically loaded from the " ) + cc.warning( "SGX_KEY_S_CHAIN_TARGET" ) + cc.notice( " environment variable if not specified." ) ); + console.log( soi + cc.debug( "--" ) + cc.bright( "sgx-bls-key-main-net" ) + cc.sunny( "=" ) + cc.error( "name" ) + cc.debug( "....." ) + cc.attention( "SGX/BLS key name" ) + cc.notice( " for " ) + cc.note( "Main-net" ) + cc.notice( ". Value is automatically loaded from the " ) + cc.warning( "BLS_KEY_ETHEREUM" ) + cc.notice( " environment variable if not specified." ) ); + console.log( soi + cc.debug( "--" ) + cc.bright( "sgx-bls-key-s-chain" ) + cc.sunny( "=" ) + cc.error( "name" ) + cc.debug( "......" ) + cc.attention( "SGX/BLS key name" ) + cc.notice( " for " ) + cc.note( "S-chain" ) + cc.notice( ". Value is automatically loaded from the " ) + cc.warning( "BLS_KEY_S_CHAIN" ) + cc.notice( " environment variable if not specified." ) ); + console.log( soi + cc.debug( "--" ) + cc.bright( "sgx-bls-key-t-chain" ) + cc.sunny( "=" ) + cc.error( "name" ) + cc.debug( "......" ) + cc.attention( "SGX/BLS key name" ) + cc.notice( " for " ) + cc.note( "S<->S Target S-chain" ) + cc.notice( ". Value is automatically loaded from the " ) + cc.warning( "BLS_KEY_S_CHAIN_TARGET" ) + cc.notice( " environment variable if not specified." ) ); // console.log( soi + cc.debug( "--" ) + cc.bright( "sgx-ssl-key-main-net" ) + cc.sunny( "=" ) + cc.attention( "path" ) + cc.debug( "....." ) + cc.notice( "Path to " ) + cc.note( "SSL key file" ) + cc.notice( " for " ) + cc.bright( "SGX wallet" ) + cc.notice( " of " ) + cc.note( "Main-net" ) + cc.notice( ". Value is automatically loaded from the " ) + cc.warning( "SGX_SSL_KEY_FILE_ETHEREUM" ) + cc.notice( " environment variable if not specified." ) ); console.log( soi + cc.debug( "--" ) + cc.bright( "sgx-ssl-key-s-chain" ) + cc.sunny( "=" ) + cc.attention( "path" ) + cc.debug( "......" ) + cc.notice( "Path to " ) + cc.note( "SSL key file" ) + cc.notice( " for " ) + cc.bright( "SGX wallet" ) + cc.notice( " of " ) + cc.note( "S-chain" ) + cc.notice( ". Value is automatically loaded from the " ) + cc.warning( "SGX_SSL_KEY_FILE_S_CHAIN" ) + cc.notice( " environment variable if not specified." ) ); @@ -584,6 +587,21 @@ function parse( joExternalHandlers, argv ) { imaState.joAccount_t_chain.strSgxKeyName = joArg.value; continue; } + if( joArg.name == "sgx-bls-key-main-net" ) { + owaspUtils.verifyArgumentWithNonEmptyValue( joArg ); + imaState.joAccount_main_net.strBlsKeyName = joArg.value; + continue; + } + if( joArg.name == "sgx-bls-key-s-chain" ) { + owaspUtils.verifyArgumentWithNonEmptyValue( joArg ); + imaState.joAccount_s_chain.strBlsKeyName = joArg.value; + continue; + } + if( joArg.name == "sgx-bls-key-t-chain" ) { + owaspUtils.verifyArgumentWithNonEmptyValue( joArg ); + imaState.joAccount_t_chain.strBlsKeyName = joArg.value; + continue; + } // if( joArg.name == "sgx-ssl-key-main-net" ) { owaspUtils.verifyArgumentIsPathToExistingFile( joArg ); @@ -2100,6 +2118,23 @@ function ima_common_init() { try { ensure_have_chain_credentials( "S<->S Target S-Chain", imaState.joAccount_t_chain, false, isPrintGathered && isPrintSecurityValues ); } catch ( err ) {} + if( isPrintGathered && isPrintSecurityValues ) { + if( imaState.joAccount_main_net.strBlsKeyName ) { + ensure_have_value( "BLS/Main Net key name", imaState.joAccount_main_net.strBlsKeyName, false, isPrintGathered, null, ( x ) => { + return cc.attention( x ); + } ); + } + if( imaState.joAccount_s_chain.strBlsKeyName ) { + ensure_have_value( "BLS/S-Chain key name", imaState.joAccount_s_chain.strBlsKeyName, false, isPrintGathered, null, ( x ) => { + return cc.attention( x ); + } ); + } + if( imaState.joAccount_t_chain.strBlsKeyName ) { + ensure_have_value( "BLS/Target S-Chain key name", imaState.joAccount_t_chain.strBlsKeyName, false, isPrintGathered, null, ( x ) => { + return cc.attention( x ); + } ); + } + } // // ensure_have_value( "Amount of wei to transfer", imaState.nAmountOfWei, false, isPrintGathered, null, ( x ) => { diff --git a/agent/main.js b/agent/main.js index cd1cd70fa..e5ea1ed91 100644 --- a/agent/main.js +++ b/agent/main.js @@ -224,7 +224,8 @@ global.imaState = { "strSgxURL": owaspUtils.toStringURL( process.env.SGX_URL_ETHEREUM ), "strSgxKeyName": owaspUtils.toStringURL( process.env.SGX_KEY_ETHEREUM ), "strPathSslKey": ( process.env.SGX_SSL_KEY_FILE_ETHEREUM || "" ).toString().trim(), - "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_ETHEREUM || "" ).toString().trim() + "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_ETHEREUM || "" ).toString().trim(), + "strBlsKeyName": owaspUtils.toStringURL( process.env.BLS_KEY_ETHEREUM ) }, "joAccount_s_chain": { "privateKey": owaspUtils.toEthPrivateKey( process.env.PRIVATE_KEY_FOR_SCHAIN ), @@ -234,7 +235,8 @@ global.imaState = { "strSgxURL": owaspUtils.toStringURL( process.env.SGX_URL_S_CHAIN ), "strSgxKeyName": owaspUtils.toStringURL( process.env.SGX_KEY_S_CHAIN ), "strPathSslKey": ( process.env.SGX_SSL_KEY_FILE_S_CHAIN || "" ).toString().trim(), - "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_S_CHAIN || "" ).toString().trim() + "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_S_CHAIN || "" ).toString().trim(), + "strBlsKeyName": owaspUtils.toStringURL( process.env.BLS_KEY_S_CHAIN ) }, "joAccount_t_chain": { "privateKey": owaspUtils.toEthPrivateKey( process.env.PRIVATE_KEY_FOR_SCHAIN_TARGET ), @@ -244,7 +246,8 @@ global.imaState = { "strSgxURL": owaspUtils.toStringURL( process.env.SGX_URL_S_CHAIN_TARGET ), "strSgxKeyName": owaspUtils.toStringURL( process.env.SGX_KEY_S_CHAIN_TARGET ), "strPathSslKey": ( process.env.SGX_SSL_KEY_FILE_S_CHAIN_TARGET || "" ).toString().trim(), - "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_S_CHAIN_TARGET || "" ).toString().trim() + "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_S_CHAIN_TARGET || "" ).toString().trim(), + "strBlsKeyName": owaspUtils.toStringURL( process.env.BLS_KEY_T_CHAIN ) }, // @@ -2231,12 +2234,13 @@ if( imaState.nJsonRpcPort > 0 ) { const ip = req.socket.remoteAddress; if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) log.write( strLogPrefix + cc.normal( "New connection from " ) + cc.info( ip ) + "\n" ); - ws_peer.on( "message", async function( message ) { - let joAnswer = { + ws_peer.on( "message", function( message ) { + const joAnswer = { method: null, id: null, error: null }; + let isSkipMode = false; try { const joMessage = JSON.parse( message ); if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) @@ -2261,10 +2265,40 @@ if( imaState.nJsonRpcPort > 0 ) { // joAnswer.schain_network_info = imaState.joSChainNetworkInfo; // break; case "skale_imaVerifyAndSign": - joAnswer = await imaBLS.handle_skale_imaVerifyAndSign( joMessage ); + // joAnswer = await imaBLS.handle_skale_imaVerifyAndSign( joMessage ); + isSkipMode = true; + imaBLS.handle_skale_imaVerifyAndSign( joMessage ).then( function( joAnswer ) { + try { + if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) + log.write( strLogPrefix + cc.sunny( ">>>" ) + " " + cc.normal( "answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); + ws_peer.send( JSON.stringify( joAnswer ) ); + } catch ( err ) { + if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { + log.write( strLogPrefix + + cc.error( "Failed to sent answer to " ) + cc.info( ip ) + + cc.error( ", error is: " ) + cc.warning( err ) + "\n" + ); + } + } + } ); break; case "skale_imaBSU256": - joAnswer = await imaBLS.handle_skale_imaBSU256( joMessage ); + // joAnswer = await imaBLS.handle_skale_imaBSU256( joMessage ); + isSkipMode = true; + imaBLS.handle_skale_imaBSU256( joMessage ).then( function( joAnswer ) { + try { + if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) + log.write( strLogPrefix + cc.sunny( ">>>" ) + " " + cc.normal( "answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); + ws_peer.send( JSON.stringify( joAnswer ) ); + } catch ( err ) { + if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { + log.write( strLogPrefix + + cc.error( "Failed to sent answer to " ) + cc.info( ip ) + + cc.error( ", error is: " ) + cc.warning( err ) + "\n" + ); + } + } + } ); break; default: throw new Error( "Unknown method name \"" + joMessage.method + "\" was specified" ); @@ -2277,18 +2311,20 @@ if( imaState.nJsonRpcPort > 0 ) { ); } } - try { - if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) - log.write( strLogPrefix + cc.sunny( ">>>" ) + " " + cc.normal( "answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); - ws_peer.send( JSON.stringify( joAnswer ) ); - } catch ( err ) { - if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { - log.write( strLogPrefix + - cc.error( "Failed to sent answer to " ) + cc.info( ip ) + - cc.error( ", error is: " ) + cc.warning( err ) + "\n" - ); + if( ! isSkipMode ) { + try { + if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) + log.write( strLogPrefix + cc.sunny( ">>>" ) + " " + cc.normal( "answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); + ws_peer.send( JSON.stringify( joAnswer ) ); + } catch ( err ) { + if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { + log.write( strLogPrefix + + cc.error( "Failed to sent answer to " ) + cc.info( ip ) + + cc.error( ", error is: " ) + cc.warning( err ) + "\n" + ); + } } - } + } // if( ! isSkipMode ) } ); // ws_peer.send( "something" ); } ); diff --git a/npms/skale-observer/observer.js b/npms/skale-observer/observer.js index 516e2e2ca..f89f7bb99 100644 --- a/npms/skale-observer/observer.js +++ b/npms/skale-observer/observer.js @@ -540,7 +540,8 @@ async function ensure_have_worker( opts ) { "strSgxURL": opts.imaState.joAccount_main_net.strSgxURL, "strSgxKeyName": opts.imaState.joAccount_main_net.strSgxKeyName, "strPathSslKey": opts.imaState.joAccount_main_net.strPathSslKey, - "strPathSslCert": opts.imaState.joAccount_main_net.strPathSslCert + "strPathSslCert": opts.imaState.joAccount_main_net.strPathSslCert, + "strBlsKeyName": opts.imaState.joAccount_main_net.strBlsKeyName }, "joAccount_s_chain": { "privateKey": opts.imaState.joAccount_s_chain.privateKey, @@ -550,7 +551,8 @@ async function ensure_have_worker( opts ) { "strSgxURL": opts.imaState.joAccount_s_chain.strSgxURL, "strSgxKeyName": opts.imaState.joAccount_s_chain.strSgxKeyName, "strPathSslKey": opts.imaState.joAccount_s_chain.strPathSslKey, - "strPathSslCert": opts.imaState.joAccount_s_chain.strPathSslCert + "strPathSslCert": opts.imaState.joAccount_s_chain.strPathSslCert, + "strBlsKeyName": opts.imaState.joAccount_s_chain.strBlsKeyName }, // "tc_main_net": IMA.tc_main_net, // "tc_s_chain": IMA.tc_s_chain, diff --git a/test/agent-test.js b/test/agent-test.js index 810635e92..b45863221 100644 --- a/test/agent-test.js +++ b/test/agent-test.js @@ -187,7 +187,8 @@ global.imaState = { "strSgxURL": owaspUtils.toStringURL( process.env.SGX_URL_ETHEREUM ), "strSgxKeyName": owaspUtils.toStringURL( process.env.SGX_KEY_ETHEREUM ), "strPathSslKey": ( process.env.SGX_SSL_KEY_FILE_ETHEREUM || "" ).toString().trim(), - "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_ETHEREUM || "" ).toString().trim() + "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_ETHEREUM || "" ).toString().trim(), + "strBlsKeyName": owaspUtils.toStringURL( process.env.BLS_KEY_ETHEREUM ) }, "joAccount_s_chain": { "privateKey": owaspUtils.toEthPrivateKey( process.env.PRIVATE_KEY_FOR_SCHAIN ), @@ -196,7 +197,8 @@ global.imaState = { "strSgxURL": owaspUtils.toStringURL( process.env.SGX_URL_S_CHAIN ), "strSgxKeyName": owaspUtils.toStringURL( process.env.SGX_KEY_S_CHAIN ), "strPathSslKey": ( process.env.SGX_SSL_KEY_FILE_S_CHAIN || "" ).toString().trim(), - "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_S_CHAIN || "" ).toString().trim() + "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_S_CHAIN || "" ).toString().trim(), + "strBlsKeyName": owaspUtils.toStringURL( process.env.BLS_KEY_S_CHAIN ) }, "joAccount_t_chain": { "privateKey": owaspUtils.toEthPrivateKey( process.env.PRIVATE_KEY_FOR_SCHAIN_TARGET ), @@ -205,7 +207,8 @@ global.imaState = { "strSgxURL": owaspUtils.toStringURL( process.env.SGX_URL_S_CHAIN_TARGET ), "strSgxKeyName": owaspUtils.toStringURL( process.env.SGX_KEY_S_CHAIN_TARGET ), "strPathSslKey": ( process.env.SGX_SSL_KEY_FILE_S_CHAIN_TARGET || "" ).toString().trim(), - "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_S_CHAIN_TARGET || "" ).toString().trim() + "strPathSslCert": ( process.env.SGX_SSL_CERT_FILE_S_CHAIN_TARGET || "" ).toString().trim(), + "strBlsKeyName": owaspUtils.toStringURL( process.env.BLS_KEY_T_CHAIN ) }, // From b8f512f8209d3dd18b223056bd491ef7d4ec5930 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Mon, 3 Oct 2022 20:14:57 +0100 Subject: [PATCH 07/23] JS only IMA agent, first working version --- agent/bls.js | 24 +++++++-------------- agent/main.js | 59 ++++++++++++++++++--------------------------------- 2 files changed, 29 insertions(+), 54 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index c2c5fa614..75bcddf4b 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -1097,7 +1097,7 @@ async function do_sign_messages_impl( ++joGatheringTracker.nCountErrors; } } catch ( err ) { - ++nCountErrors; + ++joGatheringTracker.nCountErrors; const strErrorMessage = strLogPrefix + cc.error( "S-Chain node " ) + strNodeDescColorized + " " + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " signature fail from node " ) + cc.info( joNode.nodeID ) + @@ -1505,7 +1505,7 @@ async function do_sign_u256( u256, details, fn ) { ++joGatheringTracker.nCountErrors; } } catch ( err ) { - ++nCountErrors; + ++joGatheringTracker.nCountErrors; const strErrorMessage = strLogPrefix + cc.error( "S-Chain node " ) + strNodeDescColorized + " " + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " signature fail from node " ) + cc.info( joNode.nodeID ) + @@ -1748,21 +1748,13 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { throw new Error( "JSON RPC call to SGX failed, RPC call reported error: " + owaspUtil.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "SGX" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); - if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { - const strErrorMessage = - strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + - cc.error( "SGX reported wallet error: " ) + - cc.warning( owaspUtil.extract_error_message( joOut, "unknown wallet error(4)" ) ) + - cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + - "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - details.write( strErrorMessage ); - throw new Error( "JSON RPC call to SGX failed with \"unknown wallet error(4)\", sequence ID is " + sequence_id ); - } + let joSignResult = joOut; + if( joOut.result != null && joOut.result != undefined && typeof joOut.result == "object" ) + joSignResult = joOut.result; + if( joOut.signResult != null && joOut.signResult != undefined && typeof joOut.signResult == "object" ) + joSignResult = joOut.signResult; isSuccess = true; - const joSignResult = ( "result" in joOut ) ? joOut.result : joOut; - joRetVal.signResult = joSignResult; + joRetVal.result = { signResult: joSignResult }; if( "qa" in joCallData ) joRetVal.qa = joCallData.qa; } ); // joCall.call ... diff --git a/agent/main.js b/agent/main.js index e5ea1ed91..e35a15748 100644 --- a/agent/main.js +++ b/agent/main.js @@ -2251,6 +2251,22 @@ if( imaState.nJsonRpcPort > 0 ) { if( ! ( "id" in joMessage ) ) throw new Error( "\"id\" field was not specified" ); joAnswer.id = joMessage.id; + const fn_send_answer = function( joAnswer ) { + try { + joAnswer.method = joMessage.method; + joAnswer.id = joMessage.id; + if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) + log.write( strLogPrefix + cc.sunny( ">>>" ) + " " + cc.normal( "answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); + ws_peer.send( JSON.stringify( joAnswer ) ); + } catch ( err ) { + if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { + log.write( strLogPrefix + + cc.error( "Failed to sent answer to " ) + cc.info( ip ) + + cc.error( ", error is: " ) + cc.warning( err ) + "\n" + ); + } + } + }; switch ( joMessage.method ) { case "echo": case "ping": @@ -2268,36 +2284,14 @@ if( imaState.nJsonRpcPort > 0 ) { // joAnswer = await imaBLS.handle_skale_imaVerifyAndSign( joMessage ); isSkipMode = true; imaBLS.handle_skale_imaVerifyAndSign( joMessage ).then( function( joAnswer ) { - try { - if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) - log.write( strLogPrefix + cc.sunny( ">>>" ) + " " + cc.normal( "answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); - ws_peer.send( JSON.stringify( joAnswer ) ); - } catch ( err ) { - if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { - log.write( strLogPrefix + - cc.error( "Failed to sent answer to " ) + cc.info( ip ) + - cc.error( ", error is: " ) + cc.warning( err ) + "\n" - ); - } - } + fn_send_answer( joAnswer ); } ); break; case "skale_imaBSU256": // joAnswer = await imaBLS.handle_skale_imaBSU256( joMessage ); isSkipMode = true; imaBLS.handle_skale_imaBSU256( joMessage ).then( function( joAnswer ) { - try { - if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) - log.write( strLogPrefix + cc.sunny( ">>>" ) + " " + cc.normal( "answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); - ws_peer.send( JSON.stringify( joAnswer ) ); - } catch ( err ) { - if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { - log.write( strLogPrefix + - cc.error( "Failed to sent answer to " ) + cc.info( ip ) + - cc.error( ", error is: " ) + cc.warning( err ) + "\n" - ); - } - } + fn_send_answer( joAnswer ); } ); break; default: @@ -2311,20 +2305,9 @@ if( imaState.nJsonRpcPort > 0 ) { ); } } - if( ! isSkipMode ) { - try { - if( IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) - log.write( strLogPrefix + cc.sunny( ">>>" ) + " " + cc.normal( "answer to " ) + cc.info( ip ) + cc.normal( ": " ) + cc.j( joAnswer ) + "\n" ); - ws_peer.send( JSON.stringify( joAnswer ) ); - } catch ( err ) { - if( IMA.verbose_get() >= IMA.RV_VERBOSE.error ) { - log.write( strLogPrefix + - cc.error( "Failed to sent answer to " ) + cc.info( ip ) + - cc.error( ", error is: " ) + cc.warning( err ) + "\n" - ); - } - } - } // if( ! isSkipMode ) + if( ! isSkipMode ) + fn_send_answer( joAnswer ); + // if( ! isSkipMode ) } ); // ws_peer.send( "something" ); } ); From 2ca10469e870178cda172ecf89f26b3ecc519072 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Mon, 3 Oct 2022 20:24:32 +0100 Subject: [PATCH 08/23] transient commit, working on JS only IMA agent --- agent/bls.js | 98 ++++++++++++++++----------------- agent/cli.js | 4 +- agent/main.js | 2 +- agent/oracle.js | 18 +++--- npms/skale-ima/index.js | 36 ++++++------ npms/skale-observer/observer.js | 12 ++-- 6 files changed, 85 insertions(+), 85 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 75bcddf4b..406c3048b 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -46,7 +46,7 @@ async function with_timeout( strDescription, promise, seconds ) { let result_err = null, isComplete = false; promise.catch( function( err ) { isComplete = true; - result_err = new Error( strDescription + "error: " + owaspUtil.extract_error_message( err ) ); + result_err = new Error( strDescription + "error: " + owaspUtils.extract_error_message( err ) ); } ).finally( function() { isComplete = true; } ); @@ -363,7 +363,7 @@ function perform_bls_glue( // fnShellRestore(); } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "BLS glue CRITICAL ERROR:" ) + cc.error( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "BLS glue CRITICAL ERROR:" ) + cc.error( " error description is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "BLS glue output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -462,7 +462,7 @@ function perform_bls_glue_u256( details, u256, arrSignResults ) { // fnShellRestore(); } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "BLS glue CRITICAL ERROR:" ) + cc.error( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "BLS glue CRITICAL ERROR:" ) + cc.error( " error description is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "BLS glue output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -526,7 +526,7 @@ function perform_bls_verify_i( fnShellRestore(); return true; } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " BLS node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify error:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " BLS node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify error:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "CRITICAL ERROR:" ) + cc.error( " BLS node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -575,7 +575,7 @@ function perform_bls_verify_i_u256( details, nZeroBasedNodeIndex, joResultFromNo fnShellRestore(); return true; } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " BLS u256 node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify error:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " BLS u256 node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify error:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "CRITICAL ERROR:" ) + cc.error( " BLS u256 node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.error( " verify output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -644,7 +644,7 @@ function perform_bls_verify( fnShellRestore(); return true; } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "BLS/summary verify CRITICAL ERROR:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "BLS/summary verify CRITICAL ERROR:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "BLS/summary verify output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -702,7 +702,7 @@ function perform_bls_verify_u256( details, joGlueResult, u256, joCommonPublicKey fnShellRestore(); return true; } catch ( err ) { - const s1 = strLogPrefix + cc.fatal( "BLS u256/summary verify CRITICAL ERROR:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const s1 = strLogPrefix + cc.fatal( "BLS u256/summary verify CRITICAL ERROR:" ) + cc.normal( " error description is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; const s2 = strLogPrefix + cc.error( "BLS u256/summary verify output is:\n" ) + cc.notice( strOutput ) + "\n"; log.write( s1 ); details.write( s1 ); @@ -786,7 +786,7 @@ async function check_correctness_of_messages_to_sign( details, strLogPrefix, str cc.error( " Correctness validation failed for message " ) + cc.info( idxMessage ) + cc.error( " sent to " ) + cc.info( joChainName ) + cc.error( ", message is: " ) + cc.j( joMessage ) + - cc.error( ", error information: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error information: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( s ); details.write( s ); @@ -932,7 +932,7 @@ async function do_sign_messages_impl( const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -993,7 +993,7 @@ async function do_sign_messages_impl( const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call reported error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( " failed, RPC call reported error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -1015,7 +1015,7 @@ async function do_sign_messages_impl( strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + cc.error( "S-Chain node " ) + strNodeDescColorized + cc.error( " reported wallet error: " ) + - cc.warning( owaspUtil.extract_error_message( joOut, "unknown wallet error(1)" ) ) + + cc.warning( owaspUtils.extract_error_message( joOut, "unknown wallet error(1)" ) ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -1070,7 +1070,7 @@ async function do_sign_messages_impl( const strErrorMessage = strLogPrefixA + cc.error( "S-Chain node " ) + strNodeDescColorized + cc.error( " sign " ) + cc.error( " CRITICAL ERROR:" ) + cc.error( " partial signature fail from with index " ) + cc.info( nZeroBasedNodeIndex ) + - cc.error( ", error is " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -1101,7 +1101,7 @@ async function do_sign_messages_impl( const strErrorMessage = strLogPrefix + cc.error( "S-Chain node " ) + strNodeDescColorized + " " + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " signature fail from node " ) + cc.info( joNode.nodeID ) + - cc.error( ", error is " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -1158,10 +1158,10 @@ async function do_sign_messages_impl( log.write( cc.debug( "Will call sending function (fn)" ) + "\n" ); details.write( cc.debug( "Will call sending function (fn) for " ) + "\n" ); /*await*/ fn( strError, jarrMessages, joGlueResult ).catch( ( err ) => { - const strErrorMessage = cc.error( "Problem(2) in BLS sign result handler: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const strErrorMessage = cc.error( "Problem(2) in BLS sign result handler: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - errGathering = "Problem(2) in BLS sign result handler: " + owaspUtil.extract_error_message( err ); + errGathering = "Problem(2) in BLS sign result handler: " + owaspUtils.extract_error_message( err ); return; } ); bHaveResultReportCalled = true; @@ -1177,13 +1177,13 @@ async function do_sign_messages_impl( /*await*/ fn( "signature error(2), got " + joGatheringTracker.nCountErrors + " errors(s) for " + jarrNodes.length + " node(s)", jarrMessages, null ).catch( ( err ) => { const strErrorMessage = cc.error( "Problem(3) in BLS sign result handler, not enough successful BLS signature parts(" ) + - cc.info( cntSuccess ) + cc.error( " when all attempts done, error details: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.info( cntSuccess ) + cc.error( " when all attempts done, error details: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); errGathering = "Problem(3) in BLS sign result handler, not enough successful BLS signature parts(" + - cntSuccess + " when all attempts done, error details: " + owaspUtil.extract_error_message( err ); + cntSuccess + " when all attempts done, error details: " + owaspUtils.extract_error_message( err ); reject( new Error( errGathering ) ); } ); bHaveResultReportCalled = true; @@ -1195,12 +1195,12 @@ async function do_sign_messages_impl( const strErrorMessage = cc.error( "Problem(4) in BLS sign result handler, not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error details: " ) + - cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); errGathering = "Problem(4) in BLS sign result handler, not enough successful BLS signature parts(" + - cntSuccess + ") and timeout reached, error details: " + owaspUtil.extract_error_message( err ); + cntSuccess + ") and timeout reached, error details: " + owaspUtils.extract_error_message( err ); reject( new Error( errGathering ) ); } ); bHaveResultReportCalled = true; @@ -1214,7 +1214,7 @@ async function do_sign_messages_impl( details.write( cc.success( "BLS verification and sending promise awaited." ) + "\n" ); log.write( cc.success( "BLS verification and sending promise awaited." ) + "\n" ); } ).catch( err => { - const strErrorMessage = cc.error( "Failed to verify BLS and send message : " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const strErrorMessage = cc.error( "Failed to verify BLS and send message : " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); } ); @@ -1233,7 +1233,7 @@ async function do_sign_messages_impl( const strErrorMessage = cc.error( "Problem(5) in BLS sign result handler, not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error details: " ) + - cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); details.exposeDetailsTo( log, strGatheredDetailsName, false ); @@ -1244,7 +1244,7 @@ async function do_sign_messages_impl( return; } if( ! bHaveResultReportCalled ) { - const strErrorMessage = cc.error( "Failed BLS sign result awaiting(2): " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const strErrorMessage = cc.error( "Failed BLS sign result awaiting(2): " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); bHaveResultReportCalled = true; @@ -1252,7 +1252,7 @@ async function do_sign_messages_impl( const strErrorMessage = cc.error( "Problem(6) in BLS sign result handler, not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error details: " ) + - cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); details.exposeDetailsTo( log, strGatheredDetailsName, false ); @@ -1262,15 +1262,15 @@ async function do_sign_messages_impl( } } catch ( err ) { const strErrorMessage = - cc.error( "Failed BLS sign due to generic flow exception: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( "Failed BLS sign due to generic flow exception: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + cc.error( ", call stack is: " ) + "\n" + err.stack() + "\n"; log.write( strErrorMessage ); if( details ) details.write( strErrorMessage ); if( ! bHaveResultReportCalled ) { bHaveResultReportCalled = true; - await fn( "Failed BLS sign due to exception: " + owaspUtil.extract_error_message( err ), jarrMessages, null ).catch( ( err ) => { - const strErrorMessage = cc.error( "Failed BLS sign due to error-erporting callback exception: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + await fn( "Failed BLS sign due to exception: " + owaspUtils.extract_error_message( err ), jarrMessages, null ).catch( ( err ) => { + const strErrorMessage = cc.error( "Failed BLS sign due to error-erporting callback exception: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); if( details ) { details.write( strErrorMessage ); @@ -1396,7 +1396,7 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); return; @@ -1417,7 +1417,7 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain node " ) + strNodeDescColorized + - cc.error( " failed, RPC call reported error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.error( " failed, RPC call reported error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); return; @@ -1433,7 +1433,7 @@ async function do_sign_u256( u256, details, fn ) { strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + cc.error( "S-Chain node " ) + strNodeDescColorized + cc.error( " reported wallet error: " ) + - cc.warning( owaspUtil.extract_error_message( joOut, "unknown wallet error(2)" ) ) + + cc.warning( owaspUtils.extract_error_message( joOut, "unknown wallet error(2)" ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); @@ -1480,7 +1480,7 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = strLogPrefixA + cc.error( "S-Chain node " ) + strNodeDescColorized + cc.error( " sign " ) + cc.error( " CRITICAL ERROR:" ) + cc.error( " partial signature fail from with index " ) + cc.info( nZeroBasedNodeIndex ) + - cc.error( ", error is " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.error( ", error is " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); } @@ -1509,7 +1509,7 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = strLogPrefix + cc.error( "S-Chain node " ) + strNodeDescColorized + " " + cc.fatal( "CRITICAL ERROR:" ) + cc.error( " signature fail from node " ) + cc.info( joNode.nodeID ) + - cc.error( ", error is " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.error( ", error is " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); } @@ -1553,10 +1553,10 @@ async function do_sign_u256( u256, details, fn ) { log.write( cc.debug( "Will call sending function (fn)" ) + "\n" ); details.write( cc.debug( "Will call sending function (fn) for " ) + "\n" ); /*await*/ fn( strError, u256, joGlueResult ).catch( ( err ) => { - const strErrorMessage = cc.error( "Problem(2) in BLS u256 sign result handler: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const strErrorMessage = cc.error( "Problem(2) in BLS u256 sign result handler: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - errGathering = "Problem(2) in BLS u256 sign result handler: " + owaspUtil.extract_error_message( err ); + errGathering = "Problem(2) in BLS u256 sign result handler: " + owaspUtils.extract_error_message( err ); } ); if( strError ) { errGathering = strError; @@ -1570,13 +1570,13 @@ async function do_sign_u256( u256, details, fn ) { /*await*/ fn( "signature error(2, u256), got " + joGatheringTracker.nCountErrors + " errors(s) for " + jarrNodes.length + " node(s)", u256, null ).catch( ( err ) => { const strErrorMessage = cc.error( "Problem(3) in BLS u256 sign result handler, not enough successful BLS signature parts(" ) + - cc.info( cntSuccess ) + cc.error( " when all attempts done, error details: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.info( cntSuccess ) + cc.error( " when all attempts done, error details: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); errGathering = "Problem(3) in BLS u256 sign result handler, not enough successful BLS signature parts(" + - cntSuccess + " when all attempts done, error details: " + owaspUtil.extract_error_message( err ); + cntSuccess + " when all attempts done, error details: " + owaspUtils.extract_error_message( err ); reject( new Error( errGathering ) ); } ); return; @@ -1587,12 +1587,12 @@ async function do_sign_u256( u256, details, fn ) { const strErrorMessage = cc.error( "Problem(4) in BLS u256 sign result handler, not enough successful BLS signature parts(" ) + cc.info( cntSuccess ) + cc.error( ") and timeout reached, error details: " ) + - cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); errGathering = "Problem(4) in BLS u256 sign result handler, not enough successful BLS signature parts(" + - cntSuccess + ") and timeout reached, error details: " + owaspUtil.extract_error_message( err ); + cntSuccess + ") and timeout reached, error details: " + owaspUtils.extract_error_message( err ); reject( new Error( errGathering ) ); } ); return; @@ -1605,7 +1605,7 @@ async function do_sign_u256( u256, details, fn ) { details.write( cc.info( "BLS u256 sign promise awaited." ) + "\n" ); log.write( cc.info( "BLS u256 sign promise awaited." ) + "\n" ); } ).catch( err => { - const strErrorMessage = cc.error( "Failed to verify BLS and send message : " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + const strErrorMessage = cc.error( "Failed to verify BLS and send message : " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); } ); @@ -1632,27 +1632,27 @@ async function handle_skale_call_via_redirect( joCallData ) { if( err ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call to S-Chain failed, RPC call was not created, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.error( " JSON RPC call to S-Chain failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - throw new Error( "JSON RPC call to S-Chain failed, RPC call was not created, error is: " + owaspUtil.extract_error_message( err ) ); + throw new Error( "JSON RPC call to S-Chain failed, RPC call was not created, error is: " + owaspUtils.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Will invoke " ) + cc.info( "S-Chain" ) + cc.debug( " with call data " ) + cc.j( joCallData ) + "\n" ); await joCall.call( joCallData, async function( joIn, joOut, err ) { if( err ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call to S-Chain failed, RPC call reported error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.error( " JSON RPC call to S-Chain failed, RPC call reported error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - throw new Error( "JSON RPC call to S-Chain failed, RPC call reported error: " + owaspUtil.extract_error_message( err ) ); + throw new Error( "JSON RPC call to S-Chain failed, RPC call reported error: " + owaspUtils.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "S-Chain" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { const strErrorMessage = strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + cc.error( "S-Chain reported wallet error: " ) + - cc.warning( owaspUtil.extract_error_message( joOut, "unknown wallet error(3)" ) ) + + cc.warning( owaspUtils.extract_error_message( joOut, "unknown wallet error(3)" ) ) + cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + "\n"; log.write( strErrorMessage ); @@ -1666,7 +1666,7 @@ async function handle_skale_call_via_redirect( joCallData ) { } ); // rpcCall.create ... } catch ( err ) { isSuccess = false; - const strError = owaspUtil.extract_error_message( err ); + const strError = owaspUtils.extract_error_message( err ); joRetVal.error = strError; const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + @@ -1721,10 +1721,10 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { if( err ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call to SGX failed, RPC call was not created, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.error( " JSON RPC call to SGX failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - throw new Error( "JSON RPC call to SGX failed, RPC call was not created, error is: " + owaspUtil.extract_error_message( err ) ); + throw new Error( "JSON RPC call to SGX failed, RPC call was not created, error is: " + owaspUtils.extract_error_message( err ) ); } const joCallSGX = { method: "blsSignMessageHash", @@ -1742,10 +1742,10 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { if( err ) { const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call to SGX failed, RPC call reported error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.error( " JSON RPC call to SGX failed, RPC call reported error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - throw new Error( "JSON RPC call to SGX failed, RPC call reported error: " + owaspUtil.extract_error_message( err ) ); + throw new Error( "JSON RPC call to SGX failed, RPC call reported error: " + owaspUtils.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "SGX" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); let joSignResult = joOut; @@ -1761,7 +1761,7 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { } ); // rpcCall.create ... } catch ( err ) { isSuccess = false; - const strError = owaspUtil.extract_error_message( err ); + const strError = owaspUtils.extract_error_message( err ); joRetVal.error = strError; const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + diff --git a/agent/cli.js b/agent/cli.js index 60d6e4f65..1f2c59f7b 100644 --- a/agent/cli.js +++ b/agent/cli.js @@ -1299,7 +1299,7 @@ function getWeb3FromURL( strURL, log ) { } catch ( err ) { log.write( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " Failed to create " ) + cc.attention( "Web3" ) + cc.error( " connection to " ) + cc.info( strURL ) + - cc.error( ": " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + cc.error( ": " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); w3 = null; } return w3; @@ -1320,7 +1320,7 @@ async function async_check_url_at_startup( u, name ) { } catch ( err ) { details.write( cc.fatal( "ERROR:" ) + cc.error( " Failed to check URL " ) + - cc.u( u ) + cc.error( " connectivity for " ) + cc.info( name ) + cc.error( " at start-up, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.u( u ) + cc.error( " connectivity for " ) + cc.info( name ) + cc.error( " at start-up, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); } // details.exposeDetailsTo( log, "async_check_url_at_startup( \"" + u + "\", \"" + name + "\" )", true ); diff --git a/agent/main.js b/agent/main.js index e35a15748..716c773bb 100644 --- a/agent/main.js +++ b/agent/main.js @@ -2662,7 +2662,7 @@ async function single_transfer_loop() { log.write( strLogPrefix + cc.debug( "Completed: " ) + cc.tf( bResult ) + "\n" ); return bResult; } catch ( err ) { - log.write( strLogPrefix + cc.fatal( "Exception:" ) + + cc.error( owaspUtil.extract_error_message( err ) ) + "\n" ); + log.write( strLogPrefix + cc.fatal( "Exception:" ) + + cc.error( owaspUtils.extract_error_message( err ) ) + "\n" ); } g_is_single_transfer_loop = false; return false; diff --git a/agent/oracle.js b/agent/oracle.js index 385e3ed8a..809e45bb6 100644 --- a/agent/oracle.js +++ b/agent/oracle.js @@ -90,9 +90,9 @@ function oracle_get_gas_price( oracleOpts, details ) { cntAttempts = 1; rpcCall.create( url, callOpts || { }, async function( joCall, err ) { if( err ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC connection problem for url " ) + cc.u( url ) + cc.error( ", error description: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC connection problem for url " ) + cc.u( url ) + cc.error( ", error description: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); - reject( new Error( "CRITICAL ORACLE CALL ERROR: RPC connection problem for url \"" + url + "\", error description: " + owaspUtil.extract_error_message( err ) ) ); + reject( new Error( "CRITICAL ORACLE CALL ERROR: RPC connection problem for url \"" + url + "\", error description: " + owaspUtils.extract_error_message( err ) ) ); return; } try { @@ -110,10 +110,10 @@ function oracle_get_gas_price( oracleOpts, details ) { await joCall.call( joIn, async function( joIn, joOut, err ) { if( err ) { if( isVerboseTraceDetails ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " JSON RPC call" ) + cc.debug( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + cc.error( " failed, error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " JSON RPC call" ) + cc.debug( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + cc.error( " failed, error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); } - reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_submitRequest) failed, error: " + owaspUtil.extract_error_message( err ) ) ); + reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_submitRequest) failed, error: " + owaspUtils.extract_error_message( err ) ) ); return; } if( isVerboseTraceDetails ) @@ -140,10 +140,10 @@ function oracle_get_gas_price( oracleOpts, details ) { await joCall.call( joIn, async function( joIn, joOut, err ) { if( err ) { if( isVerboseTraceDetails ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " JSON RPC call" ) + cc.debug( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " failed, error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " JSON RPC call" ) + cc.debug( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " failed, error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); } - //reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_checkResult) failed, error: " + owaspUtil.extract_error_message( err ) ) ); + //reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_checkResult) failed, error: " + owaspUtils.extract_error_message( err ) ) ); return; } if( isVerboseTraceDetails ) @@ -166,7 +166,7 @@ function oracle_get_gas_price( oracleOpts, details ) { return; } ); } catch ( err ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " exception is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " exception is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); reject( err ); return; @@ -177,14 +177,14 @@ function oracle_get_gas_price( oracleOpts, details ) { return; } ); } catch ( err ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + cc.error( " exception is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + cc.error( " exception is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); reject( err ); return; } } ); } catch ( err ) { - details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call object creation failed, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call object creation failed, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); reject( err ); return; diff --git a/npms/skale-ima/index.js b/npms/skale-ima/index.js index aa759c4f1..e30f308e8 100644 --- a/npms/skale-ima/index.js +++ b/npms/skale-ima/index.js @@ -192,7 +192,7 @@ async function get_web3_blockNumber( details, cntAttempts, w3, retValOnFail, thr cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -222,7 +222,7 @@ async function get_web3_blockNumber( details, cntAttempts, w3, retValOnFail, thr cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -257,7 +257,7 @@ async function get_web3_transactionCount( details, cntAttempts, w3, address, par cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -287,7 +287,7 @@ async function get_web3_transactionCount( details, cntAttempts, w3, address, par cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -322,7 +322,7 @@ async function get_web3_transactionReceipt( details, cntAttempts, w3, txHash, re cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -352,7 +352,7 @@ async function get_web3_transactionReceipt( details, cntAttempts, w3, txHash, re cc.error( "Failed call attempt " ) + cc.info( idxAttempt ) + cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + - cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); } ++ idxAttempt; @@ -393,9 +393,9 @@ async function get_web3_pastEvents( details, w3, cntAttempts, joContract, strEve cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + cc.error( ", from block " ) + cc.warning( nBlockFrom ) + cc.error( ", to block " ) + cc.warning( nBlockTo ) + - cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); - if( owaspUtil.extract_error_message( err ).indexOf( strErrorTextAboutNotExistingEvent ) >= 0 ) { + if( owaspUtils.extract_error_message( err ).indexOf( strErrorTextAboutNotExistingEvent ) >= 0 ) { details.write( cc.error( "Did stopped calls to " ) + cc.note( strFnName + "()" ) + cc.error( " because event " ) + cc.notice( strEventName ) + @@ -439,9 +439,9 @@ async function get_web3_pastEvents( details, w3, cntAttempts, joContract, strEve cc.error( " to " ) + cc.note( strFnName + "()" ) + cc.error( " via " ) + cc.u( u ) + cc.error( ", from block " ) + cc.warning( nBlockFrom ) + cc.error( ", to block " ) + cc.warning( nBlockTo ) + - cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); - if( owaspUtil.extract_error_message( err ).indexOf( strErrorTextAboutNotExistingEvent ) >= 0 ) { + if( owaspUtils.extract_error_message( err ).indexOf( strErrorTextAboutNotExistingEvent ) >= 0 ) { details.write( cc.error( "Did stopped calls to " ) + cc.note( strFnName + "()" ) + cc.error( " because event " ) + cc.notice( strEventName ) + @@ -552,7 +552,7 @@ async function get_web3_pastEventsIterative( details, w3, attempts, joContract, cc.error( "Got scan error during interative scan of " ) + cc.info( idxBlockSubRangeFrom ) + cc.error( "/" ) + cc.info( idxBlockSubRangeTo ) + cc.error( " block sub-range in " ) + cc.info( nBlockFrom ) + cc.error( "/" ) + cc.info( nBlockTo ) + - cc.error( " block range, error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" + cc.error( " block range, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); } idxBlockSubRangeFrom = idxBlockSubRangeTo; @@ -721,7 +721,7 @@ async function do_oracle_gas_price_setup( details.write( cc.error( "Failed to fetch " ) + cc.info( "Main Net gas price" ) + cc.error( " via call to " ) + cc.info( "Oracle" ) + - cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + cc.error( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); } } if( gasPriceOnMainNet === null ) { @@ -1141,8 +1141,8 @@ async function dry_run_call( details, w3, methodWithArguments, joAccount, strDRC details.write( strLogPrefix + cc.fatal( "CRITICAL DRY RUN FAIL" ) + " " + cc.error( " invoking the " ) + cc.info( strMethodName ) + cc.error( " method: " ) + - cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); - return "CRITICAL DRY RUN FAIL invoking the \"" + strMethodName + "\" method: " + owaspUtil.extract_error_message( err ); + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); + return "CRITICAL DRY RUN FAIL invoking the \"" + strMethodName + "\" method: " + owaspUtils.extract_error_message( err ); } } return null; @@ -1418,7 +1418,7 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc strMsg = cc.fatal( "BAD ERROR:" ) + " " + cc.error( "TM - transaction was not sent, underlying error is: " ) + - cc.warning( owaspUtil.extract_error_message( err ) ); + cc.warning( owaspUtils.extract_error_message( err ) ); details.write( strPrefixDetails + strMsg + "\n" ); log.write( strPrefixLog + strMsg + "\n" ); // throw err; @@ -5673,7 +5673,7 @@ async function do_transfer( ++ cntFailedNodes; const strError = strLogPrefix + cc.fatal( strDirection + " message analysis error:" ) + " " + cc.error( "Failed to scan events on node " ) + cc.info( jo_node.name ) + - cc.error( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + + cc.error( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + cc.error( ", detailed node description is: " ) + cc.j( jo_node ) + "\n"; details.write( strError ); @@ -5716,7 +5716,7 @@ async function do_transfer( cc.error( "Failed to process events for " ) + cc.sunny( strDirection ) + cc.error( " message " ) + cc.info( idxMessage + 1 ) + cc.error( " on node " ) + cc.info( jo_node.name ) + cc.success( " using URL " ) + cc.info( jo_node.http_endpoint_ip ) + - cc.debug( ", error is: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n"; + cc.debug( ", error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; details.write( strError ); if( verbose_get() >= RV_VERBOSE.fatal ) log.write( strError ); @@ -5970,7 +5970,7 @@ async function do_transfer( } ); // fn_sign_messages } catch ( err ) { const strError = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " Exception from sigining messages function: " ) + cc.error( owaspUtil.extract_error_message( err ) ); + cc.error( " Exception from sigining messages function: " ) + cc.error( owaspUtils.extract_error_message( err ) ); log.write( strError + "\n" ); details.write( strError + "\n" ); if( detailsB ) diff --git a/npms/skale-observer/observer.js b/npms/skale-observer/observer.js index f89f7bb99..298d2a41f 100644 --- a/npms/skale-observer/observer.js +++ b/npms/skale-observer/observer.js @@ -70,7 +70,7 @@ function getWeb3FromURL( strURL, log ) { } catch ( err ) { log.write( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " Failed to create " ) + cc.attention( "Web3" ) + cc.error( " connection to " ) + cc.info( strURL ) + - cc.error( ": " ) + cc.warning( owaspUtil.extract_error_message( err ) ) ); + cc.error( ": " ) + cc.warning( owaspUtils.extract_error_message( err ) ) ); w3 = null; } return w3; @@ -310,7 +310,7 @@ async function load_schains_connected_only( w3_main_net, w3_s_chain, strChainNam arr_schains.push( jo_schain ); } catch ( err ) { if( opts && opts.details ) { - opts.details.write( cc.error( "Got error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + opts.details.write( cc.error( "Got error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); opts.details.write( err.stack ); } } @@ -346,7 +346,7 @@ async function check_connected_schains( strChainNameConnectedTo, arr_schains, ad } } catch ( err ) { if( opts && opts.details ) { - opts.details.write( cc.error( "Got error: " ) + cc.warning( owaspUtil.extract_error_message( err ) ) + "\n" ); + opts.details.write( cc.error( "Got error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); opts.details.write( err.stack ); } } @@ -458,7 +458,7 @@ async function cache_schains( strChainNameConnectedTo, w3_main_net, w3_s_chain, if( opts.fn_chache_changed ) opts.fn_chache_changed( g_arr_schains_cached, null ); // null - no error } catch ( err ) { - strError = owaspUtil.extract_error_message( err ); + strError = owaspUtils.extract_error_message( err ); if( ! strError ) strError = "unknown exception during S-Chains download"; if( opts.fn_chache_changed ) @@ -616,7 +616,7 @@ async function discover_chain_id( strURL ) { const rpcCallOpts = null; await rpcCall.create( strURL, rpcCallOpts, async function( joCall, err ) { if( err ) { - //ret = "Failed to create RPC (" + strURL + ") call: " + owaspUtil.extract_error_message( err ); + //ret = "Failed to create RPC (" + strURL + ") call: " + owaspUtils.extract_error_message( err ); return; } await joCall.call( { @@ -624,7 +624,7 @@ async function discover_chain_id( strURL ) { "params": [] }, async function( joIn, joOut, err ) { if( err ) { - //ret = "Failed to query RPC (" + strURL + ") for chain ID: " + owaspUtil.extract_error_message( err ); + //ret = "Failed to query RPC (" + strURL + ") for chain ID: " + owaspUtils.extract_error_message( err ); return; } if( ! ( "result" in joOut && joOut.result ) ) { From 319bbc3fb318a977281caddd0188d6dffc6f79f5 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 11 Oct 2022 16:24:06 +0100 Subject: [PATCH 09/23] Added IMA message verfication into skale_imaVerifyAndSign handler --- agent/bls.js | 29 ++++++++++++++++++++++++++++- npms/skale-ima/index.js | 2 +- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 406c3048b..d7343eeb9 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -31,7 +31,7 @@ const child_process = require( "child_process" ); const shell = require( "shelljs" ); const { Keccak } = require( "sha3" ); const { cc } = require( "./utils" ); -const owaspUtil = require( "../npms/skale-owasp/owasp-util" ); +const owaspUtils = require( "../npms/skale-owasp/owasp-util" ); function init() { owaspUtils.owaspAddUsageRef(); @@ -1690,6 +1690,7 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { details.write( strLogPrefix + cc.debug( "Will verify and sign " ) + cc.j( joCallData ) + "\n" ); const nIdxCurrentMsgBlockStart = joCallData.params.startMessageIdx; const strFromChainName = joCallData.params.srcChainName; + const strDirection = joCallData.params.direction; const jarrMessages = joCallData.params.messages; const nThreshold = discover_bls_threshold( imaState.joSChainNetworkInfo ); const nParticipants = discover_bls_participants( imaState.joSChainNetworkInfo ); @@ -1698,6 +1699,32 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { const strMessageHash = owaspUtils.remove_starting_0x( keccak256_message( jarrMessages, nIdxCurrentMsgBlockStart, strFromChainName ) ); details.write( strLogPrefix + cc.debug( "Message hash to sign is " ) + cc.info( strMessageHash ) + "\n" ); // + const joExtraSignOpts = null; + if( strDirection == "S2S" ) { + // joCallData.params.dstChainName + // joCallData.params.srcChainName + const strSChainNameSrc = joCallData.params.srcChainName; + const arr_schains_cached = skale_observer.get_last_cached_schains(); + if( ( !arr_schains_cached ) || arr_schains_cached.length == 0 ) + throw new Error( "Could not handle S2S skale_imaVerifyAndSign(1), no S-Chains in SKALE NETWORK observer cached yet, try again later" ); + const jo_schain_src = null; + let strUrlSrcSChain = null; + for( let idxChain = 0; idxChain < arr_schains_cached.length; ++ idxChain ) { + const jo_schain = arr_schains_cached[idxSChain]; + if( jo_schain.data.name.toString() == strSChainNameSrc.toString() ) { + strUrlSrcSChain = skale_observer.pick_random_schain_w3_url( jo_schain ); + break; + } + } // for( let idxChain = 0; idxChain < arr_schains_cached.length; ++ idxChain ) + if( jo_schain_src == null || strUrlSrcSChain == null || ( !strUrlSrcSChain.length ) ) + throw new Error( "Could not handle S2S skale_imaVerifyAndSign(2), no S-Chains in SKALE NETWORK observer cached yet, try again later" ); + joExtraSignOpts.skale_observer = skale_observer; + joExtraSignOpts.w3_src = skale_observer.getWeb3FromURL( strUrlSrcSChain, details ); // ???????????????????????????????????????????????????? + joExtraSignOpts.chain_id_src = jo_schain_src.data.computed.schain_id; + joExtraSignOpts.cid_dst = jo_schain_src.data.computed.chainId; + } + await check_correctness_of_messages_to_sign( details, strLogPrefix, strDirection, jarrMessages, nIdxCurrentMsgBlockStart, joExtraSignOpts ); + // let joAccount = imaState.joAccount_s_chain; if( ! joAccount.strURL ) { joAccount = imaState.joAccount_main_net; diff --git a/npms/skale-ima/index.js b/npms/skale-ima/index.js index e30f308e8..2a66dc638 100644 --- a/npms/skale-ima/index.js +++ b/npms/skale-ima/index.js @@ -1550,7 +1550,7 @@ async function safe_send_signed_transaction( details, w3, serializedTx, strActio details.write( strPrefixDetails + strMsg + "\n" ); log.write( strPrefixLog + strMsg + "\n" ); const strTX = "0x" + serializedTx.toString( "hex" ); // strTX is string starting from "0x" - details.write( strLogPrefix + cc.debug( "....signed raw TX is " ) + cc.j( strTX ) + "\n" ); + details.write( strLogPrefix + cc.debug( "....signed raw TX is " ) + cc.info( strTX ) + "\n" ); let joReceipt = null; let bHaveReceipt = false; try { From 33dec68a99b155c50dfca24fdb2d60ac54bb6623 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 11 Oct 2022 16:42:53 +0100 Subject: [PATCH 10/23] Added IMA message verfication into skale_imaVerifyAndSign handler --- agent/bls.js | 4 ++-- npms/skale-ima/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index d7343eeb9..701a91012 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -1709,13 +1709,13 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { throw new Error( "Could not handle S2S skale_imaVerifyAndSign(1), no S-Chains in SKALE NETWORK observer cached yet, try again later" ); const jo_schain_src = null; let strUrlSrcSChain = null; - for( let idxChain = 0; idxChain < arr_schains_cached.length; ++ idxChain ) { + for( let idxSChain = 0; idxSChain < arr_schains_cached.length; ++ idxSChain ) { const jo_schain = arr_schains_cached[idxSChain]; if( jo_schain.data.name.toString() == strSChainNameSrc.toString() ) { strUrlSrcSChain = skale_observer.pick_random_schain_w3_url( jo_schain ); break; } - } // for( let idxChain = 0; idxChain < arr_schains_cached.length; ++ idxChain ) + } // for( let idxSChain = 0; idxSChain < arr_schains_cached.length; ++ idxSChain ) if( jo_schain_src == null || strUrlSrcSChain == null || ( !strUrlSrcSChain.length ) ) throw new Error( "Could not handle S2S skale_imaVerifyAndSign(2), no S-Chains in SKALE NETWORK observer cached yet, try again later" ); joExtraSignOpts.skale_observer = skale_observer; diff --git a/npms/skale-ima/index.js b/npms/skale-ima/index.js index 2a66dc638..50b3f3125 100644 --- a/npms/skale-ima/index.js +++ b/npms/skale-ima/index.js @@ -1550,7 +1550,7 @@ async function safe_send_signed_transaction( details, w3, serializedTx, strActio details.write( strPrefixDetails + strMsg + "\n" ); log.write( strPrefixLog + strMsg + "\n" ); const strTX = "0x" + serializedTx.toString( "hex" ); // strTX is string starting from "0x" - details.write( strLogPrefix + cc.debug( "....signed raw TX is " ) + cc.info( strTX ) + "\n" ); + details.write( strLogPrefix + cc.debug( "....signed raw TX is " ) + cc.attention( strTX ) + "\n" ); let joReceipt = null; let bHaveReceipt = false; try { From a65fc4cc753a768f14457e897647fe7af3329407 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 11 Oct 2022 17:16:49 +0100 Subject: [PATCH 11/23] Added IMA message verfication into skale_imaVerifyAndSign handler --- agent/bls.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/bls.js b/agent/bls.js index 701a91012..394dac4f8 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -1716,7 +1716,7 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { break; } } // for( let idxSChain = 0; idxSChain < arr_schains_cached.length; ++ idxSChain ) - if( jo_schain_src == null || strUrlSrcSChain == null || ( !strUrlSrcSChain.length ) ) + if( jo_schain_src == null || strUrlSrcSChain == null || strUrlSrcSChain.length == 0 ) throw new Error( "Could not handle S2S skale_imaVerifyAndSign(2), no S-Chains in SKALE NETWORK observer cached yet, try again later" ); joExtraSignOpts.skale_observer = skale_observer; joExtraSignOpts.w3_src = skale_observer.getWeb3FromURL( strUrlSrcSChain, details ); // ???????????????????????????????????????????????????? From c3ad648cfb36707feba233a873a86905313124e7 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 11 Oct 2022 17:47:46 +0100 Subject: [PATCH 12/23] unit test fix --- test/agent-test.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/agent-test.js b/test/agent-test.js index b45863221..e38113f6b 100644 --- a/test/agent-test.js +++ b/test/agent-test.js @@ -755,7 +755,11 @@ describe( "Agent Utils Module", function() { } ); it( "Compose IMA Agent URL", function() { - assert.equal( imaUtils.compose_ima_agent_node_url( { ip: "127.0.0.1", httpRpcPort: 14999 } ), "http://127.0.0.1:14999" ); + // HTTP_JSON = 3 + // IMA_AGENT_JSON = 10 + // so... distance is 10 - 3 = 7 + // as result, 14999 + 7 = 15006 + assert.equal( imaUtils.compose_ima_agent_node_url( { ip: "127.0.0.1", httpRpcPort: 14999 } ), "http://127.0.0.1:15006" ); } ); } ); From fb3bae7d776ef25745d5e2edd261987b148fc2ff Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 11 Oct 2022 17:50:32 +0100 Subject: [PATCH 13/23] runtime fix --- agent/bls.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 394dac4f8..b3e5ba2cd 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -1707,11 +1707,11 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { const arr_schains_cached = skale_observer.get_last_cached_schains(); if( ( !arr_schains_cached ) || arr_schains_cached.length == 0 ) throw new Error( "Could not handle S2S skale_imaVerifyAndSign(1), no S-Chains in SKALE NETWORK observer cached yet, try again later" ); - const jo_schain_src = null; - let strUrlSrcSChain = null; + let jo_schain_src = null, strUrlSrcSChain = null; for( let idxSChain = 0; idxSChain < arr_schains_cached.length; ++ idxSChain ) { const jo_schain = arr_schains_cached[idxSChain]; if( jo_schain.data.name.toString() == strSChainNameSrc.toString() ) { + jo_schain_src = jo_schain; strUrlSrcSChain = skale_observer.pick_random_schain_w3_url( jo_schain ); break; } From 43516f8f5921c6e0a7de76ad3f7bfe05bda30424 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 11 Oct 2022 18:31:40 +0100 Subject: [PATCH 14/23] runtime fix --- agent/bls.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index b3e5ba2cd..fa6244262 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -1699,7 +1699,7 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { const strMessageHash = owaspUtils.remove_starting_0x( keccak256_message( jarrMessages, nIdxCurrentMsgBlockStart, strFromChainName ) ); details.write( strLogPrefix + cc.debug( "Message hash to sign is " ) + cc.info( strMessageHash ) + "\n" ); // - const joExtraSignOpts = null; + let joExtraSignOpts = null; if( strDirection == "S2S" ) { // joCallData.params.dstChainName // joCallData.params.srcChainName @@ -1718,10 +1718,12 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { } // for( let idxSChain = 0; idxSChain < arr_schains_cached.length; ++ idxSChain ) if( jo_schain_src == null || strUrlSrcSChain == null || strUrlSrcSChain.length == 0 ) throw new Error( "Could not handle S2S skale_imaVerifyAndSign(2), no S-Chains in SKALE NETWORK observer cached yet, try again later" ); - joExtraSignOpts.skale_observer = skale_observer; - joExtraSignOpts.w3_src = skale_observer.getWeb3FromURL( strUrlSrcSChain, details ); // ???????????????????????????????????????????????????? - joExtraSignOpts.chain_id_src = jo_schain_src.data.computed.schain_id; - joExtraSignOpts.cid_dst = jo_schain_src.data.computed.chainId; + joExtraSignOpts = { + skale_observer: skale_observer, + w3_src: skale_observer.getWeb3FromURL( strUrlSrcSChain, details ), + chain_id_src: jo_schain_src.data.computed.schain_id, + cid_dst: jo_schain_src.data.computed.chainId + }; } await check_correctness_of_messages_to_sign( details, strLogPrefix, strDirection, jarrMessages, nIdxCurrentMsgBlockStart, joExtraSignOpts ); // From 430f313bc4c92f7fbcdafd05179143d222bb55f7 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Tue, 11 Oct 2022 18:32:43 +0100 Subject: [PATCH 15/23] unit test fix --- test/agent-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/agent-test.js b/test/agent-test.js index e38113f6b..f5f6d669b 100644 --- a/test/agent-test.js +++ b/test/agent-test.js @@ -759,7 +759,7 @@ describe( "Agent Utils Module", function() { // IMA_AGENT_JSON = 10 // so... distance is 10 - 3 = 7 // as result, 14999 + 7 = 15006 - assert.equal( imaUtils.compose_ima_agent_node_url( { ip: "127.0.0.1", httpRpcPort: 14999 } ), "http://127.0.0.1:15006" ); + assert.equal( imaUtils.compose_ima_agent_node_url( { ip: "127.0.0.1", httpRpcPort: 14999 } ), "ws://127.0.0.1:15006" ); } ); } ); From e55d70356c8191b8d706d620f8abc7340ceccb3e Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Wed, 12 Oct 2022 19:05:40 +0100 Subject: [PATCH 16/23] better web socket handling --- agent/rpc-call.js | 64 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/agent/rpc-call.js b/agent/rpc-call.js index cb703d3ae..a3fb8da16 100644 --- a/agent/rpc-call.js +++ b/agent/rpc-call.js @@ -29,9 +29,17 @@ const net = require( "net" ); const g_nConnectionTimeoutSeconds = 60; +function rpc_call_init() { + owaspUtils.owaspAddUsageRef(); +} + +function validateURL( x ) { + return owaspUtils.validateURL( x ); +} + function is_http_url( strURL ) { try { - if( !owaspUtils.validateURL( strURL ) ) + if( !validateURL( strURL ) ) return false; const u = new URL( strURL ); if( u.protocol == "http:" || u.protocol == "https:" ) @@ -43,7 +51,7 @@ function is_http_url( strURL ) { function is_ws_url( strURL ) { try { - if( !owaspUtils.validateURL( strURL ) ) + if( !validateURL( strURL ) ) return false; const u = new URL( strURL ); if( u.protocol == "ws:" || u.protocol == "wss:" ) @@ -53,10 +61,6 @@ function is_ws_url( strURL ) { return false; } -function rpc_call_init() { - owaspUtils.owaspAddUsageRef(); -} - async function wait_web_socket_is_open( socket, fnDone, fnStep ) { fnDone = fnDone || async function( nStep ) {}; fnDone = fnStep || async function( nStep ) { return true; }; @@ -93,29 +97,37 @@ async function wait_web_socket_is_open( socket, fnDone, fnStep ) { } async function do_connect( joCall, opts, fn ) { + let wsConn = joCall.wsConn ? joCall.wsConn : null; try { fn = fn || async function() {}; - if( !owaspUtils.validateURL( joCall.url ) ) + if( !validateURL( joCall.url ) ) throw new Error( "JSON RPC CALLER cannot connect web socket to invalid URL: " + joCall.url ); if( is_ws_url( joCall.url ) ) { let strWsError = null; - joCall.wsConn = new ws( joCall.url ); - joCall.wsConn.on( "open", async function() { + wsConn = new ws( joCall.url ); + joCall.wsConn = wsConn; + wsConn.on( "open", async function() { await fn( joCall, null ); } ); - joCall.wsConn.on( "close", async function() { + wsConn.on( "close", async function() { strWsError = "web socket was closed, please check provided URL is valid and accessible"; - joCall.wsConn = 0; + joCall.wsConn = null; } ); - joCall.wsConn.on( "error", async function( err ) { + wsConn.on( "error", async function( err ) { strWsError = err.toString() || "internal web socket error"; log.write( cc.u( joCall.url ) + cc.error( " web socket error: " ) + cc.warning( err.toString() ) + "\n" ); + joCall.wsConn = null; + wsConn.close(); + do_reconnect_ws_step( joCall, opts ); } ); - joCall.wsConn.on( "fail", async function( err ) { + wsConn.on( "fail", async function( err ) { strWsError = err.toString() || "internal web socket failure"; log.write( cc.u( joCall.url ) + cc.error( " web socket fail: " ) + cc.warning( err.toString() ) + "\n" ); + joCall.wsConn = null; + wsConn.close(); + do_reconnect_ws_step( joCall, opts ); } ); - joCall.wsConn.on( "message", async function incoming( data ) { + wsConn.on( "message", async function incoming( data ) { // log.write( cc.info( "WS message " ) + cc.attention( data ) + "\n" ); const joOut = JSON.parse( data ); if( joOut.id in joCall.mapPendingByCallID ) { @@ -129,7 +141,7 @@ async function do_connect( joCall, opts, fn ) { await entry.fn( entry.joIn, joOut, null ); } } ); - await wait_web_socket_is_open( joCall.wsConn, + await wait_web_socket_is_open( wsConn, async function( nStep ) { // done }, async function( nStep ) { // step @@ -155,12 +167,13 @@ async function do_connect( joCall, opts, fn ) { joCall.wsConn = null; await fn( joCall, err ); } + return joCall; } async function do_connect_if_needed( joCall, opts, fn ) { try { fn = fn || async function() {}; - if( !owaspUtils.validateURL( joCall.url ) ) + if( !validateURL( joCall.url ) ) throw new Error( "JSON RPC CALLER cannot connect web socket to invalid URL: " + joCall.url ); if( is_ws_url( joCall.url ) && ( !joCall.wsConn ) ) { await joCall.reconnect( fn ); @@ -170,6 +183,20 @@ async function do_connect_if_needed( joCall, opts, fn ) { } catch ( err ) { await fn( joCall, err ); } + return joCall; +} + +async function do_reconnect_ws_step( joCall, opts, fn ) { + if( ! opts.isAutoReconnect ) + return; + fn = fn || async function() {}; + do_connect( joCall, opts, async function( joCall, err ) { + if( err ) { + do_reconnect_ws_step( joCall, opts ); + return; + } + await fn( joCall, null ); + } ); } const impl_sleep = ( milliseconds ) => { return new Promise( resolve => setTimeout( resolve, milliseconds ) ); }; @@ -194,7 +221,7 @@ async function do_call( joCall, joIn, fn ) { joCall.wsConn.send( JSON.stringify( joIn ) ); } else { // console.log( "--- --- --- call URL is", joCall.url ); - if( !owaspUtils.validateURL( joCall.url ) ) { + if( !validateURL( joCall.url ) ) { // throw new Error( "JSON RPC CALLER cannot do query post to invalid URL: " + joCall.url ); await fn( joIn, null, "JSON RPC CALLER cannot do query post to invalid URL: " + joCall.url ); return; @@ -263,7 +290,7 @@ async function do_call( joCall, joIn, fn ) { } async function rpc_call_create( strURL, opts, fn ) { - if( !owaspUtils.validateURL( strURL ) ) + if( !validateURL( strURL ) ) throw new Error( "JSON RPC CALLER cannot create a call object invalid URL: " + strURL ); fn = fn || async function() {}; if( !( strURL && typeof strURL == "string" && strURL.length > 0 ) ) @@ -291,6 +318,7 @@ async function rpc_call_create( strURL, opts, fn ) { } }; await do_connect( joCall, opts, fn ); + return joCall; } function generate_random_integer_in_range( min, max ) { From 5235749e9d34a7c8bd5a9fe3ca84a7c2bcf2c450 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 13 Oct 2022 13:02:32 +0100 Subject: [PATCH 17/23] Force disconnect from SGX when no longer needed --- agent/bls.js | 10 +++++++++- agent/rpc-call.js | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index fa6244262..97dc900d7 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -937,6 +937,7 @@ async function do_sign_messages_impl( "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); + await rpcCall.disconnect(); return; } let targetChainName = ""; @@ -958,8 +959,10 @@ async function do_sign_messages_impl( fromChainName = "" + joExtraSignOpts.chain_id_src; // targetChainURL = owaspUtils.w3_2_url( joExtraSignOpts.w3_dst ); // fromChainURL = owaspUtils.w3_2_url( joExtraSignOpts.w3_src ); - } else + } else { + await rpcCall.disconnect(); throw new Error( "CRITICAL ERROR: Failed do_sign_messages_impl() with unknown directon \"" + strDirection + "\"" ); + } const joParams = { direction: "" + strDirection, @@ -998,6 +1001,7 @@ async function do_sign_messages_impl( "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); + await rpcCall.disconnect(); return; } details.write( @@ -1020,6 +1024,7 @@ async function do_sign_messages_impl( "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); + await rpcCall.disconnect(); return; } details.write( strLogPrefix + cc.normal( "Node " ) + cc.info( joNode.nodeID ) + cc.normal( " sign result: " ) + cc.j( joOut.result ? joOut.result : null ) + "\n" ); @@ -1040,6 +1045,7 @@ async function do_sign_messages_impl( cc.debug( " because " ) + cc.info( nThreshold ) + cc.debug( "/" ) + cc.info( nCountOfBlsPartsToCollect ) + cc.debug( " threshold number of BLS signature parts already gathered" ) + "\n" ); + await rpcCall.disconnect(); return; } const arrTmp = joOut.result.signResult.signatureShare.split( ":" ); @@ -1107,7 +1113,9 @@ async function do_sign_messages_impl( log.write( strErrorMessage ); details.write( strErrorMessage ); } + await rpcCall.disconnect(); } ); // joCall.call ... + await rpcCall.disconnect(); } ); // rpcCall.create ... } // for( let i = 0; i < jarrNodes.length; ++i ) diff --git a/agent/rpc-call.js b/agent/rpc-call.js index a3fb8da16..72d4b2f41 100644 --- a/agent/rpc-call.js +++ b/agent/rpc-call.js @@ -187,7 +187,9 @@ async function do_connect_if_needed( joCall, opts, fn ) { } async function do_reconnect_ws_step( joCall, opts, fn ) { - if( ! opts.isAutoReconnect ) + if( ! joCall.isAutoReconnect ) + return; + if( joCall.isDisconnectMode ) return; fn = fn || async function() {}; do_connect( joCall, opts, async function( joCall, err ) { @@ -199,7 +201,25 @@ async function do_reconnect_ws_step( joCall, opts, fn ) { } ); } -const impl_sleep = ( milliseconds ) => { return new Promise( resolve => setTimeout( resolve, milliseconds ) ); }; +async function do_disconnect( joCall, fn ) { + fn = fn || async function() {}; + try { + joCall.isDisconnectMode = true; + const wsConn = joCall.wsConn ? joCall.wsConn : null; + joCall.wsConn = null; + if( wsConn ) + wsConn.close(); + joCall.isDisconnectMode = false; + try { + await fn( joCall, null ); + } catch ( err ) { + } + } catch ( err ) { + await await fn( joCall, err ); + } +} + +const do_sleep = ( milliseconds ) => { return new Promise( resolve => setTimeout( resolve, milliseconds ) ); }; async function do_call( joCall, joIn, fn ) { // console.log( "--- --- --- initial joIn is", joIn ); @@ -269,17 +289,17 @@ async function do_call( joCall, joIn, fn ) { } ); for( let idxWait = 0; ! bCompleteFlag; ++ idxWait ) { if( idxWait < 50 ) - await impl_sleep( 5 ); + await do_sleep( 5 ); else if( idxWait < 100 ) - await impl_sleep( 10 ); + await do_sleep( 10 ); else if( idxWait < 1000 ) - await impl_sleep( 100 ); + await do_sleep( 100 ); else { const nLastWaitPeriod = 200; if( ( idxWait - 1000 ) * nLastWaitPeriod > g_nConnectionTimeoutSeconds ) bCompleteFlag = true; else - await impl_sleep( nLastWaitPeriod ); + await do_sleep( nLastWaitPeriod ); } } // for( let idxWait = 0; ! bCompleteFlag; ++ idxWait ) try { @@ -300,6 +320,8 @@ async function rpc_call_create( strURL, opts, fn ) { "joRpcOptions": opts ? opts : null, "mapPendingByCallID": { }, "wsConn": null, + "isAutoReconnect": opts.isAutoReconnect ? true : false, + "isDisconnectMode": false, "reconnect": async function( fnAfter ) { await do_connect( joCall, fnAfter ); }, @@ -315,6 +337,9 @@ async function rpc_call_create( strURL, opts, fn ) { } await do_call( joCall, joIn, fnAfter ); } ); + }, + "disconnect": async function( fnAfter ) { + await do_disconnect( joCall, fnAfter ); } }; await do_connect( joCall, opts, fn ); @@ -473,5 +498,6 @@ module.exports = { get_valid_host_and_port: get_valid_host_and_port, check_tcp_promise: check_tcp_promise, check_tcp: check_tcp, - check_url: check_url + check_url: check_url, + sleep: do_sleep }; // module.exports From 610506f7213f10d5531af3093b499c7771056df6 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 13 Oct 2022 13:17:48 +0100 Subject: [PATCH 18/23] disconnectable RPC calls --- agent/bls.js | 24 +++++++++++++++++------- agent/main.js | 11 +++++++++++ agent/oracle.js | 10 +++++++++- npms/skale-ima/index.js | 16 ++++++++++++++++ npms/skale-observer/observer.js | 4 ++++ 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 97dc900d7..7bd2596da 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -937,7 +937,7 @@ async function do_sign_messages_impl( "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - await rpcCall.disconnect(); + await joCall.disconnect(); return; } let targetChainName = ""; @@ -960,7 +960,7 @@ async function do_sign_messages_impl( // targetChainURL = owaspUtils.w3_2_url( joExtraSignOpts.w3_dst ); // fromChainURL = owaspUtils.w3_2_url( joExtraSignOpts.w3_src ); } else { - await rpcCall.disconnect(); + await joCall.disconnect(); throw new Error( "CRITICAL ERROR: Failed do_sign_messages_impl() with unknown directon \"" + strDirection + "\"" ); } @@ -1001,7 +1001,7 @@ async function do_sign_messages_impl( "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - await rpcCall.disconnect(); + await joCall.disconnect(); return; } details.write( @@ -1024,7 +1024,7 @@ async function do_sign_messages_impl( "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - await rpcCall.disconnect(); + await joCall.disconnect(); return; } details.write( strLogPrefix + cc.normal( "Node " ) + cc.info( joNode.nodeID ) + cc.normal( " sign result: " ) + cc.j( joOut.result ? joOut.result : null ) + "\n" ); @@ -1045,7 +1045,7 @@ async function do_sign_messages_impl( cc.debug( " because " ) + cc.info( nThreshold ) + cc.debug( "/" ) + cc.info( nCountOfBlsPartsToCollect ) + cc.debug( " threshold number of BLS signature parts already gathered" ) + "\n" ); - await rpcCall.disconnect(); + await joCall.disconnect(); return; } const arrTmp = joOut.result.signResult.signatureShare.split( ":" ); @@ -1113,9 +1113,8 @@ async function do_sign_messages_impl( log.write( strErrorMessage ); details.write( strErrorMessage ); } - await rpcCall.disconnect(); + await joCall.disconnect(); } ); // joCall.call ... - await rpcCall.disconnect(); } ); // rpcCall.create ... } // for( let i = 0; i < jarrNodes.length; ++i ) @@ -1407,6 +1406,7 @@ async function do_sign_u256( u256, details, fn ) { cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); + await joCall.disconnect(); return; } details.write( @@ -1428,6 +1428,7 @@ async function do_sign_u256( u256, details, fn ) { cc.error( " failed, RPC call reported error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); + await joCall.disconnect(); return; } details.write( @@ -1445,6 +1446,7 @@ async function do_sign_u256( u256, details, fn ) { "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); + await joCall.disconnect(); return; } details.write( strLogPrefix + cc.normal( "Node " ) + cc.info( joNode.nodeID ) + cc.normal( " sign result: " ) + cc.j( joOut.result ? joOut.result : null ) + "\n" ); @@ -1521,6 +1523,7 @@ async function do_sign_u256( u256, details, fn ) { log.write( strErrorMessage ); details.write( strErrorMessage ); } + await joCall.disconnect(); } ); // joCall.call ... } ); // rpcCall.create ... } @@ -1643,6 +1646,7 @@ async function handle_skale_call_via_redirect( joCallData ) { cc.error( " JSON RPC call to S-Chain failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); + await joCall.disconnect(); throw new Error( "JSON RPC call to S-Chain failed, RPC call was not created, error is: " + owaspUtils.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Will invoke " ) + cc.info( "S-Chain" ) + cc.debug( " with call data " ) + cc.j( joCallData ) + "\n" ); @@ -1653,6 +1657,7 @@ async function handle_skale_call_via_redirect( joCallData ) { cc.error( " JSON RPC call to S-Chain failed, RPC call reported error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); + await joCall.disconnect(); throw new Error( "JSON RPC call to S-Chain failed, RPC call reported error: " + owaspUtils.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "S-Chain" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); @@ -1666,10 +1671,12 @@ async function handle_skale_call_via_redirect( joCallData ) { log.write( strErrorMessage ); details.write( strErrorMessage ); details.write( strErrorMessage ); + await joCall.disconnect(); throw new Error( "JSON RPC call to S-Chain failed with \"unknown wallet error(3)\", sequence ID is " + sequence_id ); } isSuccess = true; joRetVal = joOut; // joOut.result + await joCall.disconnect(); } ); // joCall.call ... } ); // rpcCall.create ... } catch ( err ) { @@ -1761,6 +1768,7 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { cc.error( " JSON RPC call to SGX failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); + await joCall.disconnect(); throw new Error( "JSON RPC call to SGX failed, RPC call was not created, error is: " + owaspUtils.extract_error_message( err ) ); } const joCallSGX = { @@ -1782,6 +1790,7 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { cc.error( " JSON RPC call to SGX failed, RPC call reported error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); + await joCall.disconnect(); throw new Error( "JSON RPC call to SGX failed, RPC call reported error: " + owaspUtils.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "SGX" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); @@ -1794,6 +1803,7 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { joRetVal.result = { signResult: joSignResult }; if( "qa" in joCallData ) joRetVal.qa = joCallData.qa; + await joCall.disconnect(); } ); // joCall.call ... } ); // rpcCall.create ... } catch ( err ) { diff --git a/agent/main.js b/agent/main.js index 716c773bb..479bbc6bf 100644 --- a/agent/main.js +++ b/agent/main.js @@ -1389,6 +1389,7 @@ imaCLI.parse( { await rpcCall.create( imaState.strURL_s_chain, rpcCallOpts, async function( joCall, err ) { if( err ) { console.log( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain failed" ) ); + await joCall.disconnect(); process.exit( 156 ); } await joCall.call( { @@ -1399,6 +1400,7 @@ imaCLI.parse( { }, async function( joIn, joOut, err ) { if( err ) { console.log( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain failed, error: " ) + cc.warning( err ) ); + await joCall.disconnect(); process.exit( 157 ); } log.write( strLogPrefix + cc.normal( "S-Chain network information: " ) + cc.j( joOut.result ) + "\n" ); @@ -1417,6 +1419,7 @@ imaCLI.parse( { await rpcCall.create( strNodeURL, rpcCallOpts, async function( joCall, err ) { if( err ) { console.log( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain failed" ) ); + await joCall.disconnect(); process.exit( 158 ); } await joCall.call( { @@ -1432,7 +1435,9 @@ imaCLI.parse( { } log.write( strLogPrefix + cc.normal( "Node " ) + cc.info( joNode.nodeID ) + cc.normal( " IMA information: " ) + cc.j( joOut.result ) + "\n" ); //process.exit( 0 ); + await joCall.disconnect(); } ); + await joCall.disconnect(); } ); } //process.exit( 0 ); @@ -1442,6 +1447,7 @@ imaCLI.parse( { process.exit( 0 ); } }, 100 ); + await joCall.disconnect(); } ); } ); return true; @@ -1855,6 +1861,7 @@ async function discover_s_chain_network( fnAfter, isSilent, joPrevSChainNetworkI ); } fnAfter( err, null ); + await joCall.disconnect(); return; } await joCall.call( { @@ -1872,6 +1879,7 @@ async function discover_s_chain_network( fnAfter, isSilent, joPrevSChainNetworkI ); } fnAfter( err, null ); + await joCall.disconnect(); return; } if( ( !isSilent ) && IMA.verbose_get() >= IMA.RV_VERBOSE.trace ) @@ -1890,6 +1898,7 @@ async function discover_s_chain_network( fnAfter, isSilent, joPrevSChainNetworkI ); } fnAfter( err2, null ); + await joCall.disconnect(); return; } const jarrNodes = joSChainNetworkInfo.network; @@ -1945,6 +1954,7 @@ async function discover_s_chain_network( fnAfter, isSilent, joPrevSChainNetworkI } // fnAfter( err, null ); ++ cntFailed; + await joCall.disconnect(); return; } joCall.call( { @@ -2075,6 +2085,7 @@ async function discover_s_chain_network( fnAfter, isSilent, joPrevSChainNetworkI ); } }, nWaitStepMilliseconds ); + await joCall.disconnect(); } ); } ); } catch ( err ) { diff --git a/agent/oracle.js b/agent/oracle.js index 809e45bb6..12592c19e 100644 --- a/agent/oracle.js +++ b/agent/oracle.js @@ -93,6 +93,7 @@ function oracle_get_gas_price( oracleOpts, details ) { details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC connection problem for url " ) + cc.u( url ) + cc.error( ", error description: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); reject( new Error( "CRITICAL ORACLE CALL ERROR: RPC connection problem for url \"" + url + "\", error description: " + owaspUtils.extract_error_message( err ) ) ); + await joCall.disconnect(); return; } try { @@ -114,6 +115,7 @@ function oracle_get_gas_price( oracleOpts, details ) { details.write( err.stack + "\n" ); } reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_submitRequest) failed, error: " + owaspUtils.extract_error_message( err ) ) ); + await joCall.disconnect(); return; } if( isVerboseTraceDetails ) @@ -122,6 +124,7 @@ function oracle_get_gas_price( oracleOpts, details ) { details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " bad unexpecected result" ) + cc.normal( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + "\n" ); details.write( err.stack + "\n" ); reject( new Error( "CRITICAL ORACLE CALL ERROR: bad unexpecected result(oracle_submitRequest)" ) ); + await joCall.disconnect(); return; } for( let idxAttempt = 0; idxAttempt < cntAttempts; ++idxAttempt ) { @@ -144,6 +147,7 @@ function oracle_get_gas_price( oracleOpts, details ) { details.write( err.stack + "\n" ); } //reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_checkResult) failed, error: " + owaspUtils.extract_error_message( err ) ) ); + await joCall.disconnect(); return; } if( isVerboseTraceDetails ) @@ -154,6 +158,7 @@ function oracle_get_gas_price( oracleOpts, details ) { details.write( err.stack + "\n" ); } // reject( new Error( "CRITICAL ORACLE CALL ERROR: bad unexpecected result(oracle_checkResult)" ) ); + await joCall.disconnect(); return; } const joResult = JSON.parse( joOut.result ); @@ -163,25 +168,28 @@ function oracle_get_gas_price( oracleOpts, details ) { if( isVerbose ) details.write( cc.success( "success, computed " ) + cc.sunny( "Gas Price" ) + cc.success( "=" ) + cc.info( gp.toString() ) + cc.success( "=" ) + cc.info( "0x" + gp.toString( 16 ) ) + "\n" ); resolve( gp ); + await joCall.disconnect(); return; } ); } catch ( err ) { details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " exception is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); reject( err ); + await joCall.disconnect(); return; } } // for( let idxAttempt = 0; idxAttempt < cntAttempts; ++idxAttempt ) details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " all attempts timed out" ) + "\n" ); reject( new Error( "RPC call(oracle_checkResult) all attempts timed out" ) ); + await joCall.disconnect(); return; } ); } catch ( err ) { details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call" ) + cc.normal( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + cc.error( " exception is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); reject( err ); - return; } + await joCall.disconnect(); } ); } catch ( err ) { details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC call object creation failed, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); diff --git a/npms/skale-ima/index.js b/npms/skale-ima/index.js index 50b3f3125..d5d1bfe83 100644 --- a/npms/skale-ima/index.js +++ b/npms/skale-ima/index.js @@ -1354,6 +1354,7 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); + await joCall.disconnect(); return; } const txAdjusted = JSON.parse( JSON.stringify( rawTx ) ); // tx // rawTx @@ -1375,6 +1376,7 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); + await joCall.disconnect(); return; } details.write( cc.debug( "Transaction Manager sign-and-send result is: " ) + cc.j( joOut ) + "\n" ); @@ -1387,6 +1389,7 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc details.write( s ); return; } + await joCall.disconnect(); } ); } ); await sleep( 5000 ); @@ -1446,6 +1449,7 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); + await joCall.disconnect(); return; } const msgHash = tx.hash( false ); @@ -1466,6 +1470,7 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); + await joCall.disconnect(); return; } details.write( cc.debug( "SGX wallet ECDSA sign result is: " ) + cc.j( joOut ) + "\n" ); @@ -1504,6 +1509,7 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc tx.r = joNeededResult.r; tx.s = joNeededResult.s; details.write( cc.debug( "Resulting adjusted transaction is: " ) + cc.j( tx ) + "\n" ); + await joCall.disconnect(); } ); } ); await sleep( 3000 ); @@ -4775,6 +4781,7 @@ async function async_pending_tx_start( details, w3, w3_opposite, chain_id, chain if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); + await joCall.disconnect(); return; } const joIn = { @@ -4790,15 +4797,18 @@ async function async_pending_tx_start( details, w3, w3_opposite, chain_id, chain if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); + await joCall.disconnect(); return; } details.write( cc.debug( "Pending work start result is: " ) + cc.j( joOut ) + "\n" ); if( joOut && "result" in joOut && "success" in joOut.result ) { if( joOut.result.success ) { details.write( strLogPrefix + cc.success( "Success, pending work start reported" ) + "\n" ); + await joCall.disconnect(); return; } else { details.write( strLogPrefix + cc.warning( "Pending work start was not reported with success" ) + "\n" ); + await joCall.disconnect(); return; } } else { @@ -4806,6 +4816,7 @@ async function async_pending_tx_start( details, w3, w3_opposite, chain_id, chain if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); + await joCall.disconnect(); return; } } ); @@ -4836,6 +4847,7 @@ async function async_pending_tx_complete( details, w3, w3_opposite, chain_id, ch if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); + await joCall.disconnect(); return; } const joIn = { @@ -4851,14 +4863,17 @@ async function async_pending_tx_complete( details, w3, w3_opposite, chain_id, ch if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); + await joCall.disconnect(); return; } details.write( cc.debug( "Pending work complete result is: " ) + cc.j( joOut ) + "\n" ); if( joOut && "result" in joOut && "success" in joOut.result ) { if( joOut.result.success ) { details.write( strLogPrefix + cc.success( "Success, pending work complete reported" ) + "\n" ); + await joCall.disconnect(); return; } else { + await joCall.disconnect(); details.write( strLogPrefix + cc.warning( "Pending work complete was not reported with success" ) + "\n" ); return; } @@ -4867,6 +4882,7 @@ async function async_pending_tx_complete( details, w3, w3_opposite, chain_id, ch if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); + await joCall.disconnect(); return; } } ); diff --git a/npms/skale-observer/observer.js b/npms/skale-observer/observer.js index 298d2a41f..fbb73f565 100644 --- a/npms/skale-observer/observer.js +++ b/npms/skale-observer/observer.js @@ -617,6 +617,7 @@ async function discover_chain_id( strURL ) { await rpcCall.create( strURL, rpcCallOpts, async function( joCall, err ) { if( err ) { //ret = "Failed to create RPC (" + strURL + ") call: " + owaspUtils.extract_error_message( err ); + await joCall.disconnect(); return; } await joCall.call( { @@ -625,13 +626,16 @@ async function discover_chain_id( strURL ) { }, async function( joIn, joOut, err ) { if( err ) { //ret = "Failed to query RPC (" + strURL + ") for chain ID: " + owaspUtils.extract_error_message( err ); + await joCall.disconnect(); return; } if( ! ( "result" in joOut && joOut.result ) ) { //ret = "Failed to query RPC (" + strURL + ") for chain ID, got bad result: " + JSON.stringify( joOut ); + await joCall.disconnect(); return; } ret = joOut.result; + await joCall.disconnect(); } ); // joCall.call ... } ); // rpcCall.create ... return ret; From 2c207714b7270176045572b1a01e87d729629523 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 13 Oct 2022 19:53:54 +0100 Subject: [PATCH 19/23] disconnectable RPC calls --- agent/bls.js | 12 ++++++++---- agent/main.js | 10 ++++++---- agent/oracle.js | 11 ++++++----- agent/rpc-call.js | 2 +- npms/skale-ima/index.js | 12 ++++++++---- npms/skale-observer/observer.js | 3 ++- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 7bd2596da..50fa655bd 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -937,7 +937,8 @@ async function do_sign_messages_impl( "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); return; } let targetChainName = ""; @@ -1406,7 +1407,8 @@ async function do_sign_u256( u256, details, fn ) { cc.error( " failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); return; } details.write( @@ -1646,7 +1648,8 @@ async function handle_skale_call_via_redirect( joCallData ) { cc.error( " JSON RPC call to S-Chain failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); throw new Error( "JSON RPC call to S-Chain failed, RPC call was not created, error is: " + owaspUtils.extract_error_message( err ) ); } details.write( strLogPrefix + cc.debug( "Will invoke " ) + cc.info( "S-Chain" ) + cc.debug( " with call data " ) + cc.j( joCallData ) + "\n" ); @@ -1768,7 +1771,8 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { cc.error( " JSON RPC call to SGX failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); throw new Error( "JSON RPC call to SGX failed, RPC call was not created, error is: " + owaspUtils.extract_error_message( err ) ); } const joCallSGX = { diff --git a/agent/main.js b/agent/main.js index 479bbc6bf..66bc900a7 100644 --- a/agent/main.js +++ b/agent/main.js @@ -1389,7 +1389,8 @@ imaCLI.parse( { await rpcCall.create( imaState.strURL_s_chain, rpcCallOpts, async function( joCall, err ) { if( err ) { console.log( cc.fatal( "CRITICAL ERROR:" ) + cc.error( " JSON RPC call to S-Chain failed" ) ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); process.exit( 156 ); } await joCall.call( { @@ -1437,7 +1438,6 @@ imaCLI.parse( { //process.exit( 0 ); await joCall.disconnect(); } ); - await joCall.disconnect(); } ); } //process.exit( 0 ); @@ -1861,7 +1861,8 @@ async function discover_s_chain_network( fnAfter, isSilent, joPrevSChainNetworkI ); } fnAfter( err, null ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); return; } await joCall.call( { @@ -1954,7 +1955,8 @@ async function discover_s_chain_network( fnAfter, isSilent, joPrevSChainNetworkI } // fnAfter( err, null ); ++ cntFailed; - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); return; } joCall.call( { diff --git a/agent/oracle.js b/agent/oracle.js index 12592c19e..60ad6a5af 100644 --- a/agent/oracle.js +++ b/agent/oracle.js @@ -92,8 +92,9 @@ function oracle_get_gas_price( oracleOpts, details ) { if( err ) { details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " RPC connection problem for url " ) + cc.u( url ) + cc.error( ", error description: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); + if( joCall ) + await joCall.disconnect(); reject( new Error( "CRITICAL ORACLE CALL ERROR: RPC connection problem for url \"" + url + "\", error description: " + owaspUtils.extract_error_message( err ) ) ); - await joCall.disconnect(); return; } try { @@ -114,8 +115,8 @@ function oracle_get_gas_price( oracleOpts, details ) { details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " JSON RPC call" ) + cc.debug( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + cc.error( " failed, error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); } - reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_submitRequest) failed, error: " + owaspUtils.extract_error_message( err ) ) ); await joCall.disconnect(); + reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_submitRequest) failed, error: " + owaspUtils.extract_error_message( err ) ) ); return; } if( isVerboseTraceDetails ) @@ -123,8 +124,8 @@ function oracle_get_gas_price( oracleOpts, details ) { if( !( "result" in joOut && typeof joOut.result == "string" && joOut.result.length > 0 ) ) { details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " bad unexpecected result" ) + cc.normal( "(" ) + cc.attention( "oracle_submitRequest" ) + cc.normal( ")" ) + "\n" ); details.write( err.stack + "\n" ); - reject( new Error( "CRITICAL ORACLE CALL ERROR: bad unexpecected result(oracle_submitRequest)" ) ); await joCall.disconnect(); + reject( new Error( "CRITICAL ORACLE CALL ERROR: bad unexpecected result(oracle_submitRequest)" ) ); return; } for( let idxAttempt = 0; idxAttempt < cntAttempts; ++idxAttempt ) { @@ -146,8 +147,8 @@ function oracle_get_gas_price( oracleOpts, details ) { details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " JSON RPC call" ) + cc.debug( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + cc.error( " failed, error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n" ); details.write( err.stack + "\n" ); } - //reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_checkResult) failed, error: " + owaspUtils.extract_error_message( err ) ) ); await joCall.disconnect(); + //reject( new Error( "CRITICAL ORACLE CALL ERROR: JSON RPC call(oracle_checkResult) failed, error: " + owaspUtils.extract_error_message( err ) ) ); return; } if( isVerboseTraceDetails ) @@ -157,8 +158,8 @@ function oracle_get_gas_price( oracleOpts, details ) { details.write( cc.fatal( "CRITICAL ORACLE CALL ERROR:" ) + cc.error( " bad unexpecected result" ) + cc.normal( "(" ) + cc.attention( "oracle_checkResult" ) + cc.normal( ")" ) + "\n" ); details.write( err.stack + "\n" ); } - // reject( new Error( "CRITICAL ORACLE CALL ERROR: bad unexpecected result(oracle_checkResult)" ) ); await joCall.disconnect(); + // reject( new Error( "CRITICAL ORACLE CALL ERROR: bad unexpecected result(oracle_checkResult)" ) ); return; } const joResult = JSON.parse( joOut.result ); diff --git a/agent/rpc-call.js b/agent/rpc-call.js index 72d4b2f41..c956b70a7 100644 --- a/agent/rpc-call.js +++ b/agent/rpc-call.js @@ -320,7 +320,7 @@ async function rpc_call_create( strURL, opts, fn ) { "joRpcOptions": opts ? opts : null, "mapPendingByCallID": { }, "wsConn": null, - "isAutoReconnect": opts.isAutoReconnect ? true : false, + "isAutoReconnect": ( opts && "isAutoReconnect" in opts && opts.isAutoReconnect ) ? true : false, "isDisconnectMode": false, "reconnect": async function( fnAfter ) { await do_connect( joCall, fnAfter ); diff --git a/npms/skale-ima/index.js b/npms/skale-ima/index.js index d5d1bfe83..5038d22fe 100644 --- a/npms/skale-ima/index.js +++ b/npms/skale-ima/index.js @@ -1354,7 +1354,8 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); return; } const txAdjusted = JSON.parse( JSON.stringify( rawTx ) ); // tx // rawTx @@ -1449,7 +1450,8 @@ async function safe_sign_transaction_with_account( details, w3, tx, rawTx, joAcc if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); return; } const msgHash = tx.hash( false ); @@ -4781,7 +4783,8 @@ async function async_pending_tx_start( details, w3, w3_opposite, chain_id, chain if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); return; } const joIn = { @@ -4847,7 +4850,8 @@ async function async_pending_tx_complete( details, w3, w3_opposite, chain_id, ch if( verbose_get() >= RV_VERBOSE.error ) log.write( s ); details.write( s ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); return; } const joIn = { diff --git a/npms/skale-observer/observer.js b/npms/skale-observer/observer.js index fbb73f565..5e07e750d 100644 --- a/npms/skale-observer/observer.js +++ b/npms/skale-observer/observer.js @@ -617,7 +617,8 @@ async function discover_chain_id( strURL ) { await rpcCall.create( strURL, rpcCallOpts, async function( joCall, err ) { if( err ) { //ret = "Failed to create RPC (" + strURL + ") call: " + owaspUtils.extract_error_message( err ); - await joCall.disconnect(); + if( joCall ) + await joCall.disconnect(); return; } await joCall.call( { From 68ffddb46d03cb3b1c76b543472a037adddff3a1 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 13 Oct 2022 20:39:57 +0100 Subject: [PATCH 20/23] code cleanup --- agent/bls.js | 56 ---------------------------------------------------- 1 file changed, 56 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 50fa655bd..1fe92ab36 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -1826,62 +1826,6 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { return joRetVal; } -/* - -2022-09-28 12:46:22.936: JSON RPC: <<< message from ::ffff:127.0.0.1: -{ - "method":"skale_imaVerifyAndSign", - "params":{ - "direction":"S2S", - "startMessageIdx":11, - "dstChainName":"Bob1000", - "srcChainName":"Bob1001", - "messages":[ - { - "sender":"0xD2aaA00900000000000000000000000000000000", - "destinationContract":"0xD2aaA00900000000000000000000000000000000", - "data":"0x0000000000000000000000000000000000000000000000000000000000000009000000000000000000000000dedd5a997604ade31542e8a3d6aaa280e348aef10000000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003e8", - "savedBlockNumberForOptimizations":448 - } - ], - "qa":{ - "skaled_no":0, - "sequence_id":"9cef78ef82228cce2e4ed4bee0c485acca0f368c1d7ae94aa235d26c0b778db3", - "ts":"2022-09-28 12:46:22.934" - } - }, - "jsonrpc":"2.0", - "id":3937967578497932 -} - ---- --- --- --- --- GATHERED SUCCESS DETAILS FOR LATEST( (handle_skale_call_via_redirect()) action (BEGIN) --- --- ------ --- - -2022-09-28 12:46:22.938: Will invoke S-Chain with call data { method: "skale_imaVerifyAndSign", params: { direction: "S2S", startMessageIdx: 11, dstChainName: "Bob1000", srcChainName: "Bob1001", messages: [{ sender: "0xD2aaA00900000000000000000000000000000000", destinationContract: "0xD2aaA00900000000000000000000000000000000", data: "0x0000000000000000000000000000000000000000000000000000000000000009000000000000000000000000dedd5a997604ade31542e8a3d6aaa280e348aef10000000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003e8", savedBlockNumberForOptimizations: 448}], qa: { skaled_no: 0, sequence_id: "9cef78ef82228cce2e4ed4bee0c485acca0f368c1d7ae94aa235d26c0b778db3", ts: "2022-09-28 12:46:22.934"}}, jsonrpc: "2.0", id: 3937967578497932} -2022-09-28 12:46:23.052: Call to S-Chain done, answer is: { id: 3937967578497932, jsonrpc: "2.0", result: { qa: { sequence_id: "9cef78ef82228cce2e4ed4bee0c485acca0f368c1d7ae94aa235d26c0b778db3", skaled_no: 0, ts: "2022-09-28 12:46:22.934"}, signResult: { errorMessage: "", signatureShare: "17478565975047244907103895167228083798921988971796902124088684491074746004285:15031994568930252855707831149520060050211430984917981813828217031708710584295:16774908233857298972544743177670408960120003931859857609581436687829921077359:0", status: 0, type: "BLSSignRsp"}}} - ---- --- --- --- --- GATHERED SUCCESS DETAILS FOR LATEST( (handle_skale_call_via_redirect()) action (END) --- --- --- --- --- - -2022-09-28 12:46:23.053: JSON RPC: >>> answer to ::ffff:127.0.0.1: -{ - "id":3937967578497932, - "jsonrpc":"2.0", - "result":{ - "qa":{ - "sequence_id":"9cef78ef82228cce2e4ed4bee0c485acca0f368c1d7ae94aa235d26c0b778db3", - "skaled_no":0, - "ts":"2022-09-28 12:46:22.934" - }, - "signResult":{ - "errorMessage":"", - "signatureShare":"17478565975047244907103895167228083798921988971796902124088684491074746004285:15031994568930252855707831149520060050211430984917981813828217031708710584295:16774908233857298972544743177670408960120003931859857609581436687829921077359:0", - "status":0, - "type":"BLSSignRsp" - } - } -} - - */ - module.exports = { init: init, do_sign_messages_m2s: do_sign_messages_m2s, From 3ffb1557e08a390fbf7e8a3c1e4ef2a841a2154c Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 13 Oct 2022 21:16:52 +0100 Subject: [PATCH 21/23] basic Oracle U256 signing implementation --- agent/bls.js | 241 +++++++++++++++++++++++++++++++++++--------------- agent/main.js | 2 - 2 files changed, 172 insertions(+), 71 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index 1fe92ab36..c7e6d5a7b 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -1393,7 +1393,9 @@ async function do_sign_u256( u256, details, fn ) { details.write( strLogPrefix + cc.debug( "Will(u256) collect " ) + cc.info( nCountOfBlsPartsToCollect ) + cc.debug( " from " ) + cc.info( jarrNodes.length ) + cc.debug( " nodes" ) + "\n" ); for( let i = 0; i < jarrNodes.length; ++i ) { const joNode = jarrNodes[i]; - const strNodeURL = imaUtils.compose_schain_node_url( joNode ); + const strNodeURL = imaState.isCrossImaBlsMode + ? imaUtils.compose_ima_agent_node_url( joNode ) + : imaUtils.compose_schain_node_url( joNode ); const strNodeDescColorized = cc.u( strNodeURL ) + " " + cc.normal( "(" ) + cc.bright( i ) + cc.normal( "/" ) + cc.bright( jarrNodes.length ) + cc.normal( ", ID " ) + cc.info( joNode.nodeID ) + cc.normal( ")" ); const rpcCallOpts = null; @@ -1418,7 +1420,7 @@ async function do_sign_u256( u256, details, fn ) { await joCall.call( { method: "skale_imaBSU256", params: { - valueToSign: u256 + valueToSign: u256 // must be 0x string, came from outside 0x string } }, async function( joIn, joOut, err ) { ++joGatheringTracker.nCountReceived; // including errors @@ -1632,71 +1634,71 @@ async function do_sign_u256( u256, details, fn ) { details.write( strLogPrefix + cc.debug( "Completed signing u256 procedure " ) + "\n" ); } -async function handle_skale_call_via_redirect( joCallData ) { - const sequence_id = owaspUtils.remove_starting_0x( get_w3().utils.soliditySha3( log.generate_timestamp_string( null, false ) ) ); - const strLogPrefix = ""; - const strNodeURL = imaState.strURL_s_chain; - const rpcCallOpts = null; - let joRetVal = { }; - const details = log.createMemoryStream( true ); - let isSuccess = false; - try { - await rpcCall.create( strNodeURL, rpcCallOpts, async function( joCall, err ) { - if( err ) { - const strErrorMessage = - strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call to S-Chain failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - if( joCall ) - await joCall.disconnect(); - throw new Error( "JSON RPC call to S-Chain failed, RPC call was not created, error is: " + owaspUtils.extract_error_message( err ) ); - } - details.write( strLogPrefix + cc.debug( "Will invoke " ) + cc.info( "S-Chain" ) + cc.debug( " with call data " ) + cc.j( joCallData ) + "\n" ); - await joCall.call( joCallData, async function( joIn, joOut, err ) { - if( err ) { - const strErrorMessage = - strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + - cc.error( " JSON RPC call to S-Chain failed, RPC call reported error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - await joCall.disconnect(); - throw new Error( "JSON RPC call to S-Chain failed, RPC call reported error: " + owaspUtils.extract_error_message( err ) ); - } - details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "S-Chain" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); - if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { - const strErrorMessage = - strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + - cc.error( "S-Chain reported wallet error: " ) + - cc.warning( owaspUtils.extract_error_message( joOut, "unknown wallet error(3)" ) ) + - cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + - "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - details.write( strErrorMessage ); - await joCall.disconnect(); - throw new Error( "JSON RPC call to S-Chain failed with \"unknown wallet error(3)\", sequence ID is " + sequence_id ); - } - isSuccess = true; - joRetVal = joOut; // joOut.result - await joCall.disconnect(); - } ); // joCall.call ... - } ); // rpcCall.create ... - } catch ( err ) { - isSuccess = false; - const strError = owaspUtils.extract_error_message( err ); - joRetVal.error = strError; - const strErrorMessage = - strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + - cc.error( "JSON RPC call finished with error: " ) + cc.warning( strError ) + - "\n"; - log.write( strErrorMessage ); - details.write( strErrorMessage ); - } - details.exposeDetailsTo( log, "handle_skale_call_via_redirect()", isSuccess ); - details.close(); - return joRetVal; -} +// async function handle_skale_call_via_redirect( joCallData ) { +// const sequence_id = owaspUtils.remove_starting_0x( get_w3().utils.soliditySha3( log.generate_timestamp_string( null, false ) ) ); +// const strLogPrefix = ""; +// const strNodeURL = imaState.strURL_s_chain; +// const rpcCallOpts = null; +// let joRetVal = { }; +// const details = log.createMemoryStream( true ); +// let isSuccess = false; +// try { +// await rpcCall.create( strNodeURL, rpcCallOpts, async function( joCall, err ) { +// if( err ) { +// const strErrorMessage = +// strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + +// cc.error( " JSON RPC call to S-Chain failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; +// log.write( strErrorMessage ); +// details.write( strErrorMessage ); +// if( joCall ) +// await joCall.disconnect(); +// throw new Error( "JSON RPC call to S-Chain failed, RPC call was not created, error is: " + owaspUtils.extract_error_message( err ) ); +// } +// details.write( strLogPrefix + cc.debug( "Will invoke " ) + cc.info( "S-Chain" ) + cc.debug( " with call data " ) + cc.j( joCallData ) + "\n" ); +// await joCall.call( joCallData, async function( joIn, joOut, err ) { +// if( err ) { +// const strErrorMessage = +// strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + +// cc.error( " JSON RPC call to S-Chain failed, RPC call reported error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; +// log.write( strErrorMessage ); +// details.write( strErrorMessage ); +// await joCall.disconnect(); +// throw new Error( "JSON RPC call to S-Chain failed, RPC call reported error: " + owaspUtils.extract_error_message( err ) ); +// } +// details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "S-Chain" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); +// if( joOut.result == null || joOut.result == undefined || ( !typeof joOut.result == "object" ) ) { +// const strErrorMessage = +// strLogPrefix + cc.fatal( "Wallet CRITICAL ERROR:" ) + " " + +// cc.error( "S-Chain reported wallet error: " ) + +// cc.warning( owaspUtils.extract_error_message( joOut, "unknown wallet error(3)" ) ) + +// cc.error( ", " ) + cc.notice( "sequence ID" ) + cc.error( " is " ) + cc.attention( sequence_id ) + +// "\n"; +// log.write( strErrorMessage ); +// details.write( strErrorMessage ); +// details.write( strErrorMessage ); +// await joCall.disconnect(); +// throw new Error( "JSON RPC call to S-Chain failed with \"unknown wallet error(3)\", sequence ID is " + sequence_id ); +// } +// isSuccess = true; +// joRetVal = joOut; // joOut.result +// await joCall.disconnect(); +// } ); // joCall.call ... +// } ); // rpcCall.create ... +// } catch ( err ) { +// isSuccess = false; +// const strError = owaspUtils.extract_error_message( err ); +// joRetVal.error = strError; +// const strErrorMessage = +// strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + +// cc.error( "JSON RPC call finished with error: " ) + cc.warning( strError ) + +// "\n"; +// log.write( strErrorMessage ); +// details.write( strErrorMessage ); +// } +// details.exposeDetailsTo( log, "handle_skale_call_via_redirect()", isSuccess ); +// details.close(); +// return joRetVal; +// } async function handle_skale_imaVerifyAndSign( joCallData ) { const strLogPrefix = ""; @@ -1749,7 +1751,7 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { if( ! joAccount.strURL ) { joAccount = imaState.joAccount_main_net; if( ! joAccount.strSgxURL ) - throw new Error( "SGX URL is unknown, cannot verify IMA message(s)" ); + throw new Error( "SGX URL is unknown, cannot sign IMA message(s)" ); if( ! joAccount.strBlsKeyName ) throw new Error( "BLS keys name is unknown, cannot sign IMA message(s)" ); } @@ -1826,6 +1828,106 @@ async function handle_skale_imaVerifyAndSign( joCallData ) { return joRetVal; } +async function handle_skale_imaBSU256( joCallData ) { + const strLogPrefix = ""; + const details = log.createMemoryStream( true ); + const joRetVal = { }; + let isSuccess = false; + try { + // + details.write( strLogPrefix + cc.debug( "Will BSU256-sign " ) + cc.j( joCallData ) + "\n" ); + const nThreshold = discover_bls_threshold( imaState.joSChainNetworkInfo ); + const nParticipants = discover_bls_participants( imaState.joSChainNetworkInfo ); + details.write( strLogPrefix + cc.debug( "Discovered BLS threshold is " ) + cc.info( nThreshold ) + cc.debug( "." ) + "\n" ); + details.write( strLogPrefix + cc.debug( "Discovered number of BLS participants is " ) + cc.info( nParticipants ) + cc.debug( "." ) + "\n" ); + // + details.write( strLogPrefix + cc.debug( "BSU256 value is " ) + cc.info( joCallData.params.valueToSign ) + "\n" ); + let arrBytes = imaUtils.hexToBytes( joCallData.params.valueToSign, false ); + arrBytes = a2ha( arrBytes ); + const strMessageHash = owaspUtils.remove_starting_0x( imaUtils.bytesToHex( arrBytes, false ) ); + details.write( strLogPrefix + cc.debug( "BSU256-hash to sign is " ) + cc.info( strMessageHash ) + "\n" ); + // + let joAccount = imaState.joAccount_s_chain; + if( ! joAccount.strURL ) { + joAccount = imaState.joAccount_main_net; + if( ! joAccount.strSgxURL ) + throw new Error( "SGX URL is unknown, cannot sign U256" ); + if( ! joAccount.strBlsKeyName ) + throw new Error( "BLS keys name is unknown, cannot sign U256" ); + } + let rpcCallOpts = null; + if( "strPathSslKey" in joAccount && typeof joAccount.strPathSslKey == "string" && joAccount.strPathSslKey.length > 0 && + "strPathSslCert" in joAccount && typeof joAccount.strPathSslCert == "string" && joAccount.strPathSslCert.length > 0 + ) { + rpcCallOpts = { + "cert": fs.readFileSync( joAccount.strPathSslCert, "utf8" ), + "key": fs.readFileSync( joAccount.strPathSslKey, "utf8" ) + }; + // details.write( cc.debug( "Will sign via SGX with SSL options " ) + cc.j( rpcCallOpts ) + "\n" ); + } + const signerIndex = imaState.joAccount_s_chain.nNodeNumber; + await rpcCall.create( joAccount.strSgxURL, rpcCallOpts, async function( joCall, err ) { + if( err ) { + const strErrorMessage = + strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " JSON RPC call to SGX failed, RPC call was not created, error is: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + if( joCall ) + await joCall.disconnect(); + throw new Error( "JSON RPC call to SGX failed, RPC call was not created, error is: " + owaspUtils.extract_error_message( err ) ); + } + const joCallSGX = { + method: "blsSignMessageHash", + // type: "BLSSignReq", + params: { + keyShareName: joAccount.strBlsKeyName, + messageHash: strMessageHash, + n: nParticipants, + t: nThreshold, + signerIndex: signerIndex + 0 // 1-based + } + }; + details.write( strLogPrefix + cc.debug( "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 strErrorMessage = + strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + + cc.error( " JSON RPC call to SGX failed, RPC call reported error: " ) + cc.warning( owaspUtils.extract_error_message( err ) ) + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + await joCall.disconnect(); + throw new Error( "JSON RPC call to SGX failed, RPC call reported error: " + owaspUtils.extract_error_message( err ) ); + } + details.write( strLogPrefix + cc.debug( "Call to " ) + cc.info( "SGX" ) + cc.debug( " done, answer is: " ) + cc.j( joOut ) + "\n" ); + let joSignResult = joOut; + if( joOut.result != null && joOut.result != undefined && typeof joOut.result == "object" ) + joSignResult = joOut.result; + if( joOut.signResult != null && joOut.signResult != undefined && typeof joOut.signResult == "object" ) + joSignResult = joOut.signResult; + isSuccess = true; + joRetVal.result = { signResult: joSignResult }; + if( "qa" in joCallData ) + joRetVal.qa = joCallData.qa; + await joCall.disconnect(); + } ); // joCall.call ... + } ); // rpcCall.create ... + } catch ( err ) { + isSuccess = false; + const strError = owaspUtils.extract_error_message( err ); + joRetVal.error = strError; + const strErrorMessage = + strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + + cc.error( "BSU256-signer error: " ) + cc.warning( strError ) + + "\n"; + log.write( strErrorMessage ); + details.write( strErrorMessage ); + } + details.exposeDetailsTo( log, "BSU256-signer", isSuccess ); + details.close(); + return joRetVal; +} + module.exports = { init: init, do_sign_messages_m2s: do_sign_messages_m2s, @@ -1834,5 +1936,6 @@ module.exports = { do_sign_u256: do_sign_u256, // handle_skale_imaVerifyAndSign: handle_skale_call_via_redirect, handle_skale_imaVerifyAndSign: handle_skale_imaVerifyAndSign, - handle_skale_imaBSU256: handle_skale_call_via_redirect + // handle_skale_imaBSU256: handle_skale_call_via_redirect + handle_skale_imaBSU256: handle_skale_imaBSU256 }; // module.exports diff --git a/agent/main.js b/agent/main.js index 66bc900a7..cc91d37c9 100644 --- a/agent/main.js +++ b/agent/main.js @@ -2562,8 +2562,6 @@ async function single_transfer_loop() { return true; } - if( IMA.verbose_get() >= IMA.RV_VERBOSE.information ) - log.write( strLogPrefix + cc.debug( "Will invoke Oracle gas price setup..." ) + "\n" ); let b0 = true; if( IMA.getEnabledOracle() ) { if( IMA.verbose_get() >= IMA.RV_VERBOSE.information ) From 7b13e5941bfed1bb9df729ded1ded20c2fd9e1cd Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 13 Oct 2022 21:27:42 +0100 Subject: [PATCH 22/23] code cleanup --- agent/main.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/agent/main.js b/agent/main.js index cc91d37c9..2573f2c52 100644 --- a/agent/main.js +++ b/agent/main.js @@ -2283,16 +2283,7 @@ if( imaState.nJsonRpcPort > 0 ) { switch ( joMessage.method ) { case "echo": case "ping": - // call: { "id": 1, "method": "echo" } - // answer: { "id": 1, "method": "echo", "error": null } - // call: { "id": 1, "method": "ping" } - // answer: { "id": 1, "method": "ping", "error": null } break; - // case "get_schain_network_info": - // // call: { "id": 1, "method": "get_schain_network_info" } - // // answer: { "id": 1, "method": "get_schain_network_info", "error": null, "schain_network_info": ... } - // joAnswer.schain_network_info = imaState.joSChainNetworkInfo; - // break; case "skale_imaVerifyAndSign": // joAnswer = await imaBLS.handle_skale_imaVerifyAndSign( joMessage ); isSkipMode = true; From a6e064b707002998790b108ddd75b6f07a76bab7 Mon Sep 17 00:00:00 2001 From: Sergiy Lavrynenko Date: Thu, 13 Oct 2022 22:12:19 +0100 Subject: [PATCH 23/23] improved Oracle U256 signing implementation --- agent/bls.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/agent/bls.js b/agent/bls.js index c7e6d5a7b..1e4e5d642 100644 --- a/agent/bls.js +++ b/agent/bls.js @@ -552,6 +552,7 @@ function perform_bls_verify_i_u256( details, nZeroBasedNodeIndex, joResultFromNo let strOutput = ""; try { shell.cd( strActionDir ); + // const joMsg = { message: keccak256_u256( u256, true ) }; details.write( strLogPrefix + cc.debug( "BLS u256 node " ) + cc.notice( "#" ) + cc.info( nZeroBasedNodeIndex ) + cc.debug( " verify message " ) + cc.j( joMsg ) + cc.debug( " composed from " ) + cc.j( u256 ) + cc.debug( " using glue " ) + cc.j( joResultFromNode ) + cc.debug( " and public key " ) + cc.j( joPublicKey ) + "\n" ); const strSignResultFileName = strActionDir + "/sign-result" + nZeroBasedNodeIndex + ".json"; @@ -1835,17 +1836,16 @@ async function handle_skale_imaBSU256( joCallData ) { let isSuccess = false; try { // - details.write( strLogPrefix + cc.debug( "Will BSU256-sign " ) + cc.j( joCallData ) + "\n" ); + details.write( strLogPrefix + cc.debug( "Will U256-BLS-sign " ) + cc.j( joCallData ) + "\n" ); const nThreshold = discover_bls_threshold( imaState.joSChainNetworkInfo ); const nParticipants = discover_bls_participants( imaState.joSChainNetworkInfo ); details.write( strLogPrefix + cc.debug( "Discovered BLS threshold is " ) + cc.info( nThreshold ) + cc.debug( "." ) + "\n" ); details.write( strLogPrefix + cc.debug( "Discovered number of BLS participants is " ) + cc.info( nParticipants ) + cc.debug( "." ) + "\n" ); // - details.write( strLogPrefix + cc.debug( "BSU256 value is " ) + cc.info( joCallData.params.valueToSign ) + "\n" ); - let arrBytes = imaUtils.hexToBytes( joCallData.params.valueToSign, false ); - arrBytes = a2ha( arrBytes ); - const strMessageHash = owaspUtils.remove_starting_0x( imaUtils.bytesToHex( arrBytes, false ) ); - details.write( strLogPrefix + cc.debug( "BSU256-hash to sign is " ) + cc.info( strMessageHash ) + "\n" ); + const u256 = joCallData.params.valueToSign; + details.write( strLogPrefix + cc.debug( "U256 original value is " ) + cc.info( u256 ) + "\n" ); + const strMessageHash = keccak256_u256( u256, true ); + details.write( strLogPrefix + cc.debug( "haso of U256 value to sign is " ) + cc.info( strMessageHash ) + "\n" ); // let joAccount = imaState.joAccount_s_chain; if( ! joAccount.strURL ) { @@ -1918,12 +1918,12 @@ async function handle_skale_imaBSU256( joCallData ) { joRetVal.error = strError; const strErrorMessage = strLogPrefix + cc.fatal( "CRITICAL ERROR:" ) + " " + - cc.error( "BSU256-signer error: " ) + cc.warning( strError ) + + cc.error( "U256-BLS-signer error: " ) + cc.warning( strError ) + "\n"; log.write( strErrorMessage ); details.write( strErrorMessage ); } - details.exposeDetailsTo( log, "BSU256-signer", isSuccess ); + details.exposeDetailsTo( log, "U256-BLS-signer", isSuccess ); details.close(); return joRetVal; }