eosio.msig/src/eosio.msig.cpp
/*
propose function manually parses input data (instead of taking parsed arguments from dispatcher)
because parsing data in the dispatcher uses too much CPU in case if proposed transaction is big

If we use dispatcher the function signature should be:

void multisig::propose( account_name proposer,
                        name proposal_name,
                        vector<permission_level> requested,
                        transaction  trx)
*/
propose function manually parses input data (instead of taking parsed arguments from dispatcher)
because parsing data in the dispatcher uses too much CPU in case if proposed transaction is big

If we use dispatcher the function signature should be.

void multisig::propose( account_name proposer,
name proposal_name,
vector requested,
transaction  trx)
propose function manually parses input data ( instead of taking parsed arguments from dispatcher ) because parsing data in the dispatcher uses too much CPU in case if proposed transaction is big If we use dispatcher the function signature should be . void multisig :: propose ( account_name proposer name proposal_name vector requested transaction trx )
void multisig::propose() {
   constexpr size_t max_stack_buffer_size = 512;
   size_t size = action_data_size();
   char* buffer = (char*)( max_stack_buffer_size < size ? malloc(size) : alloca(size) );
   read_action_data( buffer, size );
   account_name proposer;
   name proposal_name;
   vector<permission_level> requested;
   transaction_header trx_header;
   datastream<const char*> ds( buffer, size );
   ds >> proposer >> proposal_name >> requested;
   size_t trx_pos = ds.tellp();
   ds >> trx_header;
   require_auth( proposer );
   eosio_assert( trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" );
   proposals proptable( _self, proposer );
   eosio_assert( proptable.find( proposal_name ) == proptable.end(), "proposal with the same name exists" );
   bytes packed_requested = pack(requested);
   auto res = ::check_transaction_authorization( buffer+trx_pos, size-trx_pos,
                                                 (const char*)0, 0,
                                                 packed_requested.data(), packed_requested.size()
                                               );
   eosio_assert( res > 0, "transaction authorization failed" );
   proptable.emplace( proposer, [&]( auto& prop ) {
      prop.proposal_name       = proposal_name;
      prop.packed_transaction  = bytes( buffer+trx_pos, buffer+size );
   });
   approvals apptable(  _self, proposer );
   apptable.emplace( proposer, [&]( auto& a ) {
      a.proposal_name       = proposal_name;
      a.requested_approvals.reserve( requested.size() );
      for ( auto& level : requested ) {
         a.requested_approvals.push_back( approval{ level, time_point{ microseconds{0} } } );
      }
   });
}
void multisig :: propose ( ) { constexpr size_t max_stack_buffer_size = 512 ; size_t size = action_data_size ( ) ; char * buffer = ( char * ) ( max_stack_buffer_size < size ? malloc ( size ) : alloca ( size ) ) ; read_action_data ( buffer , size ) ; account_name proposer ; name proposal_name ; vector < permission_level > requested ; transaction_header trx_header ; datastream < const char * > ds ( buffer , size ) ; ds >> proposer >> proposal_name >> requested ; size_t trx_pos = ds . tellp ( ) ; ds >> trx_header ; require_auth ( proposer ) ; eosio_assert ( trx_header . expiration >= eosio :: time_point_sec ( current_time_point ( ) ) , " " ) ; proposals proptable ( _self , proposer ) ; eosio_assert ( proptable . find ( proposal_name ) == proptable . end ( ) , " " ) ; bytes packed_requested = pack ( requested ) ; auto res = :: check_transaction_authorization ( buffer + trx_pos , size - trx_pos , ( const char * ) 0 , 0 , packed_requested . data ( ) , packed_requested . size ( ) ) ; eosio_assert ( res > 0 , " " ) ; proptable . emplace ( proposer , [ & ] ( auto & prop ) { prop . proposal_name = proposal_name ; prop . packed_transaction = bytes ( buffer + trx_pos , buffer + size ) ; } ) ; approvals apptable ( _self , proposer ) ; apptable . emplace ( proposer , [ & ] ( auto & a ) { a . proposal_name = proposal_name ; a . requested_approvals . reserve ( requested . size ( ) ) ; for ( auto & level : requested ) { a . requested_approvals . push_back ( approval { level , time_point { microseconds { 0 } } } ) ; } } ) ; }
propose function manually parses input data (instead of taking parsed arguments from dispatcher)
because parsing data in the dispatcher uses too much CPU in case if proposed transaction is big
propose function manually parses input data ( instead of taking parsed arguments from dispatcher ) because parsing data in the dispatcher uses too much CPU in case if proposed transaction is big
//eosio_assert( trx_header.actions.size() > 0, "transaction must have at least one action" );