0

I'm trying to modify the eosio.token contract to fit a purpose. And I need to send many delayed transactions to an array of accounts. Here's the code:

for (auto i = st.bearers.begin(); i != st.bearers.end(); i++)
{
    transaction out{};
    out.actions.emplace_back(
        permission_level{get_self(), "active"_n},                                         //permission for the action (in this case needs to be the issuer of the token)
        get_self(),                                                                       //the contract to call
        "issue"_n,                                                                        //the action
        std::make_tuple(*i, asset(11, st.supply.symbol), std::string("regular payout"))); //the data
    out.delay_sec = 10;
    out.send(i->value, _self);
}

I sometimes get the "transaction took too long" error:

Error 3080006: Transaction took too long Error Details: deadline exceeded pending console output:

Which scares me. I'm supposed to make this scale A LOT and send many many more transactions.

How can I make this code rune more efficiently?

3
  • at time only one delayed transaction possible through on account. Second delayed transaction is possible when first one is complete. So you need to do is to send a algo that deferred a transaction containing all accounts in a array. And when delay limit reached. Push all transaction using transafer action. If you don't get what is Said Ping me I send you a demo code for this( I implemented this in my task) Commented Dec 16, 2018 at 6:20
  • Hi! Thank you so much for your help! I'm afraid I didn't understand everything you said (English is not my native language). You said you could send me a demo from your own code? I'd be very very grateful. I couldn't find a way to ping you directly, though...
    – jpedrosous
    Commented Dec 16, 2018 at 14:50
  • Do There delay transactions occuring from a single account to many accounts? Commented Dec 17, 2018 at 3:56

1 Answer 1

1
  1. If you are sending all these transactions from one account, Than all you could do :

void Democontract::demoaction(account_name from,vector &tos,vector &memos,string memo,uint64_t delay){

    eosio::transaction txn{};
    // max_delay in EOS is 45 days(in seconds)
    uint64_t max_delay = 10;
    string appending_char = "a";
    eosio_assert((((memo.length() == 11) || (memo.length() == 12))), "check the length of memo");
    if (memo.length() == 11){
        memo = memo.append(appending_char);
    }else if (memo.length() == 12){
        memo = memo.substr(0, 11);
    }

    if ((delay <= max_delay)){   // here we are reaching the limit to deferred time so now final execution is near.

         //Here you can do calculations according to your  requirement.

        txn.actions.emplace_back(
            eosio::permission_level(from, N(active)),
            N(youraccount),
            N(intermediate),
            std::make_tuple(from, tos, memos, memo));
        txn.delay_sec = delay;
        txn.send(eosio::string_to_name(memo.c_str()), from);
    }else{ //Here we again call this action after certain period
        //remember this recursion is not in stack
        print(memo);
        txn.actions.emplace_back(
            eosio::permission_level(from, N(active)),
            N(youraccount),
            N(demoaction),
            std::make_tuple(from, tos, memos, memo, delay - max_delay));
        txn.delay_sec = max_delay;
        txn.send(eosio::string_to_name(memo.c_str()), from);
        print("Inside repeat______________________________________\n");
    }
}
void Democontract::intermediate(account_name from,vector<account_name> &tos,vector<string> &memos,string memo)
{
    eosio::token t(N(eosio.token));
    const auto sym_name = eosio::symbol_type(S(4, EOS)).name();
    const auto my_balance = t.get_balance(from, sym_name);

    print("\n start the transactions __________________\n");
    for (int i = 0; i < tos.size(); i++)
    {
        print(name{tos[i]});

        //just a demo calculation to put value in tosend(How many EOS we send)
        eosio::asset tosend = (my_balance * 0.01 * 100) / 10000;

        Democontract::finalpush(from, tos[i], tosend, memos[i], 0);
    }
    print("\n finish with the pushing  transctions after delay is over ________________\n");
}

// @abi action
void Democontract::finalpush(account_name from,account_name to,asset quantity,string memo,uint64_t delay)
{
    require_auth(from);

    eosio::transaction txn{};

    txn.actions.emplace_back(
        eosio::permission_level(from, N(active)),
        N(eosio.token),
        N(transfer),
        std::make_tuple(from, to, quantity, memo));
    txn.delay_sec = delay;
    txn.send(eosio::string_to_name(memo.c_str()), from);
}

so you need to pass all argument to demoaction.

  1. If you are using multiple accounts to debit and multiple accounts to credit. than you also need to send a vector of account(just like `from' in my case here)

Here we push all transfer action in the end only. You can see in this code and put logic whatever you want in calculation part if you send some other parameters.

9
  • Ok I think I got it! But my problem is that the whole processing of the action is taking too long. For each new member in the array, the processing time is touching the 30ms deadline so it fails...
    – jpedrosous
    Commented Dec 17, 2018 at 9:42
  • Did you send all transaction from a single account to mulitple account ? Commented Dec 17, 2018 at 10:44
  • Yes this issue is said to be resolved but I think it is not. So many people getting this issue many time especially on test net. In order to avoid or minimized the occuranse you wrapped your all deferred transaction into a single transaction and transfer them in the end. You can refer here : github.com/EOSIO/eos/issues/3150 Commented Dec 17, 2018 at 10:55
  • I'm sending from a single account to multiple accounts, but for that reason I can't wrap everything into a single transaction since they have different destinations.
    – jpedrosous
    Commented Dec 17, 2018 at 11:34
  • Different destinations means you are trasfering to different accounts, I m right..? Commented Dec 17, 2018 at 12:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.