Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

unpack data when forming transaction, useful for … #8676

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 29 additions & 23 deletions programs/cleos/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,28 @@ 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()));
}

//resolver for ABI serializer to decode actions in proposed transaction in multisig contract
auto abi_serializer_resolver = [](const name& account) -> fc::optional<abi_serializer> {
static unordered_map<account_name, fc::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;

fc::optional<abi_serializer> abis;
if (raw_abi_blob.size() != 0) {
abis.emplace(fc::raw::unpack<abi_def>(raw_abi_blob), 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;
};

void prompt_for_wallet_password(string& pw, const string& name) {
if(pw.size() == 0 && name != "SecureEnclave") {
std::cout << localized("password: ");
Expand Down Expand Up @@ -399,7 +421,13 @@ fc::variant push_transaction( signed_transaction& trx, const std::vector<public_
}
} else {
if (!tx_return_packed) {
return fc::variant(trx);
try {
fc::variant unpacked_data_trx;
abi_serializer::to_variant(trx, unpacked_data_trx, abi_serializer_resolver, abi_serializer_max_time);
victorj8 marked this conversation as resolved.
Show resolved Hide resolved
return unpacked_data_trx;
} catch (...) {
return fc::variant(trx);
}
} else {
return fc::variant(packed_transaction(trx, compression));
}
Expand Down Expand Up @@ -440,28 +468,6 @@ void print_action( const fc::variant& at ) {
}
}

//resolver for ABI serializer to decode actions in proposed transaction in multisig contract
auto abi_serializer_resolver = [](const name& account) -> fc::optional<abi_serializer> {
static unordered_map<account_name, fc::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;

fc::optional<abi_serializer> abis;
if (raw_abi_blob.size() != 0) {
abis.emplace(fc::raw::unpack<abi_def>(raw_abi_blob), 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;
};

bytes variant_to_bin( const account_name& account, const action_name& action, const fc::variant& action_args_var ) {
auto abis = abi_serializer_resolver( account );
FC_ASSERT( abis.valid(), "No ABI found for ${contract}", ("contract", account));
Expand Down
30 changes: 30 additions & 0 deletions tests/nodeos_run_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,36 @@
if actual != expected:
errorExit("FAILURE - Wrong currency1111 balance (expected=%s, actual=%s)" % (str(expected), str(actual)), raw=True)

Print("push transfer action to currency1111 contract with sign skipping option enabled")
data="{\"from\":\"currency1111\",\"to\":\"defproducera\",\"quantity\":"
data +="\"00.0001 CUR\",\"memo\":\"test\"}"
opts="-s -d --permission currency1111@active"
trans=node.pushMessage(contract, action, data, opts)

try:
assert(not trans[1]["signatures"])
except (AssertionError, KeyError) as _:
Print("ERROR: Expected signatures array to be empty due to skipping option enabled.")
raise

try:
assert(trans[1]["actions"][0]["data"]["from"] == "currency1111")
assert(trans[1]["actions"][0]["data"]["to"] == "defproducera")
assert(trans[1]["actions"][0]["data"]["quantity"] == "0.0001 CUR")
assert(trans[1]["actions"][0]["data"]["memo"] == "test")
except (AssertionError, KeyError) as _:
victorj8 marked this conversation as resolved.
Show resolved Hide resolved
Print("ERROR: Expecting unpacked data fields on push transfer action json result.")
raise

result=node.pushTransaction(trans[1], None)

amountStr=node.getTableAccountBalance("currency1111", currencyAccount.name)

expected="99999.9999 CUR"
actual=amountStr
if actual != expected:
errorExit("FAILURE - Wrong currency1111 balance (expectedgma=%s, actual=%s)" % (str(expected), str(actual)), raw=True)

Print("Locking wallet \"%s\"." % (defproduceraWallet.name))
if not walletMgr.lockWallet(defproduceraWallet):
cmdError("%s wallet lock" % (ClientName))
Expand Down