AntelopeIO / leap

C++ implementation of the Antelope protocol
Other
116 stars 68 forks source link

New RPC endpoint send_read_only_transaction #440

Closed linh2931 closed 1 year ago

linh2931 commented 2 years ago

This is the first of the three phases of implementing parallel readonly transaction execution. The task is to make sure readonly transactions to be handled correctly without multithreading involved. After this is done, move to parallelizing readonly transactions and necessary configuration changes.

  1. Create a new RPC endpoint send_readonly_transaction.
  2. Do not set contract account usage with default CPU and NET usage initially. This is to prevent resource_limits_config_object from updated.
  3. Do not create transaction_object, as duplicate transaction checking is not needed for readonly transactions.
  4. Do not increment action sequence (dynamic_global_property_object), receiver sequence (account_metadata_object), auth sequence (account_metadata_object) at the end of transaction execution. Readonly transactions should be a no-op on those sequences.
  5. Do not update transaction usage (resource_usage_object) at the end of transaction execution.
  6. Do not allow authority checks so that permission_usage_object is not updated.
  7. Assert when a user (a smart contract) tries to modify DB states. Specifically, add asserts to db_store_i64, db_update_i64, and db_remove_i64 in chain/apply_context.cpp, store, update, and remove in generic_index class in apply_context.hpp.
  8. Assert when native functions are called to change database. Specifically, add assert to any method in eosio_contract.cpp which modifies DB states.
  9. Set chainbase mode to assert_on_wirte. Assert if any of create, modify, remove is called. This is intended to be a safety net. Any assert in assert_on_wirte mode is a bug which requires a fix.
  10. Only enforce block CPU deadline, and in next phase enforce parallel readonly transactions deadline.
  11. Do not perform deepmind logging for readonly transactions.

See also https://github.com/eosnetworkfoundation/product/issues/95 https://github.com/AntelopeIO/leap/issues/364

linh2931 commented 2 years ago

To help identify where to disable chainbase state modification while executing readonly transactions, below is a list of locations that modify chainbase state:

  1. resource_limits_manager::update_account_usage. Modify resource_limits_config_object to set initial CPU and NET usage by an account. Called by transaction_context::init(), in turn by transaction_context::init_for_input_trx()
  2. transaction_context::record_transaction. Create transaction_object for checks for dups. Called by transaction_context::init_for_input_trx()
  3. Increment global_action_sequence in dynamic_global_property_object. Called by apply_context::next_global_sequence(), in turn by apply_context::exec_one()
  4. Increment recv_sequence in account_metadata_object. Called by apply_context::next_recv_sequence(), in turn by apply_context::exec_one()
  5. Increment auth_sequence in account_metadata_object. Called by apply_context::next_auth_sequence(), in turn by apply_context::exec_one()
  6. resource_limits_manager::add_transaction_usage. Modify resource_usage_object to set actual CPU and NET usage by an account. Called by transaction_context::finalize()
  7. authorization_manager::update_permission_usage. Modify permission_usage_object to update permission usage. Called by transaction_context::finalize()