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

[3.2] return the error from the contract itself in the transaction trace log message for asserts #733

Merged
merged 7 commits into from
Aug 16, 2022

Conversation

linh2931
Copy link
Member

@linh2931 linh2931 commented Jul 27, 2022

Resolves #760.

Returns contract name, action name, and detailed assert message from the contract in the transaction trace log. The assert message size is limited to 1024 bytes to prevent from logging arbitrarily long messages from untrusted contract writers.

The logging from a test contract raising an assert looks like

debug 2022-08-05T13:41:41.262 nodeos    producer_plugin.cpp:577       operator()           ] [TRX_TRACE] Block 9989 for producer eosio is REJECTING tx: 45fffd73291befb3dfdc261c2b61061f6b6fe142ef34601c554bf2706cf784ee, auth: eosio : assertion failure with message: This is a test, contract name: hello, action name: hi

@linh2931 linh2931 requested review from heifner and spoonincode July 27, 2022 17:27
plugins/producer_plugin/producer_plugin.cpp Outdated Show resolved Hide resolved
plugins/producer_plugin/producer_plugin.cpp Outdated Show resolved Hide resolved
…n for the functionalities; used FC format_string and top_message
if (_pending_block_mode == pending_block_mode::producing) {
fc_dlog(_trx_failed_trace_log, "[TRX_TRACE] Block ${block_num} for producer ${prod} is REJECTING tx: ${txid}, auth: ${a} : ${why} ",
fc_dlog(_trx_failed_trace_log, "[TRX_TRACE] Block ${block_num} for producer ${prod} is REJECTING tx: ${txid}, auth: ${a} : ${why}, contract name: ${contract}, action name: ${act}",
Copy link
Member

Choose a reason for hiding this comment

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

I think contract: and action: should be after auth and before the exception details.
Also drop "name" from "contract name" and "action name" to make the log a bit shorter, or maybe go with the suggested action::{receiver}:{action_name} eosio.token:transfer .

Copy link
Member Author

Choose a reason for hiding this comment

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

Will change. Was hesitate to add contract and action before the existing "why".

Copy link
Member

Choose a reason for hiding this comment

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

I think @matthewdarwin might be one of the few (or only one) parsing these log messages. He will have to update his parsing either way.

Choose a reason for hiding this comment

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

Better if ${why} is at the end as Kevin says.

@@ -547,24 +571,30 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
}

if (except_ptr) {
auto [contract_name, act_name, details] = get_detailed_contract_exception_info(except_ptr, response);
Copy link
Member

Choose a reason for hiding this comment

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

This should only be called when logging. The log messages are debug level, so this should only be called during debug level logging. That can be done, I think, by having it return a fc::mutable_variant_object() and calling it inline with the log statement.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the comment to avoid unnecessary call. With returning fc::mutable_variant_object within the log statement, does the following output look good?
debug 2022-08-10T14:38:29.504 nodeos producer_plugin.cpp:581 operator() ] [TRX_TRACE] Block 10058 for producer eosio is REJECTING tx: 1b43cf20688149c8b1d42f1603ab20c0bd35206b37923eacc43b8791376741f8, auth: eosio, {"contract":"hello","action":"hi","details":"assertion failure with message: This is a test"}

Copy link
Member Author

Choose a reason for hiding this comment

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

Will change details above to message.

Copy link
Member

Choose a reason for hiding this comment

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

I personally do not like that example output. The embedded JSON seems rather verbose to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

I just made get_detailed_contract_exception_info to return a string. An example log would look like

debug 2022-08-10T21:56:12.249 nodeos producer_plugin.cpp:575 operator() ] [TRX_TRACE] Block 10294 for producer eosio is REJECTING tx: d56f2f044ef34155958919983d2532df30c7e9c3a7fa8cce0f465992b7a8a6f2, auth: eosio, action::hello:hi:assertion failure with message: This is a test

Choose a reason for hiding this comment

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

Should there be space after "action: "? Why is there double "::"?
The 'with' is not adding value?
Is there always a message, or message is optional?

What if the action is "assertion failure with message:" (just making stupid example). Is that even valid? Then the log would be:

assertion failure with message: with message: This is a test

This would get parsed wrong probably.

We have two strings of arbitrary length making it difficult to deal with.

debug 2022-08-10T21:56:12.249 nodeos producer_plugin.cpp:575 operator() ] [TRX_TRACE] Block 10294 for producer eosio is REJECTING tx: d56f2f044ef34155958919983d2532df30c7e9c3a7fa8cce0f465992b7a8a6f2, auth: eosio, action::hello:hi:assertion failure // This is a test

Would be easier to parse, assuming '//' is not valid 'action'.

Choose a reason for hiding this comment

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

(Replace // with any other unique separator)

Copy link
Member Author

Choose a reason for hiding this comment

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

"assertion failure with message:" is added by host function eosio_assert or eosio_assert_message, which is better to be left alone. How about action: hello:hi, assertion failure with message: This is a test?

Choose a reason for hiding this comment

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

What are the valid characters for "action"? Is comma never used? If yes, then this is fine because I can depend on it to parse the message (before comma and after comma).

I don't know the nodeos internals, I am maybe not making reasonable suggestions.

Copy link
Member Author

Choose a reason for hiding this comment

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

action's type is eosio::name, which can only be 'a' to 'z' and '1' to '5'. We are good here. Will push a change after I am done with some other work.

plugins/producer_plugin/producer_plugin.cpp Outdated Show resolved Hide resolved
plugins/producer_plugin/producer_plugin.cpp Outdated Show resolved Hide resolved
}

if (except_ptr) {
details = fc::format_string("${d}", fc::mutable_variant_object() ("d", except_ptr->top_message()), true); // true for limitting the formatted string size
Copy link
Member

Choose a reason for hiding this comment

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

This seems like it is an inefficient way to call variant.cpp clean_append. Unfortunately, clean_append is only in variant.cpp. I think we should create a general purpose clean method that optionally escapes control characters (specifically newline) and truncates. That could then be used here.
As is this leaves any newlines put in by the contract writer in the output.

Copy link
Member Author

@linh2931 linh2931 Aug 10, 2022

Choose a reason for hiding this comment

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

Can we do this later after the decision about FC de-submodule is made? I have created #803

plugins/producer_plugin/producer_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
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enhancement: return the error from the contract itself in the transaction trace log message for asserts
3 participants