Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug/1702 adopt precompiled oracle #1713

Merged
merged 35 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
685fd91
1702 add owner field to nodes in chain params
olehnikolaiev Oct 20, 2023
a733b76
1702 use historicGroupIndex
olehnikolaiev Oct 24, 2023
b7cd5a5
1702 update precompiled to work with oracle
olehnikolaiev Oct 24, 2023
295b850
1702 improve tests
olehnikolaiev Oct 30, 2023
786882f
1702 improve tests
olehnikolaiev Oct 31, 2023
e9b63e9
1702 remove unnecessary changes
olehnikolaiev Oct 31, 2023
4f22ffb
Merge branch 'v3.18.0' into bug/1702-adopt-precompiled-oracle
olehnikolaiev Oct 31, 2023
a348f52
1702 fix tests
olehnikolaiev Nov 1, 2023
3815c22
1702 introduce PrecompiledConfigPatch
olehnikolaiev Nov 3, 2023
ee9c48a
#1702 renamed owner to nodeAddress
kladkogex Nov 6, 2023
aa4c0d8
#1702 changed [] to at() for safe vector access
kladkogex Nov 6, 2023
95215c7
#1702 added param validation
kladkogex Nov 6, 2023
4d55443
#1702 added a log record if node info is empty in config
kladkogex Nov 6, 2023
7f136c5
#1702 changed assertion to runtime error
kladkogex Nov 6, 2023
ea28913
#1702 changed assertion to runtime error
kladkogex Nov 6, 2023
3652a82
#1702 changed to standard boost library
kladkogex Nov 6, 2023
41ddce9
1702 fix build
olehnikolaiev Nov 6, 2023
399e9b1
1702 deny access to some config fields from precompileds for security…
olehnikolaiev Nov 6, 2023
cfbd435
1702 fix tests
olehnikolaiev Nov 7, 2023
80618dd
#1702 improve code quality
olehnikolaiev Nov 7, 2023
582b526
#1702 use common approach to access config variables
olehnikolaiev Nov 8, 2023
ea694fc
#1702 improve code quality
olehnikolaiev Nov 8, 2023
ca16ebf
#1702 improve input proccessing for precompileds
olehnikolaiev Nov 13, 2023
4995613
#1702 add more checks
olehnikolaiev Nov 13, 2023
edd62d4
#1702 improve tests
olehnikolaiev Nov 13, 2023
aaab497
Merge branch 'v3.18.0' into bug/1702-adopt-precompiled-oracle
olehnikolaiev Nov 21, 2023
3b122e5
Merge branch 'v3.18.0' into bug/1702-adopt-precompiled-oracle
olehnikolaiev Nov 21, 2023
4b51081
#1702 pass historic publicKey instead of address
olehnikolaiev Nov 22, 2023
e411718
Merge branch 'bug/1702-adopt-precompiled-oracle' of github.com:skalen…
olehnikolaiev Nov 22, 2023
a504090
#1702 fix tests
olehnikolaiev Nov 22, 2023
1a67380
#1702 add more tests
olehnikolaiev Nov 22, 2023
7700738
#1702 change [] to at()
olehnikolaiev Nov 22, 2023
c8921f6
#1702 change [] to at()
olehnikolaiev Nov 22, 2023
23a5437
#1702 change [] to at()
olehnikolaiev Nov 22, 2023
d301345
Merge branch 'v3.18.0' into bug/1702-adopt-precompiled-oracle
olehnikolaiev Nov 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libethcore/ChainOperationParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ struct GroupNode {
u256 id;
u256 schainIndex;
std::string publicKey;
std::string owner;
};

/// skale
Expand Down
3 changes: 2 additions & 1 deletion libethereum/ChainParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ ChainParams ChainParams::loadConfig(
u256 sChainIndex = groupNodeConfObj[0].get_uint64();
u256 id = groupNodeConfObj[1].get_uint64();
std::string publicKey = groupNodeConfObj[2].get_str();
groupNodes.push_back( { id, sChainIndex, publicKey } );
std::string owner = groupNodeConfObj[3].get_str();
groupNodes.push_back( { id, sChainIndex, publicKey, owner } );
}
std::sort( groupNodes.begin(), groupNodes.end(),
[]( const GroupNode& lhs, const GroupNode& rhs ) {
Expand Down
18 changes: 9 additions & 9 deletions libethereum/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@
Defaults::setDBPath( m_dbPath );

if ( ChainParams().sChain.nodeGroups.size() > 0 )
initIMABLSPublicKey();
initHistoricGroupIndex();

Check warning on line 317 in libethereum/Client.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Client.cpp#L317

Added line #L317 was not covered by tests

// init snapshots for not newly created chains
if ( number() ) {
Expand Down Expand Up @@ -621,7 +621,7 @@
}

if ( chainParams().sChain.nodeGroups.size() > 0 )
updateIMABLSPublicKey();
updateHistoricGroupIndex();

m_snapshotAgent->doSnapshotIfNeeded( number(), _timestamp );

Expand Down Expand Up @@ -1288,9 +1288,9 @@
return ret;
}

void Client::initIMABLSPublicKey() {
void Client::initHistoricGroupIndex() {

Check warning on line 1291 in libethereum/Client.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Client.cpp#L1291

Added line #L1291 was not covered by tests
if ( number() == 0 ) {
imaBLSPublicKeyGroupIndex = 0;
historicGroupIndex = 0;

Check warning on line 1293 in libethereum/Client.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Client.cpp#L1293

Added line #L1293 was not covered by tests
return;
}

Expand All @@ -1311,15 +1311,15 @@
it = prevIt;
}

imaBLSPublicKeyGroupIndex = std::distance( chainParams().sChain.nodeGroups.begin(), it );
historicGroupIndex = std::distance( chainParams().sChain.nodeGroups.begin(), it );

Check warning on line 1314 in libethereum/Client.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Client.cpp#L1314

Added line #L1314 was not covered by tests
}

void Client::updateIMABLSPublicKey() {
void Client::updateHistoricGroupIndex() {
uint64_t blockTimestamp = blockInfo( hashFromNumber( number() ) ).timestamp();
uint64_t currentFinishTs = chainParams().sChain.nodeGroups[imaBLSPublicKeyGroupIndex].finishTs;
uint64_t currentFinishTs = chainParams().sChain.nodeGroups[historicGroupIndex].finishTs;
if ( blockTimestamp >= currentFinishTs )
++imaBLSPublicKeyGroupIndex;
assert( imaBLSPublicKeyGroupIndex < chainParams().sChain.nodeGroups.size() );
++historicGroupIndex;
assert( historicGroupIndex < chainParams().sChain.nodeGroups.size() );
}

// new block watch
Expand Down
24 changes: 20 additions & 4 deletions libethereum/Client.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,22 @@ class Client : public ClientBase, protected Worker {
}

std::array< std::string, 4 > getIMABLSPublicKey() const {
return chainParams().sChain.nodeGroups[imaBLSPublicKeyGroupIndex].blsPublicKey;
return chainParams().sChain.nodeGroups[historicGroupIndex].blsPublicKey;
}

// get node id for historic node in chain
std::string getHistoricNodeId( unsigned _id ) const {
return chainParams().sChain.nodeGroups[historicGroupIndex].nodes[_id].id.str();
}

// get schain index for historic node in chain
std::string getHistoricNodeIndex( unsigned _idx ) const {
return chainParams().sChain.nodeGroups[historicGroupIndex].nodes[_idx].schainIndex.str();
}

// get node owner for historic node in chain
std::string getHistoricNodeOwner( unsigned _idx ) const {
return chainParams().sChain.nodeGroups[historicGroupIndex].nodes[_idx].owner;
}

void doStateDbCompaction() const { m_state.getOriginalDb()->doCompaction(); }
Expand Down Expand Up @@ -532,10 +547,11 @@ class Client : public ClientBase, protected Worker {
fs::path m_dbPath;

private:
void initIMABLSPublicKey();
void updateIMABLSPublicKey();
void initHistoricGroupIndex();
void updateHistoricGroupIndex();

unsigned imaBLSPublicKeyGroupIndex = 0;
// which group corresponds to the current block timestamp on this node
unsigned historicGroupIndex = 0;

public:
FILE* performance_fd;
Expand Down
80 changes: 69 additions & 11 deletions libethereum/Precompiled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,26 @@
return uValue;
}

static bool isCallToHistoricData( const std::string& callData ) {
return skutils::tools::wildcmp( "skaleConfig.sChain.nodes.*", callData.c_str() );

Check warning on line 760 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L759-L760

Added lines #L759 - L760 were not covered by tests
}

static std::pair< std::string, unsigned > parseHistoricFieldReuqest( const std::string& callData ) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please improve so that exact matches are always used, so inccorect strings do not result in a match

size_t numberLength = callData.find( ']' ) - callData.find( '[' ) - 1;
unsigned id = std::stoul( callData.substr( callData.find( '[' ) + 1, numberLength ) );
std::string fieldName;
if ( callData.find( "id" ) != std::string::npos ) {
fieldName = "id";
} else if ( callData.find( "schainIndex" ) != std::string::npos ) {
fieldName = "schainIndex";
} else if ( callData.find( "owner" ) != std::string::npos ) {
fieldName = "owner";

Check warning on line 772 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L763-L772

Added lines #L763 - L772 were not covered by tests
} else {
fieldName = "unknown field";

Check warning on line 774 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L774

Added line #L774 was not covered by tests
}
return { fieldName, id };

Check warning on line 776 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L776

Added line #L776 was not covered by tests
}

ETH_REGISTER_PRECOMPILED( getConfigVariableUint256 )( bytesConstRef _in ) {
try {
size_t lengthName;
Expand All @@ -767,18 +787,37 @@

if ( !g_configAccesssor )
throw std::runtime_error( "Config accessor was not initialized" );
nlohmann::json joConfig = g_configAccesssor->getConfigJSON();
nlohmann::json joValue =
skutils::json_config_file_accessor::stat_extract_at_path( joConfig, rawName );
std::string strValue = skutils::tools::trim_copy(
joValue.is_string() ? joValue.get< std::string >() : joValue.dump() );

std::string strValue;

Check warning on line 791 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L791

Added line #L791 was not covered by tests
// call to skaleConfig.sChain.nodes means call to the historic data
// need to proccess it in a different way
if ( isCallToHistoricData( rawName ) ) {
if ( !g_skaleHost )
throw std::runtime_error( "SkaleHost accessor was not initialized" );

Check warning on line 796 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L794-L796

Added lines #L794 - L796 were not covered by tests

std::string field;

Check warning on line 798 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L798

Added line #L798 was not covered by tests
unsigned id;
std::tie( field, id ) = parseHistoricFieldReuqest( rawName );
if ( field == "id" ) {
strValue = g_skaleHost->getHistoricNodeId( id );
} else if ( field == "schainIndex" ) {
strValue = g_skaleHost->getHistoricNodeIndex( id );

Check warning on line 804 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L800-L804

Added lines #L800 - L804 were not covered by tests
} else {
throw std::runtime_error( "Incorrect config field" );

Check warning on line 806 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L806

Added line #L806 was not covered by tests
}
} else {
nlohmann::json joConfig = g_configAccesssor->getConfigJSON();

Check warning on line 809 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L809

Added line #L809 was not covered by tests
nlohmann::json joValue =
skutils::json_config_file_accessor::stat_extract_at_path( joConfig, rawName );
strValue = skutils::tools::trim_copy(
joValue.is_string() ? joValue.get< std::string >() : joValue.dump() );

Check warning on line 813 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L811-L813

Added lines #L811 - L813 were not covered by tests
}
Comment on lines +826 to +832
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change so that the else {} part is only used when the patch is enabled, since stat_extract_at_path is unsecure and complex. If it is needed, it needs to be rewritten in a clean and secure
way using standard C++ and boost libraries


// dev::u256 uValue( strValue.c_str() );
dev::u256 uValue = stat_parse_u256_hex_or_dec( strValue );
// std::cout << "------------ Loaded config var \""
// << rawName << "\" value is " << uValue
// << "\n";

bytes response = toBigEndian( uValue );
return { true, response };
} catch ( std::exception& ex ) {
Expand Down Expand Up @@ -807,11 +846,30 @@

if ( !g_configAccesssor )
throw std::runtime_error( "Config accessor was not initialized" );
nlohmann::json joConfig = g_configAccesssor->getConfigJSON();
nlohmann::json joValue =
skutils::json_config_file_accessor::stat_extract_at_path( joConfig, rawName );
std::string strValue = skutils::tools::trim_copy(
joValue.is_string() ? joValue.get< std::string >() : joValue.dump() );

std::string strValue;

Check warning on line 850 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L850

Added line #L850 was not covered by tests
// call to skaleConfig.sChain.nodes means call to the historic data
// need to proccess it in a different way
if ( isCallToHistoricData( rawName ) ) {
if ( !g_skaleHost )
throw std::runtime_error( "SkaleHost accessor was not initialized" );

Check warning on line 855 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L853-L855

Added lines #L853 - L855 were not covered by tests

std::string field;

Check warning on line 857 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L857

Added line #L857 was not covered by tests
unsigned id;
std::tie( field, id ) = parseHistoricFieldReuqest( rawName );
if ( field == "owner" ) {
strValue = g_skaleHost->getHistoricNodeOwner( id );

Check warning on line 861 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L859-L861

Added lines #L859 - L861 were not covered by tests
} else {
throw std::runtime_error( "Incorrect config field" );

Check warning on line 863 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L863

Added line #L863 was not covered by tests
}
} else {
nlohmann::json joConfig = g_configAccesssor->getConfigJSON();

Check warning on line 866 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L866

Added line #L866 was not covered by tests
nlohmann::json joValue =
skutils::json_config_file_accessor::stat_extract_at_path( joConfig, rawName );
strValue = skutils::tools::trim_copy(
joValue.is_string() ? joValue.get< std::string >() : joValue.dump() );

Check warning on line 870 in libethereum/Precompiled.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/Precompiled.cpp#L868-L870

Added lines #L868 - L870 were not covered by tests
}

dev::u256 uValue( strValue.c_str() );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c_str() is not needed here since the constructor takes std::string


bytes response = toBigEndian( uValue );
Expand Down
12 changes: 12 additions & 0 deletions libethereum/SkaleHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,18 @@
return m_client.getIMABLSPublicKey();
}

std::string SkaleHost::getHistoricNodeId( unsigned _id ) const {
return m_client.getHistoricNodeId( _id );

Check warning on line 954 in libethereum/SkaleHost.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/SkaleHost.cpp#L953-L954

Added lines #L953 - L954 were not covered by tests
}

std::string SkaleHost::getHistoricNodeIndex( unsigned _index ) const {
return m_client.getHistoricNodeIndex( _index );

Check warning on line 958 in libethereum/SkaleHost.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/SkaleHost.cpp#L957-L958

Added lines #L957 - L958 were not covered by tests
}

std::string SkaleHost::getHistoricNodeOwner( unsigned _idx ) const {
return m_client.getHistoricNodeOwner( _idx );

Check warning on line 962 in libethereum/SkaleHost.cpp

View check run for this annotation

Codecov / codecov/patch

libethereum/SkaleHost.cpp#L961-L962

Added lines #L961 - L962 were not covered by tests
}

uint64_t SkaleHost::submitOracleRequest(
const string& _spec, string& _receipt, string& _errorMessage ) {
return m_consensus->submitOracleRequest( _spec, _receipt, _errorMessage );
Expand Down
9 changes: 9 additions & 0 deletions libethereum/SkaleHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,15 @@ class SkaleHost {
std::map< std::string, uint64_t > getConsensusDbUsage() const;
std::array< std::string, 4 > getIMABLSPublicKey() const;

// get node id for historic node in chain
std::string getHistoricNodeId( unsigned _id ) const;

// get schain index for historic node in chain
std::string getHistoricNodeIndex( unsigned _idx ) const;

// get node owner for historic node in chain
std::string getHistoricNodeOwner( unsigned _idx ) const;

uint64_t submitOracleRequest( const string& _spec, string& _receipt, string& _errorMessage );
uint64_t checkOracleResult( const string& _receipt, string& _result );

Expand Down
14 changes: 10 additions & 4 deletions test/unittests/libethereum/ClientTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,8 @@ static std::string const c_genesisInfoSkaleIMABLSPublicKeyTest = std::string() +
"30": [
0,
30,
"0x6180cde2cbbcc6b6a17efec4503a7d4316f8612f411ee171587089f770335f484003ad236c534b9afa82befc1f69533723abdb6ec2601e582b72dcfd7919338b"
"0x6180cde2cbbcc6b6a17efec4503a7d4316f8612f411ee171587089f770335f484003ad236c534b9afa82befc1f69533723abdb6ec2601e582b72dcfd7919338b",
"0x23bbe8db4e347b4e8c937c1c8350e4b5ed33adb3db69cbdb7a38e1f40a1b82fe"
]
},
"finish_ts": null,
Expand All @@ -887,7 +888,8 @@ static std::string const c_genesisInfoSkaleIMABLSPublicKeyTest = std::string() +
"26": [
3,
26,
"0x3a581d62b12232dade30c3710215a271984841657449d1f474295a13737b778266f57e298f123ae80cbab7cc35ead1b62a387556f94b326d5c65d4a7aa2abcba"
"0x3a581d62b12232dade30c3710215a271984841657449d1f474295a13737b778266f57e298f123ae80cbab7cc35ead1b62a387556f94b326d5c65d4a7aa2abcba",
"0x47bbe8db4e347b4e8c937c1c8350e4b7ed30adb3db69bbdb7a38c1f40a1b82fd"
]
},
"finish_ts": 4294967290,
Expand Down Expand Up @@ -923,9 +925,10 @@ BOOST_AUTO_TEST_CASE( initAndUpdateIMABLSPUblicKey ) {

std::array< std::string, 4 > imaBLSPublicKeyOnStartUp = { "12457351342169393659284905310882617316356538373005664536506840512800919345414", "11573096151310346982175966190385407867176668720531590318594794283907348596326", "13929944172721019694880576097738949215943314024940461401664534665129747139387", "7375214420811287025501422512322868338311819657776589198925786170409964211914" };


BOOST_REQUIRE( testClient->getIMABLSPublicKey() == imaBLSPublicKeyOnStartUp );

BOOST_REQUIRE( testClient->getHistoricNodeOwner( 0 ) == "0x47bbe8db4e347b4e8c937c1c8350e4b7ed30adb3db69bbdb7a38c1f40a1b82fd" );
BOOST_REQUIRE( testClient->getHistoricNodeId( 0 ) == "26" );
BOOST_REQUIRE( testClient->getHistoricNodeIndex( 0 ) == "3" );

BOOST_REQUIRE( testClient->mineBlocks( 1 ) );

Expand All @@ -934,6 +937,9 @@ BOOST_AUTO_TEST_CASE( initAndUpdateIMABLSPUblicKey ) {
std::array< std::string, 4 > imaBLSPublicKeyAfterBlock = { "10860211539819517237363395256510340030868592687836950245163587507107792195621", "2419969454136313127863904023626922181546178935031521540751337209075607503568", "3399776985251727272800732947224655319335094876742988846345707000254666193993", "16982202412630419037827505223148517434545454619191931299977913428346639096984" };

BOOST_REQUIRE( testClient->getIMABLSPublicKey() == imaBLSPublicKeyAfterBlock );
BOOST_REQUIRE( testClient->getHistoricNodeOwner( 0 ) == "0x23bbe8db4e347b4e8c937c1c8350e4b5ed33adb3db69cbdb7a38e1f40a1b82fe" );
BOOST_REQUIRE( testClient->getHistoricNodeId( 0 ) == "30" );
BOOST_REQUIRE( testClient->getHistoricNodeIndex( 0 ) == "0" );
}

BOOST_AUTO_TEST_SUITE_END()
Expand Down
Loading
Loading