Skip to content

Commit

Permalink
allow zero length messages, test for inline failure propagation and e…
Browse files Browse the repository at this point in the history
…mpty transaction failure

ref EOSIO#175
  • Loading branch information
wanderingbort committed Sep 7, 2017
1 parent 8dd711d commit befe187
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 19 deletions.
3 changes: 3 additions & 0 deletions contracts/test_api/test_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,13 @@ extern "C" {

//test transaction
WASM_TEST_HANDLER(test_transaction, send_message);
WASM_TEST_HANDLER(test_transaction, send_message_empty);
WASM_TEST_HANDLER(test_transaction, send_message_max);
WASM_TEST_HANDLER(test_transaction, send_message_large);
WASM_TEST_HANDLER(test_transaction, send_message_recurse);
WASM_TEST_HANDLER(test_transaction, send_message_inline_fail);
WASM_TEST_HANDLER(test_transaction, send_transaction);
WASM_TEST_HANDLER(test_transaction, send_transaction_empty);
WASM_TEST_HANDLER(test_transaction, send_transaction_max);
WASM_TEST_HANDLER(test_transaction, send_transaction_large);

Expand Down
3 changes: 3 additions & 0 deletions contracts/test_api/test_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,13 @@ struct test_crypto {
struct test_transaction {

static unsigned int send_message();
static unsigned int send_message_empty();
static unsigned int send_message_max();
static unsigned int send_message_large();
static unsigned int send_message_recurse();
static unsigned int send_message_inline_fail();
static unsigned int send_transaction();
static unsigned int send_transaction_empty();
static unsigned int send_transaction_max();
static unsigned int send_transaction_large();
};
40 changes: 31 additions & 9 deletions contracts/test_api/test_transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,9 @@ unsigned int test_transaction::send_message() {
return WASM_TEST_PASS;
}

unsigned int test_transaction::send_transaction() {
dummy_message payload = {DUMMY_MESSAGE_DEFAULT_A, DUMMY_MESSAGE_DEFAULT_B, DUMMY_MESSAGE_DEFAULT_C};
auto msg = messageCreate(N(testapi), WASM_TEST_ACTION("test_message", "read_message"), &payload, sizeof(dummy_message));


auto trx = transactionCreate();
transactionRequireScope(trx, N(testapi));
transactionAddMessage(trx, msg);
transactionSend(trx);
unsigned int test_transaction::send_message_empty() {
auto msg = messageCreate(N(testapi), WASM_TEST_ACTION("test_message", "assert_true"), nullptr, 0);
messageSend(msg);
return WASM_TEST_PASS;
}

Expand Down Expand Up @@ -54,6 +48,34 @@ unsigned int test_transaction::send_message_recurse() {
return WASM_TEST_PASS;
}

/**
* cause failure due to inline TX failure
*/
unsigned int test_transaction::send_message_inline_fail() {
auto msg = messageCreate(N(testapi), WASM_TEST_ACTION("test_message", "assert_false"), nullptr, 0);
messageSend(msg);
return WASM_TEST_PASS;
}

unsigned int test_transaction::send_transaction() {
dummy_message payload = {DUMMY_MESSAGE_DEFAULT_A, DUMMY_MESSAGE_DEFAULT_B, DUMMY_MESSAGE_DEFAULT_C};
auto msg = messageCreate(N(testapi), WASM_TEST_ACTION("test_message", "read_message"), &payload, sizeof(dummy_message));


auto trx = transactionCreate();
transactionRequireScope(trx, N(testapi));
transactionAddMessage(trx, msg);
transactionSend(trx);
return WASM_TEST_PASS;
}

unsigned int test_transaction::send_transaction_empty() {
auto trx = transactionCreate();
transactionRequireScope(trx, N(testapi));
transactionSend(trx);
return WASM_TEST_FAIL;
}

/**
* cause failure due to too many pending deferred transactions
*/
Expand Down
22 changes: 12 additions & 10 deletions libraries/chain/wasm_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,18 +290,20 @@ DEFINE_INTRINSIC_FUNCTION4(env,messageCreate,messageCreate,i32,i64,code,i64,type
auto& wasm = wasm_interface::get();
auto mem = wasm.current_memory;

EOS_ASSERT( length > 0, tx_unknown_argument,
"Attempting to push an empty message" );
EOS_ASSERT( length >= 0, tx_unknown_argument,
"Pushing a message with a negative length" );

Bytes payload;
try {
// memoryArrayPtr checks that the entire array of bytes is valid and
// within the bounds of the memory segment so that transactions cannot pass
// bad values in attempts to read improper memory
const char* buffer = memoryArrayPtr<const char>( mem, uint32_t(data), uint32_t(length) );
payload.insert(payload.end(), buffer, buffer + length);
} catch( const Runtime::Exception& e ) {
FC_THROW_EXCEPTION(tx_unknown_argument, "Message data is not a valid memory range");
if (length > 0) {
try {
// memoryArrayPtr checks that the entire array of bytes is valid and
// within the bounds of the memory segment so that transactions cannot pass
// bad values in attempts to read improper memory
const char* buffer = memoryArrayPtr<const char>( mem, uint32_t(data), uint32_t(length) );
payload.insert(payload.end(), buffer, buffer + length);
} catch( const Runtime::Exception& e ) {
FC_THROW_EXCEPTION(tx_unknown_argument, "Message data is not a valid memory range");
}
}

auto& pmsg = wasm.current_apply_context->create_pending_message(Name(code), Name(type), payload);
Expand Down
5 changes: 5 additions & 0 deletions tests/api_tests/api_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,13 +384,18 @@ BOOST_FIXTURE_TEST_CASE(test_all, testing_fixture)

//Test transaction
BOOST_CHECK_MESSAGE( CALL_TEST_FUNCTION( TEST_METHOD("test_transaction", "send_message"), {}, {}) == WASM_TEST_PASS, "test_transaction::send_message()");
BOOST_CHECK_MESSAGE( CALL_TEST_FUNCTION( TEST_METHOD("test_transaction", "send_message_empty"), {}, {}) == WASM_TEST_PASS, "test_transaction::send_message_empty()");
BOOST_CHECK_EXCEPTION( CALL_TEST_FUNCTION( TEST_METHOD("test_transaction", "send_message_large"), {}, {} ),
tx_resource_exhausted, is_tx_resource_exhausted );
BOOST_CHECK_EXCEPTION( CALL_TEST_FUNCTION( TEST_METHOD("test_transaction", "send_message_max"), {}, {} ),
tx_resource_exhausted, is_tx_resource_exhausted );
BOOST_CHECK_EXCEPTION( CALL_TEST_FUNCTION( TEST_METHOD("test_transaction", "send_message_recurse"), {}, fc::raw::pack(dummy13) ),
tx_resource_exhausted, is_tx_resource_exhausted );
BOOST_CHECK_EXCEPTION( CALL_TEST_FUNCTION( TEST_METHOD("test_transaction", "send_message_inline_fail"), {}, {} ),
fc::assert_exception, is_assert_exception );
BOOST_CHECK_MESSAGE( CALL_TEST_FUNCTION( TEST_METHOD("test_transaction", "send_transaction"), {}, {}) == WASM_TEST_PASS, "test_transaction::send_message()");
BOOST_CHECK_EXCEPTION( CALL_TEST_FUNCTION( TEST_METHOD("test_transaction", "send_transaction_empty"), {}, {} ),
tx_unknown_argument, is_tx_unknown_argument );
BOOST_CHECK_EXCEPTION( CALL_TEST_FUNCTION( TEST_METHOD("test_transaction", "send_transaction_large"), {}, {} ),
tx_resource_exhausted, is_tx_resource_exhausted );
BOOST_CHECK_EXCEPTION( CALL_TEST_FUNCTION( TEST_METHOD("test_transaction", "send_transaction_max"), {}, {} ),
Expand Down

0 comments on commit befe187

Please sign in to comment.