From 57334856fcee182e550a0c773d5f8c4c2fe77a3f Mon Sep 17 00:00:00 2001 From: Kayan Date: Tue, 2 Oct 2018 10:54:17 +0800 Subject: [PATCH] improve duplicate code/abi check --- programs/cleos/httpc.hpp | 2 ++ programs/cleos/main.cpp | 37 ++++++++++++++++++++----------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/programs/cleos/httpc.hpp b/programs/cleos/httpc.hpp index 532f9b7623d..54e60866fbc 100644 --- a/programs/cleos/httpc.hpp +++ b/programs/cleos/httpc.hpp @@ -91,7 +91,9 @@ namespace eosio { namespace client { namespace http { const string get_table_func = chain_func_base + "/get_table_rows"; const string get_table_by_scope_func = chain_func_base + "/get_table_by_scope"; const string get_code_func = chain_func_base + "/get_code"; + const string get_code_hash_func = chain_func_base + "/get_code_hash"; const string get_abi_func = chain_func_base + "/get_abi"; + const string get_raw_abi_func = chain_func_base + "/get_raw_abi"; const string get_raw_code_and_abi_func = chain_func_base + "/get_raw_code_and_abi"; const string get_currency_balance_func = chain_func_base + "/get_currency_balance"; const string get_currency_stats_func = chain_func_base + "/get_currency_stats"; diff --git a/programs/cleos/main.cpp b/programs/cleos/main.cpp index 21ba6de2d5c..50b291879ef 100644 --- a/programs/cleos/main.cpp +++ b/programs/cleos/main.cpp @@ -2333,12 +2333,14 @@ int main( int argc, char** argv ) { std::vector old_wasm; bool duplicate = false; + fc::sha256 old_hash, new_hash; if (!suppress_duplicate_check) { try { - const auto result = call(get_raw_code_and_abi_func, fc::mutable_variant_object("account_name", account)); - old_wasm = result["wasm"].as_blob().data; + const auto result = call(get_code_hash_func, fc::mutable_variant_object("account_name", account)); + old_hash = fc::sha256(result["code_hash"].as_string()); } catch (...) { - std::cout << "Failed to get old contract, continue without duplicate check..." << std::endl; + std::cerr << "Failed to get existing code hash, continue without duplicate check..." << std::endl; + suppress_duplicate_check = true; } } @@ -2362,14 +2364,17 @@ int main( int argc, char** argv ) { if(wasm.compare(0, 8, binary_wasm_header)) std::cerr << localized("WARNING: ") << wasmPath << localized(" doesn't look like a binary WASM file. Is it something else, like WAST? Trying anyways...") << std::endl; code_bytes = bytes(wasm.begin(), wasm.end()); - - if (code_bytes.size() > 0 && code_bytes.size() == old_wasm.size()) { - duplicate = (memcmp(&(code_bytes[0]), &(old_wasm[0]), code_bytes.size()) == 0); - } } else { code_bytes = bytes(); } + if (!suppress_duplicate_check) { + if (code_bytes.size()) { + new_hash = fc::sha256::hash(&(code_bytes[0]), code_bytes.size()); + } + duplicate = (old_hash == new_hash); + } + if (!duplicate) { actions.emplace_back( create_setcode(account, code_bytes ) ); if ( shouldSend ) { @@ -2387,14 +2392,11 @@ int main( int argc, char** argv ) { bool duplicate = false; if (!suppress_duplicate_check) { try { - const auto result = call(get_raw_code_and_abi_func, fc::mutable_variant_object("account_name", account)); - const std::vector abi_v = result["abi"].as_blob().data; - abi_def abi_d; - if (abi_serializer::to_abi(abi_v, abi_d)) { - old_abi = fc::raw::pack(abi_d); - } + const auto result = call(get_raw_abi_func, fc::mutable_variant_object("account_name", account)); + old_abi = result["abi"].as_blob().data; } catch (...) { - std::cout << "Failed to get old contract, continue without duplicate check..." << std::endl; + std::cerr << "Failed to get existing raw abi, continue without duplicate check..." << std::endl; + suppress_duplicate_check = true; } } @@ -2412,13 +2414,14 @@ int main( int argc, char** argv ) { EOS_ASSERT( fc::exists( abiPath ), abi_file_not_found, "no abi file found ${f}", ("f", abiPath) ); abi_bytes = fc::raw::pack(fc::json::from_file(abiPath).as()); - if (abi_bytes.size() > 0 && abi_bytes.size() == old_abi.size()) { - duplicate = (memcmp(&(abi_bytes[0]), &(old_abi[0]), abi_bytes.size()) == 0); - } } else { abi_bytes = bytes(); } + if (!suppress_duplicate_check) { + duplicate = (old_abi.size() == abi_bytes.size() && std::equal(old_abi.begin(), old_abi.end(), abi_bytes.begin())); + } + if (!duplicate) { try { actions.emplace_back( create_setabi(account, abi_bytes) );