From 8e8b2116b2cf8fbfb84646ee2acbf6f966604dd0 Mon Sep 17 00:00:00 2001 From: Steven Watanabe Date: Tue, 23 Feb 2021 14:06:08 -0500 Subject: [PATCH] Add get_raw_abi to rodeos --- .../rodeos/include/b1/rodeos/wasm_ql.hpp | 2 + libraries/rodeos/wasm_ql.cpp | 65 +++++++++++++++++++ programs/rodeos/wasm_ql_http.cpp | 9 +++ 3 files changed, 76 insertions(+) diff --git a/libraries/rodeos/include/b1/rodeos/wasm_ql.hpp b/libraries/rodeos/include/b1/rodeos/wasm_ql.hpp index efda0464752..8e90f35af5b 100644 --- a/libraries/rodeos/include/b1/rodeos/wasm_ql.hpp +++ b/libraries/rodeos/include/b1/rodeos/wasm_ql.hpp @@ -109,6 +109,8 @@ const std::vector& query_get_block(wasm_ql::thread_state& thread_state, const std::vector& contract_kv_prefix, std::string_view body); const std::vector& query_get_abi(wasm_ql::thread_state& thread_state, const std::vector& contract_kv_prefix, std::string_view body); +const std::vector& query_get_raw_abi(wasm_ql::thread_state& thread_state, const std::vector& contract_kv_prefix, + std::string_view body); const std::vector& query_get_required_keys(wasm_ql::thread_state& thread_state, std::string_view body); const std::vector& query_send_transaction(wasm_ql::thread_state& thread_state, const std::vector& contract_kv_prefix, std::string_view body, diff --git a/libraries/rodeos/wasm_ql.cpp b/libraries/rodeos/wasm_ql.cpp index e0ef5a9ecf5..f2f3490f7b3 100644 --- a/libraries/rodeos/wasm_ql.cpp +++ b/libraries/rodeos/wasm_ql.cpp @@ -449,6 +449,71 @@ const std::vector& query_get_abi(wasm_ql::thread_state& thread_state, cons return thread_state.action_return_value; } // query_get_abi +struct get_raw_abi_params { + eosio::name account_name = {}; + std::optional abi_hash; +}; + +EOSIO_REFLECT(get_raw_abi_params, account_name, abi_hash) + +struct get_raw_abi_result { + eosio::name account_name; + eosio::checksum256 code_hash; + eosio::checksum256 abi_hash; + std::optional abi; +}; + +EOSIO_REFLECT(get_raw_abi_result, account_name, code_hash, abi_hash, abi) + +const std::vector& query_get_raw_abi(wasm_ql::thread_state& thread_state, const std::vector& contract_kv_prefix, + std::string_view body) { + get_raw_abi_params params; + std::string s{ body.begin(), body.end() }; + eosio::json_token_stream stream{ s.data() }; + try { + from_json(params, stream); + } catch (std::exception& e) { + throw std::runtime_error("An error occurred deserializing get_abi_params: "s + e.what()); + } + + rocksdb::ManagedSnapshot snapshot{ thread_state.shared->db->rdb.get() }; + chain_kv::write_session write_session{ *thread_state.shared->db, snapshot.snapshot() }; + db_view_state db_view_state{ state_account, *thread_state.shared->db, write_session, contract_kv_prefix }; + + get_raw_abi_result result = {}; + + auto meta = get_state_row( + db_view_state.kv_state.view, + std::make_tuple(eosio::name{ "account.meta" }, eosio::name{ "primary" }, params.account_name)); + if (meta) { + auto& meta0 = std::get(meta->second); + if (!meta0.code->vm_type && !meta0.code->vm_version) + result.code_hash = meta0.code->code_hash; + } + + auto acc = get_state_row( + db_view_state.kv_state.view, + std::make_tuple(eosio::name{ "account" }, eosio::name{ "primary" }, params.account_name)); + if (!acc) + throw std::runtime_error("account " + (std::string)params.account_name + " not found"); + auto& acc0 = std::get(acc->second); + + result.account_name = acc0.name; + if (acc0.abi.pos != acc0.abi.end) { + auto fc_abi_hash = fc::sha256::hash(acc0.abi.pos, acc0.abi.remaining()); + auto abi_hash_stream = eosio::input_stream(fc_abi_hash.data(), fc_abi_hash.data_size()); + eosio::from_bin(result.abi_hash, abi_hash_stream); + if(!params.abi_hash || *params.abi_hash != result.abi_hash) { + result.abi = fc::base64_encode(reinterpret_cast(acc0.abi.pos), acc0.abi.remaining()); + } + } + + // todo: avoid the extra copy + auto json = eosio::convert_to_json(result); + thread_state.action_return_value.assign(json.begin(), json.end()); + return thread_state.action_return_value; +} // query_get_raw_abi + // Ignores data field struct action_no_data { eosio::name account = {}; diff --git a/programs/rodeos/wasm_ql_http.cpp b/programs/rodeos/wasm_ql_http.cpp index 90dbd94fe9b..9d3598f0646 100644 --- a/programs/rodeos/wasm_ql_http.cpp +++ b/programs/rodeos/wasm_ql_http.cpp @@ -233,6 +233,15 @@ void handle_request(const wasm_ql::http_config& http_config, const wasm_ql::shar std::string_view{ req.body().data(), req.body().size() }), "application/json")); return; + } else if (req.target() == "/v1/chain/get_raw_abi") { + if (req.method() != http::verb::post) + return send( + error(http::status::bad_request, "Unsupported HTTP-method for " + req.target().to_string() + "\n")); + auto thread_state = state_cache.get_state(); + send(ok(query_get_raw_abi(*thread_state, temp_contract_kv_prefix, + std::string_view{ req.body().data(), req.body().size() }), + "application/json")); + return; } else if (req.target() == "/v1/chain/get_required_keys") { // todo: replace with a binary endpoint? if (req.method() != http::verb::post) return send(