Skip to content

Commit

Permalink
Merge pull request #704 from eosnetworkfoundation/backport-cleos-loca…
Browse files Browse the repository at this point in the history
…l-abi-file

Backport cleos local abi file
  • Loading branch information
jgiszczak authored Aug 8, 2022
2 parents f19322d + 5e660e6 commit fda9c85
Show file tree
Hide file tree
Showing 4 changed files with 381 additions and 38 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/ubuntu-2004.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ jobs:
name: Ubuntu 20.04 | Build
runs-on: ubuntu-latest
steps:
- name: Check for ccache disable
id: no-ccache
uses: saulmaldonado/skip-workflow@b934401f1ef10783ab5e7f25a78a31959a4fbad3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
search: '["pull_request"]'
pr-message: 'body'
phrase: '[no-ccache]'
- name: Timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}
Expand All @@ -27,13 +35,15 @@ jobs:
submodules: recursive
fetch-depth: 0
- name: Preserve ccache
if: ${{ !steps.no-ccache.outputs.skip }}
uses: actions/cache@v1.1.0
with:
path: .ccache
key: $ubuntu-20.04-ccache_make-${{ steps.ccache_cache_timestamp.outputs.timestamp }}
restore-keys: |
$ubuntu-20.04-ccache_make-
- name: Build
if: ${{ !steps.no-ccache.outputs.skip }}
run: |
set -e
export CCACHE_DIR=${GITHUB_WORKSPACE}/.ccache
Expand Down Expand Up @@ -63,6 +73,30 @@ jobs:
echo =====
tar -pczf build.tar.gz build
tar -pczf usr_local.tar.gz installed
- name: Build without ccache
if: ${{ steps.no-ccache.outputs.skip }}
run: |
set -e
export CCACHE_DISABLE=1
export DOCKER="docker run --rm -v ${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE} -w ${GITHUB_WORKSPACE} -e CCACHE_DISABLE --user $(id -u):$(id -g) ${UBUNTU_2004_IMAGE}"
export DOCKER_ROOT="docker run --rm -v ${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE} -e CCACHE_DISABLE -w ${GITHUB_WORKSPACE} ${UBUNTU_2004_IMAGE}"
docker pull ${UBUNTU_2004_IMAGE}
echo =====
mkdir build
${DOCKER} bash -c "cd build && cmake -DCMAKE_BUILD_TYPE=Release -UCMAKE_CXX_COMPILER_LAUNCHER -UCMAKE_C_COMPILER_LAUNCHER .."
echo =====
${DOCKER} bash -c "cd build && make -j $(nproc)"
echo =====
mkdir install
${DOCKER_ROOT} bash -c "cd build && DESTDIR=${GITHUB_WORKSPACE}/installed make -j $(nproc) dev-install"
echo =====
ls -la ${GITHUB_WORKSPACE}
echo =====
${DOCKER} build/bin/nodeos --version
${DOCKER} build/bin/nodeos --full-version
echo =====
tar -pczf build.tar.gz build
tar -pczf usr_local.tar.gz installed
- name: Upload build
uses: actions/upload-artifact@v1
with:
Expand Down
87 changes: 51 additions & 36 deletions programs/cleos/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,22 +96,12 @@ Usage: ./cleos create account [OPTIONS] creator name OwnerKey ActiveKey
#include <boost/filesystem.hpp>
#include <boost/process.hpp>
#include <boost/process/spawn.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <boost/range/algorithm/sort.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/algorithm/string/classification.hpp>

#pragma pop_macro("N")

#include <Inline/BasicTypes.h>
#include <IR/Module.h>
#include <IR/Validate.h>
#include <WASM/WASM.h>
#include <Runtime/Runtime.h>

#include <fc/io/fstream.hpp>

#define CLI11_HAS_FILESYSTEM 0
Expand Down Expand Up @@ -164,9 +154,10 @@ std::string clean_output( std::string str ) {
return fc::escape_string( str, nullptr, escape_control_chars );
}

string url = "http://127.0.0.1:8888/";
string default_url = "http://127.0.0.1:8888/";
string default_wallet_url = "unix://" + (determine_home_directory() / "eosio-wallet" / (string(key_store_executable_name) + ".sock")).string();
string wallet_url; //to be set to default_wallet_url in main
std::map<name, std::string> abi_files_override;
bool no_verify = false;
vector<string> headers;

Expand Down Expand Up @@ -282,7 +273,8 @@ class signing_keys_option {
try {
std::vector<public_key_type> keys = json_keys.template as<std::vector<public_key_type>>();
signing_keys = std::move(keys);
} EOS_RETHROW_EXCEPTIONS(public_key_type_exception, "Invalid public key array format '${data}'", ("data", fc::json::to_string(json_keys, fc::time_point::maximum())))
} EOS_RETHROW_EXCEPTIONS(public_key_type_exception, "Invalid public key array format '${data}'",
("data", fc::json::to_string(json_keys, fc::time_point::maximum())))
}
}
return signing_keys;
Expand Down Expand Up @@ -328,7 +320,7 @@ fc::variant call( const std::string& url,
}
catch(boost::system::system_error& e) {
std::string exec_name;
if(url == ::url) {
if(url == ::default_url) {
exec_name = node_executable_name;
} else if(url == ::wallet_url) {
exec_name = key_store_executable_name;
Expand All @@ -342,18 +334,18 @@ fc::variant call( const std::string& url,

template<typename T>
fc::variant call( const std::string& path,
const T& v ) { return call( url, path, fc::variant(v) ); }
const T& v ) { return call( ::default_url, path, fc::variant( v) ); }

template<>
fc::variant call( const std::string& url,
const std::string& path) { return call( url, path, fc::variant() ); }

eosio::chain_apis::read_only::get_consensus_parameters_results get_consensus_parameters() {
return call(url, get_consensus_parameters_func).as<eosio::chain_apis::read_only::get_consensus_parameters_results>();
return call(::default_url, get_consensus_parameters_func).as<eosio::chain_apis::read_only::get_consensus_parameters_results>();
}

eosio::chain_apis::read_only::get_info_results get_info() {
return call(url, get_info_func).as<eosio::chain_apis::read_only::get_info_results>();
return call(::default_url, get_info_func).as<eosio::chain_apis::read_only::get_info_results>();
}

string generate_nonce_string() {
Expand All @@ -364,32 +356,34 @@ chain::action generate_nonce_action() {
return chain::action( {}, config::null_account_name, name("nonce"), fc::raw::pack(fc::time_point::now().time_since_epoch().count()));
}

auto abi_serializer_resolver_empty = [](const name& account) -> std::optional<abi_serializer> {
return std::optional<abi_serializer>();
};

//resolver for ABI serializer to decode actions in proposed transaction in multisig contract
auto abi_serializer_resolver = [](const name& account) -> std::optional<abi_serializer> {
static unordered_map<account_name, std::optional<abi_serializer> > abi_cache;
auto it = abi_cache.find( account );
if ( it == abi_cache.end() ) {
const auto raw_abi_result = call(get_raw_abi_func, fc::mutable_variant_object("account_name", account));
const auto raw_abi_blob = raw_abi_result["abi"].as_blob().data;

std::optional<abi_serializer> abis;
if (raw_abi_blob.size() != 0) {
abis.emplace(fc::raw::unpack<abi_def>(raw_abi_blob), abi_serializer_max_time);
if (abi_files_override.find(account) != abi_files_override.end()) {
abis.emplace( fc::json::from_file(abi_files_override[account]).as<abi_def>(), abi_serializer::create_yield_function( abi_serializer_max_time ));
} else {
std::cerr << "ABI for contract " << account.to_string() << " not found. Action data will be shown in hex only." << std::endl;
const auto raw_abi_result = call(get_raw_abi_func, fc::mutable_variant_object("account_name", account));
const auto raw_abi_blob = raw_abi_result["abi"].as_blob().data;
if (raw_abi_blob.size() != 0) {
abis.emplace(fc::raw::unpack<abi_def>(raw_abi_blob), abi_serializer::create_yield_function( abi_serializer_max_time ));
} else {
std::cerr << "ABI for contract " << account.to_string() << " not found. Action data will be shown in hex only." << std::endl;
}
}
abi_cache.emplace( account, abis );

return abis;
}

return it->second;
};

auto abi_serializer_resolver_empty = [](const name& account) -> std::optional<abi_serializer> {
return std::optional<abi_serializer>();
};

void prompt_for_wallet_password(string& pw, const string& name) {
if(pw.size() == 0 && name != "SecureEnclave") {
std::cout << localized("password: ");
Expand Down Expand Up @@ -1018,7 +1012,7 @@ struct set_action_permission_subcommand {
string requirementStr;

set_action_permission_subcommand(CLI::App* actionRoot) {
auto permissions = actionRoot->add_subcommand("permission", localized("set parmaters dealing with account permissions"));
auto permissions = actionRoot->add_subcommand("permission", localized("Set paramaters dealing with account permissions"));
permissions->add_option("account", accountStr, localized("The account to set/delete a permission authority for"))->required();
permissions->add_option("code", codeStr, localized("The account that owns the code for the action"))->required();
permissions->add_option("type", typeStr, localized("The type of the action"))->required();
Expand Down Expand Up @@ -1220,7 +1214,7 @@ struct create_account_subcommand {

if( active_key_str.empty() ) {
active = owner;
} else if ( active_key_str.find('{') != string::npos ) {
} else if ( active_key_str.find('{') != string::npos ) {
try{
active = parse_json_authority_or_key(active_key_str);
} EOS_RETHROW_EXCEPTIONS( explained_exception, "Invalid active authority: ${authority}", ("authority", owner_key_str) )
Expand Down Expand Up @@ -2704,7 +2698,26 @@ CLI::callback_t header_opt_callback = [](CLI::results_t res) {
return true;
};

CLI::callback_t abi_files_overide_callback = [](CLI::results_t account_abis) {
for (vector<string>::iterator itr = account_abis.begin(); itr != account_abis.end(); ++itr) {
size_t delim = itr->find(":");
std::string acct_name, abi_path;
if (delim != std::string::npos) {
acct_name = itr->substr(0, delim);
abi_path = itr->substr(delim + 1);
}
if (acct_name.length() == 0 || abi_path.length() == 0) {
std::cerr << "please specify --abi-file in form of <contract name>:<abi file path>.\n";
return false;
}
abi_files_override[name(acct_name)] = abi_path;
}
return true;
};


int main( int argc, char** argv ) {

fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug);
context = eosio::client::http::create_http_context();
wallet_url = default_wallet_url;
Expand All @@ -2717,9 +2730,10 @@ int main( int argc, char** argv ) {
app.add_option( "--wallet-host", obsoleted_option_host_port, localized("The host where ${k} is running", ("k", key_store_executable_name)) )->group("");
app.add_option( "--wallet-port", obsoleted_option_host_port, localized("The port where ${k} is running", ("k", key_store_executable_name)) )->group("");

app.add_option( "-u,--url", url, localized("The http/https URL where ${n} is running", ("n", node_executable_name)), true );
app.add_option( "-u,--url", ::default_url, localized( "The http/https URL where ${n} is running", ("n", node_executable_name)), true );
app.add_option( "--wallet-url", wallet_url, localized("The http/https URL where ${k} is running", ("k", key_store_executable_name)), true );

app.add_option( "--abi-file", abi_files_overide_callback, localized("In form of <contract name>:<abi file path>, use a local abi file for serialization and deserialization instead of getting the abi data from the blockchain; repeat this option to pass multiple abi files for different contracts"))->type_size(0, 1000);
app.add_option( "-r,--header", header_opt_callback, localized("Pass specific HTTP header; repeat this option to pass multiple headers"));
app.add_flag( "-n,--no-verify", no_verify, localized("Don't verify peer certificate when using HTTPS"));
app.add_flag( "--no-auto-" + string(key_store_executable_name), no_auto_keosd, localized("Don't automatically launch a ${k} if one is not currently running", ("k", key_store_executable_name)));
Expand Down Expand Up @@ -2858,7 +2872,7 @@ int main( int argc, char** argv ) {
});

// validate subcommand
auto validate = app.add_subcommand("validate", localized("Validate transactions"));
auto validate = app.add_subcommand("validate", localized("Validate transactions"));
validate->require_subcommand();

// validate signatures
Expand Down Expand Up @@ -3496,6 +3510,7 @@ int main( int argc, char** argv ) {
string amount;
string memo;
bool pay_ram = false;

auto transfer = app.add_subcommand("transfer", localized("Transfer tokens from account to account"));
transfer->add_option("sender", sender, localized("The account sending tokens"))->required();
transfer->add_option("recipient", recipient, localized("The account receiving tokens"))->required();
Expand Down Expand Up @@ -3529,27 +3544,27 @@ int main( int argc, char** argv ) {
auto connect = net->add_subcommand("connect", localized("Start a new connection to a peer"));
connect->add_option("host", new_host, localized("The hostname:port to connect to."))->required();
connect->callback([&] {
const auto& v = call(url, net_connect, new_host);
const auto& v = call(::default_url, net_connect, new_host);
std::cout << fc::json::to_pretty_string(v) << std::endl;
});

auto disconnect = net->add_subcommand("disconnect", localized("Close an existing connection"));
disconnect->add_option("host", new_host, localized("The hostname:port to disconnect from."))->required();
disconnect->callback([&] {
const auto& v = call(url, net_disconnect, new_host);
const auto& v = call(::default_url, net_disconnect, new_host);
std::cout << fc::json::to_pretty_string(v) << std::endl;
});

auto status = net->add_subcommand("status", localized("Status of existing connection"));
status->add_option("host", new_host, localized("The hostname:port to query status of connection"))->required();
status->callback([&] {
const auto& v = call(url, net_status, new_host);
const auto& v = call(::default_url, net_status, new_host);
std::cout << fc::json::to_pretty_string(v) << std::endl;
});

auto connections = net->add_subcommand("peers", localized("Status of all existing peers"));
connections->callback([&] {
const auto& v = call(url, net_connections);
const auto& v = call(::default_url, net_connections);
std::cout << fc::json::to_pretty_string(v) << std::endl;
});

Expand Down Expand Up @@ -4245,7 +4260,7 @@ int main( int argc, char** argv ) {
auto cancel = msig->add_subcommand("cancel", localized("Cancel proposed transaction"));
add_standard_transaction_options_plus_signing(cancel, "canceler@active");
cancel->add_option("proposer", proposer, localized("The proposer name (string)"))->required();
cancel->add_option("proposal_name", proposal_name, localized("proposal name (string)"))->required();
cancel->add_option("proposal_name", proposal_name, localized("The proposal name (string)"))->required();
cancel->add_option("canceler", canceler, localized("The canceler name (string)"));
cancel->callback([&]() {
auto accountPermissions = get_account_permissions(tx_permission);
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ set_property(TEST nodeos_retry_transaction_lr_test PROPERTY LABELS long_running_


add_test(NAME cli_test COMMAND tests/cli_test.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST cli_test PROPERTY LABELS nonparallelizable_tests)

add_test(NAME larger_lib_test COMMAND tests/large-lib-test.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST larger_lib_test PROPERTY LABELS nonparallelizable_tests)
Expand Down
Loading

0 comments on commit fda9c85

Please sign in to comment.