0

I have a contract action that does some cleanup:

void token::cleanup() { ... }

that I want to run asynchronously from another action like this: schedule("cleanup", 10). my scheduling method looks like this:

void token::schedule(std::string proc, int delay)
{   
    transaction t;
    t.actions.emplace_back(
        permission_level{_self, name("active")},
        _self, name(proc),
        std::make_tuple()
    );  
    t.delay_sec = delay;
    t.send(now(), _self);
}   

but when run, it generates the error below. I've read many questions on the subject but usually they concern sending an action to another contract. in my case I just want to call my own contract. what am I missing?

error 2019-02-03T23:23:02.511 thread-0 http_plugin.cpp:580
handle_exception ] FC Exception encountered while processing chain.push_transaction debug 2019-02-03T23:23:02.511 thread-0 http_plugin.cpp:581 handle_exception ] Exception Details: 3100006 subjective_block_production_exception: Subjective exception thrown during block production Authorization failure with sent deferred transaction consisting only of actions to self {} thread-0 apply_context.cpp:347 schedule_deferred_transaction transaction declares authority '{"actor":"t","permission":"active"}', but does not have signatures for it under a provided delay of 10000 ms, provided permissions [{"actor":"t","permission":"eosio.code"}], provided keys [], and a delay max limit of 3888000000 ms {"auth":{"actor":"t","permission":"active"},"provided_delay":10000,"provided_permissions":[{"actor":"t","permission":"eosio.code"}],"provided_keys":[],"delay_max_limit_ms":3888000000} thread-0 authorization_manager.cpp:520 check_authorization

incidentally, I'm working with CDT 1.5.0


from reading the error message more thoroughly I can see that the permissions provided consist of "eosio.code"... the contract is deployed under the "t" account with the active permission i.e. "t@active" so I don't understand where the "eosio.code" is coming from...

  • you are using the transaction action of eosio.token contract. So you need to provide the premission for that. You are converting a string into a name type are you sure this is fine.? – Nirdesh Kumar Choudhary Feb 4 at 5:36
  • 1
    you can provide the permission for an account like this: cleos set account permission sender active '{"threshold": 1,"keys": [{"key": "private_keyof this account","weight": 1}],"accounts": [{"permission":{"actor":"account1","permission":"eosio.code"},"weight":1}]}' owner -p account2 this is how i provide the permission to account2 – Nirdesh Kumar Choudhary Feb 4 at 6:09
3

as Nirdesh alluded to in the comments, when a transaction is deferred, it is run by the eosio account and therefore that account needs to be given permission to make the call. Nirdesh's solution above is more complete but the very minimum required to make it work is:

cleos set account permission --add-code t active

where t is the name of the account that owns the contract containing the deferred transaction

the solution was provided by @cc32d9 on the Telegram group

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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