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

Fix deferred actions #368

Merged
merged 3 commits into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
37 changes: 37 additions & 0 deletions include/dao.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,36 @@ namespace pricing {
eosio::indexed_by<name("byrecipient"), eosio::const_mem_fun<Payment, uint64_t, &Payment::by_recipient>>,
eosio::indexed_by<name("byassignment"), eosio::const_mem_fun<Payment, uint64_t, &Payment::by_assignment>>>
payment_table;

// deferred actions table

TABLE deferred_actions_table {
uint64_t id;
eosio::time_point_sec execute_time;
std::vector<eosio::permission_level> auth;
name account;
name action_name;
std::vector<char> data;

uint64_t primary_key() const { return id; }
uint64_t by_execute_time() const { return execute_time.sec_since_epoch(); }

};
typedef multi_index<"defactions"_n, deferred_actions_table,
eosio::indexed_by<"bytime"_n, eosio::const_mem_fun<deferred_actions_table, uint64_t, &deferred_actions_table::by_execute_time>>
> deferred_actions_tables;


// deferred actions test - remove
TABLE testdtrx_table {
uint64_t id;
uint64_t number;
std::string text;

uint64_t primary_key() const { return id; }
};
typedef multi_index<"testdtrx"_n, testdtrx_table> testdtrx_tables;


ACTION assigntokdao(asset token, uint64_t dao_id, bool force);

Expand Down Expand Up @@ -203,6 +233,12 @@ namespace pricing {

ACTION reset(); // debugging - maybe with the dev flags

ACTION executenext(); // execute stored deferred actions

// Actions for testing deferred transactions - only for unit tests
ACTION addtest(eosio::time_point_sec execute_time, uint64_t number, std::string text);
ACTION testdtrx(uint64_t number, std::string text);

#ifdef DEVELOP_BUILD_HELPERS

struct InputEdge {
Expand Down Expand Up @@ -503,6 +539,7 @@ namespace pricing {

}

void schedule_deferred_action(eosio::time_point_sec execute_time, eosio::action action);

private:

Expand Down
98 changes: 83 additions & 15 deletions src/dao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2785,26 +2785,16 @@ void dao::activatebdg(uint64_t assign_badge_id)
else {
//Let's reschedule then
//Schedule a trx to close the proposal
eosio::transaction trx;
trx.actions.emplace_back(eosio::action(

eosio::action act(
eosio::permission_level(get_self(), eosio::name("active")),
get_self(),
eosio::name("activatebdg"),
std::make_tuple(badgeAssing.getID())
));

auto activationTime = startTime.sec_since_epoch();

constexpr auto aditionalDelaySec = 60;
trx.delay_sec = (activationTime - now.sec_since_epoch()) + aditionalDelaySec;

auto dhoSettings = getSettingsDocument();

auto nextID = dhoSettings->getSettingOrDefault("next_schedule_id", int64_t(0));

trx.send(nextID, get_self());
);

schedule_deferred_action(startTime + eosio::seconds(4), act);

dhoSettings->setSetting(Content{"next_schedule_id", nextID + 1});
}
}

Expand Down Expand Up @@ -3512,6 +3502,7 @@ void dao::reset() {

require_auth(_self);

/*
delete_table<election_vote_table>(get_self(), 0);
delete_table<election_vote_table>(get_self(), 1);
delete_table<election_vote_table>(get_self(), 2);
Expand All @@ -3522,8 +3513,85 @@ void dao::reset() {
delete_table<payment_table>(get_self(), get_self().value);
delete_table<Document::document_table>(get_self(), get_self().value);
delete_table<Edge::edge_table>(get_self(), get_self().value);
delete_table<deferred_actions_tables>(get_self(), get_self().value);
delete_table<testdtrx_tables>(get_self(), get_self().value);
*/

}

// Action to choose and execute the next action
// Note: anybody can call this - fails if there is no action to execute.
void dao::executenext() {

deferred_actions_tables deftrx(get_self(), get_self().value);

auto idx = deftrx.get_index<"bytime"_n>();
auto itr = idx.begin();

if (itr != idx.end() && itr->execute_time <= eosio::current_time_point()) {

// Note: We can't use the public constructor because it will misinterpret the
// data and pack it again - data is already in packed format.
eosio::action act;
act.account = itr->account;
act.name = itr->action_name;
act.authorization = itr->auth;
act.data = itr->data;

act.send();
idx.erase(itr);
}
else {
eosio::check(false, "No deferred actions to execute at this time.");
}
}

// Add a new deferred transaction
void dao::schedule_deferred_action(eosio::time_point_sec execute_time, eosio::action action) {

deferred_actions_tables deftrx(get_self(), get_self().value);

deftrx.emplace(get_self(), [&](auto& row) {
row.id = deftrx.available_primary_key();
row.execute_time = execute_time;
row.auth = action.authorization;
row.account = action.account;
row.action_name = action.name;
row.data = action.data;
});
}


// Test methods for deferred transactions - delete
void dao::addtest(eosio::time_point_sec execute_time, uint64_t number, std::string text) {
require_auth(get_self());

// 1 - Create an action object
eosio::action act(
eosio::permission_level(get_self(), eosio::name("active")),
get_self(),
eosio::name("testdtrx"),
std::make_tuple(number, text)
);

/// 2 - Schedule the action
schedule_deferred_action(execute_time, act);

}

void dao::testdtrx(uint64_t number, std::string text) {
require_auth(get_self());

testdtrx_tables testdtrx(get_self(), get_self().value);

// Add the new entry to the testdtrx table
testdtrx.emplace(get_self(), [&](auto& row) {
row.id = testdtrx.available_primary_key();
row.number = number;
row.text = text;
});
}



} // namespace hypha
15 changes: 4 additions & 11 deletions src/proposals/proposal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -521,26 +521,19 @@ namespace hypha
publishImpl(proposal);

proposal.update();

//Schedule a trx to close the proposal
eosio::transaction trx;
trx.actions.emplace_back(eosio::action(
eosio::action act(
permission_level(m_dao.get_self(), eosio::name("active")),
m_dao.get_self(),
eosio::name("closedocprop"),
std::make_tuple(proposal.getID())
));
);

auto expiration = proposal.getContentWrapper().getOrFail(BALLOT, EXPIRATION_LABEL, "Proposal has no expiration")->getAs<eosio::time_point>();

constexpr auto aditionalDelaySec = 60;
trx.delay_sec = (expiration.sec_since_epoch() - eosio::current_time_point().sec_since_epoch()) + aditionalDelaySec;

auto nextID = m_dhoSettings->getSettingOrDefault("next_schedule_id", int64_t(0));

trx.send(util::hashCombine(nextID, proposal.getID()), m_dao.get_self());
m_dao.schedule_deferred_action(expiration + eosio::seconds(4), act);

m_dhoSettings->setSetting(Content{"next_schedule_id", nextID + 1});
}

std::optional<Document> Proposal::getItemDocOpt(const char* docItem, const name& docType, ContentWrapper &contentWrapper)
Expand Down
19 changes: 4 additions & 15 deletions src/recurring_activity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,28 +83,17 @@ void RecurringActivity::scheduleArchive()
if (isInfinite()) {
return;
}

//Schedule a trx to close the proposal
eosio::transaction trx;
trx.actions.emplace_back(eosio::action(
eosio::action act(
eosio::permission_level(m_dao->get_self(), eosio::name("active")),
m_dao->get_self(),
eosio::name("archiverecur"),
std::make_tuple(getID())
));

auto expiration = getEndDate().sec_since_epoch();

constexpr auto aditionalDelaySec = 60;
trx.delay_sec = (expiration - eosio::current_time_point().sec_since_epoch()) + aditionalDelaySec;

auto dhoSettings = m_dao->getSettingsDocument();

auto nextID = dhoSettings->getSettingOrDefault("next_schedule_id", int64_t(0));
);

trx.send(nextID, m_dao->get_self());
m_dao->schedule_deferred_action(getEndDate() + eosio::seconds(4), act);

dhoSettings->setSetting(Content{"next_schedule_id", nextID + 1});
}

eosio::time_point RecurringActivity::getStartDate()
Expand Down
21 changes: 6 additions & 15 deletions src/upvote_election/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,31 +356,22 @@ namespace hypha {
static void scheduleElectionUpdate(dao& dao, UpvoteElection& election, time_point date)
{
if (date < eosio::current_time_point()) return;

//Schedule a trx to close the proposal
eosio::transaction trx;
trx.actions.emplace_back(eosio::action(
eosio::action act(
eosio::permission_level(dao.get_self(), eosio::name("active")),
dao.get_self(),
eosio::name("updateupvelc"),
std::make_tuple(election.getId(), true, false)
));
);

dao.schedule_deferred_action(date + eosio::seconds(4), act);

EOS_CHECK(
date > eosio::current_time_point(),
"Can only schedule for dates in the future"
);

constexpr auto aditionalDelaySec = 10;
trx.delay_sec = (date - eosio::current_time_point()).to_seconds() + aditionalDelaySec;

auto dhoSettings = dao.getSettingsDocument();

auto nextID = dhoSettings->getSettingOrDefault("next_schedule_id", int64_t(0));

trx.send(nextID, dao.get_self());

dhoSettings->setSetting(Content{ "next_schedule_id", nextID + 1 });

}

static void assignDelegateBadges(
Expand Down
Loading