diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index 02ad6deb7..f7356fc36 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -24,7 +24,7 @@ with: token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} repository: skalenetwork/skale-ci-integration_tests - ref: v3.18.0 + ref: master submodules: recursive - name: Set up Node uses: actions/setup-node@v3.4.0 diff --git a/libconsensus b/libconsensus index 2f7c74374..adc20562c 160000 --- a/libconsensus +++ b/libconsensus @@ -1 +1 @@ -Subproject commit 2f7c7437465ed3cbbfc914ce9fb0fefe3d096ecb +Subproject commit adc20562c360ab1f6902d6162cfba4e472e7ffb2 diff --git a/libethcore/ChainOperationParams.h b/libethcore/ChainOperationParams.h index 9123ad3cf..1383b84b8 100644 --- a/libethcore/ChainOperationParams.h +++ b/libethcore/ChainOperationParams.h @@ -90,6 +90,7 @@ struct NodeInfo { bool syncNode; bool archiveMode; bool syncFromCatchup; + bool testSignatures; NodeInfo( std::string _name = "TestNode", u256 _id = 1, std::string _ip = "127.0.0.11", uint16_t _port = 11111, std::string _ip6 = "::1", uint16_t _port6 = 11111, @@ -107,7 +108,8 @@ struct NodeInfo { "11559732032986387107991004021392285783925812861821192530917403151452391805634", "8495653923123431417604973247489272438418190587263600148770280649306958101930", "4082367875863433681332203403145435568316851327593401208105741076214120093531" }, - bool _syncNode = false, bool _archiveMode = false, bool _syncFromCatchup = false ) { + bool _syncNode = false, bool _archiveMode = false, bool _syncFromCatchup = false, + bool _testSignatures = true ) { name = _name; id = _id; ip = _ip; @@ -122,6 +124,7 @@ struct NodeInfo { syncNode = _syncNode; archiveMode = _archiveMode; syncFromCatchup = _syncFromCatchup; + testSignatures = _testSignatures; } }; diff --git a/libethereum/ChainParams.cpp b/libethereum/ChainParams.cpp index cb1b90d40..4b2be0789 100644 --- a/libethereum/ChainParams.cpp +++ b/libethereum/ChainParams.cpp @@ -217,40 +217,40 @@ void ChainParams::processSkaleConfigItems( ChainParams& cp, json_spirit::mObject if ( cp.rotateAfterBlock_ < 0 ) cp.rotateAfterBlock_ = 0; - string ecdsaKeyName; + bool testSignatures = false; try { - ecdsaKeyName = infoObj.at( "ecdsaKeyName" ).get_str(); + testSignatures = infoObj.at( "testSignatures" ).get_bool(); } catch ( ... ) { } + string ecdsaKeyName; array< string, 4 > BLSPublicKeys; array< string, 4 > commonBLSPublicKeys; + if ( !testSignatures ) { + ecdsaKeyName = infoObj.at( "ecdsaKeyName" ).get_str(); - try { js::mObject ima = infoObj.at( "wallets" ).get_obj().at( "ima" ).get_obj(); - keyShareName = ima.at( "keyShareName" ).get_str(); - - t = ima.at( "t" ).get_int(); - - BLSPublicKeys[0] = ima["BLSPublicKey0"].get_str(); - BLSPublicKeys[1] = ima["BLSPublicKey1"].get_str(); - BLSPublicKeys[2] = ima["BLSPublicKey2"].get_str(); - BLSPublicKeys[3] = ima["BLSPublicKey3"].get_str(); - commonBLSPublicKeys[0] = ima["commonBLSPublicKey0"].get_str(); commonBLSPublicKeys[1] = ima["commonBLSPublicKey1"].get_str(); commonBLSPublicKeys[2] = ima["commonBLSPublicKey2"].get_str(); commonBLSPublicKeys[3] = ima["commonBLSPublicKey3"].get_str(); - } catch ( ... ) { - // all or nothing - if ( !keyShareName.empty() ) - throw; + + if ( !syncNode ) { + keyShareName = ima.at( "keyShareName" ).get_str(); + + t = ima.at( "t" ).get_int(); + + BLSPublicKeys[0] = ima["BLSPublicKey0"].get_str(); + BLSPublicKeys[1] = ima["BLSPublicKey1"].get_str(); + BLSPublicKeys[2] = ima["BLSPublicKey2"].get_str(); + BLSPublicKeys[3] = ima["BLSPublicKey3"].get_str(); + } } cp.nodeInfo = { nodeName, nodeID, ip, static_cast< uint16_t >( port ), ip6, static_cast< uint16_t >( port6 ), sgxServerUrl, ecdsaKeyName, keyShareName, BLSPublicKeys, - commonBLSPublicKeys, syncNode, archiveMode, syncFromCatchup }; + commonBLSPublicKeys, syncNode, archiveMode, syncFromCatchup, testSignatures }; auto sChainObj = skaleObj.at( "sChain" ).get_obj(); SChain s{}; diff --git a/libethereum/SchainPatch.cpp b/libethereum/SchainPatch.cpp index 065b74210..a2e5bf19c 100644 --- a/libethereum/SchainPatch.cpp +++ b/libethereum/SchainPatch.cpp @@ -30,6 +30,8 @@ SchainPatchEnum getEnumForPatchName( const std::string& _patchName ) { return SchainPatchEnum::SkipInvalidTransactionsPatch; else if ( _patchName == "EIP1559TransactionsPatch" ) return SchainPatchEnum::EIP1559TransactionsPatch; + else if ( _patchName == "VerifyBlsSyncPatch" ) + return SchainPatchEnum::VerifyBlsSyncPatch; else if ( _patchName == "FlexibleDeploymentPatch" ) return SchainPatchEnum::FlexibleDeploymentPatch; else @@ -62,6 +64,8 @@ std::string getPatchNameForEnum( SchainPatchEnum _enumValue ) { return "SelfdestructStorageLimitPatch"; case SchainPatchEnum::EIP1559TransactionsPatch: return "EIP1559TransactionsPatch"; + case SchainPatchEnum::VerifyBlsSyncPatch: + return "VerifyBlsSyncPatch"; case SchainPatchEnum::FlexibleDeploymentPatch: return "FlexibleDeploymentPatch"; default: diff --git a/libethereum/SchainPatch.h b/libethereum/SchainPatch.h index c31628975..9af149fb9 100644 --- a/libethereum/SchainPatch.h +++ b/libethereum/SchainPatch.h @@ -135,6 +135,11 @@ DEFINE_SIMPLE_PATCH( SelfdestructStorageLimitPatch ); */ DEFINE_SIMPLE_PATCH( EIP1559TransactionsPatch ); +/* + * Enable bls signatures verification for sync node + */ +DEFINE_AMNESIC_PATCH( VerifyBlsSyncPatch ); + /* * Purpose: passing both transaction origin and sender to the ConfigController contract * Version introduced: 3.19.0 diff --git a/libethereum/SchainPatchEnum.h b/libethereum/SchainPatchEnum.h index 313432999..e77aeaa5c 100644 --- a/libethereum/SchainPatchEnum.h +++ b/libethereum/SchainPatchEnum.h @@ -17,6 +17,7 @@ enum class SchainPatchEnum { SkipInvalidTransactionsPatch, SelfdestructStorageLimitPatch, EIP1559TransactionsPatch, + VerifyBlsSyncPatch, FlexibleDeploymentPatch, PatchesCount }; diff --git a/libethereum/SkaleHost.cpp b/libethereum/SkaleHost.cpp index a830dae8a..bb91505e1 100644 --- a/libethereum/SkaleHost.cpp +++ b/libethereum/SkaleHost.cpp @@ -81,6 +81,8 @@ std::unique_ptr< ConsensusInterface > DefaultConsensusFactory::create( patchTimeStamps["verifyDaSigsPatchTimestamp"] = m_client.chainParams().getPatchTimestamp( SchainPatchEnum::VerifyDaSigsPatch ); + patchTimeStamps["verifyBlsSyncPatchTimestamp"] = + m_client.chainParams().getPatchTimestamp( SchainPatchEnum::VerifyBlsSyncPatch ); auto consensus_engine_ptr = make_unique< ConsensusEngine >( _extFace, m_client.number(), ts, 0, patchTimeStamps, m_client.chainParams().sChain.consensusStorageLimit ); @@ -89,10 +91,8 @@ std::unique_ptr< ConsensusInterface > DefaultConsensusFactory::create( this->fillSgxInfo( *consensus_engine_ptr ); } - this->fillPublicKeyInfo( *consensus_engine_ptr ); - this->fillRotationHistory( *consensus_engine_ptr ); return consensus_engine_ptr; @@ -143,13 +143,15 @@ void DefaultConsensusFactory::fillSgxInfo( ConsensusEngine& consensus ) const tr } void DefaultConsensusFactory::fillPublicKeyInfo( ConsensusEngine& consensus ) const try { + if ( m_client.chainParams().nodeInfo.testSignatures ) + // no keys in tests + return; + const std::string sgxServerUrl = m_client.chainParams().nodeInfo.sgxServerUrl; std::shared_ptr< std::vector< std::string > > ecdsaPublicKeys = std::make_shared< std::vector< std::string > >(); for ( const auto& node : m_client.chainParams().sChain.nodes ) { - if ( node.publicKey.size() == 0 ) - return; // just don't do anything ecdsaPublicKeys->push_back( node.publicKey.substr( 2 ) ); } @@ -157,15 +159,15 @@ void DefaultConsensusFactory::fillPublicKeyInfo( ConsensusEngine& consensus ) co for ( const auto& node : m_client.chainParams().sChain.nodes ) { std::vector< std::string > public_key_share( 4 ); if ( node.id != this->m_client.chainParams().nodeInfo.id ) { - public_key_share[0] = node.blsPublicKey[0]; - public_key_share[1] = node.blsPublicKey[1]; - public_key_share[2] = node.blsPublicKey[2]; - public_key_share[3] = node.blsPublicKey[3]; + public_key_share[0] = node.blsPublicKey.at( 0 ); + public_key_share[1] = node.blsPublicKey.at( 1 ); + public_key_share[2] = node.blsPublicKey.at( 2 ); + public_key_share[3] = node.blsPublicKey.at( 3 ); } else { - public_key_share[0] = m_client.chainParams().nodeInfo.BLSPublicKeys[0]; - public_key_share[1] = m_client.chainParams().nodeInfo.BLSPublicKeys[1]; - public_key_share[2] = m_client.chainParams().nodeInfo.BLSPublicKeys[2]; - public_key_share[3] = m_client.chainParams().nodeInfo.BLSPublicKeys[3]; + public_key_share[0] = m_client.chainParams().nodeInfo.BLSPublicKeys.at( 0 ); + public_key_share[1] = m_client.chainParams().nodeInfo.BLSPublicKeys.at( 1 ); + public_key_share[2] = m_client.chainParams().nodeInfo.BLSPublicKeys.at( 2 ); + public_key_share[3] = m_client.chainParams().nodeInfo.BLSPublicKeys.at( 3 ); } blsPublicKeys.push_back( @@ -179,11 +181,10 @@ void DefaultConsensusFactory::fillPublicKeyInfo( ConsensusEngine& consensus ) co size_t n = m_client.chainParams().sChain.nodes.size(); size_t t = ( 2 * n + 1 ) / 3; - if ( ecdsaPublicKeys->size() && ecdsaPublicKeys->at( 0 ).size() && blsPublicKeys.size() && - blsPublicKeys[0]->at( 0 ).size() ) - consensus.setPublicKeyInfo( ecdsaPublicKeys, blsPublicKeysPtr, t, n ); + consensus.setPublicKeyInfo( + ecdsaPublicKeys, blsPublicKeysPtr, t, n, m_client.chainParams().nodeInfo.syncNode ); } catch ( ... ) { - std::throw_with_nested( std::runtime_error( "Error filling SGX info (nodeGroups)" ) ); + std::throw_with_nested( std::runtime_error( "Error filling public keys info (nodeGroups)" ) ); } @@ -193,8 +194,9 @@ void DefaultConsensusFactory::fillRotationHistory( ConsensusEngine& consensus ) std::map< uint64_t, std::vector< uint64_t > > historicNodeGroups; auto u256toUint64 = []( const dev::u256& u ) { return std::stoull( u.str() ); }; for ( const auto& nodeGroup : m_client.chainParams().sChain.nodeGroups ) { - std::vector< string > commonBLSPublicKey = { nodeGroup.blsPublicKey[0], - nodeGroup.blsPublicKey[1], nodeGroup.blsPublicKey[2], nodeGroup.blsPublicKey[3] }; + std::vector< string > commonBLSPublicKey = { nodeGroup.blsPublicKey.at( 0 ), + nodeGroup.blsPublicKey.at( 1 ), nodeGroup.blsPublicKey.at( 2 ), + nodeGroup.blsPublicKey.at( 3 ) }; previousBLSKeys[nodeGroup.finishTs] = commonBLSPublicKey; std::vector< uint64_t > nodes; // add ecdsa keys info and historic groups info diff --git a/libethereum/ValidationSchemes.cpp b/libethereum/ValidationSchemes.cpp index 4040e774a..e6b493e7e 100644 --- a/libethereum/ValidationSchemes.cpp +++ b/libethereum/ValidationSchemes.cpp @@ -164,7 +164,7 @@ void validateConfigJson( js::mObject const& _obj ) { { "snapshotIntervalSec", { { js::int_type }, JsonFieldPresence::Optional } }, { "rotateAfterBlock", { { js::int_type }, JsonFieldPresence::Optional } }, { "wallets", { { js::obj_type }, JsonFieldPresence::Optional } }, - { "ecdsaKeyName", { { js::str_type }, JsonFieldPresence::Required } }, + { "ecdsaKeyName", { { js::str_type }, JsonFieldPresence::Optional } }, { "verifyImaMessagesViaLogsSearch", { { js::bool_type }, JsonFieldPresence::Optional } }, { "verifyImaMessagesViaContractCall", @@ -222,6 +222,7 @@ void validateConfigJson( js::mObject const& _obj ) { { "syncNode", { { js::bool_type }, JsonFieldPresence::Optional } }, { "archiveMode", { { js::bool_type }, JsonFieldPresence::Optional } }, { "syncFromCatchup", { { js::bool_type }, JsonFieldPresence::Optional } }, + { "testSignatures", { { js::bool_type }, JsonFieldPresence::Optional } }, { "wallets", { { js::obj_type }, JsonFieldPresence::Optional } } } ); std::string keyShareName = ""; @@ -268,7 +269,6 @@ void validateConfigJson( js::mObject const& _obj ) { { "maxSkaledLeveldbStorageBytes", { { js::int_type }, JsonFieldPresence::Optional } }, { "freeContractDeployment", { { js::bool_type }, JsonFieldPresence::Optional } }, { "multiTransactionMode", { { js::bool_type }, JsonFieldPresence::Optional } }, - { "nodeGroups", { { js::obj_type }, JsonFieldPresence::Optional } }, { "nodeGroups", { { js::obj_type }, JsonFieldPresence::Optional } } }, []( const string& _key ) { // function fow allowing fields diff --git a/test/unittests/libethereum/ClientTest.cpp b/test/unittests/libethereum/ClientTest.cpp index a3f8850e0..ed9bdb878 100644 --- a/test/unittests/libethereum/ClientTest.cpp +++ b/test/unittests/libethereum/ClientTest.cpp @@ -411,7 +411,7 @@ static std::string const c_genesisInfoSkaleTest = std::string() + "basePort": )E"+std::to_string( rand_port ) + R"E(, "logLevel": "trace", "logLevelProposal": "trace", - "ecdsaKeyName": "NEK:fa112" + "testSignatures": true }, "sChain": { "schainName": "TestChain", @@ -887,7 +887,7 @@ static std::string const c_genesisInfoSkaleIMABLSPublicKeyTest = std::string() + "basePort": )E"+std::to_string( rand_port ) + R"E(, "logLevel": "trace", "logLevelProposal": "trace", - "ecdsaKeyName": "NEK:fa112" + "testSignatures": true }, "sChain": { "schainName": "TestChain", @@ -1002,7 +1002,7 @@ static std::string const c_skaleConfigString = R"E( "nodeID": 1112, "bindIP": "127.0.0.1", "basePort": )E"+std::to_string( rand_port ) + R"E(, - "ecdsaKeyName": "NEK:fa112" + "testSignatures": true }, "sChain": { "schainName": "TestChain", diff --git a/test/unittests/libethereum/PrecompiledConfig.json b/test/unittests/libethereum/PrecompiledConfig.json index b7b4901f0..ec4673de2 100644 --- a/test/unittests/libethereum/PrecompiledConfig.json +++ b/test/unittests/libethereum/PrecompiledConfig.json @@ -38,7 +38,7 @@ "basePort": 1234, "logLevel": "trace", "logLevelProposal": "trace", - "ecdsaKeyName": "NEK:fa112", + "testSignatures": true, "wallets": { "ima": { "n": 1 diff --git a/test/unittests/libethereum/PrecompiledTest.cpp b/test/unittests/libethereum/PrecompiledTest.cpp index bec328e70..7be67c511 100644 --- a/test/unittests/libethereum/PrecompiledTest.cpp +++ b/test/unittests/libethereum/PrecompiledTest.cpp @@ -1619,7 +1619,7 @@ static std::string const genesisInfoSkaleConfigTest = std::string() + "basePort": 1234, "logLevel": "trace", "logLevelProposal": "trace", - "ecdsaKeyName": "NEK:fa112", + "testSignatures": true, "wallets": { "ima": { "n": 1 diff --git a/test/unittests/libethereum/SkaleHost.cpp b/test/unittests/libethereum/SkaleHost.cpp index 7f2be5290..f4b93ce8d 100644 --- a/test/unittests/libethereum/SkaleHost.cpp +++ b/test/unittests/libethereum/SkaleHost.cpp @@ -130,6 +130,7 @@ struct SkaleHostFixture : public TestOutputHelperFixture { chainParams.extraData = h256::random().asBytes(); chainParams.sChain.nodeGroups = { { {}, uint64_t(-1), {"0", "0", "1", "0"} } }; chainParams.nodeInfo.port = chainParams.nodeInfo.port6 = rand_port; + chainParams.nodeInfo.testSignatures = true; chainParams.sChain.nodes[0].port = chainParams.sChain.nodes[0].port6 = rand_port; // not 0-timestamp genesis - to test patch diff --git a/test/unittests/libweb3jsonrpc/jsonrpc.cpp b/test/unittests/libweb3jsonrpc/jsonrpc.cpp index 570017327..c004aaf6d 100644 --- a/test/unittests/libweb3jsonrpc/jsonrpc.cpp +++ b/test/unittests/libweb3jsonrpc/jsonrpc.cpp @@ -101,7 +101,7 @@ static std::string const c_genesisConfigString = "basePort": )"+std::to_string( rand_port ) + R"(, "logLevel": "trace", "logLevelProposal": "trace", - "ecdsaKeyName": "NEK:fa112" + "testSignatures": true }, "sChain": { "schainName": "TestChain",