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

Support multiple http endpoints #1137

Merged
merged 14 commits into from May 15, 2023
Merged

Support multiple http endpoints #1137

merged 14 commits into from May 15, 2023

Conversation

huangminghuang
Copy link
Contributor

@huangminghuang huangminghuang commented May 5, 2023

This PR implements the proposal https://github.com/eosnetworkfoundation/product/blob/main/api-http/proposals/http-plugin.md to support multiple endpoints for http plugins.

APIs are categorized into the following groups:

chain_ro

  • v1/chain/get_activated_protocol_features
  • v1/chain/get_block_info
  • v1/chain/get_block_header_state
  • v1/chain/get_account
  • v1/chain/get_code
  • v1/chain/get_code_hash
  • v1/chain/get_consensus_parameters
  • v1/chain/get_abi
  • v1/chain/get_raw_code_and_abi
  • v1/chain/get_raw_abi
  • v1/chain/get_table_rows
  • v1/chain/get_table_by_scope
  • v1/chain/get_currency_balance
  • v1/chain/get_currency_stats
  • v1/chain/get_producers
  • v1/chain/get_producer_schedule
  • v1/chain/get_scheduled_transactions
  • v1/chain/get_required_keys
  • v1/chain/get_transaction_id
  • v1/chain/send_read_only_transaction
  • v1/chain/get_accounts_by_authorizers
  • v1/chain/get_raw_block
  • v1/chain/get_block
  • v1/chain/get_block_header
  • v1/chain/get_transaction_status

chain_rw

  • v1/chain/compute_transaction
  • v1/chain/push_transaction
  • v1/chain/push_transactions
  • v1/chain/send_transaction
  • v1/chain/send_transaction2

db_size

  • v1/db_size/get

net_ro

  • v1/net/status
  • v1/net/connections

net_rw

  • v1/net/connect
  • v1/net/disconnect

producer_ro

  • v1/producer/paused
  • v1/producer/get_runtime_options
  • v1/producer/get_greylist
  • v1/producer/get_whitelist_blacklist
  • v1/producer/get_scheduled_protocol_feature_activations
  • v1/producer/get_supported_protocol_features
  • v1/producer/get_account_ram_corrections
  • v1/producer/get_unapplied_transactions

producer_rw

  • v1/producer/pause
  • v1/producer/resume
  • v1/producer/update_runtime_options
  • v1/producer/add_greylist_accounts
  • v1/producer/remove_greylist_accounts
  • v1/producer/set_whitelist_blacklist
  • v1/producer/schedule_protocol_feature_activations
  • v1/producer/get_integrity_hash

snapshot

  • v1/producer/get_snapshot_requests
  • v1/producer/create_snapshot
  • v1/producer/schedule_snapshot
  • v1/producer/unschedule_snapshot

trace_api

  • v1/trace_api/get_block
  • v1/trace_api/get_transaction_trace

prometheus

  • v1/prometheus/metrics

node

  • v1/node/get_supported_apis
  • v1/chain/get_info

User configuration knob

A single http-category-address can be used to configure all addresses in command line and ini file. The option can be used multiple times as needed.

http-server-address   = http-category-address
http-category-address = chain_ro,127.0.0.1:8081
http-category-address = chain_ro,:9090
http-category-address = chain_rw,[::1]:8082
http-category-address = net_ro,127.0.0.1:8081
http-category-address = net_rw,[::]:8083 
http-category-address = producer_ro,/tmp/absolute_unix_path.sock
http-category-address = producer_rw,./relative/unix_path.sock
http-category-address = snapshot,./relative/unix_path.sock

A single hostname:port specification can be used by multiple categories, as of the case for 127.0.0.1:8081 in above example. However, two specifications having the same port with different hostname strings are always considered as configuration error regardless whether they can be resolved into the same set of IP addresses. For example, the following configuration are invalid.

http-category-address = chain_ro,127.0.0.1:8081
http-category-address = chain_rw,localhost:8081 # error, 127.0.0.1 and localhost are different

For the node category, it is NOT user configurable because it will be available for all listened http addresses.

For backward compatibility, the HTTP category facility has to be opted in by specifying http-server-address = http-category-address explicitly.
When http-server-address = http-category-address, all the unspecified categories are considered disabled. In addition, http-server-address = http-category-address cannot be specified together with a non-empty unix-socket-path.

All existing configuration options in the http plugin apply to all handlers for all addresses; this includes the http-threads option. This means all handlers share the same thread pool.

server address format

  • server address can be in one of the following formats

    • ipv4_address:port like 127.0.0.1:8080
    • ipv6_address:port like [2001:db8:3c4d:15::1a2f:1a2b]:8080
    • hostname:port like my.domain.com:8080
    • unix socket path (must starts with '/' or './')
  • In the case of the hostname, the IP address is resolved by ARP, ALL resolved addresses will be listened to.

  • To listen to all interfaces for both IPv4 and IPv6, just use :8080. Notice that the behavior of [::]:8080 is dependent on whether the IPv4-mapped IPv6 is enabled in the system.

Resolves #965

@heifner heifner added the OCI Work exclusive to OCI team label May 5, 2023
@heifner heifner added this to the Leap v5.0.0-rc1 milestone May 5, 2023
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/chain_api_plugin/chain_api_plugin.cpp Show resolved Hide resolved
plugins/http_plugin/include/eosio/http_plugin/common.hpp Outdated Show resolved Hide resolved
@@ -241,6 +241,10 @@ add_test(NAME plugin_http_api_test COMMAND tests/plugin_http_api_test.py WORKING
set_tests_properties(plugin_http_api_test PROPERTIES TIMEOUT 50)
set_property(TEST plugin_http_api_test PROPERTY LABELS nonparallelizable_tests)

add_test(NAME plugin_http_category_api_test COMMAND tests/plugin_http_api_test.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_tests_properties(plugin_http_category_api_test PROPERTIES TIMEOUT 50 ENVIRONMENT "PLUGIN_HTTP_TEST_CATEGORY=ON")
set_property(TEST plugin_http_category_api_test PROPERTY LABELS nonparallelizable_tests)
Copy link
Member

Choose a reason for hiding this comment

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

How is different then the existing plugin_http_api_test, no new args are passed to the test.

Copy link
Member

Choose a reason for hiding this comment

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

I see this passes an ENVIRONMENT variable. Can we change that to an argument to the python test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried several ways and failed. This is the only way that I can think of which doesn't require me to rewrite the entire test.

plugins/http_plugin/tests/unit_tests.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/tests/unit_tests.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/tests/unit_tests.cpp Outdated Show resolved Hide resolved
@heifner
Copy link
Member

heifner commented May 11, 2023

Tests failing because keosd not launching:

info  2023-05-10T21:38:51.868 keosd     wallet_plugin.cpp:32          plugin_initialize    ] initializing wallet plugin
warn  2023-05-10T21:38:51.869 keosd     http_plugin.cpp:483           plugin_initialize    ] 13 N5boost10wrapexceptINS_12bad_any_castEEE: boost::bad_any_cast: failed conversion using boost::any_cast
rethrow boost::bad_any_cast: failed conversion using boost::any_cast: 
    {"what":"boost::bad_any_cast: failed conversion using boost::any_cast"}
    keosd  http_plugin.cpp:483 plugin_initialize

appbase: exception thrown during plugin "eosio::wallet_api_plugin" initialization.
boost::bad_any_cast: failed conversion using boost::any_cast

plugins/http_plugin/tests/unit_tests.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
boost::system::error_code ec;
tcp::resolver resolver(plugin_state->thread_pool.get_executor());
auto endpoints = resolver.resolve(host, port, boost::asio::ip::tcp::resolver::passive, ec);
EOS_ASSERT(!ec, chain::plugin_config_exception, "failed to resolve address: ${msg}", ("msg", ec.message()));
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, why are we throwing here if the address is incorrect? Where is the intended try/catch block?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe main() should catch it.

Copy link
Member

Choose a reason for hiding this comment

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

Good point, should likely not throw from here.

Copy link
Member

Choose a reason for hiding this comment

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

This looks like it is only called from is_on_loopback which is only currently called from plugin_initialize. However It seems like it would be better for this to only log a warning and return false. Seems like loopback should always be resolvable so unable to resolve likely means not on loopback.

plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
@greg7mdp
Copy link
Contributor

I'm not understanding where we do the open()/bind()/listen() on the acceptor in this new version?

plugins/http_plugin/http_plugin.cpp Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation OCI Work exclusive to OCI team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nodeos Endpoint IP and Port Configuration
4 participants