monero icon indicating copy to clipboard operation
monero copied to clipboard

[DRAFT] Add ReadWrite locking mechanism on top of Blockchain.

Open 0xFFFC0000 opened this issue 1 year ago • 2 comments

This will fix existing locking issues, and provide a foundation to implement more fine-grained locking mechanisms in future works.

0xFFFC0000 avatar Feb 14 '24 12:02 0xFFFC0000

@jeffro256 thanks for your comment. I left some comments too.

0xFFFC0000 avatar Feb 15 '24 13:02 0xFFFC0000

Leaving this here just to keep in mind. This deadlock should be fixed:

Thread 1, waiting while holding the lock:

libc.so.6!__futex_abstimed_wait_common (Unknown Source:0)
libc.so.6!pthread_cond_wait@@GLIBC_2.3.2 (Unknown Source:0)
boost::condition_variable::wait(boost::unique_lock<boost::mutex> & m, boost::condition_variable * const this) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/thread/pthread/condition_variable.hpp:76)
tools::threadpool::waiter::wait(tools::threadpool::waiter * const this, tools::threadpool::waiter * const this@entry) (/home/0xfffc/developments/monero/src/common/threadpool.cpp:135)
cryptonote::Blockchain::prepare_handle_incoming_blocks(cryptonote::Blockchain * const this, const std::vector<cryptonote::block_complete_entry, std::allocator<cryptonote::block_complete_entry> > & blocks_entry, std::vector<cryptonote::block, std::allocator<cryptonote::block> > & blocks) (/home/0xfffc/developments/monero/src/cryptonote_core/blockchain.cpp:5366)
cryptonote::core::prepare_handle_incoming_blocks(std::vector<cryptonote::block, std::allocator<cryptonote::block> > & blocks, const std::vector<cryptonote::block_complete_entry, std::allocator<cryptonote::block_complete_entry> > & blocks_entry, cryptonote::core * const this) (/home/0xfffc/developments/monero/src/cryptonote_core/cryptonote_core.cpp:1620)
cryptonote::core::handle_block_found(cryptonote::core * const this, cryptonote::block & b, cryptonote::block_verification_context & bvc) (/home/0xfffc/developments/monero/src/cryptonote_core/cryptonote_core.cpp:1555)
cryptonote::core_rpc_server::on_submitblock(cryptonote::core_rpc_server * const this, const cryptonote::COMMAND_RPC_SUBMITBLOCK::request & req, cryptonote::COMMAND_RPC_SUBMITBLOCK::response & res, epee::json_rpc::error & error_resp, const cryptonote::core_rpc_server::connection_context * ctx) (/home/0xfffc/developments/monero/src/rpc/core_rpc_server.cpp:2255)
cryptonote::core_rpc_server::on_generateblocks(cryptonote::core_rpc_server * const this, const cryptonote::COMMAND_RPC_GENERATEBLOCKS::request & req, cryptonote::COMMAND_RPC_GENERATEBLOCKS::response & res, epee::json_rpc::error & error_resp, const cryptonote::core_rpc_server::connection_context * ctx) (/home/0xfffc/developments/monero/src/rpc/core_rpc_server.cpp:2327)
cryptonote::core_rpc_server::handle_http_request_map<epee::net_utils::connection_context_base>(cryptonote::core_rpc_server * const this, cryptonote::core_rpc_server * const this@entry, const epee::net_utils::http::http_request_info & query_info, epee::net_utils::http::http_response_info & response_info, epee::net_utils::connection_context_base & m_conn_context) (/home/0xfffc/developments/monero/src/rpc/core_rpc_server.h:152)
cryptonote::core_rpc_server::handle_http_request(cryptonote::core_rpc_server * const this, const epee::net_utils::http::http_request_info & query_info, epee::net_utils::http::http_response_info & response, cryptonote::core_rpc_server::connection_context & m_conn_context) (/home/0xfffc/developments/monero/src/rpc/core_rpc_server.h:95)
epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base>::handle_request(epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> * const this, const epee::net_utils::http::http_request_info & query_info, epee::net_utils::http::http_response_info & response) (/home/0xfffc/developments/monero/contrib/epee/include/net/http_protocol_handler.h:201)
epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base>::handle_request_and_send_response(epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base> * const this, const epee::net_utils::http::http_request_info & query_info) (/home/0xfffc/developments/monero/contrib/epee/include/net/http_protocol_handler.inl:589)
epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base>::handle_query_measure(epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base> * const this) (/home/0xfffc/developments/monero/contrib/epee/include/net/http_protocol_handler.inl:503)
epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base>::handle_query_measure(epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base> * const this) (/home/0xfffc/developments/monero/contrib/epee/include/net/http_protocol_handler.inl:486)
epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base>::handle_retriving_query_body(epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base> * const this) (/home/0xfffc/developments/monero/contrib/epee/include/net/http_protocol_handler.inl:471)
epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base>::handle_recv(epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base> * const this, epee::net_utils::http::simple_http_connection_handler<epee::net_utils::connection_context_base> * const this@entry, const void * ptr, const void * ptr@entry, size_t cb, size_t cb@entry) (/usr/include/c++/13/bits/new_allocator.h:104)
epee::net_utils::connection<epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> >::start_read()::{lambda(boost::system::error_code const&, unsigned long)#1}::operator()(boost::system::error_code const&, unsigned long) const::{lambda()#1}::operator()() const(const struct {...} * const __closure) (/home/0xfffc/developments/monero/contrib/epee/include/net/abstract_tcp_server2.inl:406)
boost::asio::asio_handler_invoke<epee::net_utils::connection<epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> >::start_read()::{lambda(boost::system::error_code const&, unsigned long)#1}::operator()(boost::system::error_code const&, unsigned long) const::{lambda()#1}>(epee::net_utils::connection<epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> >::start_read()::{lambda(boost::system::error_code const&, unsigned long)#1}::operator()(boost::system::error_code const&, unsigned long) const::{lambda()#1}&, ...)(struct {...} & function) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/asio/handler_invoke_hook.hpp:69)
boost_asio_handler_invoke_helpers::invoke<epee::net_utils::connection<epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> >::start_read()::{lambda(boost::system::error_code const&, unsigned long)#1}::operator()(boost::system::error_code const&, unsigned long) const::{lambda()#1}, epee::net_utils::connection<epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> >::start_read()::{lambda(boost::system::error_code const&, unsigned long)#1}::operator()(boost::system::error_code const&, unsigned long) const::{lambda()#1}>(epee::net_utils::connection<epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> >::start_read()::{lambda(boost::system::error_code const&, unsigned long)#1}::operator()(boost::system::error_code const&, unsigned long) const::{lambda()#1}&, epee::net_utils::connection<epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> >::start_read()::{lambda(boost::system::error_code const&, unsigned long)#1}::operator()(boost::system::error_code const&, unsigned long) const::{lambda()#1}&)(struct {...} & context, struct {...} & function) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/asio/detail/handler_invoke_helpers.hpp:37)
boost::asio::detail::completion_handler<epee::net_utils::connection<epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> >::start_read()::{lambda(boost::system::error_code const&, unsigned long)#1}::operator()(boost::system::error_code const&, unsigned long) const::{lambda()#1}>::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long)(boost::asio::detail::io_service_impl * owner, boost::asio::detail::operation * base) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/asio/detail/completion_handler.hpp:68)
boost::asio::detail::task_io_service_operation::complete(std::size_t bytes_transferred, const boost::system::error_code & ec, boost::asio::detail::task_io_service & owner, boost::asio::detail::task_io_service_operation * const this) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/asio/detail/task_io_service_operation.hpp:38)
boost::asio::detail::strand_service::do_complete(boost::asio::detail::io_service_impl * owner, boost::asio::detail::operation * base, const boost::system::error_code & ec) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/asio/detail/impl/strand_service.ipp:167)
boost::asio::detail::task_io_service_operation::complete(std::size_t bytes_transferred, const boost::system::error_code & ec, boost::asio::detail::task_io_service & owner, boost::asio::detail::task_io_service_operation * const this) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/asio/detail/task_io_service_operation.hpp:38)
boost::asio::detail::task_io_service::do_run_one(const boost::system::error_code & ec, boost::asio::detail::task_io_service::thread_info & this_thread, boost::asio::detail::posix_mutex::scoped_lock & lock, boost::asio::detail::task_io_service * const this) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/asio/detail/impl/task_io_service.ipp:372)
boost::asio::detail::task_io_service::run(boost::system::error_code & ec, boost::asio::detail::task_io_service * const this) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/asio/detail/impl/task_io_service.ipp:149)
boost::asio::io_service::run(boost::asio::io_service * const this) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/asio/impl/io_service.ipp:59)
epee::net_utils::boosted_tcp_server<epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> >::worker_thread(epee::net_utils::boosted_tcp_server<epee::net_utils::http::http_custom_handler<epee::net_utils::connection_context_base> > * const this) (/home/0xfffc/developments/monero/contrib/epee/include/net/abstract_tcp_server2.inl:1317)
boost::(anonymous namespace)::thread_proxy(void * param) (/home/0xfffc/developments/monero/contrib/depends/work/build/x86_64-pc-linux-gnu/boost/1_64_0-41f40726f35/libs/thread/src/pthread/thread.cpp:171)
libc.so.6!start_thread (Unknown Source:0)
libc.so.6!clone3 (Unknown Source:0)

Thread 2, locking while other thread has the lock:

libc.so.6!__futex_abstimed_wait_common (Unknown Source:0)
libc.so.6!pthread_cond_wait@@GLIBC_2.3.2 (Unknown Source:0)
boost::condition_variable::wait(boost::unique_lock<boost::mutex> & m, boost::condition_variable * const this) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/thread/pthread/condition_variable.hpp:76)
boost::shared_mutex::lock_shared(boost::shared_mutex * const this) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/thread/pthread/shared_mutex.hpp:191)
boost::shared_lock<boost::shared_mutex>::lock(boost::shared_lock<boost::shared_mutex> * const this) (/home/0xfffc/developments/monero/contrib/depends/x86_64-pc-linux-gnu/include/boost/thread/lock_types.hpp:645)
cryptonote::Blockchain::blockchain_transaction::start_read(cryptonote::Blockchain::blockchain_transaction * const this) (/home/0xfffc/developments/monero/src/cryptonote_core/blockchain.h:142)
cryptonote::Blockchain::get_block_id_by_height(const cryptonote::Blockchain * const this, uint64_t height) (/home/0xfffc/developments/monero/src/cryptonote_core/blockchain.cpp:793)
cryptonote::Blockchain::get_pending_block_id_by_height(const cryptonote::Blockchain * const this, const cryptonote::Blockchain * const this@entry, uint64_t height) (/home/0xfffc/developments/monero/src/cryptonote_core/blockchain.cpp:822)
cryptonote::get_block_longhash(const cryptonote::Blockchain * pbc, const cryptonote::blobdata & bd, crypto::hash & res, const uint64_t height, const int major_version, const crypto::hash * seed_hash, const int miners) (/home/0xfffc/developments/monero/src/cryptonote_core/cryptonote_tx_utils.cpp:695)
cryptonote::get_block_longhash(const int miners, const crypto::hash * seed_hash, const uint64_t height, crypto::hash & res, const cryptonote::block & b, const cryptonote::Blockchain * pbc) (/home/0xfffc/developments/monero/src/cryptonote_core/cryptonote_tx_utils.cpp:711)
cryptonote::get_block_longhash(const cryptonote::Blockchain * pbc, const cryptonote::Blockchain * pbc@entry, const cryptonote::block & b, const uint64_t height, const uint64_t height@entry, const crypto::hash * seed_hash, const crypto::hash * seed_hash@entry, const int miners, const int miners@entry) (/home/0xfffc/developments/monero/src/cryptonote_core/cryptonote_tx_utils.cpp:717)
cryptonote::Blockchain::block_longhash_worker(const cryptonote::Blockchain * const this, uint64_t height, const epee::span<cryptonote::block const> & blocks, std::unordered_map<crypto::hash, crypto::hash, std::hash<crypto::hash>, std::equal_to<crypto::hash>, std::allocator<std::pair<crypto::hash const, crypto::hash> > > & map) (/home/0xfffc/developments/monero/src/cryptonote_core/blockchain.cpp:4985)
std::function<void ()>::operator()() const(const std::function<void()> * const this) (/usr/include/c++/13/bits/std_function.h:591)
tools::threadpool::run(tools::threadpool * const this, bool flush) (/home/0xfffc/developments/monero/src/common/threadpool.cpp:169)
boost::(anonymous namespace)::thread_proxy(void * param) (/home/0xfffc/developments/monero/contrib/depends/work/build/x86_64-pc-linux-gnu/boost/1_64_0-41f40726f35/libs/thread/src/pthread/thread.cpp:171)
libc.so.6!start_thread (Unknown Source:0)
libc.so.6!clone3 (Unknown Source:0)

0xFFFC0000 avatar Feb 16 '24 10:02 0xFFFC0000