Open DmytroNazarenko opened 2 months ago
Root cause: racing condition between two lines here:
Block temp = preSeal();
State readStateForLock = temp.mutableState().createStateReadOnlyCopy();
Way to reproduce:
add sleep
Block temp = preSeal();
LOG( m_loggerDetail ) << "got preSeal: verion = " << *( temp.state().m_storedVersion );
this_thread::sleep_for( 2s );
// TODO there can be race conditions between prev and next line!
State readStateForLock = temp.mutableState().createStateReadOnlyCopy();
2024-08-14 12:08:44.504968 Current state version is 2 but stored version is 3
2024-08-14 12:08:44.505041 exception in client call(2):/home/dimalit/skaled/libskale/State.cpp(457): Throw in function dev::eth::Account* skale::State::account(const Address&)
Dynamic exception type: boost::exception_detail::clone_impl<skale::error::AttemptToReadFromStateInThePast>
2024-08-14 12:08:44.505370 http://127.0.0.1:55250 <<< {"error":{"code":-32004,"message":"Invalid RPC parameters."},"id":1,"jsonrpc":"2.0"} 2024-08-14 12:08:44.505459 Performance warning: 2.002512 seconds execution time for eth_call call with id=1 when called from origin http://127.0.0.1:55250 through server with index=0
Unit test that reproduces:
BOOST_AUTO_TEST_CASE( RaceOnVersion ) {
Address addr{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"};
State base( 0 );
State copy = base;
thread writer([&base, addr](){
State w = base.createStateModifyCopy();
w.incNonce( addr );
w.commit(dev::eth::CommitBehaviour::RemoveEmptyAccounts );
});
this_thread::sleep_for(1s);
BOOST_REQUIRE_THROW( copy.getNonce(addr), skale::error::AttemptToReadFromStateInThePast );
writer.join();
}
(StateUnitTests.cpp)
Test with snapshot-based State:
BOOST_AUTO_TEST_CASE( RaceOnVersion ) {
Address addr{ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" };
State base( 0, "/tmp/state", h256() );
base.createReadOnlyStateDBSnap( 0 );
State copy = base.createReadOnlySnapBasedCopy();
thread writer( [&base, addr]() {
base.incNonce( addr );
base.commit( dev::eth::CommitBehaviour::RemoveEmptyAccounts );
} );
this_thread::sleep_for( 1s );
copy.getNonce( addr );
writer.join();
}
valgrind --tool=helgrind ./testeth -t StateUnitTests/RaceOnVersion -- --verbosity 3 --express
(no errors reported)
Per @dimalit : the problem should be fixed by https://github.com/skalenetwork/skaled/issues/1545
Description
While making eth_call to the latest block, the error
Invalid RPC parameters
has appeared:The
Invalid RPC parameters
error was caused by the exception in skaled:AttemptToReadFromStateInThePast
Need to investigate and fix the problem
Environment
light-vast-diphda
Logs
Discover search [2024-08-09T13_50_21.265+01_00].csv